From 8e74ae929a89eb174934985956984c7ea0509aa6 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Thu, 27 Aug 2026 18:23:10 +0800 Subject: [PATCH 1/2] Pay down group-2 visual debt without raising design-system ratchets. Split ui-primitives into primitive recipes, land built-but-unregistered AppliedFilters/CopyButton, and align GATES prose to the measured 34 shadow-alias baseline. Co-authored-by: Cursor --- data/repo-awareness-snapshot.json | 10 +- docs/README.md | 1 + docs/design-system/COMPONENTS.md | 15 +- docs/design-system/FIX-GUIDE.md | 43 +- docs/design-system/GATES.md | 94 ++- docs/design-system/TOKENS.md | 18 + docs/design-system/adoption-manifest.json | 35 +- scripts/check-design-sync-contract.mjs | 24 +- scripts/check-design-system-contract.mjs | 15 +- scripts/design-system-contract-baseline.json | 88 +- scripts/design-system-contract-utils.mjs | 47 ++ scripts/generate-design-sync-contract.mjs | 90 ++- scripts/generate-design-system-adoption.mjs | 15 +- src/app/globals.css | 2 +- .../mockups/answer-evidence-popups/page.tsx | 6 +- src/app/mockups/mode-dropdown/page.tsx | 6 +- .../mockups/recent-searches-bottom/page.tsx | 2 +- .../answer-chat-perfected-mockups.tsx | 6 +- .../answer-chat-perfected-v2-mockups.tsx | 2 +- .../answer-chat-redesign-mockups.tsx | 10 +- src/components/applications-launcher-page.tsx | 2 +- .../bedside-sheet-mockup.tsx | 2 +- .../clinical-console-mockup.tsx | 2 +- .../directory-grid-mockup.tsx | 4 +- .../calculator-mockups/guided-flow-mockup.tsx | 6 +- .../search-detail-mockup.tsx | 14 +- .../calculator-mockups/search-page-mockup.tsx | 2 +- .../show-all-directions-mockup.tsx | 4 +- src/components/calculators/bedside-sheet.tsx | 2 +- .../calculators/clinical-console.tsx | 2 +- src/components/calculators/guided-flow.tsx | 6 +- src/components/calculators/search-detail.tsx | 14 +- src/components/calculators/search-page.tsx | 2 +- .../clinical-dashboard/ClinicalSidebar.tsx | 4 +- .../clinical-dashboard/answer-status.tsx | 36 +- .../clinical-dashboard/auth-panel.tsx | 2 +- .../clinical-dashboard/differentials-home.tsx | 2 +- .../document-search-results.tsx | 2 +- .../favourites-command-library-page.tsx | 4 +- .../library-health-strip.tsx | 2 +- .../master-search-header.tsx | 6 +- .../medication-prescribing-workspace.tsx | 2 +- .../medication-record-page.tsx | 4 +- .../clinical-dashboard/settings-dialog.tsx | 2 +- .../differentials/diagnosis-map-panel.tsx | 4 +- .../differential-detail-page.tsx | 4 +- .../differential-presentation-actions.tsx | 2 +- ...ifferential-presentation-workflow-page.tsx | 2 +- .../document-navigation-contract-mockups.tsx | 6 +- .../document-navigation-final-mockups.tsx | 6 +- ...cument-navigation-final-review-mockups.tsx | 6 +- .../document-navigation-pane-mockups.tsx | 2 +- .../document-navigation-perfected-mockups.tsx | 6 +- ...ocument-phone-fused-directions-mockups.tsx | 2 +- .../document-phone-title-mockups.tsx | 2 +- .../document-phone-title-refined-mockups.tsx | 2 +- .../document-phone-zero-chrome-mockups.tsx | 2 +- src/components/document-search-mockups.tsx | 6 +- .../document-top-navigation-mockups.tsx | 2 +- src/components/dsm/dsm-comparison-page.tsx | 2 +- src/components/dsm/dsm-diagnosis-page.tsx | 2 +- .../dsm-differential-considerations-page.tsx | 4 +- .../factsheets-compact-view-mockups.tsx | 6 +- .../factsheets/factsheets-search-page.tsx | 2 +- .../filter-sheet-restyle-mockups.tsx | 2 +- .../formulation/formulation-builder-page.tsx | 2 +- .../formulation/formulation-home-page.tsx | 2 +- .../formulation/formulation-map-page.tsx | 2 +- .../master-document-flow-mockups.tsx | 16 +- src/components/mode-home-template.tsx | 4 +- .../phone-mode-sheet-yes-mockups.tsx | 6 +- src/components/primitive-recipes/clinical.tsx | 171 ++++ src/components/primitive-recipes/composer.ts | 43 + src/components/primitive-recipes/feedback.tsx | 411 ++++++++++ src/components/primitive-recipes/recipes.ts | 147 ++++ src/components/registry-record-loader.tsx | 2 +- .../services-filter-options-mockups.tsx | 2 +- src/components/sidebar-live-mockup.tsx | 2 +- .../specifiers/specifier-map-page.tsx | 2 +- src/components/specifiers/specifier-ui.tsx | 2 +- .../specifiers/specifiers-home-page.tsx | 2 +- .../screens/compare-screen.tsx | 2 +- .../therapy-navigation-mockups/shared.tsx | 2 +- .../rectangle-direction-mockups.tsx | 8 +- .../split-pane-refined-mockups.tsx | 2 +- .../tools-page-mockup-page.tsx | 4 +- .../tools-search-directions-mockups.tsx | 4 +- src/components/ui-primitives.tsx | 764 +----------------- src/components/ui/answer-card.tsx | 2 +- src/components/ui/applied-filters.tsx | 91 +++ src/components/ui/catalogue-toolbar.tsx | 52 +- src/components/ui/copy-button.tsx | 61 ++ tests/applied-filters.dom.test.tsx | 47 ++ ...clinical-dashboard-merge-artifacts.test.ts | 4 +- tests/copy-button.dom.test.tsx | 43 + tests/dashboard-degraded-notice.dom.test.tsx | 3 +- tests/decoration-on-text.contract.test.ts | 4 +- tests/design-sync-contract.test.ts | 2 + tests/design-system-adoption.test.ts | 7 + tests/design-system-contract-utils.test.ts | 59 ++ tests/disabled-encoding.contract.test.ts | 16 +- tests/search-shell-focus.contract.test.ts | 3 +- tests/status-semantics-contract.test.ts | 10 +- tests/ui-overlay-css-contract.test.ts | 4 +- tests/ui-style-contract.spec.ts | 92 +++ tests/ui-visual-baseline.spec.ts | 5 + 106 files changed, 1728 insertions(+), 1108 deletions(-) create mode 100644 src/components/primitive-recipes/clinical.tsx create mode 100644 src/components/primitive-recipes/composer.ts create mode 100644 src/components/primitive-recipes/feedback.tsx create mode 100644 src/components/primitive-recipes/recipes.ts create mode 100644 src/components/ui/applied-filters.tsx create mode 100644 src/components/ui/copy-button.tsx create mode 100644 tests/applied-filters.dom.test.tsx create mode 100644 tests/copy-button.dom.test.tsx diff --git a/data/repo-awareness-snapshot.json b/data/repo-awareness-snapshot.json index 76d2fceb1e..3b7fa3cc68 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": "3e4f966015b826e0f84e3f1439e9e751f237fc1f", - "committed_at": "2026-08-27T07:49:35+00:00" + "sha": "32652318b43b7d28a3e230d773f4821951a05591", + "committed_at": "2026-08-27T16:40:06+08: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 1f29f11b69..1e3d445818 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 | 17 | +| `Button` | controls | yes | yes | inherited-global-root | yes | no | 19 | | `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 `