@nurix/etna 0.19.3 → 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.
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/harness.json +1 -1
- package/data/harnesses/code/rules/frontend.md +3 -3
- package/data/harnesses/code/skills/design/SKILL.md +20 -8
- package/data/harnesses/code/skills/design/data/catalog/rules.csv +10 -5
- package/data/harnesses/code/skills/design/data/combinations/Readme.md +8 -4
- package/data/harnesses/code/skills/design/data/combinations/accent-presets.md +113 -0
- package/data/harnesses/code/skills/design/data/combinations/fonts-known.json +11 -0
- package/data/harnesses/code/skills/design/data/combinations/manifest.json +57 -10
- package/data/harnesses/code/skills/design/data/combinations/motion.csv +10 -0
- package/data/harnesses/code/skills/design/data/combinations/palettes.csv +92 -49
- package/data/harnesses/code/skills/design/data/combinations/styles.csv +67 -54
- package/data/harnesses/code/skills/design/data/combinations/typography.csv +64 -61
- package/data/harnesses/code/skills/design/data/design-md/library/expo.md +4 -4
- package/data/harnesses/code/skills/design/data/design-md/library/lovable.md +5 -5
- package/data/harnesses/code/skills/design/data/design-md/library/minimax.md +6 -6
- package/data/harnesses/code/skills/design/data/design-md/library/notion.md +4 -4
- package/data/harnesses/code/skills/design/data/design-md/library/runwayml.md +4 -4
- package/data/harnesses/code/skills/design/data/design-md/library/sentry.md +2 -2
- package/data/harnesses/code/skills/design/data/design-md/library/slack.md +6 -6
- package/data/harnesses/code/skills/design/data/design-md/library/webflow.md +5 -5
- package/data/harnesses/code/skills/design/data/design-md/nurix.md +11 -7
- package/data/harnesses/code/skills/design/data/design-tokens/SCHEMA.md +256 -141
- package/data/harnesses/code/skills/design/data/design-tokens/airbnb/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/airtable/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/anthropic-claude/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/apple/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/binance/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/bmw/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/cal/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/clay/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/clickhouse/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/cohere/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/coinbase/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/composio/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/cursor/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/elevenlabs/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/expo/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/figma/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/framer/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/goldens.json +123 -123
- package/data/harnesses/code/skills/design/data/design-tokens/hashicorp/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/ibm/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/intercom/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/kraken/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.resolver.json +1 -1
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.dark.json +10 -0
- package/data/harnesses/code/skills/design/data/design-tokens/linear-app/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/lovable/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/meta/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/minimax/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/mintlify/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/miro/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/mistral-ai/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/mongodb/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/notion/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/nurix/design.tokens.json +307 -2
- package/data/harnesses/code/skills/design/data/design-tokens/nvidia/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/ollama/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/opencode-ai/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/posthog/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/raycast/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/replicate/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.resolver.json +1 -1
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.dark.json +10 -0
- package/data/harnesses/code/skills/design/data/design-tokens/resend/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/revolut/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/runwayml/design.tokens.json +310 -2
- package/data/harnesses/code/skills/design/data/design-tokens/sanity/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/sentry/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/shopify/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/slack/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/spacex/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/spotify/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/stripe/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/supabase/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/superhuman/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/tesla/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/theverge/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/together-ai/design.tokens.json +313 -1
- package/data/harnesses/code/skills/design/data/design-tokens/uber/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/vercel/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.resolver.json +1 -1
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.dark.json +10 -0
- package/data/harnesses/code/skills/design/data/design-tokens/voltagent/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/warp/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/webflow/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/wired/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/wise/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/x-ai/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/design-tokens/zapier/design.tokens.json +309 -1
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/command-center.tsx +25 -25
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/create-edit.tsx +18 -18
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/dashboard.tsx +82 -105
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/entity-detail.tsx +97 -93
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/list-detail.tsx +16 -15
- package/data/harnesses/code/skills/design/data/operator-pack/exemplars/log-stream.tsx +34 -34
- package/data/harnesses/code/skills/design/data/operator-pack/surface-catalog.md +5 -5
- package/data/harnesses/code/skills/design/references/create.md +49 -7
- package/data/harnesses/code/skills/design/references/diagnosis.md +3 -3
- package/data/harnesses/code/skills/design/references/hard-rules.md +25 -3
- package/data/harnesses/code/skills/design/references/improve.md +32 -3
- package/data/harnesses/code/skills/design/references/interaction.md +3 -3
- package/data/harnesses/code/skills/design/references/introspect.md +1 -1
- package/data/harnesses/code/skills/design/references/lifecycle.md +2 -2
- package/data/harnesses/code/skills/design/references/personality.md +280 -133
- package/data/harnesses/code/skills/design/references/structure.md +22 -1
- package/data/harnesses/code/skills/design/scripts/convert-design-md.mjs +306 -26
- package/data/harnesses/code/skills/design/scripts/derive-personality.mjs +596 -104
- package/data/harnesses/code/skills/design/scripts/lib/checks.mjs +200 -11
- package/data/harnesses/code/skills/design/scripts/lib/vocabulary.mjs +65 -0
- package/data/harnesses/code/skills/design/scripts/phase-gate.mjs +95 -11
- package/data/harnesses/code/skills/design/scripts/preship-sweep.mjs +50 -5
- package/data/harnesses/code/skills/design/scripts/render-rung.mjs +214 -14
- package/data/harnesses/code/skills/design/scripts/scaffold.mjs +242 -25
- package/data/harnesses/code/skills/design/scripts/self-integrity.mjs +81 -6
- package/data/harnesses/code/skills/design/scripts/snapshot-goldens.mjs +101 -5
- package/data/harnesses/code/skills/design/scripts/validate-combinations.mjs +142 -17
- package/package.json +1 -1
package/data/harness-index.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
Tailwind v4 + shadcn-based UI conventions for **web** apps — styling, the `@nurix/components` library, personality tokens, and design-skill routing. Package versions live in [`general.md`](general.md); the Express server and API envelope in [`express.md`](express.md); React Native styling is out of scope — that's [`react-native.md`](react-native.md).
|
|
4
4
|
|
|
5
5
|
- **Build every UI through the `design` skill** — route the brief through it instead of hand-rolling layouts; it owns the archetype, personality tokens, and `@nurix/components` wiring.
|
|
6
|
-
- **
|
|
6
|
+
- **The brief's stated theme binds** — dark boots dark when the brief says so (the artifact's `theme-default` carries it); light is the default only when the brief is silent.
|
|
7
7
|
- **@nurix/\* are restricted-scope npm packages** — installed from the npm registry, auto-authed by a read token in `~/.npmrc`. Just attempt the install; the token authenticates you automatically. Don't pre-empt or second-guess it. If the install actually fails, flag it to the user — never reach for alternatives, a substitute package, or `npm login`.
|
|
8
8
|
- **@nurix/components** — the UI component library (restricted-scope npm package, pre-built); import by subpath, e.g. `@nurix/components/button`.
|
|
9
9
|
- No components.json / shadcn CLI scaffold (.tsx, not .jsx) — consume the prebuilt library; never `npx shadcn add`.
|
|
10
10
|
- Vite: `@tailwindcss/vite` + `@vitejs/plugin-react-swc`. Pin react / react-dom / react/jsx-runtime / react/jsx-dev-runtime to the app's single copy via `resolve.alias` (@nurix/\* ship nested react — keep one hook dispatcher).
|
|
11
11
|
- Tailwind v4, CSS-only (no tailwind.config.js, no PostCSS): styling runs through the `@tailwindcss/vite` plugin.
|
|
12
|
-
- CSS entry `globals.css`, imports in order — `@import "./personality.css"` (token source) → `@import "tailwindcss"` → the library's `styles.css` — then `@theme inline {…}` mapping vars to tokens.
|
|
13
|
-
- Tokens: CSS vars in `:root, :root[data-theme="light"]` + the archetype selector `[data-style="…"]` (personality.css), consumed as semantic Tailwind tokens (bg-card, text-foreground). Honor the archetype's radius/theme decisions (e.g. re-assert `--radius-*` to 0 for a flat archetype
|
|
12
|
+
- CSS entry `globals.css`, imports in order — `@import "./fonts.css"` (generated @fontsource registrations, first) → `@import "./personality.css"` (token source) → `@import "tailwindcss"` → the library's `styles.css` — then `@theme inline {…}` mapping vars to tokens.
|
|
13
|
+
- Tokens: CSS vars in `:root, :root[data-theme="light"]` + the archetype selector `[data-style="…"]` (personality.css), consumed as semantic Tailwind tokens (bg-card, text-foreground). Honor the archetype's radius/theme decisions (e.g. re-assert `--radius-*` to 0 for a flat archetype). The emitted `globals.css` always carries the active `@custom-variant dark` line; the theme attribute convention is `data-theme`. The library bundles class-variance-authority, clsx, tailwind-merge.
|
|
14
14
|
- Plus general styling rules (spacing in 2/4/6/8, object-cover, truncate, motion, color tokens — never hardcoded hex in components).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design
|
|
3
|
-
description: Design, build, review, polish, redesign, or introspect internal operator UIs — CRMs, ticket queues, admin panels, analytics dashboards, log viewers, command centers, and any internal/back-office tool an operator, agent, or analyst works in all day. Resolves the project's brand from its design-tokens artifact (design.tokens.json), derives structure from the domain objects, emits a working React + Tailwind UI against @nurix/components or shadcn/ui, and holds it to operator-grade quality across a full sixteen-dimension taxonomy. Triggers on "build a dashboard", "design an admin panel", "review this CRM UI", "polish this queue", "redesign this internal tool", "why does this table feel off", "make it feel like Linear", or any create/improve/introspect request for an internal operator interface. Coverage is the operator pack: marketing sites, landing pages, storefronts, homepages, and mobile-native apps are out of scope — no carried pack covers them, so refuse cleanly and redirect. The machinery is not the limit; the packs are.
|
|
3
|
+
description: Design, build, review, polish, redesign, judge, or introspect internal operator UIs — CRMs, ticket queues, admin panels, analytics dashboards, log viewers, command centers, and any internal/back-office tool an operator, agent, or analyst works in all day. Resolves the project's brand from its design-tokens artifact (design.tokens.json), derives structure from the domain objects, emits a working React + Tailwind UI against @nurix/components or shadcn/ui, and holds it to operator-grade quality across a full sixteen-dimension taxonomy. Triggers on "build a dashboard", "design an admin panel", "review this CRM UI", "polish this queue", "redesign this internal tool", "judge this UI", "does this look right", "screenshot review", "why does this table feel off", "why does this feel off visually" (introspect keeps the causal why; judge owns the rendered whether), "make it feel like Linear", or any create/improve/introspect request for an internal operator interface. Coverage is the operator pack: marketing sites, landing pages, storefronts, homepages, and mobile-native apps are out of scope — no carried pack covers them, so refuse cleanly and redirect. The machinery is not the limit; the packs are.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# design
|
|
@@ -15,29 +15,41 @@ The design skill. Its shipped coverage is the **operator pack**: internal tools
|
|
|
15
15
|
2. **The signal checklist recognizes** when no project artifact speaks: the audience is employees / agents / analysts; the metric is task throughput, not conversion; the surfaces are queues / tables / forms / monitors. The design.md library (`data/design-md/library/`) assists the lookup by resemblance — it never overrides the checklist.
|
|
16
16
|
3. **Refuse with a redirect** when no carried pack covers the brief — marketing sites, landing pages, storefronts, mobile-native. State plainly which pack is missing and point elsewhere; never a degraded attempt. The machinery is artifact-agnostic; the boundary is pack coverage, and it moves only by adding a pack.
|
|
17
17
|
|
|
18
|
-
**Then the intent digest — infer and confirm.** Build a structured digest — entities, archetype guesses, density tier, substrate — with **every inference marked as inferred**. Present it once for confirmation before any derivation begins. Ask questions only for strategic unknowns whose answers change the design. Nothing auto-runs on silent inference; nothing stalls on a blanket interview.
|
|
18
|
+
**Then the intent digest — infer and confirm.** Build a structured digest — entities, archetype guesses, density tier, substrate, **and the mandatory look block** (theme; 2–3 named product anchors, never adjectives; the delight ceiling; the resolved source and how it was authorized) — with **every inference marked as inferred**. Present it once for confirmation before any derivation begins. Ask questions only for strategic unknowns whose answers change the design. Nothing auto-runs on silent inference; nothing stalls on a blanket interview. The look block is gated at intake — `phase-gate.mjs intake` validates its enums and anchors and, for an autonomously recorded resolution, the resolution record in the artifact root `$description`; the detail lives in [`references/create.md`](references/create.md).
|
|
19
19
|
|
|
20
20
|
## Boot order
|
|
21
21
|
|
|
22
|
-
Before **any** design output, read [`references/hard-rules.md`](references/hard-rules.md) — the boot-loaded floor of
|
|
22
|
+
Before **any** design output, read [`references/hard-rules.md`](references/hard-rules.md) — the boot-loaded floor of 136 rules <!-- count:rules=136 --> (bans, deterministic thresholds, mandatory procedures, each keyed to an anchor id). Then route by workflow. JIT loads never happen at boot — they fire at the gate that needs them.
|
|
23
|
+
|
|
24
|
+
**Hold the four-layer stack for every run** — who owns what, and who wins:
|
|
25
|
+
|
|
26
|
+
- **L4 — Patterns** (the operator pack): surface catalog, per-archetype exemplars, trust rubric, microcopy — consumes L3's vocabulary under L2's budgets, and never introduces vocabulary the artifact lacks (token-pure).
|
|
27
|
+
- **L3 — Look** (the token artifact): every visual value — primitives, color roles, ramp, elevation, wash, motion base, dials — composed at generation time and emitted once by `derive-personality.mjs`; never makes a structural call.
|
|
28
|
+
- **L2 — Structure** (the object pass): entities → surface map → density tiers → per-surface delight budgets → scaffolds → fixtures; decides structure and permission, never a look value — a budget grants vocabulary, never values.
|
|
29
|
+
- **L1 — Floor** (rules + gates): the twelve-principle doctrine floor, the machine rule catalog, and the fail-closed phase gates — an admission filter every layer's output passes through; never a value source, and **nothing overrides it**.
|
|
30
|
+
|
|
31
|
+
Two composition orders resolve the stack. **Composition A** (generation time) collapses all value conflicts into one artifact by a single linear precedence — defaults → resolved source (a seed composition partitioned by domain: palette = color, type = type, style = treatment) → brief bindings → recorded deviations; the taste profile biases the picks, it never holds a slot. **Composition B** (runtime) carries only contexts — theme, density, the behavioral dials; every value is already resolved. Expressiveness is granted *inside* the floor by L2's budgets, never as an exception to L1.
|
|
23
32
|
|
|
24
33
|
| Route | Load, when |
|
|
25
34
|
| --- | --- |
|
|
26
35
|
| **create** (nothing exists yet) | [`references/create.md`](references/create.md) at intake; then per phase: [`structure.md`](references/structure.md) at structure, [`personality.md`](references/personality.md) at tokens, [`lifecycle.md`](references/lifecycle.md) + [`interaction.md`](references/interaction.md) at surfaces |
|
|
27
36
|
| **improve** (a UI already exists) | [`references/improve.md`](references/improve.md) + [`references/diagnosis.md`](references/diagnosis.md) |
|
|
37
|
+
| **judge** (does the rendered app look right — an improve preset) | [`references/improve.md`](references/improve.md) (the `judge` preset row + protocol) + [`references/diagnosis.md`](references/diagnosis.md) |
|
|
28
38
|
| **introspect** (why is it wrong) | [`references/introspect.md`](references/introspect.md) + [`references/diagnosis.md`](references/diagnosis.md) |
|
|
29
39
|
| JIT — archetype exemplar | `data/operator-pack/exemplars/<slug>.tsx` at that archetype's emission gate during surfaces — never at boot |
|
|
30
40
|
| JIT — fixture pair | `data/catalog/fixtures/<id>.{flag,pass}` only when a rule is contested and the contrastive pair teaches it (authoring repo only — pairs are stripped from shipped bundles; when the folder is absent, the finding's exact-fix line carries the teaching) |
|
|
31
41
|
| JIT — combination tables, look | `data/combinations/product-router.csv` at every intake; `typography.csv` / `palettes.csv` / `styles.csv` at intake only when the look resolves to authoring a fresh artifact, typography and palettes again at tokens before any hint resolves — contract: [`data/combinations/Readme.md`](data/combinations/Readme.md) |
|
|
32
42
|
| JIT — combination tables, surface picks | `data/combinations/charts.csv` at the emission gate of any chart-composing surface; `icons.csv` once at the first surface-composition gate — same contract |
|
|
43
|
+
| JIT — taste profile | `docs/design/taste.yml` at intake and at resolution — the project's standing taste input (biases picks, never sets values); missing or malformed degrades to no-profile behavior with a one-line notice, never a block |
|
|
44
|
+
| JIT — judge referents | at a judge run's critique step: the resolved style row's `checklist` (`data/combinations/styles.csv`), the artifact's `anchors`, and the project taste profile (`docs/design/taste.yml`) — the fixed referents beside the brief, never free-floating taste |
|
|
33
45
|
|
|
34
|
-
A consulted combination table is a **floor
|
|
46
|
+
A consulted combination table is a **floor**: the tables are the floor. A recorded off-table pick — the reason written into what the run produces (the token `$description`, an adjacent code comment, the finding body — sites per the contract) — is legitimate craft, and the record is what makes it so; an **unrecorded** off-table pick is the violation, the same class as skipping a gate.
|
|
35
47
|
|
|
36
48
|
## The three workflows
|
|
37
49
|
|
|
38
50
|
**Create** makes taste where nothing exists. It runs **six gated phases** — intake, structure, scaffold, tokens, fixtures, surfaces — and closes on the verification ladder. Each boundary is `phase-gate.mjs <phase>`; the next phase does not open until the gate is green. The object pass is never skipped — a small brief earns a proportionally small pass, never a guessed archetype; every surface takes an archetype from the closed six <!-- count:archetypes=6 --> (`list-detail`, `dashboard`, `entity-detail`, `create-edit`, `log-stream`, `command-center`). Fixtures are seeded and generated **before** surfaces, because realistic data is taste-bearing design material. See [`create.md`](references/create.md).
|
|
39
51
|
|
|
40
|
-
**Improve** is one engine over a UI that already exists, run at a point on scope × depth × authority; the verbs — review, polish, redesign, typeset — are parameter bindings, never sibling files. Emission is **jailed to the lever manifest** by default: an edit may emit only values inside the project artifact's vocabulary, enforced by the end-of-run verify sweep (`preship-sweep.mjs --files <touched...> --manifest design.tokens.json`). On a foreign UI, **extract a token artifact first** (payload `provenance: extracted`) — record what IS, never what should be. Wrong fundamentals are tier-two (`lever-change`) findings: finish the within-levers work, report them, and offer a consent-gated lever run — never change levers unbidden. At the fix step, a finding that names a chart or icon loads `data/combinations/charts.csv` / `icons.csv` before the edit. See [`improve.md`](references/improve.md) + [`diagnosis.md`](references/diagnosis.md).
|
|
52
|
+
**Improve** is one engine over a UI that already exists, run at a point on scope × depth × authority; the verbs — review, polish, redesign, typeset, judge — are parameter bindings, never sibling files. `judge` is the diagnose-only preset with rendered evidence — screenshots captured, read back, critiqued against the brief, the artifact's `anchors`, the style row's `checklist`, and the taste profile; no headless browser → it refuses, never a source-only critique. Emission is **jailed to the lever manifest** by default: an edit may emit only values inside the project artifact's vocabulary, enforced by the end-of-run verify sweep (`preship-sweep.mjs --files <touched...> --manifest design.tokens.json`). On a foreign UI, **extract a token artifact first** (payload `provenance: extracted`) — record what IS, never what should be. Wrong fundamentals are tier-two (`lever-change`) findings: finish the within-levers work, report them, and offer a consent-gated lever run — never change levers unbidden. At the fix step, a finding that names a chart or icon loads `data/combinations/charts.csv` / `icons.csv` before the edit. See [`improve.md`](references/improve.md) + [`diagnosis.md`](references/diagnosis.md).
|
|
41
53
|
|
|
42
54
|
**Introspect** explains **why** a UI isn't working; it reads code and never edits it. **Ask the reader question first**, every run, verbatim — designer / developer / PM — never inferred, never a stored default. Diagnose causes-first (Structure → Behavior → Perception), narrate each finding from the felt symptom down to its cause, render it in the reader's register, and **always file a dated report**. When the audited UI renders charts, diagnosis loads `data/combinations/charts.csv`. See [`introspect.md`](references/introspect.md) + [`diagnosis.md`](references/diagnosis.md).
|
|
43
55
|
|
|
@@ -47,8 +59,8 @@ Under `scripts/`; spawn them from this skill directory. All ESM, Node ≥ 22, ze
|
|
|
47
59
|
|
|
48
60
|
- `phase-gate.mjs <phase> [--project <dir>]` — validates a phase's exit preconditions **and runs the machine catalog + lever-manifest drift check over the project's UI files**; exit non-zero printing the exact fix. Phases: `intake`, `structure`, `scaffold`, `tokens`, `fixtures`, `surfaces`.
|
|
49
61
|
- `preship-sweep.mjs [--project <dir>] [--files <file...>] [--manifest design.tokens.json]` — whole-app catalog sweep + viewport sweep + copy audit + scope cross-check; prints the manual `proc-*` checklist. With `--files`, a scoped verify run over just those files — improve's end-of-run gate.
|
|
50
|
-
- `render-rung.mjs [--project <dir>] [--url <dev-server>]` — render-only rules at 375/768/1024/1440 plus the render instruments (evidence, never gates)
|
|
51
|
-
- `derive-personality.mjs <artifact-dir> [--check|--emit <outdir>] [--theme light|dark]` — `--check` is the coverage gate over the design-tokens artifact; `--emit` writes `personality.css` + `globals.css
|
|
62
|
+
- `render-rung.mjs [--project <dir>] [--url <dev-server>] [--require] [--screenshot <outdir>]` — render-only rules at 375/768/1024/1440 plus the render instruments (evidence, never gates). `--require` makes the rung a gate (create's ladder): no importable headless browser exits non-zero printing the exact install command. Without `--require` (non-require improve runs) the skip degrades gracefully — exit 0, the skip landing as a named finding, never silently. `--screenshot <outdir>` writes one PNG per viewport — judge's capture plumbing.
|
|
63
|
+
- `derive-personality.mjs <artifact-dir> [--check|--emit <outdir>] [--theme light|dark]` — `--check` is the coverage gate over the design-tokens artifact; `--emit` writes `personality.css` + `globals.css` + `src/styles/fonts.css` (the generated `@fontsource` registering imports, gated by the font-binding check, `cod-16`). The gate fails unless all 27 primitives <!-- count:primitives=27 -->, both dials, and every one of the 36 color values (19 semantic <!-- count:semantic-tokens=19 --> + 17 substrate <!-- count:substrate-tokens=17 -->) <!-- count:color-tokens=36 --> is assigned or hinted; emit refuses while any token carries a hint.
|
|
52
64
|
- `scaffold.mjs <structure.md> --out <dir>` — routes, nav, state-shells, and fixture wiring from the entity/surface map.
|
|
53
65
|
- `generate-fixtures.mjs <structure.md> --seed <n> --out <dir>` — seeded, domain-shaped fixture modules.
|
|
54
66
|
- `self-integrity.mjs` — run from `skills/design/`: anchor parity (prose ↔ catalog), stated counts, fixture-pair presence and contrastive validity. CI-owned.
|
|
@@ -59,7 +71,7 @@ The skill writes these into the consumer project; the emitted code and these fil
|
|
|
59
71
|
|
|
60
72
|
- `design.tokens.json` + `design.resolver.json` (+ `design.tokens.dark.json` when the look has dark values) at project root — the canonical look artifact + lever manifest ([schema](data/design-tokens/SCHEMA.md)). Create writes it; improve reads and, on a foreign UI, extracts it. Payload provenance is one of `project | extracted | library | default` (extracted sits at project precedence).
|
|
61
73
|
- `docs/design/structure.md` — the entity/surface map, in a fenced `yaml structure` block; `scaffold.mjs` consumes it.
|
|
62
|
-
- `docs/design/findings/YYYY-MM-DD-<slug>.md` — dated introspect and review reports.
|
|
74
|
+
- `docs/design/findings/YYYY-MM-DD-<slug>.md` — dated introspect and review reports; `docs/design/judge-YYYY-MM-DD.md` — the dated judge report (a judge run always writes one, even when nothing is applied).
|
|
63
75
|
- `docs/memory/design-decay.md` — the decay ledger: rules skipped or fought, the fix-or-classify classifications, guidance that produced wrong output. Append-only, maintainer-read, human-closed. The skill never self-modifies — it observes decay; the maintainer closes it.
|
|
64
76
|
|
|
65
77
|
## Substrate and scope
|
|
@@ -4,10 +4,10 @@ typ-02,P1,"Body text sits at 14px or above on operator surfaces; nothing renders
|
|
|
4
4
|
typ-03,P1,"Form inputs are at least 16px on touch and mobile surfaces to defeat iOS zoom.",">=16px",machine,edit,source,"Touch/mobile surfaces only; desktop operator inputs are exempt.",ben;uupm,yes
|
|
5
5
|
typ-04,P1,"Line-height runs inverse to size: looser for body prose, tighter for headings.","body 1.4-1.6; headings 1.1-1.3",judged,sweep,none,"Prose text only (universality flag); dense table leading legitimately runs tighter and is exempt.",imp;new;gnu;uupm;volt/sentry,na
|
|
6
6
|
typ-05,P1,"Prose measure stays inside the readable band; data tables are exempt.","45-75ch",machine,edit,source,"Tables exempt.",imp;stitch;taste;gnu,yes
|
|
7
|
-
typ-06,P1,"At most
|
|
7
|
+
typ-06,P1,"At most three font families per app, each with a distinct job (display / body / numeric-mono); a fourth family is banned. The type scale holds the declared ramp's steps.","<=3 families; ramp steps <=7",machine,sweep,source,"<=3 families is the hard machine bound (three families require a declared numeric-mono job among them); scale conformance gates on the declared ramp (<=7 steps).",imp;new;ben;taste,yes
|
|
8
8
|
typ-07,P1,"Tabular lining numerals on every numeric column, KPI, timer, and ID.",,machine,edit,source,"The survey's single most convergent operator-table rule; font-variant-numeric on numeric contexts.",floor;new;ben;volt/stripe;volt/binance;uupm,yes
|
|
9
9
|
typ-08,P1,"All-caps micro-labels carry positive tracking; tracking never falls below the negative floor.",">=0.02em; floor >=-0.04em; caps band 0.05-0.12em",machine,edit,source,,imp;ben;taste,yes
|
|
10
|
-
typ-09,P1,"Type sizes come from a fixed rem scale, never viewport-fluid; scale steps hold the ratio band.","step ratio 1.125-1.2",machine,edit,source,"Operator surfaces; ban vw/vh/clamp on font-size.",imp,yes
|
|
10
|
+
typ-09,P1,"Type sizes come from a fixed rem scale, never viewport-fluid; scale steps hold the ratio band.","step ratio 1.125-1.2",machine,edit,source,"Operator surfaces; ban vw/vh/clamp on font-size. The fixed scale is the declared ramp's emitted utilities (text-h1 through text-display), not merely a scale.",imp,yes
|
|
11
11
|
typ-10,P1,"Adjacent type-scale steps stay at least a quarter apart.",">=25%",machine,sweep,source,"Given a declared scale.",gnu,yes
|
|
12
12
|
typ-11,P1,"No UI font weight below 400.",">=400",machine,edit,source,,gnu,yes
|
|
13
13
|
typ-12,P1,"Never size type in em; px or rem only.",,machine,edit,source,"em compounds unpredictably.",gnu,yes
|
|
@@ -18,6 +18,7 @@ typ-16,P1,"Serif faces are banned in dashboards and software UIs.",,machine,edit
|
|
|
18
18
|
typ-17,P1,"AI-default fonts are house-taste flags: Inter-as-reflex, Roboto or Arial or system-as-primary, Space Grotesk.",,judged,sweep,none,"House taste; a brand may legitimately choose Inter.",taste;stitch;ben,na
|
|
19
19
|
typ-18,P1,"Ration eyebrow and micro-label uppercase-tracking instances against section count.","<= ceil(sectionCount/3)",machine,sweep,source,"Mechanical count; marketing-scoped, rarely fires on operator surfaces.",taste,yes
|
|
20
20
|
typ-19,P1,"Code and mono type never scales down: fixed at 16px, long lines scroll horizontally rather than wrap.","16px fixed",machine,edit,source,,volt/sentry,yes
|
|
21
|
+
typ-20,P1,"The display ramp step appears only on surfaces stamped brand-forward; at most one display-step element per surface.","<=1 display element/surface",machine,gate+sweep,source,"Deterministic against the budget stamp: a display-step element on a non-brand-forward-stamped file is the violation; on a brand-forward surface the count caps at one.",v3;budget,yes
|
|
21
22
|
col-01,P2,"Non-text UI components clear the component-contrast floor: input borders, icons, focus rings.",">=3:1",machine,render,render,"Pixel-measured at the render rung.",WCAG 1.4.11,na
|
|
22
23
|
col-02,P2,"One accent, reserved for primary action, selection, and state; the accent stays below the saturation ceiling.","saturation <80%",machine,edit,source,"Saturation <80% is the machine check; the one-accent count is warning-tier judged (status palettes are additional, not accent violations).",floor;stitch;taste;volt/binance;volt/sentry,yes
|
|
23
24
|
col-03,P2,"Color is never the only signal: status always pairs with an icon or text.",,machine,render,render,"Pairing is confirmed on the rendered element (use-of-color, WCAG 1.4.1).",WCAG 1.4.1;uxui;uupm,na
|
|
@@ -33,6 +34,7 @@ col-12,P2,"AI-slop palette ban: purple and blue neon glows and gradients, purple
|
|
|
33
34
|
col-13,P2,"Semantic price and status colors are text-only, never fills, and never repurposed for generic success or error.",,machine,edit,source,"Per token set.",volt/binance,yes
|
|
34
35
|
col-14,P2,"Data-viz elements clear contrast: lines and bars against the background, data labels against theirs.","lines/bars >=3:1; labels >=4.5:1",machine,render,render,"Pixel-measured at the render rung.",uupm,na
|
|
35
36
|
col-15,P2,"One grey family per app: no warm and cool grey mixing.",,judged,sweep,none,"Warning-tier: a deliberate warm-surface/cool-chrome split is a brand decision, not drift.",taste;gnu,na
|
|
37
|
+
col-16,P2,"A wash token is consumed only on brand-forward-stamped surfaces; wash stops obey the slop ban.",,machine,gate+sweep,source,"Wash consumption (var(--wash-*)) on a non-brand-forward-stamped file is the deterministic violation; the stop vocabulary itself (col-12 slop ban) is admitted at the artifact gate.",v3;budget,yes
|
|
36
38
|
spc-01,P3,"Every spacing value lands on the declared 4/8-based scale.","standard 4/8/12/16/24/32/48/64/96px; dense 2/4/8/12/16/24/32px; monotony ceiling >=10 identical",machine,edit,source,"On-scale conformance is the machine core; the monotony sub-check (>=10 identical) does not apply to operator surfaces, where uniform row/cell rhythm is deliberate (universality flag).",gnu;ben;taste;uupm;imp;new,yes
|
|
37
39
|
spc-02,P3,"Adjacent spacing values stay at least a quarter apart.",">=25%",machine,sweep,source,"On the declared spacing scale.",gnu,yes
|
|
38
40
|
spc-03,P3,"Click and tap targets clear the minimum target size (WCAG 2.2 SC 2.5.8); touch-primary surfaces go larger.",">=24x24px; >=44px touch; dense-row 28px; >=8px spacing exception",machine,render,render,"Assembled as one SC 2.5.8 (spatial + interaction restatement); dense data-row controls compact to 28px; undersized allowed only via the >=8px target-spacing exception (int-11). Actual geometry measured at render.",WCAG 2.5.8;HIG;volt/binance;wcag22;deep-research,na
|
|
@@ -48,6 +50,7 @@ spc-12,P3,"Section rhythm runs tighter on dense product pages than marketing.","
|
|
|
48
50
|
spc-13,P3,"Cockpit rule above the density threshold: no card boxes, hairline dividers, tight padding, mono numbers.","density >7",judged,sweep,none,"Warning-tier, dial-conditional: fires only at the declared dense tier.",taste,na
|
|
49
51
|
spc-14,P3,"Content-overload ceilings on action areas, elements, visible required fields, and nav items.",">7 action areas; 15+ elements; 12+ required fields; nav 5-9",judged,sweep,none,"Warning-tier: dense operator surfaces legitimately exceed the element counts.",uxui,na
|
|
50
52
|
spc-15,P3,"Grid and bento integrity: N items fill exactly N cells, no orphan corners, spans interlock.",,machine,render,render,"Mechanical fill; actual cell occupancy confirmed at render (dynamic lists are not statically countable).",taste,na
|
|
53
|
+
spc-16,P3,"In fixed-width table and grid cells, rendered text fits the cell: no overlap or clip without a truncate or scroll affordance.",,machine,render,render,"Actual overflow measured on the rendered DOM at the render rung; fixed-width cells only.",v3;render,na
|
|
51
54
|
dep-01,P4,"z-index values come only from a declared scale; ban arbitrary values.","scale 0/10/20/40/100/1000; ban 999; ban 9999",machine,edit,source,,new;uupm;stitch,yes
|
|
52
55
|
dep-02,P5,"One h1 per view; heading levels never skip.","one h1",machine,sweep,source,"Whole-app cross-file check.",new;uupm,yes
|
|
53
56
|
dep-03,P5,"Dashboard holds a small set of primary metrics above the fold.","<=~4",judged,sweep,none,"Non-deterministic threshold; primary metric is not machine-detectable and command centers legitimately exceed (universality flag).",imp,na
|
|
@@ -77,7 +80,7 @@ mot-04,B2,"Ban spring and bounce easing on operator surfaces and ban linear ever
|
|
|
77
80
|
mot-05,B2,"Animate only transform and opacity, never top, left, width, height, or margin.",,machine,edit,source,"The survey's most convergent motion rule.",ben;stitch;taste;uupm,yes
|
|
78
81
|
mot-06,B2,"will-change only rides an in-progress transform or opacity animation, never blanket, never left dangling.",,machine,edit,source,,D26,yes
|
|
79
82
|
mot-07,B2,"Loading indicators skeleton the content shape, delay to avoid flash, and follow the wait-time thresholds.","delay 150-300ms; nothing <500ms; spinner/skeleton 500ms-2s; progress bar >2s",machine,edit,source,"Partial.",new;stitch;uupm;ben,yes
|
|
80
|
-
mot-08,B2,"Stagger children by
|
|
83
|
+
mot-08,B2,"Stagger children by the stagger-unit token's per-item delay, capped in count and total sequence length; baseline-stamped surfaces skip arrival cascades.","stagger-unit 0-60ms/item; cap 8 children; total <1s",machine,edit+render,source,"The numeric half is machine: per-item delays check against the stagger-unit token at source, child count and total sequence length confirm on the DOM at the render rung. The orchestration boundary rides the budget stamp — baseline-stamped surfaces skip arrival cascades; brand-forward surfaces may run motion-stagger.",uupm;taste,yes
|
|
81
84
|
mot-09,B2,"Ban scroll-event listeners for animation; observers or scrubbing only.","window.addEventListener('scroll')",machine,edit,source,,taste,yes
|
|
82
85
|
mot-10,B2,"Ban useState for continuous scroll or pointer values; motion values instead.",,machine,edit,source,"Framework-scoped (React).",taste,yes
|
|
83
86
|
mot-11,B2,"Exit runs shorter than enter; press scale stays in the tight band; few animated elements per view.","exit 60-70% of enter; press scale 0.95-1.05; <=1-2 elements",judged,sweep,none,"Warning-tier: coordinated pairs legitimately exceed the element cap.",uupm,na
|
|
@@ -87,7 +90,7 @@ sta-03,B5,"Error copy follows the formula: what happened, why, how to fix; ban d
|
|
|
87
90
|
sta-04,B1,"Errors render inline next to the offending field, not banner-only; every error is visible.",,judged,sweep,none,"Warning-tier: system-wide failures legitimately banner.",uxui,na
|
|
88
91
|
sta-05,B1,"Toasts auto-dismiss in the short band, announce politely, and never steal focus.","3-5s; aria-live polite",machine,edit,source,"Attrs.",uupm,yes
|
|
89
92
|
sta-06,B1,"Empty-state taxonomy: first-time, user-cleared, no-results, no-access, and error are distinct states with distinct copy.",,judged,sweep,none,"Judgment on which state applies; presence is machine once the state is declared.",gnu,na
|
|
90
|
-
cod-01,S3,"Emitted CSS defines every token the substrate consumes.",,machine,gate,source,"Coverage check over the full
|
|
93
|
+
cod-01,S3,"Emitted CSS defines every token the substrate consumes.",,machine,gate,source,"Coverage check over the full schema-v2 token surface (36 color roles, elevation, wash, the ramp utilities) at token emission.",D6,yes
|
|
91
94
|
cod-02,S3,"On improve runs, every value stays inside the lever manifest's vocabulary.",,machine,edit,source,"The D10 golden-rule drift check.",D10,yes
|
|
92
95
|
cod-03,S3,"Every color, spacing, radius, and duration in a diff resolves to an emitted token.","",machine,edit,source,"Token-lock; the survey's only script-proven enforcement pattern (stitch validate.js + uupm resolver).",stitch;uupm,yes
|
|
93
96
|
cod-04,S2,"No elision comments; files compile before done.","",machine,edit,source,"Bans rest-of-code, ellipsis-comment, TODO, and for-brevity markers; files-compile is verified at the compile rung.",taste;stitch,yes
|
|
@@ -101,6 +104,8 @@ cod-11,S2,"Every emitted component exports a typed Props interface; no HTML tags
|
|
|
101
104
|
cod-12,S4,"Runtime perf budgets: LCP, INP, CLS, and frame time.","LCP <2.5s; INP <200ms; CLS <0.1; 16ms frame",machine,render,render,"Runtime metrics measured at the render rung.",taste;uupm,na
|
|
102
105
|
cod-13,B5,"Audit output carries a numeric before to after per finding; no vague language, no feels without a measurable change.",,judged,sweep,none,"The D22 finding-schema contract, enforced by self-integrity over findings rather than the UI check engine.",ben,na
|
|
103
106
|
cod-14,B5,"One name per concept, one concept per name, across UI copy, help text, and API names.",,judged,sweep,none,"Legacy-locked internal names may lag a renamed label; divergence must be deliberate, never accidental.",jam,na
|
|
107
|
+
cod-15,S3,"Per-theme rendered token drift: under each theme context the resolver declares, rendered background, foreground, and primary equal that context's authored values.","--background; --foreground; --primary",machine,render,render,"Measured on the rendered surface per declared theme context at the render rung; the dark armor's authored values are the ground truth.",v3;emission,na
|
|
108
|
+
cod-16,S2,"Every family name in an emitted font stack binds to an installed package's registered family or a system generic.",,machine,gate,source,"Fail-closed at derive-personality --emit (stack vs package.json binding); the source shell checks each named stack family against a registering @fontsource import or @font-face in the emitted CSS, or the system-generic set.",v3;emission,yes
|
|
104
109
|
inst-01,P5,"Edge density: Canny edge pixels over total pixels, the cheapest instrument, start here.","Canny edges / pixels; r~0.83 with visual-search times",judged,render,render,"Instrument, never a gate: dense is not bad (lower-complexity-is-better refuted 0-3); a number is evidence inside a judged finding, never a verdict.",rosenholtz 2007;deep-research,na
|
|
105
110
|
inst-02,P5,"Feature congestion of the rendered surface.",,judged,render,render,"Instrument, never a gate: dense is not bad; evidence inside a judged finding, never a verdict.",rosenholtz 2007;deep-research,na
|
|
106
111
|
inst-03,P5,"Subband entropy of the rendered surface.",,judged,render,render,"Instrument, never a gate: dense is not bad; evidence inside a judged finding, never a verdict.",rosenholtz 2007;deep-research,na
|
|
@@ -111,7 +116,7 @@ inst-07,P5,"Figure-ground contrast of the surface.",,judged,render,render,"Instr
|
|
|
111
116
|
inst-08,P5,"Contour congestion of the surface.",,judged,render,render,"Instrument, never a gate: dense is not bad; evidence inside a judged finding, never a verdict.",miniukovich CHI'15;aalto-ui/aim;deep-research,na
|
|
112
117
|
inst-09,P2,"Colorfulness of the surface.",,judged,render,render,"Instrument, never a gate: dense is not bad; evidence inside a judged finding, never a verdict.",miniukovich CHI'15;aalto-ui/aim;deep-research,na
|
|
113
118
|
inst-10,P2,"Distinct-RGB count of the surface.",,judged,render,render,"Instrument, never a gate: dense is not bad; evidence inside a judged finding, never a verdict.",miniukovich CHI'15;aalto-ui/aim;deep-research,na
|
|
114
|
-
inst-11,B1,"KLM operator-cost of the core loop: sum the typed operators over a fixed path.","P=1.10s; H=0.40s; M=1.35s; K=0.20-0.28s; klm-fa 89.1% agreement",judged,render,render,"Comparative cost model, not throughput ground truth; a judged diagnosis dimension pairing with the D28 core loop and floor
|
|
119
|
+
inst-11,B1,"KLM operator-cost of the core loop: sum the typed operators over a fixed path.","P=1.10s; H=0.40s; M=1.35s; K=0.20-0.28s; klm-fa 89.1% agreement",judged,render,render,"Comparative cost model, not throughput ground truth; a judged diagnosis dimension pairing with the D28 core loop and floor f01 throughput; countable clicks, keystrokes, tab-stops, and homings given a fixed path.",card-moran-newell;al-megren 2018;deep-research,na
|
|
115
120
|
trust-01,B1,"AI presence is disclosed on the surface.",,judged,sweep,none,"Absence grades auto-critical (D34).",D34,na
|
|
116
121
|
trust-02,B1,"A human override path is visible.",,judged,sweep,none,"Absence grades auto-critical (D34).",D34,na
|
|
117
122
|
trust-03,B1,"AI-initiated irreversible actions are consent-gated with a preview.",,judged,sweep,none,"Absence grades auto-critical (D34).",D34,na
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Combinations — the consumption contract
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Eight curated pick tables — typography pairings, palettes, movement styles, motion moments, product-router priors, chart choices, icon picks, landing patterns — plus [`accent-presets.md`](accent-presets.md), the accent-scale reference, that ground the skill's picks in vetted combinations instead of free association. Rows carry a tier: **operator-active** rows are consumable; **dormant-marketing** rows are ignored by operator work — no operator run reads them; they await a future marketing pack. Presence on disk is not consumption: every dataset declares its consumer steps below, and the routing path loads the table into context mechanically at each declared step — consulting is not skippable, exactly like the boot prose.
|
|
4
4
|
|
|
5
5
|
## The contract
|
|
6
6
|
|
|
@@ -8,18 +8,22 @@ Seven curated pick tables — typography pairings, palettes, movement styles, pr
|
|
|
8
8
|
| --- | --- | --- | --- |
|
|
9
9
|
| `typography.csv` | intake — only when the look resolves to authoring a fresh artifact (not a library copy / default); tokens — loaded before any typography hint is resolved | — (emission is jailed to the lever manifest) | — |
|
|
10
10
|
| `palettes.csv` | intake — fresh-artifact authoring only; tokens — loaded before any color hint is resolved | — | — |
|
|
11
|
-
| `styles.csv` | intake — fresh-artifact authoring only (movement vocabulary for the look) | — | — |
|
|
12
|
-
| `
|
|
11
|
+
| `styles.csv` | intake — fresh-artifact authoring only (movement vocabulary for the look); preship — the picked row's `checklist` column is walked item by item (the did-the-look-land sweep) | — | — |
|
|
12
|
+
| `accent-presets.md` | tokens — loaded at accent hint-resolution: the 12 pre-vetted 7-step OKLCH scales are the floor for a fresh artifact's accent | — | — |
|
|
13
|
+
| `motion.csv` | surfaces — loaded at the emission gate of any surface that composes motion, beside `charts.csv` / `icons.csv`; budget-gated: `baseline` rows serve every surface, `brand-forward` rows only surfaces stamped brand-forward | — | — |
|
|
14
|
+
| `product-router.csv` | intake — always: the front gate's recognition assist and the digest's density/archetype priors; also the brief-keyed resolution router — the brief's traits (domain, product type, tone words) filter `styles.csv` / `palettes.csv` / `typography.csv` to the 2–3-row shortlist that enters context at the pick moment (Moment 1b) | — | — |
|
|
13
15
|
| `charts.csv` | surfaces — loaded at the emission gate of any surface that composes a chart | fix step — when a finding names a chart | diagnosis — when the audited UI renders charts |
|
|
14
16
|
| `icons.csv` | surfaces — loaded once at the first surface-composition gate (icon picks happen throughout) | fix step — when a finding names an icon | — |
|
|
15
17
|
| `landing.csv` | — dormant; no load point anywhere (activation = a future marketing pack) | — | — |
|
|
16
18
|
|
|
19
|
+
The `judge` verb loads the resolved style row's `checklist` as well — the same items the preship sweep walks, scored against the rendered UI as the did-the-look-land referent.
|
|
20
|
+
|
|
17
21
|
## The deviation rule
|
|
18
22
|
|
|
19
23
|
A consulted table is a **floor** — going off-table is allowed only against a stated reason recorded into what the run produces:
|
|
20
24
|
|
|
21
25
|
- **look values** (a pairing, a palette) — the token's `$description`;
|
|
22
|
-
- **surface picks** (a chart type, an icon) — a code comment adjacent to the deviating pick;
|
|
26
|
+
- **surface picks** (a chart type, an icon, a motion moment) — a code comment adjacent to the deviating pick;
|
|
23
27
|
- **improve / introspect** — the finding body.
|
|
24
28
|
|
|
25
29
|
An unrecorded off-table pick is a violation, the same class as skipping a gate.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# data/combinations/accent-presets.md
|
|
2
|
+
|
|
3
|
+
**Load when:** accent choice or override (user picks an accent, or override request).
|
|
4
|
+
|
|
5
|
+
Pre-vetted accent palettes per neutral temperature. Each entry: accent name + 7-step OKLCH scale + WCAG contrast pass against neutral-50 (light bg) and neutral-950 (dark bg).
|
|
6
|
+
|
|
7
|
+
**One accent by default; reach for a second only when the active style genuinely requires it** (a status-coded or multi-accent style row). Status colors (emerald / amber / rose / violet / zinc — see `status-palettes.md`) don't count against this — they're semantic, not decorative accents.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## How to use
|
|
12
|
+
|
|
13
|
+
1. User picks an accent (or overrides the default).
|
|
14
|
+
2. Emit the chosen accent's 7-step scale into `personality.css`:
|
|
15
|
+
|
|
16
|
+
```css
|
|
17
|
+
:root,
|
|
18
|
+
:root[data-theme="light"] {
|
|
19
|
+
--color-accent-50: /* from table below */;
|
|
20
|
+
--color-accent-100: /* ... */;
|
|
21
|
+
--color-accent-300: /* ... */;
|
|
22
|
+
--color-accent-500: /* ... */;
|
|
23
|
+
--color-accent-600: /* ... */;
|
|
24
|
+
--color-accent-700: /* ... */;
|
|
25
|
+
--color-accent-900: /* ... */;
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
3. Update `personality.css` header comment to capture which accent and why.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Accent table
|
|
34
|
+
|
|
35
|
+
| Accent | Use case | 50 | 100 | 300 | 500 | 600 | 700 | 900 | Light bg contrast | Dark bg contrast |
|
|
36
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
37
|
+
| **emerald** (default) | Status-rich CRM; "active" emphasis | `oklch(0.97 0.02 165)` | `oklch(0.93 0.06 165)` | `oklch(0.80 0.13 165)` | `oklch(0.69 0.18 165)` | `oklch(0.60 0.18 165)` | `oklch(0.50 0.18 165)` | `oklch(0.30 0.18 165)` | AA / AAA | AAA / AA |
|
|
38
|
+
| **indigo** | Generic SaaS; trust-building | `oklch(0.97 0.02 270)` | `oklch(0.93 0.06 270)` | `oklch(0.78 0.13 270)` | `oklch(0.55 0.20 270)` | `oklch(0.47 0.20 270)` | `oklch(0.39 0.20 270)` | `oklch(0.25 0.18 270)` | AAA / AAA | AAA / AAA |
|
|
39
|
+
| **violet** | Power tools; technical UIs | `oklch(0.97 0.02 295)` | `oklch(0.93 0.06 295)` | `oklch(0.78 0.13 295)` | `oklch(0.55 0.22 295)` | `oklch(0.48 0.22 295)` | `oklch(0.40 0.22 295)` | `oklch(0.25 0.20 295)` | AA / AAA | AAA / AAA |
|
|
40
|
+
| **rose** | Critical workflows; alert-prone domains | `oklch(0.97 0.02 15)` | `oklch(0.93 0.06 15)` | `oklch(0.78 0.13 15)` | `oklch(0.62 0.22 15)` | `oklch(0.55 0.22 15)` | `oklch(0.45 0.22 15)` | `oklch(0.30 0.20 15)` | AA / AAA | AAA / AA |
|
|
41
|
+
| **amber** | Warehouses; logistics; energy | `oklch(0.97 0.04 100)` | `oklch(0.94 0.09 95)` | `oklch(0.84 0.14 90)` | `oklch(0.78 0.16 80)` | `oklch(0.70 0.17 75)` | `oklch(0.60 0.17 70)` | `oklch(0.40 0.16 65)` | A / AAA | AAA / A (caution) |
|
|
42
|
+
| **teal** | Healthcare; calm clinical UIs | `oklch(0.97 0.02 195)` | `oklch(0.93 0.06 195)` | `oklch(0.78 0.12 195)` | `oklch(0.60 0.13 195)` | `oklch(0.52 0.13 195)` | `oklch(0.43 0.13 195)` | `oklch(0.28 0.12 195)` | AA / AAA | AAA / AAA |
|
|
43
|
+
| **sky** | Customer support; conversational | `oklch(0.97 0.02 225)` | `oklch(0.93 0.06 225)` | `oklch(0.80 0.13 225)` | `oklch(0.68 0.15 225)` | `oklch(0.58 0.16 225)` | `oklch(0.48 0.17 225)` | `oklch(0.30 0.16 225)` | AA / AAA | AAA / AAA |
|
|
44
|
+
| **blue** | Traditional enterprise | `oklch(0.97 0.02 245)` | `oklch(0.93 0.06 245)` | `oklch(0.78 0.13 245)` | `oklch(0.55 0.20 245)` | `oklch(0.47 0.20 245)` | `oklch(0.39 0.20 245)` | `oklch(0.25 0.18 245)` | AAA / AAA | AAA / AAA |
|
|
45
|
+
| **pink** | Brand-driven; younger ops teams | `oklch(0.97 0.02 0)` | `oklch(0.93 0.06 0)` | `oklch(0.80 0.15 0)` | `oklch(0.67 0.22 0)` | `oklch(0.58 0.22 0)` | `oklch(0.48 0.22 0)` | `oklch(0.30 0.20 0)` | AA / AAA | AAA / AAA |
|
|
46
|
+
| **orange** | High-energy; field service | `oklch(0.97 0.04 50)` | `oklch(0.93 0.09 50)` | `oklch(0.82 0.15 50)` | `oklch(0.70 0.19 50)` | `oklch(0.62 0.19 50)` | `oklch(0.52 0.19 50)` | `oklch(0.32 0.17 50)` | A / AAA | AAA / A (caution) |
|
|
47
|
+
| **zinc (mono)** | Plain / cron archetypes; no accent | `oklch(0.97 0 0)` | `oklch(0.93 0 0)` | `oklch(0.80 0 0)` | `oklch(0.55 0 0)` | `oklch(0.44 0 0)` | `oklch(0.37 0 0)` | `oklch(0.20 0 0)` | n/a (mono) | n/a (mono) |
|
|
48
|
+
| **stone (warm mono)** | Plain archetype with warm-zinc | `oklch(0.97 0.005 80)` | `oklch(0.93 0.006 80)` | `oklch(0.80 0.008 80)` | `oklch(0.55 0.012 80)` | `oklch(0.44 0.013 80)` | `oklch(0.37 0.014 80)` | `oklch(0.20 0.016 80)` | n/a (mono) | n/a (mono) |
|
|
49
|
+
|
|
50
|
+
Contrast pass legend:
|
|
51
|
+
|
|
52
|
+
- **AAA** ≥ 7:1 (text-on-bg comfortable for body text)
|
|
53
|
+
- **AA** 4.5–7:1 (large text or body, depending on size)
|
|
54
|
+
- **A** 3:1–4.5:1 (UI elements only, not body text)
|
|
55
|
+
- **caution** — pass for large text only; check before using as body text
|
|
56
|
+
|
|
57
|
+
`amber` and `orange` on dark backgrounds need careful handling — pair with text-foreground or a darker swatch.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Picking by neutral temperature
|
|
62
|
+
|
|
63
|
+
| Neutral temperature (archetype) | Avoid | Good fits |
|
|
64
|
+
| --- | --- | --- |
|
|
65
|
+
| **Cool slate** (linear / cron) | amber, orange (clash) | indigo, blue, sky, violet, teal |
|
|
66
|
+
| **True gray** (stripe / pylon / default-soft) | (anything OK; gray is neutral) | emerald, indigo, violet, sky, pink |
|
|
67
|
+
| **Warm zinc** (plain) | sky, blue (clash) | emerald, teal, amber, orange, stone, rose |
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## Picking by use case
|
|
72
|
+
|
|
73
|
+
- **Default operator UI** → emerald (the default — works with `stripe`, plays nicely with status colors)
|
|
74
|
+
- **CRM / sales tools** → indigo (trust-building) or sky (conversational)
|
|
75
|
+
- **Healthcare / clinical** → teal (calm) or blue (traditional)
|
|
76
|
+
- **Logistics / warehouses** → amber (high-visibility) or orange (high-energy)
|
|
77
|
+
- **Engineering / DevOps** → violet or blue
|
|
78
|
+
- **Security / monitoring** → indigo (calm authority)
|
|
79
|
+
- **Plain or cron archetype** → zinc or stone (mono, no accent)
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Dark theme handling
|
|
84
|
+
|
|
85
|
+
For light themes, `--primary` typically resolves to `--color-accent-600`. For dark themes, `--primary` stays at `--color-accent-600` but text-on-accent uses the lighter swatches:
|
|
86
|
+
|
|
87
|
+
```css
|
|
88
|
+
[data-theme="dark"] {
|
|
89
|
+
--accent: var(--color-neutral-800); /* the surface */
|
|
90
|
+
--accent-foreground: var(--color-accent-300); /* text */
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Don't lighten `--primary` in dark mode — it gets washed out. Keep `--primary` at the same OKLCH; foreground stays white.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Inline-comment rationale
|
|
99
|
+
|
|
100
|
+
Capture the accent choice in `personality.css`:
|
|
101
|
+
|
|
102
|
+
```css
|
|
103
|
+
/* Accent: indigo — chosen for a traditional enterprise CRM where users expect
|
|
104
|
+
"trust-building" blue tones. Considered emerald (default) but the project's
|
|
105
|
+
existing brand uses indigo. */
|
|
106
|
+
:root {
|
|
107
|
+
--color-accent-500: oklch(0.55 0.2 270);
|
|
108
|
+
--color-accent-600: oklch(0.47 0.2 270);
|
|
109
|
+
--color-accent-700: oklch(0.39 0.2 270);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Rationale lives next to the values. No sidecar JSON cache.
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "design-combinations-manifest/v1",
|
|
3
|
-
"generated": "2026-07-
|
|
4
|
-
"
|
|
3
|
+
"generated": "2026-07-08",
|
|
4
|
+
"provenance": "Provenance: google-fonts.csv (1,924 families) — the upstream ui-ux-pro-max canonical catalog (inspirations/nextlevelbuilder.ui-ux-pro-max-skill src/ui-ux-pro-max/data/google-fonts.csv) — is not imported wholesale; fonts-known.json plus typography.csv's css-import column cover font-availability resolution.",
|
|
5
|
+
"note": "Provenance ledger for the eight combination datasets plus the accent-presets.md reference. Maintainer-facing. Refresh is trigger-based, never calendar-based — each dataset's refresh_trigger names the event that invalidates it. Datasets were regenerated by deep-research runs seeded from the ui-ux-pro-max canonical corpus (submodule) and v1's brand CSVs; a richer source displaces even the seed. Tiers: operator-active rows are consumed by operator work; dormant-marketing rows ship full-breadth and self-contained, ignored until a marketing pack activates them.",
|
|
5
6
|
"tiers": {
|
|
6
7
|
"operator-active": "consumed by the operator pack (create/improve/introspect)",
|
|
7
8
|
"dormant-marketing": "carried, self-contained, ignored by operator work; activated by a future marketing pack"
|
|
8
9
|
},
|
|
9
10
|
"datasets": {
|
|
10
11
|
"typography.csv": {
|
|
12
|
+
"source": "docs/features/design-skill/data/source-csv/typography.csv (+ docs/features/design-skill/data/operator-arsenal.md for the mono_family/display-size-hint values)",
|
|
13
|
+
"imported": "2026-07-08",
|
|
11
14
|
"seed": {
|
|
12
15
|
"source": "inspirations/nextlevelbuilder.ui-ux-pro-max-skill src/ui-ux-pro-max/data/typography.csv",
|
|
13
16
|
"date": "2026-07-06",
|
|
@@ -38,13 +41,15 @@
|
|
|
38
41
|
"evidence": "A generator read google-fonts.csv, and each of the 60 rows was emitted only after asserting its three families exist and intersecting the desired ramp with the family's actual Styles weights, so unavailable weights are impossible by construction; a post-write pass re-parsed the CSV and confirmed every family+weight in every heading/body cell and every mono_family value is present in fonts-known.json (83 families, exact set match, zero extras or gaps); the seed's Fontshare-only Satoshi/General Sans/Clash Display were removed; mono_family is populated on all 60 rows where the seed had none; contrast is computed from a documented family classifier (sans/serif/mono, with decorative and handwriting faces treated as display and serifed display faces Abril Fatface/Calistoga treated as serif) yielding only the six allowed enum values; all 60 notes are original one-sentence descriptions, not lifted from the all-rights-reserved upstream; RFC-4180 quoting, UTF-8 no BOM, ASCII-only, trailing newline, uniform 13 columns all verified"
|
|
39
42
|
},
|
|
40
43
|
"rows": {
|
|
41
|
-
"total":
|
|
42
|
-
"operator_active":
|
|
43
|
-
"dormant_marketing":
|
|
44
|
+
"total": 63,
|
|
45
|
+
"operator_active": 39,
|
|
46
|
+
"dormant_marketing": 24
|
|
44
47
|
},
|
|
45
48
|
"refresh_trigger": "a Google Fonts availability change (family or weight added/removed) or a substrate font-stack change in the typography.family.* tokens"
|
|
46
49
|
},
|
|
47
50
|
"palettes.csv": {
|
|
51
|
+
"source": "docs/features/design-skill/data/source-csv/colors.csv",
|
|
52
|
+
"imported": "2026-07-08",
|
|
48
53
|
"seed": {
|
|
49
54
|
"source": "inspirations/nextlevelbuilder.ui-ux-pro-max-skill src/ui-ux-pro-max/data/colors.csv",
|
|
50
55
|
"date": "2026-07-06",
|
|
@@ -71,13 +76,15 @@
|
|
|
71
76
|
"evidence": "Independent validator re-read the written CSV: parsed 48 data rows; contrast checks: 864, contrast failures: 0; tiers operator-active=34, dormant-marketing=14; total problems: 0; RESULT: 0 failures - every row passes 11 foreground/base pairs at >=4.5:1 and 7 signal roles (success, warning, chart-1..5) at >=3:1 against its own background across all 34 roles, versus the 192-row seed that covered only 17 roles with admitted post-hoc WCAG patches"
|
|
72
77
|
},
|
|
73
78
|
"rows": {
|
|
74
|
-
"total":
|
|
75
|
-
"operator_active":
|
|
79
|
+
"total": 91,
|
|
80
|
+
"operator_active": 77,
|
|
76
81
|
"dormant_marketing": 14
|
|
77
82
|
},
|
|
78
83
|
"refresh_trigger": "a token-surface change (color role added or removed in the design-tokens schema)"
|
|
79
84
|
},
|
|
80
85
|
"styles.csv": {
|
|
86
|
+
"source": "docs/features/design-skill/data/source-csv/styles.csv",
|
|
87
|
+
"imported": "2026-07-08",
|
|
81
88
|
"seed": {
|
|
82
89
|
"source": "ui-ux-pro-max styles.csv (84) + v1 design.csv (~200 descriptions, absorbed by merge)",
|
|
83
90
|
"date": "2026-07-06",
|
|
@@ -112,12 +119,52 @@
|
|
|
112
119
|
"seed_note": "seed.rows=284 retained from the orchestrator's given fragment (84 + the seed's '~200' line estimate); the v1 design.csv actually holds 17 distinct named movements, all absorbed."
|
|
113
120
|
},
|
|
114
121
|
"rows": {
|
|
115
|
-
"total":
|
|
116
|
-
"operator_active":
|
|
117
|
-
"dormant_marketing":
|
|
122
|
+
"total": 66,
|
|
123
|
+
"operator_active": 26,
|
|
124
|
+
"dormant_marketing": 40
|
|
118
125
|
},
|
|
119
126
|
"refresh_trigger": "a doctrine-floor change (hard-rules families added or changed)"
|
|
120
127
|
},
|
|
128
|
+
"motion.csv": {
|
|
129
|
+
"source": "docs/features/design-skill/data/source-csv/motion.csv",
|
|
130
|
+
"imported": "2026-07-08",
|
|
131
|
+
"seed": {
|
|
132
|
+
"source": "docs/features/design-skill/data/source-csv/motion.csv",
|
|
133
|
+
"date": "2026-07-08",
|
|
134
|
+
"rows": 16
|
|
135
|
+
},
|
|
136
|
+
"research": {
|
|
137
|
+
"run": "2026-07-08",
|
|
138
|
+
"sources": [
|
|
139
|
+
"design-tokens SCHEMA.md temporal primitives - every row's physics keyed to the stored duration tokens (duration-unit/fast/normal/slow, plus the v2 stagger-unit) and to ease-default with its emit-derived ease-enter/ease-exit pair",
|
|
140
|
+
"hard-rules motion family (mot-03..mot-09) - the admission filter: no springs, no page-load orchestration, transform/opacity-only physics, the 8-child stagger cap, reduced-motion behavior stated per row"
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
"displacements": [
|
|
144
|
+
"16 GSAP-keyed seed recipes translated to CSS transition/keyframe form and reduced to 9 operator moments; spring/bounce easings, scroll-jacked choreography, and page-load orchestration recipes were not carried (mot-04)",
|
|
145
|
+
"seed pixel-and-milliseconds physics generalized to token names: durations to duration-fast/normal/slow and duration-unit multiples, easings to ease-default/ease-enter/ease-exit, shadow growth to elevation.sm/elevation.overlay, per-item delays to --stagger-delay",
|
|
146
|
+
"a budget gate column added per row (baseline vs brand-forward) so surface stamps can filter arrival choreography mechanically (mot-08); archetype applicability restated in the closed-six vocabulary"
|
|
147
|
+
],
|
|
148
|
+
"quality_bar": {
|
|
149
|
+
"criterion": "every row keyed to legal temporal token names (no raw ms-only or GSAP physics), archetypes drawn only from the closed six, budget machine-readable, do/dont/performance prose citing the governing mot-* rules",
|
|
150
|
+
"verdict": "beats-seed",
|
|
151
|
+
"evidence": "all 9 rows pass validate-combinations.mjs: duration_token and easing_token cells reference only the schema's temporal vocabulary, archetypes validate against the closed six, budget validates as baseline|brand-forward (5 baseline, 4 brand-forward); the seed's GSAP snippets and raw millisecond values appear nowhere in the output"
|
|
152
|
+
},
|
|
153
|
+
"rows": {
|
|
154
|
+
"total": 9,
|
|
155
|
+
"operator_active": 9,
|
|
156
|
+
"dormant_marketing": 0
|
|
157
|
+
},
|
|
158
|
+
"refresh_trigger": "a temporal-primitive change in the design-tokens schema (duration/easing tokens added or renamed) or a motion-rule family change (mot-*)"
|
|
159
|
+
},
|
|
160
|
+
"accent-presets.md": {
|
|
161
|
+
"source": "docs/features/design-skill/data/accent-presets.md",
|
|
162
|
+
"imported": "2026-07-08",
|
|
163
|
+
"scales": 12,
|
|
164
|
+
"steps_per_scale": 7,
|
|
165
|
+
"note": "12 pre-vetted 7-step OKLCH accent scales with per-step WCAG grades against light and dark backgrounds plus the neutral-temperature clash matrix; the hint-resolution reference the tokens phase loads when composing a fresh artifact's accent",
|
|
166
|
+
"refresh_trigger": "an accent-scale addition or removal, or a WCAG-grade recomputation of the preset scales"
|
|
167
|
+
},
|
|
121
168
|
"product-router.csv": {
|
|
122
169
|
"seed": {
|
|
123
170
|
"source": "ui-ux-pro-max products.csv (192) + ui-reasoning.csv (161), merged",
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
id,moment,tier,keywords,trigger,duration_token,easing_token,transform_delta,archetypes,budget,do,dont,performance_notes
|
|
2
|
+
1,control-hover-feedback,operator-active,"hover, button, control, press feedback, acknowledge",hover,duration-normal,ease-default,translateY(-1px); opacity 0.92,list-detail;dashboard;entity-detail;create-edit;log-stream;command-center,baseline,"Hold the nudge to a single pixel so it registers as acknowledgement rather than travel; mirror the exact reverse on pointer-out.","Never move layout-affecting properties on hover - width, height, and margin stay fixed; transform and opacity only (mot-05).","Transform plus opacity keeps the response on the compositor thread; bind enter and leave as a matched pair so a fast pointer exit never strands the raised state."
|
|
3
|
+
2,row-hover-lift,operator-active,"hover, row, card, lift, elevation, motion-lift",hover,duration-normal,ease-default,translateY(-2px); shadow none -> elevation.sm,list-detail;dashboard;entity-detail;command-center,baseline,"Ships as the motion-lift utility class; pair the 2px rise with a one-step shadow growth to elevation.sm so depth and displacement agree.","No scale and no lift past 2px on operator surfaces - larger displacement reads as animation instead of feedback, and hardcoded shadow values are out: the growth targets the elevation tokens.","Define the transition once on the shared class rather than per-element inline styles when a screen holds many hoverable rows; shadow interpolation at elevation.sm scale is paint-cheap."
|
|
4
|
+
3,section-arrival-fade,operator-active,"arrival, fade, section, viewport, reveal",viewport-enter,duration-slow,ease-enter,opacity 0 -> 1; translateY(8px) -> 0,dashboard;entity-detail,brand-forward,"Keep the rise inside 8-16px so the entrance reads as a fade with weight rather than a slide; fire once per section on first viewport entry via IntersectionObserver (mot-09).","Never leave content that must be crawlable or usable without JS in an invisible-by-default state, and never wire the trigger to scroll events - observe entry instead (mot-09).","One observer per section container, disconnected after the first fire; baseline-stamped surfaces skip this moment entirely (mot-08)."
|
|
5
|
+
4,list-arrival-stagger,operator-active,"list, table, arrival, stagger, cascade, motion-stagger",data-load,duration-slow,ease-enter,opacity 0 -> 1; translateY(8px) -> 0; per-item delay --stagger-delay,list-detail;dashboard,brand-forward,"Ships as the motion-stagger utility; the per-item delay rides --stagger-delay (stagger-unit, 30-50ms band) and items are targeted by stable data attributes so re-renders keep their targets.","Cap the cascade at 8 children - items past the cap mount instantly (mot-08); never replay the cascade on pagination, sort, filter, or live append, and never run it on baseline-stamped surfaces.","Total sequence stays under 1s by construction (8 children x 50ms ceiling plus duration-slow); virtualized lists animate only the items actually mounted."
|
|
6
|
+
5,card-grid-arrival-stagger,operator-active,"grid, cards, kpi, arrival, stagger, wave",viewport-enter or data-load,duration-slow,ease-enter,opacity 0 -> 1; scale(0.96) -> 1; translateY(12px) -> 0; per-item delay --stagger-delay,dashboard;command-center,brand-forward,"Order the wave from the reading start (top-left) so the eye lands with the layout; a bento arrangement may radiate the order from its center card instead.","No overshoot or bounce easing on data-bearing cards - the admitted curve is ease-enter (mot-04); never stagger more than 8 cards or the tail feels laggy.","Toggle one class on the grid container and let per-item delays do the sequencing; observe the container once rather than each card (mot-09). Brand-forward surfaces only (mot-08)."
|
|
7
|
+
6,view-crossfade,operator-active,"route, view, navigation, crossfade, transition",route-change,duration-fast (exit) / duration-normal (enter),ease-exit (out) / ease-enter (in),opacity 1 -> 0 on exit; opacity 0 -> 1 on enter,list-detail;dashboard;entity-detail;create-edit;log-stream;command-center,brand-forward,"Resolve the exit faster than the entry so back and forward feel immediate; begin prefetching the destination view's critical data during the exit fade.","Never block navigation on the animation - the route swap proceeds regardless of tween state; no full-screen wipes, curtains, or shared-element morphs (mot-04 orchestration ban).","Opacity-only keeps the whole swap on the compositor thread; the full round trip stays inside 250ms so the app never feels held back by its own transition."
|
|
8
|
+
7,panel-enter,operator-active,"panel, drawer, sheet, slide, overlay, enter",panel-open,duration-slow (open) / duration-normal (close),ease-enter (open) / ease-exit (close),translateX(100%) -> translateX(0); scrim opacity 0 -> 1,list-detail;dashboard;entity-detail;create-edit;log-stream;command-center,baseline,"Slide the panel on transform only with its elevation.overlay shadow present from the first frame; the close mirrors the open at the faster exit pairing.","Never animate the panel's width or push the page over by margin to make room (mot-05); the underlay scrim fades on opacity inside the same window, never as separate choreography.","A translateX slide keeps even a 420px-wide panel on the compositor; prefers-reduced-motion collapses both open and close to an instant swap (mot-03)."
|
|
9
|
+
8,skeleton-shimmer,operator-active,"loading, skeleton, shimmer, placeholder, wait",async-wait,duration-unit x28 (1400ms loop),ease-default,gradient overlay translateX(-100%) -> translateX(100%); loop,list-detail;dashboard;entity-detail;create-edit;log-stream;command-center,baseline,"Sweep a gradient overlay across the placeholder by transform and sync every skeleton in a group to one clock so the sheen reads as a single pass; delay the first paint 150-300ms to avoid flash (mot-07).","Never drive the sweep with background-position or width (mot-05 - the admitted physics moves a transform-positioned overlay); no shimmer at all for waits under 500ms (mot-07).","Kill the loop the moment real content mounts - orphaned repeating animations leak across SPA route changes; prefers-reduced-motion gets a static placeholder (mot-03)."
|
|
10
|
+
9,busy-indicator-pulse,operator-active,"loading, busy, dots, pulse, inline wait",async-wait,duration-unit x8 (400ms per beat),ease-default,per-dot translateY(0) -> translateY(-4px) -> 0; opacity 0.5 -> 1 -> 0.5; phase offset stagger-unit x3,dashboard;create-edit;command-center;log-stream,baseline,"Three dots phase-offset by a stagger-unit multiple, each beating on opacity plus a small rise; reserve it for the 500ms-2s wait band where a skeleton has no content shape to hold (mot-07).","No indicator for sub-300ms operations - it flashes and feels worse than nothing; keep the full loop period at or under 1.5s so a long wait never appears frozen on one beat.","Pause the loop while the tab or view is hidden and kill it on completion; three children sits far under the 8-child stagger cap (mot-08)."
|