@ericrisco/rsc 3.1.4 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -7
- package/manifest.json +17 -68
- package/package.json +6 -1
- package/scripts/design-upstream.js +92 -0
- package/scripts/doctor.js +0 -24
- package/scripts/lib/default-skill-floor.js +5 -1
- package/scripts/lib/domains.js +2 -2
- package/scripts/lib/recommend.js +1 -3
- package/scripts/lib/retired-skills.js +7 -1
- package/skills/design/IMPECCABLE-LICENSE.txt +191 -0
- package/skills/design/SKILL.md +79 -328
- package/skills/design/THIRD_PARTY.md +26 -0
- package/skills/design/engine/LICENSE +21 -0
- package/skills/design/engine/RUN.md +515 -0
- package/skills/design/engine/UPSTREAM.json +4 -0
- package/skills/design/engine/assets/app.css +216 -0
- package/skills/design/engine/assets/base.css +105 -0
- package/skills/design/engine/assets/base.js +37 -0
- package/skills/design/engine/assets/charts.js +617 -0
- package/skills/design/engine/assets/scenes/stage.css +28 -0
- package/skills/design/engine/assets/scenes/stage.js +133 -0
- package/skills/design/engine/library/app.json +1327 -0
- package/skills/design/engine/library/directions.json +1078 -0
- package/skills/design/engine/library/heroes.json +1086 -0
- package/skills/design/engine/library/motions.json +92 -0
- package/skills/design/engine/library/palettes.json +1485 -0
- package/skills/design/engine/library/photos.json +7240 -0
- package/skills/design/engine/library/sections.json +4429 -0
- package/skills/design/engine/library/sites.json +8350 -0
- package/skills/design/engine/library/type.json +2024 -0
- package/skills/design/engine/references/app-screens.md +1199 -0
- package/skills/design/engine/references/colour.md +141 -0
- package/skills/design/engine/references/copy.md +177 -0
- package/skills/design/engine/references/critique.md +182 -0
- package/skills/design/engine/references/imagery.md +791 -0
- package/skills/design/engine/references/layout.md +292 -0
- package/skills/design/engine/references/motion.md +980 -0
- package/skills/design/engine/references/research.md +356 -0
- package/skills/design/engine/references/scenes.md +174 -0
- package/skills/design/engine/references/tells.md +115 -0
- package/skills/design/engine/references/type.md +170 -0
- package/skills/design/engine/scripts/assets.mjs +865 -0
- package/skills/design/engine/scripts/draw.mjs +584 -0
- package/skills/design/engine/scripts/inspect.mjs +303 -0
- package/skills/design/engine/scripts/lib/app-draw.mjs +203 -0
- package/skills/design/engine/scripts/lib/cdp.mjs +248 -0
- package/skills/design/engine/scripts/lib/probe.mjs +909 -0
- package/skills/design/engine/scripts/lib/rules.mjs +243 -0
- package/skills/design/engine/scripts/lint.mjs +119 -0
- package/skills/design/engine/scripts/scenes.mjs +124 -0
- package/skills/design/evals/cases.yaml +35 -46
- package/skills/design/references/design-md.md +49 -0
- package/skills/design/references/finish-review.md +46 -0
- package/skills/design/references/modes.md +51 -0
- package/skills/expo/SKILL.md +3 -4
- package/skills/marketing/references/landing-copy.md +2 -2
- package/skills/react/SKILL.md +2 -2
- package/skills/react-native/SKILL.md +3 -3
- package/skills/suggest/SKILL.md +12 -8
- package/skills/suggest/evals/cases.yaml +6 -0
- package/skills/swift-ios/SKILL.md +1 -1
- package/skills/ui-engineering/SKILL.md +3 -4
- package/skills/ui-engineering/evals/cases.yaml +2 -2
- package/skills/variant-explorer/SKILL.md +4 -4
- package/skills/variant-explorer/evals/cases.yaml +1 -1
- package/targets/clone-bootstrap.mjs +1 -1
- package/scripts/lib/design-identity.js +0 -117
- package/scripts/lib/starting-point.js +0 -314
- package/skills/design/evals/README.md +0 -53
- package/skills/design/references/ai-tells.md +0 -75
- package/skills/design/references/brand-grounding.md +0 -197
- package/skills/design/references/copywriting-frameworks.md +0 -138
- package/skills/design/references/design-systems.md +0 -49
- package/skills/design/references/inspiration-sources.md +0 -96
- package/skills/design/references/landing-anatomy-and-cro.md +0 -202
- package/skills/design/references/motion-and-interaction.md +0 -232
- package/skills/design/references/research-method.md +0 -154
- package/skills/design/references/signature-and-craft.md +0 -148
- package/skills/design/references/starting-point.md +0 -75
- package/skills/design/references/trends-2026.md +0 -80
- package/skills/design/references/visual-system.md +0 -237
- package/skills/design/scripts/verify.sh +0 -357
- package/skills/design-dna/PROMPT.md +0 -211
- package/skills/design-dna/SKILL.md +0 -162
- package/skills/design-dna/design-dna.schema.json +0 -230
- package/skills/design-dna/evals/README.md +0 -64
- package/skills/design-dna/evals/cases.yaml +0 -68
- package/skills/design-dna/references/method.md +0 -436
- package/skills/design-dna/scripts/emit.py +0 -164
- package/skills/design-dna/templates/PROMPT.md.tmpl +0 -42
- package/skills/design-dna/templates/SKILL.md.tmpl +0 -42
- package/skills/design-dna/templates/check.py.tmpl +0 -143
- package/skills/design-loop/SKILL.md +0 -160
- package/skills/design-loop/evals/README.md +0 -56
- package/skills/design-loop/evals/cases.yaml +0 -60
- package/skills/motion-craft/SKILL.md +0 -125
- package/skills/motion-craft/evals/cases.yaml +0 -38
- package/skills/motion-craft/scripts/verify.sh +0 -75
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: __SLUG__
|
|
3
|
-
description: "Use when building anything in the __NAME__ style: __ONE_LINE__ Fires on '__SLUG__', 'in the __NAME__ style', 'another one like <reference>', 'same look as before'. Captured from __MEDIUM__; drives any format. NOT inventing a new direction (that is `design`), NOT re-deriving this style (its record already exists in dna.json)."
|
|
4
|
-
tags: [style, design-dna, __SLUG__]
|
|
5
|
-
recommends: [design-dna, nextjs, marketing]
|
|
6
|
-
origin: design-dna
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# __NAME__
|
|
10
|
-
|
|
11
|
-
*__ONE_LINE__*
|
|
12
|
-
|
|
13
|
-
Captured __CAPTURED__ from __MEDIUM__. Reference kept in `reference/`. Worked proof in `example/`.
|
|
14
|
-
|
|
15
|
-
## How to use this
|
|
16
|
-
|
|
17
|
-
1. Load **`PROMPT.md` only**, and attach `reference/__REF__`. Never paste `dna.json` into a prompt: it is the record, not the payload, and its size is exactly what breaks compliance.
|
|
18
|
-
2. Pick an archetype by name before writing a line. Structure first, or piece 8 will not sit beside piece 1 as a set.
|
|
19
|
-
3. Build. Web build goes to `../nextjs/SKILL.md`, words to `../marketing/SKILL.md`; the identity stays here.
|
|
20
|
-
4. Run the self-check. Name every test and its result:
|
|
21
|
-
|
|
22
|
-
python3 scripts/check.py <output files or a rendered PNG>
|
|
23
|
-
|
|
24
|
-
Non-zero exit means do not ship. Answer the MANUAL tests out loud.
|
|
25
|
-
|
|
26
|
-
## What this style is, in one screen
|
|
27
|
-
|
|
28
|
-
__SUMMARY__
|
|
29
|
-
|
|
30
|
-
## Do not
|
|
31
|
-
|
|
32
|
-
__BANS__
|
|
33
|
-
|
|
34
|
-
## Known drift risks
|
|
35
|
-
|
|
36
|
-
__CONFIDENCE__
|
|
37
|
-
|
|
38
|
-
These are the values that were inferred rather than measured. If output starts feeling off, re-measure these first.
|
|
39
|
-
|
|
40
|
-
## Maintenance
|
|
41
|
-
|
|
42
|
-
Re-capture only when the reference itself changes. To extend the style, edit `dna.json`, then recompile `PROMPT.md` under the 2KB cap: adding a signature means deleting one. Method and rationale: `../design-dna/SKILL.md`.
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""Auto tests for the __NAME__ style. Exits non-zero on any failure.
|
|
3
|
-
|
|
4
|
-
python3 scripts/check.py <output.html|output.css|output.png> [more files...]
|
|
5
|
-
|
|
6
|
-
Reads dna.json and runs every test marked "auto": true that carries a "probe".
|
|
7
|
-
Tests without a probe are reported as MANUAL and never silently pass.
|
|
8
|
-
A probe handed no artefact it can read is reported as SKIP with its reason -
|
|
9
|
-
never as PASS or FAIL.
|
|
10
|
-
|
|
11
|
-
Probe kinds
|
|
12
|
-
-----------
|
|
13
|
-
regex_absent {"kind":"regex_absent","pattern":"..."} fails if the pattern appears
|
|
14
|
-
regex_count {"kind":"regex_count","pattern":"...","exactly":1} or "min"/"max"
|
|
15
|
-
distinct_css {"kind":"distinct_css","property":"font-size","max":3} distinct declared values
|
|
16
|
-
css_ratio {"kind":"css_ratio","property":"font-size","min":6.0} largest / smallest declared
|
|
17
|
-
min_unit {"kind":"min_unit","property":"font-size","min_px":28} smallest declared value
|
|
18
|
-
color_coverage {"kind":"color_coverage","hex":"#ff4d00","max_pct":8,
|
|
19
|
-
"tolerance":24} needs an image file + Pillow
|
|
20
|
-
"""
|
|
21
|
-
import json, os, re, sys
|
|
22
|
-
|
|
23
|
-
HERE = os.path.dirname(os.path.abspath(__file__))
|
|
24
|
-
DNA_PATH = os.path.join(HERE, "..", "dna.json")
|
|
25
|
-
if not os.path.isfile(DNA_PATH):
|
|
26
|
-
sys.exit("no dna.json beside this script, so there is nothing to check against.\n"
|
|
27
|
-
"This style skill was scaffolded and never finished. Fix:\n"
|
|
28
|
-
" write dna.json, then validate it with\n"
|
|
29
|
-
" python3 ../design-dna/scripts/emit.py <slug> --validate")
|
|
30
|
-
DNA = json.load(open(DNA_PATH))
|
|
31
|
-
|
|
32
|
-
TEXT_EXT = {".html", ".htm", ".css", ".scss", ".jsx", ".tsx", ".svg", ".md", ".js", ".ts"}
|
|
33
|
-
IMG_EXT = {".png", ".jpg", ".jpeg", ".webp"}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def load(paths):
|
|
37
|
-
text, images = "", []
|
|
38
|
-
for p in paths:
|
|
39
|
-
ext = os.path.splitext(p)[1].lower()
|
|
40
|
-
if ext in IMG_EXT:
|
|
41
|
-
images.append(p)
|
|
42
|
-
elif ext in TEXT_EXT or os.path.isfile(p):
|
|
43
|
-
text += "\n" + open(p, encoding="utf-8", errors="replace").read()
|
|
44
|
-
return text, images
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
def css_values(text, prop):
|
|
48
|
-
out = []
|
|
49
|
-
for raw in re.findall(rf"{re.escape(prop)}\s*:\s*([^;}}\"']+)", text, re.I):
|
|
50
|
-
m = re.match(r"\s*(-?[\d.]+)\s*(px|rem|em|pt|%)?", raw)
|
|
51
|
-
if not m:
|
|
52
|
-
continue
|
|
53
|
-
n = float(m.group(1))
|
|
54
|
-
unit = (m.group(2) or "px").lower()
|
|
55
|
-
out.append(n * 16 if unit in ("rem", "em") else n)
|
|
56
|
-
return out
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def coverage(path, hex_target, tol):
|
|
60
|
-
try:
|
|
61
|
-
from PIL import Image
|
|
62
|
-
except ImportError:
|
|
63
|
-
return None, "Pillow not installed (pip install pillow)"
|
|
64
|
-
tr, tg, tb = (int(hex_target.lstrip("#")[i:i + 2], 16) for i in (0, 2, 4))
|
|
65
|
-
im = Image.open(path).convert("RGB")
|
|
66
|
-
im.thumbnail((400, 400))
|
|
67
|
-
px = list(im.get_flattened_data()) if hasattr(im, "get_flattened_data") else list(im.getdata())
|
|
68
|
-
hit = sum(1 for r, g, b in px if abs(r - tr) <= tol and abs(g - tg) <= tol and abs(b - tb) <= tol)
|
|
69
|
-
return 100.0 * hit / max(1, len(px)), None
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# Probes that read declared values. Handed no text they must SKIP: a regex over an empty
|
|
73
|
-
# string is not a check, and calling it PASS or FAIL is the gate lying in one direction
|
|
74
|
-
# or the other.
|
|
75
|
-
TEXT_PROBES = ("regex_absent", "regex_count", "distinct_css", "css_ratio", "min_unit")
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def run(test, text, images):
|
|
79
|
-
pr = test.get("probe")
|
|
80
|
-
if not pr:
|
|
81
|
-
return "MANUAL", "no probe declared"
|
|
82
|
-
k = pr.get("kind")
|
|
83
|
-
if k in TEXT_PROBES and not text.strip():
|
|
84
|
-
return "SKIP", "no text artefact passed; this probe reads declarations, not pixels"
|
|
85
|
-
if k == "regex_absent":
|
|
86
|
-
hits = re.findall(pr["pattern"], text, re.I)
|
|
87
|
-
return ("FAIL" if hits else "PASS"), f"{len(hits)} match(es)"
|
|
88
|
-
if k == "regex_count":
|
|
89
|
-
n = len(re.findall(pr["pattern"], text, re.I))
|
|
90
|
-
ok = (n == pr["exactly"]) if "exactly" in pr else (pr.get("min", 0) <= n <= pr.get("max", 10 ** 9))
|
|
91
|
-
return ("PASS" if ok else "FAIL"), f"found {n}"
|
|
92
|
-
if k == "distinct_css":
|
|
93
|
-
vals = sorted(set(css_values(text, pr["property"])))
|
|
94
|
-
return ("PASS" if len(vals) <= pr["max"] else "FAIL"), f"{len(vals)} distinct: {vals}"
|
|
95
|
-
if k == "css_ratio":
|
|
96
|
-
vals = [v for v in css_values(text, pr["property"]) if v > 0]
|
|
97
|
-
if not vals:
|
|
98
|
-
return "SKIP", f"no {pr['property']} declarations found"
|
|
99
|
-
r = max(vals) / min(vals)
|
|
100
|
-
return ("PASS" if r >= pr["min"] else "FAIL"), f"ratio {r:.2f}:1"
|
|
101
|
-
if k == "min_unit":
|
|
102
|
-
vals = [v for v in css_values(text, pr["property"]) if v > 0]
|
|
103
|
-
if not vals:
|
|
104
|
-
return "SKIP", f"no {pr['property']} declarations found"
|
|
105
|
-
return ("PASS" if min(vals) >= pr["min_px"] else "FAIL"), f"smallest {min(vals)}px"
|
|
106
|
-
if k == "color_coverage":
|
|
107
|
-
if not images:
|
|
108
|
-
return "SKIP", "no image passed; render the output to PNG to check coverage"
|
|
109
|
-
pct, err = coverage(images[0], pr["hex"], pr.get("tolerance", 24))
|
|
110
|
-
if err:
|
|
111
|
-
return "SKIP", err
|
|
112
|
-
lo, hi = pr.get("min_pct", 0), pr.get("max_pct", 100)
|
|
113
|
-
return ("PASS" if lo <= pct <= hi else "FAIL"), f"{pct:.1f}% of canvas"
|
|
114
|
-
return "SKIP", f"unknown probe kind {k!r}"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def main():
|
|
118
|
-
if len(sys.argv) < 2:
|
|
119
|
-
print(__doc__)
|
|
120
|
-
return 2
|
|
121
|
-
text, images = load(sys.argv[1:])
|
|
122
|
-
failed = manual = 0
|
|
123
|
-
print(f"design-dna check: {DNA['meta']['name']}\n")
|
|
124
|
-
for t in DNA.get("tests", []):
|
|
125
|
-
if not t.get("auto"):
|
|
126
|
-
status, detail = "MANUAL", "human judgement"
|
|
127
|
-
else:
|
|
128
|
-
status, detail = run(t, text, images)
|
|
129
|
-
failed += status == "FAIL"
|
|
130
|
-
manual += status == "MANUAL"
|
|
131
|
-
print(f" [{status:6}] {t['id']:28} {t['check']}")
|
|
132
|
-
if detail:
|
|
133
|
-
print(f" {detail}")
|
|
134
|
-
if status == "FAIL":
|
|
135
|
-
print(f" fail looks like: {t['fail_looks_like']}")
|
|
136
|
-
print(f"\n{failed} failed, {manual} need human judgement.")
|
|
137
|
-
if manual:
|
|
138
|
-
print("Answer the MANUAL tests out loud before you call this done.")
|
|
139
|
-
return 1 if failed else 0
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if __name__ == "__main__":
|
|
143
|
-
sys.exit(main())
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: design-loop
|
|
3
|
-
description: "Use when something must be built well and there is a real reference it should beat: turn what makes the reference good into measured mechanisms, then run a builder and three fresh-context critics until all three pass. Fires on 'design loop', 'make it as good as <site>', 'it looks generic'. NOT keeping an already-won look (that is `design-dna`)."
|
|
4
|
-
tags: [design, critique, loop, reference, quality, convergence]
|
|
5
|
-
recommends: [design, design-dna, marketing, nextjs]
|
|
6
|
-
origin: risco
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Design Loop — the front door of the design area
|
|
10
|
-
|
|
11
|
-
*A reference you can open, mechanisms you can check, and three judges who did not build the thing.*
|
|
12
|
-
|
|
13
|
-
This is where a design request **enters**. It owns the method: the bar, the judges, the rounds. It
|
|
14
|
-
does not own the visual system — `../design/SKILL.md` does, and this skill invokes it as the builder.
|
|
15
|
-
|
|
16
|
-
**Why the method and not a rubric.** A rubric scored by whoever built the piece measures *intent*,
|
|
17
|
-
because the builder knows what they were going for and so they see it there. And scores drift upward
|
|
18
|
-
every round: a 7 that becomes an 8 with nothing changed is how a loop declares itself finished early.
|
|
19
|
-
Binary verdicts from someone who did not build it are the fix for both.
|
|
20
|
-
|
|
21
|
-
Four phases. Do not skip ahead, and do not start building during 1 to 3.
|
|
22
|
-
|
|
23
|
-
## Phase 1 — Interview
|
|
24
|
-
|
|
25
|
-
Ask exactly these three, together, then stop and wait.
|
|
26
|
-
|
|
27
|
-
1. What are you building, and how long or how big?
|
|
28
|
-
2. Name something that already does this brilliantly — a site, a video, a doc, anything I can open.
|
|
29
|
-
If nothing comes to mind, say skip.
|
|
30
|
-
3. Any files I should work from? Design system, brand doc, script, existing draft.
|
|
31
|
-
|
|
32
|
-
**A vague bar is the number one reason this method fails.** If they name something vague ("Apple's
|
|
33
|
-
website", "good SaaS design"), push once for the specific page or file: a critic with no concrete
|
|
34
|
-
reference invents the comparison and approves everything on round one.
|
|
35
|
-
|
|
36
|
-
On *skip*, propose three candidate bars, one line each on why, and wait. No answer → take the
|
|
37
|
-
hardest one and say so. **Where they come from:** `../design/references/starting-point.md` — run its
|
|
38
|
-
step 0 first, because a bar the project already owns outranks anything you would pick from outside,
|
|
39
|
-
and proposing from memory is how this promise used to resolve to the AI-template median.
|
|
40
|
-
|
|
41
|
-
**Where to go looking.** For a whole page to beat, and for the flows and single patterns behind it:
|
|
42
|
-
`../design/references/inspiration-sources.md`. For a component idea rather than a whole reference:
|
|
43
|
-
a gallery of real products. Browse for the technique, never to clone a
|
|
44
|
-
competitor's exact grid — and come back with **a specific page you can open**, because a gallery
|
|
45
|
-
is not a bar.
|
|
46
|
-
|
|
47
|
-
## Phase 2 — Preflight
|
|
48
|
-
|
|
49
|
-
A check, not a question. Run it before any work and report in one block.
|
|
50
|
-
|
|
51
|
-
- **Fetch the bar now.** Screenshot the URL or read the file. Blocked or missing → say so, ask for
|
|
52
|
-
another. Never substitute a description from memory.
|
|
53
|
-
- **Confirm you can render our output**: screenshots for a site, a filmstrip for animation, a PDF
|
|
54
|
-
render for a doc.
|
|
55
|
-
- **Name the generation tools the goal needs** (image, video, voice) and confirm they are connected.
|
|
56
|
-
- **Confirm the input files exist**: design system, brand doc, script.
|
|
57
|
-
- **Read the harness identity if it exists** — `02-DOCS/wiki/brand/`, reached from the root
|
|
58
|
-
`CLAUDE.md` `## Brand & voice` section, the same place `design`, `marketing` and
|
|
59
|
-
`presentations` read. A bar from outside cannot silently overrule the identity this project
|
|
60
|
-
already committed to: if the reference contradicts it, say which rule conflicts and let the
|
|
61
|
-
user decide which one wins. If no identity exists yet, say so — this run is what creates it.
|
|
62
|
-
|
|
63
|
-
Then print what is working, what is missing, and **which critic goes blind** if something is
|
|
64
|
-
missing. Never carry on quietly with a critic that cannot see — a verdict from a judge who cannot
|
|
65
|
-
see the thing is worse than no verdict, because it looks like evidence.
|
|
66
|
-
|
|
67
|
-
## Phase 3 — Teardown
|
|
68
|
-
|
|
69
|
-
Read the reference properly and write **5 to 7 mechanisms** to `bar.md`.
|
|
70
|
-
|
|
71
|
-
Mechanisms, not adjectives. "Feels premium" is useless. These are useful:
|
|
72
|
-
|
|
73
|
-
- headline is 5x body size, three type sizes total
|
|
74
|
-
- one accent colour, used at most twice per screen
|
|
75
|
-
- motion always resolves in one direction
|
|
76
|
-
- nothing animates for under 400ms
|
|
77
|
-
- whitespace above the fold is at least 40% of the frame
|
|
78
|
-
|
|
79
|
-
Every line must be something a critic can check by looking. Show `bar.md` to the user before
|
|
80
|
-
continuing — and where a mechanism contradicts the harness identity, mark the conflict rather
|
|
81
|
-
than resolving it silently in favour of the reference.
|
|
82
|
-
|
|
83
|
-
## Phase 4 — Loop
|
|
84
|
-
|
|
85
|
-
Split the goal into the smallest pieces that can be improved and judged on their own. You choose
|
|
86
|
-
them. Keep it to three or four unless told otherwise: **every extra piece multiplies the run, and so
|
|
87
|
-
does every extra round.**
|
|
88
|
-
|
|
89
|
-
For each piece: fan out a builder, then three critics, each with fresh context and no knowledge of
|
|
90
|
-
how the builder worked.
|
|
91
|
-
|
|
92
|
-
- **Brief critic** — judges against the stated goal only. Does it do the thing? Ignore aesthetics.
|
|
93
|
-
- **System critic** — judges against the project's design system only. Objective adherence.
|
|
94
|
-
- **Craft critic** — judges against `bar.md` and rendered output only. Put ours next to the
|
|
95
|
-
reference blind, labels stripped, say which is better, name the single biggest gap.
|
|
96
|
-
|
|
97
|
-
Write each critic's brief yourself, adapted to this goal. Do not reuse generic wording across
|
|
98
|
-
different goals.
|
|
99
|
-
|
|
100
|
-
### Rules
|
|
101
|
-
|
|
102
|
-
- **Critics judge rendered output, never the code.** Reading the implementation makes a critic
|
|
103
|
-
evaluate intent instead of result.
|
|
104
|
-
- **Binary verdicts, not scores.** Scores drift upward every round.
|
|
105
|
-
- **Critics are harsh, and harshness has a floor.** A critic has explicit permission to say a piece
|
|
106
|
-
passes. A judge under standing orders to find fault will manufacture one, and then "all three must
|
|
107
|
-
pass" is a door that recedes as you approach it.
|
|
108
|
-
- **All three must pass.** Any fail goes back to the builder with the single biggest gap named — one,
|
|
109
|
-
not a list.
|
|
110
|
-
- **No fixed round count.** The exit is winning, or the user stopping the run, or the halt below.
|
|
111
|
-
|
|
112
|
-
### The halt — how this loop is allowed to end
|
|
113
|
-
|
|
114
|
-
Fresh-context critics cannot see the gap history, so nothing arbitrates across rounds. Left alone,
|
|
115
|
-
two incompatible gaps ("more air" / "more density") make the builder ping-pong forever, and the only
|
|
116
|
-
brake is a human watching. Keep the gap history and use it:
|
|
117
|
-
|
|
118
|
-
> **The same biggest gap named twice for the same piece halts that piece.** Put the two competing
|
|
119
|
-
> demands side by side and ask the user to decide. Do not spend a third round on it.
|
|
120
|
-
|
|
121
|
-
This is not a nicety. A loop whose declared exit is "all three pass" and which cannot detect that it
|
|
122
|
-
will never get there is a gate that cannot close.
|
|
123
|
-
|
|
124
|
-
### Progress and cost
|
|
125
|
-
|
|
126
|
-
Keep a live progress page: piece status, each critic's verdict, gap history, round count.
|
|
127
|
-
|
|
128
|
-
There is **no reliable self-reported token cost, so do not show one.** Show round count and pieces
|
|
129
|
-
instead. If the user names a ceiling, treat it as a checkpoint: pause and ask before passing it, and
|
|
130
|
-
tell them plainly that the real brake is them watching and stopping the run.
|
|
131
|
-
|
|
132
|
-
## When the piece wins
|
|
133
|
-
|
|
134
|
-
Hand the winner to `../design-dna/SKILL.md` to codify it: measured ratios, bans and tests that can
|
|
135
|
-
fail, so piece eight still sits beside piece one as a set. Winning once and not writing down why is
|
|
136
|
-
how the look drifts back to generic by the fifth piece.
|
|
137
|
-
|
|
138
|
-
## What breaks this
|
|
139
|
-
|
|
140
|
-
| Symptom | Cause | Fix |
|
|
141
|
-
|---|---|---|
|
|
142
|
-
| Everything approved on round one | Vague bar | Push for the specific page or file |
|
|
143
|
-
| Approvals that do not survive a second look | Builder judged its own work | Critics need fresh context |
|
|
144
|
-
| Verdicts creep upward each round | Scores instead of binaries | Binary job, not a score |
|
|
145
|
-
| Loop never exits | No halt on a repeated gap | Apply the halt above |
|
|
146
|
-
| Loop exits with the piece still weak | Fixed round count | The exit is winning |
|
|
147
|
-
| Obeys the letter, misses the point | Over-specifying | Every extra instruction is one fewer decision the model makes with its own judgment |
|
|
148
|
-
|
|
149
|
-
## Hand-offs
|
|
150
|
-
|
|
151
|
-
- **The visual system, brand grounding, page composition** → `../design/SKILL.md`. It is the builder
|
|
152
|
-
this loop invokes; it stays reachable directly when there is no bar to beat and no loop to run.
|
|
153
|
-
- **Codifying the winner into a permanent identity** → `../design-dna/SKILL.md`.
|
|
154
|
-
- **The words** → `../marketing/SKILL.md`. **The build** → `../nextjs/SKILL.md`.
|
|
155
|
-
- **Motion craft** → `../motion-craft/SKILL.md`. **How the interface should be built** → `../ui-engineering/SKILL.md`.
|
|
156
|
-
- **"Show me a few versions and I'll pick"** → `../variant-explorer/SKILL.md`. That is selection among
|
|
157
|
-
variants; this is convergence against a bar.
|
|
158
|
-
- **SDD gate.** This skill runs a method; it does not outrank the chain. If the request is a new
|
|
159
|
-
feature or a non-trivial behaviour change in a real app, `../specify/SKILL.md` runs first, then
|
|
160
|
-
`plan`, then the loop builds what was approved.
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# Eval harness — `design-loop` skill
|
|
2
|
-
|
|
3
|
-
Agent-run eval, not a shell script. The cases in `cases.yaml` are fed to a Claude Code agent and
|
|
4
|
-
graded by inspection. The "harness" is the procedure below plus a human (or a judge agent) checking
|
|
5
|
-
outputs against the rubrics.
|
|
6
|
-
|
|
7
|
-
## What's under test
|
|
8
|
-
|
|
9
|
-
1. **Triggering** — does the loop fire when a goal comes with a real reference to beat, and stay
|
|
10
|
-
quiet on the near-misses that belong to a sibling? The expensive confusions are `design` (visual
|
|
11
|
-
system, no bar), `prototype` (variants picked by preference, no bar) and `design-dna` (the winner
|
|
12
|
-
already exists).
|
|
13
|
-
2. **Capability** — when it fires, does it hold the three phases it is easiest to skip, and does its
|
|
14
|
-
loop actually terminate?
|
|
15
|
-
|
|
16
|
-
## A. Triggering accuracy
|
|
17
|
-
|
|
18
|
-
Run each `should_trigger` prompt in a session with the skill installed. It must activate. Run each
|
|
19
|
-
`should_not_trigger` prompt: it must stay quiet and the named `route_to` sibling must be the one that
|
|
20
|
-
answers.
|
|
21
|
-
|
|
22
|
-
The two cases worth watching, because they are where the boundary really is:
|
|
23
|
-
|
|
24
|
-
- *"Show me three versions and I'll pick"* → `prototype`. Selection is not convergence. The user is
|
|
25
|
-
the judge and no bar exists.
|
|
26
|
-
- *"Codify this into a reusable style"* → `design-dna`. Nothing left to converge; this is the
|
|
27
|
-
downstream half.
|
|
28
|
-
|
|
29
|
-
## B. Capability
|
|
30
|
-
|
|
31
|
-
The three scenarios are the three things this skill exists to do and the three it is cheapest to
|
|
32
|
-
fake:
|
|
33
|
-
|
|
34
|
-
1. **The vague bar and the blind critic.** A bar of "Apple's website" must be pushed back on once,
|
|
35
|
-
and a missing render capability must be declared as *which critic goes blind* — not absorbed
|
|
36
|
-
silently. A critic that cannot see, still voting, is the failure this phase prevents.
|
|
37
|
-
2. **Termination.** The scenario hands it an oscillation: air, then density, then air again. The
|
|
38
|
-
skill must halt the piece and surface the two competing demands. **This is the case that matters
|
|
39
|
-
most**: everything else in the skill is judgement, but a loop that cannot detect it will never
|
|
40
|
-
converge is a gate that cannot close, and the constitution's P2 forbids exactly that.
|
|
41
|
-
3. **Hand-off on winning.** Four more pages after a win must go through `design-dna`, not four more
|
|
42
|
-
loops. Re-deriving a style you already won is how the set stops looking like a set.
|
|
43
|
-
|
|
44
|
-
## Grading
|
|
45
|
-
|
|
46
|
-
A case passes when every `must_include` line is observably present in the agent's output or actions.
|
|
47
|
-
Partial credit is not useful here: the mechanisms are the skill, and a run that keeps the prose but
|
|
48
|
-
drops the halt has kept the part that costs nothing.
|
|
49
|
-
|
|
50
|
-
## Known limits of this eval
|
|
51
|
-
|
|
52
|
-
- **Scores vs binaries** and **critics judging rendered output only** are properties of a real
|
|
53
|
-
multi-round run. A single-turn eval can check that the skill *states* them; it cannot prove a
|
|
54
|
-
four-round run honoured them. Verifying that needs a live run against a real reference.
|
|
55
|
-
- The halt is checked from a described history, not a real one. It tests the rule, not the
|
|
56
|
-
bookkeeping that feeds it.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
skill: design-loop
|
|
2
|
-
|
|
3
|
-
should_trigger:
|
|
4
|
-
- prompt: "Build me a landing page for our analytics product that's as good as linear.app — here's the URL."
|
|
5
|
-
why: "Goal plus a named, openable reference to beat. This is the skill's core shape: a bar exists and the work must clear it."
|
|
6
|
-
- prompt: "Our homepage looks generic. Loop it against stripe.com until it actually wins."
|
|
7
|
-
why: "'Looks generic' plus a named bar plus explicit looping — three of the skill's stated triggers in one sentence."
|
|
8
|
-
- prompt: "/design-loop"
|
|
9
|
-
why: "Explicit invocation by name; the skill must run its own interview rather than asking what the user wants in free form."
|
|
10
|
-
- prompt: "I want a pitch deck that holds up next to this one — attaching their PDF."
|
|
11
|
-
why: "Non-obvious because the medium is not web. The method is medium-agnostic: a deck with an openable reference is the same loop, and the craft critic renders to PDF instead of screenshots."
|
|
12
|
-
- prompt: "Run the critic loop on the pricing page and don't stop until it beats the reference."
|
|
13
|
-
why: "Names the mechanism (critic loop) and the exit condition (beating the reference) rather than the outcome."
|
|
14
|
-
- prompt: "Quiero que esta página le gane a la de vercel. Dale vueltas hasta que gane."
|
|
15
|
-
why: "Non-English phrasing with no keyword overlap with the description; the trigger is the semantic shape — a reference to beat plus iteration until it wins."
|
|
16
|
-
- prompt: "This animation feels cheap compared to the one on their site. Can you get it to that level?"
|
|
17
|
-
why: "Non-obvious: reads like a motion request, but a named reference plus a quality gap is a bar to converge against. The loop owns convergence and hands the motion implementation to the craft siblings."
|
|
18
|
-
|
|
19
|
-
should_not_trigger:
|
|
20
|
-
- prompt: "This page came out great. Codify it into a reusable style so my next five pages match it."
|
|
21
|
-
route_to: "design-dna"
|
|
22
|
-
why: "The winner already exists; nothing left to converge. Capturing an identity is the downstream half of the pipe, not the loop."
|
|
23
|
-
- prompt: "Pick a colour palette and type pairing for my product and give me the Tailwind tokens."
|
|
24
|
-
route_to: "design"
|
|
25
|
-
why: "Visual system work with no reference to beat and nothing to judge. `design` stays directly reachable exactly for this."
|
|
26
|
-
- prompt: "Show me three versions of this button and I'll pick the one I like."
|
|
27
|
-
route_to: "variant-explorer"
|
|
28
|
-
why: "Selection among variants by human preference, not convergence against a measured bar. The user is the judge and there is no reference."
|
|
29
|
-
- prompt: "Review the motion in this diff and tell me what's off."
|
|
30
|
-
route_to: "motion-craft"
|
|
31
|
-
why: "One diff, motion-specific, no reference and no build-then-judge rounds. The motion craft skill owns the complaint-to-cause mapping; reviewing is not looping."
|
|
32
|
-
- prompt: "Write the hero headline and value prop for our developer-tool site."
|
|
33
|
-
route_to: "marketing"
|
|
34
|
-
why: "The words, not the bar. `voice` constrains copy in this pipe; it does not write it."
|
|
35
|
-
- prompt: "Set up the Next.js App Router routing and server actions for these pages."
|
|
36
|
-
route_to: "nextjs"
|
|
37
|
-
why: "Pure build mechanics with no design judgement involved at all."
|
|
38
|
-
|
|
39
|
-
capability:
|
|
40
|
-
- scenario: "User asks: 'Make our homepage as good as Apple's website.' (Vague bar. The repo has a design system at design-system.md but no way to render output to screenshots.)"
|
|
41
|
-
must_include:
|
|
42
|
-
- "Pushes back ONCE for the specific page or file rather than accepting 'Apple's website' — names that a vague bar is the top failure mode because a critic with no concrete reference invents the comparison and approves everything on round one."
|
|
43
|
-
- "Runs preflight BEFORE any work and reports it as one block: fetches the bar, checks render capability, checks input files."
|
|
44
|
-
- "Explicitly names that the CRAFT critic goes blind because output cannot be rendered — does not quietly proceed with three critics when only two can see."
|
|
45
|
-
- "Does not start building during the interview, preflight or teardown phases."
|
|
46
|
-
- "Writes 5-7 mechanisms to bar.md as checkable measurements (ratios, coverage, percentages, absences) and shows them to the user before continuing; rejects adjectives like 'feels premium' as mechanisms."
|
|
47
|
-
- "Uses binary verdicts, never numeric scores, and states that scores drift upward every round."
|
|
48
|
-
- "Keeps critics on rendered output only, never the implementation, and gives each fresh context with no knowledge of how the builder worked."
|
|
49
|
-
- scenario: "The loop is running on a hero section. Round 2's craft critic names 'not enough breathing room above the fold' as the biggest gap. Round 3's craft critic names 'the hero feels empty, needs more density' as the biggest gap. Round 4 would name 'not enough breathing room' again."
|
|
50
|
-
must_include:
|
|
51
|
-
- "HALTS that piece instead of starting another round — detects that the same biggest gap has been named twice for the same piece."
|
|
52
|
-
- "Puts the two competing demands side by side (more air vs more density) and asks the user to decide, rather than picking one itself or averaging them."
|
|
53
|
-
- "Does not present the halt as a failure of the loop; it is the declared exit for non-convergence."
|
|
54
|
-
- "Shows round count and pieces rather than claiming a token cost, and states that no reliable self-reported token cost exists."
|
|
55
|
-
- "Keeps the gap history that made the detection possible, as part of the live progress page."
|
|
56
|
-
- scenario: "A piece has cleared all three critics and the user says 'perfect, now do the other four pages'."
|
|
57
|
-
must_include:
|
|
58
|
-
- "Hands the winner to design-dna to codify it into a permanent identity before building the remaining pieces, rather than re-running the loop from scratch four more times."
|
|
59
|
-
- "Names why: winning once without writing down the mechanisms is how the look drifts back to generic by the fifth piece."
|
|
60
|
-
- "Does not merge the won style with any other identity."
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: motion-craft
|
|
3
|
-
description: "Use when an interface moves and the movement has to feel right — durations and easing, what must never animate, fixing motion that reads sluggish, cheap or janky, and reduced-motion. Web and native. NOT the visual system (that is `design`), NOT the graded critique (that is `design-loop`)."
|
|
4
|
-
tags: [motion, animation, interface, craft, frontend]
|
|
5
|
-
recommends: [design]
|
|
6
|
-
profiles: [full]
|
|
7
|
-
origin: risco
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Motion craft — movement that reads as intent
|
|
11
|
-
|
|
12
|
-
Motion is not decoration laid over an interface. It is the interface **explaining what just
|
|
13
|
-
happened**: what appeared, what it came from, what is still loading, what the user just did. When
|
|
14
|
-
motion feels wrong the complaint is almost never "the curve is off" — it is "this feels cheap", or
|
|
15
|
-
"slow", or "I don't know what happened". Those are the symptoms this skill exists to convert into
|
|
16
|
-
decisions.
|
|
17
|
-
|
|
18
|
-
## The one rule
|
|
19
|
-
|
|
20
|
-
**Every animation answers a question the user is already asking.** If you cannot name the question,
|
|
21
|
-
delete the animation — it is costing time and attention and returning nothing.
|
|
22
|
-
|
|
23
|
-
| The user is asking | The motion that answers it |
|
|
24
|
-
| --- | --- |
|
|
25
|
-
| "Where did this come from?" | It enters from its origin, not from nowhere |
|
|
26
|
-
| "Is it working?" | Immediate feedback, under 100ms, even before the result |
|
|
27
|
-
| "What did I just do?" | The changed thing moves; nothing else does |
|
|
28
|
-
| "Where did it go?" | It exits toward where it can be found again |
|
|
29
|
-
| nothing | **no animation** |
|
|
30
|
-
|
|
31
|
-
That table is the whole method. Everything below is how to honour it without shipping something
|
|
32
|
-
that janks.
|
|
33
|
-
|
|
34
|
-
## Duration: the only numbers worth memorising
|
|
35
|
-
|
|
36
|
-
Movement is read as *slow* long before it is read as *long*. The usable range is narrower than most
|
|
37
|
-
people expect, and the mistake is almost always **too slow**, not too fast.
|
|
38
|
-
|
|
39
|
-
| What moves | Range | Why |
|
|
40
|
-
| --- | --- | --- |
|
|
41
|
-
| State on an element already on screen (hover, toggle, press) | 100–150ms | It must feel like a response, not an event |
|
|
42
|
-
| Something entering or leaving in place (menu, tooltip, toast) | 150–250ms | Long enough to be seen, short enough not to be waited for |
|
|
43
|
-
| A region rearranging (list reflow, panel) | 250–350ms | Bigger travel needs more time to stay legible |
|
|
44
|
-
| A full view transition | 300–400ms | The ceiling. Past 400ms it is a wait, not a transition |
|
|
45
|
-
|
|
46
|
-
Two rules that come from those numbers, not from taste:
|
|
47
|
-
|
|
48
|
-
- **Exits are faster than entrances**, usually by about a third. The user has already decided; making
|
|
49
|
-
them watch the decision leave is the single most common way an interface feels sluggish.
|
|
50
|
-
- **Distance and duration scale together, sub-linearly.** Doubling the travel does not double the
|
|
51
|
-
time. If a value grows past 400ms because the element crosses the screen, the layout is the
|
|
52
|
-
problem, not the timing.
|
|
53
|
-
|
|
54
|
-
## Easing: three curves cover almost everything
|
|
55
|
-
|
|
56
|
-
- **Entering, or responding to input** — start fast, settle slow (`ease-out` family). The user's
|
|
57
|
-
attention is already there; arriving quickly and settling reads as responsive.
|
|
58
|
-
- **Leaving** — start slow, accelerate away (`ease-in` family). It matches how the eye lets go.
|
|
59
|
-
- **Moving between two on-screen positions** — accelerate and decelerate (`ease-in-out` family).
|
|
60
|
-
|
|
61
|
-
**Linear is for one thing only: continuous, non-positional change** — a progress bar filling, a
|
|
62
|
-
spinner rotating, a colour crossfade. Linear on anything that moves in space reads as mechanical,
|
|
63
|
-
because nothing physical starts at full speed.
|
|
64
|
-
|
|
65
|
-
Springs are worth reaching for when the motion should feel *physical* — dragging, dismissing,
|
|
66
|
-
anything the user's finger or pointer is still in contact with. They are the wrong tool for
|
|
67
|
-
appearing and disappearing, where a bounce reads as indecision.
|
|
68
|
-
|
|
69
|
-
## What must never animate
|
|
70
|
-
|
|
71
|
-
This is where most jank comes from, and it is not a matter of degree.
|
|
72
|
-
|
|
73
|
-
- **Never animate layout.** Width, height, top, left, margin, padding — each frame forces the engine
|
|
74
|
-
to recompute geometry. Animate transform and opacity, which do not.
|
|
75
|
-
- **Never `transition: all`.** It is the shortest path to animating layout by accident. List the
|
|
76
|
-
properties.
|
|
77
|
-
- **Never animate what the user is reading.** Text that moves while being read is illegible.
|
|
78
|
-
- **Never block input on an animation.** The interface accepts the next action immediately, even
|
|
79
|
-
mid-motion. An animation that must finish before the user may act has become a modal dialog.
|
|
80
|
-
- **Never animate more than one thing per event.** If three things move when one changed, the user
|
|
81
|
-
cannot tell which one mattered.
|
|
82
|
-
|
|
83
|
-
## Reduced motion is not an edge case
|
|
84
|
-
|
|
85
|
-
A real share of people have vestibular conditions for which large movement is nauseating, and they
|
|
86
|
-
have told their operating system so. Honouring it is not optional and it is not a fallback to
|
|
87
|
-
nothing:
|
|
88
|
-
|
|
89
|
-
- **Keep** the feedback: opacity changes, colour, instant state.
|
|
90
|
-
- **Remove** the travel: no sliding across the screen, no scaling, no parallax, no auto-playing loops.
|
|
91
|
-
- The interface must still say what happened — it just says it without moving.
|
|
92
|
-
|
|
93
|
-
An implementation with no reduced-motion branch is unfinished, the same way an interface with no
|
|
94
|
-
error state is unfinished.
|
|
95
|
-
|
|
96
|
-
## Diagnosing motion that feels wrong
|
|
97
|
-
|
|
98
|
-
The complaint names the symptom; this maps it to a cause.
|
|
99
|
-
|
|
100
|
-
| Complaint | Usually | Fix |
|
|
101
|
-
| --- | --- | --- |
|
|
102
|
-
| "Sluggish" | Duration too long, or the exit matches the entrance | Cut to the range above; make exits faster |
|
|
103
|
-
| "Cheap" / "amateur" | Linear easing on positional movement, or bounce on entrances | Match curve to direction |
|
|
104
|
-
| "Janky" / "stutters" | Animating layout properties | Move to transform and opacity |
|
|
105
|
-
| "Distracting" | More than one thing moving per event | Animate only what changed |
|
|
106
|
-
| "I don't know what happened" | Motion with no origin or destination | Move it from where it came from |
|
|
107
|
-
| "Nice, but I'd turn it off" | No reduced-motion branch, or motion that repeats | Honour the setting; never loop what is not loading |
|
|
108
|
-
|
|
109
|
-
## Anti-patterns → STOP
|
|
110
|
-
|
|
111
|
-
| If you're about to… | Reality / Fix |
|
|
112
|
-
| --- | --- |
|
|
113
|
-
| Add motion because the screen feels static | Static is not a defect. Motion with no question to answer is noise with a frame cost. |
|
|
114
|
-
| Copy a duration from a design you liked | You copied the number without its distance and its context. Take the range, verify against the feel. |
|
|
115
|
-
| Animate a list so every item cascades in | Stagger past ~4 items becomes a queue the user waits through. Cap it, or drop it. |
|
|
116
|
-
| Use a spring for a menu appearing | A bounce on an entrance reads as indecision. Springs are for what the pointer is still touching. |
|
|
117
|
-
| Ship motion without checking reduced-motion | It is not an edge case. Unchecked means unfinished. |
|
|
118
|
-
| Reach here for the visual system | Type, colour, spacing and composition are `../design/SKILL.md`. This skill only moves what that one placed. |
|
|
119
|
-
|
|
120
|
-
## See Also
|
|
121
|
-
|
|
122
|
-
- `../design/SKILL.md` — the visual system this motion serves.
|
|
123
|
-
- `../design-loop/SKILL.md` — the graded critique that judges a finished screen, motion included.
|
|
124
|
-
- `../design-dna/SKILL.md` — turning a look, motion rules included, into a reusable identity.
|
|
125
|
-
- `../accessibility/SKILL.md` — the wider ground reduced-motion sits in.
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
skill: motion-craft
|
|
2
|
-
|
|
3
|
-
should_trigger:
|
|
4
|
-
- prompt: "The menu animation feels sluggish, can you make it feel snappier?"
|
|
5
|
-
why: "The canonical case: a complaint about feel, which this skill converts into a duration and an easing decision."
|
|
6
|
-
- prompt: "What duration and easing should this dropdown use?"
|
|
7
|
-
why: "Directly the numbers this skill owns, for an element entering in place."
|
|
8
|
-
- prompt: "My list animation stutters when it reflows."
|
|
9
|
-
why: "Jank is the symptom of animating layout properties, which is the one hard rule here."
|
|
10
|
-
- prompt: "Añade una animación al abrir el panel, pero que no quede cutre."
|
|
11
|
-
why: "Same ask in Spanish; the trigger is the intent, not the language."
|
|
12
|
-
- prompt: "Does this respect prefers-reduced-motion? I don't think we handled it."
|
|
13
|
-
why: "Reduced-motion is treated here as part of finishing the work, not as an edge case."
|
|
14
|
-
- prompt: "Everything on the page moves at once when I click one button."
|
|
15
|
-
why: "More than one thing moving per event is a named diagnosis in this skill."
|
|
16
|
-
|
|
17
|
-
should_not_trigger:
|
|
18
|
-
- prompt: "Design a landing page for my analytics SaaS — hero, pricing, the works."
|
|
19
|
-
route_to: "design"
|
|
20
|
-
why: "Type, colour, spacing and composition are the visual system, which this skill only moves once it exists."
|
|
21
|
-
- prompt: "Review this checkout screen and tell me how good it actually is, with a grade."
|
|
22
|
-
route_to: "design-loop"
|
|
23
|
-
why: "Graded critique of a finished screen is the loop's job; this skill builds motion, it does not judge screens."
|
|
24
|
-
- prompt: "This design came out great — turn it into a style I can reuse everywhere."
|
|
25
|
-
route_to: "design-dna"
|
|
26
|
-
why: "Codifying a look into a permanent identity is capture, not motion craft."
|
|
27
|
-
- prompt: "Make the site keyboard navigable and fix the contrast failures."
|
|
28
|
-
route_to: "accessibility"
|
|
29
|
-
why: "Accessibility beyond reduced-motion is its own ground; only the motion half lives here."
|
|
30
|
-
- prompt: "Our React app re-renders too much and the profiler shows wasted renders."
|
|
31
|
-
route_to: "react"
|
|
32
|
-
why: "A rendering performance problem is framework work, even when the symptom looks like stutter."
|
|
33
|
-
|
|
34
|
-
capability:
|
|
35
|
-
- prompt: "This modal slides in over 600ms with a linear curve and it feels cheap. Fix it and say why."
|
|
36
|
-
why: "Exercises the two most common defects at once — too slow, and linear on positional movement — and demands the reasoning, not just new numbers."
|
|
37
|
-
- prompt: "We animate width and height on the sidebar and it janks on mobile. What do we do instead?"
|
|
38
|
-
why: "The layout-vs-compositor rule is the load-bearing piece of technical content here."
|