Docs·ba2a6d13·Updated Jul 17, 2026·85 ADRs
Back
ADR-079implemented

ADR-079: Karmyq Visual Design System v2 (finish the warm system + harden it into tokens)

ADR-079: Karmyq Visual Design System v2 (finish the warm system + harden it into tokens)

Status: Implemented Date: 2026-06-17 Sprint: 104 (research) → implemented in 105 Version: 11.13.0

Context

Sprint 88 shipped a "warm commons" design system — the .kq-* shell (karmyq-shell.css), Fraunces + Hanken Grotesk type, relationship-led RequestCard, finite "caught up" states, one quiet NotificationBell — anchored to a CSS-variable token system in globals.css :root that ThemeProvider overrides per community. Sprints 89/90/101 extended it to the community page (ADR-068), visible decay (ADR-070), and the request-detail action surface. The aesthetic was approved by the maintainer (docs/design/sprint-87/sprint-88-recommendation.md §5).

The Sprint 104 UI-facelift research (docs/design/sprint-104-ui-facelift/) audited all four surface clusters against a shared 1–5 scorecard and found the system is real, good, and only ~60% adopted:

  • Community page (avg 4.4) and Dashboard Home (4.0) are on the warm shell.
  • Request feed + detail (avg 2.1) and Profile + chrome (2.9) lag. The standalone Request feed (pages/requests/index.tsx), offers/index.tsx, and matches/[id].tsx are pre-S88 fossils that re-introduce the exact patterns the Sprint 87 audit flagged: a bold % Match badge leading the card, off-palette raw Tailwind colors (red-600, yellow-100, gray-200), SaaS "Smart Filtering" chrome, and wide cold grids.

The audit catalogued the divergence as a cross-cluster drift table: four different content widths, two card/elevation languages (border-vs-shadow), three corner radii, two match-signal treatments (quiet whisper vs bold pill), serif-vs-bold-sans display type, and raw-Tailwind-vs-token color. Each row is a missing or under-used token.

The problem is therefore not "the app is cold" (S87's finding) but "the app is half-converted, and the seam shows." The facelift is finishing the system we already chose and hardening it into tokens so it cannot drift again — not inventing a new aesthetic.

Decision

Adopt and implement Visual Design System v2: (1) complete adoption of the warm .kq-* system across the live frontend clusters and (2) harden the drift axes into named tokens. The maintainer chose "A-plus" (review 2026-06-17): Direction A (convergence; no new visual personality required) is the mandated scope. B-style texture/motif hooks were intentionally deferred because no Sprint 105 finite state or divider consumed them. All shipped deltas are expressed against CSS-variable tokens so they survive per-community re-skinning.

Three directions were studied (mockups in docs/design/sprint-104-ui-facelift/mockups/):

  • A — Tidy Commons (chosen as the S105 scope): convergence — finish the warm system everywhere, kill the fossils, standardize cards/width/status-color/type. Alone, this lifts the two weak clusters (Request feed 2.1, Profile/chrome 2.9) to ~4.2 — a meaningful facelift, not a cleanup.
  • B — Field Guide (optional garnish only): the convergence above + a whisper of paper-grain texture, the serif ramp, and a leaf motif. Built as default-off token hooks so it can be dialed up later without re-plumbing; not an S105 deliverable.
  • C — Almanac: an expressive step-up (bolder display, duotone hero, promoted accent). Most memorable, highest re-skin risk; parked as a future option.

Rationale: S104's strongest finding is that the app is half-converted (Request feed 2.1 vs Community 4.4 is real drift), not that it needs new personality. Direction A fixes exactly that and keeps the approved aesthetic intact; the failure mode to avoid is letting "facelift" become "new costume."

Design principles (the rubric)

P1 one reading column · P2 border-not-shadow elevation · P3 one radius per role · P4 smooth Fraunces ramp · P5 color = meaning, from tokens only · P6 quiet density (match-% always a whisper) · P7 warm finite states everywhere · P8 calm motion + an optional whisper of paper texture. P1–P7 shipped in Sprint 105; P8 remains the single creative dial and is deferred until a real surface consumes it.

Token-system implications

New/clarified tokens in globals.css :root + karmyq-shell.css: --measure (one content width), --radius-card, kq-headline-sm, one canonical card primitive (.kq-card, with legacy .card de-emphasized), semantic status/urgency helpers in src/lib/requestDisplay.ts, and kq-finite-state via the shared EmptyState component. The --texture / motif hook did not ship in Sprint 105 because it had no live consumer. No palette or type-family change — the brand colors and Fraunces + Hanken pairing are unchanged.

Implementation notes (Sprint 105)

S105 shipped the foundation first, then converged the request/detail/offers/match cluster, Profile and global chrome, Dashboard Home, and a light Community polish. The standalone /requests feed route was retired deliberately and redirects to Dashboard Home, leaving /requests/[id] as the canonical request detail route. Dashboard Home now keeps the primary caught-up state finite and adds a quieter secondary path to browse communities for established members with an empty primary queue.

Consequences

Positive:

  • One coherent design language across the app; the cross-cluster drift closes and is tokenized so it cannot silently recur.
  • The two weak clusters (Request feed 2.1, Profile/chrome 2.9) rise to parity with the community page.
  • A genuine facelift from convergence alone ("make the app look like its best page"), without re-opening the approved aesthetic — with the texture/motif personality held in reserve until a live surface consumes it.
  • An accessibility pass (contrast, focus, not-color-only) folds into the migration cheaply, since every surface is touched once.

Negative / risks:

  • S105 touches many surfaces; the foundation PR must land first or the propagation PRs drift.
  • The Request feed needs a fate decision (reskin vs retire) — keeping a second, colder feed is the failure mode to avoid.
  • The P8 texture must stay a whisper or it violates the "calm, library-not-poster" anchor.

Neutral:

  • Version drift is reconciled in the S105 release target: 11.13.0.
  • Texture/motif hooks remain deferred rather than shipping unused CSS.

Related