Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
b5d46b3
fix(ui): raise remaining interactive tap floors
BigSimmo Aug 27, 2026
6d693e7
feat(design-system): compact-meta density policy
BigSimmo Aug 27, 2026
1fa1ef2
refactor(ui): adopt PageHeader on mode pages and Button in sidebar
BigSimmo Aug 27, 2026
3948b7a
fix(design-system): TSX ratchets (color exemption, type map, spacing)
BigSimmo Aug 27, 2026
012821f
fix(ui): tokenise globals motion/z, Ward PRM, hash scroll clamp
BigSimmo Aug 27, 2026
dc85af7
Merge branch 'claude/ds-h36-compact-meta' into claude/ds-h36-baseline
BigSimmo Aug 27, 2026
374c8d0
Merge branch 'claude/ds-h36-page-header' into claude/ds-h36-baseline
BigSimmo Aug 27, 2026
75085f9
Merge branch 'claude/ds-h36-tsx-ratchets' into claude/ds-h36-baseline
BigSimmo Aug 27, 2026
63b9f34
Merge branch 'claude/ds-h36-motion-scroll' into claude/ds-h36-baseline
BigSimmo Aug 27, 2026
6a72654
chore(design-system): refresh contract baseline and adoption
BigSimmo Aug 27, 2026
d0455d2
test(design-system): pin v2 --text-sm to @theme --text-sm-minus at 13px
cursoragent Aug 27, 2026
e509265
docs(design-system): record production text-sm as 13px, not Tailwind …
cursoragent Aug 27, 2026
62f234f
Merge branch 'main' into claude/ds-h36-baseline
BigSimmo Aug 27, 2026
a92a774
test(design-system): fail closed if the @theme block has no closer
cursoragent Aug 27, 2026
84d6fb3
fix(fonts): vendor Geist latin WOFF2 instead of next-devtools
cursoragent Aug 27, 2026
a396aa5
fix(fonts): declare Geist variable weight range 100-900
cursoragent Aug 27, 2026
7ab5662
Merge branch 'main' into claude/ds-h36-baseline
claude Aug 27, 2026
c4c5dcc
Correct stale Dictionary header recommendation in mockups/README.md
claude Aug 27, 2026
759747f
Merge branch 'main' into claude/organize-remote-mockups-15wshq
BigSimmo Aug 27, 2026
c046d3c
fix: reconcile the branch with what actually landed on main
claude Aug 27, 2026
8c6c249
docs(design-system): align SPEC, GATES, and conventions with live typ…
cursoragent Aug 27, 2026
525492b
Merge branch 'main' into claude/ds-h36-baseline
claude Aug 27, 2026
e691247
Merge branch 'main' into claude/ds-h36-baseline
claude Aug 27, 2026
e6c4dd1
test(design-system): reject token-shaped per-step type companions
cursoragent Aug 27, 2026
bdd50c6
Merge origin/main into cursor/fix-ds-sot-drift-b22d
cursoragent Aug 27, 2026
4d7421c
Merge branch 'main' into cursor/type-catalog-pin-b8b8
BigSimmo Aug 27, 2026
1284e12
Merge branch 'main' into cursor/vendor-geist-021e
BigSimmo Aug 27, 2026
891bcac
Merge remote-tracking branch 'origin/cursor/type-catalog-pin-b8b8' in…
claude Aug 27, 2026
4fc120b
Merge remote-tracking branch 'origin/pr-2429' into bundle-ds
claude Aug 27, 2026
1dc0535
Merge remote-tracking branch 'origin/claude/organize-remote-mockups-1…
claude Aug 27, 2026
327dd4a
refactor(ui): extract cn() into src/lib/cn.ts
claude Aug 27, 2026
acc5fff
Merge remote-tracking branch 'origin/main' into bundle-ds
claude Aug 27, 2026
d18b3a2
Merge remote-tracking branch 'origin/main' into bundle-fe
claude Aug 27, 2026
6953e33
Merge remote-tracking branch 'origin/cursor/fix-ds-sot-drift-b22d' in…
claude Aug 27, 2026
4a3f08c
Merge branch 'main' into cursor/vendor-geist-021e
BigSimmo Aug 27, 2026
04d1e1f
Merge remote-tracking branch 'origin/main' into cursor/vendor-geist-021e
claude Aug 27, 2026
3305f5f
Merge branch 'main' into cursor/vendor-geist-021e
BigSimmo Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .design-sync/NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ absence of both before calling it a defect.
`--name\s*:`, not bare `var(--name)`, or referenced-but-undefined vars read
as defined) and the bundle's export list on every re-sync. A helper lives at
`.design-sync/.cache/validate-conventions.mjs` (gitignored, cheap to rewrite).
- The "Opt-in v2 token layer" paragraph was aligned to TOKENS / html mount
(`ckb-v2` on `<html>`, shared `--leading-prose`, hero companions only). The
next remote sync must not restore per-step `-lh`/`-tr`.
- The driver reports the token port as `changed: []` with `sourceKeys`
unchanged: `sourceKeys` track the authored preview + preview-affecting config,
NOT component source. A component-source or token change surfaces instead as
Expand Down
14 changes: 8 additions & 6 deletions .design-sync/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,14 @@ glyphs). Label and caption **text** uses `--text-muted`.
## Opt-in v2 token layer

`.ckb-v2` is an opt-in class that swaps in the v2 shell: white surfaces, a blue
`--command`, a crisper `--e1`…`--e4` ladder, a 7-step type scale with per-step
line-height and tracking, semantic spacing (`--gap-*`, `--pad-*`), density
(`--tap-min`, `--chip-height`, `--row-*`), icon sizes (`--icon-*`) and motion
durations. Add `ckb-v2` (plus `dark` for the dark ramp) to a subtree to adopt it;
without the class nothing changes. Components that reference v2-only tokens carry
a v1 fallback (`var(--pad-panel,1.5rem)`) so they render correctly either way.
`--command`, a crisper `--e1`…`--e4` ladder, a 7-step type scale (size steps with
shared `--leading-prose`; hero companions `--text-hero--line-height` /
`--text-hero-tr` only — no per-step leading or tracking), semantic spacing
(`--gap-*`, `--pad-*`), density (`--tap-min`, `--chip-height`, `--row-*`), icon
sizes (`--icon-*`) and motion durations. Production puts `ckb-v2` on `<html>`
(`src/app/layout.tsx`); subtree opt-in is no longer the production model.
Components that reference v2-only tokens carry a v1 fallback
(`var(--pad-panel,1.5rem)`) so they render correctly either way.

## Class-string vocabulary (exported constants)

Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*.pdf binary
*.png binary
*.webp binary
*.woff2 binary

# The historical Markdown ledgers are serial-only. New review records and issue
# changes use immutable per-request files, so GitHub never needs a workstation-
Expand Down
2 changes: 1 addition & 1 deletion docs/design-system-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ npm run check:icon-scale
### 2.2 Typography Scale

- **Named Steps Only**: Font sizes must use the registered type steps in `@theme`:
- `text-3xs` (10px - absolute floor), `text-2xs` (11px), `text-xs` (12px), `text-sm-minus` (13px), `text-sm` (14px), `text-base-minus` (15px), `text-base` (16px), `text-lg-minus` (17px), `text-lg` (18px), `text-xl` (20px), `text-2xl-minus` (22px), `text-2xl` (24px).
- `text-3xs` (10px - absolute floor), `text-2xs` (11px), `text-xs` (12px), `text-sm` / `text-sm-minus` (13px; v2 `--text-sm` equals `@theme --text-sm-minus` at `0.8125rem`), `text-base-minus` (15px), `text-base` (16px), `text-lg-minus` (17px), `text-lg` (18px), `text-xl` (20px), `text-2xl-minus` (22px), `text-2xl` (24px).
- **Arbitrary Size Prohibited**: `text-[12px]`, `text-[13px]`, etc. are blocked by `npm run check:type-scale --strict`.
- **Declared Steps Usage**: Any type step declared in `@theme` must have production consumers (no dead or unselected type tokens).

Expand Down
9 changes: 6 additions & 3 deletions docs/design-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,12 @@ When you meet a pre-token hardcode (mockups being promoted, old branches), map i
Named steps live in the `@theme` block of `globals.css` and are **size-only** (no baked
line-height/tracking — set `leading-*`/`tracking-*` at the call site):

`text-3xs` 10px (floor) · `text-2xs` 11px · (`text-xs` 12 / `text-sm` 14 / `text-base`
16 from Tailwind) · `text-sm-minus` 13px · `text-base-minus` 15px · (`text-lg` 18 / `text-xl`
20 / `text-2xl` 24 from Tailwind) · `text-lg-minus` 17px · `text-2xl-minus` 22px.
`text-3xs` 10px (floor) · `text-2xs` 11px · (`text-xs` 12 / `text-base` 16 from Tailwind) ·
`text-sm` / `text-sm-minus` 13px (v2 `--text-sm` equals `@theme --text-sm-minus` at
`0.8125rem`; Tailwind's default `text-sm` 14px is overridden app-wide because `ckb-v2` is
mounted on `<html>`. Pinned in `tests/ckb-v2-token-contract.test.ts`; do not restore 14px
and do not alias the two files at each other) · `text-base-minus` 15px · (`text-lg` 18 /
`text-xl` 20 / `text-2xl` 24 from Tailwind) · `text-lg-minus` 17px · `text-2xl-minus` 22px.

- **10px is the floor.** An 8px `text-4xs` step existed and is retired — indefensible at any
density in a clinical product. Do not reintroduce a sub-10px step.
Expand Down
10 changes: 7 additions & 3 deletions docs/design-system/GATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ than CI, two of them by the second reader; review does not scale past two carefu
| Check | What it enforces | Label |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------ |
| `npm run check:design-system-contract` (token baseline + adoption + design-sync contracts) | Raw colour literals (ratchet against `design-system-contract-baseline.json`), literal `shadow-[…]` classes, the legacy tap class, interactive tap-size literals, therapy-compass `tc-btn` base-class use; border+ring edge conflicts, 1px shadow spreads, layout-property transitions and legacy shadow aliases (all ratcheted **per path**, so new use fails anywhere); status-coloured numerals and colour-only status indicators; raw padding, radius, gap and line-height literals in both classes and CSS declarations (ratcheted **per path**; named utilities and Tailwind arbitrary-property forms such as `[padding:22px]` both count; values computed with `var()`/`env()`/`calc()`/`clamp()`/`max()`, zero with any CSS unit identifier, and the CSS-wide keywords are exempt); declared-but-unselected type steps (**hard rule** with a gated exemption list); `dark:` colour overrides, legacy palette utilities and image-inversion filters (all pinned at **zero**, not ratcheted); deterministic adoption truth; local source/export/preview/design-sync parity. Mockups exempt. | implemented-blocking |
| `tests/ckb-v2-token-contract.test.ts` | v2 layer stays class-scoped (no `:root` leak) · `--border-lux` solid and no lighter than `--border`, both themes · dark surface ramp monotonic and separated · `--surface-subtle` aliases up · text/muted/heading ≥4.5:1 on the light shell, muted ≥4.5:1 dark · `--text-soft` pinned **below** 4.5:1 and ≥3:1 (both sides, so the tier cannot be "fixed" away) · command pair ≥4.5:1 both themes · `--shadow-inset` true inset · elevation ladder carries no baked 1px hairline · tap floor ≠ chip height ≠ compact row · reduced-motion zeroes durations · type-scale pins `--leading-prose` plus `--text-hero--line-height` / `--text-hero-tr` (no per-step `-lh`/`-tr` orphans) | implemented-blocking |
| `tests/ckb-v2-token-contract.test.ts` | v2 layer stays class-scoped (no `:root` leak) · `--border-lux` solid and no lighter than `--border`, both themes · dark surface ramp monotonic and separated · `--surface-subtle` aliases up · text/muted/heading ≥4.5:1 on the light shell, muted ≥4.5:1 dark · `--text-soft` pinned **below** 4.5:1 and ≥3:1 (both sides, so the tier cannot be "fixed" away) · command pair ≥4.5:1 both themes · `--shadow-inset` true inset · elevation ladder carries no baked 1px hairline · tap floor ≠ chip height ≠ compact row · reduced-motion zeroes durations · type-scale pins `--leading-prose` plus `--text-hero--line-height` / `--text-hero-tr` (no per-step `-lh`/`-tr` orphans) · v2 `--text-sm` === `@theme --text-sm-minus` === `0.8125rem` (literals; not aliased at each other) | implemented-blocking |
| `tests/design-token-contract.test.ts` | Live-layer token relationships (companion to the v2 contract) | implemented-blocking |
| `tests/source-badges-off-vocab.dom.test.tsx` | Enum resilience: off-vocabulary `clinical_validation_status` degrades to the neutral triad, logs once, never throws | implemented-blocking |
| `tests/source-metadata-browser-safety.test.ts` | The `process is not defined` client-bundle crash stays fixed (server logger never ships to the browser) | implemented-blocking |
Expand Down Expand Up @@ -223,14 +223,18 @@ point where the scale argument for (b) would start being true.

## 4 · Recorded verification evidence

Recorded at export (31 July 2026), **not re-run for this document set**:
The `npx tsc` / `npm run lint` / `npm run test` / `npm run verify:ui` bullets remain the
31 July 2026 snapshot and were **not re-run** for later document-set edits. The
`check:design-system-contract` bullet was **re-quoted** against the current
`scripts/design-system-contract-baseline.json` (raw colours 0) so it stays aligned with
the adoption pin.

- `npx tsc --noEmit` — pass · `npm run lint` — pass
- `npm run test` — **4 689 passed, 1 failed, 3 skipped**; the failure is
`tests/installed-lock-parity.test.ts`, environmental (`brace-expansion` lock drift, issue
`#149`, fixed by `npm ci`), pre-existing and unrelated
- `npm run verify:ui` — **344 passed**, exit 0
- `check:design-system-contract` — pass: 625 production files, raw colours 2, literal
- `check:design-system-contract` — pass: 625 production files, raw colours 0, literal
shadows 0, legacy tap classes 0

The honest sentence includes the failure. Exit code 0 alone is never proof — quote the
Expand Down
7 changes: 5 additions & 2 deletions docs/design-system/SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,11 @@ to `MarkText`. One wrong token, two defects. (PR 3; gate planned.)

### 4.5 Type

Seven steps, each with its own line-height **and** tracking (gated — contract test
`:194-204`). Negative tracking only from `--text-body` up; 12px floor. Step roles:
Seven **size** steps; xs–xl are size-only; shared leading is `--leading-prose`. Hero
keeps `--text-hero--line-height` and `--text-hero-tr` only. Do not reintroduce per-step
`-lh` / `-tr` / `--text-{step}--line-height` orphans (gated — contract test `pins shared
leading and hero companions, not per-step orphans`). Negative tracking only from
`--text-body` up; 12px floor. Step roles:
`--text-xs` eyebrows/chips/captions · `--text-sm` metadata/dense cells/hints · `--text-body`
UI body/row titles · `--text-md` **answer prose** · `--text-lg` card and panel titles ·
`--text-xl` page titles · `--text-hero` hero counts.
Expand Down
15 changes: 11 additions & 4 deletions mockups/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,14 @@ design decision rather than guessed at from the names.
| `document-image-status` | Fixture backing a component test — keep. |
| `accessible-table-browser-fixture` | Fixture backing a component test — keep. |

### Dictionary browse header — three rounds, no recorded winner
### Dictionary browse header — three rounds, keep all three

`dictionary-browse-header`, `dictionary-browse-header-compact`, `dictionary-control-row` —
see the dated write-ups below; each attacks a different part of the same header and none is
recorded as the final pick.
see the dated write-ups below; each attacks a different part of the same header. Round two's
Version 01 is the one that actually shipped to `/dictionary/browse` (confirmed against the
shipping commit, corrected below — the write-up briefly recorded the wrong version as chosen).
None of the three routes supersedes another at the route level — round two and round three both
import code from round one's component file, so all three stay regardless.

### Search chrome & composer

Expand Down Expand Up @@ -230,9 +233,13 @@ dropdown on phones** and moves **Abbreviations out of the header into the Filter
| Version | Phone chrome | Trade-off |
| ------------------------------ | ------------ | ------------------------------------------------------------------- |
| 01 Title bar + letter dropdown | 2 rows | Title still costs a row the mode nav already implies |
| 02 Single fused row (rec.) | 1 row | An active filter chip costs the row its title and count at 390 px |
| 02 Single fused row | 1 row | An active filter chip costs the row its title and count at 390 px |
| 03 Slim toolbar, title retired | 1 slim bar | Phone loses its visual page title; depends on the mode nav above it |

**Shipped: Version 01**, not the recommendation the study opened with — the commit that shipped this study to
`/dictionary/browse` records "Version 01 is the chosen direction" (PR #2143). `dictionary-control-row`'s later study
builds on that outcome.

Demoting a view switch into a sheet hides state, so each version surfaces an active **Abbreviations** chip beside the
letter control. Without it the header would claim 96 terms while listing 24 abbreviations.

Expand Down
Loading
Loading