@hegemonart/get-design-done 1.44.0 → 1.45.0

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.
@@ -5,14 +5,14 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Get Design Done — 5-stage agent-orchestrated design pipeline with 9 connections, handoff-first workflow, bidirectional Figma write-back, 22+ specialized agents, queryable knowledge layer (intel store, dependency analysis, learnings extraction), and a self-improvement loop (reflector, frontmatter + budget feedback, global-skills layer). v1.20.0 ships the SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream, and resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) for rate-limit + 429 + context-overflow recovery. Full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation (auto-tag + GitHub Release + release-time smoke test).",
8
- "version": "1.44.0"
8
+ "version": "1.45.0"
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "get-design-done",
13
13
  "source": "./",
14
14
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), Claude Design handoff, bidirectional Figma write-back, and a queryable intel store (.design/intel/) for dependency and learnings queries. Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows) and release automation. Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain.",
15
- "version": "1.44.0",
15
+ "version": "1.45.0",
16
16
  "author": {
17
17
  "name": "hegemonart"
18
18
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "get-design-done",
3
3
  "short_name": "gdd",
4
- "version": "1.44.0",
4
+ "version": "1.45.0",
5
5
  "description": "Agent-orchestrated 5-stage design pipeline: Brief → Explore → Plan → Design → Verify. 22+ specialized agents, 9 connections (Figma, Refero, Preview, Storybook, Chromatic, Figma Writer, Graphify, Pinterest, Claude Design), handoff-first workflow via Claude Design bundles, bidirectional Figma write-back (annotations, Code Connect), queryable intel store (`.design/intel/`) for O(1) design surface lookups, and self-improvement loop (reflector agent, frontmatter + budget feedback, global-skills layer at `~/.claude/gdd/global-skills/`). Standalone commands: style, darkmode, compare, figma-write, graphify, handoff, analyze-dependencies, skill-manifest, extract-learnings, reflect, apply-reflections. Embeds NNG heuristics, WCAG thresholds, typographic systems, motion framework, and anti-pattern catalog. Ships with a full CI/CD pipeline (Node 22/24 × Linux/macOS/Windows, lint + schema + frontmatter + stale-ref + shellcheck + gitleaks + injection-scan + blocking size-budget) and release automation (auto-tag + GitHub Release + release-time smoke test). Optimization layer (v1.0.4.1, retroactive): gdd-router + gdd-cache-manager skills, PreToolUse budget-enforcer hook, tier-aware agent frontmatter, lazy checker gates, streaming synthesizer, /gdd:warm-cache + /gdd:optimize commands, and cost telemetry at .design/telemetry/costs.jsonl — targeting 50-70% per-task token-cost reduction with no quality-floor regression. v1.20.0 SDK foundation: gdd-state MCP server (11 typed tools), lockfile-safe STATE.md mutations, event stream at .design/telemetry/events.jsonl, resilience primitives (jittered-backoff, rate-guard, error-classifier, iteration-budget) with rate-limit + 429 + context-overflow recovery, and TypeScript toolchain. v1.27.7 ships gdd-mcp (Phase 27.7): 12 read-only MCP tools for sub-3s priming. v1.28.0 (Phase 28): Foundational References Tier 2 — 5 new reference files (color-theory, composition, proportion-systems, i18n, contrast-advanced), 2 verifier i18n probes + 1 explore i18n-readiness probe, 12 additive cross-link insertions across 10 existing references, 2 orthogonal audit-scoring lens-tags (composition_alignment + i18n_readiness).",
6
6
  "author": {
7
7
  "name": "hegemonart",
package/CHANGELOG.md CHANGED
@@ -4,6 +4,47 @@ All notable changes to get-design-done are documented here. Versions follow [sem
4
4
 
5
5
  ---
6
6
 
7
+ ## [1.45.0] - 2026-06-02
8
+
9
+ ### Phase 45 - Canonical Domain Reference Index
10
+
11
+ GDD has 38+ reference docs with flat indexing - agents loaded fragments by name and missed the rest, or
12
+ loaded all 5 motion files and wasted tokens. Phase 45 ships 7 navigation entry-points over the existing
13
+ content (it indexes, never re-authors). Planned and executed via the GSD pipeline (parallel research +
14
+ parallel authoring subagents). No new runtime dependency, no new egress.
15
+
16
+ ### Breaking changes
17
+
18
+ - **Two CI gates now guard the domain indexes.** `npm run check:domain-links` fails if any cross-link in
19
+ the 7 entry-points points at a missing file or anchor; `npm run check:no-duplication` fails if an index
20
+ copies large blocks from the fragment it should only link. Contributors editing the 7
21
+ `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md` entries must keep
22
+ links resolving and keep entries link-only.
23
+
24
+ ### Added
25
+
26
+ - **7 domain-index entry-points** at `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md`,
27
+ each <=300 lines: a mission, a "use this when" index of the subordinate fragments, 3-5 rules-of-thumb, and
28
+ cross-domain see-also links. `motion.md` and `typography.md` were transformed in place; the other five are new.
29
+ - **Registry `domain-index` kind**: `reference/registry.schema.json` gains the type; the 7 entries register
30
+ as `domain-index` so skills can query indexes first and drill into detail second.
31
+ - **`scripts/check-domain-cross-links.cjs`** + **`scripts/check-no-duplication.cjs`** (maintainer-only) + the
32
+ two CI steps.
33
+ - **Consumer migration**: `motion-mapper` now loads `motion.md` (the index) and drills into a fragment only
34
+ when classifying against it (an 89% token cut versus loading all four motion fragments up front);
35
+ `design-auditor` and `design-executor` lead their reference reading with the domain indexes. Token-load
36
+ baseline at `test/fixtures/baselines/phase-45/token-load.json`.
37
+
38
+ ### Notes
39
+
40
+ - 6-manifest lockstep at **v1.45.0** + `OFF_CADENCE_VERSIONS.add('1.45.0')` + 37 `manifests-version.txt`
41
+ baselines forward-propagated 1.44.0 -> 1.45.0. Tarball golden 869 -> 874 (+5 new shipped `reference/*.md`;
42
+ the two CI scripts are maintainer-only, not shipped).
43
+ - SC#9 (Phase 41 rule `references[]` migration to canonical entries) is deferred to a follow-up; the rule
44
+ links to `anti-patterns.md` still resolve, so the migration is a nice-to-have rather than a blocker.
45
+
46
+ ---
47
+
7
48
  ## [1.44.0] - 2026-06-02
8
49
 
9
50
  ### Phase 44 - Harness Capability Matrix
package/README.md CHANGED
@@ -249,6 +249,8 @@ All 14 runtimes receive their native artifact layout (`skills/`, `command/`, `ag
249
249
 
250
250
  **Harness capability matrix (v1.44.0).** The full per-harness support matrix (skill discovery, command syntax, MCP, install path, status) lives in **[`HARNESSES.md`](HARNESSES.md)** at the repo root, generated from `scripts/lib/manifest/harnesses.json` (the single source of truth; CI drift-gates it). Each harness carries an honest status (`tested` / `experimental` / `untested`) and a `last_verified` stamp; a freshness gate warns at 60 days and fails at 180 for `tested` harnesses, surfaced in `/gdd:health`. The 14-harness count above is the same SoT the matrix reads, so it cannot drift. The five deep-dive reference files (`reference/codex-tools.md`, `reference/gemini-tools.md`, `reference/peer-cli-capabilities.md`, `reference/peer-protocols.md`, `reference/runtime-models.md`) remain as appendices linked from the matrix. **No new runtime dependency.**
251
251
 
252
+ **Domain reference index (v1.45.0).** The 38+ reference docs are now navigated through 7 canonical entry-points - `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md` - each indexing its subordinate fragments with a "use this when" pointer plus a handful of rules-of-thumb. Design skills load the relevant domain index first and drill into a fragment only when needed (motion-mapper dropped roughly 89% of its up-front reference tokens this way). The indexes link, never copy: `check:domain-links` fails CI on a broken cross-link and `check:no-duplication` fails on large copy-paste. The detailed fragments stay in place as the drill-in targets. **No new runtime dependency.**
253
+
252
254
  Verify with:
253
255
 
254
256
  ```
@@ -45,6 +45,7 @@ Minimum expected files:
45
45
  - `.design/DESIGN-CONTEXT.md` - goals, brand direction, design decisions (D-XX)
46
46
  - `.design/DESIGN-PLAN.md` - planned tasks and acceptance criteria
47
47
  - `.design/tasks/` - what was actually done (glob all task files)
48
+ - **Domain-index navigation (Phase 45):** the 7 entry-points `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md` index every fragment below. For a pillar, load the relevant domain index first, then drill into the specific fragments it lists only as the pillar needs them - this is the cheap navigation layer over the detailed fragments.
48
49
  - `reference/audit-scoring.md` - existing 7-category scoring rubric (understand, do not duplicate)
49
50
  - `reference/brand-voice.md` - voice axes, archetype library, and tone-by-context table (use when auditing Pillar 1: Copy)
50
51
  - `reference/gestalt.md` - 8 Gestalt principles with scoring rubrics (use when auditing Pillar 2: Visual Hierarchy)
@@ -34,7 +34,7 @@ The orchestrating stage supplies a `<required_reading>` block in the prompt. Rea
34
34
  - `.design/STATE.md` - pipeline state (decisions, blockers, must-haves)
35
35
  - `.design/DESIGN-PLAN.md` - full task list (your task is identified by task_id)
36
36
  - `.design/DESIGN-CONTEXT.md` - brand decisions, constraints, locked choices
37
- - The reference file(s) relevant to the task type (e.g., `reference/typography.md` for a typography task)
37
+ - The reference file(s) relevant to the task type (e.g., `reference/typography.md` for a typography task). The 7 domain-index entry-points `reference/{typography,color,spatial,motion,interaction,responsive,ux-writing}.md` (Phase 45) are the navigation start: load the index, drill into the fragments it lists only as the task needs them.
38
38
 
39
39
  **Invariant:** read all listed files FIRST, before making any changes.
40
40
 
@@ -24,11 +24,15 @@ You inventory motion and animation patterns. Zero session memory. You do not mod
24
24
  ## Required Reading
25
25
 
26
26
  - `.design/STATE.md`
27
- - `reference/motion.md` (if present)
28
- - `reference/motion-advanced.md` (if present) - advanced patterns: spring physics, scroll-driven, FLIP, View Transitions API, gesture/drag mechanics, clip-path patterns, blur crossfades, Framer Motion hardware-accel gotcha
29
- - `reference/motion-easings.md` (if present) - 12 canonical easing presets; classify each detected easing against this catalog
30
- - `reference/motion-transition-taxonomy.md` (if present) - 8 transition families; classify page/route transitions against this taxonomy
31
- - `reference/motion-spring.md` (if present) - spring presets; classify spring configs against gentle/wobbly/stiff/slow
27
+ - `reference/motion.md` (if present) - **the motion domain-index (Phase 45): start here.** It indexes the
28
+ motion fragments below with a "use this when" pointer for each. Load a specific fragment ONLY when you
29
+ reach the classification step that needs it (drill-in), not all of them up front - this is the bulk of
30
+ the token saving (the index is ~1.7k tokens vs ~15k for all four fragments).
31
+ - Drill-in fragments (load on demand, per the index in `motion.md`):
32
+ - `reference/motion-advanced.md` - advanced patterns: spring physics, scroll-driven, FLIP, View Transitions API, gesture/drag mechanics, clip-path patterns, blur crossfades, Framer Motion hardware-accel gotcha
33
+ - `reference/motion-easings.md` - 12 canonical easing presets; classify each detected easing against this catalog
34
+ - `reference/motion-transition-taxonomy.md` - 8 transition families; classify page/route transitions against this taxonomy
35
+ - `reference/motion-spring.md` - spring presets; classify spring configs against gentle/wobbly/stiff/slow
32
36
  - Any files supplied by the orchestrator
33
37
 
34
38
  ## Scan Strategy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hegemonart/get-design-done",
3
- "version": "1.44.0",
3
+ "version": "1.45.0",
4
4
  "description": "A design-quality pipeline for AI coding agents: brief, plan, implement, and verify UI work against your design system.",
5
5
  "author": "Hegemon",
6
6
  "homepage": "https://github.com/hegemonart/get-design-done",
@@ -69,6 +69,8 @@
69
69
  "build:harnesses:check": "node scripts/generate-harnesses-md.cjs --check",
70
70
  "check:harness-freshness": "node scripts/check-harness-freshness.cjs",
71
71
  "verify:harness": "node scripts/verify-harness.cjs",
72
+ "check:domain-links": "node scripts/check-domain-cross-links.cjs",
73
+ "check:no-duplication": "node scripts/check-no-duplication.cjs",
72
74
  "sync:rule-catalogue": "node scripts/sync-rule-catalogue.cjs --check",
73
75
  "validate:manifest": "node scripts/validate-manifest.cjs --check",
74
76
  "validate:schemas": "node --experimental-strip-types scripts/validate-schemas.ts",
@@ -0,0 +1,34 @@
1
+ # Color - Palette, Contrast, and Aesthetic Direction
2
+
3
+ Color governs how palettes are constructed, how semantic color roles are assigned, how
4
+ contrast compliance is verified, and how the aesthetic style direction is confirmed.
5
+ Read `color-theory.md` when building a new palette from scratch. Read `palette-catalog.md`
6
+ when adopting an industry-vertical baseline. Read `contrast-advanced.md` for APCA
7
+ thresholds on thin or colored text. Read `style-vocabulary.md` to confirm whether an
8
+ aesthetic style's color requirements fit the product type. Does not cover type sizing for
9
+ legibility (see `typography.md`) or dark-mode implementation steps beyond OKLCH token
10
+ generation (see `color-theory.md`).
11
+
12
+ ## Fragment Index
13
+
14
+ | Fragment | When to load |
15
+ |---|---|
16
+ | [`./color-theory.md`](./color-theory.md) | constructing a palette, choosing a color space, building OKLCH harmonies, animating color, auditing under color-blindness simulation |
17
+ | [`./palette-catalog.md`](./palette-catalog.md) | adopting a pre-built industry-vertical palette as a baseline token set (40+ verticals, WCAG-verified) |
18
+ | [`./contrast-advanced.md`](./contrast-advanced.md) | computing text/UI contrast beyond WCAG 2.1 AA - especially for thin, large, or colored text where WCAG 2.1 misranks |
19
+ | [`./style-vocabulary.md`](./style-vocabulary.md) | confirming a UI aesthetic direction: does the style require dark mode, what are its signature color effects, which product types should avoid it |
20
+
21
+ ## Rules of Thumb
22
+
23
+ 1. Author new palette tokens in OKLCH, not HSL or hex. OKLCH ΔL/ΔC/Δh steps are perceptually uniform - equal numeric jumps produce equal perceived brightness jumps. HSL's lightness channel is not perceptual.
24
+ 2. Never rely on color alone to convey state (error, warning, success). Always pair with an icon, label, or pattern - WCAG 1.4.1.
25
+ 3. For the APCA dual-target pattern: meet WCAG 2.1 AA (4.5:1 for body text) AND check Lc 60 (APCA) for thin weights and colored backgrounds. The two systems can disagree on the same pair.
26
+ 4. Check every palette under deutan (most common), protan, and tritan simulations before shipping. The color-blindness palettes in `color-theory.md` provide pre-vetted swap sets.
27
+
28
+ ## See Also
29
+
30
+ - Typography legibility at small sizes: [`./typography.md`](./typography.md)
31
+ - OKLCH interpolation in color animations: [`./motion.md`](./motion.md)
32
+ - Spatial depth via shadow and elevation: [`./spatial.md`](./spatial.md)
33
+ - Healthcare: critical-value flags not color-only: [`./domains/healthcare-patterns.md`](./domains/healthcare-patterns.md)
34
+ - Finance: gain/loss color rules: [`./domains/finance-patterns.md`](./domains/finance-patterns.md)
@@ -0,0 +1,48 @@
1
+ # Interaction - Domain Index
2
+
3
+ This domain covers how users trigger, navigate, and recover from actions: accessibility requirements, component API quality, form patterns, information architecture, onboarding, and the emotional layer.
4
+
5
+ <!-- Phase 45 domain-index: loads this file instead of individual interaction fragments -->
6
+
7
+ ---
8
+
9
+ ## Mission
10
+
11
+ Interaction is the broadest design domain. It governs every point where a user acts on the interface and the interface responds. Load only the specific fragment for the task at hand using the index below. Does not cover visual placement of interactive elements (see `spatial.md`) or copy for UI elements (see `ux-writing.md`).
12
+
13
+ ---
14
+
15
+ ## Fragment Index
16
+
17
+ | Fragment | When to load |
18
+ |---|---|
19
+ | `./accessibility.md` | WCAG 2.1 AA thresholds, keyboard navigation, focus management, ARIA roles. Required for every interactive surface without exception. |
20
+ | `./component-authoring.md` | Designing or reviewing component APIs: P-01 Minimal API through P-06 Edge Honesty, composability, defaults, animation-as-state |
21
+ | `./form-patterns.md` | Forms are in scope: label position, validation timing, autofill tokens, password UX, CAPTCHA ethics |
22
+ | `./information-architecture.md` | Navigation structure is in scope: hub-and-spoke, faceted nav, card sort benchmarks, wayfinding |
23
+ | `./onboarding-progressive-disclosure.md` | First-run experience is in scope: empty-state patterns, product tours, checklist onboarding, Aha-moment mapping |
24
+ | `./emotional-design.md` | Holistic quality overlay after pillar scoring: Norman visceral/behavioral/reflective three-level lens |
25
+ | `./components/README.md` | Auditing a specific component against benchmark: entry to 38 spec files (accordion through tree) |
26
+
27
+ ---
28
+
29
+ ## Rules of Thumb
30
+
31
+ 1. Accessibility is not a final checklist - build it in from the start. Every interactive component begins with the WAI-ARIA contract from `accessibility.md`, not a retrofit after design is complete.
32
+ 2. P-01 Minimal API from `component-authoring.md`: a component's API surface is its test surface. Every prop that can be removed should be removed.
33
+ 3. Form label position: top-aligned is the default for all but settings-page scan forms. Placeholder-as-label is a WCAG 1.3.5 failure on any form with more than 3 fields.
34
+ 4. Empty-state onboarding outperforms product tours by completion rate for creation tools. Only use a tour when unfamiliar terminology requires context, and cap it at 5 steps.
35
+ 5. The emotional design lens applies after technical and usability requirements are met. Visceral quality (appearance) and behavioral quality (task flow) both need to be solid before reflective quality (brand meaning) is addressed.
36
+
37
+ ---
38
+
39
+ ## Cross-Domain See Also
40
+
41
+ - Gesture animation and animation-as-state: `reference/motion.md`
42
+ - Spatial grouping informs IA mental models: `reference/spatial.md`
43
+ - Touch target sizing differs by platform: `reference/responsive.md`
44
+ - Error message copy and empty-state copy: `reference/ux-writing.md`
45
+ - Healthcare form patterns (PHI isolation): `reference/domains/healthcare-patterns.md`
46
+ - Civic one-thing-per-page forms: `reference/domains/civic-patterns.md`
47
+ - Typography: `reference/typography.md`
48
+ - Color: `reference/color.md`
@@ -1,6 +1,27 @@
1
- # Motion & Animation Framework
1
+ # Motion - Animation Domain Index
2
2
 
3
- Based on Emil Kowalski's design engineering philosophy. Apply these rules in order - do not skip to "how should this animate" before answering "should this animate."
3
+ Based on Emil Kowalski's design engineering philosophy. Apply these rules in order. Do not skip to "how should this animate" before answering "should this animate."
4
+
5
+ <!-- Phase 45 domain-index: loads this file instead of individual motion fragments -->
6
+
7
+ ---
8
+
9
+ ## Mission
10
+
11
+ Motion governs animation decisions across the UI: whether to animate, duration budgets, easing choices, spring physics, transition taxonomy, and interpolation. Read this file first for the decision framework and core rules, then drill into the specialist fragment below. Does not cover CSS layout transitions (see `spatial.md`) or OS-level reduced-motion policy (see `responsive.md`).
12
+
13
+ ---
14
+
15
+ ## Fragment Index
16
+
17
+ | Fragment | When to load |
18
+ |---|---|
19
+ | `./motion-easings.md` | Choosing or auditing easing curve values: 12 canonical `--ease-*` presets, cubic-bezier equivalents, 60fps settle-times |
20
+ | `./motion-spring.md` | Interaction is draggable or needs physics feel: gentle/wobbly/stiff/slow presets, Framer Motion and React Spring syntax |
21
+ | `./motion-transition-taxonomy.md` | Classifying page or route transitions: 8 families (3d, blur, cover, destruction, dissolve, distortion, grid, light) |
22
+ | `./motion-interpolate.md` | Mapping input-to-output ranges: progress/scroll/gesture/time-linked animations, 4 extrapolation modes |
23
+ | `./motion-advanced.md` | Advanced platform APIs: FLIP, scroll-driven, View Transitions, gesture/drag, clip-path, WAAPI |
24
+ | `./framer-motion-patterns.md` | Codebase uses Framer Motion: spring/tween config, AnimatePresence, variants, gestures, a11y, bounce:0 rule |
4
25
 
5
26
  ---
6
27
 
@@ -12,7 +33,7 @@ Based on Emil Kowalski's design engineering philosophy. Apply these rules in ord
12
33
  |---|---|
13
34
  | 100+/day - keyboard shortcuts, command palette, list navigation | **No animation. Ever.** |
14
35
  | Tens/day - hover states, toggles, tab switching | Remove or keep to <80ms. No delay. |
15
- | Occasional - modals opening, drawers, toasts | Standard animation (150300ms) |
36
+ | Occasional - modals opening, drawers, toasts | Standard animation (150-300ms) |
16
37
  | Rare - onboarding, celebrations, first-time flows | Can add personality and delight |
17
38
  | Once - loading splash, page transitions | Full animation budget |
18
39
 
@@ -25,9 +46,9 @@ Valid animation purposes only. If it doesn't serve one of these, remove it.
25
46
  | Purpose | Example |
26
47
  |---|---|
27
48
  | **Spatial consistency** | Toast enters/exits same edge each time |
28
- | **State indication** | Button morphs to show loading success |
49
+ | **State indication** | Button morphs to show loading to success |
29
50
  | **Cause-effect explanation** | Item deletion - item flies to trash |
30
- | **Feedback** | Button scales 0.97 on press |
51
+ | **Feedback** | Button scales on press |
31
52
  | **Prevent jarring changes** | Content appearing/disappearing needs transition |
32
53
 
33
54
  Invalid purposes: "It looks cool", "It feels modern", "Other apps do it."
@@ -42,44 +63,28 @@ Invalid purposes: "It looks cool", "It feels modern", "Other apps do it."
42
63
  | **Interactive/draggable** | Spring physics | Follows finger/cursor naturally |
43
64
  | **Bounce/elastic** | **Never** | Feels toy-like and dated |
44
65
 
45
- CSS:
46
- ```css
47
- /* Enter */
48
- transition: transform 200ms cubic-bezier(0, 0, 0.2, 1); /* ease-out */
49
-
50
- /* Exit */
51
- transition: transform 150ms cubic-bezier(0.4, 0, 1, 1); /* ease-in */
52
-
53
- /* Transition */
54
- transition: all 200ms cubic-bezier(0.4, 0, 0.2, 1); /* ease-in-out */
55
- ```
66
+ See `reference/motion-easings.md` for the full `--ease-*` token catalog.
56
67
 
57
68
  ### Question 4: What Duration?
58
69
 
59
70
  | Animation type | Duration | Notes |
60
71
  |---|---|---|
61
- | Micro-interactions | 80150ms | Hover, press, toggle |
62
- | Component enter/exit | 150250ms | Modals, drawers, dropdowns |
63
- | Page transitions | 200350ms | Route changes |
64
- | Complex/orchestrated | 400ms | Multi-step, staggered reveals |
72
+ | Micro-interactions | 80-150ms | Hover, press, toggle |
73
+ | Component enter/exit | 150-250ms | Modals, drawers, dropdowns |
74
+ | Page transitions | 200-350ms | Route changes |
75
+ | Complex/orchestrated | <=400ms | Multi-step, staggered reveals |
65
76
  | **Never exceed** | 400ms | Anything longer feels broken |
66
77
 
67
- **Exit faster than enter**: Exit animations should run at **6070%** of the enter duration. Exiting elements should get out of the way fast.
68
-
69
- ```
70
- Enter: 250ms
71
- Exit: 150ms (60% of 250)
72
- ```
78
+ **Exit faster than enter**: Exit animations should run at **60-70%** of the enter duration.
73
79
 
74
80
  ### Question 5: Only Animate `transform` and `opacity`
75
81
 
76
- **Only these properties animate on the GPU:**
77
82
  ```css
78
- /* SAFE */
83
+ /* SAFE - GPU-accelerated */
79
84
  transform: translateX(), translateY(), scale(), rotate()
80
- opacity: 0 1
85
+ opacity: 0 to 1
81
86
 
82
- /* DANGEROUS triggers layout/paint */
87
+ /* DANGEROUS - triggers layout/paint */
83
88
  width, height, top, left, margin, padding, font-size
84
89
  ```
85
90
 
@@ -89,319 +94,73 @@ Exception: `filter` (blur) is GPU-accelerated in modern browsers but battery-exp
89
94
 
90
95
  ## Stagger Rules
91
96
 
92
- When animating a list of items entering:
93
- - Stagger delay: **30–50ms** per item
94
- - Maximum stagger depth: **6–8 items** (items beyond that appear simultaneously)
95
- - Direction: top-to-bottom OR left-to-right - never random
96
-
97
- ```css
98
- .item:nth-child(1) { animation-delay: 0ms; }
99
- .item:nth-child(2) { animation-delay: 40ms; }
100
- .item:nth-child(3) { animation-delay: 80ms; }
101
- /* etc. — cap at ~6 staggered items */
102
- ```
97
+ - Stagger delay: **30-50ms** per item
98
+ - Maximum stagger depth: **6-8 items** (items beyond that appear simultaneously)
99
+ - Direction: top-to-bottom OR left-to-right, never random
103
100
 
104
101
  ---
105
102
 
106
103
  ## Press Feedback
107
104
 
108
- Every clickable element must give visual feedback within **100ms** of interaction.
105
+ Every clickable element must give visual feedback within **100ms** of interaction. The canonical scale value for press feedback is **`0.96`**.
106
+
107
+ - Never use `scale(0.95)` - too large, feels unresponsive
108
+ - Never use `scale(0.97)` or higher - imperceptible at high DPI
109
+ - `0.96` is the correct value for standard interactive elements
109
110
 
110
111
  ```css
111
112
  button:active {
112
- transform: scale(0.97); /* NOT 0.90 — too dramatic */
113
+ transform: scale(0.96);
113
114
  transition: transform 80ms ease-out;
114
115
  }
115
-
116
- /* On release */
117
- button:not(:active) {
118
- transform: scale(1);
119
- transition: transform 150ms ease-out;
120
- }
121
116
  ```
122
117
 
123
- Scale range: **0.95–0.98** for buttons. **0.97** is the safest default.
124
- Never scale below 0.90 - it looks broken.
125
-
126
118
  ---
127
119
 
128
120
  ## `prefers-reduced-motion`
129
121
 
130
- Always respect this. It's not optional.
122
+ Always respect this. It is not optional.
131
123
 
132
124
  ```css
133
125
  @media (prefers-reduced-motion: reduce) {
134
- *,
135
- *::before,
136
- *::after {
126
+ *, *::before, *::after {
137
127
  animation-duration: 0.01ms !important;
138
- animation-iteration-count: 1 !important;
139
128
  transition-duration: 0.01ms !important;
140
129
  scroll-behavior: auto !important;
141
130
  }
142
131
  }
143
132
  ```
144
133
 
145
- Or in JavaScript:
146
- ```js
147
- const prefersReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
148
- if (!prefersReduced) {
149
- // Run animation
150
- }
151
- ```
152
-
153
- ---
154
-
155
- ## What Never To Animate
156
-
157
- - Keyboard shortcuts and commands (too frequent)
158
- - Tab switching within a page
159
- - Filter/sort toggles on data tables
160
- - Expanding/collapsing sidebar navigation items during heavy use
161
- - Any interaction the user will perform 50+ times in a session
162
-
163
- ---
164
-
165
- ## The Invisible Detail Rule
166
-
167
- The best animations are ones users cannot describe but notice when absent. Signs of this:
168
- - The interaction feels "snappy" or "responsive" without thinking about why
169
- - Removing the animation makes the UI feel broken
170
- - Users say "it feels premium" but can't point to any specific feature
171
-
172
- This is the goal. Not "look at this animation" - "why does this feel so good to use?"
173
-
174
134
  ---
175
135
 
176
- ## Quick Animation Audit Checklist
136
+ ## Quick Audit Checklist
177
137
 
178
138
  - [ ] No animation on keyboard-triggered actions
179
- - [ ] All durations 400ms
139
+ - [ ] All durations <=400ms
180
140
  - [ ] Exit < enter duration
181
141
  - [ ] Only `transform` and `opacity` for performance
182
142
  - [ ] `prefers-reduced-motion` implemented
183
- - [ ] Stagger 50ms per item, capped at 68 items
143
+ - [ ] Stagger <=50ms per item, capped at 6-8 items
184
144
  - [ ] Press feedback on all interactive elements
185
145
  - [ ] No bounce/elastic easing anywhere
186
146
  - [ ] All animations have a defined purpose
187
147
 
188
148
  ---
189
149
 
190
- ## Spring Physics
191
-
192
- Spring-based animation replaces duration-based tweening with physics parameters
193
- (stiffness, damping, mass). Output feels more organic and adapts to interruption.
194
-
195
- ### React Spring
196
-
197
- ```jsx
198
- import { useSpring, animated } from '@react-spring/web';
199
-
200
- const styles = useSpring({
201
- from: { opacity: 0, transform: 'translateY(20px)' },
202
- to: { opacity: 1, transform: 'translateY(0px)' },
203
- config: { tension: 170, friction: 26 } // default preset
204
- });
205
- ```
206
-
207
- React Spring presets:
208
-
209
- | Preset | tension | friction | Character |
210
- |--------|---------|----------|-----------|
211
- | default | 170 | 26 | balanced |
212
- | gentle | 120 | 14 | smooth, leisurely |
213
- | wobbly | 180 | 12 | playful bounce |
214
- | stiff | 210 | 20 | snappy |
215
- | slow | 280 | 60 | slow and deliberate |
216
- | molasses | 280 | 120 | very slow, no bounce |
217
-
218
- ### Framer Motion
219
-
220
- ```jsx
221
- <motion.div
222
- animate={{ x: 100 }}
223
- transition={{ type: "spring", stiffness: 100, damping: 15, mass: 1 }}
224
- />
225
- ```
226
-
227
- Parameter guidance:
228
-
229
- | Param | Range | Effect |
230
- |-------|-------|--------|
231
- | stiffness | 50–300 | higher = snappier arrival |
232
- | damping | 10–40 | higher = less oscillation |
233
- | mass | 0.5–2 | higher = more inertia, slower response |
234
-
235
- Rule of thumb: for UI micro-interactions use stiffness 150–250, damping 20–30, mass 1.
236
-
237
- ---
238
-
239
- ## Scroll-Triggered Animations
240
-
241
- Use IntersectionObserver for scroll-reveal effects - it replaces scroll-event
242
- listeners with a throttled browser-native API.
243
-
244
- ### Basic pattern
245
-
246
- ```js
247
- const observer = new IntersectionObserver((entries) => {
248
- entries.forEach(entry => {
249
- if (entry.isIntersecting) {
250
- entry.target.classList.add('in-view');
251
- // Optional: disconnect after first trigger
252
- // observer.unobserve(entry.target);
253
- }
254
- });
255
- }, {
256
- threshold: 0.1,
257
- rootMargin: '0px 0px -100px 0px' // trigger 100px before entering viewport bottom
258
- });
259
-
260
- document.querySelectorAll('.reveal').forEach(el => observer.observe(el));
261
- ```
262
-
263
- ### Threshold guidance
264
-
265
- | threshold | Meaning |
266
- |-----------|---------|
267
- | 0.0 | element enters viewport edge |
268
- | 0.1–0.25 | element partially visible (most common for reveals) |
269
- | 0.5 | element half-visible |
270
- | 1.0 | element fully visible |
271
-
272
- ### Once vs repeat
273
-
274
- - **Once** - call `observer.unobserve(entry.target)` after first intersection.
275
- Use for: hero reveals, one-shot entrance animations, stat counters.
276
- - **Repeat** - leave observer active. Use for: progress indicators, parallax effects,
277
- sticky nav state changes.
278
-
279
- ### Performance rules
280
-
281
- 1. Animate only `transform` and `opacity` (GPU-accelerated). Avoid `top`, `left`, `width`, `height`.
282
- 2. No debounce/throttle needed - IntersectionObserver is already throttled by the browser.
283
- 3. For many elements, share a single observer instance and call `observe()` once per element.
284
- 4. Prefer CSS transitions triggered by a class toggle over requestAnimationFrame loops.
285
- 5. Use `will-change: transform, opacity` sparingly (only on elements that animate repeatedly).
286
-
287
- ---
288
-
289
- ## MIFB Micro-Motion Extensions
290
- Source: jakubkrehel/make-interfaces-feel-better (MIT) - motion.md
291
-
292
- ### Interruptible Animations
293
-
294
- Use CSS transitions for interactive elements because transitions retarget mid-animation - when a user moves their cursor away before a hover animation completes, the transition reverses smoothly from wherever it currently is. Keyframe animations restart from the beginning, creating a jarring jump.
295
-
296
- **Decision rule:**
297
- - Interactive states (hover, focus, active, pressed): always CSS transitions
298
- - Orchestrated sequences, entrance effects, data-driven animations: keyframe or JS animation
299
-
300
- ```css
301
- /* Good — transition retargets smoothly */
302
- .button { transition: background-color 150ms ease-out; }
303
-
304
- /* Avoid for interactive — restarts on interruption */
305
- .button:hover { animation: hover-bg 150ms ease-out forwards; }
306
- ```
307
-
308
- ### Split-and-Stagger Enter/Exit
309
-
310
- For multi-element entrances (card grids, lists, feature sections):
311
-
312
- - Default stagger: 100ms between elements
313
- - Heading words: 80ms per word
314
- - Entrance transform: `opacity: 0 → 1` + `translateY(12px → 0)` + `blur(4px → 0)`
315
- - Entrance duration: 300ms, `ease-out`
316
- - Exit transform: `opacity: 1 → 0` + `translateY(0 → -12px)` (opposite direction, smaller offset)
317
- - Exit duration: 150ms (half the entrance duration - exits should be faster)
318
-
319
- The blur component adds a depth cue that makes entrances feel less flat. Keep blur modest (4px) - the goal is a subtle focus effect, not a visible blur.
320
-
321
- ### Contextual Icon Animations - Cross-Fade Pattern
322
-
323
- When swapping two icons (e.g., play ↔ pause, chevron-up ↔ chevron-down, bookmark ↔ bookmarked), use this exact cross-fade spec:
324
-
325
- **Framer Motion spring (preferred):**
326
- - `scale: 0.25 → 1` (entering), `scale: 1 → 0.25` (exiting)
327
- - `opacity: 0 → 1` (entering), `opacity: 1 → 0` (exiting)
328
- - `filter: blur(4px) → blur(0)` (entering), `blur(0) → blur(4px)` (exiting)
329
- - `transition: { type: "spring", duration: 0.3, bounce: 0 }` - **bounce MUST be 0**
150
+ ## Rules of Thumb
330
151
 
331
- **CSS fallback (no Framer):**
332
- - Keep both icons in the DOM, one `position: absolute`
333
- - Use `cubic-bezier(0.2, 0, 0, 1)` easing
334
- - Duration: 200ms
335
-
336
- The scale + blur combination creates a focus-snap effect that feels intentional rather than mechanical. The `bounce: 0` hard constraint exists because any bounce on a 0.25-scale origin point makes icons appear to "pop" invasively.
337
-
338
- ### Scale on Press - Canonical Value
339
-
340
- The canonical scale value for press feedback is **`0.96`**.
341
-
342
- Rules:
343
- - Never use `scale(0.95)` - too large, feels unresponsive
344
- - Never use `scale(0.97)` - too subtle at high DPI, not perceived as feedback
345
- - Never use `scale(0.98)` or higher - imperceptible
346
- - `0.96` is the ONLY correct value for standard interactive elements
347
-
348
- Tailwind: `active:scale-[0.96]`
349
- Framer: `whileTap={{ scale: 0.96 }}`
350
-
351
- For primary CTAs where maximum tactility is needed (purchase, send, confirm):
352
- use `0.96` with a shadow reduction: `box-shadow: none` during press.
353
-
354
- Deprecation note: earlier versions of `reference/checklists.md` referenced `scale(0.97)`. That entry has been reconciled. **0.96 is the canonical value.**
355
-
356
- ### AnimatePresence initial={false}
357
-
358
- When `AnimatePresence` wraps UI that exists in the DOM before it enters the animation scope (e.g., a tab panel that renders its first tab immediately, a dropdown that's already open on first load), use `initial={false}`:
359
-
360
- ```tsx
361
- <AnimatePresence initial={false}>
362
- {isOpen && <motion.div key="panel" initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }} />}
363
- </AnimatePresence>
364
- ```
365
-
366
- Without `initial={false}`, Framer will animate the FIRST render of children - meaning UI that's immediately visible on page load will "fade in" unnecessarily. This creates a flash/flicker that signals poor craftsmanship.
367
-
368
- **Rule:** Any `AnimatePresence` wrapping persistent UI should have `initial={false}`.
369
-
370
- ### will-change - GPU Property Table
371
-
372
- Only add `will-change` when you observe first-frame stutter on lower-end hardware. Do NOT add it preemptively - it consumes GPU memory continuously for every element that has it.
373
-
374
- GPU-compositable properties (safe with will-change):
375
- | Property | will-change value |
376
- |----------|------------------|
377
- | transform (translate, scale, rotate) | `transform` |
378
- | opacity | `opacity` |
379
- | filter (blur, brightness, contrast) | `filter` |
380
- | clip-path | `clip-path` |
381
-
382
- Never use `will-change: all` or `will-change: contents` - this forces the entire element and its subtree onto a new compositor layer, thrashing memory.
383
-
384
- Remove `will-change` after the animation completes if applied dynamically:
385
- ```js
386
- element.addEventListener('transitionend', () => element.style.willChange = 'auto')
387
- ```
152
+ 1. Keyboard-initiated actions (command palette, list navigation, shortcuts) must have zero animation. They repeat hundreds of times daily and every ms is felt.
153
+ 2. Default to named spring presets (gentle/wobbly/stiff/slow) rather than raw stiffness/damping numbers; presets are tuned for 60fps settle-time and predictable feel.
154
+ 3. Always use `--ease-*` CSS custom property tokens rather than inline `cubic-bezier()` strings; tokens keep easing consistent and respect `prefers-reduced-motion`.
155
+ 4. OKLCH is the correct color space for animated color transitions; sRGB interpolation produces muddy mid-transition colors. See `reference/color-theory.md` for color interpolation in animation.
388
156
 
389
157
  ---
390
158
 
391
- ## Advanced Patterns
392
-
393
- For spring physics, scroll-driven animation, FLIP, View Transitions API, gesture & drag mechanics, clip-path animation patterns, blur-to-mask crossfades, WAAPI, Framer Motion hardware-acceleration gotcha, motion cohesion & personality, and the next-day slow-motion review process, see:
394
-
395
- → **`reference/motion-advanced.md`** (Phase 18)
396
-
397
- For the canonical easing catalog (`--ease-*` tokens, cubic-bezier equivalents, 60fps settle-times):
398
-
399
- → **`reference/motion-easings.md`** (Phase 18)
400
-
401
- For spring parameter presets (gentle / wobbly / stiff / slow):
402
-
403
- → **`reference/motion-spring.md`** (Phase 18)
404
-
405
- For transition family taxonomy (8 families: 3d / blur / cover / destruction / dissolve / distortion / grid / light):
159
+ ## Cross-Domain See Also
406
160
 
407
- **`reference/motion-transition-taxonomy.md`** (Phase 18)
161
+ - Color animation uses OKLCH path: `reference/color.md`
162
+ - Gesture semantics (velocity, pointer capture): `reference/interaction.md`
163
+ - OS-level reduced-motion: `reference/responsive.md`
164
+ - CSS layout transitions: `reference/spatial.md`
165
+ - Typography: `reference/typography.md`
166
+ - UX writing: `reference/ux-writing.md`
@@ -625,8 +625,9 @@
625
625
  {
626
626
  "name": "motion",
627
627
  "path": "reference/motion.md",
628
- "type": "motion",
629
- "description": "Motion vocabulary seed (extended in Phase 18)"
628
+ "type": "domain-index",
629
+ "description": "Phase 45 domain-index: motion navigation - indexes easings, spring, transition-taxonomy, interpolate, advanced, framer-motion-patterns.",
630
+ "phase": 45
630
631
  },
631
632
  {
632
633
  "name": "motion-advanced",
@@ -797,8 +798,9 @@
797
798
  {
798
799
  "name": "typography",
799
800
  "path": "reference/typography.md",
800
- "type": "heuristic",
801
- "description": "Typography-system heuristics used by visual-hierarchy-mapper"
801
+ "type": "domain-index",
802
+ "description": "Phase 45 domain-index: typography navigation - indexes type-scale heuristics, variable-fonts-loading, proportion-systems.",
803
+ "phase": 45
802
804
  },
803
805
  {
804
806
  "name": "user-research",
@@ -1049,6 +1051,41 @@
1049
1051
  "type": "meta-rules",
1050
1052
  "phase": 42,
1051
1053
  "description": "Phase 42 multi-harness skill-placeholder catalogue: the four placeholders ({{command_prefix}}/{{model}}/{{config_file}}/{{ask_instruction}}) + per-harness substitution table + the \\{{...}} escape + the <!-- harness-only: a,b --> block rule. Skills authored once in source/skills/, compiled per-harness by scripts/build-skills.cjs via scripts/lib/build/factory.cjs reading scripts/lib/manifest/harnesses.json."
1054
+ },
1055
+ {
1056
+ "name": "color",
1057
+ "path": "reference/color.md",
1058
+ "type": "domain-index",
1059
+ "phase": 45,
1060
+ "description": "Phase 45 domain-index: color + contrast navigation - color-theory, palette-catalog, contrast-advanced, style-vocabulary."
1061
+ },
1062
+ {
1063
+ "name": "spatial",
1064
+ "path": "reference/spatial.md",
1065
+ "type": "domain-index",
1066
+ "phase": 45,
1067
+ "description": "Phase 45 domain-index: layout/spacing/composition - composition, proportion-systems, css-grid-layout, visual-hierarchy-layout, gestalt, image-optimization, data-visualization, surfaces."
1068
+ },
1069
+ {
1070
+ "name": "interaction",
1071
+ "path": "reference/interaction.md",
1072
+ "type": "domain-index",
1073
+ "phase": 45,
1074
+ "description": "Phase 45 domain-index: interaction + a11y + components - accessibility, component-authoring, form-patterns, information-architecture, onboarding-progressive-disclosure, emotional-design, components/."
1075
+ },
1076
+ {
1077
+ "name": "responsive",
1078
+ "path": "reference/responsive.md",
1079
+ "type": "domain-index",
1080
+ "phase": 45,
1081
+ "description": "Phase 45 domain-index: responsive + i18n + platforms - i18n, rtl-cjk-cultural, platforms, native-platforms, performance, css-grid-layout."
1082
+ },
1083
+ {
1084
+ "name": "ux-writing",
1085
+ "path": "reference/ux-writing.md",
1086
+ "type": "domain-index",
1087
+ "phase": 45,
1088
+ "description": "Phase 45 domain-index: UX-writing + voice - brand-voice, style-vocabulary, anti-patterns."
1052
1089
  }
1053
1090
  ]
1054
1091
  }
@@ -4,19 +4,41 @@
4
4
  "title": "Reference Registry",
5
5
  "description": "Typed index of every reference/*.md (and reference/*.json default) in the plugin. Enables agents to query by type instead of grep-hunting import strings. Round-trip enforced: every reference/*.md must appear in entries[], every entry must resolve to an existing file.",
6
6
  "type": "object",
7
- "required": ["version", "generated_at", "entries"],
7
+ "required": [
8
+ "version",
9
+ "generated_at",
10
+ "entries"
11
+ ],
8
12
  "properties": {
9
- "$schema": { "type": "string" },
10
- "version": { "const": 1 },
11
- "generated_at": { "type": "string", "format": "date-time" },
13
+ "$schema": {
14
+ "type": "string"
15
+ },
16
+ "version": {
17
+ "const": 1
18
+ },
19
+ "generated_at": {
20
+ "type": "string",
21
+ "format": "date-time"
22
+ },
12
23
  "entries": {
13
24
  "type": "array",
14
25
  "items": {
15
26
  "type": "object",
16
- "required": ["name", "path", "type"],
27
+ "required": [
28
+ "name",
29
+ "path",
30
+ "type"
31
+ ],
17
32
  "properties": {
18
- "name": { "type": "string", "minLength": 1, "pattern": "^[a-z0-9][a-z0-9-._]*$" },
19
- "path": { "type": "string", "minLength": 1 },
33
+ "name": {
34
+ "type": "string",
35
+ "minLength": 1,
36
+ "pattern": "^[a-z0-9][a-z0-9-._]*$"
37
+ },
38
+ "path": {
39
+ "type": "string",
40
+ "minLength": 1
41
+ },
20
42
  "type": {
21
43
  "type": "string",
22
44
  "enum": [
@@ -41,13 +63,28 @@
41
63
  "typography",
42
64
  "layout",
43
65
  "performance",
44
- "component-spec"
66
+ "component-spec",
67
+ "domain-index"
68
+ ]
69
+ },
70
+ "tier": {
71
+ "enum": [
72
+ "L0",
73
+ "L1",
74
+ "L2"
45
75
  ]
46
76
  },
47
- "tier": { "enum": ["L0", "L1", "L2"] },
48
- "phase": { "type": "number", "description": "Phase that introduced this entry. Numbers are allowed (e.g., 19.6, 27.5, 27.6, 27.7, 28.5) — decimal phases are valid per the long-standing precedent established by Phases 19.6 / 27.5 / 27.6 / 27.7 / 28.5." },
49
- "description": { "type": "string" },
50
- "registered_at": { "type": "string", "format": "date-time" }
77
+ "phase": {
78
+ "type": "number",
79
+ "description": "Phase that introduced this entry. Numbers are allowed (e.g., 19.6, 27.5, 27.6, 27.7, 28.5) — decimal phases are valid per the long-standing precedent established by Phases 19.6 / 27.5 / 27.6 / 27.7 / 28.5."
80
+ },
81
+ "description": {
82
+ "type": "string"
83
+ },
84
+ "registered_at": {
85
+ "type": "string",
86
+ "format": "date-time"
87
+ }
51
88
  },
52
89
  "additionalProperties": false
53
90
  }
@@ -0,0 +1,74 @@
1
+ # Responsive Design - Domain Index
2
+
3
+ This is the domain entry-point for responsive design. Load this file when the
4
+ interface will render in more than one locale, platform, or viewport condition.
5
+ It covers i18n engineering primitives, RTL and CJK cultural adaptation,
6
+ platform-specific conventions, native token bridging, and performance budgets.
7
+ It does not cover the CSS Grid implementation of responsive layouts (see
8
+ `reference/spatial.md` for container queries and `clamp()`); it does not cover
9
+ copy tone for localized content (see `reference/ux-writing.md`).
10
+
11
+ ---
12
+
13
+ ## Fragment Index
14
+
15
+ → **`reference/i18n.md`** (Phase 28) - use when localizing text: expansion
16
+ budgets (+30-40%), CSS logical props, `Intl.*` APIs, ICU MessageFormat,
17
+ bidi isolation, Unicode normalization, multi-script font stacks
18
+
19
+ → **`reference/rtl-cjk-cultural.md`** (Phase 28) - use when targeting RTL
20
+ locales or CJK audiences: layout mirroring rules, bidirectional text isolation,
21
+ Arabic/Hebrew/Devanagari rendering, cultural color meanings and imagery norms
22
+
23
+ → **`reference/platforms.md`** (Phase 19) - use when targeting multiple
24
+ platforms: iOS/Android/web/visionOS/watchOS nav patterns, safe area insets,
25
+ gesture vocabularies, haptics, native typography conventions
26
+
27
+ → **`reference/native-platforms.md`** (Phase 34.1) - use when bridging design
28
+ tokens to native code: canonical CSS token to SwiftUI Color / Compose Color /
29
+ Flutter ThemeData mapping, precision contract for the round-trip
30
+
31
+ → **`reference/performance.md`** (Phase 19) - use for any production
32
+ responsive build: Core Web Vitals budgets by project type, JS/font/image
33
+ budgets, React runtime perf rules
34
+
35
+ → **`reference/css-grid-layout.md`** (Phase 18) - load the container-queries
36
+ and `clamp()` sections only: fluid responsive components, safe-area insets,
37
+ logical CSS props in Grid context
38
+
39
+ ---
40
+
41
+ ## Rules of Thumb
42
+
43
+ **1. Size containers for the worst-case expansion locale.**
44
+ Russian and Finnish strings expand +40% from an English baseline. Any text
45
+ container designed at English width will overflow in those locales. Build for
46
+ `EN base x 1.4` as the standard layout-budget rule; top-aligned labels absorb
47
+ expansion without horizontal breakage.
48
+
49
+ **2. CSS logical properties are the implementation primitive for RTL.**
50
+ Never use `left`/`right` in a layout that will need to mirror. Replace
51
+ `margin-left` with `margin-inline-start`, `padding-right` with
52
+ `padding-inline-end`, and positioned `left` with `inset-inline-start`. The full
53
+ mapping is in `reference/rtl-cjk-cultural.md`.
54
+
55
+ **3. `prefers-reduced-motion` is a responsive property, not optional.**
56
+ Any animation behind a media query must resolve to `transition: none` or
57
+ `animation-duration: 0.01ms` when the user has set OS-level reduced-motion.
58
+ The CSS reset pattern is in `reference/motion.md`.
59
+
60
+ **4. Native token precision contract: no re-derivation in component code.**
61
+ Color hex values bridge to native at 8-bit channel precision (no rounding).
62
+ Dimension px values bridge as integer dp/pt. The token-bridge round-trip in
63
+ `reference/native-platforms.md` is the source of truth - any re-derivation
64
+ in component code will drift from the canonical value.
65
+
66
+ ---
67
+
68
+ ## Cross-Domain See Also
69
+
70
+ - i18n text expansion affects type container sizing: `reference/typography.md`
71
+ - Touch targets differ from pointer targets: `reference/interaction.md`
72
+ - Layout shifts at breakpoints: `reference/spatial.md`
73
+ - OS-level reduced-motion links to animation rules: `reference/motion.md`
74
+ - Civic multi-language government forms: `reference/domains/civic-patterns.md`
@@ -0,0 +1,38 @@
1
+ # Spatial - Composition, Grid, and Perceptual Organization
2
+
3
+ Spatial design governs how elements are placed, sized, and related in two-dimensional
4
+ space: composition principles (rule of thirds, focal point, eye-flow), proportion
5
+ derivation (baseline grid, spacing ladder), CSS implementation (Grid, container queries,
6
+ clamp), visual hierarchy, Gestalt grouping, and data presentation. Read this file first,
7
+ then load the specific fragment for the task at hand. Does not cover 3D depth signaling
8
+ via color/shadow as a color decision (see `color.md`) or responsive layout shifts driven
9
+ by locale/platform (see `responsive.md`).
10
+
11
+ ## Fragment Index
12
+
13
+ | Fragment | When to load |
14
+ |---|---|
15
+ | [`./composition.md`](./composition.md) | choosing a compositional grid (rule of thirds, root rectangles, Fibonacci), placing a focal point, deciding eye-flow archetype (Z / F / Gutenberg) |
16
+ | [`./proportion-systems.md`](./proportion-systems.md) | deriving the baseline grid unit, spacing ladder, icon sizing, corner radius from a single multiplier (4pt / 8pt / sqrt(2)) |
17
+ | [`./css-grid-layout.md`](./css-grid-layout.md) | implementing CSS Grid templates, subgrid, container queries, `clamp()` fluid type, logical props, anchor positioning |
18
+ | [`./visual-hierarchy-layout.md`](./visual-hierarchy-layout.md) | ordering elements by importance: Z-order, whitespace rules, shadow depth, 24 landing archetypes |
19
+ | [`./gestalt.md`](./gestalt.md) | auditing perceptual grouping: proximity, similarity, continuity, closure, figure/ground - 8 principles with scoring rubrics |
20
+ | [`./image-optimization.md`](./image-optimization.md) | images in layout: format matrix, srcset/sizes math, LQIP/BlurHash, CDN transforms, image budget |
21
+ | [`./data-visualization.md`](./data-visualization.md) | charts/dashboards: 25-type chart-choice matrix, color-blind palettes, axis conventions, UUPM dashboard patterns |
22
+ | [`./surfaces.md`](./surfaces.md) | surface treatments: concentric radius formula, optical alignment, 3-layer shadow system, hit area sizing |
23
+
24
+ ## Rules of Thumb
25
+
26
+ 1. Place primary CTAs on the rule-of-thirds power points (the 33%/67% intersections), not dead-center. Centered heroes are the intentional exception, not the default.
27
+ 2. Choose one baseline unit for the whole product (4pt, 8pt, or sqrt(2)) and author every spacing, sizing, and radius token as a multiple of it. No one-off values.
28
+ 3. CSS Grid container queries (`@container`) should replace media queries for component-level layout. Reserve media queries for page-level breakpoints only.
29
+ 4. Gestalt proximity rule: related controls 8px apart or less; unrelated groups 32px apart or more. The layout should communicate relationships before the user reads labels.
30
+ 5. Choose the chart type before the color palette. The wrong chart type cannot be rescued by a better palette. Use `data-visualization.md` chart-choice matrix first.
31
+
32
+ ## See Also
33
+
34
+ - Shadow and elevation as color/depth signal: [`./color.md`](./color.md)
35
+ - Type scale ties into spatial proportion grid: [`./typography.md`](./typography.md)
36
+ - Responsive layout shifts at breakpoints: [`./responsive.md`](./responsive.md)
37
+ - Gestalt grouping informs information architecture: [`./interaction.md`](./interaction.md)
38
+ - Gaming: TV-safe area constraints: [`./domains/gaming-patterns.md`](./domains/gaming-patterns.md)
@@ -1,5 +1,34 @@
1
1
  # Typography - Scale, Pairing, and Hierarchy
2
2
 
3
+ This file is the domain index for typography. It covers type-scale construction,
4
+ weight hierarchy, font pairing, and micro-typography. Read `variable-fonts-loading.md`
5
+ when web fonts are in scope. Read `proportion-systems.md` when the full UI grid is
6
+ in scope. Does not cover text-contrast (see `color.md`) or locale text expansion
7
+ (see `responsive.md`, which indexes [`./i18n.md`](./i18n.md) for the per-locale expansion budgets).
8
+
9
+ ## Fragment Index
10
+
11
+ | Fragment | When to load |
12
+ |---|---|
13
+ | This file (below) | type scale ratios, sizing tokens, weight hierarchy, font pairings, micro-typography |
14
+ | [`./variable-fonts-loading.md`](./variable-fonts-loading.md) | web fonts, `@font-face`, `font-display`, FOIT/FOUT, variable font axes, subsetting, fallback metrics |
15
+ | [`./proportion-systems.md`](./proportion-systems.md) | 4pt/8pt/sqrt(2) baseline grid, spacing ladder, icon sizing, corner radius derivation |
16
+
17
+ ## Rules of Thumb
18
+
19
+ 1. A 1.25 (Major Third) or 1.333 (Perfect Fourth) ratio fits 95% of SaaS products; only reach for 1.618 when visual drama is the explicit brief.
20
+ 2. Never author `line-height` as a pixel value - always use a unitless multiplier (1.4-1.6 for body, 1.1-1.2 for headings); unitless values scale with user font-size overrides.
21
+ 3. Font weight on the web has only 7 meaningful stops (100-700 in 100-steps); any weight not in the font file rounds to the nearest available - check the variable font `wght` range before specifying 450 or 600.
22
+ 4. Baseline-grid lock: every spacing and sizing token should be a multiple of the chosen baseline unit; `padding: 12px` next to body at `16/24` on an 8pt grid is a silent proportion break.
23
+ 5. For localized UIs, size type containers for +40% expansion (Russian/Finnish worst-case); top-aligned labels are the only label position that absorbs expansion without layout breakage.
24
+
25
+ ## See Also
26
+
27
+ - Text contrast and color-blindness checks: [`./color.md`](./color.md)
28
+ - Text expansion in localized UIs: [`./responsive.md`](./responsive.md)
29
+ - Proportion systems tie type to spatial grid: [`./spatial.md`](./spatial.md)
30
+ - Finance number formatting (tabular-nums): [`./domains/finance-patterns.md`](./domains/finance-patterns.md)
31
+
3
32
  ---
4
33
 
5
34
  ## Type Scale Systems
@@ -35,7 +64,7 @@ Choose a ratio and base size. Common ratios:
35
64
 
36
65
  Never create a scale ad-hoc. Pick one ratio, generate the scale, use only values in the scale.
37
66
 
38
- **See:** [`./proportion-systems.md`](./proportion-systems.md) §Modular Relationships for how the type scale ties to spacing / sizing / radius scales - when one ratio drives all four scales the whole UI gains a single rhythm rather than four independently-tuned progressions.
67
+ **See:** [`./proportion-systems.md`](./proportion-systems.md) for how the type scale ties to spacing / sizing / radius scales.
39
68
 
40
69
  ---
41
70
 
@@ -43,11 +72,11 @@ Never create a scale ad-hoc. Pick one ratio, generate the scale, use only values
43
72
 
44
73
  | Context | Line height | Notes |
45
74
  |---|---|---|
46
- | Body text | **1.5 1.75** | More generous = more readable |
47
- | Headings | **1.1 1.3** | Tight heading stacks look intentional |
75
+ | Body text | **1.5 - 1.75** | More generous = more readable |
76
+ | Headings | **1.1 - 1.3** | Tight heading stacks look intentional |
48
77
  | Captions / small text | **1.4** | Smaller text needs more breathing room |
49
- | Code blocks | **1.6 1.8** | Line scanning for code |
50
- | Display / hero | **0.9 1.1** | Can go very tight for dramatic effect |
78
+ | Code blocks | **1.6 - 1.8** | Line scanning for code |
79
+ | Display / hero | **0.9 - 1.1** | Can go very tight for dramatic effect |
51
80
 
52
81
  ---
53
82
 
@@ -55,9 +84,9 @@ Never create a scale ad-hoc. Pick one ratio, generate the scale, use only values
55
84
 
56
85
  | Context | Characters per line | Notes |
57
86
  |---|---|---|
58
- | Desktop body | **65 75 chars** | Optimal reading comfort |
59
- | Mobile body | **35 55 chars** | Narrower viewport forces shorter |
60
- | Hero/display | **35 55 chars** | Headings should never wrap awkwardly |
87
+ | Desktop body | **65 - 75 chars** | Optimal reading comfort |
88
+ | Mobile body | **35 - 55 chars** | Narrower viewport forces shorter |
89
+ | Hero/display | **35 - 55 chars** | Headings should never wrap awkwardly |
61
90
  | Data/tables | No limit | Tables have own structure |
62
91
 
63
92
  Enforce with `max-width`: `65ch` for body containers works with any font size.
@@ -68,13 +97,13 @@ Enforce with `max-width`: `65ch` for body containers works with any font size.
68
97
 
69
98
  | Role | Weight | Notes |
70
99
  |---|---|---|
71
- | Display headings | **700 900** | Bold commands attention |
72
- | Page headings | **600 700** | Strong but not display-level |
73
- | Section headings | **500 600** | Distinguish from body |
100
+ | Display headings | **700 - 900** | Bold commands attention |
101
+ | Page headings | **600 - 700** | Strong but not display-level |
102
+ | Section headings | **500 - 600** | Distinguish from body |
74
103
  | Body text | **400** | Regular - no emphasis weight |
75
104
  | UI labels | **500** | Slightly heavier than body |
76
105
  | Captions | **400** | Regular - size reduces emphasis |
77
- | Monospace code | **400 500** | |
106
+ | Monospace code | **400 - 500** | |
78
107
 
79
108
  **Rule**: Never use `font-weight: 300` (light) on small text. It becomes illegible below 16px.
80
109
 
@@ -127,7 +156,7 @@ Enforce with `max-width`: `65ch` for body containers works with any font size.
127
156
 
128
157
  **All caps body text** - reserved for: labels, badges, category markers, short UI labels only. Never for sentences or paragraphs.
129
158
 
130
- **Inconsistent tracking** - only use `letter-spacing` intentionally. Positive tracking on uppercase labels is fine. Negative tracking on small body text reduces readability. Random tracking changes across components signal lack of system.
159
+ **Inconsistent tracking** - only use `letter-spacing` intentionally. Positive tracking on uppercase labels is fine. Negative tracking on small body text reduces readability.
131
160
 
132
161
  ---
133
162
 
@@ -136,8 +165,8 @@ Enforce with `max-width`: `65ch` for body containers works with any font size.
136
165
  | Use case | letter-spacing |
137
166
  |---|---|
138
167
  | Body text | `0` (default) |
139
- | Uppercase labels / badges | `0.05em 0.1em` |
140
- | Display headings | `−0.02em 0.01em` |
168
+ | Uppercase labels / badges | `0.05em - 0.1em` |
169
+ | Display headings | `-0.02em - 0.01em` |
141
170
  | Monospace code | `0` or slight positive |
142
171
 
143
172
  ---
@@ -174,68 +203,19 @@ Test: Can you tell which element is a heading just from the weight/family, witho
174
203
 
175
204
  ## Brand Archetype Quick Guide
176
205
 
177
- Pick the archetype closest to the project brief; use the recommended pairing
178
- as a starting point (adjust for specific constraints).
179
-
180
206
  | Archetype | Character | Recommended Pairing |
181
207
  |-----------|-----------|---------------------|
182
208
  | SaaS / productivity | clear, neutral, utilitarian | Inter (UI) + Inter (body) - single family |
183
209
  | Consumer / editorial | warm, opinionated, expressive | Fraunces or GT Sectra (display) + Inter (body) |
184
210
  | Enterprise / finance | authoritative, conservative | IBM Plex Sans (UI) + IBM Plex Serif (body) |
185
211
  | Developer tools | technical, efficient | Geist (UI) + Geist Mono (code) |
186
- | Bold / expressive | high-energy, distinctive | Söhne or Mona Sans (display) + Inter (body) |
187
-
188
- **Selection heuristic:** If the brief uses words like "professional", "trustworthy", "clean" → SaaS or Enterprise. If "warm", "editorial", "narrative" → Consumer. If "bold", "energetic", "distinctive" → Bold. If "technical", "efficient", "fast" → Dev tools.
189
-
190
- ---
191
-
192
- ## Variable Fonts
193
-
194
- Variable fonts expose typographic axes that can be animated or set per-context
195
- via `font-variation-settings`. Prefer variable fonts over static family fallbacks
196
- when available - one file covers all weights and widths.
197
-
198
- ### Common axes
199
-
200
- | Axis | Range | Purpose |
201
- |------|-------|---------|
202
- | wght | 100–900 | Weight (Thin → Black) |
203
- | wdth | 50%–150% | Width (Condensed → Extended) |
204
- | ital | 0 / 1 | Italic toggle (discrete in most) |
205
- | opsz | font-size value | Optical size (auto-applies when `font-optical-sizing: auto`) |
206
-
207
- ### @font-face format
208
-
209
- ```css
210
- @font-face {
211
- font-family: 'InterVariable';
212
- src: url('/fonts/InterVariable.woff2') format('woff2-variations');
213
- font-weight: 100 900;
214
- font-style: normal;
215
- }
216
- ```
217
-
218
- ### Usage via font-variation-settings
219
-
220
- ```css
221
- .heading { font-variation-settings: "wght" 700, "opsz" 32; }
222
- .body { font-variation-settings: "wght" 400; }
223
- ```
224
-
225
- ### Fallback strategy
226
-
227
- Always include a non-variable fallback of the same family in the font stack:
228
-
229
- ```css
230
- font-family: 'InterVariable', 'Inter', -apple-system, system-ui, sans-serif;
231
- ```
212
+ | Bold / expressive | high-energy, distinctive | Sohne or Mona Sans (display) + Inter (body) |
232
213
 
233
- **See:** [`./i18n.md`](./i18n.md) §Multi-Script Font Stacks for when a multi-script project should ship weighted-static fonts rather than a single variable font (some scripts ship as static-only families; mixing scripts in a single variable file is rarely viable).
214
+ **Selection heuristic:** If the brief uses words like "professional", "trustworthy", "clean" use SaaS or Enterprise. If "warm", "editorial", "narrative" use Consumer. If "bold", "energetic", "distinctive" use Bold. If "technical", "efficient", "fast" use Dev tools.
234
215
 
235
216
  ---
236
217
 
237
218
  ## Micro-Typography
238
- Source: jakubkrehel/make-interfaces-feel-better (MIT) - typography.md
239
219
 
240
220
  ### text-wrap
241
221
 
@@ -254,7 +234,7 @@ Apply antialiasing at root level only:
254
234
  -moz-osx-font-smoothing: grayscale;
255
235
  }
256
236
  ```
257
- Never apply per-element - this creates inconsistency within a single text block and is one of the most common micro-typography mistakes. The antialiased value makes text appear slightly thinner/lighter, which is generally preferred for UI type at modern screen densities.
237
+ Never apply per-element - this creates inconsistency within a single text block.
258
238
 
259
239
  ### Tabular numerals
260
240
 
@@ -262,52 +242,4 @@ Use tabular-nums on any surface where numbers change dynamically or need to alig
262
242
  ```css
263
243
  .counter, .price, .timer, .table-cell { font-variant-numeric: tabular-nums; }
264
244
  ```
265
- Proportional numerals (the default) cause text to shift width when numbers change, creating a distracting jitter in timers and prices. Exception: Inter's `1` character widens slightly with tabular-nums - test at your numeric composition before committing.
266
-
267
- ## Font Pairings Catalog
268
- Source: nextlevelbuilder/ui-ux-pro-max-skill (MIT) - data/typography.csv
269
-
270
- 57 professionally curated pairings grouped by use-case vertical. For font loading, see `reference/data/google-fonts.csv` for the full 1923-font reference.
271
-
272
- ### SaaS / Productivity
273
- - **Inter + Inter** (mono weight hierarchy) - The "safe default" for app UIs. Use regular (400) for body, medium (500) for labels, semibold (600) for headings. Consistent x-height, excellent at small sizes.
274
- - **Inter + JetBrains Mono** - For dev tools and dashboards with code display. JetBrains Mono has excellent legibility at 12-14px.
275
- - **Geist Sans + Geist Mono** - Vercel's pair; clean, modern, designed together.
276
- - **Outfit + DM Mono** - Friendly SaaS feel with clear code fallback.
277
-
278
- ### Consumer / Marketing
279
- - **Satoshi + Cabinet Grotesk** - High-energy, modern consumer feel.
280
- - **Plus Jakarta Sans + Syne** - Playful but legible; works for creative consumer apps.
281
- - **DM Sans + DM Serif Display** - Classic pairing; editorial headers, clean body.
282
- - **Nunito + Source Code Pro** - Approachable and friendly.
283
-
284
- ### Finance / Enterprise
285
- - **IBM Plex Sans + IBM Plex Mono** - Authoritative, systematic, designed for data-heavy interfaces.
286
- - **Source Sans 3 + Source Code Pro** - Adobe's workhorse pair; widely trusted.
287
- - **Lato + Roboto Mono** - Clean, neutral enterprise pair.
288
-
289
- ### Editorial / Publishing
290
- - **Playfair Display + Source Serif 4** - High contrast serif headers with readable body serif.
291
- - **Cormorant Garamond + Proza Libre** - Elegant luxury/editorial tone.
292
- - **Libre Baskerville + Libre Franklin** - Free-license editorial pair.
293
- - **EB Garamond + Lato** - Classic print feel with modern body.
294
-
295
- ### Wellness / Health
296
- - **Nunito + Nunito Sans** - Soft, approachable, consistent x-height.
297
- - **Quicksand + Work Sans** - Rounded, friendly, healthcare-appropriate.
298
- - **Raleway + Open Sans** - Clean and welcoming.
299
-
300
- ### Dev Tools
301
- - **JetBrains Mono + Inter** - Code-first, UI-second; natural for developer tools.
302
- - **Fira Code + Fira Sans** - Cohesive family; ligatures available.
303
- - **Cascadia Code + Segoe UI** - Microsoft's modern dev pair.
304
-
305
- ### Luxury / Fashion
306
- - **Cormorant + Montserrat** - High contrast serif + geometric sans; classic luxury.
307
- - **Bodoni Moda + Jost** - Fashion editorial feel.
308
- - **Playfair Display + Raleway** - Elegant header + clean body.
309
-
310
- ### Gaming / Entertainment
311
- - **Syne + DM Sans** - Bold, energetic headers; clean readable body.
312
- - **Bebas Neue + Open Sans** - Impact headlines; neutral body.
313
- - **Exo 2 + Roboto** - Futuristic but readable.
245
+ Proportional numerals (the default) cause text to shift width when numbers change, creating jitter in timers and prices. Exception: Inter's `1` character widens slightly with tabular-nums - test at your numeric composition before committing.
@@ -0,0 +1,60 @@
1
+ # UX Writing - Domain Index
2
+
3
+ This is the domain entry-point for UX writing. Load this file when the task
4
+ involves voice, tone, or the copy standards that govern text a user reads in
5
+ the product: button labels, error messages, empty states, onboarding copy, and
6
+ microcopy. It does not cover the engineering side of localization (see
7
+ `reference/responsive.md` for string expansion budgets and `Intl.*` APIs); it
8
+ does not cover label position in forms or information architecture (see
9
+ `reference/interaction.md`).
10
+
11
+ ---
12
+
13
+ ## Fragment Index
14
+
15
+ → **`reference/brand-voice.md`** (Phase 24) - use when establishing or
16
+ auditing tone: 6 voice axes (Formal-Casual, Serious-Playful, etc.), 12
17
+ archetypes, tone-by-context matrix, industry-context palettes
18
+
19
+ → **`reference/style-vocabulary.md`** (Phase 24) - use when confirming an
20
+ aesthetic direction has a compatible voice register: the `Avoid For` column
21
+ cross-checks brand fit; `Best For` confirms product-type alignment
22
+
23
+ → **`reference/anti-patterns.md`** - use when auditing existing copy: the
24
+ BAN/SLOP grep patterns surface copy violations (AI-tells, filler phrases)
25
+ alongside visual ones
26
+
27
+ ---
28
+
29
+ ## Rules of Thumb
30
+
31
+ **1. Voice axes are independent from archetypes.**
32
+ Pick a position on each of the 6 axes first (Formal-Casual, Serious-Playful,
33
+ Authoritative-Supportive, and so on), then layer an archetype on top. The
34
+ archetype does not determine the axis position - they are orthogonal dimensions
35
+ in `reference/brand-voice.md`.
36
+
37
+ **2. Never use placeholder text as the sole label for a form field.**
38
+ It disappears on focus, fails WCAG 1.3.5, and collapses under translation.
39
+ Top-aligned labels are the only position that absorbs localization expansion
40
+ without breaking layout.
41
+
42
+ **3. Error messages follow a three-clause structure: what happened, why, what
43
+ to do.**
44
+ State the event in past tense, explain the cause in one clause, give a present
45
+ tense imperative for recovery. No tech jargon. Never blame the user.
46
+
47
+ **4. Shift toward supportive tone during error, empty-state, and onboarding
48
+ moments.**
49
+ Even a formally-voiced product should move on the axis toward supportive when
50
+ the user is at risk of abandonment. The per-context tone matrix in
51
+ `reference/brand-voice.md` provides the exact adjustment.
52
+
53
+ ---
54
+
55
+ ## Cross-Domain See Also
56
+
57
+ - String expansion budgets constrain copy length: `reference/responsive.md`
58
+ - Error copy paired with form patterns: `reference/interaction.md`
59
+ - Empty-state copy pairs with onboarding pattern: `reference/interaction.md`
60
+ - Style direction voice register cross-check: `reference/style-vocabulary.md`