@ericrisco/rsc 3.1.4 → 3.3.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.
Files changed (96) hide show
  1. package/README.md +7 -6
  2. package/manifest.json +17 -68
  3. package/package.json +6 -1
  4. package/scripts/design-upstream.js +92 -0
  5. package/scripts/doctor.js +0 -24
  6. package/scripts/lib/default-skill-floor.js +5 -1
  7. package/scripts/lib/domains.js +2 -2
  8. package/scripts/lib/recommend.js +1 -3
  9. package/scripts/lib/retired-skills.js +7 -1
  10. package/skills/design/IMPECCABLE-LICENSE.txt +191 -0
  11. package/skills/design/SKILL.md +79 -328
  12. package/skills/design/THIRD_PARTY.md +26 -0
  13. package/skills/design/engine/LICENSE +21 -0
  14. package/skills/design/engine/RUN.md +515 -0
  15. package/skills/design/engine/UPSTREAM.json +4 -0
  16. package/skills/design/engine/assets/app.css +216 -0
  17. package/skills/design/engine/assets/base.css +105 -0
  18. package/skills/design/engine/assets/base.js +37 -0
  19. package/skills/design/engine/assets/charts.js +617 -0
  20. package/skills/design/engine/assets/scenes/stage.css +28 -0
  21. package/skills/design/engine/assets/scenes/stage.js +133 -0
  22. package/skills/design/engine/library/app.json +1327 -0
  23. package/skills/design/engine/library/directions.json +1078 -0
  24. package/skills/design/engine/library/heroes.json +1086 -0
  25. package/skills/design/engine/library/motions.json +92 -0
  26. package/skills/design/engine/library/palettes.json +1485 -0
  27. package/skills/design/engine/library/photos.json +7240 -0
  28. package/skills/design/engine/library/sections.json +4429 -0
  29. package/skills/design/engine/library/sites.json +8350 -0
  30. package/skills/design/engine/library/type.json +2024 -0
  31. package/skills/design/engine/references/app-screens.md +1199 -0
  32. package/skills/design/engine/references/colour.md +141 -0
  33. package/skills/design/engine/references/copy.md +177 -0
  34. package/skills/design/engine/references/critique.md +182 -0
  35. package/skills/design/engine/references/imagery.md +791 -0
  36. package/skills/design/engine/references/layout.md +292 -0
  37. package/skills/design/engine/references/motion.md +980 -0
  38. package/skills/design/engine/references/research.md +356 -0
  39. package/skills/design/engine/references/scenes.md +174 -0
  40. package/skills/design/engine/references/tells.md +115 -0
  41. package/skills/design/engine/references/type.md +170 -0
  42. package/skills/design/engine/scripts/assets.mjs +865 -0
  43. package/skills/design/engine/scripts/draw.mjs +584 -0
  44. package/skills/design/engine/scripts/inspect.mjs +303 -0
  45. package/skills/design/engine/scripts/lib/app-draw.mjs +203 -0
  46. package/skills/design/engine/scripts/lib/cdp.mjs +248 -0
  47. package/skills/design/engine/scripts/lib/probe.mjs +909 -0
  48. package/skills/design/engine/scripts/lib/rules.mjs +243 -0
  49. package/skills/design/engine/scripts/lint.mjs +119 -0
  50. package/skills/design/engine/scripts/scenes.mjs +124 -0
  51. package/skills/design/evals/cases.yaml +35 -46
  52. package/skills/design/references/design-md.md +49 -0
  53. package/skills/design/references/finish-review.md +46 -0
  54. package/skills/design/references/modes.md +51 -0
  55. package/skills/expo/SKILL.md +3 -4
  56. package/skills/marketing/references/landing-copy.md +2 -2
  57. package/skills/react/SKILL.md +2 -2
  58. package/skills/react-native/SKILL.md +3 -3
  59. package/skills/swift-ios/SKILL.md +1 -1
  60. package/skills/ui-engineering/SKILL.md +3 -4
  61. package/skills/ui-engineering/evals/cases.yaml +2 -2
  62. package/skills/variant-explorer/SKILL.md +4 -4
  63. package/skills/variant-explorer/evals/cases.yaml +1 -1
  64. package/targets/clone-bootstrap.mjs +1 -1
  65. package/scripts/lib/design-identity.js +0 -117
  66. package/scripts/lib/starting-point.js +0 -314
  67. package/skills/design/evals/README.md +0 -53
  68. package/skills/design/references/ai-tells.md +0 -75
  69. package/skills/design/references/brand-grounding.md +0 -197
  70. package/skills/design/references/copywriting-frameworks.md +0 -138
  71. package/skills/design/references/design-systems.md +0 -49
  72. package/skills/design/references/inspiration-sources.md +0 -96
  73. package/skills/design/references/landing-anatomy-and-cro.md +0 -202
  74. package/skills/design/references/motion-and-interaction.md +0 -232
  75. package/skills/design/references/research-method.md +0 -154
  76. package/skills/design/references/signature-and-craft.md +0 -148
  77. package/skills/design/references/starting-point.md +0 -75
  78. package/skills/design/references/trends-2026.md +0 -80
  79. package/skills/design/references/visual-system.md +0 -237
  80. package/skills/design/scripts/verify.sh +0 -357
  81. package/skills/design-dna/PROMPT.md +0 -211
  82. package/skills/design-dna/SKILL.md +0 -162
  83. package/skills/design-dna/design-dna.schema.json +0 -230
  84. package/skills/design-dna/evals/README.md +0 -64
  85. package/skills/design-dna/evals/cases.yaml +0 -68
  86. package/skills/design-dna/references/method.md +0 -436
  87. package/skills/design-dna/scripts/emit.py +0 -164
  88. package/skills/design-dna/templates/PROMPT.md.tmpl +0 -42
  89. package/skills/design-dna/templates/SKILL.md.tmpl +0 -42
  90. package/skills/design-dna/templates/check.py.tmpl +0 -143
  91. package/skills/design-loop/SKILL.md +0 -160
  92. package/skills/design-loop/evals/README.md +0 -56
  93. package/skills/design-loop/evals/cases.yaml +0 -60
  94. package/skills/motion-craft/SKILL.md +0 -125
  95. package/skills/motion-craft/evals/cases.yaml +0 -38
  96. package/skills/motion-craft/scripts/verify.sh +0 -75
@@ -1,56 +1,45 @@
1
1
  skill: design
2
2
 
3
3
  should_trigger:
4
- - prompt: "Design a landing page for our new analytics SaaS — hero, pricing, the works."
5
- why: "Explicit landing-page design with full marketing-page composition; this is the skill's core use case."
6
- - prompt: "Our homepage looks generic, like every other AI-generated startup site. Can you make it feel premium and intentional?"
7
- why: "Rescuing a 'feels generic / AI-slop' UI is named verbatim in the description and the When-to-use list."
8
- - prompt: "Pick a color palette and type pairing for my product, and give me the Tailwind tokens."
9
- why: "Choosing a visual system (color, type, tokens) is an explicit trigger; the skill ships Tailwind v4 @theme OKLCH tokens."
10
- - prompt: "Can you do a design review of this hero section and tell me how to make it convert better?"
11
- why: "Design review / critique plus conversion intent; the skill has a dedicated design-review QA checklist and a 0-10 visual-audit rubric."
12
- - prompt: "I've got the React components built and working, but it all just looks flat and amateur — help me polish the visuals and spacing."
13
- why: "A polish pass on an existing surface; user names the symptom (flat/amateur) without naming a tool, which the skill targets ('make an interface feel premium')."
14
- - prompt: "Write the hero headline and a punchy value prop for our developer-tool site, and lay out the page so it sells."
15
- why: "Conversion copy (hero/value-prop) plus page layout for selling — the skill owns visual + landing structure and co-owns copy; non-obvious because it leads with copy."
16
- - prompt: "Add a bento-grid features section to our marketing site that doesn't look like a template."
17
- why: "'bento section' is an explicit named trigger; involves layout/composition for a marketing surface."
4
+ - prompt: "Design a landing page for our new analytics SaaS."
5
+ why: "A public page to design from scratch is the page run's core case (Persuade mode)."
6
+ - prompt: "Our homepage looks generic, like every other AI-generated startup site. Make it look designed."
7
+ why: "'Looks generic / AI-made' is named in the description; the skill exists to replace the model's default."
8
+ - prompt: "Hazme la web de un restaurante de mi pueblo, que no parezca una plantilla."
9
+ why: "A local business page in Spanish; the inventory of the subject and real pictures are exactly what the run forces."
10
+ - prompt: "Rediseña el dashboard de facturación, que se ve feo y desordenado."
11
+ why: "An app screen redesign (Operate mode) follows the app-screen run with its own draw and inspector."
12
+ - prompt: "Review this portfolio page and tell me the three changes that would improve it most."
13
+ why: "A review of an existing page: record the before in the browser, critique the screenshots, stop at findings."
14
+ - prompt: "Restyle our docs site so it stops looking like every other docs template."
15
+ why: "Read mode: the style owns the frame while the reading column stays calm."
18
16
 
19
17
  should_not_trigger:
20
- - prompt: "Write the SEO keyword strategy and do a technical SEO audit for our marketing site, targeting buyer-intent terms."
21
- route_to: "marketing"
22
- why: "Deep keyword research, GEO, and technical SEO audits are explicitly delegated to the marketing sibling; design only enforces SEO-aware markup structure."
23
- - prompt: "Set up the Next.js 15 App Router routing, server actions, and data fetching for these pages."
18
+ - prompt: "Write the hero headline, offer and CTA copy for our pricing page."
19
+ route_to: "landing-copy"
20
+ why: "The words on a conversion page belong to landing-copy; design builds the page around them."
21
+ - prompt: "Where should the filter state live, in the URL or in the component, and how do we handle loading and errors?"
22
+ route_to: "ui-engineering"
23
+ why: "How interface is built (state, boundaries, async states) is ui-engineering, not visual design."
24
+ - prompt: "Make our web app pass WCAG 2.2 AA: fix the axe violations and keyboard traps."
25
+ route_to: "accessibility"
26
+ why: "Conformance remediation is the accessibility skill's job."
27
+ - prompt: "Create our logo brief and a full brand book with print colours."
28
+ route_to: "brand-identity"
29
+ why: "A brand system for every medium is brand-identity; design consumes it with --keep palette,type."
30
+ - prompt: "Set up Next.js App Router routing and server actions for these pages."
24
31
  route_to: "nextjs"
25
- why: "Pure App Router / React 19 build mechanics are the nextjs sibling's job; design hands off the build."
26
- - prompt: "Build a daily-use internal ops dashboard for our support team to triage tickets fast — pure data tables, no marketing."
27
- route_to: "none"
28
- why: "Dense internal operational tooling is explicitly a do-NOT-force-a-landing case; the skill says not to paint a marketing skin on a daily-use tool. Routes to product judgment, not a sibling."
29
- - prompt: "Mirror our brand colors and typography into the Flutter mobile app's theme."
30
- route_to: "flutter"
31
- why: "Translating brand tokens into a Flutter app is the flutter sibling's job, not web UI design."
32
- - prompt: "Implement an iOS 26 SwiftUI Liquid Glass material for this native settings panel."
33
- route_to: "none"
34
- why: "Native iOS Liquid Glass is the external liquid-glass-design reference; this skill ships only the web glass approximation, so it should decline/defer (no in-repo sibling)."
35
- - prompt: "Help me wire up the spring physics and AnimatePresence layout animations for this modal in Framer Motion."
36
- route_to: "none"
37
- why: "Deep motion-code mechanics (springs, AnimatePresence internals) are explicitly deferred to the external motion-ui references; design only sets motion intent + budget."
32
+ why: "Framework build mechanics are nextjs."
38
33
 
39
34
  capability:
40
- - scenario: "User asks: 'Design the hero section for our new SaaS landing page and make it look premium.' (No 02-DOCS/wiki/brand/ study exists in the repo yet.)"
35
+ - scenario: "Asked to build a landing page for a bakery with no brand and no photographs."
41
36
  must_include:
42
- - "STOPS before designing and checks for a brand study at 02-DOCS/wiki/brand/ (via root CLAUDE.md ## Brand & voice); on finding it missing/incomplete, asks a focused batch of brand-grounding questions instead of guessing."
43
- - "Runs (or states it will run) the research-first protocol: WebSearch award galleries / tier-1 sites and synthesize a cited DESIGN DIRECTION before prescribing, rather than shipping from memory."
44
- - "Enforces the 5-second value-prop test: hero states what it is, who it's for, why it's better, above the fold — and shows the product, not a centered headline over an atmospheric gradient."
45
- - "Uses design tokens (Tailwind v4 @theme, OKLCH color, modular type scale, 4/8px spacing, radius/shadow tokens) — no magic hex or arbitrary px."
46
- - "Treats accessibility as a hard constraint: text contrast >= 4.5:1, visible focus, one <h1>, semantic landmarks, touch targets >= 24px (44px ideal)."
47
- - "Treats Core Web Vitals as design constraints: LCP < 2.5s with next/image priority on the hero image, INP < 200ms, CLS < 0.1, next/font."
48
- - "Benefit-led, specific copy that avoids the ban-list (revolutionary, seamless, game-changer, unlock, supercharge, elevate, etc.)."
49
- - scenario: "User asks: 'Here's our current pricing page — do a design review and tell me how good it actually is.'"
37
+ - "inventory of eight to twelve things only this client has"
38
+ - "draw.mjs deals three directions; one is chosen against the inventory with a written reason"
39
+ - "an idea sentence that fails the competitor test, and one live thing"
40
+ - "at least four real pictures found with assets.mjs and credited"
41
+ - "inspect.mjs at 1440, 768 and 390 with zero FAIL before reporting"
42
+ - scenario: "The machine has no Chrome and Node 20."
50
43
  must_include:
51
- - "Applies the design-review QA checklist (value prop in 5s, contrast >= 4.5:1, visible focus, one <h1>, semantic landmarks, LCP image priority, next/font, no transition: all, tokens not magic numbers, ban-list-clean copy, 360px fit, empty/loading/error states)."
52
- - "Scores the 11-dimension visual-audit rubric 0-10 with weights and reports the weighted total on its /115 scale, mapped to a band (<69 generic / 69-91 competent / 92-108 premium / 109+ award-tier)."
53
- - "For each dimension scoring below 8, gives a concrete actionable fix (e.g. exact spacing/token change), not a vague 'improve spacing'."
54
- - "Checks copy against the ban-list and flags hype/vague value props that fail the 5s test."
55
- - "Flags any transition: all, magic hex/px, cards-in-cards, or purple->blue everything gradient as defects, not preferences."
56
- - "Ties findings back to the brand study / cited trend source where the bar is set, rather than asserting taste."
44
+ - "runs lint.mjs and critiques screenshots from another browser tool"
45
+ - "the report says 'inspector not run' with the reason and claims no gate pass"
@@ -0,0 +1,49 @@
1
+ # DESIGN.md: the record of the system
2
+
3
+ Adapted from impeccable's `document` by Paul Bakaus (Apache-2.0), which follows the open
4
+ `design.md` format. Rewritten and shortened.
5
+
6
+ The point: the next edit, the next session and the next tool keep the look instead of drifting back
7
+ to the model's default. Write it **after** the build, from what was actually built and measured,
8
+ never before. A rulebook written ahead of the build gets defended against reality.
9
+
10
+ ## Where and when
11
+
12
+ - `DESIGN.md` at the project root, committed with the code.
13
+ - Written when a surface creates or replaces the visual system. Extending an existing surface reads
14
+ it and does not rewrite it.
15
+ - If `02-DOCS/wiki/brand/` exists, `DESIGN.md` uses the brand's colours and faces and names that
16
+ file as its source.
17
+
18
+ ## Shape
19
+
20
+ YAML front matter holds the tokens; the body explains them.
21
+
22
+ ```markdown
23
+ ---
24
+ name: <product>
25
+ description: <one line: the idea sentence>
26
+ colors:
27
+ ground: "#…"
28
+ ink: "#…"
29
+ accent: "#…"
30
+ field: "#…"
31
+ typography:
32
+ display: { fontFamily: "…", fontWeight: 600, letterSpacing: "-0.03em", lineHeight: 0.95 }
33
+ text: { fontFamily: "…", fontSize: "18px", lineHeight: 1.5 }
34
+ rounded: { button: "0px", media: "0px" }
35
+ spacing: { margin: "24px", section: "200px" }
36
+ direction: { id: "<dealt id>", seed: <n> }
37
+ ---
38
+
39
+ ## Overview the idea, the mode, the direction and why it was chosen
40
+ ## Colors roles and proportions (one ground, one ink, one accent, fields)
41
+ ## Typography the scale actually used, tracking, measure
42
+ ## Layout grid, outer margins, section rhythm, the phone composition
43
+ ## Imagery sources, crops, treatment, where credits live
44
+ ## Motion the signature move and the entrance recipe
45
+ ## Components buttons, navigation, the live thing, footer
46
+ ## Do's and Don'ts the house rules this project relies on, plus any `--allow` and its reason
47
+ ```
48
+
49
+ Values come from the built CSS and the inspector's measurements, not from memory.
@@ -0,0 +1,46 @@
1
+ # The fresh review
2
+
3
+ Adapted from impeccable's finish reviewer by Paul Bakaus (Apache-2.0); rewritten and shortened.
4
+
5
+ The builder believes its own page. The review runs **outside** the build: a fresh subagent with no
6
+ history of this conversation, so it does not inherit the builder's framing or optimism. Without
7
+ subagents, step fully out of the build and run the same checks yourself, and say in the report that
8
+ the review was not independent.
9
+
10
+ ## The packet
11
+
12
+ Hand it only this:
13
+
14
+ - the original request and the user's answers;
15
+ - the screenshots from `.taste-skill/inspect/` at every width (the reviewer has no browser);
16
+ - the last `inspect.mjs` result;
17
+ - the direction sheet (`draw.mjs --show`), the idea sentence and the live thing;
18
+ - the paths of `../engine/RUN.md` (house rules) and `../engine/references/critique.md`.
19
+
20
+ ## The checks, in order
21
+
22
+ 0. **Evidence.** Every width captured, no blank or half-loaded screenshot, content where the
23
+ filename says. If one fails, the answer is `recapture` and nothing else.
24
+ 1. **First screen.** Within five seconds: what is this, why does it matter, what do I do?
25
+ 2. **The idea.** Is the idea sentence visible on the page, in every section, and does it fail the
26
+ competitor test (would it work for the nearest competitor)?
27
+ 3. **The direction.** Was the dealt direction built, or did the build drift back to the layout the
28
+ model would have made anyway?
29
+ 4. **Substance.** Real pictures, full content, no screen that is mostly empty ground.
30
+ 5. **Truth.** No invented customers, quotes, numbers or logos. Sample content marked.
31
+ 6. **Floor.** The house rules in `../engine/RUN.md`, plus what screenshots show and code hides:
32
+ states (hover, focus, loading, empty, error), themed selection and focus rings, text that fits.
33
+
34
+ ## The four words
35
+
36
+ The first line of the answer is exactly one of these. The word follows from the checks:
37
+
38
+ - `recapture`: the evidence failed, not the page. Capture again, then a full review.
39
+ - `rebuild`: the focal element or the direction itself is wrong. Re-derive it; patches will not do.
40
+ - `fix`: an ordered list of material fixes, at most eight, most important first.
41
+ - `ship`: nothing material remains.
42
+
43
+ Then: `fixes` (when `fix`) and `keep`, one line naming what must not be diluted while fixing.
44
+ Apply the fixes in one batch, run the gate again, and send the new screenshots back for a verdict
45
+ on each fix: resolved, partial or unresolved. Two rounds at most. A partial or unresolved fix
46
+ never becomes `ship`. Report the reviewer's word as it was given.
@@ -0,0 +1,51 @@
1
+ # The four modes
2
+
3
+ Adapted from impeccable by Paul Bakaus (Apache-2.0); rewritten and shortened. The mode names what
4
+ the visitor's success looks like on this surface. Pick it from the surface, never the product: a
5
+ developer tool's landing page is Persuade, a fashion house's docs are Read.
6
+
7
+ ## Persuade
8
+
9
+ The visitor decides and acts. The design is what they judge.
10
+
11
+ - The first screen makes the offer clear and shows **the action visitors came to take, working**: a
12
+ flight search, open appointment slots, add to cart. A button that points somewhere else is not it.
13
+ - The subject's world carries the page; it is never painted over it as a poster with no working parts.
14
+ - Refuse both ends: the poster, and the stock product page (headline, subline, button, a row of
15
+ equal cards; or the split hero with a badge row under it).
16
+
17
+ ## Experience
18
+
19
+ The visitor is inside the work: portfolio, gallery, showcase. The work leads from the first
20
+ viewport and the interface recedes. Same page run as Persuade.
21
+
22
+ ## Operate
23
+
24
+ The visitor completes a task. Someone who uses tools like this should know where everything is
25
+ before they notice the style.
26
+
27
+ - The direction lends four things only: **type, palette, density and one signature move** (service
28
+ health drawn as a transit map, a schedule in a timetable's column rhythm). Never the layout, the
29
+ navigation model or the controls.
30
+ - Every control is the standard one the visitor already knows. No costume of a terminal, an
31
+ instrument bezel or ledger paper.
32
+ - Colour does real jobs: a committed shell, state colours, data series, selection. A grey screen
33
+ with one accent is the category default without its polish.
34
+ - Realistic data with units and one state worth seeing (an alert, a degraded service, an empty
35
+ filter). Never grey placeholder bars.
36
+ - The bar is the cleanest product in its category; the signature move adds to that, never replaces it.
37
+
38
+ The run, rules and checks for these screens: `../engine/references/app-screens.md`
39
+ (`draw.mjs --app`, `inspect.mjs --app`).
40
+
41
+ ## Read
42
+
43
+ The visitor understands something: docs, guide, article, changelog.
44
+
45
+ - The style owns **the frame**: masthead, rail, ground, title and section openers, how code and
46
+ tables are set. That is where palette, type and the signature move commit fully.
47
+ - The reading column stays calm: a reading face, real contrast, about 60–75 characters at about
48
+ 16px. No monospace prose. Nothing performs behind the text.
49
+ - The style never supplies the reading order or replaces the navigation with something to learn.
50
+ - Check: can a reader tell where they are, where to go next, and read comfortably? Cover the name:
51
+ could this be any other product's docs? Then the frame has not taken the style yet.
@@ -8,10 +8,9 @@ origin: risco
8
8
 
9
9
  # Expo & EAS: shipping React Native
10
10
 
11
- **Hand-off — the app vs its motion.** This skill owns the Expo platform: router, config plugins, EAS,
12
- native modules, store builds. **Animation and gestures** — Reanimated worklets, the UI runtime,
13
- sheets, screen transitions, press feedback, haptics, motion that stutters on a real device — are
14
- `../motion-craft/SKILL.md`'s.
11
+ **Scope.** This skill owns the Expo platform: router, config plugins, EAS, native modules, store
12
+ builds. Animation and gestures (Reanimated worklets, sheets, press feedback, haptics) follow
13
+ `../react-native/SKILL.md`. Visual design of web pages and screens is `../design/SKILL.md`'s.
15
14
 
16
15
 
17
16
  ## What this skill owns
@@ -1,6 +1,6 @@
1
1
  # Landing Copy by Section
2
2
 
3
- The words for every landing section, mapped 1:1 to the `design` skill's section anatomy (`../../design/references/landing-anatomy-and-cro.md`). `design` owns the visual treatment and layout; this file owns the copy that goes inside each section. Each section has **one copy job**; cut any section whose job you can't name. Ground every line in the brand study (`brand-grounding.md`) and run the value prop through the canvas (`copy-frameworks.md`) first.
3
+ The words for every landing section. `../../design/SKILL.md` owns the visual treatment, the layout and which sections exist (its argument step: one claim per section); this file owns the copy that goes inside each section. Each section has **one copy job**; cut any section whose job you can't name. Ground every line in the brand study (`brand-grounding.md`) and run the value prop through the canvas (`copy-frameworks.md`) first.
4
4
 
5
5
  ## Section map (copy job + framework)
6
6
 
@@ -187,5 +187,5 @@ Good — "Stop babysitting staging. Start free — no credit card."
187
187
 
188
188
  - `copy-frameworks.md` — the frameworks and headline formulas each section uses.
189
189
  - `brand-grounding.md` — the value prop, proof, and voice every line is grounded in.
190
- - `../../design/references/landing-anatomy-and-cro.md` — the visual anatomy these words fill.
190
+ - `../../design/SKILL.md` — the page these words fill; write the copy deck before its markup.
191
191
  - `campaigns-and-channels.md` — driving traffic to this page.
@@ -10,8 +10,8 @@ origin: risco
10
10
 
11
11
  **Hand-off — picking dependencies.** Which library to reach for (UI primitives, command menus,
12
12
  toasts, OTP inputs, charts, virtualization, drag and drop, state, styling, theming) is
13
- `../ui-engineering/SKILL.md`'s — build vs adopt is decided there, before hand-rolling a component. Animating what you
14
- install is `../motion-craft/SKILL.md`'s.
13
+ `../ui-engineering/SKILL.md`'s — build vs adopt is decided there, before hand-rolling a component. The look of a page
14
+ or screen, and its motion layer, is `../design/SKILL.md`'s.
15
15
 
16
16
 
17
17
  > Build or review a fast, typed, correctly-architected **client-side** React single-page app bundled by Vite. No server runtime, no RSC tree, no framework router. Server-rendered React (App Router, server actions, SSR/SSG) is not this skill — that is `../nextjs/SKILL.md`.
@@ -8,9 +8,9 @@ origin: risco
8
8
 
9
9
  # React Native (app code)
10
10
 
11
- **Hand-off — the app vs its motion.** Animation and gestures in a React Native app — Reanimated
12
- worklets on the UI runtime, gesture handoff, sheets, press feedback, haptics — are
13
- `../motion-craft/SKILL.md`'s, whose guidance is platform-agnostic and applies to bare React Native as well as Expo.
11
+ **Scope.** App code, including animation and gestures (Reanimated worklets on the UI runtime, gesture
12
+ handoff, sheets, press feedback, haptics), in bare React Native and in Expo. Visual design of web
13
+ pages and screens is `../design/SKILL.md`'s.
14
14
 
15
15
 
16
16
  You write the code that runs *inside* the app: render, navigate, animate, list, persist, and author native modules. Mobile is split across two skills by **verb** — run the verb test before doing anything:
@@ -13,7 +13,7 @@ origin: risco
13
13
  app lifecycle, Xcode, iOS APIs, App Store shipping. Language-level Swift — Swift 6 data-race safety
14
14
  and approachable concurrency, actors and task groups, `some` vs `any`, ARC and performance, Swift
15
15
  Testing, macros — is this skill's own ground. A concurrency error, a hang, a data race or a
16
- retain cycle belongs here. Interface feel, springs and materials: `../motion-craft/SKILL.md`.
16
+ retain cycle belongs here, and so do interface feel, springs and materials on iOS.
17
17
 
18
18
 
19
19
  Native Apple-platform apps: the code is `.swift`, the UI is SwiftUI, and the compiler enforces actor isolation. If the answer is a `@MainActor`, `@Observable`, `async let`, `#expect`, `NavigationStack`, or `@Model`, you are in the right place.
@@ -2,7 +2,7 @@
2
2
  name: ui-engineering
3
3
  description: "Use when the question is how interface should be BUILT — component boundaries, state that belongs in the URL vs the component, loading/empty/error states, forms, optimistic updates, build vs adopt. NOT the visual system (`design`), NOT framework mechanics (`react`/`nextjs`)."
4
4
  tags: [interface, frontend, architecture, components, state, craft]
5
- recommends: [design, motion-craft]
5
+ recommends: [design]
6
6
  profiles: [core, full]
7
7
  origin: risco
8
8
  ---
@@ -108,7 +108,6 @@ The split is not about difficulty, it is about **who is the authority on the beh
108
108
 
109
109
  ## See Also
110
110
 
111
- - `../design/SKILL.md` — the visual system these decisions serve.
112
- - `../motion-craft/SKILL.md` — how the pieces here move once they exist.
113
- - `../design-loop/SKILL.md` — the graded critique that judges the result.
111
+ - `../design/SKILL.md` — the visual system these decisions serve, its motion layer, and the
112
+ browser-measured critique that judges the result.
114
113
  - `../accessibility/SKILL.md` — the ground under focus, semantics and forms.
@@ -22,10 +22,10 @@ should_not_trigger:
22
22
  route_to: "react"
23
23
  why: "Framework mechanics. This skill decides what to build, not how the framework behaves."
24
24
  - prompt: "The dropdown animation feels cheap, what duration should it use?"
25
- route_to: "motion-craft"
25
+ route_to: "design"
26
26
  why: "Once the component exists, how it moves is motion craft."
27
27
  - prompt: "Grade this dashboard and tell me if it is actually good."
28
- route_to: "design-loop"
28
+ route_to: "design"
29
29
  why: "Judging a finished screen is the critique loop, not the build decisions."
30
30
  - prompt: "Set up the Next.js App Router with server actions for this project."
31
31
  route_to: "nextjs"
@@ -1,8 +1,8 @@
1
1
  ---
2
2
  name: variant-explorer
3
- description: "Use when someone wants OPTIONS rather than an answer — 'show me a few versions', picking between approaches by seeing them. Genuinely different candidates, cheap to throw away, trade-off named. NOT the critique that judges one (`design-loop`), NOT the spec (`specify`)."
3
+ description: "Use when someone wants OPTIONS rather than an answer — 'show me a few versions', picking between approaches by seeing them. Genuinely different candidates, cheap to throw away, trade-off named. NOT the critique that judges one (`design`), NOT the spec (`specify`)."
4
4
  tags: [prototyping, divergence, options, exploration, decision]
5
- recommends: [design-loop]
5
+ recommends: [design]
6
6
  profiles: [full]
7
7
  origin: risco
8
8
  ---
@@ -84,10 +84,10 @@ handing the work back. Say which one you would pick and why, and make it easy to
84
84
  | Present five or six to be thorough | Past three, they stop being compared and start being skimmed. |
85
85
  | Give options with no recommendation | Standing back is not neutrality; it hands the work back to the person who asked. |
86
86
  | Explore a decision that is cheap to reverse | Just ship one. Divergence is for what is expensive to unwind. |
87
- | Keep iterating on the winner here | Once one is chosen, refining it is `../design-loop/SKILL.md` or the relevant build skill. |
87
+ | Keep iterating on the winner here | Once one is chosen, refining it is `../design/SKILL.md` or the relevant build skill. |
88
88
 
89
89
  ## See Also
90
90
 
91
- - `../design-loop/SKILL.md` — the graded critique that takes over once a direction is chosen.
91
+ - `../design/SKILL.md` — the graded critique that takes over once a direction is chosen.
92
92
  - `../specify/SKILL.md` — when what is missing is an agreed WHAT/WHY, not options.
93
93
  - `../design/SKILL.md` — building the chosen direction properly.
@@ -16,7 +16,7 @@ should_trigger:
16
16
 
17
17
  should_not_trigger:
18
18
  - prompt: "Review this checkout screen and grade it."
19
- route_to: "design-loop"
19
+ route_to: "design"
20
20
  why: "Judging one finished thing is critique, the opposite of divergence."
21
21
  - prompt: "We need to agree what this feature is for before anyone builds it."
22
22
  route_to: "specify"
@@ -95,7 +95,7 @@ export function readManifest(root) {
95
95
  const ids = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === 'string' && ID.test(x)) : []);
96
96
  // Retired skills read as their successors. Canonical map: scripts/lib/retired-skills.js — inlined
97
97
  // because this file cannot import anything, and tests/retired-skills.test.js holds the two equal.
98
- const RETIRED = { eli5: 'orient', 'show-me': 'orient', bro: 'unslop' };
98
+ const RETIRED = { eli5: 'orient', 'show-me': 'orient', bro: 'unslop', 'design-loop': 'design', 'design-dna': 'design', 'motion-craft': 'design' };
99
99
  const skills = [...new Set(ids(parsed.skills).map((id) => (Object.hasOwn(RETIRED, id) ? RETIRED[id] : id)))];
100
100
  const own = ids(parsed.ownSkills);
101
101
  // A manifest with nothing declared is not a clone waiting to be equipped; there is nothing to offer.
@@ -1,117 +0,0 @@
1
- // Does this harness have a design identity, and can we tell?
2
- //
3
- // `design` has declared for a long time that without a brand study it STOPS and does not design.
4
- // Nothing checked it: `grep -rln "wiki/brand" scripts/` returned nothing before this file existed.
5
- // That is P2 — a rule declared binding with no mechanism is a decorative gate. Spec:
6
- // 02-DOCS/wiki/sdd/specs/design-area-cleanup.md
7
- //
8
- // Three states, and the third is the whole point. A checker that cannot look must never report
9
- // green: that exact defect was found and fixed in the design-dna style checker two days earlier,
10
- // where regex probes ran against empty text and returned vacuous passes. Absence of evidence is
11
- // reported as absence of evidence.
12
- //
13
- // Read-only. It never writes: 02-DOCS is untracked (P9) and there is no undo there.
14
- import { existsSync, lstatSync, readFileSync, readdirSync, statSync } from 'node:fs';
15
- import { join } from 'node:path';
16
-
17
- // Where the harness keeps durable design knowledge, and the section in the root instructions file
18
- // that points at it. Both are the `design`/`harness` convention, not invented here.
19
- export const BRAND_DIR = join('02-DOCS', 'wiki', 'brand');
20
- export const BRAND_SECTION = '## Brand & voice';
21
-
22
- /**
23
- * @returns {{state: 'present'|'missing'|'inconclusive', linked: boolean, articles: string[],
24
- * reason: string, fix?: string}}
25
- * `present` — articles exist under the brand dir. `linked` says whether the root
26
- * instructions file points at them, which is how other skills find it.
27
- * `missing` — looked, found nothing. Carries the fix (P6: a denial carries its way out).
28
- * `inconclusive` — could not look. Never conflated with `missing`, and never with green.
29
- */
30
- export function designIdentity(root = process.cwd()) {
31
- const dir = join(root, BRAND_DIR);
32
-
33
- let articles;
34
- try {
35
- if (!existsSync(dir)) {
36
- // existsSync FOLLOWS symlinks, so a dangling one reports false and would be filed as "no
37
- // identity here". It is not absence, it is unreadability — the same conflation this whole
38
- // area was cleaning up. lstat sees the link itself and tells the two apart.
39
- let danglingLink = false;
40
- try { danglingLink = lstatSync(dir).isSymbolicLink(); } catch { /* genuinely absent */ }
41
- if (danglingLink) {
42
- return {
43
- state: 'inconclusive',
44
- linked: false,
45
- articles: [],
46
- reason: `${BRAND_DIR} is a symlink that does not resolve`,
47
- };
48
- }
49
- return {
50
- state: 'missing',
51
- linked: false,
52
- articles: [],
53
- reason: `no ${BRAND_DIR}/ in this harness`,
54
- fix: 'run `design-loop` to converge on a winner, then `design-dna` to write its record here',
55
- };
56
- }
57
- // Not statSync: it follows symlinks, so a symlink here could report on a directory outside the
58
- // declared zone. Same reason drift-check.js:167 uses dirents.
59
- if (!statSync(dir).isDirectory()) {
60
- return {
61
- state: 'inconclusive',
62
- linked: false,
63
- articles: [],
64
- reason: `${BRAND_DIR} exists but is not a directory`,
65
- };
66
- }
67
- articles = readdirSync(dir).filter((f) => f.endsWith('.md') && f !== 'index.md');
68
- } catch (e) {
69
- // Unreadable for any reason (permissions, dangling symlink, ELOOP). We did not look, so we
70
- // cannot say. Reporting `missing` here would invent a finding; reporting green would hide one.
71
- return {
72
- state: 'inconclusive',
73
- linked: false,
74
- articles: [],
75
- reason: `cannot read ${BRAND_DIR}: ${e.code || e.message}`,
76
- };
77
- }
78
-
79
- // The link matters on its own: five skills reach the identity through the root instructions file,
80
- // so an unlinked identity is one they will not find.
81
- let linked = false;
82
- const claudeMd = join(root, 'CLAUDE.md');
83
- if (existsSync(claudeMd)) {
84
- try {
85
- linked = readFileSync(claudeMd, 'utf8').includes(BRAND_SECTION);
86
- } catch {
87
- // The articles are what we were asked about and we did read them. A CLAUDE.md we could not
88
- // read makes `linked` unknown, not the whole answer unknown — report it in the reason.
89
- return {
90
- state: articles.length ? 'present' : 'missing',
91
- linked: false,
92
- articles,
93
- reason: `${articles.length} article(s), but CLAUDE.md could not be read to confirm the link`,
94
- };
95
- }
96
- }
97
-
98
- if (!articles.length) {
99
- return {
100
- state: 'missing',
101
- linked,
102
- articles: [],
103
- reason: `${BRAND_DIR}/ exists but holds no identity article`,
104
- fix: 'run `design-loop` to converge on a winner, then `design-dna` to write its record here',
105
- };
106
- }
107
-
108
- return {
109
- state: 'present',
110
- linked,
111
- articles,
112
- reason: linked
113
- ? `${articles.length} article(s), linked from CLAUDE.md`
114
- : `${articles.length} article(s), but no "${BRAND_SECTION}" section in CLAUDE.md points at them`,
115
- ...(linked ? {} : { fix: `add a "${BRAND_SECTION}" section to CLAUDE.md linking ${BRAND_DIR}/` }),
116
- };
117
- }