Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
2 changes: 1 addition & 1 deletion 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
19 changes: 18 additions & 1 deletion tests/ckb-v2-token-contract.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { readFileSync } from "node:fs";

import { describe, expect, it } from "vitest";

import { sourceFrom } from "./helpers/source-contract";
import { sourceFrom, sourceSegment } from "./helpers/source-contract";

/**
* Invariants of the scoped `.ckb-v2` token layer (`src/app/ckb-v2-tokens.css`).
Expand Down Expand Up @@ -324,6 +324,23 @@ describe("ckb-v2 structure", () => {
expect(structural.get("--text-hero--line-height")).toMatch(/^\d+(\.\d+)?$/);
expect(structural.get("--text-hero-tr")).toMatch(/^-/);
});

it("pins v2 --text-sm to @theme --text-sm-minus at 0.8125rem (PR 3c)", () => {
// Production `text-sm` is 13px because `.ckb-v2` is mounted on <html>.
// The overlap with `--text-sm-minus` is the catalog. Do not "fix" it by
// restoring Tailwind's 14px, and do not alias the two files at each other:
// both layers keep the same literal so the documented source-of-truth
// order (v2 above the compat `@theme` block) stays intact.
const theme = declarations(
sourceSegment(globalsStylesheet, "\n@theme {", "\n}", { label: "globals.css `@theme`" }),
);
const v2Sm = structural.get("--text-sm");
const themeSmMinus = theme.get("--text-sm-minus");

expect(v2Sm).toBe("0.8125rem");
expect(themeSmMinus).toBe("0.8125rem");
expect(v2Sm).toBe(themeSmMinus);
});
});

describe("ckb-v2 category chip tones", () => {
Expand Down
Loading