Daeseon Yoo
Back to project
·Tech retro·2 min

Re-skinning the whole app to a Stark-HUD design language — without touching the file a second session was editing

Phase 1 of an app-wide design system: a single hud.css defines design tokens (glow, surface, border, radius, motion, mono) and re-skins the sidebar, toolbar, brand, pane headers, focus glow, splits and context menu to a cohesive Stark-HUD language. The neat trick: the entire main screen is styled by CSS classes, so the re-skin layers on via a stylesheet loaded after App.css — zero edits to App.tsx, which a concurrent session was actively editing (paywall). Conflict avoided by construction.

The ask, escalated

After a JARVIS orchestration view, the bar moved: "the sophistication has to show everywhere, not just the graph — isn't there a theme-based design standard?" There is — it's design tokens + a theme architecture (CSS custom properties), the way Linear / Vercel / GitHub theme. So: build the standard and start applying it.

The constraint: a contested file

The main screen lives in App.tsx, and a second Claude Code session was editing it (a paywall / entitlement feature, uncommitted). Editing it too would tangle (same-file, last-write-wins — the exact hazard from ADR-007). So the question was how to re-skin the main screen without touching App.tsx.

The unlock: it's all CSS classes

App.tsx styles everything by class (.toolbar, .toolbar button, .brand-app, .mosaic-window-toolbar, .terminal-host.focused, .context-menu…), not inline styles. So a new hud.css, imported after App.css in main.tsx, layers on top and re-skins the whole chrome — no App.tsx edit, zero conflict with the other session. The contention dissolved by working at the stylesheet layer instead of the markup layer.

What landed (Phase 1)

Terminal text stays xterm (can't be GPU/HUD-skinned — and WebGL there breaks Korean IME); only its frame is themed.

Honest status

Phase 1: the token foundation + the chrome. Not yet migrated: the modals (inline-styled — next), and wiring the atmosphere picker to a root data-theme so changing the mood re-skins the whole app. And it's a blind CSS pass — visual quality still needs eyes on the running app. The durable lesson: when a file is contested, look for a layer (here, CSS classes) where your change doesn't collide — coordination you can avoid is cheaper than coordination you have to negotiate.