diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index 0a4eb0bf2c..d4f5825035 100644 --- a/data/repo-awareness-snapshot.json +++ b/data/repo-awareness-snapshot.json @@ -1,8 +1,8 @@ { "version": "repo-awareness-snapshot-v1", "captured_revision": { - "sha": "9b26a3d69b447c5fa3d45b4e011b26ba46c32b69", - "committed_at": "2026-08-27T12:01:45+00:00" + "sha": "6b2d6f421ee2b2e33f4ccf4fa1d31581b452d4b4", + "committed_at": "2026-08-27T12:18:53+00:00" }, "routes": { "modes": [ @@ -2389,7 +2389,7 @@ { "path": "docs/design-system/FIX-GUIDE.md", "section": "design-system", - "catalogued": false + "catalogued": true }, { "path": "docs/design-system/GATES.md", @@ -3873,8 +3873,8 @@ ], "counts": { "documents": 481, - "catalogued": 106, - "uncatalogued": 375, + "catalogued": 107, + "uncatalogued": 374, "sections": 19 } }, diff --git a/docs/README.md b/docs/README.md index 6098437cc7..9491881913 100644 --- a/docs/README.md +++ b/docs/README.md @@ -36,6 +36,7 @@ npm run docs:check-links - [design-system/COMPONENTS.md](design-system/COMPONENTS.md) — the eight safety-component specifications plus the maturity matrix - [design-system/DECISIONS.md](design-system/DECISIONS.md) — conflicts C1–C5 resolved, clinical Q&A record, assumptions, blocked items - [design-system/GATES.md](design-system/GATES.md) — every design-system rule paired with its enforcement status +- [design-system/FIX-GUIDE.md](design-system/FIX-GUIDE.md) — Hazard 1–2 sweep dispositions (Fixed / Documented / Deferred / Out-of-scope) - [design-system/ADOPTION.md](design-system/ADOPTION.md) — PR 13 registration record: adoption order, per-surface file allowlists, exclusions, pins, proof shots - [comparison-behaviour.md](comparison-behaviour.md) — shared selection, state, responsive, and accessibility contract for comparison surfaces - [clinical-chat-ui-component-map.md](clinical-chat-ui-component-map.md) — chat UI component inventory diff --git a/docs/design-system/COMPONENTS.md b/docs/design-system/COMPONENTS.md index b64d1c5a90..4efef5d55d 100644 --- a/docs/design-system/COMPONENTS.md +++ b/docs/design-system/COMPONENTS.md @@ -39,14 +39,21 @@ _Remaining from the original eight in this document:_ `DocumentFrame` is built l (`src/components/ui/document-frame.tsx`, shell-only in `DocumentViewer`) but is not yet among the 55 design-sync registered visual exports — registration and full controls remain follow-up. +`AppliedFilters` (`src/components/ui/applied-filters.tsx`) and `CopyButton` +(`src/components/ui/copy-button.tsx`) are built, proof-migrated (CatalogueToolbar chip row +and answer-status copy control), and covered by DOM tests. They are **not** design-sync +registered — do not count them toward the 55 visual exports, and do not treat them as +specified-not-built. Registration remains follow-up (the Chip/Button add path is a 55-row +cascade). + `OverlayRoot`, `SegmentedControl`, and the PR 6–8 components are built and represented by the local publication contract. The generated snapshot records their current product-import counts; registration still proves only a source/API/preview/test reference and does not prove remote design-project publication or browser acceptance. _P1 reusable (specified in outline only):_ `Menu`/`Popover` · `KeyValue` · -`AppliedFilters`/`FilterSheet` · `ResponsiveActionGroup` · `ScrollableStrip`/ -`ScrollAffordance` · `SourceLink` · `Banner` · `CopyButton`/`CopyField` · +`FilterSheet` · `ResponsiveActionGroup` · `ScrollableStrip`/ +`ScrollAffordance` · `SourceLink` · `Banner` · `CopyField` · state family (`ErrorState`, `OfflineState`, `PermissionDeniedState`, `NotFoundState`, `UnavailableState`). @@ -976,9 +983,9 @@ This generated snapshot is a local source-derived inventory. It does not assert | `AnswerFooter` | answer | yes | yes | inherited-global-root | yes | no | 1 | | `AsyncButton` | controls | yes | yes | inherited-global-root | yes | no | 4 | | `Breadcrumb` | layout | yes | yes | inherited-global-root | yes | no | 1 | -| `Button` | controls | yes | yes | inherited-global-root | yes | no | 19 | +| `Button` | controls | yes | yes | inherited-global-root | yes | no | 21 | | `Checkbox` | controls | yes | yes | no | yes | no | 0 | -| `Chip` | controls | yes | yes | inherited-global-root | yes | no | 5 | +| `Chip` | controls | yes | yes | inherited-global-root | yes | no | 6 | | `ChoiceChip` | controls | yes | yes | inherited-global-root | yes | no | 4 | | `Citation` | source | yes | yes | no | yes | no | 0 | | `CitationList` | source | yes | yes | no | yes | no | 0 | diff --git a/docs/design-system/FIX-GUIDE.md b/docs/design-system/FIX-GUIDE.md index ea94c24453..9b194b5e5f 100644 --- a/docs/design-system/FIX-GUIDE.md +++ b/docs/design-system/FIX-GUIDE.md @@ -37,27 +37,27 @@ measurement of `globals.css` / `ckb-v2-tokens.css`. ## Batch B — docs dispositions -| ID | Status | Rationale | -| -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| DS-P2-04 | Documented | Intentional Geist variable interpolation. Already explained in [`docs/design-system.md`](../design-system.md) (intermediate weights; do **not** snap to 600/700). | -| DS-P2-22 | Documented | `SectionHeading` exists (`src/components/ui/section-heading.tsx`); 14 production call sites. No opportunistic migration this sweep. | -| DS-P2-23 | Documented | `AnswerCard` `frame?: "raised" \| "bare"` — both valid. Production answer surface uses **bare**. Future visual baselines must include both. Do not commit screenshots. | -| DS-P2-27 | Documented | 15-mode load: recommend first-run / Tools prominence later. No IA redesign this sweep. | -| DS-P2-28 | Documented | Settings **Motion** already has a per-control description. **Recent searches on home** does not — docs recommendation only; no extra intro copy in product this sweep. | -| DS-P2-29 | Deferred | Phone document-viewer density waits on the tap-floor (Hazard ≥3). | -| DS-P2-30 | Documented | Toast primitive exists; there is no **universal network-error** toast. Do not build toast infra here. `OverlayRoot` remains the overlay owner. | -| DS-P2-31 | Documented | Already in TOKENS §4 / SPEC §3: add `--kind-*` **with the first call site**. No values in this sweep. | -| DS-P2-32 | Documented | `--text-placeholder` is **live** (globals + v2 + `placeholder:` consumers), not planned. TOKENS §5 corrected. No further role migration. | -| DS-P2-33 | Documented | Contract `textSoftConsumers=0` in production. Keep the `--text-soft` alias until zero `var(--text-soft)` remain **including mockups**. Do not rename; do not delete this sweep. | -| DS-P3-01 | Deferred | PR-9 plan. `--shadow-focus` and dead springs are already gone. `--shadow-lift` still has live `mode-nav` and `document-search-results` consumers — do **not** delete it. | -| DS-P3-02 | Documented | TOKENS already: `--tone-*` frozen, not deleted. | -| DS-P3-03 | Documented | TOKENS already: design-side `--quantity-unit-scale` never lands. | -| DS-P3-04 | Documented | TOKENS already: ConfidenceMeter deferred; no token without a call site. | -| DS-P3-05 | Documented | Registry has **55** registered visual exports. `DocumentFrame` is built shell-only and still unregistered. Register when print primitives ship (PR 11). Docs elsewhere may still say 53/54. | -| DS-P3-07 | Documented | Full visual state matrix grows incrementally with new adoptions. | -| DS-P3-08 | Documented | QA checklist: inspect the filter band at 414–430px. No code this sweep. | -| DS-P3-09 | Documented | `#TYZK23` PWA install CLS already fixed (PR #2253). Regression-check note only; no speculative CSS. | -| DS-P3-10 | Documented | Mockup `min-h-11` and `--text-soft` body must not leak into production. | +| ID | Status | Rationale | +| -------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| DS-P2-04 | Documented | Intentional Geist variable interpolation. Already explained in [`docs/design-system.md`](../design-system.md) (intermediate weights; do **not** snap to 600/700). | +| DS-P2-22 | Documented | `SectionHeading` exists (`src/components/ui/section-heading.tsx`); 14 production call sites. No opportunistic migration this sweep. | +| DS-P2-23 | Residual / Documented | Both frames valid. Production `answer-result-surface` uses `frame="bare"`; default/preview is `frame="raised"`. Harness note on `targets` in `tests/ui-visual-baseline.spec.ts`: a future AnswerCard baseline must capture **both** frames. Do not add targets, PNGs, or `AWAITING_BASELINE` entries until a real approval path exists. | +| DS-P2-27 | Documented | 15-mode load: recommend first-run / Tools prominence later. No IA redesign this sweep. | +| DS-P2-28 | Documented | Settings **Motion** already has a per-control description. **Recent searches on home** does not — docs recommendation only; no extra intro copy in product this sweep. | +| DS-P2-29 | Deferred | Phone document-viewer density waits on the tap-floor (Hazard ≥3). | +| DS-P2-30 | Documented | Toast primitive exists; there is no **universal network-error** toast. Do not build toast infra here. `OverlayRoot` remains the overlay owner. | +| DS-P2-31 | Documented | Already in TOKENS §4 / SPEC §3: add `--kind-*` **with the first call site**. No values in this sweep. | +| DS-P2-32 | Documented | `--text-placeholder` is **live** (globals + v2 + `placeholder:` consumers), not planned. TOKENS §5 corrected. No further role migration. | +| DS-P2-33 | Documented | Contract `textSoftConsumers=0` in production. Keep the `--text-soft` alias until zero `var(--text-soft)` remain **including mockups**. Do not rename; do not delete this sweep. | +| DS-P3-01 | Deferred | PR-9 plan. `--shadow-focus` and dead springs are already gone. `--shadow-lift` still has live `mode-nav` and `document-search-results` consumers — do **not** delete it. | +| DS-P3-02 | Documented | TOKENS already: `--tone-*` frozen, not deleted. | +| DS-P3-03 | Documented | TOKENS already: design-side `--quantity-unit-scale` never lands. | +| DS-P3-04 | Documented | TOKENS already: ConfidenceMeter deferred; no token without a call site. | +| DS-P3-05 | Documented | Registry has **55** registered visual exports. `DocumentFrame` is built shell-only and still unregistered. Register when print primitives ship (PR 11). Docs elsewhere may still say 53/54. | +| DS-P3-07 | Documented | Full visual state matrix grows incrementally with new adoptions. | +| DS-P3-08 | Documented | QA checklist: inspect the filter band at 414–430px. No code this sweep. | +| DS-P3-09 | Documented | `#TYZK23` PWA install CLS already fixed (PR #2253). Regression-check note only; no speculative CSS. | +| DS-P3-10 | Documented | Mockup `min-h-11` and `--text-soft` body must not leak into production. | --- @@ -92,3 +92,4 @@ capture · `npm run ensure` unless a visual defect is proven. - `--shadow-lift` still live (`mode-nav`, `document-search-results`). - Mockup `--text-soft` still blocks alias deletion. - Mockup `min-h-11` must stay mockup-only. +- AnswerCard visual baselines: future captures must include `frame="bare"` (live `answer-result-surface`) and `frame="raised"` (default/preview). No committed screenshots this sweep. diff --git a/docs/design-system/GATES.md b/docs/design-system/GATES.md index c2d75730a8..46ce6f0b43 100644 --- a/docs/design-system/GATES.md +++ b/docs/design-system/GATES.md @@ -52,11 +52,26 @@ gated from both sides, so the build fails if an exempted step stops being declar consumer (class utility or direct `var(--text-*)` across walked production sources), and the list cannot rot. -**Still not enforced:** which of the _existing_ steps a component picks. Nothing stops a -surface choosing `text-sm-minus` over `text-sm`, and nothing mechanical can — that is a -judgement about the rendered design, not a property of the source. Do not describe the scale -as ungated, and do not write an ESLint rule duplicating the arbitrary-value check that -already ships. +**Still not enforced:** which of the _existing_ steps a component picks, except +the same-file mix below. Nothing stops a surface choosing `text-sm-minus` over +`text-sm` in isolation, and nothing mechanical should — that is a judgement +about the rendered design, not a property of the source. Do not describe the +scale as ungated, and do not write an ESLint rule duplicating the +arbitrary-value check that already ships. + +**Same-file density mix (DS-P2-02, warn/ratchet, not a hard zero).** Canonical +metadata is `--text-sm` / live `text-sm`. Compact `text-sm-minus` is a named +density notch, not a second metadata role. `check:design-system-contract` +records `sameFileTextSmMinusMix` per path and **warns** when both utilities +appear in one production file without implying the 705 legacy steps are illegal. +A new mixed file fails the per-path ratchet; existing mixed files stay until a +named density reason is recorded or the mix is removed. Do **not** delete the +705 legacy steps. + +Canonical role → live utility (TOKENS §6): `--text-xs` → `text-xs`; `--text-sm` +→ `text-sm` (compact `text-sm-minus` only with a named density reason); +`--text-body` → `text-base-minus`; `--text-md` → `text-[length:var(--text-md)]`; +`--text-lg` → `text-xl`; `--text-xl` → `text-2xl`; `--text-hero` → `text-hero`. ⚠️ **The "1 318 call sites" figure this section used to quote was a repo-wide grep including `src/app/mockups/**`, which every one of these gates excludes** — 1 360 at `7aaf9349c`. @@ -85,10 +100,15 @@ because it contributed nothing. | 11 | Published-type conformance — every `dtsPropsFor` entry exactly matches source props | **implemented-blocking** | `generate-design-sync-contract.mjs` uses the TypeScript checker to derive every public property from the exported source `*Props` type; `--check` and `check-design-sync-contract.mjs` reject drift, missing named types, or machine-specific declarations. Zero-prop visual roots are explicit. | | 12 | Publication coverage — every registered visual component has source, export, preview, prop contract and direct publication test | **implemented-blocking** | Registry/map/props parity and all 55 direct component rows are pinned by the design-sync contract and `design-sync-visual-exports.test.ts`. Behavioural, full visual-state, print, and browser acceptance remain separate gates; `DocumentFrame` is built shell-only in product but not yet among the 55 registered visual exports (print primitives remain specified-not-built). | -**Computed-style suites (planned, PR 1–2):** Tailwind conflict order · v2 cascade, ancestor -**and** same-node forms · HCM remapping under all three v2 selectors · z-index · target -geometry · contrast · print token reset. Class-string assertions are not accepted for any of -these — computed values only. +**Computed-style suites.** HCM remapping under all three v2 selectors is +**already implemented** (`ckb-v2 forced-colours computed tokens` in +`tests/ui-style-contract.spec.ts`) — do not re-litigate. Overlay z-index vs +named `--z-*` tokens is **implemented-blocking** in the same spec (`overlay +z-index computed tokens`); class-string assertions are forbidden; the +`rawCssZIndices` exception baseline stays at 8 in `globals.css`. Still planned +(PR 1–2): Tailwind conflict order · v2 cascade, ancestor **and** same-node +forms · target geometry · contrast · print token reset. Class-string assertions +are not accepted for any of these — computed values only. **Reference preview coverage is implemented-blocking for all 55 registered visual exports.** The full runtime visual state matrix remains planned: default · hover · active · focus-visible · @@ -103,34 +123,34 @@ theme-list parity, and remote design-project publication remain separate concern ## 3 · The prohibition table -| Never do this | Gate | Status | -| -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Reintroduce `.ckb-v2:not(.dark)` | Cascade computed-style test (PR 1) + contract-test selector filter update | implemented-blocking — landed #1538; contract parser + dark-ink regression guard | -| Add `prefers-color-scheme` rules to the v2 layer | — (users pin a theme against OS preference) | **manual** | -| Paint a numeral with a status colour; use amber/red decoratively | `check:design-system-contract` — `statusColouredNumerals` + `colourOnlyStatusIndicators` | **implemented-blocking** — both metrics and their per-path baselines are pinned at **0**; see §5 | -| Put `--decoration-soft`/`--text-soft` on a text node | Tier pinned both sides in the token contract; recipe AST (`decoration-on-text.contract.test.ts`) | implemented-blocking (recipes); broader AST follow-on | -| Uppercase a dose unit | `Quantity` pins `normal-case` + unit test | implemented-blocking (branch) | -| Invert a PDF, diagram or clinical image in any theme | `check:design-system-contract` — `imageInversions`, pinned at **zero**, not ratcheted | **implemented-blocking** (9 Aug 2026) — CSS `filter`/`backdrop-filter` plus the Tailwind `invert`/`hue-rotate` utilities; see §5 | -| Border **and** ring on one surface, or a 1px spread in a drop shadow | `check:design-system-contract` — `edgeOwnershipConflicts` (18) + `onePixelShadowSpreads` (0) | **implemented-blocking for new use** — AST/CSS ratchets with per-path pins; the recorded debt itself is Gate 8's remaining half | -| A child shadow heavier than its parent's | Gate 7 | implemented-partial | -| Use `--shadow-tight`/any alias in new code | `check:design-system-contract` — `legacyShadowAliases`, ratcheted at 89 with per-path pins | **implemented-blocking for new use** — a new alias in any file fails. `--shadow-tight` itself is retired onto `--e1` and additionally pinned by a tracked-tree sweep in `tests/design-token-contract.test.ts` (it was silently reverted once by the `acf78bf` merge); the remaining 89 are the other six aliases, still `#262` | -| Raw pixel size, padding, radius, gap or line-height in markup | `check:design-system-contract` — `rawPaddingLiterals` (52), `rawRadiusLiterals` (20), `rawGapLiterals` (25), `rawMarginLiterals` (74), `rawLineHeightLiterals` (0) | **implemented-blocking for new use** (9 Aug 2026) — per-path ratchets over both the utility and the CSS-declaration spelling, so a literal cannot move into `globals.css` to escape. Values containing a CSS function (`env(`, `clamp(`, `max(`, `calc(`) are sanctioned computed forms and exempt. Raw _size_ is still covered only for tap/shadow/colour | -| Animate `width`, `height`, `grid-template-*`, `top`, `left`, `gap` | `check:design-system-contract` — `layoutTransitionExceptions`, ratcheted at 11 with per-path pins | **implemented-blocking for new use** — `SAFE_TRANSITION_PROPERTIES` carries the compositor-only allowlist; phone chrome's deliberate `grid-template-rows` is in the recorded 11 | -| Hardcode a transition duration | `check:design-system-contract` — `hardcodedMotionClasses` (**zero**) + `hardcodedCssMotionDurations` (41) | **implemented-blocking** for the Tailwind `duration-*`/`delay-*`/`transition-all` form; the CSS form is a ratchet, so its 41 are debt | -| A `z-[N]` literal outside the named rungs, in JS/TS only | `require-z-index-ladder` (ESLint) | implemented-blocking. Scope: `z-[N]` literals in JS/TS AST nodes. Plain `z-30` utilities and every `.css` / `.module.css` declaration are invisible to an ESLint rule - `sidebar-live-shell.module.css` carries an off-ladder `z-index: var(--z-sidebar-flyout, 50)` this cannot see. | -| Ship a registered component without a direct publication test | Gate 12 | implemented-blocking | -| Lower a production tap target below 48px | `check:design-system-contract` — `interactiveTapFloorDeclarations` (33) + Gate 2's phone-viewport `ui-style-contract` audit + `ui-smoke` flake history | **implemented-blocking for new use** (15 Aug 2026) — a new interactive control declaring a sub-floor `min-h-*`, including comparable arbitrary values and any reachable conditional branch, fails on both the total and its own path; the 33 recorded sites remain debt. Component-wrapper tags such as `` are a known blind spot | -| Construct an enabled control with no action, destination or name | PR 4 discriminated unions + DOM contracts; `require-button-wiring` covers raw `