@nurix/etna 0.19.2 → 0.19.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/code/CLAUDE.md +2 -2
  3. package/data/harnesses/code/harness.json +2 -2
  4. package/data/harnesses/code/rules/frontend.md +3 -3
  5. package/data/harnesses/code/skills/design/SKILL.md +20 -8
  6. package/data/harnesses/code/skills/design/data/catalog/rules.csv +10 -5
  7. package/data/harnesses/code/skills/design/data/combinations/Readme.md +8 -4
  8. package/data/harnesses/code/skills/design/data/combinations/accent-presets.md +113 -0
  9. package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +11 -0
  10. package/data/harnesses/code/skills/design/data/combinations/manifest.json +57 -10
  11. package/data/harnesses/code/skills/design/data/combinations/motion.csv +10 -0
  12. package/data/harnesses/code/skills/design/data/combinations/palettes.csv +92 -49
  13. package/data/harnesses/code/skills/design/data/combinations/styles.csv +67 -54
  14. package/data/harnesses/code/skills/design/data/combinations/typography.csv +64 -61
  15. package/data/harnesses/code/skills/design/data/design-md/library/expo.md +4 -4
  16. package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +5 -5
  17. package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +6 -6
  18. package/data/harnesses/code/skills/design/data/design-md/library/notion.md +4 -4
  19. package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +4 -4
  20. package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +2 -2
  21. package/data/harnesses/code/skills/design/data/design-md/library/slack.md +6 -6
  22. package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +5 -5
  23. package/data/harnesses/code/skills/design/data/design-md/nurix.md +11 -7
  24. package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +256 -141
  25. package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +309 -1
  26. package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +309 -1
  27. package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +309 -1
  28. package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +309 -1
  29. package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +309 -1
  30. package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +309 -1
  31. package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +313 -1
  32. package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +309 -1
  33. package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +309 -1
  34. package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +309 -1
  35. package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +309 -1
  36. package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +309 -1
  37. package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +309 -1
  38. package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +313 -1
  39. package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +309 -1
  40. package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +313 -1
  41. package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +309 -1
  42. package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +123 -123
  43. package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +309 -1
  44. package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +309 -1
  45. package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +309 -1
  46. package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +313 -1
  47. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +1 -1
  48. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +10 -0
  49. package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +309 -1
  50. package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +313 -1
  51. package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +313 -1
  52. package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +309 -1
  53. package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +309 -1
  54. package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +313 -1
  55. package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +309 -1
  56. package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +313 -1
  57. package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +309 -1
  58. package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +307 -2
  59. package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +309 -1
  60. package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +309 -1
  61. package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +309 -1
  62. package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +309 -1
  63. package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +309 -1
  64. package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +309 -1
  65. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +1 -1
  66. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +10 -0
  67. package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +309 -1
  68. package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +309 -1
  69. package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +310 -2
  70. package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +313 -1
  71. package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +309 -1
  72. package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +309 -1
  73. package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +309 -1
  74. package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +309 -1
  75. package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +313 -1
  76. package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +313 -1
  77. package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +309 -1
  78. package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +313 -1
  79. package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +309 -1
  80. package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +309 -1
  81. package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +313 -1
  82. package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +309 -1
  83. package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +309 -1
  84. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +1 -1
  85. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +10 -0
  86. package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +309 -1
  87. package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +309 -1
  88. package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +309 -1
  89. package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +309 -1
  90. package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +309 -1
  91. package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +309 -1
  92. package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +309 -1
  93. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +25 -25
  94. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +18 -18
  95. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +82 -105
  96. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +97 -93
  97. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +16 -15
  98. package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +34 -34
  99. package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +5 -5
  100. package/data/harnesses/code/skills/design/references/create.md +49 -7
  101. package/data/harnesses/code/skills/design/references/diagnosis.md +3 -3
  102. package/data/harnesses/code/skills/design/references/hard-rules.md +25 -3
  103. package/data/harnesses/code/skills/design/references/improve.md +32 -3
  104. package/data/harnesses/code/skills/design/references/interaction.md +3 -3
  105. package/data/harnesses/code/skills/design/references/introspect.md +1 -1
  106. package/data/harnesses/code/skills/design/references/lifecycle.md +2 -2
  107. package/data/harnesses/code/skills/design/references/personality.md +280 -133
  108. package/data/harnesses/code/skills/design/references/structure.md +22 -1
  109. package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +306 -26
  110. package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +596 -104
  111. package/data/harnesses/code/skills/design/scripts/lib/checks.mjs +200 -11
  112. package/data/harnesses/code/skills/design/scripts/lib/vocabulary.mjs +65 -0
  113. package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +95 -11
  114. package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +50 -5
  115. package/data/harnesses/code/skills/design/scripts/render-rung.mjs +214 -14
  116. package/data/harnesses/code/skills/design/scripts/scaffold.mjs +242 -25
  117. package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +81 -6
  118. package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +101 -5
  119. package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +142 -17
  120. package/data/harnesses/etna/CLAUDE.md +1 -1
  121. package/data/harnesses/etna/harness.json +2 -2
  122. package/package.json +1 -1
@@ -22,7 +22,7 @@ This is the default archetype for the operator's primary entity — the queue sh
22
22
 
23
23
  **Density modifier.** At tier — the reference archetype. The global tier is calibrated on the operator's primary table, so list-detail runs at it unmodified.
24
24
 
25
- **Composition.** Toolbar (search, filters, bulk actions, column/view picker) + a virtualized table + a side-panel detail. Detail opens **beside** the table, never in a modal (floor P3). Bounded visible columns (rest behind the picker), right-aligned numerics in tabular figures (floor P4), sticky header, bounded pagination ("1–25 of 150") over infinite scroll, virtualization at ≥50 rows. Keyboard-first (floor P6): roving tabindex, arrow/j-k row travel, Enter opens the panel, shortcuts for the frequent verbs. Lifecycle states that matter most: **empty** (first-run vs filtered-to-nothing kept distinct), **loading** (skeleton rows mirroring the table, not a centered spinner), **partial/degraded** (stale rows marked honestly), and the per-row action's post-action state with optimistic-update-then-rollback.
25
+ **Composition.** Toolbar (search, filters, bulk actions, column/view picker) + a virtualized table + a side-panel detail. Detail opens **beside** the table, never in a modal (floor f03). Bounded visible columns (rest behind the picker), right-aligned numerics in tabular figures (floor f04), sticky header, bounded pagination ("1–25 of 150") over infinite scroll, virtualization at ≥50 rows. Keyboard-first (floor f06): roving tabindex, arrow/j-k row travel, Enter opens the panel, shortcuts for the frequent verbs. Lifecycle states that matter most: **empty** (first-run vs filtered-to-nothing kept distinct), **loading** (skeleton rows mirroring the table, not a centered spinner), **partial/degraded** (stale rows marked honestly), and the per-row action's post-action state with optimistic-update-then-rollback.
26
26
 
27
27
  **Navigation.** A top-level nav item per primary entity collection — the queues and tables the operator lives in; the default landing for that entity. Detail is not a nav item; it is a panel state on the list route.
28
28
 
@@ -42,7 +42,7 @@ Selects on an overview / home / summary brief. Distinguish from command-center:
42
42
 
43
43
  **Density modifier.** One step looser — a dashboard is a glanceable aggregate; KPI cards and charts need whitespace to separate and read at a glance, not row-scan density.
44
44
 
45
- **Composition.** A KPI / StatCard row at the top (≤4 primary metrics visible without scrolling — answer a few questions well, not many badly) + a small number of self-contained chart/panel tiles below, each a single question with a drill link. Hierarchy from spacing, not borders. Tabular figures on every KPI number (floor P4); charts read `--chart-1..5`; color is never the only signal. Lifecycle states that matter most: **loading** (per-card skeletons, never one page spinner), **partial/degraded** (a downed source names *which* panel is stale — "can't get data" is distinct from "no data"), **empty** (new-tenant zero-state that teaches the surface's value).
45
+ **Composition.** A KPI / StatCard row at the top (≤4 primary metrics visible without scrolling — answer a few questions well, not many badly) + a small number of self-contained chart/panel tiles below, each a single question with a drill link. Hierarchy from spacing, not borders. Tabular figures on every KPI number (floor f04); charts read `--chart-1..5`; color is never the only signal. Lifecycle states that matter most: **loading** (per-card skeletons, never one page spinner), **partial/degraded** (a downed source names *which* panel is stale — "can't get data" is distinct from "no data"), **empty** (new-tenant zero-state that teaches the surface's value).
46
46
 
47
47
  **Navigation.** The home/overview landing — typically the app root or the first nav item. It is a hub that links out; never a leaf. Its panels' drill targets are the list-detail and entity-detail routes.
48
48
 
@@ -62,7 +62,7 @@ Distinguish from list-detail: list-detail's detail is a lightweight row projecti
62
62
 
63
63
  **Density modifier.** At tier — it mixes dense read views (related lists, activity) with edit forms, so it sits at the global tier: neither a scan surface nor a pure form.
64
64
 
65
- **Composition.** Header (entity identity, status, primary actions) + a tab bar (overview / related collections / activity-history) + tabbed content. Related lists render as compact list-details inline; editing happens in place or opens the create-edit stepper beside the work (floor P3). Lifecycle states that matter most: **loading** (skeleton mirroring the header + tab shell), **error** (entity-not-found / load-failure with a recovery path, never a dead end), the edit **save states** (saving / saved / conflict — the concurrent-edit path from the temporal probe), and per-tab **empty** states.
65
+ **Composition.** Header (entity identity, status, primary actions) + a tab bar (overview / related collections / activity-history) + tabbed content. Related lists render as compact list-details inline; editing happens in place or opens the create-edit stepper beside the work (floor f03). Lifecycle states that matter most: **loading** (skeleton mirroring the header + tab shell), **error** (entity-not-found / load-failure with a recovery path, never a dead end), the edit **save states** (saving / saved / conflict — the concurrent-edit path from the temporal probe), and per-tab **empty** states.
66
66
 
67
67
  **Navigation.** Not a top-level nav item — reached by drilling from its list-detail (row → entity route), a dashboard, or a command-center link. Route nests under the entity's collection (`/entities/:id`); its tabs are in-surface sub-nav, never top-level entries.
68
68
 
@@ -81,7 +81,7 @@ Create mirrors edit — the same field set and order; templates prefill. Disting
81
81
 
82
82
  **Density modifier.** One step looser — forms need field breathing room and comfortable target sizes; loosening cuts entry error on a surface where mistakes are costly.
83
83
 
84
- **Composition.** A side-stepper opened **beside** the originating surface (floor P3), or a full form route for long creates. Labels above inputs; errors inline below the field, validated on blur; never placeholder-as-label. Logical field order preserved; one primary CTA bottom-right; primary targets ≥44px. Preview-then-commit for irreversible creates. Lifecycle states that matter most: **validation** (inline, on blur — diagnose → explain → recover), **submitting** (button loading, double-submit disabled), **server-error** (non-dead-end, entered values preserved), **success** (confirmation plus the next step).
84
+ **Composition.** A side-stepper opened **beside** the originating surface (floor f03), or a full form route for long creates. Labels above inputs; errors inline below the field, validated on blur; never placeholder-as-label. Logical field order preserved; one primary CTA bottom-right; primary targets ≥44px. Preview-then-commit for irreversible creates. Lifecycle states that matter most: **validation** (inline, on blur — diagnose → explain → recover), **submitting** (button loading, double-submit disabled), **server-error** (non-dead-end, entered values preserved), **success** (confirmation plus the next step).
85
85
 
86
86
  **Navigation.** Never a top-level nav item — invoked from a list-detail toolbar ("New") or an entity-detail action, and it returns to that surface on complete. A create route may exist (`/entities/new`) but is entered from the collection, not from the nav.
87
87
 
@@ -100,7 +100,7 @@ Selects on a log / event / audit / activity-feed entity — high volume, time-ke
100
100
 
101
101
  **Density modifier.** One step denser — the value of the surface is lines-on-screen; tighten to maximize visible history under one glance.
102
102
 
103
- **Composition.** Filter/search bar + a follow/tail toggle (live vs paused) + a virtualized monospace line list, with inline expansion of a selected line (expand in place, not a modal). Tabular timestamps and IDs (floor P4), level-coded severity via status tokens with a second non-color cue, hairline dividers, minimal chrome. Lifecycle states that matter most: **streaming/live** (new lines announced via `aria-live` without stealing focus), **empty** (no events yet vs filtered-to-nothing, kept distinct), **error** (stream disconnected shows reconnecting, never a dead spinner), **partial/degraded** (dropped or truncated buffer marked honestly).
103
+ **Composition.** Filter/search bar + a follow/tail toggle (live vs paused) + a virtualized monospace line list, with inline expansion of a selected line (expand in place, not a modal). Tabular timestamps and IDs (floor f04), level-coded severity via status tokens with a second non-color cue, hairline dividers, minimal chrome. Lifecycle states that matter most: **streaming/live** (new lines announced via `aria-live` without stealing focus), **empty** (no events yet vs filtered-to-nothing, kept distinct), **error** (stream disconnected shows reconnecting, never a dead spinner), **partial/degraded** (dropped or truncated buffer marked honestly).
104
104
 
105
105
  **Navigation.** A top-level nav item when logs/audit/activity is a primary operator surface; otherwise a tab inside the owning entity-detail (that entity's activity/history). Time-keyed, so deep-links carry a timestamp or anchor.
106
106
 
@@ -16,27 +16,58 @@ The gate closing each phase runs the D21 rule classes decidable at that boundary
16
16
 
17
17
  ## intake
18
18
 
19
- **Purpose.** Recognize the brief, decide pack coverage, extract intent, resolve the look.
20
- **In → out.** the brief · the design.md library · `data/combinations/product-router.csv` (+ `typography.csv` · `palettes.csv` · `styles.csv` when the look is authored fresh) → a confirmed intent digest · a design-tokens artifact at project root (`design.tokens.json` + `design.resolver.json` — the look + lever manifest).
21
- **Work.** Front gate: a project-declared identity (product-type traits) wins; otherwise the signal checklist (audience is employees / agents / analysts; the metric is task throughput, not conversion; the surfaces are queues / tables / forms / monitors), with `data/combinations/product-router.csv` — loaded at every intake — as the recognition assist and the digest's density/archetype priors. Build a structured intent digest — entity list, archetype guesses, density tier, substrate — every inference marked as inferred, present it once for confirmation, and ask only strategic unknowns whose answers change the design. Resolve the look project-first: the project's own artifact wins; a library entry serves on propose-confirm (proposed from resemblance, never applied silently); zero input wears the Nurix default. When the look resolves to authoring a fresh artifact — not a library copy, not the default — load `typography.csv`, `palettes.csv`, and `styles.csv` (pairings, palettes, movement vocabulary) before composing it; the consumption contract is [combinations/Readme.md](../data/combinations/Readme.md). Materialize the resolved artifact at project root against [SCHEMA.md](../data/design-tokens/SCHEMA.md).
22
- **Gate — `phase-gate.mjs intake`.** The digest is confirmed and a schema-valid token artifact exists at project root. A brief no pack covers is refused here — cleanly, with a redirect — never derived.
19
+ **Purpose.** Recognize the brief, decide pack coverage, extract intent, resolve the look — its direction, its source, and its delight ceiling.
20
+ **In → out.** the brief · the design.md library · `data/combinations/product-router.csv` (+ `typography.csv` · `palettes.csv` · `styles.csv` when the look is authored fresh) · `docs/design/taste.yml` → a confirmed intent digest carrying the look block · a design-tokens artifact at project root (`design.tokens.json` + `design.resolver.json` — the look + lever manifest).
21
+ **Work.** Front gate: a project-declared identity (product-type traits) wins; otherwise the signal checklist (audience is employees / agents / analysts; the metric is task throughput, not conversion; the surfaces are queues / tables / forms / monitors), with `data/combinations/product-router.csv` — loaded at every intake — as the recognition assist and the digest's density/archetype priors. Build a structured intent digest — entity list, archetype guesses, density tier, substrate, **and the mandatory look block** (below) — every inference marked as inferred, present it once for confirmation, and ask only strategic unknowns whose answers change the design. Fold look-relevant brief language into the taste profile (below) as you read it. Resolve the look through the precedence spine — **project > library (on match) > seed composition > default**, never applied unrecorded (Resolution, below): the project's own artifact wins; a library entry or a fresh seed composition is proposed-and-confirmed (interactive) or resolved-and-recorded (autonomous); `default` — the Nurix look — resolves only when the brief explicitly asks for it. When the look resolves to authoring a fresh artifact — not a library copy, not the default — load `typography.csv`, `palettes.csv`, and `styles.csv` before composing it; the consumption contract is [combinations/Readme.md](../data/combinations/Readme.md). Materialize the resolved artifact at project root against [SCHEMA.md](../data/design-tokens/SCHEMA.md) — the look block in its payload, and for a recorded resolution the resolution record in the artifact root `$description`.
22
+ **Gate — `phase-gate.mjs intake`.** The digest is confirmed and a schema-valid token artifact exists at project root, carrying a well-formed **look block** — presence, the theme / delight / resolution-mode enums, 2–3 named anchors, the resolution shape, and (for a recorded resolution) the resolution record in the artifact root `$description`. A brief no pack covers is refused here — cleanly, with a redirect — never derived.
23
23
  **Avoid.**
24
24
  - Deriving on silently inferred facts instead of presenting the digest for one confirmation.
25
25
  - Blanket-interviewing when the brief already declares its identity — ask only strategic unknowns.
26
26
  - Attempting a marketing / storefront / mobile-native brief instead of refusing on pack coverage.
27
27
  - Authoring a fresh look without `typography.csv` / `palettes.csv` / `styles.csv` in context — a gate violation.
28
+ - Filling `anchors` with adjectives instead of 2–3 named products — the gate rejects it; convert them first.
29
+ - Applying a resolution unrecorded — an autonomous pick writes its record into the artifact root `$description`, or the gate fails.
30
+
31
+ ### The look block
32
+
33
+ The intent digest carries a mandatory **look block**, filled at intake beside the entity / archetype / density fields:
34
+
35
+ ```yaml
36
+ look:
37
+ theme: light | dark | both # binding when the brief states it; default light
38
+ anchors: ["Linear", "Stripe Dashboard"] # 2–3 NAMED real products; adjectives are not anchors
39
+ delight: baseline | expressive # the global delight ceiling; per-surface budgets refine it
40
+ resolution: project | library:<slug> | seed:<style-row>+<palette-row> | default
41
+ resolution-mode: confirmed | recorded # how the resolution was authorized (below)
42
+ ```
43
+
44
+ - **`theme` is binding.** A brief-stated theme writes the payload's `theme-default`, the resolver's default context, and scaffold's `<html data-theme>`; `both` ships light-boot with a working toggle, `dark` ships dark-boot. Default light when the brief is silent.
45
+ - **`anchors` are named products, required.** Two or three real products pin the gestalt at the direction moment — unnamed ambition drifts to beige, and ~10 tokens of product names carry what a thousand adjective-words cannot. Adjectives are not anchors: convert an adjective to its nearest named products by **asking** (interactive) or **inferring-and-recording** (autonomous) through the [design.md library](../data/design-md/library/)'s resemblance lookup, then record the named products. Anchors land in the payload so improve and `judge` critique against the same targets the run aimed at.
46
+ - **Anchors work twice.** At resolution they drive the resemblance lookup; at the surfaces phase the anchor products' design.md entries JIT-load so composition leans toward the anchor's gestalt — composition is anchor-*steered*, not exemplar-cloned.
47
+
48
+ ### Resolution — propose-and-record
49
+
50
+ The precedence spine serves both session modes and is **never applied unrecorded**.
51
+
52
+ - **Interactive** (a confirmer is present): propose-confirm — the resolved source is proposed from resemblance and applied only on confirmation, never silently.
53
+ - **Autonomous** (the digest's one confirmation round goes unanswered, or the brief forbids questions): resolve the best match, set `resolution-mode: recorded`, and write the **resolution record** into the artifact root `$description` — the winner, the runner-up, and the deciding evidence. For example: `resolution: library:stripe (recorded; runner-up palettes.csv#3; brief phrase "Stripe-dashboard territory" matched product + fintech traits)`. The record is auditable and reversible — an improve run can be pointed at the runner-up by consent. Nothing is silent; nothing dead-ends.
54
+
55
+ **Selection is brief-keyed, never mood-keyed.** Route before judging: extract the brief's traits (domain, product type, tone words) → filter `product-router.csv` by product type and theme → a 2–3-row shortlist enters context with its `mood` prose → pick, the record naming the runner-up. Same brief → same shortlist; different domains → different pools — divergence by construction, not by model mood. `default` resolves only when the brief explicitly asks for the Nurix look; a look-less brief always composes from seeds through this routing. The taste profile biases the pick once it has content.
56
+
57
+ **Seed composition partitions, never contests.** A fresh artifact composes from the routed rows by domain: the **palette** row contributes color, the **typography** row type, the **style** row treatment (`css-recipe` + `tokens-hint` + the non-token `voice`). Out-of-domain content in a row — a style row's color suggestion — is advisory prose for the composer, never a value source, so no two seeds can contest the same value. The composer closes with a deliberate **best-fit harmony pass**: do the palette, type, and treatment read as one hand, for *this* user — the taste profile is in context? Harmony is judged, not mechanical; no link exists between the dimension tables.
28
58
 
29
59
  ## structure
30
60
 
31
61
  **Purpose.** Derive the app's structure from its domain objects — never guess it.
32
62
  **In → out.** the confirmed intent digest → `docs/design/structure.md` with its fenced `yaml structure` block.
33
- **Work.** The object pass: entities, attributes, relationships, cardinalities, lifecycle states; the operator's unit of work and core loop. The **temporal probe runs inside the pass** — intermediate states, read-model lag, deletion semantics, history, failure paths — because they are model facts, not later polish. Then assign each surface an archetype from the closed six-catalog (`list-detail`, `dashboard`, `entity-detail`, `create-edit`, `log-stream`, `command-center`) with its density modifier — see [surface-catalog.md](../data/operator-pack/surface-catalog.md). Navigation derives from the object model; it is never decorated onto it. The OOUX failure vocabulary (Shapeshifter / Masked / Broken / Isolated) is the judged diagnostic — see [structure.md](./structure.md).
63
+ **Work.** The object pass: entities, attributes, relationships, cardinalities, lifecycle states; the operator's unit of work and core loop. The **temporal probe runs inside the pass** — intermediate states, read-model lag, deletion semantics, history, failure paths — because they are model facts, not later polish. Then assign each surface an archetype from the closed six-catalog (`list-detail`, `dashboard`, `entity-detail`, `create-edit`, `log-stream`, `command-center`) with its density modifier — see [surface-catalog.md](../data/operator-pack/surface-catalog.md). The pass also classifies **every surface with a mandatory delight `budget`** (`baseline` / `brand-forward`) — permission is structural, decided here; defaults by archetype, overridable against a recorded reason — see [structure.md](./structure.md) (the delight budget). `scaffold.mjs` stamps the budget into each route file and `phase-gate.mjs surfaces` reads it back. Navigation derives from the object model; it is never decorated onto it. The OOUX failure vocabulary (Shapeshifter / Masked / Broken / Isolated) is the judged diagnostic — see [structure.md](./structure.md).
34
64
  **Gate — `phase-gate.mjs structure`.** The map parses; every surface carries an archetype from the catalog; the `temporal` block is present. `scaffold.mjs` consumes this block, so its shape is validated here.
35
65
  **Avoid.**
36
66
  - Skipping the object pass on a small brief — a small brief earns a proportionally small pass, never a skipped one; the skip is the characteristic failure.
37
67
  - Decorating navigation onto the UI instead of deriving it from the object model.
38
68
  - Omitting the temporal probe — intermediate states and failure paths are model facts, not afterthoughts.
39
69
  - Inventing an archetype outside the closed six.
70
+ - Leaving a surface's delight budget to chance — classify every surface, and record the reason whenever a stamp overrides its archetype's default (caught at the surfaces gate).
40
71
 
41
72
  ## scaffold
42
73
 
@@ -53,7 +84,7 @@ The gate closing each phase runs the D21 rule classes decidable at that boundary
53
84
 
54
85
  **Purpose.** Emit the complete token surface from the resolved artifact.
55
86
  **In → out.** the design-tokens artifact → `src/styles/personality.css` + `src/styles/globals.css`.
56
- **Work.** Derivation is hybrid: deterministic where the artifact states a value, judgment-with-recorded-rationale for gaps (a resolved hint records its rationale in the token's `$description`). Before any typography hint is resolved, `data/combinations/typography.csv` is in context; before any color hint, `palettes.csv` — the table is the floor for the resolution, and an off-table pairing or palette is allowed only with its stated reason recorded in the token's `$description`. The **coverage gate** `derive-personality.mjs <project-dir> --check` fails — exit non-zero, naming the missing paths — if any of the 26 visual primitives, the 2 behavioral dials, or the emission tokens is unassigned and un-hinted. Only once it is green does `derive-personality.mjs <project-dir> --emit <project-dir>` write both files (into `<project-dir>/src/styles/`), defining the full surface — 26 primitives, 17 semantic tokens, and the 17 substrate tokens no consumable value is left to fall back to gray on — and hardening both cascade contracts (selector specificity, import order) with explanatory comments. See [personality.md](./personality.md).
87
+ **Work.** Derivation is hybrid: deterministic where the artifact states a value, judgment-with-recorded-rationale for gaps (a resolved hint records its rationale in the token's `$description`). Before any typography hint is resolved, `data/combinations/typography.csv` is in context; before any color hint, `palettes.csv` **and `accent-presets.md`** — the routed-consult contract. The look's theme filters the consult: a `dark` look narrows the palette pool to dark-capable rows (`theme` column `dark` / `both`), and composing a dark look from a light-only row is off-table and needs a recorded reason. The taste profile sits in context beside the rows, biasing the pick. The table is the floor for the resolution, and an off-table pairing or palette is allowed only with its stated reason recorded in the token's `$description`. The **coverage gate** `derive-personality.mjs <project-dir> --check` fails — exit non-zero, naming the missing paths — if any of the 26 visual primitives, the 2 behavioral dials, or the emission tokens is unassigned and un-hinted. Only once it is green does `derive-personality.mjs <project-dir> --emit <project-dir>` write both files (into `<project-dir>/src/styles/`), defining the full surface — 27 primitives, 17 semantic tokens, and the 17 substrate tokens no consumable value is left to fall back to gray on — and hardening both cascade contracts (selector specificity, import order) with explanatory comments. See [personality.md](./personality.md).
57
88
  **Gate — `phase-gate.mjs tokens`.** The coverage gate passed and both files carry the full token surface with the cascade-contract comments intact.
58
89
  **Avoid.**
59
90
  - Emitting before the coverage gate passes.
@@ -82,6 +113,8 @@ The gate closing each phase runs the D21 rule classes decidable at that boundary
82
113
  **In → out.** the state-shells · the fixtures · the emitted tokens · the archetype exemplar → composed `src/routes/<surface>/` surfaces, every state present.
83
114
  **Work.** For each surface, compose in the `@nurix/components` idiom (imported by subpath) against the resolved tokens — the look comes entirely from the cascade, never from literals. Fill every lifecycle state into its pre-created shell; states are composed with the surface, not bolted on after. AI-bearing surfaces clear the [trust rubric](../data/operator-pack/trust-rubric.md); microcopy follows the error and empty-state formulas in [lifecycle.md](./lifecycle.md); keyboard and focus discipline follow [interaction.md](./interaction.md).
84
115
 
116
+ > **The budget is a grant, not only a ban.** Read each surface's stamped delight budget ([structure.md](./structure.md), the delight budget) as permission, not just a ceiling: a brand-forward dashboard *uses* the display step on its focal metric, an elevation lift on its hero card, an arrival stagger on its rows — a page of uniform 14px text ignores its budget. A baseline surface withholds ornament, never signal. The budget grants which vocabulary a surface may consume; the floor holds identically at every budget.
117
+
85
118
  > **Just-in-time exemplar.** Each archetype's token-pure exemplar ([exemplars/](../data/operator-pack/exemplars/)) loads just-in-time at that archetype's emission gate — never at boot — because imitation proximity is highest when the exemplar sits in context at the moment of composition. Composing a surface of archetype X without exemplar X in context is a **gate violation**. Imitate the composition; the look comes from the project's personality.
86
119
 
87
120
  > **Just-in-time combination tables.** `data/combinations/charts.csv` loads at the emission gate of any surface that composes a chart; `icons.csv` loads once, at the first surface-composition gate — icon picks happen throughout. Each table is the floor for its picks: an off-table chart type or icon is allowed only with its stated reason in a code comment adjacent to the deviating pick. An unrecorded off-table pick is a **gate violation**. Contract: [combinations/Readme.md](../data/combinations/Readme.md).
@@ -92,7 +125,7 @@ The gate closing each phase runs the D21 rule classes decidable at that boundary
92
125
  - Composing a chart or picking an icon without its combination table in context — a gate violation.
93
126
  - Writing states as an afterthought instead of into the pre-created shells.
94
127
  - Emitting a look disjoint from the resolved personality — literals or off-scale values instead of the cascade.
95
- - Modals where side panels belong; a workflow a pointer alone can complete (floor P3 / P6).
128
+ - Modals where side panels belong; a workflow a pointer alone can complete (floor f03 / f06).
96
129
 
97
130
  ## verification
98
131
 
@@ -102,6 +135,15 @@ The gate closing each phase runs the D21 rule classes decidable at that boundary
102
135
 
103
136
  ---
104
137
 
138
+ ## The taste profile — the standing input
139
+
140
+ A **project taste profile** rides with the consumer project at `docs/design/taste.yml` (beside the judge reports) — per-dimension summaries of the user's expressed taste (`overall`, `typography`, `color`, `density`, `motion`, `dark`), each a short `feel` line plus an `avoid` line. It is **intent, never values**: the token artifact stays the only value transport; the profile biases picks, it never sets them. It is YAML because the file is human-facing intent — prose summaries plus an explanatory header comment.
141
+
142
+ - **Captured** at intake (look-relevant brief language folds in) and whenever the user reacts to shipped output — an accepted or rejected finding, an improve consent round, a "too showy". The relevant item updates or a new one lands; provenance folds into the prose ("asked twice for tighter headings"), never into machine fields.
143
+ - **Consumed** at resolution (it biases the shortlist pick; the resolution record cites the taste items that drove it) and at the color / type moment (in context beside the seed rows). `judge` critiques against it as a fixed referent.
144
+ - **Reset** serves a deliberate style switch: an explicit flow re-asks the taste questions dimension by dimension and rewrites the items in place. The file is never deleted — switching styles is a re-interview, never a silent fall back to no-profile behavior.
145
+ - **Fail-open.** A missing or malformed `taste.yml` degrades to no-profile behavior with a one-line notice — never a crash, never a block. The profile is a bias; a bias that cannot be read cleanly is simply not applied.
146
+
105
147
  ## The preservation contract
106
148
 
107
149
  Two disciplines protect what must never silently change.
@@ -26,7 +26,7 @@ Eight fields, fixed. Every finding carries all eight, machine or judged.
26
26
 
27
27
  - **dimension** — which of the sixteen. Names *what* is wrong.
28
28
  - **cause layer** — Structure, Behavior, or Perception. Names *where the fix lives* — the meta-layer of the root, which often differs from the dimension's own layer (a felt Perception problem rooted in a Structure fact).
29
- - **evidence** — the anchor in the code: `file:line`, a token name, or a measured value. Never a vibe.
29
+ - **evidence** — the anchor in the code: `file:line`, a token name, or a measured value; for a rendered-evidence finding (a `judge` run — [improve.md](improve.md)), a screenshot path + the region within it (`shots/1440.png · header row, right cluster`). Never a vibe.
30
30
  - **before → after** — the current state → the corrected state. Numeric where machine-backed (a value → its threshold); a concrete, measurable state change where judged. Never "make it cleaner."
31
31
  - **consequence** — what it costs the operator: lost throughput, eroded trust, an unreadable figure, an irreversible mistake.
32
32
  - **tier** — `within-levers` (fixable inside the current lever manifest) or `lever-change` (needs a manifest change). The [improve.md](improve.md) jail reads this.
@@ -77,7 +77,7 @@ The render rung computes deterministic numbers (`inst-*`) over the rendered surf
77
77
 
78
78
  The load-bearing caution: **dense operator surfaces are dense on purpose.** "Lower visual complexity ⇒ better" was refuted 0–3 in adversarial verification; on an information-dense surface the sign of "good" can invert. A high instrument number is a prompt to *look*, never proof of a problem, and a threshold is never derived from an exemplar (circular). Start with edge density — cheapest, best-documented — and treat every reading as a signal.
79
79
 
80
- **KLM operator-cost** (`inst-11`): a comparative throughput diagnosis, not ground truth. Sum the typed operators over a fixed core-loop path with the published constants — **P (point) 1.10s · H (home hand between keyboard and mouse) 0.40s · M (mental prep) 1.35s · K (keystroke) 0.20–0.28s** — counting clicks, keystrokes, tab-stops, and hand-homings. It compares two paths (before a redesign vs after, path A vs path B), pairing with the entity/surface map's core loop ([structure.md](structure.md)) and floor P1's throughput-first metric. It is a cost *model*: path selection is judgment, so the number is evidence for a judged B1/B4 finding, never a verdict.
80
+ **KLM operator-cost** (`inst-11`): a comparative throughput diagnosis, not ground truth. Sum the typed operators over a fixed core-loop path with the published constants — **P (point) 1.10s · H (home hand between keyboard and mouse) 0.40s · M (mental prep) 1.35s · K (keystroke) 0.20–0.28s** — counting clicks, keystrokes, tab-stops, and hand-homings. It compares two paths (before a redesign vs after, path A vs path B), pairing with the entity/surface map's core loop ([structure.md](structure.md)) and floor f01's throughput-first metric. It is a cost *model*: path selection is judgment, so the number is evidence for a judged B1/B4 finding, never a verdict.
81
81
 
82
82
  ## The AI-surface trust rubric
83
83
 
@@ -91,7 +91,7 @@ Quality is the skill's burden, never the user's — so decay is *observed*, not
91
91
  2. **Judged findings recurring across runs** — the same judged finding reappears on a later run, evidence the guidance is not being absorbed.
92
92
  3. **Guidance fought or produced wrong output** — the agent resisted a rule, or following the guidance yielded a worse result or collided with the user's workload.
93
93
 
94
- The ledger is **maintainer-facing telemetry, not runtime state** — the emitted UI stays the only design record (floor P8). The skill never reads it back and **never self-modifies**. The maintainer reads it, diagnoses whether the failure is the skill's design or the project's circumstances, and closes it by hand — updating the skill, or going back to the user.
94
+ The ledger is **maintainer-facing telemetry, not runtime state** — the emitted UI stays the only design record (floor f08). The skill never reads it back and **never self-modifies**. The maintainer reads it, diagnoses whether the failure is the skill's design or the project's circumstances, and closes it by hand — updating the skill, or going back to the user.
95
95
 
96
96
  Entries are **dated, factual, and human-closed** — append-only, oldest at bottom:
97
97
 
@@ -4,16 +4,33 @@ The hard-prose channel: every machine ban, deterministic threshold, and mandator
4
4
 
5
5
  The backticked anchor id is the shared key: the same id names the `rules.csv` row, the check-engine rule key, the fixture pair, and a finding's provenance. Machine rules are absolute — a violation is fixed now, or classified as inapplicable in `docs/memory/design-decay.md`; never ignored silently. No waivers, no inline suppressions. Lines tagged `· render` are decided on the rendered surface at the render rung (pixels or DOM), not from source at edit time. Judged dimensions are diagnosed, not gated — the index at the foot points at where their judgment lives.
6
6
 
7
+ ## Doctrine floor
8
+
9
+ The twelve fixed principles the rule families below serve — the canonical in-skill enumeration. Nothing overrides them: expressiveness is granted by the per-surface delight budget *inside* the floor, never as an exception to it. Cite a principle by its id.
10
+
11
+ - Throughput vs delight is weighed per surface (`f01`).
12
+ - Empty states are text-first (`f02`).
13
+ - Side panels over modals (`f03`).
14
+ - Numbers are tabular (`f04`).
15
+ - One accent is the default (`f05`).
16
+ - Keyboard-first (`f06`).
17
+ - Semantic token classes only (`f07`).
18
+ - State persists in emitted code (`f08`).
19
+ - Wrong-fit briefs are refused cleanly (`f09`).
20
+ - The substrate is Tailwind + shadcn-flavor only (`f10`).
21
+ - A modular SKILL.md router with lazy references (`f11`).
22
+ - Vocabulary is a business call (`f12`).
23
+
7
24
  ## Typography
8
25
 
9
26
  - `typ-01` Body text contrast ≥ 4.5:1; large text ≥ 3:1. · render
10
27
  - `typ-02` Body ≥ 14px on operator surfaces; never below 11px anywhere.
11
28
  - `typ-03` Form inputs ≥ 16px on touch/mobile surfaces; desktop operator inputs exempt.
12
29
  - `typ-05` Prose measure 45–75ch; tables exempt.
13
- - `typ-06` ≤ 2 font families per app; type scale holds ~6 distinct sizes.
30
+ - `typ-06` ≤ 3 font families per app, each with a distinct job (display / body / numeric-mono); a fourth family is banned. Type scale holds the declared ramp's steps (≤ 7).
14
31
  - `typ-07` Tabular lining numerals (`font-variant-numeric`) on every numeric column, KPI, timer, ID.
15
32
  - `typ-08` All-caps micro-labels: letter-spacing ≥ 0.02em (caps band 0.05–0.12em); tracking never below −0.04em.
16
- - `typ-09` Font sizes from a fixed rem scale (step ratio 1.125–1.2); ban `vw`/`vh`/`clamp` on font-size; operator surfaces.
33
+ - `typ-09` Font sizes from a fixed rem scale (step ratio 1.125–1.2) — the fixed scale is the declared ramp's emitted utilities (`text-h1` … `text-display`), not merely *a* scale; ban `vw`/`vh`/`clamp` on font-size; operator surfaces.
17
34
  - `typ-10` Adjacent type-scale steps ≥ 25% apart.
18
35
  - `typ-11` No UI font weight below 400.
19
36
  - `typ-12` Never size type in `em`; px or rem only.
@@ -22,6 +39,7 @@ The backticked anchor id is the shared key: the same id names the `rules.csv` ro
22
39
  - `typ-16` Ban serif faces in dashboards and software UIs.
23
40
  - `typ-18` Uppercase-tracking (eyebrow/micro-label) instances ≤ ceil(sectionCount/3).
24
41
  - `typ-19` Code/mono type fixed at 16px; long lines scroll horizontally, never wrap.
42
+ - `typ-20` The `display` ramp step appears only on surfaces stamped `brand-forward`; ≤ 1 display-step element per surface.
25
43
 
26
44
  ## Color
27
45
 
@@ -37,6 +55,7 @@ The backticked anchor id is the shared key: the same id names the `rules.csv` ro
37
55
  - `col-10` Modal scrim 40–60% black.
38
56
  - `col-13` Semantic price/status colors are text-only, never fills; never repurposed for generic success or error.
39
57
  - `col-14` Data-viz: lines/bars ≥ 3:1 vs background; data labels ≥ 4.5:1. · render
58
+ - `col-16` A wash token (`--wash-*`) is consumed only on `brand-forward`-stamped surfaces; wash stops obey the slop ban (`col-12` vocabulary).
40
59
 
41
60
  ## Spatial
42
61
 
@@ -50,6 +69,7 @@ The backticked anchor id is the shared key: the same id names the `rules.csv` ro
50
69
  - `spc-09` Ban calc-percentage layout arithmetic (`calc(33% - 1rem)`); CSS Grid instead.
51
70
  - `spc-10` No horizontal scroll at any viewport (375/768/1024/1440); any overflow means broken. · render
52
71
  - `spc-15` Grid/bento integrity: N items fill exactly N cells; no orphan corners; spans interlock. · render
72
+ - `spc-16` In fixed-width table/grid cells, rendered text fits the cell — no overlap or clip without a `truncate`/scroll affordance. · render
53
73
 
54
74
  ## Depth & hierarchy
55
75
 
@@ -80,6 +100,7 @@ The backticked anchor id is the shared key: the same id names the `rules.csv` ro
80
100
  - `mot-05` Animate only `transform` and `opacity`; never top, left, width, height, or margin.
81
101
  - `mot-06` `will-change` only on an in-progress `transform`/`opacity` animation; never blanket, never left dangling.
82
102
  - `mot-07` Loading indicators skeleton the content shape; delay 150–300ms; nothing < 500ms, spinner/skeleton 500ms–2s, progress bar > 2s.
103
+ - `mot-08` Stagger rides the `stagger-unit` token: 0–60ms per item, ≤ 8 children, total sequence < 1s (child count and total confirmed on the DOM at the render rung). Baseline-stamped surfaces skip arrival cascades; brand-forward surfaces may run `motion-stagger`.
83
104
  - `mot-09` Ban scroll-event listeners for animation (`window.addEventListener('scroll')`); observers or scrubbing only.
84
105
  - `mot-10` Ban `useState` for continuous scroll/pointer values; motion values instead. React-scoped.
85
106
 
@@ -103,6 +124,8 @@ The backticked anchor id is the shared key: the same id names the `rules.csv` ro
103
124
  - `cod-09` Component line ceilings: < 120 ln table, < 80 ln section; never modify files outside scope.
104
125
  - `cod-11` Every emitted component exports a typed Props interface; no HTML tags in React Native output.
105
126
  - `cod-12` Runtime budgets: LCP < 2.5s, INP < 200ms, CLS < 0.1, 16ms frame. · render
127
+ - `cod-15` Per-theme rendered token drift: under each theme context the resolver declares, rendered `--background`/`--foreground`/`--primary` equal that context's authored values. · render
128
+ - `cod-16` Every family name in an emitted font stack binds to an installed package's registered family or a system generic (fail-closed at `--emit`).
106
129
 
107
130
  ## Mandatory procedures (never skip)
108
131
 
@@ -144,7 +167,6 @@ Not gated — diagnosed. Each names what the judgment covers; the mechanics live
144
167
  - `int-15` Virtualize lists ≥ 50 items; bounded/paginated lists exempt.
145
168
  - `int-16` Tactile press feedback (−1px translateY / scale 0.98, < 100–150ms); suppressed under reduced-motion.
146
169
  - `mot-02` Per-interaction reference durations (button 100 / hover 150 / tooltip 200 / tab 250 / modal 300 / page 400ms) — reference, not a ban.
147
- - `mot-08` Stagger 30–50ms/item, cap ~8 children, total < 1s; operator surfaces skip orchestration.
148
170
  - `mot-11` Exit 60–70% of enter; press scale 0.95–1.05; ≤ 1–2 animated elements per view.
149
171
  - `sta-04` Errors render inline near the field, not banner-only; system-wide failures may banner.
150
172
  - `sta-06` Empty-state taxonomy: first-time / user-cleared / no-results / no-access / error, distinct copy each.
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Loaded when the front gate routes to improve. Pairs with [diagnosis.md](diagnosis.md) (the finding source and format) and closes at the same machine-check wall create's gates enforce. Improve is every change to a UI that **already exists**; [create.md](create.md) owns the case where nothing does.
4
4
 
5
- Improve is one engine, not a set of commands. Every improvement — a review, a polish, a full redesign, a typography-only pass — is the same engine run at a different point on three axes. The familiar verbs are parameter bindings, not sibling workflows: there is no `review.md`, no `redesign.md`.
5
+ Improve is one engine, not a set of commands. Every improvement — a review, a polish, a full redesign, a typography-only pass, a rendered judgment — is the same engine run at a different point on three axes. The familiar verbs are parameter bindings, not sibling workflows: there is no `review.md`, no `redesign.md`, no `judge.md`.
6
6
 
7
7
  ## The three axes
8
8
 
@@ -22,14 +22,15 @@ Bindings over the engine, in one table. Never restated as separate files.
22
22
  | `polish` | whole app | apply | jailed | Fix everything reachable inside the current levers. |
23
23
  | `redesign` | whole app | apply | lever-consent | Apply the consented lever changes, then polish within the new manifest. |
24
24
  | `typeset` | `P1 Typography` | apply | jailed | Apply, scoped to the Typography dimension only. |
25
+ | `judge` | whole app (narrowable to a surface) | diagnose-only | jailed | Rank findings from **rendered evidence** — screenshots captured, read back, critiqued (the protocol below); change nothing. |
25
26
 
26
- A narrower or wider pass — one surface, one other dimension — is the same table with the scope cell moved. Bind the parameters; do not author a verb.
27
+ A narrower or wider pass — one surface, one other dimension — is the same table with the scope cell moved. Bind the parameters; do not author a verb. `judge --fix` is sugar, not a fifth row: a `judge` run followed by an apply-depth run over its findings — still jailed to the lever manifest, closing at the same verify sweep as any apply run.
27
28
 
28
29
  ## The golden rule: jailed to the lever manifest
29
30
 
30
31
  A design skill improves a UI **using the levers already in it**. Emitting design disjoint from the surrounding UI is a failure, not a style choice.
31
32
 
32
- The project's design-tokens artifact carries the **lever manifest** — the `lever-manifest` in its `$extensions["com.nurix.design"]` payload (spacing scale, radius scale, shadow levels, motion durations/easings, icon family, accent count) plus the token-carried allowlists (the 34 color roles, the font stacks). Read it **first**, before any diagnosis or edit.
33
+ The project's design-tokens artifact carries the **lever manifest** — the `lever-manifest` in its `$extensions["com.nurix.design"]` payload (spacing scale, radius scale, shadow levels, motion durations/easings, icon family, accent count) plus the token-carried allowlists (the 36 color roles, the font stacks). Read it **first**, before any diagnosis or edit.
33
34
 
34
35
  ### When the UI wasn't built by this skill: extract first
35
36
 
@@ -85,3 +86,31 @@ The universal preservation list holds regardless of scope or depth — never sil
85
86
  3. **Diagnose-only** → deliver the ranked findings and stop.
86
87
  4. **Apply** → edit only the files the findings name, then close at the verify sweep over the touched files, jailed to the manifest.
87
88
  5. **Escalate** → report the tier-two findings and offer the consented lever-authority follow-up.
89
+
90
+ ## `judge` — the rendered-evidence preset
91
+
92
+ The invocable eye. `judge` is the preset row above run over **rendered pixels**: same engine, same jail, same finding format — plus screenshots captured, read back, and critiqued. It ships behind an explicit verb, never as a mandatory create phase; create's pipeline keeps zero model-judged rungs.
93
+
94
+ The protocol, five steps, in order:
95
+
96
+ 1. **Render.** Reuse the render rung's browser plumbing: `render-rung.mjs --screenshot <outdir>` captures the app's key surfaces at **375 / 768 / 1440** (the rung's sweep also lands 1024 — a captured screenshot is read like any other) — the boot theme, *and* the second theme when the resolver declares a dark context (flip `data-theme`, as the rung's per-theme drift check does). Deterministic waits are the rung's existing settle logic; the PNGs land in a run-scoped temp dir.
97
+ 2. **Read back.** Read every captured image into context. **A screenshot you didn't read doesn't count** — describe each surface before critiquing it.
98
+ 3. **Critique against the four fixed referents** — never free-floating taste:
99
+ - **the brief** — does the rendered app serve the stated intent;
100
+ - **the artifact's `anchors`** — does the gestalt read in the named products' class: would this screenshot sit plausibly in Linear's or Stripe's product family;
101
+ - **the resolved style row's `checklist`** ([`styles.csv`](../data/combinations/styles.csv)) — the did-the-look-land walk, item by item, always including the standing harmony item: palette, type, and treatment read as one hand;
102
+ - **the project taste profile** (`docs/design/taste.yml`) — does the rendered app respect the recorded taste items; missing or malformed degrades to no-profile behavior with a one-line notice, as at intake.
103
+
104
+ Plus the standing judged dimensions — [diagnosis.md](diagnosis.md)'s taxonomy pass, Perception especially — with the screenshots as the evidence.
105
+ 4. **Findings** in the canonical format, verbatim — dimension · cause layer · evidence (now admitting screenshot path + region) · before→after · consequence · tier · severity · provenance — severity-ranked, unscored; fix-or-classify applies. Structure findings still precede Perception: causes-first holds even when the evidence is a pixel.
106
+ 5. **File the report.** A judge run always writes a dated findings report — `docs/design/judge-YYYY-MM-DD.md` in the consumer project — so the eye leaves a record even when nothing is applied.
107
+
108
+ ### Boundaries — what judge is not
109
+
110
+ - **Not a rung.** The verification ladder is unchanged; no machine verdict rests on the model's read of a screenshot; a create run completes without judge ever running. Pixel instruments stay evidence-inside-findings — judge is a *workflow*, subject to the same rule.
111
+ - **Not autonomous escalation.** judge recommends; the user triggers any follow-up — `judge --fix`, a lever-consent run. No regenerate-until-passing.
112
+ - **Not a score.** No numeric grades in findings, ever — run-time scores are false precision; severity ranks plus the mandatory measurable before→after per finding give comparability without pretending decimals. Scores exist only outside the skill: the eval harness computes them from its own panel; the skill never self-scores.
113
+ - **Instruments are evidence, never verdicts — on recorded empirical grounds.** "Lower visual complexity ⇒ higher quality" is refuted for this domain: surfaces that are dense on purpose invert the sign of "good". Computational clutter/aesthetics metrics validate correlationally and modestly — ≤ 49% of human ratings on webpages, ≤ 32% on apps, zero validation on dashboards and CRMs — and a subset are pretrained neural nets, excluded outright as model judgment. So a pixel instrument may be *cited inside* a judged finding and is structurally barred from gating. The two vetted instruments a judge finding reaches for first: **Edge Density** (`inst-01` — Canny edge pixels ÷ total pixels; r≈0.83 with visual-search times, the cheapest proxy for how fast an operator finds a target) and the **Keystroke-Level Model** (`inst-11` — P 1.10s · H 0.40s · M 1.35s · K 0.20–0.28s, summed over the core loop; countable operator-cost evidence for the throughput-vs-delight floor principle, `f01`). The interaction *path* is judgment, so KLM is evidence too, never ground truth.
114
+ - **Degradation.** No headless browser → judge **refuses**, printing the rung's install command (`npm install -D playwright && npx playwright install chromium`) — an eye that cannot see does not judge from memory. It never falls back to source-only critique; source-only is `review`.
115
+
116
+ Prior art for a future live-variant mode (consent-gated, human present — never a rung): impeccable's identity lock — extract the surface's existing identity into one non-aspirational sentence, then a mandatory squint test that every variant reads as the same brand — with 0–4 tunable `--p-*` parameter knobs per variant; the corpus's only closed taste loop with real eyes on it.
@@ -28,12 +28,12 @@ The **error** state surfaces on blur, never per keystroke (`int-*`), and renders
28
28
  - **Visible focus, always.** Every focusable element carries a `:focus-visible` ring driven by the `--ring` token so it follows the look. `outline: none` without a replacement is banned (`int-*`). The ring meets the catalog's contrast and width floor — do not restate it, satisfy it.
29
29
  - **Focus order follows task order.** Tab order is the sequence the operator works, not a DOM accident. Composite widgets — tables, listboxes, menus, toolbars — use roving tabindex: the widget is one tab-stop, arrow keys traverse inside it.
30
30
  - **Focus is returned on overlay close.** Opening an overlay moves focus into it; closing returns focus to the element that opened it. Focus never drops to the top of the document.
31
- - **Keyboard path parity.** Every pointer affordance has a keyboard equivalent — nothing is reachable by hover or click alone (floor P6). Hover-revealed row actions carry a focus path (`int-*`). `cursor: pointer` marks every clickable element on the web (`int-*`).
31
+ - **Keyboard path parity.** Every pointer affordance has a keyboard equivalent — nothing is reachable by hover or click alone (floor f06). Hover-revealed row actions carry a focus path (`int-*`). `cursor: pointer` marks every clickable element on the web (`int-*`).
32
32
  - **Skip links** jump to the primary work region on any surface with substantial navigation.
33
33
 
34
34
  ## Overlay policy
35
35
 
36
- Escalate only as far as the interaction demands, cheapest rung first (floor P3):
36
+ Escalate only as far as the interaction demands, cheapest rung first (floor f03):
37
37
 
38
38
  1. **Inline expansion** — reveal detail in place; no overlay at all.
39
39
  2. **Side panel** — detail and edit open *beside* the work, not on top of it (`--side-panel-width` / `--side-panel-width-rich`). This is the default for viewing and editing an entity.
@@ -57,7 +57,7 @@ Match the affordance to the action's reversibility:
57
57
  - **Command palette** (`cmdk`) is the power-user's front door — global verbs, entity jump, reachable by a single chord. Expected on any multi-surface operator tool.
58
58
  - **Row-level keyboard actions in queues.** A queue row is focusable; the frequent verbs (open, assign, resolve, advance) bind to keys; the kebab overflow is keyboard-reachable, not pointer-only. Roving tabindex moves between rows, and the row's keyboard action set mirrors its pointer menu exactly — no verb is pointer-only.
59
59
  - **Tab-stop economics on the core loop.** The operator's core loop ([structure.md](structure.md)) must complete in few keystrokes and homings. Every tab-stop on the hot path is a cost paid per item, per shift — prune stops that do not earn their place, and keep the primary verb one key away.
60
- - **KLM is the diagnosis lens, not a gate.** Counting the keystrokes, pointer homings, and mental operators of a fixed core-loop path (the Keystroke-Level Model) turns "this feels slow" into a number. It rides [diagnosis.md](diagnosis.md) as a judged instrument against floor P1's throughput metric — evidence inside a finding, never a machine verdict.
60
+ - **KLM is the diagnosis lens, not a gate.** Counting the keystrokes, pointer homings, and mental operators of a fixed core-loop path (the Keystroke-Level Model) turns "this feels slow" into a number. It rides [diagnosis.md](diagnosis.md) as a judged instrument against floor f01's throughput metric — evidence inside a finding, never a machine verdict.
61
61
 
62
62
  ## Assistive floors beyond keyboard
63
63
 
@@ -58,7 +58,7 @@ Every run files a dated report — introspection doubles as documentation, so a
58
58
  docs/design/findings/YYYY-MM-DD-<slug>.md
59
59
  ```
60
60
 
61
- `<slug>` names the target (the surface, or the app). The report carries the canonical findings so a consented improve run consumes it directly, topped with a two-line executive summary in the chosen register. It is a deliverable, not runtime state — never read back as design state (code is the cache, floor P8).
61
+ `<slug>` names the target (the surface, or the app). The report carries the canonical findings so a consented improve run consumes it directly, topped with a two-line executive summary in the chosen register. It is a deliverable, not runtime state — never read back as design state (code is the cache, floor f08).
62
62
 
63
63
  ### Template
64
64
 
@@ -6,7 +6,7 @@ The states a surface actually lives in, and the microcopy mechanisms that fill t
6
6
 
7
7
  ## The seam: mechanisms, not words
8
8
 
9
- Everything here is a **mechanism** — a formula, a required shape, a consistency discipline. The actual words are the business's call (floor P12). The skill enforces that an error names what happened / why / how to fix; it never writes the error text. It enforces one term per concept; it never picks the term. Emit shells and shapes; leave the vocabulary to the domain.
9
+ Everything here is a **mechanism** — a formula, a required shape, a consistency discipline. The actual words are the business's call (floor f12). The skill enforces that an error names what happened / why / how to fix; it never writes the error text. It enforces one term per concept; it never picks the term. Emit shells and shapes; leave the vocabulary to the domain.
10
10
 
11
11
  ## Required states per surface
12
12
 
@@ -33,7 +33,7 @@ An empty state is not one state. Five are distinct, and each earns distinct copy
33
33
  | no-access | forbidden, not empty | that it exists but is gated, who to ask |
34
34
  | error | the fetch failed | routes to the error formula below, never to "empty" |
35
35
 
36
- **The empty formula: acknowledge → state the value → at most one action.** Text-first (floor P2) — copy plus at most one action, never an illustration showcase. *At most* one, not exactly one: a read-only surface (an audit log) legitimately offers zero. Never a dead-end on an actionable surface. Copy runs one to two sentences.
36
+ **The empty formula: acknowledge → state the value → at most one action.** Text-first (floor f02) — copy plus at most one action, never an illustration showcase. *At most* one, not exactly one: a read-only surface (an audit log) legitimately offers zero. Never a dead-end on an actionable surface. Copy runs one to two sentences.
37
37
 
38
38
  ## Errors
39
39