Seven phases under one umbrella

A complete visual redesign across 18 catalogued surfaces, guided by a token migration plan, oklch contrast math, and a seven-phase base branch umbrella.

A complete visual redesign replaced the game’s typography and color palette across 18 catalogued surfaces, from buttons and game board tiles to tooltips and brand assets. Rather than landing dozens of isolated style edits directly on main, the work was structured around a dedicated token-migration decision record and sequenced through a single base branch umbrella.

Token replacement without parallel generations#

The first structural decision in the migration plan was to replace existing --color-* and --font-* custom properties directly in src/app.css as each phase landed. The repo did not introduce a parallel --color-v3-* token set to let old and new themes coexist, continuing the in-place custom property pattern set during design-system-v2-first-attempt. The codebase is a single CSS file with one running instance, so parallel token generations between phases would only ever sit as dead code. Between phases, the live app on the base branch temporarily mixed old and new surfaces, which was accepted as a normal transient state rather than gated behind feature flags.

--font-display: 'Baloo 2', display, system-ui, sans-serif;
--font-ui: 'Nunito', system-ui, sans-serif;
--font-weight-extrabold: 800;

Space Grotesk was retired in favor of Baloo 2 for headings and Nunito for body copy and buttons, while Space Mono was retained for score and game-log data. Both new fonts carry the SIL Open Font License 1.1, matching the existing font licenses and requiring no new firewall rules.

Contrast math over raw hex#

The mockup provided flat hex values, but those values were treated as a reference palette rather than raw colors to copy into CSS. Checking the mockup’s raw hex against documented WCAG contrast requirements revealed four real contrast failures before any code was committed. In particular, the raw hex for banana fruit text against the light grid background produced a 2.74:1 contrast ratio, failing the 3:1 WCAG 1.4.11 threshold and repeating an exact bug previously fixed in premature-norwegian.

dark text-muted #8f93a8 vs surface-raised #2b2c3a: 4.53:1 (needs >=4.8:1)
light text-muted #6b7280 vs surface #ffffff: 4.83:1 (needs >=5.3:1)
dark accent #e2456a vs white text: 3.97:1 (needs >=4.5:1)
banana/golden #a98a2e vs light grid #E8EAF0: 2.74:1 (needs >=3:1)

Re-expressing colors in oklch() allowed tuning lightness values specifically for perceptual uniformity while satisfying every contrast floor documented in src/app.css.

Seven phases, one base branch#

The implementation proceeded across seven grouped phase tickets: foundations, board tiles, notifications, duel flow, result panels, home menu, and brand assets. Each phase landed as its own focused PR targeting the base branch docs/design-system-redesign-1067 rather than main, following the same umbrella pattern previously used in norwegian-done-properly.

gitGraph
  accTitle: Seven-phase design system redesign branch structure
  accDescr: Seven grouped phase tickets (foundations, board tiles, notifications, duel flow, result panels, home menu, brand assets) branch from a base umbrella branch. Each phase completes its work, merges back into the umbrella, and once all seven are complete, the umbrella merges to main in a single commit.
  commit id: "main"
  branch design-umbrella
  commit id: "base branch created"
  
  branch phase/1-foundations
  commit id: "Foundations tokens"
  commit id: "Font setup"
  checkout design-umbrella
  merge phase/1-foundations
  
  branch phase/2-board
  commit id: "Board tiles"
  checkout design-umbrella
  merge phase/2-board
  
  branch phase/3-notifications
  commit id: "Notifications colors"
  checkout design-umbrella
  merge phase/3-notifications
  
  branch phase/4-duel
  commit id: "Duel flow surfaces"
  checkout design-umbrella
  merge phase/4-duel
  
  branch phase/5-results
  commit id: "Result panels"
  checkout design-umbrella
  merge phase/5-results
  
  branch phase/6-menu
  commit id: "Home menu redesign"
  checkout design-umbrella
  merge phase/6-menu
  
  branch phase/7-brand
  commit id: "Brand assets"
  checkout design-umbrella
  merge phase/7-brand
  
  checkout main
  merge design-umbrella tag: "All 7 phases merged"
Seven-phase redesign structure: each phase branches from the base umbrella, completes its work in isolation (foundations, board tiles, notifications, duel flow, result panels, home menu, brand assets), then merges back into the base branch. Once all seven are complete, the umbrella merges to main in a single commit, protecting main from intermediate breakage.

main only sees this work once, when the base PR merges.

Token migration architecture

When all seven phases were complete on the base branch, the umbrella merged to main in a single merge commit (a6cf9d0c), closing all seven phase issues at once without exposing main to intermediate breakage.

Catching contrast on press#

A ten-minute follow-up pass addressed backspace visual treatment and replaced remaining literal color: white declarations with --color-text-on-accent. Audit testing during that follow-up surfaced a second-order bug: pressed keys hardcoded white text against a light-theme active background (94% lightness), yielding a 1.23:1 contrast ratio where pressed key labels became invisible. Removing the hardcoded color allowed pressed keys to inherit proper theme text tokens while keeping submit-key overrides intact.