@litfamily/litgrok 1.0.26 → 1.0.28

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 (235) hide show
  1. package/.grok/hooks/lit-mark.mjs +42 -0
  2. package/.grok/hooks/lit-status-line.mjs +174 -21
  3. package/.grok/hooks/plan-gate.mjs +13 -3
  4. package/.grok/hooks/record-passive-event.mjs +40 -6
  5. package/.grok/hooks/session-end.json +15 -0
  6. package/.grok/hooks/session-end.mjs +6 -0
  7. package/.grok/hooks/session-liveness.mjs +102 -0
  8. package/.grok/hooks/session-rows.mjs +57 -0
  9. package/.grok/hooks/session-start.mjs +17 -0
  10. package/.grok/hooks/workflow-stage.mjs +5 -2
  11. package/.grok/rules/00-litgrok.md +14 -0
  12. package/.grok/skills/frontend-ui-ux/ATTRIBUTION.md +23 -0
  13. package/.grok/skills/frontend-ui-ux/SKILL.md +4 -1
  14. package/.grok/skills/frontend-ui-ux/examples/phase-3-readme-ab/README.md +9 -0
  15. package/.grok/skills/frontend-ui-ux/kit/components.css +414 -0
  16. package/.grok/skills/frontend-ui-ux/kit/fonts.json +22 -0
  17. package/.grok/skills/frontend-ui-ux/kit/layouts/landing.html +164 -0
  18. package/.grok/skills/frontend-ui-ux/kit/layouts/settings.html +114 -0
  19. package/.grok/skills/frontend-ui-ux/kit/layouts/workspace.html +115 -0
  20. package/.grok/skills/frontend-ui-ux/kit/styles/computational-brutalism.json +227 -0
  21. package/.grok/skills/frontend-ui-ux/kit/styles/field-notes.json +205 -0
  22. package/.grok/skills/frontend-ui-ux/kit/styles/graphite.json +200 -0
  23. package/.grok/skills/frontend-ui-ux/kit/styles/meadow.json +199 -0
  24. package/.grok/skills/frontend-ui-ux/kit/styles/neo-brutalism.json +222 -0
  25. package/.grok/skills/frontend-ui-ux/kit/ui.js +226 -0
  26. package/.grok/skills/frontend-ui-ux/references/adaptive-layout.md +10 -4
  27. package/.grok/skills/frontend-ui-ux/references/brand-and-imagery.md +11 -7
  28. package/.grok/skills/frontend-ui-ux/references/complete-contract.md +21 -0
  29. package/.grok/skills/frontend-ui-ux/references/composition.md +10 -6
  30. package/.grok/skills/frontend-ui-ux/references/craft-floor.md +256 -93
  31. package/.grok/skills/frontend-ui-ux/references/creative-directions.md +9 -6
  32. package/.grok/skills/frontend-ui-ux/references/default-editorial-pixel.json +28 -0
  33. package/.grok/skills/frontend-ui-ux/references/house-styles.md +234 -0
  34. package/.grok/skills/frontend-ui-ux/references/implementation-platforms.md +10 -6
  35. package/.grok/skills/frontend-ui-ux/references/inclusive-interface.md +11 -5
  36. package/.grok/skills/frontend-ui-ux/references/interaction-motion.md +34 -78
  37. package/.grok/skills/frontend-ui-ux/references/motion-guide.md +10 -7
  38. package/.grok/skills/frontend-ui-ux/references/performance-delivery.md +11 -8
  39. package/.grok/skills/frontend-ui-ux/references/probe-loop.md +1 -1
  40. package/.grok/skills/frontend-ui-ux/references/product-direction.md +9 -4
  41. package/.grok/skills/frontend-ui-ux/references/production-interview.md +17 -0
  42. package/.grok/skills/frontend-ui-ux/references/redesign-playbook.md +10 -6
  43. package/.grok/skills/frontend-ui-ux/references/slop-register.md +148 -73
  44. package/.grok/skills/frontend-ui-ux/references/system-foundations.md +10 -4
  45. package/.grok/skills/frontend-ui-ux/references/visual-language.md +10 -4
  46. package/.grok/skills/frontend-ui-ux/references/visual-reconstruction.md +39 -72
  47. package/.grok/skills/frontend-ui-ux/scripts/design-lock.mjs +400 -0
  48. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-driver.mjs +33 -0
  49. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-lock.mjs +196 -0
  50. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-page.mjs +1555 -0
  51. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-rules.mjs +153 -0
  52. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-server.mjs +57 -0
  53. package/.grok/skills/frontend-ui-ux/scripts/interface-probe-static.mjs +139 -0
  54. package/.grok/skills/frontend-ui-ux/scripts/interface-probe.mjs +363 -0
  55. package/.grok/skills/frontend-ui-ux/scripts/pixel-art.mjs +60 -0
  56. package/.grok/skills/lit-adhd/SKILL.md +155 -0
  57. package/.grok/skills/lit-adhd/references/card-examples.md +131 -0
  58. package/.grok/skills/lit-adhd/references/status-taxonomy.md +50 -0
  59. package/.grok/skills/lit-adhd/scripts/lib/brief.mjs +421 -0
  60. package/.grok/skills/lit-adhd/scripts/lib/collect.mjs +395 -0
  61. package/.grok/skills/lit-adhd/scripts/lib/gauge.mjs +87 -0
  62. package/.grok/skills/lit-adhd/scripts/lib/next-step.mjs +22 -0
  63. package/.grok/skills/lit-adhd/scripts/lib/plan-task-rows.mjs +32 -0
  64. package/.grok/skills/lit-adhd/scripts/lib/project-state-root.mjs +55 -0
  65. package/.grok/skills/lit-adhd/scripts/lib/redact.mjs +64 -0
  66. package/.grok/skills/lit-adhd/scripts/lib/suggest.mjs +140 -0
  67. package/.grok/skills/lit-adhd/scripts/lib/transcripts.mjs +232 -0
  68. package/.grok/skills/lit-adhd/scripts/rewind.mjs +6 -0
  69. package/.grok/skills/lit-diagram-drawer/SKILL.md +17 -5
  70. package/.grok/skills/lit-diagram-drawer/references/output-spec.md +2 -2
  71. package/.grok/skills/lit-diagram-drawer/references/style-guide.md +20 -11
  72. package/.grok/skills/lit-diagram-drawer/references/type-architecture.md +3 -3
  73. package/.grok/skills/lit-diagram-drawer/references/type-dependency.md +1 -1
  74. package/.grok/skills/lit-diagram-drawer/references/type-tree.md +3 -3
  75. package/.grok/skills/lit-diagram-drawer/references/type-wardley.md +1 -1
  76. package/.grok/skills/lit-diagram-drawer/references/verifier-guide.md +4 -0
  77. package/.grok/skills/lit-diagram-drawer/scripts/visual-quality.mjs +2 -2
  78. package/.grok/skills/lit-handoff/SKILL.md +2 -0
  79. package/.grok/skills/lit-hijack/SKILL.md +459 -0
  80. package/.grok/skills/lit-hijack/references/capture-and-provenance.md +124 -0
  81. package/.grok/skills/lit-hijack/references/clean-room-build.md +130 -0
  82. package/.grok/skills/lit-hijack/references/distil-and-licence.md +128 -0
  83. package/.grok/skills/lit-hijack/references/gap-and-port-design.md +150 -0
  84. package/.grok/skills/lit-hijack/references/parity-and-report.md +130 -0
  85. package/.grok/skills/lit-hijack/scripts/hijack.mjs +890 -0
  86. package/.grok/skills/lit-hijack/scripts/lib/safe-fetch.mjs +213 -0
  87. package/.grok/skills/lit-plan/SKILL.md +3 -1
  88. package/.grok/skills/lit-plan/references/plan-schema.md +4 -0
  89. package/.grok/skills/lit-plan/scripts/scaffold-plan.mjs +9 -2
  90. package/.grok/skills/lit-plan/scripts/scope-roots.mjs +83 -0
  91. package/.grok/skills/lit-pptx/SKILL.md +10 -5
  92. package/.grok/skills/lit-pptx/examples/13-engineering-review-computational-brutalism-ko.md +173 -0
  93. package/.grok/skills/lit-pptx/examples/14-launch-pitch-neo-brutalism-ko.md +154 -0
  94. package/.grok/skills/lit-pptx/examples/15-design-lecture-bauhaus-ko.md +139 -0
  95. package/.grok/skills/lit-pptx/examples/16-community-programme-riso-ko.md +158 -0
  96. package/.grok/skills/lit-pptx/examples/17-public-data-briefing-newsroom-ko.md +179 -0
  97. package/.grok/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Bold.ttf +0 -0
  98. package/.grok/skills/lit-pptx/fonts/jetbrains-mono/JetBrainsMono-Regular.ttf +0 -0
  99. package/.grok/skills/lit-pptx/fonts/jetbrains-mono/OFL.txt +93 -0
  100. package/.grok/skills/lit-pptx/fonts/jetbrains-mono/provenance.json +1 -0
  101. package/.grok/skills/lit-pptx/references/direction-step.md +34 -8
  102. package/.grok/skills/lit-pptx/references/tonalities/bauhaus.md +140 -0
  103. package/.grok/skills/lit-pptx/references/tonalities/computational-brutalism.md +150 -0
  104. package/.grok/skills/lit-pptx/references/tonalities/neo-brutalism.md +161 -0
  105. package/.grok/skills/lit-pptx/references/tonalities/newsroom.md +144 -0
  106. package/.grok/skills/lit-pptx/references/tonalities/riso.md +137 -0
  107. package/.grok/skills/lit-pptx/scripts/compile-deck.js +1 -1
  108. package/.grok/skills/lit-pptx/scripts/craft_extras.py +61 -3
  109. package/.grok/skills/lit-pptx/scripts/deck_output.py +76 -62
  110. package/.grok/skills/lit-pptx/scripts/embed_fonts.py +14 -1
  111. package/.grok/skills/lit-pptx/scripts/lib/grid-resolver.js +101 -110
  112. package/.grok/skills/lit-pptx/scripts/lib/layout-resolver.js +9 -15
  113. package/.grok/skills/lit-pptx/scripts/lib/render-pack.js +389 -582
  114. package/.grok/skills/lit-pptx/scripts/lib/slide-grid.js +104 -0
  115. package/.grok/skills/lit-pptx/scripts/lib/template-registry.js +60 -8
  116. package/.grok/skills/lit-pptx/scripts/qa_deck.py +4 -4
  117. package/.grok/skills/lit-pptx/templates/tonalities/atlas/pack.yaml +2 -0
  118. package/.grok/skills/lit-pptx/templates/tonalities/bauhaus/pack.yaml +98 -0
  119. package/.grok/skills/lit-pptx/templates/tonalities/chalk/pack.yaml +2 -0
  120. package/.grok/skills/lit-pptx/templates/tonalities/computational-brutalism/pack.yaml +99 -0
  121. package/.grok/skills/lit-pptx/templates/tonalities/gazette/pack.yaml +2 -0
  122. package/.grok/skills/lit-pptx/templates/tonalities/ledger/pack.yaml +2 -0
  123. package/.grok/skills/lit-pptx/templates/tonalities/neo-brutalism/pack.yaml +107 -0
  124. package/.grok/skills/lit-pptx/templates/tonalities/newsroom/pack.yaml +99 -0
  125. package/.grok/skills/lit-pptx/templates/tonalities/night/pack.yaml +2 -0
  126. package/.grok/skills/lit-pptx/templates/tonalities/paper/pack.yaml +2 -0
  127. package/.grok/skills/lit-pptx/templates/tonalities/riso/pack.yaml +99 -0
  128. package/.grok/skills/lit-pptx/templates/tonalities/signal/pack.yaml +3 -0
  129. package/.grok/skills/lit-pptx/templates/tonalities/studio/pack.yaml +2 -0
  130. package/.grok/skills/lit-recap/SKILL.md +1 -1
  131. package/.grok/skills/lit-schematic/SKILL.md +140 -0
  132. package/.grok/skills/lit-schematic/examples/iso-heat-exchanger/build.mjs +38 -0
  133. package/.grok/skills/lit-schematic/examples/iso-heat-exchanger/scene.mjs +133 -0
  134. package/.grok/skills/lit-schematic/examples/journal-adsorption-rig/build.mjs +87 -0
  135. package/.grok/skills/lit-schematic/examples/pid-dosing-skid/build.mjs +85 -0
  136. package/.grok/skills/lit-schematic/references/cutaway-outputs.md +70 -0
  137. package/.grok/skills/lit-schematic/references/isometric-craft.md +101 -0
  138. package/.grok/skills/lit-schematic/references/journal-figures.md +72 -0
  139. package/.grok/skills/lit-schematic/references/kit-api.md +134 -0
  140. package/.grok/skills/lit-schematic/references/pfd-and-layout.md +53 -0
  141. package/.grok/skills/lit-schematic/references/pid-drafting.md +103 -0
  142. package/.grok/skills/lit-schematic/references/pid-symbols.md +163 -0
  143. package/.grok/skills/lit-schematic/references/verification.md +100 -0
  144. package/.grok/skills/lit-schematic/scripts/doctor.mjs +57 -0
  145. package/.grok/skills/lit-schematic/scripts/lib/figure.mjs +81 -0
  146. package/.grok/skills/lit-schematic/scripts/lib/fonts.mjs +27 -0
  147. package/.grok/skills/lit-schematic/scripts/lib/geom.mjs +113 -0
  148. package/.grok/skills/lit-schematic/scripts/lib/interactive.mjs +292 -0
  149. package/.grok/skills/lit-schematic/scripts/lib/isa.mjs +115 -0
  150. package/.grok/skills/lit-schematic/scripts/lib/iso.mjs +719 -0
  151. package/.grok/skills/lit-schematic/scripts/lib/legend-sheet.mjs +162 -0
  152. package/.grok/skills/lit-schematic/scripts/lib/pid.mjs +937 -0
  153. package/.grok/skills/lit-schematic/scripts/lib/png.mjs +132 -0
  154. package/.grok/skills/lit-schematic/scripts/lib/qa-core.mjs +658 -0
  155. package/.grok/skills/lit-schematic/scripts/lib/route.mjs +218 -0
  156. package/.grok/skills/lit-schematic/scripts/lib/sheet.mjs +890 -0
  157. package/.grok/skills/lit-schematic/scripts/lib/svg.mjs +82 -0
  158. package/.grok/skills/lit-schematic/scripts/lib/theme.mjs +115 -0
  159. package/.grok/skills/lit-schematic/scripts/motion.mjs +129 -0
  160. package/.grok/skills/lit-schematic/scripts/qa.mjs +92 -0
  161. package/.grok/skills/lit-schematic/scripts/render.mjs +233 -0
  162. package/.grok/skills/lit-schematic/scripts/scaffold.mjs +60 -0
  163. package/.grok/skills/lit-scientific-visualization/SKILL.md +36 -12
  164. package/.grok/skills/lit-typographic-motion/SKILL.md +7 -4
  165. package/.grok/skills/lit-typographic-motion/THIRD_PARTY_NOTICES +11 -0
  166. package/.grok/skills/lit-typographic-motion/recipes/hero-3d/expected.json +62 -0
  167. package/.grok/skills/lit-typographic-motion/recipes/hero-3d/index.html +82 -0
  168. package/.grok/skills/lit-typographic-motion/references/choice-first.md +30 -0
  169. package/.grok/skills/lit-typographic-motion/references/cover.md +10 -1
  170. package/.grok/skills/lit-typographic-motion/references/depth.md +119 -0
  171. package/.grok/skills/lit-typographic-motion/references/treatment.md +9 -1
  172. package/.grok/skills/lit-typographic-motion/scripts/blender/runner.py +218 -0
  173. package/.grok/skills/lit-typographic-motion/scripts/lib/assets.mjs +230 -0
  174. package/.grok/skills/lit-typographic-motion/scripts/lib/blender.mjs +136 -0
  175. package/.grok/skills/lit-typographic-motion/scripts/lib/board.mjs +153 -0
  176. package/.grok/skills/lit-typographic-motion/scripts/lib/chrome.mjs +61 -32
  177. package/.grok/skills/lit-typographic-motion/scripts/lib/constants.mjs +4 -2
  178. package/.grok/skills/lit-typographic-motion/scripts/lib/cover-capture.mjs +20 -11
  179. package/.grok/skills/lit-typographic-motion/scripts/lib/cover-treatment.mjs +26 -2
  180. package/.grok/skills/lit-typographic-motion/scripts/lib/cover.mjs +12 -5
  181. package/.grok/skills/lit-typographic-motion/scripts/lib/frame-pool.mjs +78 -1
  182. package/.grok/skills/lit-typographic-motion/scripts/lib/gallery.mjs +160 -0
  183. package/.grok/skills/lit-typographic-motion/scripts/lib/house.mjs +43 -0
  184. package/.grok/skills/lit-typographic-motion/scripts/lib/look.mjs +39 -1
  185. package/.grok/skills/lit-typographic-motion/scripts/lib/scaffold.mjs +174 -0
  186. package/.grok/skills/lit-typographic-motion/scripts/lib/score.mjs +640 -0
  187. package/.grok/skills/lit-typographic-motion/scripts/lib/sound.mjs +143 -0
  188. package/.grok/skills/lit-typographic-motion/scripts/lib/soundtrack.mjs +12 -3
  189. package/.grok/skills/lit-typographic-motion/scripts/lib/stage-gate.mjs +44 -0
  190. package/.grok/skills/lit-typographic-motion/scripts/lib/stage-qa.mjs +132 -3
  191. package/.grok/skills/lit-typographic-motion/scripts/lib/stage-session.mjs +51 -3
  192. package/.grok/skills/lit-typographic-motion/scripts/lib/stage.mjs +74 -9
  193. package/.grok/skills/lit-typographic-motion/scripts/lib/styles.mjs +224 -0
  194. package/.grok/skills/lit-typographic-motion/scripts/lib/treatment.mjs +198 -4
  195. package/.grok/skills/lit-typographic-motion/scripts/lib/vendor/three/LICENSE +21 -0
  196. package/.grok/skills/lit-typographic-motion/scripts/lib/vendor/three/addons/environments/RoomEnvironment.js +144 -0
  197. package/.grok/skills/lit-typographic-motion/scripts/lib/vendor/three/addons/geometries/RoundedBoxGeometry.js +155 -0
  198. package/.grok/skills/lit-typographic-motion/scripts/lib/vendor/three/three.module.js +54571 -0
  199. package/.grok/skills/lit-typographic-motion/scripts/motion.mjs +56 -6
  200. package/.grok/skills/lit-typographic-motion/scripts/stage/cover-init.js +20 -8
  201. package/.grok/skills/lit-typographic-motion/scripts/stage/loop-kit.js +2 -2
  202. package/.grok/skills/lit-typographic-motion/scripts/stage/stage-kit.js +25 -0
  203. package/.grok/skills/lit-typographic-motion/styles/paper.json +1 -0
  204. package/.grok/skills/lit-typographic-motion/styles/swiss-signal.json +1 -0
  205. package/.grok/skills/lit-typographic-motion/styles/terminalcore.json +1 -0
  206. package/.grok/skills/lit-typographic-motion/styles/tidal.json +1 -0
  207. package/.grok/skills/litgrok/SKILL.md +1 -1
  208. package/.grok/skills/litresearch/SKILL.md +2 -0
  209. package/.grok/skills/readme-studio/SKILL.md +14 -12
  210. package/.grok/skills/readme-studio/references/choice-first.md +24 -0
  211. package/.grok/skills/start-work/SKILL.md +8 -1
  212. package/.grok-plugin/plugin.json +4 -1
  213. package/CHANGELOG.md +18 -0
  214. package/README.md +11 -11
  215. package/README_ko-KR.md +11 -11
  216. package/TRADEMARK.md +12 -0
  217. package/bin/litgrok.mjs +2 -0
  218. package/docs/assets/readme/badge-version.svg +1 -1
  219. package/docs/assets/showcase/brief.webp +0 -0
  220. package/docs/assets/showcase/deck.webp +0 -0
  221. package/docs/assets/showcase/page.webp +0 -0
  222. package/docs/assets/showcase/pid.webp +0 -0
  223. package/docs/assets/skills/lit-adhd.webp +0 -0
  224. package/docs/assets/skills/lit-hijack.webp +0 -0
  225. package/docs/assets/skills/lit-schematic.webp +0 -0
  226. package/docs/reference.md +11 -7
  227. package/docs/reference_ko-KR.md +11 -7
  228. package/hooks/hooks.json +11 -0
  229. package/package.json +6 -1
  230. package/plugin.json +1 -1
  231. package/.grok/skills/frontend-ui-ux/scripts/page-probe.mjs +0 -105
  232. package/.grok/skills/frontend-ui-ux/scripts/probe.mjs +0 -91
  233. package/.grok/skills/frontend-ui-ux/scripts/rule-data.mjs +0 -56
  234. package/.grok/skills/frontend-ui-ux/scripts/static-probe.mjs +0 -27
  235. package/.grok/skills/frontend-ui-ux/scripts/static-server.mjs +0 -19
@@ -1,99 +1,262 @@
1
- # Craft floor and responsive matrix
1
+ # Craft floor, responsive matrix and the probe loop
2
2
 
3
- Use this index when building, polishing, auditing, or hardening an interface. The rule IDs, numeric bounds, and severities below are the family contract; measure the rendered page through `scripts/probe.mjs` and inspect the screenshots before making a verdict. A row marked JUDG needs a human decision. The DOM probe must never turn its own absence of a finding into a pass for that row.
3
+ This reference and `references/slop-register.md` load whenever `frontend-ui-ux` activates, in
4
+ every mode. They are the numbered rule catalogue the interface probe measures and the review
5
+ table cites. Rule ids (`CF-*`, `RS-*`, `SLOP-*`) are stable family ids; cite the id, not a
6
+ paraphrase of the number. Thresholds live once, as data, in `scripts/interface-probe-rules.mjs`;
7
+ the tables below restate them for reading, and the rule table wins if the two ever differ.
4
8
 
5
- Before sampling, discard hidden, closed-disclosure, screen-reader-only, and off-canvas utility nodes. Read the actual computed style and geometry in the target viewport. A contrast estimate over an image or complex gradient is `not_verified` unless the painted pixels can be sampled. A result calculated from observed values is Derived; the observation itself is Measured. Never call either one Inferred. Do not activate controls or open disclosures just for measurement. Count closed content in the review and label its rendered checks `not_verified`.
9
+ ## 1. Run the probe
6
10
 
7
- The required run covers 320, 390, 768, and 1440 CSS pixels in the light scheme, 390 in dark mode, 390 with reduced motion, and the 720×450 CSS-pixel reflow approximation of 1440 at 200% zoom. The zoom view is an emulation and must be described as such. A missing width or an unverified rendered check belongs in the Not verified list, never a silent pass.
11
+ Run the probe from the exact installed skill directory against the page you built or were asked
12
+ to review. It accepts an HTML file, a project directory (it prefers `dist/`, `build/` or `out/`
13
+ over an unbuilt source page) or an `http(s)` URL:
8
14
 
9
- ## Typography and colour
15
+ ```bash
16
+ FRONTEND_UIUX_SKILL_ROOT="<directory containing the selected installed SKILL.md>"
17
+ node "$FRONTEND_UIUX_SKILL_ROOT/scripts/interface-probe.mjs" "<page.html | project dir | URL>" --out "<evidence dir>"
18
+ ```
10
19
 
11
- | Rule | Bound or decision | Kind | Severity |
12
- |---|---|---|---|
13
- | CF-101 | **Body-text measure (characters per rendered line):** Target 60–75 chars/line (Latin) and 30–45 (CJK-majority, meaning >30% Hangul/CJK code points). A finding (MEDIUM) is raised only when a prose block renders ≥2 lines and its longest line exceeds 90 chars (Latin, the plan's "fail above 90") or 60 chars (CJK). A single-line block never fires (Delta 1; supersedes Conflicts resolved #10's "no 90ch hard-FAIL") | DET | MEDIUM throughout, never HIGH (see calibration: the check over-fires on non-prose containers, and the Latin-glyph `ch` proxy is not a validated fit for CJK-majority copy) |
14
- | CF-102 | **Heading line-height:** 1.2–1.35 for a normal heading role; a large display/hero heading (≥40–48px) may run as tight as 1.05, exempt from the 1.2 floor (see Conflicts resolved #1) | DET | MEDIUM, only once the heading element itself renders ≥2 visual lines |
15
- | CF-103 | **Body line-height:** A finding (MEDIUM) is raised when a ≥2-line body block is below 1.4 (Latin) or 1.5 (CJK-majority). 1.5 Latin and 1.6 CJK remain the recommended targets and raise nothing. No upper bound (Delta 1; the calibrated DET floor was 1.4, and 1.5/1.6 were never calibrated as fail lines — see Conflicts resolved #2) | DET | below floor: MEDIUM |
16
- | CF-104 | **Wrapped-row line-height floor:** ≥1.4 whenever a column can wrap to 3+ lines, even in a dense layout | DET | MEDIUM |
17
- | CF-105 | **Balanced headings, no stranded last word:** Heading uses a balancing wrap mode (sourced, DET); body avoids an orphaned short last line (unsourced numeric proxy, JUDG) | DET (wrap-mode presence); JUDG (orphan call) | LOW |
18
- | CF-106 | **Tabular figures for aligned/updating numbers:** Any numeric table column, KPI, or in-place-updating number uses tabular figures | DET | LOW–MEDIUM |
19
- | CF-107 | **Sentence case for UI labels:** Button, nav, and form-control labels use sentence case, not Title Case | DET | LOW |
20
- | CF-108 | **Type-role and family ceiling:** ≤7 named type roles; ≤2 body/display families + 1 mono, a 3rd family needs a recorded exception | DET census, JUDG verdict | MEDIUM if exceeded with no recorded exception |
21
- | CF-109 | **Weight floor by size:** Below 18px stay at weight ≥400; weights 100–300 are display-only at ≥28px | DET | MEDIUM |
22
- | CF-201 | **WCAG contrast floor:** Body/small text 4.5:1; text ≥24px (or ≥18.5px bold, per krehel contrast.md's 14pt≈18.5px rounding — not 19px) and UI-component boundaries/icons/focus rings 3:1. Text inside a disabled control (`:disabled`, `aria-disabled="true"`) is skipped, per WCAG 1.4.3's inactive-component exception. Placeholder contrast is owned by CF-807 alone | DET | body below floor: HIGH; large-text/component tier below floor: MEDIUM |
23
- | CF-202 | **Focus-indicator thickness and contrast:** Focused and unfocused computed styles must differ in at least one of outline, box-shadow, border or background-color. Read them only after `el.matches(':focus-visible')` is confirmed true; if it is false, report `not_verified`. A computed `outline-style: auto` is the browser's own two-tone ring and passes the thickness and contrast checks outright, because its computed `outline-width` (1px) is not its painted width. A custom ring should be ≥2px and ≥3:1 against the resolved background just outside it | DET | HIGH only when nothing changes on focus (no visible indicator, MD-011 #2); MEDIUM when a custom ring exists but is under 2px or under 3:1 |
24
- | CF-203 | **APCA advisory layer:** Body Lc 75 min / 90 preferred; non-body Lc 60/75; large (≥36px) Lc 45/60; UI components Lc 30 floor | DET computation, JUDG weight (advisory, never blocks alone) | informational annotation on a CF-201 finding |
25
- | CF-204 | **Contrast against an image or gradient background:** Sampled worst-case region must still clear CF-201's floor | DET (derived for a CSS gradient; an image only through the optional same-origin canvas upgrade, else `not_verified`) | HIGH if the sampled region fails |
26
- | CF-205 | **One accent colour per view:** At most one high-saturation hue used for interactive emphasis in a single rendered view | JUDG with DET-assist histogram | MEDIUM |
27
- | CF-206 | **Hue tolerance for "one meaning":** Two accent/status hues within 15° of each other count as the same semantic colour | DET | LOW |
28
- | CF-207 | **Status never carried by colour alone:** A state/status indicator pairs colour with text, icon, or pattern | JUDG with DET-assist | HIGH (auto-HIGH) |
29
-
30
- ## Spacing and surfaces
31
-
32
- | Rule | Bound or decision | Kind | Severity |
33
- |---|---|---|---|
34
- | CF-301 | **On-scale spacing:** A computed padding, gap or margin value is on-scale when it is within ±1px of a multiple of 4px. Values under 4px (hairline adjustments) are skipped, and so are equal (±1px) left and right margins on a block narrower than its parent, since those are resolved `margin: auto` | DET | 1–3 distinct off-scale values in a view: LOW; more than 3: MEDIUM |
35
- | CF-302 | **Grouping ratio:** Inter-group gap ≥2× intra-group gap | DET | MEDIUM |
36
- | CF-303 | **Adjacent-element breathing room (non-interactive visual grouping):** ≥12px between bordered/filled visual blocks; ≥24px around borderless blocks and between unrelated groups — scoped to non-interactive grouping/whitespace rhythm | DET | MEDIUM |
37
- | CF-304 | **Heading spacing asymmetry:** Target: more space above a heading than below it (≈2× per current composition.md). DET fail line: a clear inversion only — above < 0.75× below AND below − above ≥12px; equal spacing is not flagged | DET | LOW |
38
- | CF-305 | **Full-width control inset:** A full-width primary control stays inset from the viewport edge (≈16px), not flush | DET | LOW |
39
- | CF-306 | **Prefer container `gap` over sibling margins:** A repeated group's rhythm comes from the parent's `gap`, not per-child margin | JUDG | LOW |
40
- | CF-401 | **Concentric radius:** Inner radius ≈ outer radius − padding, tolerance ±2px (Delta 1 adopts §C.3's gating; see the corrected Conflicts resolved #5). Both radii are capped at `min(width, height)/2` before comparing; the pair is compared only where the child's box reaches the parent corner being compared; skipped once the parent's padding exceeds 24px | DET | LOW |
41
- | CF-402 | **Elevation declared once:** A surface's border and its own shadow do not duplicate the same edge: flag only a hard, near-zero-blur shadow (≤2px) tracing the same boundary a border already draws (the "ghost card" pattern), not any border-plus-soft-shadow pairing | DET | LOW |
42
- | CF-403 | **No hard offset shadow outside a declared register:** `box-shadow` with ≈zero blur and a large solid offset is banned unless the page's recorded visual register explicitly calls for it | JUDG (register-dependent) | MEDIUM |
43
- | CF-404 | **No glow/bloom on primary actions:** One glow test shared with SLOP-010: a `box-shadow`/`filter: drop-shadow` with offset ≤2px, blur ≥16px and shadow HSL saturation >0.4 (the earlier "1.5× shorter side" test is dropped). Each glowing element is reported once: under SLOP-010 when the same glow recurs on ≥2 unrelated elements, otherwise here at LOW (a single glowing heading is also reported here, per that split) | DET | LOW |
44
- | CF-405 | **Neutral image outline:** A ~1px low-opacity, near-achromatic outline around photographic imagery | DET | LOW |
45
- | CF-406 | **Solid modal scrim:** A modal backdrop is solid or near-solid, not `backdrop-filter: blur` | DET | LOW |
46
- | CF-407 | **Undecided decorative patterns:** A grid/dot background, radial halo, marquee, or pseudo-element stripe with no real content referent | DET presence, JUDG "real referent" | LOW–MEDIUM |
47
-
48
- ## Motion, icons, targets, and copy
49
-
50
- | Rule | Bound or decision | Kind | Severity |
51
- |---|---|---|---|
52
- | CF-501 | **Named token set kept:** `enter` 420ms `cubic-bezier(0.16,1,0.3,1)`; `ui` 180ms `cubic-bezier(0.2,0.8,0.2,1)`; `exit` 160ms `cubic-bezier(0.4,0,1,1)` | DET | LOW (drift from the set) |
53
- | CF-502 | **Press feedback:** Scale to 0.96 over 150ms, ease-out; never below 0.95 | DET | LOW |
54
- | CF-503 | **Entrance scale floor:** An entrance transform never starts at `scale(0)`; it starts at ≥0.95 — this floor does not apply to an icon-swap cross-fade, which follows its own transition instead | DET | MEDIUM |
55
- | CF-504 | **Exit shorter than entrance, same path reversed:** Exit duration < entrance duration; same movement axis, reversed | DET | LOW |
56
- | CF-505 | **No spring bounce on feedback motion:** Overshoot/bounce stays at 0 for toggle/toast/press feedback | DET where a curve is inspectable, else JUDG from a recording | MEDIUM |
57
- | CF-506 | **High-frequency interaction ceiling:** A routinely-repeated interaction stays ≤150ms or instant | DET | LOW |
58
- | CF-507 | **`will-change` restricted:** Only `transform`/`opacity`/`filter`, only while the animation is running | DET | wrong property: LOW; left on at rest: MEDIUM |
59
- | CF-508 | **No layout-triggering continuous animation:** `width`/`height`/`padding`/`margin` are not animated continuously; `transform`/`opacity` are used instead, except a deliberate scoped `all` | DET | MEDIUM |
60
- | CF-509 | **Reduced-motion path stays functional:** Every motion-gated state, label, and control stays reachable with `prefers-reduced-motion: reduce` forced | DET (media query applies), JUDG (meaning preserved) | HIGH if a control/state becomes unreachable |
61
- | CF-510 | **Slow-motion replay check before sign-off:** No numeric threshold — a checklist judgment call | JUDG | LOW |
62
- | CF-601 | **Single-system stroke discipline:** One grid (24px), one stroke weight per icon set; a set that ships weight variants may match a variant to adjacent text weight (regular↔lighter, semibold/bold↔heavier) | JUDG (system-level) | MEDIUM if two unrelated icon families appear on one surface |
63
- | CF-602 | **Icon-to-text relative sizing:** Icon ≈1–1.25× adjacent text's cap-height; legible at a 16px minimum render | DET | LOW |
64
- | CF-603 | **Icon-only controls stay named and never solo on a destructive action:** Every focusable control (button, `a[href]`, input, select, textarea, `[role=button\|link\|checkbox\|radio\|switch\|tab\|menuitem]`, `[tabindex≥0]`) has a non-empty computed accessible name (from text, `aria-label`, `aria-labelledby`, an associated label, `title`, or a contained img's `alt`) — widened in Delta 1 so MD-011 #1 has a measuring rule; decorative icons are hidden from assistive tech; a destructive action is never icon-only with no label | DET | HIGH for any focusable control with an empty accessible name, and for a destructive icon-only control |
65
- | CF-604 | **Optical alignment over bounding-box alignment:** Icon-side padding runs ≈2px tighter than text-side padding in the same control | JUDG | LOW |
66
- | CF-701 | **Hit-area floor and recommendation:** Coarse pointer ≥44×44px recommended; 24×24px is the WCAG 2.5.8 AA floor: a target below it fails unless WCAG 2.5.8's spacing exception holds (a 24px-diameter circle centred on the target's box intersects no other target's box or circle). Touch-primary is decided by viewport width, not the `pointer` media feature (emulated viewports leave `(pointer: coarse)` false): widths ≤768 (320, 390, 768 and the 720 zoom pass) are touch-primary, 1440 is fine-pointer. On a touch-primary width, 24–44px is MEDIUM for a non-primary control (never a silent pass) and HIGH for a primary action — the form's sole `type=submit` button, or the first filled button or button-styled link inside the first viewport (a narrower, fully mechanical form of the heuristic §C.3's CF-404 row uses); at 1440 a 24×24px target passes. The same width rule governs CF-702, CF-703 and RS-008 | DET | below 24px without the spacing exception: HIGH (FAIL); 24–44px primary action on a touch-primary width: HIGH; 24–44px non-primary on a touch-primary width: MEDIUM; 24–44px at 1440: pass |
67
- | CF-702 | **Neighbour clearance by pointer class:** ≥8px clear space between coarse-pointer targets' expanded areas; ≥4px for fine-pointer | DET | MEDIUM |
68
- | CF-703 | **Destructive controls keep the coarse minimum everywhere:** 44×44px floor applies to a destructive control even on a fine-pointer surface (the 1440 width, per CF-701's width rule) | DET | HIGH if violated |
69
- | CF-704 | **Hover/drag-only actions expose a discrete alternate control:** Any action reachable only by hover, drag, or long-press also has a tap/keyboard-reachable equivalent | DET (stylesheet scan), else JUDG | HIGH (auto-HIGH: pointer-only-reachable control) |
70
- | CF-801 | **Verb-first, plain-word action labels:** A button/action label leads with a verb and avoids jargon | JUDG | LOW–MEDIUM |
71
- | CF-802 | **Tone calibrated by stakes:** Warm for success/onboarding/empty; neutral for routine/settings; calm for errors/destructive; serious for data-loss/security | JUDG | checklist item |
72
- | CF-803 | **Errors name what happened and how to recover:** A vague denylisted phrase with no further detail fails | DET assist + JUDG | MEDIUM |
73
- | CF-804 | **One capitalization policy:** Sentence case throughout, or a documented exception list | DET | LOW |
74
- | CF-805 | **Toggle labels state the ON condition:** A setting label describes what turns on, not a bare noun | JUDG | checklist item |
75
- | CF-806 | **Placeholders are examples, never the only label:** A real `<label>`/`aria-label` exists beside any placeholder; no bracket-instruction placeholder text | DET | MEDIUM (label-only-via-placeholder is also an accessibility escalation) |
76
- | CF-807 | **Placeholder contrast meets the same floor:** ≥4.5:1 against the field's own background (cross-ref CF-201) | DET where the pseudo-element style is inspectable, else `not_verified` | MEDIUM |
77
-
78
- ## Responsive and adaptive checks
79
-
80
- The driver owns matrix completion. The in-page probe owns the visible defect at each view. Fix a content failure where the content breaks, and record a cue-gated RTL or harden pass as inapplicable only with a reason.
81
-
82
- | Rule | Bound or decision | Kind | Severity |
20
+ What it does, in order:
21
+
22
+ 1. Asks the `browser-drive` capability probe for a verified `agent-browser`. It never installs,
23
+ downloads or updates a browser. A missing, unidentified or uncleaned driver is a `BLOCKED`
24
+ run, not a pass.
25
+ 2. Serves a local page from `127.0.0.1` on a free port (never `file://`), then opens it once per
26
+ matrix row: 320, 390, 768 and 1440 px in light mode; 390 px dark; 390 px with reduced motion;
27
+ and 1440 px at 200 % zoom, emulated as a 720 × 450 CSS px viewport at double scale
28
+ (`zoom_emulation: viewport-halved`, which reproduces reflow but not zoomed text rasterising).
29
+ 3. Waits 1200 ms, checks that the page finished loading (one extra wait, then the viewport is
30
+ recorded as not settled), runs the in-page measurement module, and saves one screenshot per
31
+ row under `<evidence dir>/screenshots/`. At 1440 px it then hovers up to five repeated list
32
+ controls for real (CF-506). It never clicks, presses or submits anything; `alert`, `confirm`
33
+ and `prompt` are stubbed before the first read, and content behind closed disclosures is
34
+ counted under Not verified instead of being opened.
35
+ 4. Writes `<evidence dir>/findings.json` (`{ manifest, findings }`, each finding naming exactly
36
+ one rule id) and prints the review table below.
37
+ 5. When a `design.lock.json` sits beside the page (or `--lock` names one), runs the DS-* lock rules
38
+ from `references/house-styles.md` in the same pass and records the lock in
39
+ `manifest.design_lock`; without one, DS-001 is listed under Not verified. A rendered run ends with
40
+ the screenshot paths and the six LOOK questions that section 2's loop answers.
41
+
42
+ Exit codes are the contract: **0** all seven matrix rows ran and no measured or derived HIGH
43
+ finding remains; **1** at least one measured or derived HIGH finding remains (this wins over a
44
+ missing row); **2** `BLOCKED: <reason>` on one line (`browser unavailable`, `browser identity
45
+ unverified`, `browser cleanup failed`, `no entry page found`, `matrix incomplete (<rows>)`). A
46
+ `not_verified` finding never sets exit 1. A blocked run still reads the source files for the
47
+ rules a file can show on its own (a literal match keeps its own tier, with `viewport: static` and
48
+ a `file:line`), and lists every rendered rule under "Not verified". Say `BLOCKED` in the reply;
49
+ never describe it as a pass.
50
+
51
+ Rules marked *judgment* below are DET-assist: a hit is printed under "Judgment calls" as a
52
+ candidate, never as a finding, and its severity applies only after you confirm it with a stated
53
+ reason (tag it Inferred).
54
+
55
+ Budget: at most 20 s per viewport and 180 s per run; 12 findings per rule per viewport; 3,000
56
+ elements and 4,000 characters of copy sampled; five controls per viewport for the focus, press
57
+ and hover samples. A viewport the budget skips is not verified.
58
+
59
+ ## 2. The loop
60
+
61
+ Every mode that edits runs the same loop:
62
+
63
+ ```
64
+ build (or baseline) -> probe -> fix -> probe -> fix -> probe -> fix -> final probe
65
+ \__________ at most three fix rounds __________/
66
+ ```
67
+
68
+ - **Fix in the cheaper order.** Delete the offending element or rule first; then use a platform
69
+ feature instead of custom code; then reuse a token or component the project already has; then
70
+ correct the value in place; add new code last.
71
+ - **Re-run the whole probe** after each round, not only the rules you touched. A fix that clears
72
+ one HIGH and adds another is caught by the same battery.
73
+ - **HIGH blocks "done".** Fix every HIGH first, then MEDIUM. A HIGH still present after three
74
+ rounds may only ship as a limitation stated once in the reply, with its reason (for example
75
+ "hero heading over a photograph, CF-204 not verified, no safe repaint"). MEDIUM and LOW never
76
+ block by themselves.
77
+ - **Thresholds do not move.** Never edit a number, add an exception or change a fixture to make a
78
+ page pass; fix the page or state the limitation. A reviewer's or judge's wording never drives a
79
+ fix round.
80
+ - **Tier every claim.** *Measured* means read straight off the render (a computed style, a
81
+ bounding box, a scroll width). *Derived* means computed from measured values (a WCAG ratio from
82
+ two sampled colours) or read through a named approximation (a stylesheet `:active` rule instead
83
+ of a real press). *Inferred* is a judgment (every `judgment:` note and every checklist row
84
+ below). Never phrase an inferred value as measured. A derived value built on a missing or stale
85
+ measurement drops to inferred. *Not verified* is its own state: the check did not run.
86
+ - **Look at the screenshots** for 320, 390 and 1440 before claiming the page works; the probe
87
+ measures rules, it does not see a composition. Answer its LOOK-1 to LOOK-6 questions in one line
88
+ each, fix the two worst, and stop after two look rounds.
89
+
90
+ ## 3. Modes
91
+
92
+ `build` is the default. The other three are opt-in by wording and nest inside this skill's
93
+ existing mode matrix: `polish` and `harden` are scoped kinds of `build`; `audit` is a probe-driven
94
+ kind of the read-only review row.
95
+
96
+ | Mode | Edits | Probe | Deliverable |
83
97
  |---|---|---|---|
84
- | RS-001 | **Canonical probe viewport set:** Base pass runs at exactly four widths: 320, 390, 768, 1440px, light scheme, motion enabled | DET | run completeness: a missing width sets exit `2` (§C.5, `BLOCKED: matrix incomplete`), never a HIGH finding |
85
- | RS-002 | **390px dark-mode pass:** Re-run 390px with the dark colour scheme active (real toggle, not a filter) | DET | run completeness: an unrun dark pass sets exit `2` (§C.5), never a HIGH finding and never a silent pass; once the pass ran: MEDIUM when no dark path is found or it adds new HIGH contrast findings (those findings keep CF-201's own severity) |
86
- | RS-003 | **Reduced-motion pass:** One pass at minimum at 390px with `prefers-reduced-motion: reduce` forced | DET (query honoured), JUDG (meaning preserved) | HIGH if a control/state becomes unreachable |
87
- | RS-004 | **1440px at 200% zoom emulation:** Re-run 1440px at an effective content width of ≈720 CSS px | DET | HIGH if the zoom pass shows page-level overflow (RS-006) or clipped text (RS-007) |
88
- | RS-005 | **Content-derived breakpoints:** A structural layout change (reflow/stack/collapse/reveal/defer/relocate/freeze) sits at the width real content first breaks, never an unexamined framework default | JUDG, DET-assisted (low-confidence advisory only — see note) | LOW, informational, alongside a finding rather than an equal-weight MEDIUM |
89
- | RS-006 | **No page-level horizontal overflow:** `scrollWidth ≤ innerWidth + 8` at every RS width (the calibrated tolerance §C.2 and MD-011 #14 use; a clean reference overflows by 6px at 320 with no visible defect) (an intentional scroll region needs its own visible affordance, see RS-010) | DET | HIGH (auto-HIGH: page-level horizontal scroll) |
90
- | RS-007 | **No unintentional clipped/overlapping text:** Text is not cut by a clipping ancestor unless a deliberate `line-clamp`/`text-overflow` is declared — the declared property alone is a sufficient, self-contained exception and does not itself require a separate "show full text" affordance | DET | clipped or offscreen text: HIGH; overlapping text pairs: MEDIUM (§C.3's split; no probe can classify content as "primary" or "secondary/metadata") |
91
- | RS-008 | **Mobile input font-size floor:** Text-entry controls render ≥16px on a touch-primary width (≤768: 320, 390, 768 and the 720 zoom pass, per CF-701's width rule), or use a documented compensating-scale technique (which keeps a 16px computed `font-size` and so passes the same read) | DET | MEDIUM |
92
- | RS-009 | **Safe-area-aware offsets:** A control fixed to a physical edge adds `env(safe-area-inset-*)` rather than a bare fixed offset; nothing interactive sits under a notch/home-indicator region. Applies only when `<meta name="viewport">` includes `viewport-fit=cover` (without it the UA keeps content inside the safe area and a bare offset is correct) | DET where the CSS is inspectable, else JUDG from a device screenshot | MEDIUM |
93
- | RS-010 | **Horizontal-scroll peek:** A scrollable rail with no other visible scroll cue (prev/next controls, pagination dots/tabs, a position counter) reveals 16–32px of the next off-screen item rather than ending flush | DET | LOW |
94
- | RS-011 | **RTL pass gated by content:** An RTL/bidi mirror check runs only when the brief's real content or shipped locales include an RTL script; logical CSS properties are used throughout so the gated pass is mostly a `dir="rtl"` toggle | JUDG (the gate), DET (the logical-property audit once gated in) | MEDIUM if a physical-direction property appears where the gate says RTL applies |
95
- | RS-012 | **Re-check discipline across states:** A finding recorded at one viewport/theme/zoom state is re-sampled at a second state before being reported as a stable pass | JUDG (procedural) | downgrades a lone-state pass to `not_verified`, not a hard fail |
96
-
97
- ## Apply findings
98
-
99
- Prioritize broken access, contrast, reachable content, and page overflow before aesthetic advisories. A HIGH finding blocks a clean completion claim until fixed or explicitly stated as a limitation with a reason. Keep the evidence tied to the exact viewport and build revision; never retune a threshold to make a run pass. For mechanics that depend on human intent, record an Inferred judgment beside the measured signal rather than claiming the signal proves the verdict.
98
+ | `build` | Full authoring of the requested surface | At least the final round; after every round is better | Working source, the inspected matrix, the review table, a tiered summary |
99
+ | `polish` | Values only (spacing, colour, radius, type size, a motion token); no new component, no changed layout or information architecture | Once as a baseline, once after the fixes | A value-only diff and the before and after tables |
100
+ | `audit` | None, not even a "quick" fix | The probe run is the deliverable | The review table, the Not verified list and the Block or Approve line |
101
+ | `harden` | Only to repair a break the stress pass found; three rounds at most | At every harden axis that applies | A table per axis with the columns Scenario, Observed and Owner, plus the fixes |
102
+
103
+ Mode words (the hook names the mode it detected; the wording and the boundary decide together):
104
+
105
+ - `polish`: *polish*, *clean up the styling*, *tighten up*, *다듬어*, or an explicit "keep the
106
+ layout / 구조는 그대로" scope, when the object is an interface surface. A request that asks for
107
+ a new component or a changed layout under polish wording is a `build`.
108
+ - `audit`: *audit*, *read-only*, *just check*, *tell me what's wrong*, *점검*, *검토만* on an
109
+ interface surface, with no fix requested in the same breath. The route words alone select it;
110
+ no memory of earlier work is needed. `audit` produces the review table as evidence and hands
111
+ the acceptance verdict to `visual-qa`; it never issues that verdict itself. A request that only
112
+ needs proof and carries no audit word still belongs to `visual-qa` directly.
113
+ - `harden`: *harden*, *stress-test*, *hold up under / with*, *robust to*, *튼튼하게*,
114
+ *견고하게* on an interface surface.
115
+ - Never widened toward video, 영상, 모션 or 발표 wording; those belong to other skills. Prose,
116
+ documents, servers and pipelines never trigger polish, audit or harden.
117
+
118
+ **Harden axes.** Name each axis and either run it or write "not applicable: <reason>":
119
+ content length (empty, one word, typical, several sentences, one unbreakable string); content
120
+ shape (emoji, right-to-left, mixed direction, diacritics and tall scripts, aligned numbers);
121
+ quantity (zero, one, realistic, about ten times realistic); container (320 px, squeezed by a
122
+ sibling, very wide); state (loading, error, disabled); environment (dark mode, zoom, reduced
123
+ motion, each toggled live).
124
+
125
+ ## 4. Review format
126
+
127
+ One table, exact column order, every row a real measurement:
128
+
129
+ | Severity | Rule | Where | Measured | Fix |
130
+ |---|---|---|---|---|
131
+ | HIGH, MEDIUM or LOW | a `CF-*`, `RS-*` or `SLOP-*` id | `selector @ viewport` (or `file:line` for a static finding) | the read value and its tier, e.g. `2.9:1 [derived]`, `18×18px [measured]` | the cheapest fix; only `build`, `polish` and `harden` may apply it |
132
+
133
+ Then a **Not verified** list naming every rule that did not run and why (blocked browser, image
134
+ under text, another element painted over text, cross-origin stylesheet or iframe, closed
135
+ disclosures, a lazy image not fetched, a harden axis without a cue). A rule missing from both the table and the list is a defect in the review itself. End with
136
+ **Block** (a HIGH remains that is neither fixed nor stated as a limitation) or **Approve**.
137
+
138
+ These HIGH/MEDIUM/LOW labels only grade probe findings. When a finding moves into
139
+ `references/evidence-review.md` or `references/inclusive-interface.md`, a HIGH maps to at least
140
+ P1 or S2 there; the probe does not rename those ladders. The table is evidence for `visual-qa`,
141
+ never its verdict.
142
+
143
+ **Always HIGH once confirmed**, never downgraded for a small surface or a prototype: a control
144
+ with no accessible name; a keyboard-reachable control with no visible focus; a pointer-only
145
+ control; motion that ignores reduced motion; content clipped, overlapped or unreachable at 320 px
146
+ or 200 % zoom; text under its contrast floor; page-level sideways scrolling; a fake text, nav or
147
+ call-to-action link (`href="#"`, `javascript:`; a logo or icon-only social link is MEDIUM); a
148
+ scroll rail whose next item shows 0 px with no controls, pager or fade. Four more are judgment calls, stated as *Inferred*: meaning carried
149
+ by colour alone; a destructive action with no confirmation or undo; an error that names no way to
150
+ recover; a semantic colour token used for an unrelated meaning. Truncated text is HIGH only when
151
+ the hidden value is needed for a task. The probe opens nothing; open drawers, accordions, tabs and
152
+ dialogs yourself before calling content unreachable.
153
+
154
+ **Reviewing a change.** Read the removed side of each hunk first: a dropped `aria-label`,
155
+ `aria-labelledby` or `role`; a `button`, `nav` or `label` turned into a `div`; a removed
156
+ `:focus-visible` rule, outline or `tabindex`; a token swapped for a literal colour; a shortened
157
+ user-facing string; a removed `prefers-reduced-motion` guard; a `will-change` left behind. Each
158
+ one re-opens the matching always-HIGH item until the added side restores it.
159
+
160
+ ## 5. Responsive matrix (RS)
161
+
162
+ | Id | Rule | Threshold | Severity | Probe |
163
+ |---|---|---|---|---|
164
+ | RS-001 | Canonical widths | 320, 390, 768, 1440 px light, all recorded in `viewports_run` | run completeness: a missing row is `BLOCKED: matrix incomplete`, never a finding | driver |
165
+ | RS-002 | Dark pass at 390 px | a real dark path with mean surface luminance < 0.35, and no new HIGH contrast finding against the light 390 pass; a page whose only dark path is a theme control is not verified (the probe never clicks it) | MEDIUM once the pass ran; an unrun pass is exit 2 | measured (derived for "no dark path") |
166
+ | RS-003 | Reduced motion at 390 px | the query matches, videos paused, no transition or animation over 250 ms per iteration on a motion property (transform, translate, scale, rotate, offsets, inset, size, margin, background-position, `all`); opacity and colour fades and progress or status motion are exempt | HIGH | measured |
167
+ | RS-004 | 1440 px at 200 % zoom (720 CSS px) | RS-006 and RS-007's clipped and offscreen checks re-run there (overlap there stays RS-007) | HIGH | derived |
168
+ | RS-005 | Content-derived breakpoints | a layout change sits where content breaks, not at a bare framework default | LOW, advisory | checklist |
169
+ | RS-006 | No page-level sideways scroll | `scrollWidth ≤ innerWidth + 8px` at every row | HIGH | measured |
170
+ | RS-007 | No clipped, offscreen or overlapping text | nothing cut without `text-overflow` or a line clamp (prefixed or not); no text past the viewport's side edges by more than 8 px outside a sideways scroller (below the fold never counts); overlap < 0.45 of the smaller box; only elements with their own text, accessibility-only spans excluded | clipped or offscreen HIGH; overlap MEDIUM | measured |
171
+ | RS-008 | Mobile input text | text-entry controls (text-like inputs, `textarea`, `select`, `contenteditable`) ≥ 16 px on touch widths (≤ 768 px, the zoom row included) | MEDIUM | measured |
172
+ | RS-009 | Safe-area offsets | only with `viewport-fit=cover`: a fixed or sticky control touching an edge carries `env(safe-area-inset-<edge>)` in its authored offset or padding | MEDIUM | derived (authored declarations; a cross-origin sheet is not verified) |
173
+ | RS-010 | Scroll-rail peek | 16 to 32 px of the next item visible, required only when the rail has no prev/next control, pager, tab or counter | LOW; HIGH when the next item shows 0 px with no cue or fade | measured |
174
+ | RS-011 | RTL pass | only when real content or locales are right-to-left; logical properties throughout | MEDIUM | checklist |
175
+ | RS-012 | Re-check at a second state | a lone-state pass is not verified until re-sampled at another width, theme or focus | downgrade only | checklist |
176
+
177
+ ## 6. Craft floor (CF)
178
+
179
+ Every DOM rule samples only what a person can see: `checkVisibility`, no accessibility-only
180
+ 1 × 1 or `clip` spans, nothing parked off canvas.
181
+
182
+ **Typography**
183
+
184
+ | Id | Rule | Threshold | Severity | Probe |
185
+ |---|---|---|---|---|
186
+ | CF-101 | Body measure | target 60 to 75 characters per line; flagged when a prose block of two or more lines has a longest line over 90 (Latin) or 60 (CJK-majority) in real prose (`p`, long `li`, `blockquote`, `dd`, long `td`; never `nav`, footer or tickers) | MEDIUM, never HIGH | derived |
187
+ | CF-102 | Heading line-height | 1.2 to 1.35 once a heading wraps to two lines; display type ≥ 40 px may go to 1.05 | MEDIUM | measured |
188
+ | CF-103 | Body line-height | flagged below 1.4 (Latin) or 1.5 (CJK) on wrapped prose; 1.5 and 1.6 are the targets; no upper bound | MEDIUM | measured |
189
+ | CF-104 | Wrapped-row floor | ≥ 1.4 for anything that wraps to three or more lines | MEDIUM | measured |
190
+ | CF-105 | Balanced headings | a heading that wraps uses `text-wrap: balance` (`pretty` suits body); a last line under 20 % of the mean of the lines before it is a judgment candidate | LOW | measured; orphans judgment |
191
+ | CF-106 | Tabular figures | numeric table columns and KPIs use `tabular-nums` or `tnum` (monospace passes) | LOW | measured |
192
+ | CF-107 | Sentence case | buttons, links, labels and tabs are not Title Case: every content word after the first capitalised; labels mostly in uncased scripts (Hangul, kana, CJK) are skipped; function words, 2 to 5 letter acronyms, inner capitals, digits and the page's own brand words are exempt; one-word labels never fire | LOW (derived when only one word is capitalised) | measured |
193
+ | CF-108 | Type roles and families | ≤ 7 roles (first family, size to 1 px, weight bucket, form controls excluded) at 390 px; ≤ 2 families plus 1 mono | MEDIUM | judgment (a recorded exception clears it) |
194
+ | CF-109 | Weight by size | ≥ 400 below 18 px; 100 to 300 only for display ≥ 28 px | MEDIUM | checklist |
195
+
196
+ **Colour and contrast**
197
+
198
+ | Id | Rule | Threshold | Severity | Probe |
199
+ |---|---|---|---|---|
200
+ | CF-201 | WCAG 2 contrast | 4.5:1 body; 3:1 for text ≥ 24 px or ≥ 18.5 px bold, and for component edges; background read from the paint stack under the text; disabled controls skipped; another element painted on top is not verified; placeholders belong to CF-807 | HIGH body, MEDIUM large | derived |
201
+ | CF-202 | Focus indicator | in-page focus confirmed as `:focus-visible`, then focused and resting styles compared: outline, shadow, border or background must change; the browser's own `auto` ring passes; a custom ring needs ≥ 2 px and ≥ 3:1 against the colour just outside it | HIGH when focus changes nothing; MEDIUM for a weak custom ring | measured |
202
+ | CF-203 | APCA | advisory Lc figure beside every CF-201 finding (body 75, non-body 60, large 45, components 30) | information | in the note |
203
+ | CF-204 | Text over image or gradient | on a CSS gradient the text clears CF-201's floor against its worst colour stop; text over an image is not verified | HIGH | derived |
204
+ | CF-205 | Accent families per view | ≤ 4 saturated hue clusters (±15°) among filled surfaces ≥ 24 × 24 px in the default rich register, ≤ 1 when the lock records `density: calm`; status roles, live regions, `aria-invalid`, success/warning/error/danger/info-style class tokens and pills ≤ 32 px tall excluded | MEDIUM | measured |
205
+ | CF-206 | Hue tolerance | hues within 15° count as one meaning | LOW | inside CF-205 |
206
+ | CF-207 | Not colour alone | state carries text, an icon or a pattern too | HIGH | checklist (Inferred) |
207
+
208
+ **Spacing and surfaces**
209
+
210
+ | Id | Rule | Threshold | Severity | Probe |
211
+ |---|---|---|---|---|
212
+ | CF-301 | One spacing scale | padding, gap and margin within ±1 px of a 4 px multiple; values under 4 px and centred auto margins skipped | LOW for 1 to 3 off-scale values, MEDIUM above | measured |
213
+ | CF-302 | Grouping ratio | gap between groups ≥ 2 × the gap inside a group | MEDIUM | checklist |
214
+ | CF-303 | Room between blocks | ≥ 12 px between bordered or filled blocks, ≥ 24 px around borderless ones (non-interactive only) | MEDIUM | checklist |
215
+ | CF-304 | Heading rhythm | target about twice the space above a heading as below; flagged only on a clear inversion (above < 0.75 × below and 12 px short), measured on rendered boxes; a heading that opens a card is not scored | LOW | measured |
216
+ | CF-305 | Full-width control inset | about 16 px from the viewport edge at 320 and 390 px | LOW | checklist |
217
+ | CF-306 | Container `gap` | rhythm from the parent's `gap`, not child margins | LOW | checklist |
218
+ | CF-401 | Concentric radius | inner = outer − padding, ±2 px, compared per corner where the child reaches that corner, radii capped at half the short side, padding ≤ 24 px | LOW | measured |
219
+ | CF-402 | Elevation once | no hard ≤ 2 px shadow retracing a border | LOW | checklist |
220
+ | CF-403 | Hard offset shadow | a zero-blur shadow offset past a hairline, unless the direction records a neo-brutalist register (a `design.lock.json` with `offset` elevation, the `neo-brutalism` house style, records one; without a lock the probe's proxy is the same shadow on ≥ 3 elements that each carry a ≥ 2 px solid border) | MEDIUM | measured |
221
+ | CF-404 | No glow on the primary action | no ≤ 2 px offset, ≥ 16 px blur, saturation > 0.4 shadow on the primary action or a heading; the same glow on ≥ 3 unrelated elements is reported once, as SLOP-010; a glow on a section, panel or the moment (the kit's `ui-glow`) is not a control halo and is never reported | LOW | measured |
222
+ | CF-405 | Neutral image outline | ~1 px, low opacity, saturation < 15 % | LOW | checklist |
223
+ | CF-406 | Solid scrim | no `backdrop-filter: blur` on a full-viewport overlay | LOW | measured |
224
+ | CF-407 | Decorative patterns | grids, halos, marquees and stripes need a real referent (see the slop register) | LOW to MEDIUM | via SLOP rows |
225
+
226
+ **Motion**
227
+
228
+ | Id | Rule | Threshold | Severity | Probe |
229
+ |---|---|---|---|---|
230
+ | CF-501 | Motion tokens | `enter` 420 ms, `ui` 180 ms, `exit` 160 ms as `references/motion-guide.md` defines | LOW | checklist |
231
+ | CF-502 | Press feedback | the `:active` rule scales to 0.95 to 0.96 over ≤ 150 ms, read from the stylesheet (never pressed) | LOW | derived; no readable rule is not verified |
232
+ | CF-503 | Entrance scale | an entrance starts at ≥ 0.95 scale, never from 0 (icon cross-fades excepted) | MEDIUM when running, LOW when only declared; never HIGH | measured or derived |
233
+ | CF-504 | Exit shorter than entrance | same path reversed | LOW | checklist |
234
+ | CF-505 | No bounce on feedback | cubic-bezier y values and `linear()` stops inside −0.1 to 1.1, also on running Web Animations; an `animation-name` token bounce, elastic, wobble, jiggle or spring (a per-frame script spring stays invisible to the probe) | MEDIUM | measured (derived for a name) |
235
+ | CF-506 | High-frequency motion | ≤ 150 ms for controls repeated ≥ 5 times in a list, table or scroller, read after a real hover at 1440 px | LOW | measured |
236
+ | CF-507 | `will-change` | only `transform`, `opacity`, `filter` (state rules included), only while animating; "at rest" read in the resting pass only | LOW; MEDIUM at rest | measured |
237
+ | CF-508 | No layout animation | never animate width, height, padding, margin or offsets (disclosure height excepted) | MEDIUM | measured |
238
+ | CF-509 | Reduced-motion path works | every state and control stays reachable with reduce on | HIGH | via RS-003 plus judgment |
239
+ | CF-510 | Slow replay | replay entrances and feedback slowly before sign-off | LOW | checklist |
240
+
241
+ **Icons, targets, microcopy**
242
+
243
+ | Id | Rule | Threshold | Severity | Probe |
244
+ |---|---|---|---|---|
245
+ | CF-601 | One icon system | one grid, one stroke weight per set | MEDIUM | checklist |
246
+ | CF-602 | Icon size | about 1 to 1.25 × the adjacent cap height, legible at 16 px | LOW | checklist |
247
+ | CF-603 | Named controls | every focusable control, `[tabindex]` ≥ 0 included, has an accessible name; never an unlabeled destructive icon | HIGH | measured |
248
+ | CF-604 | Optical alignment | icon-side padding about 2 px tighter | LOW | checklist |
249
+ | CF-701 | Target size | < 24 px HIGH unless the WCAG 2.5.8 spacing exception holds; under 44 px on touch widths (≤ 768 px) MEDIUM, HIGH for the primary action (a form's sole submit, or the first filled button or button link in the first viewport); inline prose links exempt | HIGH or MEDIUM | measured |
250
+ | CF-702 | Target clearance | ≥ 8 px between touch targets (≤ 768 px), ≥ 4 px at 1440 px | MEDIUM | measured |
251
+ | CF-703 | Destructive targets | 44 px on every pointer type | HIGH | measured |
252
+ | CF-704 | Pointer-only actions | no control revealed only by an ancestor `:hover` rule without a matching `:focus-within` or `:focus-visible` reveal; other drag and long-press cases are judgment | HIGH | measured (stylesheet); rest Inferred |
253
+ | CF-801 | Verb-first labels | actions start with a verb in plain words | LOW to MEDIUM | checklist |
254
+ | CF-802 | Tone by stakes | warm for success, neutral for routine, calm for errors, serious for data loss | checklist | checklist |
255
+ | CF-803 | Useful errors | say what happened and how to recover | MEDIUM | checklist |
256
+ | CF-804 | One capitalisation policy | sentence case throughout, or a written exception list | LOW | via CF-107 |
257
+ | CF-805 | Toggle labels | name the state that turns on | checklist | checklist |
258
+ | CF-806 | Real labels | a placeholder is never the only label | MEDIUM | measured |
259
+ | CF-807 | Placeholder contrast | ≥ 4.5:1 against the field | MEDIUM | derived |
260
+
261
+ A *checklist* row has no DET method in this probe; review it by eye and tag the claim Inferred.
262
+ The office and diagram skills carry their own subset of these rules in their QA scripts.
@@ -2,16 +2,12 @@ Explore direction only after the critical task, success signals, and surface lis
2
2
 
3
3
  ## Close the brief before exploring
4
4
 
5
- Write the fixed constraints first so exploration terminates.
6
-
7
5
  - Critical task, the two frequent secondary tasks, and return frequency.
8
6
  - Immovable inputs: existing tokens, approved marks, locales, viewport bands.
9
7
  - Direction count: 3, never more than 4.
10
8
 
11
9
  ## Read the archetype set
12
10
 
13
- Each archetype is neutral. Pick by which risk this product can absorb, not by taste.
14
-
15
11
  1. Editorial grid — modular columns, visible rules, one restrained accent. Risk: every block weighs the same; no focal point.
16
12
  2. Reduced utility — near-monochrome, one accent, large gutters, few borders. Risk: interactive and static elements look alike.
17
13
  3. Humanist soft — rounded radii, humanist sans, warm neutrals, low elevation. Risk: casual where the task is financial or clinical.
@@ -23,8 +19,6 @@ Each archetype is neutral. Pick by which risk this product can absorb, not by ta
23
19
 
24
20
  ## Blend with one base and one guest
25
21
 
26
- Two archetypes at equal weight produce mush. Subordinate one of them explicitly.
27
-
28
22
  - The base owns grid, spacing scale, radius, and density; it is not renegotiated.
29
23
  - The guest contributes exactly one dimension: type, color, or surface treatment.
30
24
  - A second import is not a refinement; it is a third direction.
@@ -69,3 +63,12 @@ Selection ends exploration. Rejected work stays readable so the decision is not
69
63
  - Keep each rejected `direction_id` with a one-line reason.
70
64
  - Freeze before token work; a later change needs an `accepted_exceptions` entry with owner and expiry.
71
65
  - Record the design contract hash the independent review pass binds its receipt to.
66
+
67
+ ## Failure patterns
68
+
69
+ Reject:
70
+
71
+ - Directions differing only in accent hue or corner radius.
72
+ - A blend with two imported dimensions and no owning base.
73
+ - "Modern", "clean", or "premium" standing in for a decision.
74
+ - A direction with no kill condition, which can never be wrong.
@@ -0,0 +1,28 @@
1
+ {
2
+ "schema_id": "litfamily.frontend-default-profile/v1",
3
+ "name": "Field notes / pixel signal",
4
+ "authorship": "Original LitGrok profile outside the immutable library",
5
+ "hierarchy": ["large editorial title with intentional breaks", "small terminal labels", "a tight editorial rhythm with thin rules, notebook-dot paper and a second accent", "layered surfaces: a colour band, a two-accent wash and one atmosphere glow", "asymmetric atmospheric field", "original task-specific pixel-art illustration as the primary visual anchor when the brief gives no visual direction"],
6
+ "spacing": {"unit_px": 8, "detail_px": 4, "section_desktop_px": [72, 96], "section_mobile_px": [40, 56]},
7
+ "density": {"default": "rich", "calm_only_when": "the request asks for a minimal, calm, quiet or restrained page (미니멀, 차분, 절제), or design-lock.mjs init --density calm; calm restores 64 to 128 px sections, a flat canvas and no glow"},
8
+ "type": {"display_desktop_px": [56, 104], "display_mobile_px": [36, 56], "latin_leading": [0.95, 1.05], "korean_leading": [1.12, 1.25], "body_leading": [1.5, 1.7]},
9
+ "palette": {"paper": "#f5f3eb", "ink": "#18272b", "accent": "#c64d2e", "accent_2": "#1d6b68", "mist": "#b7d8c7"},
10
+ "pixel_art": {
11
+ "default_when_unspecified": true,
12
+ "primary_visual_anchor": true,
13
+ "description": "When the brief gives no visual direction, use an original, task-specific pixel-art illustration as the primary visual anchor without asking. A brief that names competing directions without choosing them is unresolved, not unspecified.",
14
+ "method": "author a recognizable integer-grid motif with hard edges and nearest-neighbor scaling",
15
+ "minimum_rendered_cell_size_css_px": 6,
16
+ "rendering": "crisp and non-smoothed; use nearest-neighbor scaling and disable interpolation",
17
+ "constraint": "recognizable task-related subject, not random noise or a smooth icon"
18
+ },
19
+ "work_surfaces": {
20
+ "applies_to": "screens people work in repeatedly, such as admin consoles, analytics views and internal tools, as opposed to pages people read once",
21
+ "first_viewport": "the working content and primary controls; no hero headline, tagline or illustration block above them",
22
+ "pixel_art": "a small accent at most, never the primary visual anchor",
23
+ "keeps": "nothing of this palette: work surfaces lock the graphite house style (scripts/design-lock.mjs family default); the pixel art stays a small accent at most"
24
+ },
25
+ "responsive": {"minimum_css_width": 320, "rule": "reflow content and line breaks, never crop the title"},
26
+ "motion": "layered motion is welcome where it explains or delights (see references/motion-guide.md); state changes remain understandable with nonessential motion disabled",
27
+ "precedence": "explicit user direction and existing brand tokens override this default; if the brief names competing visual directions without choosing or delegating one, ask before applying it"
28
+ }