dreative 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +49 -27
  2. package/dist/cli/audit.js +206 -0
  3. package/dist/cli/audit.test.js +79 -0
  4. package/dist/cli/docsCheck.js +163 -0
  5. package/dist/cli/docsCheck.test.js +8 -0
  6. package/dist/cli/index.js +81 -8
  7. package/dist/server/preview.js +73 -73
  8. package/dist/server/store.js +11 -0
  9. package/dist/shared/artifacts.js +162 -0
  10. package/dist/shared/design.js +42 -22
  11. package/dist/shared/ruleSystem.js +130 -0
  12. package/dist/shared/ruleSystem.test.js +187 -0
  13. package/dist/shared/skillSystem.js +173 -0
  14. package/dist/shared/skillSystem.test.js +110 -0
  15. package/dist/ui/assets/{index--vztc_MR.js → index-CKwmbx2j.js} +13 -13
  16. package/dist/ui/index.html +12 -12
  17. package/package.json +5 -3
  18. package/skill/dreative/DESIGN.md +290 -95
  19. package/skill/dreative/PLAN.md +462 -71
  20. package/skill/dreative/SKILL.md +230 -126
  21. package/skill/dreative/frameworks/nextjs.md +13 -0
  22. package/skill/dreative/frameworks/react-vite.md +12 -0
  23. package/skill/dreative/frameworks/styling.md +14 -0
  24. package/skill/dreative/frameworks/sveltekit.md +10 -0
  25. package/skill/dreative/frameworks/vue-nuxt.md +12 -0
  26. package/skill/dreative/recipes/3d-recipes.md +44 -0
  27. package/skill/dreative/recipes/cinematic-recipes.md +19 -0
  28. package/skill/dreative/recipes/immersive-recipes.md +18 -0
  29. package/skill/dreative/recipes/media-recipes.md +60 -0
  30. package/skill/dreative/recipes/motion-recipes.md +44 -0
  31. package/skill/dreative/references/ARTIFACTS.md +180 -0
  32. package/skill/dreative/references/REFLEX_FONTS.json +44 -0
  33. package/skill/dreative/references/RULES.json +186 -0
  34. package/skill/dreative/references/SKILL_CONTRACT.md +30 -0
  35. package/skill/dreative/references/TIERS.md +42 -0
  36. package/skill/dreative/schemas/plan.schema.json +241 -0
  37. package/skill/dreative/schemas/verify.schema.json +61 -0
  38. package/skill/dreative/skills/3d.md +94 -157
  39. package/skill/dreative/skills/cinematic.md +56 -232
  40. package/skill/dreative/skills/experimental.md +111 -0
  41. package/skill/dreative/skills/immersive.md +61 -223
  42. package/skill/dreative/skills/interaction.md +9 -1
  43. package/skill/dreative/skills/media.md +135 -216
  44. package/skill/dreative/skills/mobile.md +128 -117
  45. package/skill/dreative/skills/motion.md +89 -229
  46. package/skill/dreative/skills/refined.md +116 -102
  47. package/skill/dreative/skills/ux.md +155 -144
  48. package/dist/server/ai.js +0 -177
@@ -1,102 +1,116 @@
1
- # Dreative Specialist Skill — Refined Clean Business
2
-
3
- Load this file when `plan.skills` includes `refined`, or the brief/prompt asks
4
- for a "clean modern business site", premium-but-calm marketing, DTC/e-commerce
5
- polish, "professional, not flashy", or names references like ch.maswitzerland.com
6
- or lovvelavva.com. This is the OPPOSITE pole from immersive/cinematic: quality
7
- expressed through restraint spacing, photography, and type doing all the work,
8
- with motion barely above zero. Most real client work lands here; treat it as a
9
- craft discipline, not the absence of one.
10
-
11
- It EXTENDS DESIGN.md (everything applies; this file tightens the dials). It does
12
- NOT stack with `immersive`/`cinematic` those are different registers. It pairs
13
- well with a light dose of `interaction` (press states, underline draws), the
14
- first tier of `motion` (one hero sequence, 2-3 in-view reveals), `ux` (this
15
- register's audience punishes broken function hardest), and media.md's quiet
16
- treatments only (ken-burns, curtain reveals, one hover-woken loop — imagery
17
- here is generated/sourced to ONE photographic grade, media.md §1).
18
-
19
- ## 0. The register: expensive silence
20
-
21
- What separates premium-clean from generic-clean is not any element it's the
22
- ratios:
23
-
24
- - **Whitespace is the brand.** Section padding 96-160px desktop / 56-80px
25
- mobile; content max-width 1200-1320px with WIDE outer gutters; one idea per
26
- viewport. If a section feels empty, that's the look working — resist filling.
27
- - **Photography carries the emotion.** Real product/lifestyle imagery, art-
28
- directed to one consistent grade (one light temperature, one background
29
- family). Full-bleed image sections alternate with contained text sections —
30
- the rhythm image / text / image IS the page structure. Never decorate around
31
- weak imagery; demand or generate better imagery instead.
32
- - **Type does hierarchy, color stays out of the way.** Near-monochrome palette:
33
- warm or cool neutral family + ONE accent used almost exclusively on the
34
- primary CTA and links. Backgrounds shift between 2-3 tints of the neutral
35
- (e.g. white / #f6f5f2 / #111) to separate sections without borders.
36
- - **Motion whispers.** Motion dial effectively ≤ 4: fade-rise entrances
37
- (300-400ms, once), a sticky nav that gains a hairline+blur, underline draws,
38
- press states. No parallax beyond 4%, no pinning, no canvas. A single
39
- restrained signature (a slow ken-burns on the hero image, or a marquee of
40
- press logos) is the ceiling.
41
-
42
- ## 1. Page anatomy (marketing/DTC form)
43
-
44
- The proven skeleton vary the composition per DESIGN.md §5, not the order
45
- logic:
46
-
47
- 1. **Hero**: one full-width image or split layout; headline 8 words stating
48
- the value in plain language; one CTA. No feature bullets in the hero.
49
- 2. **Credibility strip**: press/client logos, real marks, grayscale or
50
- single-tint (lovvelavva runs Forbes/Women's Health/Real Simple here
51
- this section converts and belongs high on DTC pages).
52
- 3. **Value sections** (2-4): alternating image/text, each making ONE claim
53
- with 1-2 sentences of support. Icons only if custom-drawn; three-generic-
54
- icon-cards is the tell this register must avoid most.
55
- 4. **Product/collection grid**: large images, generous gaps (24-32px), minimal
56
- card chrome image, name, price/one-liner; hover = image swap or subtle
57
- zoom-crop INSIDE a fixed frame (no card growth).
58
- 5. **Social proof**: 1-3 real testimonials with names/photos, editorial layout
59
- (big quote type), never a 3-card testimonial row.
60
- 6. **Closing CTA**: calm full-width section, one sentence, one button.
61
- 7. **Footer**: structured, generous, quiet the footer's polish is a trust
62
- signal in this register; give it real columns, legal, newsletter.
63
-
64
- E-commerce specifics: sticky add-to-cart on product pages (mobile bottom bar),
65
- price always visible, shipping/returns reassurance near the CTA, cart as a
66
- slide-over drawer not a page.
67
-
68
- ## 2. The discovery-grid variant (cosmos.so-like)
69
-
70
- For content/discovery products (galleries, moodboards, catalogs): near-zero
71
- chrome around a masonry/justified image grid; dark or paper-white surface;
72
- images at native aspect ratios (never uniform crops); hover = slight lift +
73
- metadata fade-in on top of the image; infinite scroll with a sentinel loader;
74
- the search/filter bar is the only persistent UI. The product IS the grid —
75
- navigation, branding, and controls stay almost invisible until needed.
76
-
77
- ## 3. What "modern" means here (2024+, not 2016 flat)
78
-
79
- - Hairline borders (1px, 8-12% alpha) instead of shadows for structure; the
80
- 2-3 stacked tinted shadows (interaction.md §3) reserved for genuinely
81
- floating elements (dropdowns, drawers).
82
- - Larger type than feels safe: body 17-18px on marketing pages, display
83
- clamped 2.5-4.5rem, tight leading. Small timid type is the #1 dated tell.
84
- - Radius system: one value family — either near-square (2-4px, editorial/
85
- luxury) or soft (12-16px, DTC/consumer) never mixed.
86
- - Buttons: solid accent primary + quiet text-link secondary. Pill shape only
87
- in the consumer/DTC variant. No outlined-button armies.
88
- - Real `<img>`/`<picture>` with proper aspect-ratio boxes; no CSS-drawn
89
- product mockups; `object-fit: cover` with art-directed focal points.
90
-
91
- ## 4. Guardrails
92
-
93
- - If you're adding an effect to make a section interesting, the section's
94
- content or imagery is the problem fix that instead.
95
- - No gradient meshes, no glassmorphism cards, no floating blob backgrounds,
96
- no emoji in UI copy: all instantly cheapen this register.
97
- - Accessibility floor is easy here don't squander it: AA contrast on the
98
- tinted neutrals (test the #767676-gray-on-white trap), visible focus,
99
- semantic landmarks.
100
- - Performance IS the aesthetic: LCP image preloaded, fonts 2 files,
101
- zero animation libraries unless motion is actually used — a clean site
102
- that loads instantly reads as more premium than any effect.
1
+ # Dreative Specialist Skill — Refined Clean Business
2
+
3
+ ## Contract
4
+
5
+ Follow `../references/SKILL_CONTRACT.md`. Dependencies: `ux`, `mobile`; add
6
+ `media` when photography is a primary material. Deliver a precise type/spacing/
7
+ surface system, restrained signature detail, purposeful photography, complete
8
+ states, and responsive proof. Do not confuse refined with generic minimalism.
9
+ Done means hierarchy, copy, conversion flow, polish, and calm motion hold across
10
+ desktop, keyboard, and phone.
11
+
12
+ Use `../references/REFLEX_FONTS.json` through DESIGN.md's font procedure. Common
13
+ product or editorial fonts remain valid when brand continuity, metrics, language,
14
+ reference, variable-font capability, or performance specifically earns them;
15
+ generic “clean and modern” reasoning does not.
16
+
17
+ Load this file when `plan.skills` includes `refined`, or the brief/prompt asks
18
+ for a "clean modern business site", premium-but-calm marketing, DTC/e-commerce
19
+ polish, "professional, not flashy", or names references like ch.maswitzerland.com
20
+ or lovvelavva.com. This is the OPPOSITE pole from immersive/cinematic: quality
21
+ expressed through restraint spacing, photography, and type doing all the work,
22
+ with motion barely above zero. Most real client work lands here; treat it as a
23
+ craft discipline, not the absence of one.
24
+
25
+ It EXTENDS DESIGN.md (everything applies; this file tightens the dials). It does
26
+ NOT stack with `immersive`/`cinematic` those are different registers. It pairs
27
+ well with a light dose of `interaction` (press states, underline draws), the
28
+ first tier of `motion` (one hero sequence, 2-3 in-view reveals), `ux` (this
29
+ register's audience punishes broken function hardest), and media.md's quiet
30
+ treatments only (ken-burns, curtain reveals, one hover-woken loop imagery
31
+ here is generated/sourced to ONE photographic grade, media.md §4).
32
+
33
+ ## 0. The register: expensive silence
34
+
35
+ What separates premium-clean from generic-clean is not any element it's the
36
+ ratios:
37
+
38
+ - **Whitespace is the brand.** Section padding 96-160px desktop / 56-80px
39
+ mobile; content max-width 1200-1320px with WIDE outer gutters; one idea per
40
+ viewport. If a section feels empty, that's the look working — resist filling.
41
+ - **Photography carries the emotion.** Real product/lifestyle imagery, art-
42
+ directed to one consistent grade (one light temperature, one background
43
+ family). Full-bleed image sections alternate with contained text sections —
44
+ the rhythm image / text / image IS the page structure. Never decorate around
45
+ weak imagery; demand or generate better imagery instead.
46
+ - **Type does hierarchy, color stays out of the way.** Near-monochrome palette:
47
+ warm or cool neutral family + ONE accent used almost exclusively on the
48
+ primary CTA and links. Backgrounds shift between 2-3 tints of the neutral
49
+ (e.g. white / #f6f5f2 / #111) to separate sections without borders.
50
+ - **Motion whispers.** Motion dial effectively 4: fade-rise entrances
51
+ (300-400ms, once), a sticky nav that gains a hairline+blur, underline draws,
52
+ press states. No parallax beyond 4%, no pinning, no canvas. A single
53
+ restrained signature (a slow ken-burns on the hero image, or a marquee of
54
+ press logos) is the ceiling.
55
+
56
+ ## 1. Page anatomy (marketing/DTC form)
57
+
58
+ The proven skeleton vary the composition per DESIGN.md §5, not the order
59
+ logic:
60
+
61
+ 1. **Hero**: one full-width image or split layout; headline 8 words stating
62
+ the value in plain language; one CTA. No feature bullets in the hero.
63
+ 2. **Credibility strip**: press/client logos, real marks, grayscale or
64
+ single-tint (lovvelavva runs Forbes/Women's Health/Real Simple here
65
+ this section converts and belongs high on DTC pages).
66
+ 3. **Value sections** (2-4): alternating image/text, each making ONE claim
67
+ with 1-2 sentences of support. Icons only if custom-drawn; three-generic-
68
+ icon-cards is the tell this register must avoid most.
69
+ 4. **Product/collection grid**: large images, generous gaps (24-32px), minimal
70
+ card chrome image, name, price/one-liner; hover = image swap or subtle
71
+ zoom-crop INSIDE a fixed frame (no card growth).
72
+ 5. **Social proof**: 1-3 real testimonials with names/photos, editorial layout
73
+ (big quote type), never a 3-card testimonial row.
74
+ 6. **Closing CTA**: calm full-width section, one sentence, one button.
75
+ 7. **Footer**: structured, generous, quiet the footer's polish is a trust
76
+ signal in this register; give it real columns, legal, newsletter.
77
+
78
+ E-commerce specifics: sticky add-to-cart on product pages (mobile bottom bar),
79
+ price always visible, shipping/returns reassurance near the CTA, cart as a
80
+ slide-over drawer not a page.
81
+
82
+ ## 2. The discovery-grid variant (cosmos.so-like)
83
+
84
+ For content/discovery products (galleries, moodboards, catalogs): near-zero
85
+ chrome around a masonry/justified image grid; dark or paper-white surface;
86
+ images at native aspect ratios (never uniform crops); hover = slight lift +
87
+ metadata fade-in on top of the image; infinite scroll with a sentinel loader;
88
+ the search/filter bar is the only persistent UI. The product IS the grid —
89
+ navigation, branding, and controls stay almost invisible until needed.
90
+
91
+ ## 3. What "modern" means here (2024+, not 2016 flat)
92
+
93
+ - Hairline borders (1px, 8-12% alpha) instead of shadows for structure; the
94
+ 2-3 stacked tinted shadows (interaction.md §3) reserved for genuinely
95
+ floating elements (dropdowns, drawers).
96
+ - Larger type than feels safe: body 17-18px on marketing pages, display
97
+ clamped 2.5-4.5rem, tight leading. Small timid type is the #1 dated tell.
98
+ - Radius system: one value family — either near-square (2-4px, editorial/
99
+ luxury) or soft (12-16px, DTC/consumer) — never mixed.
100
+ - Buttons: solid accent primary + quiet text-link secondary. Pill shape only
101
+ in the consumer/DTC variant. No outlined-button armies.
102
+ - Real `<img>`/`<picture>` with proper aspect-ratio boxes; no CSS-drawn
103
+ product mockups; `object-fit: cover` with art-directed focal points.
104
+
105
+ ## 4. Guardrails
106
+
107
+ - If you're adding an effect to make a section interesting, the section's
108
+ content or imagery is the problem — fix that instead.
109
+ - No gradient meshes, no glassmorphism cards, no floating blob backgrounds,
110
+ no emoji in UI copy: all instantly cheapen this register.
111
+ - Accessibility floor is easy here — don't squander it: AA contrast on the
112
+ tinted neutrals (test the #767676-gray-on-white trap), visible focus,
113
+ semantic landmarks.
114
+ - Performance IS the aesthetic: LCP image preloaded, fonts ≤ 2 files,
115
+ zero animation libraries unless motion is actually used — a clean site
116
+ that loads instantly reads as more premium than any effect.
@@ -1,144 +1,155 @@
1
- # Dreative Specialist Skill — Functional UX (everything works)
2
-
3
- Load this file when `plan.skills` includes `ux`, for ANY product-register page,
4
- and whenever a redesign touches navigation, forms, or stateful views. It EXTENDS
5
- DESIGN.md §9 (the product floor) into a full working-page contract. Its premise:
6
- a beautiful page where the menu doesn't open, a link 404s, or an effect eats
7
- clicks is a FAILED page visual craft cannot compensate for broken function.
8
- This skill is the reason "immersive but broken" never ships: it defines what
9
- "works" means, mechanically, and the runtime verification pass (SKILL.md) tests
10
- against it.
11
-
12
- ## 0. The working-page contract
13
-
14
- Every page you ship satisfies, verifiably:
15
-
16
- 1. Every visible control does something real (or is explicitly disabled with a
17
- reason). No dead buttons, no `href="#"`, no `onClick={() => {}}`.
18
- 2. Every navigation target resolvesinternal routes exist, anchors match real
19
- ids, external links open safely (`rel="noopener"`, `target="_blank"` only
20
- for true externals).
21
- 3. Every stateful view renders all its states (loading/empty/error/success),
22
- not just the happy path.
23
- 4. Keyboard alone can operate everything a pointer can.
24
- 5. Nothing decorative intercepts input, blocks scroll, or steals focus.
25
-
26
- ## 1. Navigation
27
-
28
- - **Links resolve.** Before shipping, list every `href`/`to`/`navigate` target
29
- and check each exists (route table, file, or real URL). A designed 404 is
30
- still a 404.
31
- - **Active state**: the nav marks the current page/section (aria-current +
32
- visual). Section-scroll pages update it via IntersectionObserver.
33
- - **Mobile menu is a component, not a hope**: opens AND closes (button, Esc,
34
- backdrop click, and on route change); scroll-locks the body while open
35
- (`overflow:hidden` on html, restore on close with scrollbar-gutter
36
- compensation so the page doesn't shift); traps focus while open and returns
37
- focus to the trigger on close; the toggle reflects state
38
- (`aria-expanded`, icon morph). Test the open→navigate→back sequence — stale
39
- open menus after route changes are the #1 shipped-menu bug.
40
- - **Anchors under fixed headers**: every in-page anchor target gets
41
- `scroll-margin-top` header height; smooth-scroll respects reduced-motion.
42
- - **Logo home. Back button works** spatial/SPA transitions must not break
43
- history (immersive.md §1); modals and drawers close on back where users
44
- expect it (mobile especially).
45
- - **Custom scroll (Lenis)** must not break anchors, keyboard scrolling
46
- (space/PgDn/arrows), or focus-into-view; wire `lenis.scrollTo` for anchor
47
- clicks and leave native behavior for the rest.
48
-
49
- ## 2. Forms
50
-
51
- - Every form submits somewhere real, or is explicitly wired to a stub with a
52
- visible success simulation never a button that swallows the click.
53
- - Labels above inputs (placeholder-as-label banned, DESIGN.md §9);
54
- autocomplete attributes on identity fields; correct `type`/`inputmode`
55
- (email, tel, numeric) so mobile keyboards match.
56
- - Validate on submit first (not on first keystroke); after first submit,
57
- re-validate per field on blur/change. Errors inline, next to the field,
58
- specific ("Enter a valid email"), with `aria-describedby` wiring and focus
59
- moved to the first invalid field.
60
- - Submit feedback: button enters loading state (spinner inside, fixed width,
61
- interaction.md §5), double-submit prevented, success confirmed visibly
62
- (inline message or state change not just a toast that may be missed),
63
- failure recoverable (inputs keep their values; never wipe a form on error).
64
- - Enter submits single-field forms (newsletter). Required fields marked; the
65
- disabled-until-valid pattern only when errors show on hover/focus of the
66
- disabled button, otherwise keep the button enabled and validate on click.
67
-
68
- ## 3. State coverage (every data view)
69
-
70
- For each list/table/feed/detail view, all four states are designed and
71
- reachable: **loading** (skeleton shaped like the content, DESIGN.md §9),
72
- **empty** (teaches the interface: what this will show + the action that fills
73
- it never a blank area or a lonely "No data"), **error** (what happened + a
74
- retry affordance), **populated** (including the long-content case: 100 items,
75
- 40-character names, overflow handled per DESIGN.md §15). Async actions get
76
- optimistic UI only when low-stakes (DESIGN.md §6); destructive actions get
77
- confirmation and, ideally, undo instead of a scary modal.
78
-
79
- ## 4. Keyboard, focus, and the hit-area audit
80
-
81
- - Full tab walk: every interactive element reachable in visual order, operable
82
- (Enter/Space), with a visible `:focus-visible` ring (interaction.md §0), and
83
- escapable (no traps outside intentional modal traps).
84
- - Whatever hover reveals, focus reveals (cards' secondary actions, hover-woken
85
- media, dropdown menus). Custom gestures (drag, click-and-hold) always have a
86
- plain keyboard/click equivalent (cinematic.md §2).
87
- - **The pointer-events audit** (the #1 cause of "cool but broken"): walk every
88
- overlay in the stacking order canvases, gradient/grain layers, custom
89
- cursor layers, transition curtains, closed menus, preloaders — and verify
90
- each is `pointer-events: none` (or removed from the DOM) whenever it is not
91
- actively being interacted with. A finished preloader or a closed fullscreen
92
- menu sitting at `opacity:0` with pointer-events on is an invisible wall over
93
- the whole page. Then hit-test the controls: click every button/link at its
94
- visual position if something above it swallows the click, that's a §15
95
- spatial-integrity fail, fix the layer not the button.
96
- - Modals/drawers: focus trapped inside, Esc closes, focus returns to trigger,
97
- `aria-modal` + labelled; scrim click closes (unless data-loss risk).
98
- - Semantic HTML first: real `<button>`/`<a>`/`<nav>`/`<main>`/headings in
99
- order — divs-with-onClick fail half this section automatically.
100
-
101
- ## 5. Scroll and layout stability
102
-
103
- - Zero layout shift from async content: media boxes sized up front (media.md
104
- §5), fonts `swap` with metric-compatible fallbacks, skeletons the same size
105
- as what replaces them, no banners that push content after load.
106
- - Scroll restoration: back/forward returns to the previous position (default
107
- browser behavior don't break it with manual scroll-to-top on every route;
108
- scroll to top only on forward navigation to a NEW page).
109
- - Fixed bars: content padded so nothing hides beneath them (DESIGN.md §15);
110
- 100dvh not 100vh; no horizontal body scroll at 320px.
111
- - Long pages get orientation aids: sticky nav or progress indication, and a
112
- footer that actually ends the page (no infinite-feeling voids).
113
-
114
- ## 6. Feedback and perceived performance
115
-
116
- - Every async action acknowledges input within 100ms (pressed state, spinner,
117
- optimistic change) silence after a click reads as broken even when it
118
- works.
119
- - Toasts only for transient global events; they stack in ONE corner slot
120
- (DESIGN.md §15), auto-dismiss 4s, pause on hover, and are `aria-live`.
121
- - Destructive/irreversible actions: confirm with specifics ("Delete 3 items?"),
122
- never bare "Are you sure?"; prefer undo-toast over confirm-modal when safe.
123
- - Copy per DESIGN.md §8's UX-writing rules: buttons say what they do, errors
124
- say what to do next.
125
-
126
- ## 7. The functional audit (run at verification time)
127
-
128
- This is the checklist the runtime verification pass (SKILL.md) executes with
129
- browser tools — or walks mentally, file by file, when no browser exists:
130
-
131
- 1. Click every nav link + the logo; confirm each lands where labeled.
132
- 2. Open and close the mobile menu (both directions, plus Esc, plus navigate-
133
- while-open) at 390px width.
134
- 3. Submit each form empty see inline errors; submit valid see success
135
- state; confirm no double-submit.
136
- 4. Tab through the page start to finish; note any unreachable/invisible-focus/
137
- trapped stop.
138
- 5. Hit-test 5+ controls in effect-heavy regions (hero, canvas overlays,
139
- floating elements) every click must land.
140
- 6. Trigger each data view's empty/error state if reachable (or verify the
141
- branch exists in code).
142
- 7. Console: zero uncaught errors during all of the above.
143
-
144
- Report the result as a pass/fail list, fix fails, re-run the failed items once.
1
+ # Dreative Specialist Skill — Functional UX (everything works)
2
+
3
+ ## Contract
4
+
5
+ Universal foundation: ux and baseline mobile apply to every web page.
6
+
7
+ Follow `../references/SKILL_CONTRACT.md`. This universal foundation has no
8
+ specialist dependency; pair it with `mobile` for all web delivery. Deliver the
9
+ preservation manifest, state inventory, semantic/keyboard behavior, feedback,
10
+ and functional audit evidence. It may never be deselected to fund visual work.
11
+ Done means routes, controls, forms, states, focus, hit areas, and failure paths
12
+ work without visual effects.
13
+
14
+ Load this file when `plan.skills` includes `ux`, for ANY product-register page,
15
+ and whenever a redesign touches navigation, forms, or stateful views. It EXTENDS
16
+ DESIGN.md §9 (the product floor) into a full working-page contract. Its premise:
17
+ a beautiful page where the menu doesn't open, a link 404s, or an effect eats
18
+ clicks is a FAILED pagevisual craft cannot compensate for broken function.
19
+ This skill is the reason "immersive but broken" never ships: it defines what
20
+ "works" means, mechanically, and the runtime verification pass (SKILL.md) tests
21
+ against it.
22
+
23
+ ## 0. The working-page contract
24
+
25
+ Every page you ship satisfies, verifiably:
26
+
27
+ 1. Every visible control does something real (or is explicitly disabled with a
28
+ reason). No dead buttons, no `href="#"`, no `onClick={() => {}}`.
29
+ 2. Every navigation target resolves internal routes exist, anchors match real
30
+ ids, external links open safely (`rel="noopener"`, `target="_blank"` only
31
+ for true externals).
32
+ 3. Every stateful view renders all its states (loading/empty/error/success),
33
+ not just the happy path.
34
+ 4. Keyboard alone can operate everything a pointer can.
35
+ 5. Nothing decorative intercepts input, blocks scroll, or steals focus.
36
+
37
+ ## 1. Navigation
38
+
39
+ - **Links resolve.** Before shipping, list every `href`/`to`/`navigate` target
40
+ and check each exists (route table, file, or real URL). A designed 404 is
41
+ still a 404.
42
+ - **Active state**: the nav marks the current page/section (aria-current +
43
+ visual). Section-scroll pages update it via IntersectionObserver.
44
+ - **Mobile menu is a component, not a hope**: opens AND closes (button, Esc,
45
+ backdrop click, and on route change); scroll-locks the body while open
46
+ (`overflow:hidden` on html, restore on close with scrollbar-gutter
47
+ compensation so the page doesn't shift); traps focus while open and returns
48
+ focus to the trigger on close; the toggle reflects state
49
+ (`aria-expanded`, icon morph). Test the open→navigate→back sequence — stale
50
+ open menus after route changes are the #1 shipped-menu bug.
51
+ - **Anchors under fixed headers**: every in-page anchor target gets
52
+ `scroll-margin-top` header height; smooth-scroll respects reduced-motion.
53
+ - **Logo home. Back button works** — spatial/SPA transitions must not break
54
+ history (immersive.md §2); modals and drawers close on back where users
55
+ expect it (mobile especially).
56
+ - **Custom scroll (Lenis)** must not break anchors, keyboard scrolling
57
+ (space/PgDn/arrows), or focus-into-view; wire `lenis.scrollTo` for anchor
58
+ clicks and leave native behavior for the rest.
59
+
60
+ ## 2. Forms
61
+
62
+ - Every form submits somewhere real, or is explicitly wired to a stub with a
63
+ visible success simulation never a button that swallows the click.
64
+ - Labels above inputs (placeholder-as-label banned, DESIGN.md §9);
65
+ autocomplete attributes on identity fields; correct `type`/`inputmode`
66
+ (email, tel, numeric) so mobile keyboards match.
67
+ - Validate on submit first (not on first keystroke); after first submit,
68
+ re-validate per field on blur/change. Errors inline, next to the field,
69
+ specific ("Enter a valid email"), with `aria-describedby` wiring and focus
70
+ moved to the first invalid field.
71
+ - Submit feedback: button enters loading state (spinner inside, fixed width,
72
+ interaction.md §5), double-submit prevented, success confirmed visibly
73
+ (inline message or state change not just a toast that may be missed),
74
+ failure recoverable (inputs keep their values; never wipe a form on error).
75
+ - Enter submits single-field forms (newsletter). Required fields marked; the
76
+ disabled-until-valid pattern only when errors show on hover/focus of the
77
+ disabled button, otherwise keep the button enabled and validate on click.
78
+
79
+ ## 3. State coverage (every data view)
80
+
81
+ For each list/table/feed/detail view, all four states are designed and
82
+ reachable: **loading** (skeleton shaped like the content, DESIGN.md §9),
83
+ **empty** (teaches the interface: what this will show + the action that fills
84
+ it never a blank area or a lonely "No data"), **error** (what happened + a
85
+ retry affordance), **populated** (including the long-content case: 100 items,
86
+ 40-character names, overflow handled per DESIGN.md §15). Async actions get
87
+ optimistic UI only when low-stakes (DESIGN.md §6); destructive actions get
88
+ confirmation and, ideally, undo instead of a scary modal.
89
+
90
+ ## 4. Keyboard, focus, and the hit-area audit
91
+
92
+ - Full tab walk: every interactive element reachable in visual order, operable
93
+ (Enter/Space), with a visible `:focus-visible` ring (interaction.md §0), and
94
+ escapable (no traps outside intentional modal traps).
95
+ - Whatever hover reveals, focus reveals (cards' secondary actions, hover-woken
96
+ media, dropdown menus). Custom gestures (drag, click-and-hold) always have a
97
+ plain keyboard/click equivalent (cinematic.md §3).
98
+ - **The pointer-events audit** (the #1 cause of "cool but broken"): walk every
99
+ overlay in the stacking order — canvases, gradient/grain layers, custom
100
+ cursor layers, transition curtains, closed menus, preloaders — and verify
101
+ each is `pointer-events: none` (or removed from the DOM) whenever it is not
102
+ actively being interacted with. A finished preloader or a closed fullscreen
103
+ menu sitting at `opacity:0` with pointer-events on is an invisible wall over
104
+ the whole page. Then hit-test the controls: click every button/link at its
105
+ visual position if something above it swallows the click, that's a §15
106
+ spatial-integrity fail, fix the layer not the button.
107
+ - Modals/drawers: focus trapped inside, Esc closes, focus returns to trigger,
108
+ `aria-modal` + labelled; scrim click closes (unless data-loss risk).
109
+ - Semantic HTML first: real `<button>`/`<a>`/`<nav>`/`<main>`/headings in
110
+ order divs-with-onClick fail half this section automatically.
111
+
112
+ ## 5. Scroll and layout stability
113
+
114
+ - Zero layout shift from async content: media boxes sized up front (media.md
115
+ §5), fonts `swap` with metric-compatible fallbacks, skeletons the same size
116
+ as what replaces them, no banners that push content after load.
117
+ - Scroll restoration: back/forward returns to the previous position (default
118
+ browser behavior — don't break it with manual scroll-to-top on every route;
119
+ scroll to top only on forward navigation to a NEW page).
120
+ - Fixed bars: content padded so nothing hides beneath them (DESIGN.md §15);
121
+ 100dvh not 100vh; no horizontal body scroll at 320px.
122
+ - Long pages get orientation aids: sticky nav or progress indication, and a
123
+ footer that actually ends the page (no infinite-feeling voids).
124
+
125
+ ## 6. Feedback and perceived performance
126
+
127
+ - Every async action acknowledges input within 100ms (pressed state, spinner,
128
+ optimistic change) silence after a click reads as broken even when it
129
+ works.
130
+ - Toasts only for transient global events; they stack in ONE corner slot
131
+ (DESIGN.md §15), auto-dismiss 4s, pause on hover, and are `aria-live`.
132
+ - Destructive/irreversible actions: confirm with specifics ("Delete 3 items?"),
133
+ never bare "Are you sure?"; prefer undo-toast over confirm-modal when safe.
134
+ - Copy per DESIGN.md §8's UX-writing rules: buttons say what they do, errors
135
+ say what to do next.
136
+
137
+ ## 7. The functional audit (run at verification time)
138
+
139
+ This is the checklist the runtime verification pass (SKILL.md) executes with
140
+ browser tools or walks mentally, file by file, when no browser exists:
141
+
142
+ 1. Click every nav link + the logo; confirm each lands where labeled.
143
+ 2. Open and close the mobile menu (both directions, plus Esc, plus navigate-
144
+ while-open) at 390px width.
145
+ 3. Submit each form empty → see inline errors; submit valid → see success
146
+ state; confirm no double-submit.
147
+ 4. Tab through the page start to finish; note any unreachable/invisible-focus/
148
+ trapped stop.
149
+ 5. Hit-test 5+ controls in effect-heavy regions (hero, canvas overlays,
150
+ floating elements) — every click must land.
151
+ 6. Trigger each data view's empty/error state if reachable (or verify the
152
+ branch exists in code).
153
+ 7. Console: zero uncaught errors during all of the above.
154
+
155
+ Report the result as a pass/fail list, fix fails, re-run the failed items once.