@r1z4x/tezgah 1.9.0 → 1.11.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 (429) hide show
  1. package/CHANGELOG.md +98 -1
  2. package/MANIFEST +382 -144
  3. package/README.de.md +1 -1
  4. package/README.es.md +1 -1
  5. package/README.fr.md +1 -1
  6. package/README.md +1 -1
  7. package/README.tr.md +1 -1
  8. package/bin/codegen +5 -2
  9. package/bin/tezgah-design +288 -1
  10. package/bin/tezgah-docs +1 -1
  11. package/bin/tezgah-doctor +39 -2
  12. package/bin/tezgah-import-ai-research +26 -12
  13. package/bin/tezgah-ocr-review +296 -0
  14. package/bin/tezgah-research +216 -40
  15. package/bin/tezgah-review-quote +185 -0
  16. package/bin/tezgah-setup +136 -33
  17. package/bin/tezgah-skill +1 -1
  18. package/bin/tezgah-status +201 -3
  19. package/bin/tezgah-task +203 -3
  20. package/commands/adhd.md +2 -2
  21. package/commands/ponytail.md +4 -4
  22. package/docs/architecture.md +2 -2
  23. package/docs/citations-baseline.json +2 -2
  24. package/docs/clarity-baseline.json +2 -2
  25. package/docs/contract.md +87 -42
  26. package/docs/environment.md +5 -3
  27. package/docs/evidence.md +28 -9
  28. package/docs/feature-audit.md +2 -2
  29. package/docs/gate.md +54 -31
  30. package/docs/glossary.md +5 -2
  31. package/docs/hosts.md +17 -3
  32. package/docs/index.json +34 -8
  33. package/docs/judge.md +4 -2
  34. package/docs/layers.md +3 -3
  35. package/docs/models.md +31 -9
  36. package/docs/operations.md +148 -8
  37. package/docs/research.md +786 -5
  38. package/docs/skills.md +137 -13
  39. package/docs/status-line.md +115 -1
  40. package/hooks/hooks.json +1 -1
  41. package/hooks/lang/en.json +10 -0
  42. package/hooks/lang/tr.json +11 -1
  43. package/hooks/tezgah_agents.py +38 -22
  44. package/hooks/tezgah_apps.py +18 -0
  45. package/hooks/tezgah_components.py +4 -0
  46. package/hooks/tezgah_context.py +189 -50
  47. package/hooks/tezgah_extension.py +337 -0
  48. package/hooks/tezgah_gate.py +188 -56
  49. package/hooks/tezgah_integrity.py +652 -105
  50. package/hooks/tezgah_judge.py +6 -4
  51. package/hooks/tezgah_models.py +59 -19
  52. package/hooks/tezgah_orca.py +1 -1
  53. package/hooks/tezgah_paths.py +102 -6
  54. package/hooks/tezgah_policy.py +94 -45
  55. package/hooks/tezgah_rank.py +9 -6
  56. package/hooks/tezgah_replay.py +4 -4
  57. package/hooks/tezgah_research.py +1260 -65
  58. package/hooks/tezgah_research_capture.py +1544 -0
  59. package/hooks/tezgah_research_evidence.py +842 -0
  60. package/hooks/tezgah_research_stats.py +258 -0
  61. package/hooks/tezgah_skill_pick.py +408 -106
  62. package/hooks/tezgah_stopspec.py +8 -1
  63. package/hooks/tezgah_task.py +12 -4
  64. package/hooks/tezgah_taste_ledger.py +1 -1
  65. package/hosts/cursor/hook.py +29 -2
  66. package/hosts/opencode/plugins/tezgah.js +307 -46
  67. package/hosts/opencode/tui/cli/tui.tsx +100 -0
  68. package/hosts/opencode/tui/tezgah-tui.tsx +2 -1
  69. package/output-styles/tezgah.md +10 -10
  70. package/package.json +1 -1
  71. package/packaging/install.ps1 +36 -3
  72. package/packaging/install.sh +13 -3
  73. package/packaging/upgrade.sh +61 -7
  74. package/skills/ai-research/SKILL.md +21 -14
  75. package/skills/ai-research/SOURCE +7 -5
  76. package/skills/ai-research/index/1-frame.md +6 -6
  77. package/skills/ai-research/index/2-data.md +9 -9
  78. package/skills/ai-research/index/3-train.md +36 -36
  79. package/skills/ai-research/index/4-measure.md +13 -13
  80. package/skills/ai-research/index/5-run.md +11 -11
  81. package/skills/ai-research/index/6-write.md +23 -23
  82. package/skills/ai-research/library.json +104 -104
  83. package/skills/analyze-app/SKILL.md +17 -12
  84. package/skills/design-contract/SKILL.md +42 -7
  85. package/skills/design-contract/data-views.md +2 -2
  86. package/skills/design-library/EVALS.md +1 -1
  87. package/skills/design-library/INDEX.md +39 -39
  88. package/skills/design-library/SKILL.md +19 -13
  89. package/skills/design-library/SOURCE +45 -43
  90. package/skills/feature-audit/SKILL.md +20 -14
  91. package/skills/hallmark/LICENSE +21 -0
  92. package/skills/hallmark/SKILL.md +154 -0
  93. package/skills/hallmark/SOURCE +207 -0
  94. package/skills/hallmark/agents/openai.yaml +13 -0
  95. package/skills/hallmark/references/anatomy.md +71 -0
  96. package/skills/hallmark/references/brand-truth.md +40 -0
  97. package/skills/hallmark/references/comp.md +104 -0
  98. package/skills/hallmark/references/craft.md +116 -0
  99. package/skills/hallmark/references/dark-mode.md +49 -0
  100. package/skills/hallmark/references/data-viz.md +48 -0
  101. package/skills/hallmark/references/design-md.md +53 -0
  102. package/skills/hallmark/references/direction.md +52 -0
  103. package/skills/hallmark/references/export-formats.md +80 -0
  104. package/skills/hallmark/references/flow.md +131 -0
  105. package/skills/hallmark/references/fonts.md +58 -0
  106. package/skills/hallmark/references/gates.md +243 -0
  107. package/skills/hallmark/references/genres/atmospheric.md +24 -0
  108. package/skills/hallmark/references/genres/editorial.md +24 -0
  109. package/skills/hallmark/references/genres/modern-minimal.md +24 -0
  110. package/skills/hallmark/references/genres/playful.md +24 -0
  111. package/skills/hallmark/references/imagery.md +99 -0
  112. package/skills/hallmark/references/interaction-and-states.md +89 -0
  113. package/skills/hallmark/references/layout.md +104 -0
  114. package/skills/hallmark/references/macrostructures/01-bento-grid.md +21 -0
  115. package/skills/hallmark/references/macrostructures/02-long-document.md +35 -0
  116. package/skills/hallmark/references/macrostructures/03-marquee-hero.md +21 -0
  117. package/skills/hallmark/references/macrostructures/04-stat-led.md +21 -0
  118. package/skills/hallmark/references/macrostructures/05-workbench.md +21 -0
  119. package/skills/hallmark/references/macrostructures/06-conversational-faq.md +28 -0
  120. package/skills/hallmark/references/macrostructures/07-manifesto.md +28 -0
  121. package/skills/hallmark/references/macrostructures/08-photographic.md +21 -0
  122. package/skills/hallmark/references/macrostructures/09-quote-led.md +21 -0
  123. package/skills/hallmark/references/macrostructures/10-specimen.md +21 -0
  124. package/skills/hallmark/references/macrostructures/11-catalogue.md +21 -0
  125. package/skills/hallmark/references/macrostructures/12-letter.md +21 -0
  126. package/skills/hallmark/references/macrostructures/13-index-first.md +21 -0
  127. package/skills/hallmark/references/macrostructures/14-narrative-workflow.md +21 -0
  128. package/skills/hallmark/references/macrostructures/15-split-studio.md +21 -0
  129. package/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
  130. package/skills/hallmark/references/macrostructures/17-type-specimen.md +19 -0
  131. package/skills/hallmark/references/macrostructures/18-portfolio-grid.md +21 -0
  132. package/skills/hallmark/references/macrostructures/19-map-diagram.md +21 -0
  133. package/skills/hallmark/references/macrostructures/20-ecosystem-index.md +19 -0
  134. package/skills/hallmark/references/macrostructures/21-component-playground.md +21 -0
  135. package/skills/hallmark/references/macrostructures.md +119 -0
  136. package/skills/hallmark/references/microinteractions.md +80 -0
  137. package/skills/hallmark/references/patterns.md +202 -0
  138. package/skills/hallmark/references/redesign.md +88 -0
  139. package/skills/hallmark/references/responsive.md +46 -0
  140. package/skills/hallmark/references/review-finish.md +19 -0
  141. package/skills/hallmark/references/review-hero.md +20 -0
  142. package/skills/hallmark/references/scroll-choreography.md +110 -0
  143. package/skills/hallmark/references/texture.md +90 -0
  144. package/skills/hallmark/references/themes/README.md +58 -0
  145. package/skills/hallmark/references/themes/almanac.jpg +0 -0
  146. package/skills/hallmark/references/themes/almanac.md +103 -0
  147. package/skills/hallmark/references/themes/arcade.jpg +0 -0
  148. package/skills/hallmark/references/themes/arcade.md +102 -0
  149. package/skills/hallmark/references/themes/atelier.jpg +0 -0
  150. package/skills/hallmark/references/themes/atelier.md +98 -0
  151. package/skills/hallmark/references/themes/bloom.jpg +0 -0
  152. package/skills/hallmark/references/themes/bloom.md +102 -0
  153. package/skills/hallmark/references/themes/blueprint.jpg +0 -0
  154. package/skills/hallmark/references/themes/blueprint.md +103 -0
  155. package/skills/hallmark/references/themes/broadside.jpg +0 -0
  156. package/skills/hallmark/references/themes/broadside.md +108 -0
  157. package/skills/hallmark/references/themes/brutal.jpg +0 -0
  158. package/skills/hallmark/references/themes/brutal.md +95 -0
  159. package/skills/hallmark/references/themes/carnival.jpg +0 -0
  160. package/skills/hallmark/references/themes/carnival.md +104 -0
  161. package/skills/hallmark/references/themes/cobalt.jpg +0 -0
  162. package/skills/hallmark/references/themes/cobalt.md +101 -0
  163. package/skills/hallmark/references/themes/console.jpg +0 -0
  164. package/skills/hallmark/references/themes/console.md +99 -0
  165. package/skills/hallmark/references/themes/coral.jpg +0 -0
  166. package/skills/hallmark/references/themes/coral.md +102 -0
  167. package/skills/hallmark/references/themes/darkroom.jpg +0 -0
  168. package/skills/hallmark/references/themes/darkroom.md +99 -0
  169. package/skills/hallmark/references/themes/dose.jpg +0 -0
  170. package/skills/hallmark/references/themes/dose.md +98 -0
  171. package/skills/hallmark/references/themes/dusk.jpg +0 -0
  172. package/skills/hallmark/references/themes/dusk.md +105 -0
  173. package/skills/hallmark/references/themes/editorial.jpg +0 -0
  174. package/skills/hallmark/references/themes/editorial.md +97 -0
  175. package/skills/hallmark/references/themes/formwork.jpg +0 -0
  176. package/skills/hallmark/references/themes/formwork.md +107 -0
  177. package/skills/hallmark/references/themes/furrow.jpg +0 -0
  178. package/skills/hallmark/references/themes/furrow.md +98 -0
  179. package/skills/hallmark/references/themes/garden.jpg +0 -0
  180. package/skills/hallmark/references/themes/garden.md +97 -0
  181. package/skills/hallmark/references/themes/grid.jpg +0 -0
  182. package/skills/hallmark/references/themes/grid.md +101 -0
  183. package/skills/hallmark/references/themes/halftone.jpg +0 -0
  184. package/skills/hallmark/references/themes/halftone.md +106 -0
  185. package/skills/hallmark/references/themes/hedgerow.jpg +0 -0
  186. package/skills/hallmark/references/themes/hedgerow.md +104 -0
  187. package/skills/hallmark/references/themes/hum.jpg +0 -0
  188. package/skills/hallmark/references/themes/hum.md +99 -0
  189. package/skills/hallmark/references/themes/index.json +2191 -0
  190. package/skills/hallmark/references/themes/ink.jpg +0 -0
  191. package/skills/hallmark/references/themes/ink.md +106 -0
  192. package/skills/hallmark/references/themes/kiln.jpg +0 -0
  193. package/skills/hallmark/references/themes/kiln.md +108 -0
  194. package/skills/hallmark/references/themes/loom.jpg +0 -0
  195. package/skills/hallmark/references/themes/loom.md +106 -0
  196. package/skills/hallmark/references/themes/lumen.jpg +0 -0
  197. package/skills/hallmark/references/themes/lumen.md +103 -0
  198. package/skills/hallmark/references/themes/manifesto.jpg +0 -0
  199. package/skills/hallmark/references/themes/manifesto.md +101 -0
  200. package/skills/hallmark/references/themes/midnight.jpg +0 -0
  201. package/skills/hallmark/references/themes/midnight.md +97 -0
  202. package/skills/hallmark/references/themes/newsprint.jpg +0 -0
  203. package/skills/hallmark/references/themes/newsprint.md +102 -0
  204. package/skills/hallmark/references/themes/overprint.jpg +0 -0
  205. package/skills/hallmark/references/themes/overprint.md +101 -0
  206. package/skills/hallmark/references/themes/pasteup.jpg +0 -0
  207. package/skills/hallmark/references/themes/pasteup.md +100 -0
  208. package/skills/hallmark/references/themes/piste.jpg +0 -0
  209. package/skills/hallmark/references/themes/piste.md +99 -0
  210. package/skills/hallmark/references/themes/ribbon.jpg +0 -0
  211. package/skills/hallmark/references/themes/ribbon.md +106 -0
  212. package/skills/hallmark/references/themes/rim.jpg +0 -0
  213. package/skills/hallmark/references/themes/rim.md +96 -0
  214. package/skills/hallmark/references/themes/riso.jpg +0 -0
  215. package/skills/hallmark/references/themes/riso.md +98 -0
  216. package/skills/hallmark/references/themes/solstice.jpg +0 -0
  217. package/skills/hallmark/references/themes/solstice.md +104 -0
  218. package/skills/hallmark/references/themes/specimen.jpg +0 -0
  219. package/skills/hallmark/references/themes/specimen.md +100 -0
  220. package/skills/hallmark/references/themes/spore.jpg +0 -0
  221. package/skills/hallmark/references/themes/spore.md +104 -0
  222. package/skills/hallmark/references/themes/sport.jpg +0 -0
  223. package/skills/hallmark/references/themes/sport.md +101 -0
  224. package/skills/hallmark/references/themes/squeeze.jpg +0 -0
  225. package/skills/hallmark/references/themes/squeeze.md +99 -0
  226. package/skills/hallmark/references/themes/sticker.jpg +0 -0
  227. package/skills/hallmark/references/themes/sticker.md +106 -0
  228. package/skills/hallmark/references/themes/studio.jpg +0 -0
  229. package/skills/hallmark/references/themes/studio.md +99 -0
  230. package/skills/hallmark/references/themes/terminal.jpg +0 -0
  231. package/skills/hallmark/references/themes/terminal.md +96 -0
  232. package/skills/hallmark/references/themes/terrazzo.jpg +0 -0
  233. package/skills/hallmark/references/themes/terrazzo.md +106 -0
  234. package/skills/hallmark/references/themes/ultraviolet.jpg +0 -0
  235. package/skills/hallmark/references/themes/ultraviolet.md +106 -0
  236. package/skills/hallmark/references/themes/vellum.jpg +0 -0
  237. package/skills/hallmark/references/themes/vellum.md +105 -0
  238. package/skills/hallmark/references/themes/wayfind.jpg +0 -0
  239. package/skills/hallmark/references/themes/wayfind.md +105 -0
  240. package/skills/hallmark/references/themes/werkstatt.jpg +0 -0
  241. package/skills/hallmark/references/themes/werkstatt.md +105 -0
  242. package/skills/hallmark/scripts/capture.mjs +125 -0
  243. package/skills/hallmark/scripts/fixtures/exemplars/atmospheric.html +324 -0
  244. package/skills/hallmark/scripts/fixtures/exemplars/editorial.html +363 -0
  245. package/skills/hallmark/scripts/fixtures/exemplars/modern-minimal.html +527 -0
  246. package/skills/hallmark/scripts/fixtures/exemplars/playful.html +353 -0
  247. package/skills/hallmark/scripts/fixtures/eyebrow-fail/index.html +118 -0
  248. package/skills/hallmark/scripts/fixtures/eyebrow-pass/index.html +137 -0
  249. package/skills/hallmark/scripts/fixtures/kept/after.html +27 -0
  250. package/skills/hallmark/scripts/fixtures/kept/before.html +26 -0
  251. package/skills/hallmark/scripts/fixtures/slopped.html +145 -0
  252. package/skills/hallmark/scripts/fixtures/tailwind-fail/Feature.vue +14 -0
  253. package/skills/hallmark/scripts/fixtures/tailwind-fail/Hero.tsx +33 -0
  254. package/skills/hallmark/scripts/fixtures/tailwind-fail/index.html +74 -0
  255. package/skills/hallmark/scripts/fixtures/tailwind-fail/style.css +6 -0
  256. package/skills/hallmark/scripts/fixtures/tailwind-pass/Hero.tsx +33 -0
  257. package/skills/hallmark/scripts/fixtures/tailwind-pass/index.html +57 -0
  258. package/skills/hallmark/scripts/fixtures/tailwind-pass/style.css +15 -0
  259. package/skills/hallmark/scripts/fixtures/waiver/index.html +54 -0
  260. package/skills/hallmark/scripts/imagegen.mjs +85 -0
  261. package/skills/hallmark/scripts/install-hook.mjs +70 -0
  262. package/skills/hallmark/scripts/install.mjs +141 -0
  263. package/skills/hallmark/scripts/lint-hook.mjs +49 -0
  264. package/skills/hallmark/scripts/photos.json +1 -0
  265. package/skills/hallmark/scripts/picture.mjs +71 -0
  266. package/skills/hallmark/scripts/refcheck.mjs +352 -0
  267. package/skills/hallmark/scripts/sloplint-render.mjs +1252 -0
  268. package/skills/hallmark/scripts/sloplint.mjs +4422 -0
  269. package/skills/hallmark/scripts/theme.mjs +650 -0
  270. package/skills/harness/SKILL.md +15 -8
  271. package/skills/i-have-adhd/SKILL.md +22 -11
  272. package/skills/no-ai-slop/SKILL.md +15 -1
  273. package/skills/plan-add/SKILL.md +33 -26
  274. package/skills/plan-status/SKILL.md +13 -7
  275. package/skills/plan-sync/SKILL.md +18 -12
  276. package/skills/pm-frameworks/SKILL.md +19 -10
  277. package/skills/pm-frameworks/SOURCE +7 -5
  278. package/skills/ponytail/SKILL.md +19 -14
  279. package/skills/product-analysis/SKILL.md +22 -18
  280. package/skills/product-flow/SKILL.md +14 -9
  281. package/skills/research/SKILL.md +75 -39
  282. package/skills/rl-env/SKILL.md +25 -13
  283. package/skills/rl-env/SOURCE +8 -6
  284. package/skills/tezgah-contract/SKILL.md +47 -42
  285. package/bin/tezgah-skill.py +0 -59
  286. /package/skills/ai-research/0-autoresearch-skill/{SKILL.md → ENTRY.md} +0 -0
  287. /package/skills/ai-research/01-model-architecture/litgpt/{SKILL.md → ENTRY.md} +0 -0
  288. /package/skills/ai-research/01-model-architecture/mamba/{SKILL.md → ENTRY.md} +0 -0
  289. /package/skills/ai-research/01-model-architecture/nanogpt/{SKILL.md → ENTRY.md} +0 -0
  290. /package/skills/ai-research/01-model-architecture/rwkv/{SKILL.md → ENTRY.md} +0 -0
  291. /package/skills/ai-research/01-model-architecture/torchtitan/{SKILL.md → ENTRY.md} +0 -0
  292. /package/skills/ai-research/02-tokenization/huggingface-tokenizers/{SKILL.md → ENTRY.md} +0 -0
  293. /package/skills/ai-research/02-tokenization/sentencepiece/{SKILL.md → ENTRY.md} +0 -0
  294. /package/skills/ai-research/03-fine-tuning/axolotl/{SKILL.md → ENTRY.md} +0 -0
  295. /package/skills/ai-research/03-fine-tuning/llama-factory/{SKILL.md → ENTRY.md} +0 -0
  296. /package/skills/ai-research/03-fine-tuning/peft/{SKILL.md → ENTRY.md} +0 -0
  297. /package/skills/ai-research/03-fine-tuning/unsloth/{SKILL.md → ENTRY.md} +0 -0
  298. /package/skills/ai-research/04-mechanistic-interpretability/nnsight/{SKILL.md → ENTRY.md} +0 -0
  299. /package/skills/ai-research/04-mechanistic-interpretability/pyvene/{SKILL.md → ENTRY.md} +0 -0
  300. /package/skills/ai-research/04-mechanistic-interpretability/saelens/{SKILL.md → ENTRY.md} +0 -0
  301. /package/skills/ai-research/04-mechanistic-interpretability/transformer-lens/{SKILL.md → ENTRY.md} +0 -0
  302. /package/skills/ai-research/05-data-processing/nemo-curator/{SKILL.md → ENTRY.md} +0 -0
  303. /package/skills/ai-research/05-data-processing/ray-data/{SKILL.md → ENTRY.md} +0 -0
  304. /package/skills/ai-research/06-post-training/grpo-rl-training/{SKILL.md → ENTRY.md} +0 -0
  305. /package/skills/ai-research/06-post-training/miles/{SKILL.md → ENTRY.md} +0 -0
  306. /package/skills/ai-research/06-post-training/openrlhf/{SKILL.md → ENTRY.md} +0 -0
  307. /package/skills/ai-research/06-post-training/simpo/{SKILL.md → ENTRY.md} +0 -0
  308. /package/skills/ai-research/06-post-training/slime/{SKILL.md → ENTRY.md} +0 -0
  309. /package/skills/ai-research/06-post-training/torchforge/{SKILL.md → ENTRY.md} +0 -0
  310. /package/skills/ai-research/06-post-training/trl-fine-tuning/{SKILL.md → ENTRY.md} +0 -0
  311. /package/skills/ai-research/06-post-training/verl/{SKILL.md → ENTRY.md} +0 -0
  312. /package/skills/ai-research/07-safety-alignment/constitutional-ai/{SKILL.md → ENTRY.md} +0 -0
  313. /package/skills/ai-research/07-safety-alignment/llamaguard/{SKILL.md → ENTRY.md} +0 -0
  314. /package/skills/ai-research/07-safety-alignment/nemo-guardrails/{SKILL.md → ENTRY.md} +0 -0
  315. /package/skills/ai-research/07-safety-alignment/prompt-guard/{SKILL.md → ENTRY.md} +0 -0
  316. /package/skills/ai-research/08-distributed-training/accelerate/{SKILL.md → ENTRY.md} +0 -0
  317. /package/skills/ai-research/08-distributed-training/deepspeed/{SKILL.md → ENTRY.md} +0 -0
  318. /package/skills/ai-research/08-distributed-training/megatron-core/{SKILL.md → ENTRY.md} +0 -0
  319. /package/skills/ai-research/08-distributed-training/pytorch-fsdp2/{SKILL.md → ENTRY.md} +0 -0
  320. /package/skills/ai-research/08-distributed-training/pytorch-lightning/{SKILL.md → ENTRY.md} +0 -0
  321. /package/skills/ai-research/08-distributed-training/ray-train/{SKILL.md → ENTRY.md} +0 -0
  322. /package/skills/ai-research/09-infrastructure/lambda-labs/{SKILL.md → ENTRY.md} +0 -0
  323. /package/skills/ai-research/09-infrastructure/modal/{SKILL.md → ENTRY.md} +0 -0
  324. /package/skills/ai-research/09-infrastructure/skypilot/{SKILL.md → ENTRY.md} +0 -0
  325. /package/skills/ai-research/10-optimization/awq/{SKILL.md → ENTRY.md} +0 -0
  326. /package/skills/ai-research/10-optimization/bitsandbytes/{SKILL.md → ENTRY.md} +0 -0
  327. /package/skills/ai-research/10-optimization/flash-attention/{SKILL.md → ENTRY.md} +0 -0
  328. /package/skills/ai-research/10-optimization/gguf/{SKILL.md → ENTRY.md} +0 -0
  329. /package/skills/ai-research/10-optimization/gptq/{SKILL.md → ENTRY.md} +0 -0
  330. /package/skills/ai-research/10-optimization/hqq/{SKILL.md → ENTRY.md} +0 -0
  331. /package/skills/ai-research/10-optimization/ml-training-recipes/{SKILL.md → ENTRY.md} +0 -0
  332. /package/skills/ai-research/11-evaluation/bigcode-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  333. /package/skills/ai-research/11-evaluation/lm-evaluation-harness/{SKILL.md → ENTRY.md} +0 -0
  334. /package/skills/ai-research/11-evaluation/nemo-evaluator/{SKILL.md → ENTRY.md} +0 -0
  335. /package/skills/ai-research/12-inference-serving/llama-cpp/{SKILL.md → ENTRY.md} +0 -0
  336. /package/skills/ai-research/12-inference-serving/sglang/{SKILL.md → ENTRY.md} +0 -0
  337. /package/skills/ai-research/12-inference-serving/tensorrt-llm/{SKILL.md → ENTRY.md} +0 -0
  338. /package/skills/ai-research/12-inference-serving/vllm/{SKILL.md → ENTRY.md} +0 -0
  339. /package/skills/ai-research/13-mlops/mlflow/{SKILL.md → ENTRY.md} +0 -0
  340. /package/skills/ai-research/13-mlops/swanlab/{SKILL.md → ENTRY.md} +0 -0
  341. /package/skills/ai-research/13-mlops/tensorboard/{SKILL.md → ENTRY.md} +0 -0
  342. /package/skills/ai-research/13-mlops/weights-and-biases/{SKILL.md → ENTRY.md} +0 -0
  343. /package/skills/ai-research/14-agents/a-evolve/{SKILL.md → ENTRY.md} +0 -0
  344. /package/skills/ai-research/14-agents/autogpt/{SKILL.md → ENTRY.md} +0 -0
  345. /package/skills/ai-research/14-agents/crewai/{SKILL.md → ENTRY.md} +0 -0
  346. /package/skills/ai-research/14-agents/langchain/{SKILL.md → ENTRY.md} +0 -0
  347. /package/skills/ai-research/14-agents/llamaindex/{SKILL.md → ENTRY.md} +0 -0
  348. /package/skills/ai-research/15-rag/chroma/{SKILL.md → ENTRY.md} +0 -0
  349. /package/skills/ai-research/15-rag/faiss/{SKILL.md → ENTRY.md} +0 -0
  350. /package/skills/ai-research/15-rag/pinecone/{SKILL.md → ENTRY.md} +0 -0
  351. /package/skills/ai-research/15-rag/qdrant/{SKILL.md → ENTRY.md} +0 -0
  352. /package/skills/ai-research/15-rag/sentence-transformers/{SKILL.md → ENTRY.md} +0 -0
  353. /package/skills/ai-research/16-prompt-engineering/dspy/{SKILL.md → ENTRY.md} +0 -0
  354. /package/skills/ai-research/16-prompt-engineering/guidance/{SKILL.md → ENTRY.md} +0 -0
  355. /package/skills/ai-research/16-prompt-engineering/instructor/{SKILL.md → ENTRY.md} +0 -0
  356. /package/skills/ai-research/16-prompt-engineering/outlines/{SKILL.md → ENTRY.md} +0 -0
  357. /package/skills/ai-research/17-observability/langsmith/{SKILL.md → ENTRY.md} +0 -0
  358. /package/skills/ai-research/17-observability/phoenix/{SKILL.md → ENTRY.md} +0 -0
  359. /package/skills/ai-research/18-multimodal/audiocraft/{SKILL.md → ENTRY.md} +0 -0
  360. /package/skills/ai-research/18-multimodal/blip-2/{SKILL.md → ENTRY.md} +0 -0
  361. /package/skills/ai-research/18-multimodal/clip/{SKILL.md → ENTRY.md} +0 -0
  362. /package/skills/ai-research/18-multimodal/cosmos-policy/{SKILL.md → ENTRY.md} +0 -0
  363. /package/skills/ai-research/18-multimodal/llava/{SKILL.md → ENTRY.md} +0 -0
  364. /package/skills/ai-research/18-multimodal/openpi/{SKILL.md → ENTRY.md} +0 -0
  365. /package/skills/ai-research/18-multimodal/openvla-oft/{SKILL.md → ENTRY.md} +0 -0
  366. /package/skills/ai-research/18-multimodal/segment-anything/{SKILL.md → ENTRY.md} +0 -0
  367. /package/skills/ai-research/18-multimodal/stable-diffusion/{SKILL.md → ENTRY.md} +0 -0
  368. /package/skills/ai-research/18-multimodal/whisper/{SKILL.md → ENTRY.md} +0 -0
  369. /package/skills/ai-research/19-emerging-techniques/knowledge-distillation/{SKILL.md → ENTRY.md} +0 -0
  370. /package/skills/ai-research/19-emerging-techniques/long-context/{SKILL.md → ENTRY.md} +0 -0
  371. /package/skills/ai-research/19-emerging-techniques/model-merging/{SKILL.md → ENTRY.md} +0 -0
  372. /package/skills/ai-research/19-emerging-techniques/model-pruning/{SKILL.md → ENTRY.md} +0 -0
  373. /package/skills/ai-research/19-emerging-techniques/moe-training/{SKILL.md → ENTRY.md} +0 -0
  374. /package/skills/ai-research/19-emerging-techniques/speculative-decoding/{SKILL.md → ENTRY.md} +0 -0
  375. /package/skills/ai-research/20-ml-paper-writing/academic-plotting/{SKILL.md → ENTRY.md} +0 -0
  376. /package/skills/ai-research/20-ml-paper-writing/ml-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  377. /package/skills/ai-research/20-ml-paper-writing/presenting-conference-talks/{SKILL.md → ENTRY.md} +0 -0
  378. /package/skills/ai-research/20-ml-paper-writing/systems-paper-writing/{SKILL.md → ENTRY.md} +0 -0
  379. /package/skills/ai-research/21-research-ideation/brainstorming-research-ideas/{SKILL.md → ENTRY.md} +0 -0
  380. /package/skills/ai-research/21-research-ideation/creative-thinking-for-research/{SKILL.md → ENTRY.md} +0 -0
  381. /package/skills/ai-research/22-agent-native-research-artifact/compiler/{SKILL.md → ENTRY.md} +0 -0
  382. /package/skills/ai-research/22-agent-native-research-artifact/research-manager/{SKILL.md → ENTRY.md} +0 -0
  383. /package/skills/ai-research/22-agent-native-research-artifact/rigor-reviewer/{SKILL.md → ENTRY.md} +0 -0
  384. /package/skills/design-library/adaptive-interfaces/skills/colour-independence/{SKILL.md → ENTRY.md} +0 -0
  385. /package/skills/design-library/adaptive-interfaces/skills/flexible-typography/{SKILL.md → ENTRY.md} +0 -0
  386. /package/skills/design-library/adaptive-interfaces/skills/information-density/{SKILL.md → ENTRY.md} +0 -0
  387. /package/skills/design-library/adaptive-interfaces/skills/preference-audit/{SKILL.md → ENTRY.md} +0 -0
  388. /package/skills/design-library/adaptive-interfaces/skills/responsive-accessibility/{SKILL.md → ENTRY.md} +0 -0
  389. /package/skills/design-library/adaptive-interfaces/skills/responsive-review/{SKILL.md → ENTRY.md} +0 -0
  390. /package/skills/design-library/adaptive-interfaces/skills/simplified-views/{SKILL.md → ENTRY.md} +0 -0
  391. /package/skills/design-library/adaptive-interfaces/skills/specify/{SKILL.md → ENTRY.md} +0 -0
  392. /package/skills/design-library/adaptive-interfaces/skills/user-preference-respect/{SKILL.md → ENTRY.md} +0 -0
  393. /package/skills/design-library/cognitive-accessibility/skills/adaptive-personalisation/{SKILL.md → ENTRY.md} +0 -0
  394. /package/skills/design-library/cognitive-accessibility/skills/assess-load/{SKILL.md → ENTRY.md} +0 -0
  395. /package/skills/design-library/cognitive-accessibility/skills/cognitive-load-assessment/{SKILL.md → ENTRY.md} +0 -0
  396. /package/skills/design-library/cognitive-accessibility/skills/contextual-help-design/{SKILL.md → ENTRY.md} +0 -0
  397. /package/skills/design-library/cognitive-accessibility/skills/error-prevention-recovery/{SKILL.md → ENTRY.md} +0 -0
  398. /package/skills/design-library/cognitive-accessibility/skills/focus-attention-design/{SKILL.md → ENTRY.md} +0 -0
  399. /package/skills/design-library/cognitive-accessibility/skills/memory-load-reduction/{SKILL.md → ENTRY.md} +0 -0
  400. /package/skills/design-library/cognitive-accessibility/skills/plain-language-design/{SKILL.md → ENTRY.md} +0 -0
  401. /package/skills/design-library/cognitive-accessibility/skills/review/{SKILL.md → ENTRY.md} +0 -0
  402. /package/skills/design-library/cognitive-accessibility/skills/simplify/{SKILL.md → ENTRY.md} +0 -0
  403. /package/skills/design-library/cognitive-accessibility/skills/wayfinding-navigation/{SKILL.md → ENTRY.md} +0 -0
  404. /package/skills/design-library/design-research/skills/behavioural-analytics/{SKILL.md → ENTRY.md} +0 -0
  405. /package/skills/design-library/design-research/skills/qual-quant-triangulation/{SKILL.md → ENTRY.md} +0 -0
  406. /package/skills/design-library/inclusive-interaction/skills/audit/{SKILL.md → ENTRY.md} +0 -0
  407. /package/skills/design-library/inclusive-interaction/skills/design-flow/{SKILL.md → ENTRY.md} +0 -0
  408. /package/skills/design-library/inclusive-interaction/skills/feedback-and-status/{SKILL.md → ENTRY.md} +0 -0
  409. /package/skills/design-library/inclusive-interaction/skills/gesture-alternatives/{SKILL.md → ENTRY.md} +0 -0
  410. /package/skills/design-library/inclusive-interaction/skills/keyboard-navigation/{SKILL.md → ENTRY.md} +0 -0
  411. /package/skills/design-library/inclusive-interaction/skills/keyboard-review/{SKILL.md → ENTRY.md} +0 -0
  412. /package/skills/design-library/inclusive-interaction/skills/motion-sensitivity/{SKILL.md → ENTRY.md} +0 -0
  413. /package/skills/design-library/inclusive-interaction/skills/multi-modal-input/{SKILL.md → ENTRY.md} +0 -0
  414. /package/skills/design-library/inclusive-interaction/skills/touch-target-design/{SKILL.md → ENTRY.md} +0 -0
  415. /package/skills/design-library/inclusive-interaction/skills/voice-interaction/{SKILL.md → ENTRY.md} +0 -0
  416. /package/skills/design-library/visual-critique/skills/critique-affordance/{SKILL.md → ENTRY.md} +0 -0
  417. /package/skills/design-library/visual-critique/skills/critique-brand-consistency/{SKILL.md → ENTRY.md} +0 -0
  418. /package/skills/design-library/visual-critique/skills/critique-color/{SKILL.md → ENTRY.md} +0 -0
  419. /package/skills/design-library/visual-critique/skills/critique-composition/{SKILL.md → ENTRY.md} +0 -0
  420. /package/skills/design-library/visual-critique/skills/critique-information-density/{SKILL.md → ENTRY.md} +0 -0
  421. /package/skills/design-library/visual-critique/skills/critique-typography/{SKILL.md → ENTRY.md} +0 -0
  422. /package/skills/design-library/visual-critique/skills/critique-visual-hierarchy/{SKILL.md → ENTRY.md} +0 -0
  423. /package/skills/pm-frameworks/intended-vs-implemented/{SKILL.md → ENTRY.md} +0 -0
  424. /package/skills/pm-frameworks/opportunity-solution-tree/{SKILL.md → ENTRY.md} +0 -0
  425. /package/skills/rl-env/generate-nemo-gym-env/{SKILL.md → ENTRY.md} +0 -0
  426. /package/skills/rl-env/generate-openenv-env/{SKILL.md → ENTRY.md} +0 -0
  427. /package/skills/rl-env/generate-ors-env/{SKILL.md → ENTRY.md} +0 -0
  428. /package/skills/rl-env/generate-verifiers-env/{SKILL.md → ENTRY.md} +0 -0
  429. /package/skills/rl-env/rl-env-from-description/{SKILL.md → ENTRY.md} +0 -0
@@ -0,0 +1,202 @@
1
+ # Patterns
2
+
3
+ The parts every page repeats, written to pass the gates. Take the code's shape; the names, copy, values and composition are yours. `tokens.css`, `base.css` and the slot script come from the scaffold.
4
+
5
+ ## Controls, all eight states
6
+
7
+ ```css
8
+ .btn { display: inline-flex; align-items: center; gap: var(--space-xs); min-height: 48px; padding: 0 var(--space-lg); border: 1px solid var(--color-ink); border-radius: var(--radius-input, var(--radius-pill)); background: var(--color-ink); color: var(--color-paper); font: 500 var(--text-md)/1 var(--font-body); white-space: nowrap; text-decoration: none; cursor: pointer; transition: background-color var(--dur-short) var(--ease-out), transform var(--dur-micro) var(--ease-out); }
9
+ .btn:hover { background: var(--color-ink-2); }
10
+ .btn:active { transform: translateY(1px); }
11
+ .btn:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
12
+ .btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: not-allowed; transform: none; }
13
+ .btn[aria-busy="true"] { cursor: progress; }
14
+ .btn--quiet { background: transparent; color: var(--color-ink); border-color: var(--color-rule); }
15
+ .btn--quiet:hover { background: var(--color-paper-2); }
16
+ @media (prefers-reduced-motion: reduce) { .btn { transition: background-color var(--dur-short) linear; } }
17
+ ```
18
+
19
+ One filled primary a page (F4); the quiet one goes somewhere else. Error and success belong to the form, below.
20
+
21
+ ## A photograph in a slot
22
+
23
+ ```html
24
+ <figure class="photo" data-slot="hero" data-alt="The orchard in October, rows of trees heavy with fruit">
25
+ <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/.../1280px-....jpg"
26
+ srcset=".../960px-....jpg 960w, .../1280px-....jpg 1280w, .../1920px-....jpg 1920w" sizes="(min-width: 60rem) 45vw, 100vw"
27
+ width="4000" height="5000" alt="Rows of apple trees in October light" style="object-position: 50% 40%" fetchpriority="high">
28
+ </figure>
29
+ <p class="caption">Picking runs from September to the first frost.</p>
30
+ ```
31
+
32
+ ```css
33
+ .photo { aspect-ratio: 4 / 5; min-height: 440px; margin: 0; border-radius: var(--radius-card); }
34
+ .photo > img { outline: 1px solid color-mix(in oklab, var(--color-ink) 8%, transparent); outline-offset: -1px; }
35
+ .caption { margin-top: var(--space-sm); font-size: var(--text-sm); color: var(--color-ink-2); }
36
+ ```
37
+
38
+ The `<img>` comes from `theme.mjs photos`; `base.css` supplies the cover fit, the loading wash and the theme's treatment. The credit goes in the footer's *Photographs* line; the caption is a fact from the prompt, outside the frame. A product sample takes the same kind of slot with no `<img>`: the interface built at full size (`imagery.md` § 4).
39
+
40
+ ## A choice between a few
41
+
42
+ ```html
43
+ <fieldset class="seg"><legend>Size</legend>
44
+ <input type="radio" name="size" id="s1" value="1" checked><label for="s1">One box</label>
45
+ <input type="radio" name="size" id="s2" value="2"><label for="s2">Two boxes</label>
46
+ </fieldset>
47
+ ```
48
+
49
+ ```css
50
+ .seg input { position: absolute; opacity: 0; width: 1px; height: 1px; }
51
+ .seg label { display: inline-flex; align-items: center; min-height: 44px; padding: 0 var(--space-md); border: 1px solid var(--color-rule); cursor: pointer; }
52
+ .seg input:checked + label { background: var(--color-ink); color: var(--color-paper); }
53
+ .seg input:focus-visible + label { outline: 2px solid var(--color-focus); outline-offset: 2px; }
54
+ ```
55
+
56
+ The radios stay in the flow at one pixel (53); the label carries the state and the ring, in the body face, sentence case.
57
+
58
+ ## A rail and a switcher
59
+
60
+ ```html
61
+ <ul class="rail" tabindex="0" aria-label="Upcoming dates">
62
+ <li><time datetime="2027-06-12">12 June</time> Whitby</li>
63
+ <!-- five or more items; the next one cut by the edge -->
64
+ </ul>
65
+ <div class="switch" data-switch>
66
+ <div class="seg" role="tablist" aria-label="Menu"><button role="tab" aria-selected="true" aria-controls="m1" id="t1">Lunch</button><button role="tab" aria-selected="false" aria-controls="m2" id="t2" tabindex="-1">Dinner</button></div>
67
+ <section role="tabpanel" id="m1" aria-labelledby="t1">...</section>
68
+ <section role="tabpanel" id="m2" aria-labelledby="t2" hidden>...</section>
69
+ </div>
70
+ ```
71
+
72
+ ```css
73
+ .rail { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(16rem, 22%); gap: var(--gap-columns); overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: var(--gutter); padding-inline: var(--gutter); overscroll-behavior-x: contain; }
74
+ .rail > * { scroll-snap-align: start; }
75
+ .rail:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 4px; }
76
+ ```
77
+
78
+ The rail scrolls by touch, wheel and arrow keys once focused, and sits outside the container's padding so its edge cuts the next item. The switcher's tabs move with the arrow keys (a few lines of script set `aria-selected`, `tabindex` and `hidden`); without script every panel shows in order. A pinned pair is `position: sticky; top: var(--space-2xl)` on the visual's column, released under 60rem.
79
+
80
+ ## A fact the prompt did not give
81
+
82
+ ```html
83
+ <p>Doors at <span class="fill" data-fill="time">time to be announced</span>, at <a href="#venue">the venue</a>.</p>
84
+ ```
85
+
86
+ ```css
87
+ .fill { padding: 0 0.25em; border: 1px dashed color-mix(in oklch, var(--color-muted) 70%, transparent); border-radius: 3px; color: var(--color-muted); -webkit-box-decoration-break: clone; box-decoration-break: clone; }
88
+ ```
89
+
90
+ Two a page at most, each named in the handoff (`craft.md` § 8).
91
+
92
+ ## A form that posts nowhere yet
93
+
94
+ ```html
95
+ <form class="signup" data-endpoint="" novalidate>
96
+ <label for="email">Email address</label>
97
+ <div class="signup__row">
98
+ <input id="email" name="email" type="email" autocomplete="email" required>
99
+ <button class="btn" type="submit">Send me the date</button>
100
+ </div>
101
+ <p class="signup__help" id="email-help" aria-live="polite"></p>
102
+ </form>
103
+ ```
104
+
105
+ ```js
106
+ document.querySelectorAll('form[data-endpoint]').forEach((form) => {
107
+ const input = form.querySelector('input'), help = form.querySelector('[aria-live]');
108
+ form.addEventListener('submit', (e) => {
109
+ e.preventDefault();
110
+ const ok = input.checkValidity();
111
+ input.toggleAttribute('aria-invalid', !ok);
112
+ if (!ok) { input.setAttribute('aria-describedby', help.id); help.textContent = 'That address looks incomplete. Write it as name@example.com.'; input.focus(); return; }
113
+ if (!form.dataset.endpoint) { help.textContent = 'Nothing was sent: this form is not connected yet.'; return; }
114
+ fetch(form.dataset.endpoint, { method: 'POST', body: new FormData(form) })
115
+ .then((r) => { help.textContent = r.ok ? 'Thanks. The date goes to ' + input.value.trim() + '.' : 'That did not go through. Try again in a minute.'; })
116
+ .catch(() => { help.textContent = 'That did not go through. Try again in a minute.'; });
117
+ });
118
+ });
119
+ ```
120
+
121
+ ```css
122
+ .signup__row { display: flex; gap: var(--space-xs); }
123
+ .signup input { flex: 1; min-width: 0; min-height: 48px; padding: 0 var(--space-md); border: 1px solid var(--color-muted); border-radius: var(--radius-input, var(--radius-pill)); background: var(--color-paper); color: var(--color-ink); outline: 2px solid transparent; outline-offset: -3px; }
124
+ .signup input:focus-visible { outline-color: var(--color-focus); }
125
+ .signup input[aria-invalid] { border-color: var(--color-error); }
126
+ .signup__help { min-height: 1lh; margin-top: var(--space-2xs); font-size: var(--text-sm); color: var(--color-muted); }
127
+ ```
128
+
129
+ ## One reveal that survives no script
130
+
131
+ ```html
132
+ <script>document.documentElement.classList.add('js');</script>
133
+ ```
134
+
135
+ ```css
136
+ .js [data-reveal] { opacity: 0; transform: translateY(8px); transition: opacity var(--dur-long) var(--ease-out), transform var(--dur-long) var(--ease-out); transition-delay: calc(var(--i, 0) * 40ms); }
137
+ .js [data-reveal].is-in { opacity: 1; transform: none; }
138
+ @media (prefers-reduced-motion: reduce) { .js [data-reveal] { opacity: 1; transform: none; transition: none; } }
139
+ ```
140
+
141
+ ```js
142
+ const io = new IntersectionObserver((es) => es.forEach((e) => { if (e.isIntersecting) { e.target.classList.add('is-in'); io.unobserve(e.target); } }), { rootMargin: '0px 0px -10% 0px' });
143
+ document.querySelectorAll('[data-reveal]').forEach((el) => io.observe(el));
144
+ ```
145
+
146
+ Visible with scripting off (62), at its end state under reduced motion, once, and only where the theme lets something move.
147
+
148
+ ## Figures that compare
149
+
150
+ ```css
151
+ .stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
152
+ .stats > * { padding-inline: var(--space-lg); border-left: 1px solid var(--color-rule); }
153
+ .stats > :first-child { padding-left: 0; border-left: 0; }
154
+ .stats b { display: block; font: 600 var(--text-3xl)/1 var(--font-display); font-variant-numeric: tabular-nums; }
155
+ @media (max-width: 60rem) { .stats { grid-template-columns: minmax(0, 1fr); } .stats > * { padding: var(--space-md) 0; border-left: 0; border-top: 1px solid var(--color-rule); } .stats > :first-child { border-top: 0; } }
156
+ ```
157
+
158
+ Only figures the user gave (46a), each with its unit and what it counts.
159
+
160
+ ## A loop that can pause
161
+
162
+ Anything moving past 5 seconds (a marquee, an ambient loop, a looping video) holds still until the script runs, stops off-screen and under reduced motion, pauses on hover and focus, and carries a visible pause control (18, WCAG 2.2.2).
163
+
164
+ ```html
165
+ <figure data-loop>
166
+ <!-- the drawing, the loop or the video -->
167
+ <button class="btn btn--quiet" type="button" data-loop-toggle>Pause</button>
168
+ </figure>
169
+ ```
170
+
171
+ ```css
172
+ [data-loop]:not(.is-running), [data-loop]:not(.is-running) *, [data-loop]:not(.is-running) *::before, [data-loop]:not(.is-running) *::after { animation-play-state: paused !important; }
173
+ html:not(.js) [data-loop-toggle] { display: none; }
174
+ @media (prefers-reduced-motion: reduce) { [data-loop-toggle] { display: none; } }
175
+ ```
176
+
177
+ ```js
178
+ document.querySelectorAll('[data-loop]').forEach((el) => {
179
+ const btn = el.querySelector('[data-loop-toggle]');
180
+ const s = { seen: false, hover: false, focus: false, held: matchMedia('(prefers-reduced-motion: reduce)').matches };
181
+ const sync = () => {
182
+ const run = s.seen && !s.hover && !s.focus && !s.held;
183
+ el.classList.toggle('is-running', run);
184
+ el.querySelectorAll('video').forEach((v) => (run ? v.play().catch(() => {}) : v.pause()));
185
+ btn.textContent = s.held ? 'Play' : 'Pause';
186
+ };
187
+ btn.addEventListener('click', () => { s.held = !s.held; sync(); });
188
+ [['pointerenter', 'hover', true], ['pointerleave', 'hover', false], ['focusin', 'focus', true], ['focusout', 'focus', false]].forEach(([t, k, v]) => el.addEventListener(t, () => { s[k] = v; sync(); }));
189
+ new IntersectionObserver(([e]) => { s.seen = e.isIntersecting; sync(); }).observe(el);
190
+ });
191
+ ```
192
+
193
+ ## A way past the nav
194
+
195
+ ```html
196
+ <a class="skip" href="#main">Skip to content</a>
197
+ ```
198
+
199
+ ```css
200
+ .skip { position: absolute; left: var(--space-md); top: calc(-1 * var(--space-3xl)); z-index: var(--z-toast); padding: var(--space-xs) var(--space-md); background: var(--color-ink); color: var(--color-paper); }
201
+ .skip:focus-visible { top: var(--space-md); }
202
+ ```
@@ -0,0 +1,88 @@
1
+ # Redesign
2
+
3
+ Loaded only when the user names Hallmark with `redesign` or `audit` (`/hallmark redesign <target>`, *redesign the site with Hallmark*). A request that changes an existing design without naming Hallmark (a restyle, new colours or a new theme, a polish, a redesign, a small edit) never loads this file: it is done as asked, in the project's own system. A redesign is a build whose material is the page that exists: SKILL.md still binds, and this file says what the run keeps, what replaces the Step 1 ask and what the sweep adds. The target is the user's own code (a file, a folder, a route on a dev server); a live URL with no source behind it can only be audited, through `--url`.
4
+
5
+ ## What a redesign keeps
6
+
7
+ - **The content.** Every fact, claim, name, price, date and quote the page states. Figures, quotes and logos already there are the user's material: carried over as found and listed in the handoff to verify, one a gate doubts (a trend nobody measured, 46a) included. Nothing is added: no action, section, claim or picture the page did not have, beyond what the user hands over and what a gate requires (a pause on a loop, 18; a focus ring). A drawing made from the page's own facts (its channels, its steps, a figure) is composition, and full depth may make one.
8
+ - **The wiring.** Every link, form, field, handler, route, id and test hook; every script, data call and analytics call. Edit markup inside the component that owns it. Never move logic, rename a prop, or drop a `name`, an `id`, a `key`, a `type`, an `href` or a `data-testid` that a script or a test reads. A prop the Floor empties (an emoji passed as an icon) may go with it, named in the handoff. A state the screen has no logic for (a failed load, an undo) is listed for the owner, never built.
9
+ - **The files.** No file deleted, no route removed and no component tree replaced without a file-level plan the user approved, and no test edited to make the redesign pass. Documents in the repo (a README, a prompt, a deck) explain the product; they are not page copy. In a git project, start from a clean tree, `.hallmark/` aside (ask the user to commit or stash; never do it for them), so the redesign is one diff they can read and revert. The stylesheet is the redesign's to edit: the append-only rule guards it from a build, not from its own redesign.
10
+ - **The brand,** when there is one. A brand is chosen: a logo, a colour or a face the project names (a brand file, a logo asset, named tokens, a font file of its own) or the user states. It stays at every depth, its values read from the project's files, never from memory. A framework default or a look the gates name (the purple-to-blue gradient, Inter as the display, a stock swatch) is not a brand: restyle and full replace it, and the Picks block says so in case it was. A locked `design.md` is the system at every depth.
11
+ - **The words,** unless a gate names them. Wording that fails a copy gate (19, 54, 58, 63, 69) is tightened from the facts already on the page, and the handoff lists every changed line, before and after. An eyebrow is never just deleted: where its heading is figurative, the plain label becomes the heading (*Opening hours* over *When to find us* becomes *Opening hours*). Terms, disclaimers and consent text are never reworded. When the user says to keep every word, stamp `copy: verbatim`: 19, 58 and 69 then report as notes.
12
+
13
+ ## Depth
14
+
15
+ The verb is a **full** redesign: the content and the wiring stay, the system and the composition change. A lighter depth runs only when the same request asks for it in so many words, and the Picks block names the depth:
16
+
17
+ | Depth | Stays | Changes | Only when the request says |
18
+ | --- | --- | --- | --- |
19
+ | **full** | the content and the wiring | the system and the composition: shape, hero, section objects, chrome | nothing else: it is the verb |
20
+ | **restyle** | the layout | the system: colour, type, radius, shadow, motion, the controls | *keep the layout*, *restyle*, *reskin*, *only the colours and type* |
21
+ | **polish** | the system and the layout | only what a gate names: the tells, contrast, states, motion, tokens | *polish*, *keep our look*, *only fix what looks generated* |
22
+
23
+ The depths do not blend: a polish that finds the concept wrong says so and recommends the full run, it never smuggles one in.
24
+
25
+ **Full depth on an app screen** recomposes each screen inside the shell it has: what leads, and how the figures, tables and forms are arranged (`flow.md` § App screens). Routes, destinations and each component's logic stay; there is no hero stage and no hero review.
26
+
27
+ *From scratch* is a build, not a depth: SKILL.md as written, the old page as its Step 2 inventory, in new files beside the old ones.
28
+
29
+ ## Before
30
+
31
+ 1. Run the pre-flight (Step 0), then list the pages in the target: route, file, and whether each is a page or an app screen (`flow.md` § App screens). In a framework project start the dev server and record through `--url`; the linter does not render the empty shell `index.html` from disk. An unstamped page has no genre: infer it from the page as Step 1 would from a prompt, and say so.
32
+ 2. Record the page as it stands:
33
+
34
+ ```
35
+ node <skill-dir>/scripts/sloplint.mjs <target> --genre <genre> --render --before [--url <route> ...] [--scope app]
36
+ ```
37
+
38
+ It prints the findings grouped by gate and writes them to `.hallmark/before.txt`, the screenshots to `.hallmark/before/` and the record to `.hallmark/before.json`: every link, form, field, inline handler, test hook, script tag, selector a script queries, heading and figure. Git ignores the folder's screenshots and records.
39
+
40
+ 3. Look at the screenshots before you weigh the findings, so the linter does not write the verdict, then give the read in four lines: what the page is for (the audience, the one action); what works and stays (at least one thing); what reads as generated (the worst tells, by gate); what is broken.
41
+
42
+ **`audit <target>` stops here.** It loads `gates.md` § 1, § 4 and § 5, walks the judged gates from the screenshots, and reports the findings by tier with `file:line`, the read, the lightest depth that settles them and what only a deeper one would. It changes none of the project's files.
43
+
44
+ ## The ask
45
+
46
+ One message replaces the Step 1 ask; skip it when the request already answers it or no one can answer:
47
+
48
+ > *Before I redesign, three things. 1. **What must stay**: the brand, a section, a page? Say *keep the layout* and I only restyle. 2. **What is wrong with it**, in your words, and the feeling you want instead. 3. **Anything new to show**: screenshots, photos, numbers, a quote. Or say **go ahead** and I will redesign it in full.*
49
+
50
+ ## The plan
51
+
52
+ The Picks block opens with four rows of its own, and nothing is deleted until the user has seen the Files row:
53
+
54
+ ```markdown
55
+ - **Redesign** · full · 3 pages (/, /pricing, /docs)
56
+ - **Before** · Floor 14 FAIL · Reflex 9 · a centred template in a stock indigo; the pricing table is clear and stays
57
+ - **Keeps** · every link, field and handler · the green and the brand face · the pricing table
58
+ - **Files** · edit: app/page.tsx, app/pricing/page.tsx, app/globals.css · create: app/tokens.css, app/base.css · delete: none
59
+ ```
60
+
61
+ Then the build rows the depth reaches: Theme at restyle and full (dealt, `brand` or locked); Shape, Chrome, Hero, Signature and Sections at full only, where Step 2 runs with the page's own content as its inventory. At polish the block stops after Files. The deal's `--prompt` is the read's first line (what the page is for, in plain nouns), never the page's own copy, which is what the redesign is leaving behind.
62
+
63
+ ## Build
64
+
65
+ - **Polish** is `flow.md` § The sweep, on the user's own page: fix in place, single elements and tokens, never restructure, under the check stamp with `built: the project · redesign: polish`. It loads `gates.md` § 1 to § 5 and `patterns.md`, `interaction-and-states.md` when the page has a form, the theme file an old stamp names, and from `craft.md` only the section a finding points at.
66
+ - **Where the layout stays** (polish and restyle), the stamp's `redesign:` field tells sloplint to report the layout gates (6b, 8, 9, 32, 42, 44a, 44c, 58, 77, 79) as notes; at polish the spacing and scale gates (24b, 59, 78) too, so a polish does not re-space a site it was asked to keep. Print them for the user with the depth that would settle them; do not rebuild them. At every depth 58 (the screen budget) is a note too: the words are the owner's, and only a copy gate cuts one. In app scope those gates are skipped, so the handoff's Layout row comes from the read and the review. A theme's own composition rules (its do-nots, the dials that vary between pages) yield to a kept layout: the theme lends its system, and every page takes one dial set.
67
+ - **Restyle and full** start from the scaffold, with the depth in the stamp: `theme.mjs scaffold <slug> --redesign <depth>`, or `scaffold --brand --redesign <depth>` for a kept brand, its tokens filled from the palette and faces the pre-flight found (no `check`: the coordinates are the user's); add `--scope app` for app screens. It writes `tokens.css` and `base.css` beside the project's stylesheet and prints the imports that fit it (`export-formats.md` has the Tailwind and shadcn names). Then the shared components and the chrome, then the pages, the most visited first, each swept before the next.
68
+ - **More than one page** at restyle or full: lock the system once the scaffold has run (`design-md.md`). Every page reads it and the variety rule inverts: pages share theme, type and accent, and differ only in shape. One stylesheet for several pages lists a hero posture per route, `hero: Settled (/), Stage (/contact)`. Past three pages, give each page to its own subagent where the harness has them, with `design.md`, the page's files and this file.
69
+ - **Full depth** runs the hero stage and the hero review; polish and restyle skip both. The old sections still sit below the new hero at that stage: the stage judges the first screen alone, and what it reports below the fold waits for the sweep. Gate 8 judges the composition, not the order of the content: a kept sequence in a new composition is waived on the record.
70
+
71
+ ## After
72
+
73
+ 1. The sweep, against the record: `sloplint <target> --genre <genre> --render --kept`. Anything the page had and no longer has is a `FAIL kept` (a link, a form, a field, a handler, a test hook, a script, a selector a script still queries) or a `WARN kept` (a heading, a figure, an image, an id). Restore it, or put it on the record in the stamp: `/* Hallmark · dropped /blog, #team · the user is retiring the blog and the team section */`, or for a line a copy gate named, `/* Hallmark · reworded "Built for modern teams" to "Out of your way" · 19 names the opener */`, or `dropped "<the line>" · 69 names it` for a line a gate cuts whole. The run also writes `.hallmark/compare.html`, the before and after screenshots side by side: give the user its path.
74
+ 2. The project's own checks, where it has them: the type check, the build, the tests. A redesign that breaks one is not finished.
75
+ 3. The finish review also takes the `before` screenshots and answers what the old page did better (`review-finish.md`). A polish hands it only the full pages at 1440, before and after, and takes at most five findings. A finding that is a plain defect (a misalignment, a broken glyph, a label that lies) is fixed at any depth; one that asks for a new composition joins the layout findings; one that asks for content the page never had goes to the owner in the handoff.
76
+ 4. The log entry carries `mode: redesign`, `depth` and `scope` (page, site or app), plus the build's fields at full depth.
77
+ 5. The handoff, ahead of the material ask; where the layout stayed it adds a Layout row (the findings only a full redesign would settle):
78
+
79
+ ```
80
+ Redesign · full · 3 pages
81
+ Before Floor 14 FAIL · Reflex 9
82
+ After Floor 0 · Reflex 1 waived (47b)
83
+ Kept 14/14 links · 5/5 fields · 9/9 handlers · 11/11 headings · every figure
84
+ Changed the system and the composition: shape, hero, sections, chrome
85
+ Dropped none
86
+ Yours 2 claims kept as found ("50,000+ teams", the Acme quote) · 4 lines reworded, listed below
87
+ Compare .hallmark/compare.html
88
+ ```
@@ -0,0 +1,46 @@
1
+ # Responsive
2
+
3
+ Loaded for an unusual layout. No desktop-only interactions; every page renders without fault from 320 to 1920 CSS pixels.
4
+
5
+ ## What the script checks and what it cannot
6
+
7
+ sloplint covers the mechanical half at 320, 375, 414, 768, 1024, 1280, 1440 and 1920: horizontal scroll and `overflow-x: clip` (34), wrapping controls (49), image tracks and display heads (50), radio tabs (53), stacked sticky elements (56). Check by eye at each width what it cannot see: every desktop sidebar or filter column collapses into a menu or a disclosure, section heads stack to one column, and a per-theme override carries its own mobile rule.
8
+
9
+ ## Breakpoints
10
+
11
+ Two, shared by the whole page, in `rem` so they follow the user's font size. The scaffold steps its tokens down at both: under 60rem (about 960px, the layout breakpoint) gutters drop to 24px and the three section gaps to 80, 96 and 120px; under 40rem (about 640px, the type breakpoint) gutters drop to 16px, the section gaps to 56, 72 and 96px, and column gaps to 16px. Write component rules against the same two widths, in one direction for the whole page. Add a third only where the content itself breaks.
12
+
13
+ - **Under 60rem:** multi-column grids go to one column, tilts and clip effects drop, sticky panes unstick, every hero posture collapses to content height (Poster may stay full-bleed).
14
+ - **Under 40rem:** display sizes step down, margin captions move inline, annotations consolidate.
15
+
16
+ ## Fluid and discrete
17
+
18
+ `clamp()` for sizes that change continuously (the scale's display tokens already do); media queries for layouts that change discretely. Detect capability with `@media (hover: hover)` and `(pointer: coarse)`, never with width:
19
+
20
+ ```css
21
+ @media (hover: hover) { .link:hover { text-decoration-thickness: 2px; } }
22
+ @media (pointer: coarse) { .btn { min-height: 48px; } }
23
+ ```
24
+
25
+ Body-adjacent UI (meta, nav links, controls) runs larger on a phone and tightens at 60rem (`craft.md` § 9).
26
+
27
+ ## Clickable text never wraps
28
+
29
+ Buttons, primary nav links and CTAs are single-line at every width from 320 to 1920 (49a); footer links, tabs and breadcrumbs too unless a real phrase cannot shorten (49b). When one wraps, in this order:
30
+
31
+ 1. **Shorten the label.** *Get started free* to *Start free*; *Read the documentation* to *Read the docs*.
32
+ 2. **`white-space: nowrap`** on the control, and let the row around it reflow.
33
+ 3. **Collapse the row**, not the labels: under 60rem the links that no longer fit go behind a menu, while two or three short ones that fit stay in the bar.
34
+
35
+ ## Units and safe areas
36
+
37
+ - `dvh` or `svh` for heights that meet mobile browser chrome, never `vh` on a hero (6a); `width: 100%`, never `100vw` (34).
38
+ - With `viewport-fit=cover`, fold the safe area into the gutter token: `--gutter: max(16px, env(safe-area-inset-left))`.
39
+
40
+ ## Tables, images, languages
41
+
42
+ - **Tables** on a phone keep the column that names the row and the one that acts on it in view: restack each row as a labelled block, or pin the first column (`craft.md` § 9, F25). Ten columns on a phone is a redesign, not a squeeze.
43
+ - **Images:** `srcset` with width descriptors, `<picture>` for a different crop, `width` and `height` attributes on every image, `loading="lazy"` below the fold and never on the LCP element.
44
+ - **Languages:** logical properties (`margin-inline-start`, `padding-block`), room for 30 to 40% longer strings, no hard-coded date or number formats.
45
+
46
+ Never: device sniffing instead of feature queries, hover-only interactions, breakpoints in `px`.
@@ -0,0 +1,19 @@
1
+ # Finish review
2
+
3
+ You are reviewing a built page against a fixed list. You did not build it and will not be told why anything is the way it is. Read the page, not the intent. Your inputs, and nothing else: the screenshots the render tier wrote (the folds at 1280 x 800, 1440 x 900 and 1920 x 1080, the full page at 1440 and at 375), the page's HTML or component source, the theme or idea line from the stamp, on a theme build the theme file and its picture, the hero review's findings with how each was settled, and `gates.md` § 4. Look at the screenshots first; open the HTML only to quote copy or to locate a finding; the linter has already read the CSS. A pinned pane shows once in a full-page shot: the column beside its later screens is the pin, not an empty half. Batch your reads; stop reading by the tenth turn and write.
4
+
5
+ First line: one of `recapture` (a screenshot is missing, blank or shows the wrong thing; list what to recapture and stop), `rebuild` (the first viewport fails the idea or the theme wholesale), `fix` (findings follow), `ship` (nothing owed).
6
+
7
+ Then the findings, ranked by cost to the page, at most eight, one line each: the gate or the plain defect, where it is, what you would do. Not findings: a direction you would not have chosen; what the theme file prescribes or refuses (its blooms, a glow on a theme with none); an element the hero review settled, unless you name a new reason. The theme's picture is the bar for finish and never a model: is this page as finished as that one, in a composition of its own?
8
+
9
+ Scroll the 1440 full page one screen at a time before ranking: a screen with nothing big enough to be its reason (a head and a line adrift, a narrow column beside an empty half, a section head under 40px, an empty coloured box or a drawn illustration where a photograph or the product should be, a row of counting marks) outranks every detail finding (`layout.md` § 8). Then the copy: name any head that would pass unchanged on a competitor's page (`craft.md` § 6).
10
+
11
+ Then one answer to the question no gate can: does the stamp's idea or theme describe the page in front of you? Name the largest gap, or say there is none.
12
+
13
+ On a custom run (`theme: custom`) the page owes no shape, composition or hero layout: it was designed from nothing, so judge it as a design, never against `layout.md`. Before the idea line, write two lines of your own from the screenshots: what the page is about, and the one thing a visitor would remember. Then three findings when they fail. **Seen before:** the page, or a section, reads as a template, a catalog theme or a familiar site; name which and where. **Clean:** something is on the page without a job (a device repeated, a decoration, a box around nothing), or a screen has nothing worth looking at. **Carried:** the idea lives in the hero and stops there.
14
+
15
+ On a redesign you also get the `before` screenshots, and the content is fixed: never ask for copy, an action or a visual the old page did not have. Add one answer: what did the old page do better? Name anything a visitor could do, read or find before that is harder now; if nothing, say so. On a polish you get only the full pages at 1440, before and after: the layout was kept on purpose, so ask one thing, whether anything still reads as machine-made, in at most five findings.
16
+
17
+ On an app screen (the stamp says `shape: app screen`) there is no hero, fold or section rhythm to judge, and the gates `flow.md` § App screens skips are not findings. Read the full screens at 1440 and 375 and ask what someone fluent in the category would: is the hierarchy clear, is the density even, does every control and table work on a phone, are the states there.
18
+
19
+ Close with one line naming what must not be diluted while fixing. Where the theme file and its picture disagree, the theme file wins over its picture. Do not fix anything.
@@ -0,0 +1,20 @@
1
+ # Hero review
2
+
3
+ You are reviewing the first screen of a page that is still being built. You did not build it and will not be told why anything is the way it is. Your inputs, and nothing else: the four `hero-*` screenshots, the stamp's first two lines, the Picks block's Material and Signature rows, and on a theme build the theme's picture. Batch your reads; stop reading by the tenth turn and write.
4
+
5
+ First line: `ship` or `fix`.
6
+
7
+ Then at most five findings, one line each, worst first. Ask:
8
+
9
+ - Does the headline say something only this product could say, in seven words or fewer?
10
+ - Is the content centred in the screen, or does it stop early over a band of nothing? Is the visual beside the text, a real picture (the user's, a photograph, the product built), and does it hold its half of the screen at 60% of its height or more? Where the shape puts no image in the fold (a Marquee, a Poster or a Banner hero), the type is the visual: does it fill the screen? At 1920 the container and the type hold their 1440 size by rule, so extra air there is not a finding.
11
+ - Does anything read as a template: a centred stack, a pill or a label above the headline, a gradient blob, an empty coloured box where a picture should be, a drawn illustration, a row of counting marks, two filled buttons side by side? A filled primary beside an outlined or text action that goes somewhere else is the control pair, and a sample of the product built in a slot is the product; neither is a finding. Grey bars or outline cards inside a slot are.
12
+ - Is the page's signature, its strongest real thing, on this screen? Delete the picture in your head: if the screen still says the same thing, the picture is too weak or too small.
13
+ - Does the type carry the theme at this size?
14
+ - With the theme's picture: is this first screen as finished as its first screen, in a composition of its own?
15
+
16
+ On a custom run (`theme: custom`) the composition is free: skip the centred, beside-the-text and 60% questions, and ask instead whether this screen is one you would expect a model to make for this prompt. If it is, say what gives it away.
17
+
18
+ On a redesign the page's content is fixed and what sits below the first screen is the old page, not yet rebuilt: neither is a finding. Never ask for copy, an action or a visual the page does not have; say in one line what the owner could supply.
19
+
20
+ What the theme file prescribes (its blooms, its control pair) or refuses is not a finding. Where the theme file and its picture disagree, the theme file wins over its picture. Do not fix anything.
@@ -0,0 +1,110 @@
1
+ # Scroll choreography: the one earned pattern
2
+
3
+ The default is still none: the reveal-once in `craft.md` § 5 is the page norm. This file is the exception: a scroll-linked pattern used once, on structure, when the content has a sequence worth pinning or scrubbing. sloplint's F8 counts pattern families and flags a second one.
4
+
5
+ ## Budget
6
+
7
+ - **One pattern per page.** Two scroll behaviours compete for the same attention.
8
+ - **Never on body text.** Targets are structural: a pinned section, one display element, a 2px spine, figures. Prose never moves under the reader.
9
+ - **Hero entrance rules unchanged.** The page-load orchestration in `craft.md` § 5 stays as is; scroll choreography never replaces it, and no element carries both.
10
+ - **Static end-state mandatory.** Base CSS shows the finished layout. The choreography lives entirely inside `@supports (animation-timeline: view())` and `@media (prefers-reduced-motion: no-preference) and (min-width: 40rem)`; reduced motion, small screens and browsers without support get the complete page.
11
+ - **Order matters:** the `animation` shorthand resets `animation-timeline` and `animation-range`, so declare them after it.
12
+ - **`linear` is correct here:** scrubbing maps scroll distance to progress one to one; an easing curve detaches the page from the thumb.
13
+ - A pattern counts as one of the page's three motion primitives (`microinteractions.md`).
14
+
15
+ ## 1 · Pinned chapter: steps reveal while the section is pinned
16
+
17
+ The tall track owns a named view-timeline; the pinned pane's steps consume it in slices. (Elements inside a stuck pane cannot drive their own `view()`: they are not moving.)
18
+
19
+ ```html
20
+ <section class="chapter">
21
+ <div class="chapter__pin">
22
+ <h2>How it works</h2>
23
+ <ol class="chapter__steps"><li>…</li><li>…</li><li>…</li></ol>
24
+ </div>
25
+ </section>
26
+ ```
27
+ ```css
28
+ .chapter { min-height: 280vh; } /* track length = pin duration */
29
+ .chapter__pin { position: sticky; top: calc(var(--banner-height, 0px) + var(--space-xl)); }
30
+ @supports (animation-timeline: view()) {
31
+ @media (prefers-reduced-motion: no-preference) and (min-width: 40rem) {
32
+ .chapter { view-timeline: --chapter block; }
33
+ .chapter__steps li { animation: chapter-step linear both; animation-timeline: --chapter; }
34
+ .chapter__steps li:nth-child(1) { animation-range: contain 5% contain 30%; }
35
+ .chapter__steps li:nth-child(2) { animation-range: contain 30% contain 55%; }
36
+ .chapter__steps li:nth-child(3) { animation-range: contain 55% contain 80%; }
37
+ @keyframes chapter-step { from { opacity: 0.2; transform: translateY(8px); } to { opacity: 1; transform: none; } }
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## 2 · Scrub-linked headline: one display element, clip wipe
43
+
44
+ For a mid-page Statement head (`layout.md` § 5), never the hero `h1`, whose entrance is the load reveal. One element a page.
45
+
46
+ ```css
47
+ .statement__head { /* base: fully drawn */ }
48
+ @supports (animation-timeline: view()) {
49
+ @media (prefers-reduced-motion: no-preference) and (min-width: 40rem) {
50
+ .statement__head {
51
+ animation: head-wipe linear both;
52
+ animation-timeline: view();
53
+ animation-range: entry 20% cover 45%;
54
+ }
55
+ @keyframes head-wipe {
56
+ from { clip-path: inset(0 100% 0 0); transform: translateX(-0.25em); }
57
+ to { clip-path: inset(0 0 0 0); transform: none; }
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## 3 · Progress spine: `scroll(root)` scaling a 2px rule
64
+
65
+ Reading progress as a hairline, not a chrome bar. A functional indicator, so `linear` is canon. Hidden below 40rem (it eats the mobile gutter).
66
+
67
+ ```css
68
+ .spine { position: fixed; inset-block: 0; left: max(1rem, 2vw); width: 2px; background: var(--color-rule); }
69
+ .spine::after { content: ""; position: absolute; inset: 0; background: var(--color-accent);
70
+ transform-origin: top; transform: scaleY(0); }
71
+ @media (max-width: 40rem) { .spine { display: none; } }
72
+ @supports (animation-timeline: scroll()) {
73
+ @media (prefers-reduced-motion: no-preference) and (min-width: 40rem) {
74
+ .spine::after { animation: spine-grow linear both; animation-timeline: scroll(root); }
75
+ @keyframes spine-grow { to { transform: scaleY(1); } }
76
+ }
77
+ }
78
+ ```
79
+
80
+ ## 4 · Sticky diptych: a two-pane pin
81
+
82
+ The structure is a Split (`layout.md` § 5) with one side pinned: `.sticky-stack { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--gap-columns); }`, `.pane-sticky { position: sticky; top: calc(var(--banner-height, 0px) + var(--space-xl)); align-self: start; z-index: var(--z-sticky); }` (it docks below a sticky nav, 56), `.pane-scroll { display: grid; gap: var(--space-2xl); }`, each figure at 16:10 and 440px tall or more; under 60rem one column and `position: static`. The choreography adds only this: the scrolling figures fade in on their own `view()` (they move, so self-timelines work); the pinned side holds from one diptych to the next.
83
+
84
+ ```css
85
+ /* base: .sticky-stack grid + .pane-sticky pin, above; the pinned side holds down the page */
86
+ @supports (animation-timeline: view()) {
87
+ @media (prefers-reduced-motion: no-preference) and (min-width: 40rem) {
88
+ .pane-scroll figure { animation: fig-in linear both; animation-timeline: view();
89
+ animation-range: entry 0% entry 60%; }
90
+ @keyframes fig-in { from { opacity: 0.3; transform: translateY(12px); } to { opacity: 1; transform: none; } }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ## JS fallback (optional, shared)
96
+
97
+ When JS is present and `animation-timeline` is not, the one fallback is the reveal-once in `craft.md` § 5, never a scroll listener or a scrub polyfill:
98
+
99
+ ```html
100
+ <script>
101
+ if (!CSS.supports('animation-timeline: view()')) {
102
+ const io = new IntersectionObserver((es) => es.forEach((e) => {
103
+ if (e.isIntersecting) { e.target.classList.add('is-seen'); io.unobserve(e.target); }
104
+ }), { rootMargin: '0px 0px -20%' });
105
+ document.querySelectorAll('[data-reveal]').forEach((el) => io.observe(el));
106
+ }
107
+ </script>
108
+ ```
109
+
110
+ Pair it with a `--dur-long` `--ease-out` transition to the end state, and hide `[data-reveal]` only under the `.js` class the script adds (62). Without script and without support, the static layout is already the finished page.
@@ -0,0 +1,90 @@
1
+ # Texture and print artifacts: a budgeted vocabulary
2
+
3
+ Loaded only when the picked theme earns texture (affinity table below) or a custom draw's lineage is print. Texture is a treatment with a budget, never ambience: one artifact family per page, tokened opacity, never animated, never under body text at more than a whisper. Grain smeared everywhere is the tic `flow.md` § Harnesses refuses; grain from this file, on a theme that earns it, is craft.
4
+
5
+ ## The budget (binds on every artifact)
6
+
7
+ - **One artifact family per page.** Grain, halftone, misregistration, scanline or deckle, never two. A risograph print is one family: its grain and its misregistration come from the same drum. A halftone that is a photograph's treatment belongs to the image, not the page, and does not count.
8
+ - **Tokened opacity, declared in the token block:** `--texture-opacity` <= 0.08 page-wide, <= 0.15 scoped to a card or plate. Under running body text, <= 0.05 or nothing. A low-frequency wash (a base frequency of 0.02 or lower: a fibre, a paper tone) tints rather than specks and may run to 0.12 page-wide, with contrast measured on the result.
9
+ - **Never animated.** No drifting grain, no pulsing dots.
10
+ - **`pointer-events: none` and `aria-hidden="true"`** on every overlay; texture never intercepts input, and the retro signal is atmosphere, never a drawn monitor bezel (47a).
11
+ - **Perf:** pure CSS or a data-URI SVG filter; no image requests for texture.
12
+
13
+ ## 1 · Grain (paper)
14
+
15
+ A speck grain, tokenised:
16
+
17
+ ```css
18
+ :root { --texture-opacity: 0.08; }
19
+ .grained { position: relative; isolation: isolate; }
20
+ .grained::after {
21
+ content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 1;
22
+ background-size: 200px 200px; opacity: var(--texture-opacity);
23
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 9 -4'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
24
+ }
25
+ ```
26
+
27
+ The colour matrix turns the noise into discrete specks (alpha is the noise times nine, minus four), so the grain reads at 1x inside the budget; untreated `feTurbulence` at these opacities is a haze nobody sees. On a dark ground the specks must be light: change the matrix's first three rows to `0 0 0 0 1` so each speck is white, keep the opacity. One plate, one accent card, or the page at 0.08 or less when the theme names grain.
28
+
29
+ ## 2 · Halftone (dot field)
30
+
31
+ A dot screen with a size token:
32
+
33
+ ```css
34
+ :root { --halftone-size: 12px; --halftone-dot: 1.5px; }
35
+ .halftone { background-image: radial-gradient(var(--color-ink) var(--halftone-dot), transparent var(--halftone-dot));
36
+ background-size: var(--halftone-size) var(--halftone-size); }
37
+ ```
38
+
39
+ Plate fills and section bands. Never under or overlapping type. Dot in ink or one spot colour, never the accent at full field strength.
40
+
41
+ ## 3 · Misregistration (chromatic echo)
42
+
43
+ Riso's signature, portable to any print-lineage custom run:
44
+
45
+ ```css
46
+ .misreg { position: relative; display: inline-block; isolation: isolate; }
47
+ .misreg::before, .misreg::after {
48
+ content: attr(data-text); position: absolute; inset: 0; z-index: -1;
49
+ white-space: nowrap; pointer-events: none;
50
+ }
51
+ .misreg::before { color: var(--color-accent); transform: translate(-2px, -2px); }
52
+ .misreg::after { color: var(--color-accent-2, var(--color-focus)); transform: translate(2px, 2px); }
53
+ ```
54
+
55
+ **One focal word per page, in the hero, under the theme's `waive 38iii`; never every heading.** The span is an inline block so the copies sit on the glyphs whatever the head's line-height, and they print behind the ink so the word keeps its colour; only the fringes carry the echoes. The echo colours are the theme's declared spot inks (`--color-accent` and `--color-accent-2` here, or the theme's own echo tokens); the offset stays 1 to 3px (more reads broken, not printed). It may settle once on load over `--dur-long` at most, static under reduced motion; it never loops.
56
+
57
+ ## 4 · Scanline (CRT)
58
+
59
+ Arcade's recipe; the retro signal is atmosphere, never a drawn monitor bezel (47a):
60
+
61
+ ```css
62
+ :root { --scanline: oklch(from var(--color-ink) l c h / 0.06); }
63
+ body::after { content: ""; position: fixed; inset: 0; z-index: var(--z-raised);
64
+ pointer-events: none;
65
+ background: repeating-linear-gradient(transparent 0 2px, var(--scanline) 2px 3px); }
66
+ ```
67
+
68
+ `--scanline` is a page-local decorative token at low alpha. Arcade and arcade-adjacent customs only.
69
+
70
+ ## 5 · Deckle (paper edge)
71
+
72
+ For plates, tickets, and stubs on print-lineage pages:
73
+
74
+ ```css
75
+ .deckled { box-shadow: inset 0 0 0 1px var(--color-rule);
76
+ mask-image: radial-gradient(6px at 0 50%, transparent 97%, black);
77
+ mask-size: 12px 24px; mask-repeat: repeat-y; mask-position: left; }
78
+ ```
79
+
80
+ One edge, one element class per page (a ticket edge, a stamp perforation). Never on cards generally; it is an artifact, not a border style.
81
+
82
+ ## Affinity: who earns texture
83
+
84
+ A theme earns texture when its Surfaces section names one; a custom draw earns it when its lineage is print (risograph, letterpress, ticket stock, line printer), and then it picks the one artifact that lineage used. The budget above binds every theme, whatever its file says: page-wide grain at 0.08 or less, 0.15 inside one plate, 0.05 or nothing under running text. Examples: Riso (grain and misregistration), Halftone (a dot screen), Paste-up (a fibre wash), Darkroom (film grain), Arcade (scanlines).
85
+
86
+ **Never:** a texture a theme does not name, grain on a modern-minimal page, two artifact families on one page, or a texture as ambience over everything because the page felt flat.
87
+
88
+ ## Reduced motion and accessibility
89
+
90
+ The settle-once misregistration and nothing else moves; everything here ships identical under `prefers-reduced-motion: reduce` because nothing animates. Texture never lowers text contrast below the gate-40/41 thresholds: measure contrast on the textured result, not the flat token.