Commit Graph
3 Commits
Author SHA1 Message Date
jgamboaandClaude eafe426c8e Stage 5: wire the skin switch — both UIs now reachable
The reunion is complete: one build contains both UIs and picks between them at
bootstrap.

- src/shared/types.ts regains `skin: "modern" | "win7"` on AppSettings.
- SettingsService regains the skin signal, setSkin() and applySkin(), which
  toggles the `.win7` class on <html>.
- buildPreload emits __APP_SKIN and adds `.win7` conditionally again, instead
  of unconditionally as it had since fe028a9.
- chromeOptions() regains its parameter: win7 gets frameless + transparent,
  modern gets the macOS hiddenInset fusion or the plain native frame.
- core/platform.ts regains APP_SKIN / IS_WIN7_CHROME (added in stage 4).
- main.ts now selects on both axes — skin picks the tree, APP_MODE picks the
  root within it.
- Both tab-bars get a skin row, with the reopen caveat as its tooltip.

DEFAULT_SETTINGS.skin is "modern", matching the original design and `main`.
Worth flagging: this branch has booted win7 unconditionally since fe028a9, so
after this commit it starts in the modern UI unless the setting says otherwise.
One word in types.ts flips that if the win7 look should be the default.

i18n: en.ts is the source of truth and everything else falls back to it, so
only en was strictly required — but es/eu/fr/de/zh/ja got real translations
too, each matching the terminology that locale already uses for the Theme row.

Verified both skins on live single-instance captures. Modern boots and renders
fully styled, which also proves Tailwind scans skins/shadlike/** — a purge
would have produced an unstyled page rather than this one. Win7, selected by
setting skin in the persisted settings, is still pixel-identical to the
pre-refactor baseline across all five stages. The persisted settings file was
backed up and restored, so it still carries no skin key and resolves to the
default through the backend's merge.

Not verified: clicking the new skin row itself, which needs an interaction pass
— no window automation is available here. Its bindings compile and the built
bundle contains options.skin, setSkin and the translated labels.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 05:01:57 +02:00
jgamboaandClaude b35c30d5ab Stage 3: split styles.css into a shared base plus per-skin sheets
The 919-line stylesheet had a clean seam: `main`'s version is 278 lines and
this branch only ever APPENDED to it. Verified that directly — a diff of
main's styles.css against our first 298 lines differs only by the @layer
statement and the 7.css import.

- ui/src/styles.css (296) keeps the shared half: the @layer statement, the
  Tailwind import, the OKLCH tokens, @theme inline, the data-text interface
  sizes, the animations and the accent axis. The @layer statement must stay
  first here — it is one of only two rule types allowed above @import, and it
  is what sorts `skin` above `utilities`.
- app/skins/7like/7like.css (636) takes the whole win7 section plus the
  scoped-7.css import that feeds layer(skin).
- app/skins/shadlike/shadlike.css is near-empty by nature, not by omission:
  that skin IS the shared token system plus inline Tailwind, so there is no
  framework to bridge and no cascade to invert. The file documents why, and
  what does/does not belong in it.

Both are @imported from styles.css, so one bundle still ships both, scoped by
`.win7` exactly as before.

One real trap caught here: the @font-face url() is resolved relative to the
stylesheet, so moving the win7 section three directories deeper would have
silently 404'd Noto Sans — the build stays green and the app just falls back
to a different font. Fixed by moving the fonts INTO the skin (they exist only
for the Win7 look, where Noto Sans substitutes for Segoe UI), which keeps
`./fonts/...` correct wherever the folder goes. Confirmed in the built output:
both woff2 emitted as hashed assets with the url rewritten to ./media/.

Verified: build clean, built CSS keeps `@layer theme,base,components,
utilities,skin,skinfix` and all 7.css selectors, the live window's opaque
interior is pixel-identical to the pre-refactor baseline, and both harness
renders (light and dark) diff to exactly zero. A layer-assignment mistake here
would not be subtle — 7.css would lose to ~1900 Tailwind utilities and the app
would look nothing like this.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 04:53:57 +02:00
jgamboaandClaude 39e019af9f Stage 2: move the win7 component tree into app/skins/7like/
All 14 components (including title-bar/, which has no modern counterpart)
move under app/skins/7like/. git records every one as a rename — no content
changed except main.ts.

The @core alias from stage 1 paid off exactly as intended: not one of the 67
service imports needed touching despite every file changing depth. The only
relative imports left inside the tree are skin-internal (app -> its dialogs,
connection-manager -> title-bar), and those survived because the move
preserved their relative structure.

Added skins/7like/index.ts exporting SEVEN_ROOTS { main, manager, editor }.
Every skin will export that same shape, so main.ts can pick a tree by skin
and then a root by APP_MODE without knowing either skin's internals. main.ts
selects from that barrel now, with the second axis still hardcoded until the
shadlike tree lands.

Verified: tsc clean, build:ui clean, opaque interior pixel-identical to the
pre-refactor baseline. That last check also proves Tailwind still scans the
templates from their new skins/** paths — a silent utility purge would have
collapsed the layout rather than reproducing it exactly.

The three structural 7.css contracts that a careless move breaks silently are
intact by construction, since no markup changed: app-title-bar is still a
direct child of .window.w7-frame, nothing new nests inside menu[role=tablist],
and the context menu still emits ul[role=menu] > li[role=menuitem] > button.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-16 04:50:53 +02:00