@phuc1403/musketeer 0.8.0 → 0.10.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.
- package/INSTALLATION.md +52 -52
- package/README.md +49 -49
- package/bin/musketeer.js +168 -168
- package/manifest.json +333 -301
- package/package.json +48 -48
- package/src/dotnet-scaffold-copier.js +79 -79
- package/src/provisioner/detect.js +93 -93
- package/src/self-update.js +77 -77
- package/template/.claude/agents/code-reviewer.md +182 -166
- package/template/.claude/agents/git-manager.md +18 -18
- package/template/.claude/agents/hallmark-auditor.md +78 -78
- package/template/.claude/agents/researcher.md +33 -33
- package/template/.claude/hooks/block-unsafe-adr-title.cjs +85 -85
- package/template/.claude/hooks/git-skill-reminder.cjs +53 -0
- package/template/.claude/hooks/init-adr-dir.cjs +173 -173
- package/template/.claude/hooks/inject-adr-flags.cjs +94 -94
- package/template/.claude/hooks/lib/adr/command-scan.cjs +115 -115
- package/template/.claude/hooks/lib/characteristics/checker.cjs +357 -357
- package/template/.claude/hooks/lib/colors.cjs +180 -122
- package/template/.claude/hooks/lib/git-info-cache.cjs +191 -191
- package/template/.claude/hooks/lib/transcript-parser.cjs +300 -277
- package/template/.claude/hooks/sync-adr-toc.cjs +146 -146
- package/template/.claude/hooks/{usage-context-awareness.cjs → usage-quota-cache-refresh.cjs} +166 -166
- package/template/.claude/hooks/validate-characteristics-hook.cjs +66 -66
- package/template/.claude/hooks/validate-cml-hook.js +145 -145
- package/template/.claude/skills/adr-writer/SKILL.md +48 -48
- package/template/.claude/skills/adr-writer/references/adr-example.md +35 -35
- package/template/.claude/skills/architecture-characteristic-writer/SKILL.md +215 -215
- package/template/.claude/skills/architecture-characteristic-writer/assets/worksheet-template.md +29 -29
- package/template/.claude/skills/architecture-characteristic-writer/references/characteristics-catalog.md +40 -40
- package/template/.claude/skills/architecture-characteristic-writer/scripts/ranking-table.cjs +171 -171
- package/template/.claude/skills/code-review/SKILL.md +201 -54
- package/template/.claude/skills/code-review/references/checklist-workflow.md +96 -0
- package/template/.claude/skills/code-review/references/checklists/api.md +52 -52
- package/template/.claude/skills/code-review/references/checklists/base.md +100 -100
- package/template/.claude/skills/code-review/references/checklists/web-app.md +54 -54
- package/template/.claude/skills/code-review/references/code-review-reception.md +113 -0
- package/template/.claude/skills/code-review/references/codebase-scan-workflow.md +30 -0
- package/template/.claude/skills/code-review/references/edge-case-scouting.md +119 -0
- package/template/.claude/skills/code-review/references/input-mode-resolution.md +135 -0
- package/template/.claude/skills/code-review/references/parallel-review-workflow.md +76 -0
- package/template/.claude/skills/code-review/references/requesting-code-review.md +116 -0
- package/template/.claude/skills/code-review/references/spec-compliance-review.md +43 -0
- package/template/.claude/skills/code-review/references/task-management-reviews.md +140 -0
- package/template/.claude/skills/code-review/references/verification-before-completion.md +139 -0
- package/template/.claude/skills/context-map/SKILL.md +80 -80
- package/template/.claude/skills/context-map/example.cml +106 -106
- package/template/.claude/skills/context-map/reference/Bounded Context/Bounded Context.md +40 -40
- package/template/.claude/skills/context-map/reference/Bounded Context/businessModel.md +5 -5
- package/template/.claude/skills/context-map/reference/Bounded Context/domainVisionStatement.md +2 -2
- package/template/.claude/skills/context-map/reference/Bounded Context/evolution.md +5 -5
- package/template/.claude/skills/context-map/reference/Bounded Context/implementationTechnology.md +1 -1
- package/template/.claude/skills/context-map/reference/Bounded Context/implements.md +1 -1
- package/template/.claude/skills/context-map/reference/Bounded Context/knowledgeLevel.md +4 -4
- package/template/.claude/skills/context-map/reference/Bounded Context/realizes.md +9 -9
- package/template/.claude/skills/context-map/reference/Bounded Context/refines.md +10 -10
- package/template/.claude/skills/context-map/reference/Bounded Context/responsibilities.md +26 -26
- package/template/.claude/skills/context-map/reference/Bounded Context/type.md +23 -23
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Anticorruption Layer.md +5 -5
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Bounded Context Relationship.md +12 -12
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Conformist.md +5 -5
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Customer-Supplier (C-S).md +22 -22
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Open Host Service.md +4 -4
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Partnership (P).md +13 -13
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Published Language.md +4 -4
- package/template/.claude/skills/context-map/reference/Bounded Context Relationship/Shared Kernel (SK).md +12 -12
- package/template/.claude/skills/context-map/reference/Context Map.md +62 -62
- package/template/.claude/skills/context-map/reference/Domain/Domain.md +30 -30
- package/template/.claude/skills/context-map/reference/Domain/supports.md +33 -33
- package/template/.claude/skills/context-map/reference/Domain/type.md +3 -3
- package/template/.claude/skills/context-map/reference/Semantic Rules.md +32 -32
- package/template/.claude/skills/git/SKILL.md +131 -115
- package/template/.claude/skills/git/references/branch-management.md +88 -88
- package/template/.claude/skills/git/references/commit-standards.md +46 -46
- package/template/.claude/skills/git/references/context-efficiency.md +54 -0
- package/template/.claude/skills/git/references/gh-cli-guide.md +109 -109
- package/template/.claude/skills/git/references/safety-protocols.md +69 -69
- package/template/.claude/skills/git/references/workflow-commit.md +58 -58
- package/template/.claude/skills/git/references/workflow-merge-pr.md +136 -0
- package/template/.claude/skills/git/references/workflow-merge.md +48 -48
- package/template/.claude/skills/git/references/workflow-pr.md +58 -58
- package/template/.claude/skills/git/references/workflow-push.md +52 -52
- package/template/.claude/skills/hallmark/SKILL.md +552 -552
- package/template/.claude/skills/hallmark/references/anti-patterns.md +412 -412
- package/template/.claude/skills/hallmark/references/assets.md +406 -406
- package/template/.claude/skills/hallmark/references/color.md +95 -95
- package/template/.claude/skills/hallmark/references/component-cookbook.md +256 -256
- package/template/.claude/skills/hallmark/references/components/c1-outlined-chip.md +12 -12
- package/template/.claude/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -16
- package/template/.claude/skills/hallmark/references/components/c3-typographic-link.md +8 -8
- package/template/.claude/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -16
- package/template/.claude/skills/hallmark/references/components/f1-bento-grid.md +20 -20
- package/template/.claude/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -20
- package/template/.claude/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -11
- package/template/.claude/skills/hallmark/references/components/f4-step-sequence.md +11 -11
- package/template/.claude/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -11
- package/template/.claude/skills/hallmark/references/components/f6-product-card-grid.md +41 -41
- package/template/.claude/skills/hallmark/references/components/ft1-mast-headed.md +13 -13
- package/template/.claude/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -10
- package/template/.claude/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -12
- package/template/.claude/skills/hallmark/references/components/ft4-dense-typographic.md +10 -10
- package/template/.claude/skills/hallmark/references/components/ft5-statement.md +21 -21
- package/template/.claude/skills/hallmark/references/components/ft6-letter-close.md +19 -19
- package/template/.claude/skills/hallmark/references/components/ft7-newsletter-first.md +27 -27
- package/template/.claude/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -25
- package/template/.claude/skills/hallmark/references/components/h1-marquee.md +15 -15
- package/template/.claude/skills/hallmark/references/components/h2-split-diptych.md +15 -15
- package/template/.claude/skills/hallmark/references/components/h3-quote-led.md +11 -11
- package/template/.claude/skills/hallmark/references/components/h4-stat-led.md +14 -14
- package/template/.claude/skills/hallmark/references/components/h5-letter-hero.md +11 -11
- package/template/.claude/skills/hallmark/references/components/h6-photographic-fold.md +16 -16
- package/template/.claude/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -27
- package/template/.claude/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -23
- package/template/.claude/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -27
- package/template/.claude/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -12
- package/template/.claude/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -19
- package/template/.claude/skills/hallmark/references/components/n2-floating-chip.md +14 -14
- package/template/.claude/skills/hallmark/references/components/n3-side-rail.md +14 -14
- package/template/.claude/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -9
- package/template/.claude/skills/hallmark/references/components/n5-floating-pill.md +28 -28
- package/template/.claude/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -24
- package/template/.claude/skills/hallmark/references/components/n7-brutal-slab.md +22 -22
- package/template/.claude/skills/hallmark/references/components/n8-terminal-command.md +21 -21
- package/template/.claude/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -17
- package/template/.claude/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -15
- package/template/.claude/skills/hallmark/references/components/s2-hanging.md +13 -13
- package/template/.claude/skills/hallmark/references/components/s3-sticky-pinned.md +19 -19
- package/template/.claude/skills/hallmark/references/components/s4-inline-no-break.md +11 -11
- package/template/.claude/skills/hallmark/references/components/s5-bottom-anchored.md +13 -13
- package/template/.claude/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -12
- package/template/.claude/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -19
- package/template/.claude/skills/hallmark/references/components/t3-single-huge-quote.md +11 -11
- package/template/.claude/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -14
- package/template/.claude/skills/hallmark/references/contract.md +24 -24
- package/template/.claude/skills/hallmark/references/copy.md +182 -182
- package/template/.claude/skills/hallmark/references/custom-craft.md +626 -626
- package/template/.claude/skills/hallmark/references/custom-theme.md +329 -329
- package/template/.claude/skills/hallmark/references/design-md.md +116 -116
- package/template/.claude/skills/hallmark/references/export-formats.md +328 -328
- package/template/.claude/skills/hallmark/references/floating-nav.md +89 -89
- package/template/.claude/skills/hallmark/references/genres/atmospheric.md +65 -65
- package/template/.claude/skills/hallmark/references/genres/editorial.md +70 -70
- package/template/.claude/skills/hallmark/references/genres/modern-minimal.md +67 -67
- package/template/.claude/skills/hallmark/references/genres/playful.md +65 -65
- package/template/.claude/skills/hallmark/references/hero-enrichment.md +474 -474
- package/template/.claude/skills/hallmark/references/imagery-kit.md +170 -170
- package/template/.claude/skills/hallmark/references/interaction-and-states.md +207 -207
- package/template/.claude/skills/hallmark/references/layout-and-space.md +111 -111
- package/template/.claude/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -35
- package/template/.claude/skills/hallmark/references/macrostructures/02-long-document.md +34 -34
- package/template/.claude/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -31
- package/template/.claude/skills/hallmark/references/macrostructures/04-stat-led.md +32 -32
- package/template/.claude/skills/hallmark/references/macrostructures/05-workbench.md +32 -32
- package/template/.claude/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -33
- package/template/.claude/skills/hallmark/references/macrostructures/07-manifesto.md +32 -32
- package/template/.claude/skills/hallmark/references/macrostructures/08-photographic.md +34 -34
- package/template/.claude/skills/hallmark/references/macrostructures/09-quote-led.md +32 -32
- package/template/.claude/skills/hallmark/references/macrostructures/10-specimen.md +32 -32
- package/template/.claude/skills/hallmark/references/macrostructures/11-catalogue.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/12-letter.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/13-index-first.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/15-split-studio.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures/21-component-playground.md +23 -23
- package/template/.claude/skills/hallmark/references/macrostructures.md +89 -89
- package/template/.claude/skills/hallmark/references/microinteractions.md +260 -260
- package/template/.claude/skills/hallmark/references/motion.md +109 -109
- package/template/.claude/skills/hallmark/references/preview-examples.md +49 -49
- package/template/.claude/skills/hallmark/references/responsive.md +138 -138
- package/template/.claude/skills/hallmark/references/slop-test.md +205 -205
- package/template/.claude/skills/hallmark/references/structure.md +164 -164
- package/template/.claude/skills/hallmark/references/study.md +511 -511
- package/template/.claude/skills/hallmark/references/typography.md +243 -243
- package/template/.claude/skills/hallmark/references/verbs/audit.md +25 -25
- package/template/.claude/skills/hallmark/references/verbs/redesign.md +269 -269
- package/template/.claude/skills/hallmark-loop/SKILL.md +105 -105
- package/template/.claude/skills/hallmark-loop/references/auditor-call.md +60 -60
- package/template/.claude/skills/hallmark-loop/references/capture.md +78 -78
- package/template/.claude/skills/hallmark-loop/references/loop-control.md +79 -79
- package/template/.claude/skills/handoff/SKILL.md +15 -15
- package/template/.claude/skills/knowledge-crunching/SKILL.md +94 -94
- package/template/.claude/skills/research/SKILL.md +69 -69
- package/template/.claude/skills/skill-creator/LICENSE.txt +201 -201
- package/template/.claude/skills/skill-creator/SKILL.md +154 -149
- package/template/.claude/skills/skill-creator/agents/analyzer.md +274 -274
- package/template/.claude/skills/skill-creator/agents/comparator.md +202 -202
- package/template/.claude/skills/skill-creator/agents/grader.md +223 -223
- package/template/.claude/skills/skill-creator/assets/eval_review.html +146 -146
- package/template/.claude/skills/skill-creator/eval-viewer/generate_review.py +471 -471
- package/template/.claude/skills/skill-creator/eval-viewer/viewer.html +1325 -1325
- package/template/.claude/skills/skill-creator/references/benchmark-optimization-guide.md +86 -86
- package/template/.claude/skills/skill-creator/references/distribution-guide.md +79 -79
- package/template/.claude/skills/skill-creator/references/eval-infrastructure-guide.md +129 -129
- package/template/.claude/skills/skill-creator/references/eval-schemas.md +121 -121
- package/template/.claude/skills/skill-creator/references/mcp-skills-integration.md +71 -71
- package/template/.claude/skills/skill-creator/references/metadata-quality-criteria.md +94 -94
- package/template/.claude/skills/skill-creator/references/plugin-marketplace-hosting.md +104 -104
- package/template/.claude/skills/skill-creator/references/plugin-marketplace-overview.md +89 -89
- package/template/.claude/skills/skill-creator/references/plugin-marketplace-schema.md +93 -93
- package/template/.claude/skills/skill-creator/references/plugin-marketplace-sources.md +103 -103
- package/template/.claude/skills/skill-creator/references/plugin-marketplace-troubleshooting.md +76 -76
- package/template/.claude/skills/skill-creator/references/script-quality-criteria.md +106 -106
- package/template/.claude/skills/skill-creator/references/skill-anatomy-and-requirements.md +77 -77
- package/template/.claude/skills/skill-creator/references/skill-creation-workflow.md +152 -151
- package/template/.claude/skills/skill-creator/references/skill-design-patterns.md +75 -75
- package/template/.claude/skills/skill-creator/references/skillmark-benchmark-criteria.md +102 -102
- package/template/.claude/skills/skill-creator/references/structure-organization-criteria.md +114 -114
- package/template/.claude/skills/skill-creator/references/testing-and-iteration.md +78 -78
- package/template/.claude/skills/skill-creator/references/token-efficiency-criteria.md +74 -74
- package/template/.claude/skills/skill-creator/references/troubleshooting-guide.md +81 -81
- package/template/.claude/skills/skill-creator/references/validation-checklist.md +83 -83
- package/template/.claude/skills/skill-creator/references/writing-effective-instructions.md +88 -88
- package/template/.claude/skills/skill-creator/references/yaml-frontmatter-reference.md +92 -92
- package/template/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +401 -401
- package/template/.claude/skills/skill-creator/scripts/encoding_utils.py +36 -36
- package/template/.claude/skills/skill-creator/scripts/generate_report.py +326 -326
- package/template/.claude/skills/skill-creator/scripts/improve_description.py +248 -248
- package/template/.claude/skills/skill-creator/scripts/init_skill.py +360 -360
- package/template/.claude/skills/skill-creator/scripts/package_skill.py +143 -143
- package/template/.claude/skills/skill-creator/scripts/quick_validate.py +110 -110
- package/template/.claude/skills/skill-creator/scripts/run_eval.py +310 -310
- package/template/.claude/skills/skill-creator/scripts/run_loop.py +332 -332
- package/template/.claude/skills/skill-creator/scripts/utils.py +47 -47
- package/template/.claude/skills/tdd/SKILL.md +142 -142
- package/template/.claude/skills/tdd/deep-modules.md +15 -15
- package/template/.claude/skills/tdd/interface-design.md +31 -31
- package/template/.claude/skills/tdd/mocking.md +59 -59
- package/template/.claude/skills/tdd/refactoring.md +10 -10
- package/template/.claude/skills/tdd/tests.md +61 -61
- package/template/.claude/statusline.cjs +0 -0
- package/template/.claude/skills/code-review/references/adversarial-review.md +0 -223
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
# Motion
|
|
2
|
-
|
|
3
|
-
Most AI-generated motion is scattered — hover lifts on every card, fade-in on every scroll, bouncing icons. Quiet it. One orchestrated moment beats ten small ones.
|
|
4
|
-
|
|
5
|
-
> For per-interaction recipes (button press, focus, modal, toast, optimistic update, command palette, drag handle, etc.), see [`microinteractions.md`](microinteractions.md). This file is the *language* of motion; that file is the *vocabulary*.
|
|
6
|
-
|
|
7
|
-
## Principles
|
|
8
|
-
|
|
9
|
-
- **Animate only `transform` and `opacity`.** These are GPU-composited; they don't trigger layout. Anything else is a performance bug waiting.
|
|
10
|
-
- **Duration is three buckets.** Micro (100–150ms), minor (200–300ms), major (300–500ms). Exits are ~75% of the enter.
|
|
11
|
-
- **Easing is exponential ease-out.** Elements coming in slow down into place. Elements leaving accelerate away.
|
|
12
|
-
- **Motion serves perception.** If you can't explain what a transition communicates, cut it.
|
|
13
|
-
- **Reduced motion is non-optional.** `@media (prefers-reduced-motion: reduce)` collapses all spatial motion to opacity crossfade.
|
|
14
|
-
|
|
15
|
-
## Easings
|
|
16
|
-
|
|
17
|
-
Use these three. Name them as tokens.
|
|
18
|
-
|
|
19
|
-
```css
|
|
20
|
-
:root {
|
|
21
|
-
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* elements entering */
|
|
22
|
-
--ease-in: cubic-bezier(0.7, 0, 0.84, 0); /* elements leaving */
|
|
23
|
-
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* state toggles */
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
`ease`, `ease-in-out` (default), `cubic-bezier(0.25, 0.1, 0.25, 1)` — these are the browser defaults and they read as uncrafted.
|
|
28
|
-
|
|
29
|
-
## Durations
|
|
30
|
-
|
|
31
|
-
```css
|
|
32
|
-
:root {
|
|
33
|
-
--dur-micro: 120ms; /* button press, toggle tick, color shift */
|
|
34
|
-
--dur-short: 220ms; /* hover lift, tooltip, menu open */
|
|
35
|
-
--dur-long: 420ms; /* modal, drawer, accordion, page reveal */
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Exits use roughly 75% of the enter:
|
|
40
|
-
|
|
41
|
-
```css
|
|
42
|
-
.menu.is-open { transition: transform var(--dur-short) var(--ease-out); }
|
|
43
|
-
.menu.is-close { transition: transform calc(var(--dur-short) * 0.75) var(--ease-in); }
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Page-load orchestration
|
|
47
|
-
|
|
48
|
-
One sequence on page load. Stagger by DOM index using a CSS custom property, not by JS.
|
|
49
|
-
|
|
50
|
-
```html
|
|
51
|
-
<section style="--i: 0">…</section>
|
|
52
|
-
<section style="--i: 1">…</section>
|
|
53
|
-
<section style="--i: 2">…</section>
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
```css
|
|
57
|
-
.reveal {
|
|
58
|
-
opacity: 0;
|
|
59
|
-
transform: translateY(8px);
|
|
60
|
-
animation: reveal var(--dur-long) var(--ease-out) forwards;
|
|
61
|
-
animation-delay: calc(var(--i, 0) * 60ms);
|
|
62
|
-
}
|
|
63
|
-
@keyframes reveal {
|
|
64
|
-
to { opacity: 1; transform: none; }
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Cap total stagger at ~500ms. Beyond that the page feels slow to settle.
|
|
69
|
-
|
|
70
|
-
## Scroll-linked motion
|
|
71
|
-
|
|
72
|
-
- Use IntersectionObserver, **never** `scroll` event listeners.
|
|
73
|
-
- Use it only for *reveal once* effects. No parallax. No scroll-scrubbed animations unless there is a specific reason.
|
|
74
|
-
- Every scroll-triggered motion must have a reduced-motion fallback.
|
|
75
|
-
|
|
76
|
-
## State transitions
|
|
77
|
-
|
|
78
|
-
- Button hover / active: micro duration, `--ease-out`, `transform: translateY(-1px)` on hover, `translateY(0)` on active. Never a `box-shadow` transition on hover on a dark background (glow effect).
|
|
79
|
-
- Menu / tooltip / dropdown: short duration, `--ease-out` on open, `--ease-in` on close. Use the popover API or `inert` to manage focus.
|
|
80
|
-
- Modal: long duration, scale-in (0.96 → 1) + opacity crossfade. Backdrop fades in at the same duration.
|
|
81
|
-
- Accordion: animate `grid-template-rows: 0fr` → `grid-template-rows: 1fr` (not `height`). With `--ease-in-out`.
|
|
82
|
-
|
|
83
|
-
## Reduced motion
|
|
84
|
-
|
|
85
|
-
```css
|
|
86
|
-
@media (prefers-reduced-motion: reduce) {
|
|
87
|
-
*, *::before, *::after {
|
|
88
|
-
animation-duration: 150ms !important;
|
|
89
|
-
animation-iteration-count: 1 !important;
|
|
90
|
-
transition-duration: 150ms !important;
|
|
91
|
-
}
|
|
92
|
-
.reveal { animation: reveal-reduced 150ms linear forwards; }
|
|
93
|
-
@keyframes reveal-reduced { to { opacity: 1; transform: none; } }
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Functional motion (progress bars, loading spinners, skeletons) still runs — just slower.
|
|
98
|
-
|
|
99
|
-
## Bans
|
|
100
|
-
|
|
101
|
-
- `ease` (browser default, mediocre).
|
|
102
|
-
- `linear` on anything except progress bars and ticking loaders.
|
|
103
|
-
- Bounce / elastic / overshoot on UI elements. Dated; signals "template".
|
|
104
|
-
- Animating `width`, `height`, `top`, `left`, `margin`, `padding`.
|
|
105
|
-
- `will-change` set preemptively across a whole class. Only on the element, only while it's animating.
|
|
106
|
-
- Parallax.
|
|
107
|
-
- Custom cursors.
|
|
108
|
-
- Scroll-driven animations without a reduced-motion fallback.
|
|
109
|
-
- Infinite loops (other than functional loaders) — they pull the eye and never let go.
|
|
1
|
+
# Motion
|
|
2
|
+
|
|
3
|
+
Most AI-generated motion is scattered — hover lifts on every card, fade-in on every scroll, bouncing icons. Quiet it. One orchestrated moment beats ten small ones.
|
|
4
|
+
|
|
5
|
+
> For per-interaction recipes (button press, focus, modal, toast, optimistic update, command palette, drag handle, etc.), see [`microinteractions.md`](microinteractions.md). This file is the *language* of motion; that file is the *vocabulary*.
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
- **Animate only `transform` and `opacity`.** These are GPU-composited; they don't trigger layout. Anything else is a performance bug waiting.
|
|
10
|
+
- **Duration is three buckets.** Micro (100–150ms), minor (200–300ms), major (300–500ms). Exits are ~75% of the enter.
|
|
11
|
+
- **Easing is exponential ease-out.** Elements coming in slow down into place. Elements leaving accelerate away.
|
|
12
|
+
- **Motion serves perception.** If you can't explain what a transition communicates, cut it.
|
|
13
|
+
- **Reduced motion is non-optional.** `@media (prefers-reduced-motion: reduce)` collapses all spatial motion to opacity crossfade.
|
|
14
|
+
|
|
15
|
+
## Easings
|
|
16
|
+
|
|
17
|
+
Use these three. Name them as tokens.
|
|
18
|
+
|
|
19
|
+
```css
|
|
20
|
+
:root {
|
|
21
|
+
--ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* elements entering */
|
|
22
|
+
--ease-in: cubic-bezier(0.7, 0, 0.84, 0); /* elements leaving */
|
|
23
|
+
--ease-in-out: cubic-bezier(0.65, 0, 0.35, 1); /* state toggles */
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`ease`, `ease-in-out` (default), `cubic-bezier(0.25, 0.1, 0.25, 1)` — these are the browser defaults and they read as uncrafted.
|
|
28
|
+
|
|
29
|
+
## Durations
|
|
30
|
+
|
|
31
|
+
```css
|
|
32
|
+
:root {
|
|
33
|
+
--dur-micro: 120ms; /* button press, toggle tick, color shift */
|
|
34
|
+
--dur-short: 220ms; /* hover lift, tooltip, menu open */
|
|
35
|
+
--dur-long: 420ms; /* modal, drawer, accordion, page reveal */
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Exits use roughly 75% of the enter:
|
|
40
|
+
|
|
41
|
+
```css
|
|
42
|
+
.menu.is-open { transition: transform var(--dur-short) var(--ease-out); }
|
|
43
|
+
.menu.is-close { transition: transform calc(var(--dur-short) * 0.75) var(--ease-in); }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Page-load orchestration
|
|
47
|
+
|
|
48
|
+
One sequence on page load. Stagger by DOM index using a CSS custom property, not by JS.
|
|
49
|
+
|
|
50
|
+
```html
|
|
51
|
+
<section style="--i: 0">…</section>
|
|
52
|
+
<section style="--i: 1">…</section>
|
|
53
|
+
<section style="--i: 2">…</section>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```css
|
|
57
|
+
.reveal {
|
|
58
|
+
opacity: 0;
|
|
59
|
+
transform: translateY(8px);
|
|
60
|
+
animation: reveal var(--dur-long) var(--ease-out) forwards;
|
|
61
|
+
animation-delay: calc(var(--i, 0) * 60ms);
|
|
62
|
+
}
|
|
63
|
+
@keyframes reveal {
|
|
64
|
+
to { opacity: 1; transform: none; }
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Cap total stagger at ~500ms. Beyond that the page feels slow to settle.
|
|
69
|
+
|
|
70
|
+
## Scroll-linked motion
|
|
71
|
+
|
|
72
|
+
- Use IntersectionObserver, **never** `scroll` event listeners.
|
|
73
|
+
- Use it only for *reveal once* effects. No parallax. No scroll-scrubbed animations unless there is a specific reason.
|
|
74
|
+
- Every scroll-triggered motion must have a reduced-motion fallback.
|
|
75
|
+
|
|
76
|
+
## State transitions
|
|
77
|
+
|
|
78
|
+
- Button hover / active: micro duration, `--ease-out`, `transform: translateY(-1px)` on hover, `translateY(0)` on active. Never a `box-shadow` transition on hover on a dark background (glow effect).
|
|
79
|
+
- Menu / tooltip / dropdown: short duration, `--ease-out` on open, `--ease-in` on close. Use the popover API or `inert` to manage focus.
|
|
80
|
+
- Modal: long duration, scale-in (0.96 → 1) + opacity crossfade. Backdrop fades in at the same duration.
|
|
81
|
+
- Accordion: animate `grid-template-rows: 0fr` → `grid-template-rows: 1fr` (not `height`). With `--ease-in-out`.
|
|
82
|
+
|
|
83
|
+
## Reduced motion
|
|
84
|
+
|
|
85
|
+
```css
|
|
86
|
+
@media (prefers-reduced-motion: reduce) {
|
|
87
|
+
*, *::before, *::after {
|
|
88
|
+
animation-duration: 150ms !important;
|
|
89
|
+
animation-iteration-count: 1 !important;
|
|
90
|
+
transition-duration: 150ms !important;
|
|
91
|
+
}
|
|
92
|
+
.reveal { animation: reveal-reduced 150ms linear forwards; }
|
|
93
|
+
@keyframes reveal-reduced { to { opacity: 1; transform: none; } }
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Functional motion (progress bars, loading spinners, skeletons) still runs — just slower.
|
|
98
|
+
|
|
99
|
+
## Bans
|
|
100
|
+
|
|
101
|
+
- `ease` (browser default, mediocre).
|
|
102
|
+
- `linear` on anything except progress bars and ticking loaders.
|
|
103
|
+
- Bounce / elastic / overshoot on UI elements. Dated; signals "template".
|
|
104
|
+
- Animating `width`, `height`, `top`, `left`, `margin`, `padding`.
|
|
105
|
+
- `will-change` set preemptively across a whole class. Only on the element, only while it's animating.
|
|
106
|
+
- Parallax.
|
|
107
|
+
- Custom cursors.
|
|
108
|
+
- Scroll-driven animations without a reduced-motion fallback.
|
|
109
|
+
- Infinite loops (other than functional loaders) — they pull the eye and never let go.
|
|
@@ -1,49 +1,49 @@
|
|
|
1
|
-
# Preview-block worked examples
|
|
2
|
-
|
|
3
|
-
Four sample Step 5 preview blocks for the model to imitate, varied across macrostructure types. Load this file only when picking an unusual macrostructure or custom theme and the bullet-list spec in `SKILL.md § 5. Preview` doesn't give enough scaffolding on its own. Most builds don't need to read this file.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
*Long Document (editorial, motion-cut):*
|
|
8
|
-
> **Hallmark · v1.0.0**
|
|
9
|
-
>
|
|
10
|
-
> - **Macrostructure** · Long Document
|
|
11
|
-
> - **Theme** · Linen (cool slate paper · steel-blue accent · geometric sans)
|
|
12
|
-
> - **Enrichment** · Tier-B hand-built SVG (a 60-line coffee bean with `@property --rise` 6 s breathing-loop)
|
|
13
|
-
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
|
|
14
|
-
> - **Motion** · breathing-loop on bean only (respects `prefers-reduced-motion`)
|
|
15
|
-
> - **Slop test** · 69 / 69 ✓
|
|
16
|
-
> - **Diversification** · first run for this project
|
|
17
|
-
|
|
18
|
-
*Bento Grid (SaaS, motion-on):*
|
|
19
|
-
> **Hallmark · v1.0.0**
|
|
20
|
-
>
|
|
21
|
-
> - **Macrostructure** · Bento Grid
|
|
22
|
-
> - **Theme** · Linen (cool slate paper · steel-blue accent · geometric sans)
|
|
23
|
-
> - **Enrichment** · E1 Clipped-Edge Demo Video, Tier-A CSS-art trace waterfall
|
|
24
|
-
> - **Sections** · Hero · 6-tile Bento (stat · sparkline · quote · code · integrations · spotlight) · Index Footer
|
|
25
|
-
> - **Motion** · counter · pricing-lift · CSS marquee on integrations strip
|
|
26
|
-
> - **Slop test** · 69 / 69 ✓
|
|
27
|
-
> - **Diversification** · differs from Plain on paper hue (light-cool vs pure-white) + accent (indigo vs ink-blue)
|
|
28
|
-
|
|
29
|
-
*Manifesto (declarative, no enrichment):*
|
|
30
|
-
> **Hallmark · v1.0.0**
|
|
31
|
-
>
|
|
32
|
-
> - **Macrostructure** · Manifesto
|
|
33
|
-
> - **Theme** · Manifesto (dark · Inter Tight 900 · single red bleed)
|
|
34
|
-
> - **Enrichment** · none (typography only — voice carries the brand)
|
|
35
|
-
> - **Sections** · Masthead · Title · Five Declarations · Bleed Band · What We Refuse · Working Rules · Practice · Reading · Colophon
|
|
36
|
-
> - **Motion** · none — typography only
|
|
37
|
-
> - **Slop test** · 69 / 69 ✓
|
|
38
|
-
> - **Diversification** · differs from Linen on paper band (dark vs light) + display style (display-heavy vs geometric-sans)
|
|
39
|
-
|
|
40
|
-
*Custom (Coffeebox archival café):*
|
|
41
|
-
> **Hallmark · v1.0.0**
|
|
42
|
-
>
|
|
43
|
-
> - **Macrostructure** · Long Document
|
|
44
|
-
> - **Theme** · custom (vibe: "archival warmth, hand-set, no varnish" · paper oklch(94% 0.020 65) · accent oklch(58% 0.16 35) terracotta · Fraunces italic display + Source Serif 4 body)
|
|
45
|
-
> - **Enrichment** · Tier-A pure-CSS coffee bean (60-line SVG, breathing-loop optional)
|
|
46
|
-
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
|
|
47
|
-
> - **Motion** · breathing-loop on bean (with reduced-motion fallback)
|
|
48
|
-
> - **Slop test** · 69 / 69 ✓
|
|
49
|
-
> - **Diversification** · custom axes: light / italic-serif / chromatic-terracotta — differs from previous catalog Linen on accent hue + display style
|
|
1
|
+
# Preview-block worked examples
|
|
2
|
+
|
|
3
|
+
Four sample Step 5 preview blocks for the model to imitate, varied across macrostructure types. Load this file only when picking an unusual macrostructure or custom theme and the bullet-list spec in `SKILL.md § 5. Preview` doesn't give enough scaffolding on its own. Most builds don't need to read this file.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
*Long Document (editorial, motion-cut):*
|
|
8
|
+
> **Hallmark · v1.0.0**
|
|
9
|
+
>
|
|
10
|
+
> - **Macrostructure** · Long Document
|
|
11
|
+
> - **Theme** · Linen (cool slate paper · steel-blue accent · geometric sans)
|
|
12
|
+
> - **Enrichment** · Tier-B hand-built SVG (a 60-line coffee bean with `@property --rise` 6 s breathing-loop)
|
|
13
|
+
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
|
|
14
|
+
> - **Motion** · breathing-loop on bean only (respects `prefers-reduced-motion`)
|
|
15
|
+
> - **Slop test** · 69 / 69 ✓
|
|
16
|
+
> - **Diversification** · first run for this project
|
|
17
|
+
|
|
18
|
+
*Bento Grid (SaaS, motion-on):*
|
|
19
|
+
> **Hallmark · v1.0.0**
|
|
20
|
+
>
|
|
21
|
+
> - **Macrostructure** · Bento Grid
|
|
22
|
+
> - **Theme** · Linen (cool slate paper · steel-blue accent · geometric sans)
|
|
23
|
+
> - **Enrichment** · E1 Clipped-Edge Demo Video, Tier-A CSS-art trace waterfall
|
|
24
|
+
> - **Sections** · Hero · 6-tile Bento (stat · sparkline · quote · code · integrations · spotlight) · Index Footer
|
|
25
|
+
> - **Motion** · counter · pricing-lift · CSS marquee on integrations strip
|
|
26
|
+
> - **Slop test** · 69 / 69 ✓
|
|
27
|
+
> - **Diversification** · differs from Plain on paper hue (light-cool vs pure-white) + accent (indigo vs ink-blue)
|
|
28
|
+
|
|
29
|
+
*Manifesto (declarative, no enrichment):*
|
|
30
|
+
> **Hallmark · v1.0.0**
|
|
31
|
+
>
|
|
32
|
+
> - **Macrostructure** · Manifesto
|
|
33
|
+
> - **Theme** · Manifesto (dark · Inter Tight 900 · single red bleed)
|
|
34
|
+
> - **Enrichment** · none (typography only — voice carries the brand)
|
|
35
|
+
> - **Sections** · Masthead · Title · Five Declarations · Bleed Band · What We Refuse · Working Rules · Practice · Reading · Colophon
|
|
36
|
+
> - **Motion** · none — typography only
|
|
37
|
+
> - **Slop test** · 69 / 69 ✓
|
|
38
|
+
> - **Diversification** · differs from Linen on paper band (dark vs light) + display style (display-heavy vs geometric-sans)
|
|
39
|
+
|
|
40
|
+
*Custom (Coffeebox archival café):*
|
|
41
|
+
> **Hallmark · v1.0.0**
|
|
42
|
+
>
|
|
43
|
+
> - **Macrostructure** · Long Document
|
|
44
|
+
> - **Theme** · custom (vibe: "archival warmth, hand-set, no varnish" · paper oklch(94% 0.020 65) · accent oklch(58% 0.16 35) terracotta · Fraunces italic display + Source Serif 4 body)
|
|
45
|
+
> - **Enrichment** · Tier-A pure-CSS coffee bean (60-line SVG, breathing-loop optional)
|
|
46
|
+
> - **Sections** · Masthead · Letter · Three Notes · Visit · Colophon
|
|
47
|
+
> - **Motion** · breathing-loop on bean (with reduced-motion fallback)
|
|
48
|
+
> - **Slop test** · 69 / 69 ✓
|
|
49
|
+
> - **Diversification** · custom axes: light / italic-serif / chromatic-terracotta — differs from previous catalog Linen on accent hue + display style
|
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
# Responsive
|
|
2
|
-
|
|
3
|
-
Mobile-first. Content-driven breakpoints. No desktop-only interactions.
|
|
4
|
-
|
|
5
|
-
## Mobile — non-negotiable
|
|
6
|
-
|
|
7
|
-
Every Hallmark output must render flawlessly at **320 px, 375 px, 414 px, and 768 px** CSS-pixel widths. Eyeball each viewport before marking the output complete:
|
|
8
|
-
|
|
9
|
-
- No horizontal scroll (slop-test gate 36)
|
|
10
|
-
- No clickable text wrapping to two lines (gate 59)
|
|
11
|
-
- No image-bearing grid pushing the layout past viewport — use `minmax(0, 1fr)`, never bare `1fr`, on tracks containing images (gate 61)
|
|
12
|
-
- Root carries `overflow-x: clip` on both `html` and `body` — never `hidden` (gate 62)
|
|
13
|
-
- Display headers wrap inside long words via `overflow-wrap: anywhere; min-width: 0` (gate 63)
|
|
14
|
-
- Section heads collapse to one column on mobile across every theme variant — per-theme overrides need a matching mobile rule (gate 64)
|
|
15
|
-
- No scroll-jump on radio-tab clicks — radios in normal flow OR JS guard with `focus({ preventScroll: true })` (gate 65)
|
|
16
|
-
|
|
17
|
-
This is a hard floor, not a wish list. A page that fails any of these on any of those four widths is not done. The slop-test gates listed run automatically — keep this checklist near the screen while building.
|
|
18
|
-
|
|
19
|
-
## Principles
|
|
20
|
-
|
|
21
|
-
- Base styles are for the smallest viewport. `min-width` media queries add as you go up. Never `max-width` as the primary direction.
|
|
22
|
-
- Breakpoints are where the *content* breaks, not where a device sits. If the headline reflows awkwardly at 720px, that's a breakpoint — regardless of what the Tailwind defaults say.
|
|
23
|
-
- Use `pointer` and `hover` media queries instead of width to detect *interaction capability*.
|
|
24
|
-
|
|
25
|
-
## Breakpoints
|
|
26
|
-
|
|
27
|
-
Three or four, content-driven. As a default:
|
|
28
|
-
|
|
29
|
-
```css
|
|
30
|
-
@media (min-width: 40rem) { /* ~640px — tablet, small laptop */ }
|
|
31
|
-
@media (min-width: 60rem) { /* ~960px — desktop baseline */ }
|
|
32
|
-
@media (min-width: 90rem) { /* ~1440px — wide */ }
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Use `rem` so the breakpoints respect the user's font size.
|
|
36
|
-
|
|
37
|
-
## Fluid scaling
|
|
38
|
-
|
|
39
|
-
Prefer `clamp()` for sizes that change continuously; use media queries for layouts that change discretely.
|
|
40
|
-
|
|
41
|
-
```css
|
|
42
|
-
h1 { font-size: clamp(2.5rem, 4vw + 1rem, 6rem); }
|
|
43
|
-
.container { padding-inline: clamp(1rem, 4vw, 4rem); }
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Pointer and hover queries
|
|
47
|
-
|
|
48
|
-
```css
|
|
49
|
-
@media (hover: hover) and (pointer: fine) {
|
|
50
|
-
.card:hover { transform: translateY(-2px); }
|
|
51
|
-
}
|
|
52
|
-
@media (pointer: coarse) {
|
|
53
|
-
.btn { min-height: 48px; }
|
|
54
|
-
}
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Never build a mouse-hover interaction that has no touch equivalent.
|
|
58
|
-
|
|
59
|
-
## Clickable text — never wraps
|
|
60
|
-
|
|
61
|
-
Buttons, primary nav links, footer links, tab labels, breadcrumbs, and CTAs must read as **single-line affordances at every viewport between 320 px and 1920 px**. A button or nav link wrapping to two lines looks broken — visitors read it as a styling error, not as intentional. The shortest fix is almost always to shorten the label.
|
|
62
|
-
|
|
63
|
-
```css
|
|
64
|
-
/* Affordances are single-line — let the parent reflow, not the label. */
|
|
65
|
-
.btn,
|
|
66
|
-
.nav__link,
|
|
67
|
-
.foot__link,
|
|
68
|
-
.cta {
|
|
69
|
-
white-space: nowrap;
|
|
70
|
-
}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
```css
|
|
74
|
-
/* When the row can't fit, collapse the row, not the labels. */
|
|
75
|
-
@media (max-width: 40rem) {
|
|
76
|
-
.nav__rail { display: none; } /* desktop nav hides */
|
|
77
|
-
.nav__sheet-toggle { display: grid; } /* mobile menu shows */
|
|
78
|
-
}
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**Order of fixes**, when something does wrap:
|
|
82
|
-
|
|
83
|
-
1. **Shorten the label.** *"Get started free"* → *"Start free"*. *"Read the documentation"* → *"Read docs"*. *"Schedule a demo"* → *"Book demo"*. Most CTA labels are 30–40 % longer than they need to be.
|
|
84
|
-
2. **`white-space: nowrap`** on the affordance, let the parent flex/grid reflow.
|
|
85
|
-
3. **`hidden=until-found`** the lowest-priority nav item at narrow widths (it remains in DOM for find-in-page and SEO).
|
|
86
|
-
4. **Collapse the nav** into a sheet / off-canvas / disclosure menu below a content-driven breakpoint.
|
|
87
|
-
|
|
88
|
-
**Never:** let a primary CTA or top-level nav link wrap. Long footer-link labels can wrap *only* in a footer column where wrapping is part of the column's rhythm — not in the inline footer link strip (Ft2).
|
|
89
|
-
|
|
90
|
-
This is gate **59** in [`slop-test.md`](slop-test.md). Audit any output that ships interactive affordances and confirm none wrap at the breakpoints listed above.
|
|
91
|
-
|
|
92
|
-
## Viewport units
|
|
93
|
-
|
|
94
|
-
- Use `dvh` / `svh` / `lvh` instead of `vh` for heights that interact with mobile chrome.
|
|
95
|
-
- Never `width: 100vw`. Use `width: 100%` with padding; `100vw` includes the scrollbar on desktop and causes overflow.
|
|
96
|
-
|
|
97
|
-
## Safe areas
|
|
98
|
-
|
|
99
|
-
For iOS notch / Android navigation bars:
|
|
100
|
-
|
|
101
|
-
```html
|
|
102
|
-
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
```css
|
|
106
|
-
body {
|
|
107
|
-
padding-inline: max(1rem, env(safe-area-inset-left));
|
|
108
|
-
padding-bottom: max(1rem, env(safe-area-inset-bottom));
|
|
109
|
-
}
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
## Tables on small screens
|
|
113
|
-
|
|
114
|
-
Tables of data that won't fit: collapse to cards. Use `display: block` on `<tr>` and `data-label` attributes keyed from `<th>`, rendered via `::before`. Or, the better option: redesign the data for small screens — tables are rarely the right mobile representation.
|
|
115
|
-
|
|
116
|
-
## Images
|
|
117
|
-
|
|
118
|
-
- `srcset` with width descriptors for responsive sizing.
|
|
119
|
-
- `<picture>` for art direction (different crop at different widths).
|
|
120
|
-
- `loading="lazy"` on anything below the fold.
|
|
121
|
-
- `width` and `height` attributes on every image, always, to avoid CLS.
|
|
122
|
-
|
|
123
|
-
## Internationalisation
|
|
124
|
-
|
|
125
|
-
- Reserve 30–40% extra horizontal space for German, Russian, and Finnish translations.
|
|
126
|
-
- Use logical properties: `margin-inline-start`, `padding-block`, `border-inline-end`. Not `margin-left` etc. RTL comes for free.
|
|
127
|
-
- Don't hard-code language-specific punctuation or date formats.
|
|
128
|
-
|
|
129
|
-
## Bans
|
|
130
|
-
|
|
131
|
-
- Desktop-first media queries (`max-width: 768px` as the primary direction).
|
|
132
|
-
- `vh` on full-height layouts (use `dvh`).
|
|
133
|
-
- `100vw` widths.
|
|
134
|
-
- Device-sniffing UA strings instead of feature queries.
|
|
135
|
-
- Hover-only interactions.
|
|
136
|
-
- Ignoring `prefers-color-scheme` when the app claims to support dark mode.
|
|
137
|
-
- Fixed pixel breakpoints that don't respect `rem`.
|
|
138
|
-
- Tables of 10+ columns on mobile without a redesign.
|
|
1
|
+
# Responsive
|
|
2
|
+
|
|
3
|
+
Mobile-first. Content-driven breakpoints. No desktop-only interactions.
|
|
4
|
+
|
|
5
|
+
## Mobile — non-negotiable
|
|
6
|
+
|
|
7
|
+
Every Hallmark output must render flawlessly at **320 px, 375 px, 414 px, and 768 px** CSS-pixel widths. Eyeball each viewport before marking the output complete:
|
|
8
|
+
|
|
9
|
+
- No horizontal scroll (slop-test gate 36)
|
|
10
|
+
- No clickable text wrapping to two lines (gate 59)
|
|
11
|
+
- No image-bearing grid pushing the layout past viewport — use `minmax(0, 1fr)`, never bare `1fr`, on tracks containing images (gate 61)
|
|
12
|
+
- Root carries `overflow-x: clip` on both `html` and `body` — never `hidden` (gate 62)
|
|
13
|
+
- Display headers wrap inside long words via `overflow-wrap: anywhere; min-width: 0` (gate 63)
|
|
14
|
+
- Section heads collapse to one column on mobile across every theme variant — per-theme overrides need a matching mobile rule (gate 64)
|
|
15
|
+
- No scroll-jump on radio-tab clicks — radios in normal flow OR JS guard with `focus({ preventScroll: true })` (gate 65)
|
|
16
|
+
|
|
17
|
+
This is a hard floor, not a wish list. A page that fails any of these on any of those four widths is not done. The slop-test gates listed run automatically — keep this checklist near the screen while building.
|
|
18
|
+
|
|
19
|
+
## Principles
|
|
20
|
+
|
|
21
|
+
- Base styles are for the smallest viewport. `min-width` media queries add as you go up. Never `max-width` as the primary direction.
|
|
22
|
+
- Breakpoints are where the *content* breaks, not where a device sits. If the headline reflows awkwardly at 720px, that's a breakpoint — regardless of what the Tailwind defaults say.
|
|
23
|
+
- Use `pointer` and `hover` media queries instead of width to detect *interaction capability*.
|
|
24
|
+
|
|
25
|
+
## Breakpoints
|
|
26
|
+
|
|
27
|
+
Three or four, content-driven. As a default:
|
|
28
|
+
|
|
29
|
+
```css
|
|
30
|
+
@media (min-width: 40rem) { /* ~640px — tablet, small laptop */ }
|
|
31
|
+
@media (min-width: 60rem) { /* ~960px — desktop baseline */ }
|
|
32
|
+
@media (min-width: 90rem) { /* ~1440px — wide */ }
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use `rem` so the breakpoints respect the user's font size.
|
|
36
|
+
|
|
37
|
+
## Fluid scaling
|
|
38
|
+
|
|
39
|
+
Prefer `clamp()` for sizes that change continuously; use media queries for layouts that change discretely.
|
|
40
|
+
|
|
41
|
+
```css
|
|
42
|
+
h1 { font-size: clamp(2.5rem, 4vw + 1rem, 6rem); }
|
|
43
|
+
.container { padding-inline: clamp(1rem, 4vw, 4rem); }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Pointer and hover queries
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
@media (hover: hover) and (pointer: fine) {
|
|
50
|
+
.card:hover { transform: translateY(-2px); }
|
|
51
|
+
}
|
|
52
|
+
@media (pointer: coarse) {
|
|
53
|
+
.btn { min-height: 48px; }
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Never build a mouse-hover interaction that has no touch equivalent.
|
|
58
|
+
|
|
59
|
+
## Clickable text — never wraps
|
|
60
|
+
|
|
61
|
+
Buttons, primary nav links, footer links, tab labels, breadcrumbs, and CTAs must read as **single-line affordances at every viewport between 320 px and 1920 px**. A button or nav link wrapping to two lines looks broken — visitors read it as a styling error, not as intentional. The shortest fix is almost always to shorten the label.
|
|
62
|
+
|
|
63
|
+
```css
|
|
64
|
+
/* Affordances are single-line — let the parent reflow, not the label. */
|
|
65
|
+
.btn,
|
|
66
|
+
.nav__link,
|
|
67
|
+
.foot__link,
|
|
68
|
+
.cta {
|
|
69
|
+
white-space: nowrap;
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```css
|
|
74
|
+
/* When the row can't fit, collapse the row, not the labels. */
|
|
75
|
+
@media (max-width: 40rem) {
|
|
76
|
+
.nav__rail { display: none; } /* desktop nav hides */
|
|
77
|
+
.nav__sheet-toggle { display: grid; } /* mobile menu shows */
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Order of fixes**, when something does wrap:
|
|
82
|
+
|
|
83
|
+
1. **Shorten the label.** *"Get started free"* → *"Start free"*. *"Read the documentation"* → *"Read docs"*. *"Schedule a demo"* → *"Book demo"*. Most CTA labels are 30–40 % longer than they need to be.
|
|
84
|
+
2. **`white-space: nowrap`** on the affordance, let the parent flex/grid reflow.
|
|
85
|
+
3. **`hidden=until-found`** the lowest-priority nav item at narrow widths (it remains in DOM for find-in-page and SEO).
|
|
86
|
+
4. **Collapse the nav** into a sheet / off-canvas / disclosure menu below a content-driven breakpoint.
|
|
87
|
+
|
|
88
|
+
**Never:** let a primary CTA or top-level nav link wrap. Long footer-link labels can wrap *only* in a footer column where wrapping is part of the column's rhythm — not in the inline footer link strip (Ft2).
|
|
89
|
+
|
|
90
|
+
This is gate **59** in [`slop-test.md`](slop-test.md). Audit any output that ships interactive affordances and confirm none wrap at the breakpoints listed above.
|
|
91
|
+
|
|
92
|
+
## Viewport units
|
|
93
|
+
|
|
94
|
+
- Use `dvh` / `svh` / `lvh` instead of `vh` for heights that interact with mobile chrome.
|
|
95
|
+
- Never `width: 100vw`. Use `width: 100%` with padding; `100vw` includes the scrollbar on desktop and causes overflow.
|
|
96
|
+
|
|
97
|
+
## Safe areas
|
|
98
|
+
|
|
99
|
+
For iOS notch / Android navigation bars:
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
body {
|
|
107
|
+
padding-inline: max(1rem, env(safe-area-inset-left));
|
|
108
|
+
padding-bottom: max(1rem, env(safe-area-inset-bottom));
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Tables on small screens
|
|
113
|
+
|
|
114
|
+
Tables of data that won't fit: collapse to cards. Use `display: block` on `<tr>` and `data-label` attributes keyed from `<th>`, rendered via `::before`. Or, the better option: redesign the data for small screens — tables are rarely the right mobile representation.
|
|
115
|
+
|
|
116
|
+
## Images
|
|
117
|
+
|
|
118
|
+
- `srcset` with width descriptors for responsive sizing.
|
|
119
|
+
- `<picture>` for art direction (different crop at different widths).
|
|
120
|
+
- `loading="lazy"` on anything below the fold.
|
|
121
|
+
- `width` and `height` attributes on every image, always, to avoid CLS.
|
|
122
|
+
|
|
123
|
+
## Internationalisation
|
|
124
|
+
|
|
125
|
+
- Reserve 30–40% extra horizontal space for German, Russian, and Finnish translations.
|
|
126
|
+
- Use logical properties: `margin-inline-start`, `padding-block`, `border-inline-end`. Not `margin-left` etc. RTL comes for free.
|
|
127
|
+
- Don't hard-code language-specific punctuation or date formats.
|
|
128
|
+
|
|
129
|
+
## Bans
|
|
130
|
+
|
|
131
|
+
- Desktop-first media queries (`max-width: 768px` as the primary direction).
|
|
132
|
+
- `vh` on full-height layouts (use `dvh`).
|
|
133
|
+
- `100vw` widths.
|
|
134
|
+
- Device-sniffing UA strings instead of feature queries.
|
|
135
|
+
- Hover-only interactions.
|
|
136
|
+
- Ignoring `prefers-color-scheme` when the app claims to support dark mode.
|
|
137
|
+
- Fixed pixel breakpoints that don't respect `rem`.
|
|
138
|
+
- Tables of 10+ columns on mobile without a redesign.
|