howone 0.1.28 → 0.1.30

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 (224) hide show
  1. package/package.json +1 -1
  2. package/templates/vite/.howone/skills/hallmark/SKILL.md +48 -42
  3. package/templates/vite/.howone/skills/hallmark/references/anti-patterns.md +12 -6
  4. package/templates/vite/.howone/skills/hallmark/references/assets.md +7 -0
  5. package/templates/vite/.howone/skills/hallmark/references/component-cookbook.md +19 -10
  6. package/templates/vite/.howone/skills/hallmark/references/components/f2-sticky-scroll-stack.md +1 -1
  7. package/templates/vite/.howone/skills/hallmark/references/components/ft6-letter-close.md +1 -1
  8. package/templates/vite/.howone/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +1 -1
  9. package/templates/vite/.howone/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +1 -1
  10. package/templates/vite/.howone/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +1 -1
  11. package/templates/vite/.howone/skills/hallmark/references/components/n11-mega-menu.md +40 -0
  12. package/templates/vite/.howone/skills/hallmark/references/components/n12-banner-retract.md +34 -0
  13. package/templates/vite/.howone/skills/hallmark/references/components/n13-inline-cmdk-pill.md +39 -0
  14. package/templates/vite/.howone/skills/hallmark/references/components/n1b-saas-three-section.md +35 -0
  15. package/templates/vite/.howone/skills/hallmark/references/components/n9-edge-aligned-minimal.md +1 -1
  16. package/templates/vite/.howone/skills/hallmark/references/components/s3-sticky-pinned.md +2 -2
  17. package/templates/vite/.howone/skills/hallmark/references/copy.md +8 -8
  18. package/templates/vite/.howone/skills/hallmark/references/custom-craft.md +2 -2
  19. package/templates/vite/.howone/skills/hallmark/references/custom-theme.md +50 -12
  20. package/templates/vite/.howone/skills/hallmark/references/export-formats.md +1 -1
  21. package/templates/vite/.howone/skills/hallmark/references/genres/atmospheric.md +11 -7
  22. package/templates/vite/.howone/skills/hallmark/references/genres/editorial.md +6 -4
  23. package/templates/vite/.howone/skills/hallmark/references/genres/modern-minimal.md +10 -6
  24. package/templates/vite/.howone/skills/hallmark/references/genres/playful.md +15 -10
  25. package/templates/vite/.howone/skills/hallmark/references/hero-enrichment.md +13 -12
  26. package/templates/vite/.howone/skills/hallmark/references/interaction-and-states.md +2 -1
  27. package/templates/vite/.howone/skills/hallmark/references/layout-and-space.md +4 -3
  28. package/templates/vite/.howone/skills/hallmark/references/macrostructures/04-stat-led.md +3 -1
  29. package/templates/vite/.howone/skills/hallmark/references/macrostructures/12-letter.md +1 -1
  30. package/templates/vite/.howone/skills/hallmark/references/macrostructures.md +1 -1
  31. package/templates/vite/.howone/skills/hallmark/references/microinteractions.md +1 -3
  32. package/templates/vite/.howone/skills/hallmark/references/preview-examples.md +12 -12
  33. package/templates/vite/.howone/skills/hallmark/references/responsive.md +8 -8
  34. package/templates/vite/.howone/skills/hallmark/references/slop-test.md +72 -85
  35. package/templates/vite/.howone/skills/hallmark/references/structure.md +9 -13
  36. package/templates/vite/.howone/skills/hallmark/references/study.md +40 -17
  37. package/templates/vite/.howone/skills/hallmark/references/themes/carnival.md +301 -0
  38. package/templates/vite/.howone/skills/hallmark/references/themes/cobalt.md +146 -0
  39. package/templates/vite/.howone/skills/hallmark/references/themes/hum.md +403 -0
  40. package/templates/vite/.howone/skills/hallmark/references/themes/lumen.md +478 -0
  41. package/templates/vite/.howone/skills/hallmark/references/typography.md +3 -3
  42. package/templates/vite/.howone/skills/hallmark/references/verbs/redesign.md +1 -1
  43. package/templates/vite/.howone/skills/howone/03-sdk/07-ai-action-calls.md +28 -86
  44. package/templates/vite/.howone/skills/howone/03-sdk/09-workflow-execute-sse.md +105 -0
  45. package/templates/vite/.howone/skills/howone/04-ai/03-ai-sdk-handoff.md +15 -13
  46. package/templates/vite/.howone/skills/howone/SKILL.md +2 -2
  47. package/templates/vite/package.json +1 -1
  48. package/templates/vite/.howone/skills/hallmark/LICENSE +0 -21
  49. package/templates/vite/.howone/skills/hallmark/README.md +0 -147
  50. package/templates/vite/.howone/skills/hallmark/ROADMAP.md +0 -201
  51. package/templates/vite/.howone/skills/hallmark/docs/recipes.md +0 -186
  52. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-anya.jpg +0 -0
  53. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-bananastudio.jpg +0 -0
  54. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-hyperlane.jpg +0 -0
  55. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-najm.jpg +0 -0
  56. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-slow-pour.jpg +0 -0
  57. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-soroe.jpg +0 -0
  58. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-tally.jpg +0 -0
  59. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-wayfare.jpg +0 -0
  60. package/templates/vite/.howone/skills/hallmark/docs/study-examples.md +0 -176
  61. package/templates/vite/.howone/skills/hallmark/docs/talk-slides.md +0 -364
  62. package/templates/vite/.howone/skills/hallmark/package.json +0 -36
  63. package/templates/vite/.howone/skills/hallmark/site/OG-hallmark.png +0 -0
  64. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/brief.md +0 -71
  65. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/index.html +0 -64
  66. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/style.css +0 -240
  67. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/brief.md +0 -65
  68. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/index.html +0 -105
  69. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/style.css +0 -250
  70. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/brief.md +0 -64
  71. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/index.html +0 -131
  72. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/style.css +0 -240
  73. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/brief.md +0 -67
  74. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/index.html +0 -86
  75. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/style.css +0 -262
  76. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/brief.md +0 -63
  77. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/index.html +0 -167
  78. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/style.css +0 -457
  79. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/brief.md +0 -65
  80. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/index.html +0 -159
  81. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/style.css +0 -288
  82. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/brief.md +0 -64
  83. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/index.html +0 -146
  84. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/style.css +0 -484
  85. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/brief.md +0 -64
  86. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/index.html +0 -116
  87. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/style.css +0 -354
  88. package/templates/vite/.howone/skills/hallmark/site/_tests/09-slow-pour/index.html +0 -638
  89. package/templates/vite/.howone/skills/hallmark/site/_tests/10-owl-hours/index.html +0 -515
  90. package/templates/vite/.howone/skills/hallmark/site/_tests/11-soroe-ceramics/index.html +0 -515
  91. package/templates/vite/.howone/skills/hallmark/site/_tests/12-loafer/index.html +0 -608
  92. package/templates/vite/.howone/skills/hallmark/site/_tests/13-alma/index.html +0 -587
  93. package/templates/vite/.howone/skills/hallmark/site/_tests/README.md +0 -157
  94. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-loop.mp4 +0 -0
  95. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-still.jpg +0 -0
  96. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-example.mp4 +0 -0
  97. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-still.jpg +0 -0
  98. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-loop.mp4 +0 -0
  99. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-still.jpg +0 -0
  100. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Podcast-loop.mp4 +0 -0
  101. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-loop.mp4 +0 -0
  102. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-still.jpg +0 -0
  103. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-loop.mp4 +0 -0
  104. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-still.jpg +0 -0
  105. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/after-quiet-hour.png +0 -0
  106. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-loop.mp4 +0 -0
  107. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-still.jpg +0 -0
  108. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/audit-example.png +0 -0
  109. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/before-quiet-hour.png +0 -0
  110. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/example-redesign-uractivation.png +0 -0
  111. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-loop.mp4 +0 -0
  112. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-still.jpg +0 -0
  113. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/study-example.png +0 -0
  114. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/uractivation-after-loop.mp4 +0 -0
  115. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-loop.mp4 +0 -0
  116. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-still.jpg +0 -0
  117. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/index.html +0 -77
  118. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/style.css +0 -238
  119. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/index.html +0 -110
  120. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/style.css +0 -326
  121. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/index.html +0 -134
  122. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/style.css +0 -262
  123. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/README.md +0 -30
  124. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/README.md +0 -17
  125. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/audit-report.md +0 -56
  126. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/input.html +0 -160
  127. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/notes.md +0 -29
  128. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/input.html +0 -63
  129. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/notes.md +0 -72
  130. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/output.html +0 -374
  131. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/diagnosis.md +0 -52
  132. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/input-description.md +0 -29
  133. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/notes.md +0 -61
  134. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.css +0 -193
  135. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.html +0 -66
  136. package/templates/vite/.howone/skills/hallmark/site/css/base.css +0 -194
  137. package/templates/vite/.howone/skills/hallmark/site/css/components.css +0 -4886
  138. package/templates/vite/.howone/skills/hallmark/site/css/sections.css +0 -2072
  139. package/templates/vite/.howone/skills/hallmark/site/css/tokens.css +0 -1129
  140. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/index.html +0 -475
  141. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/styles.css +0 -1584
  142. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/tokens.css +0 -96
  143. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/index.html +0 -344
  144. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/script.js +0 -103
  145. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/styles.css +0 -1103
  146. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/tokens.css +0 -83
  147. package/templates/vite/.howone/skills/hallmark/site/examples/najm/index.html +0 -368
  148. package/templates/vite/.howone/skills/hallmark/site/examples/najm/script.js +0 -133
  149. package/templates/vite/.howone/skills/hallmark/site/examples/najm/styles.css +0 -1062
  150. package/templates/vite/.howone/skills/hallmark/site/examples/najm/tokens.css +0 -97
  151. package/templates/vite/.howone/skills/hallmark/site/examples/tally/app.js +0 -84
  152. package/templates/vite/.howone/skills/hallmark/site/examples/tally/index.html +0 -446
  153. package/templates/vite/.howone/skills/hallmark/site/examples/tally/styles.css +0 -1087
  154. package/templates/vite/.howone/skills/hallmark/site/examples/tally/tokens.css +0 -101
  155. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/index.html +0 -359
  156. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/style.css +0 -1168
  157. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/tokens.css +0 -81
  158. package/templates/vite/.howone/skills/hallmark/site/favicon-dark.svg +0 -5
  159. package/templates/vite/.howone/skills/hallmark/site/favicon-light.svg +0 -5
  160. package/templates/vite/.howone/skills/hallmark/site/index.html +0 -1043
  161. package/templates/vite/.howone/skills/hallmark/site/js/main.js +0 -1175
  162. package/templates/vite/.howone/skills/hallmark/vercel.json +0 -6
  163. package/templates/vite/.howone/skills/impeccable/SKILL.md +0 -168
  164. package/templates/vite/.howone/skills/impeccable/agents/impeccable-asset-producer.md +0 -101
  165. package/templates/vite/.howone/skills/impeccable/reference/adapt.md +0 -190
  166. package/templates/vite/.howone/skills/impeccable/reference/animate.md +0 -175
  167. package/templates/vite/.howone/skills/impeccable/reference/audit.md +0 -133
  168. package/templates/vite/.howone/skills/impeccable/reference/bolder.md +0 -113
  169. package/templates/vite/.howone/skills/impeccable/reference/brand.md +0 -118
  170. package/templates/vite/.howone/skills/impeccable/reference/clarify.md +0 -174
  171. package/templates/vite/.howone/skills/impeccable/reference/codex.md +0 -105
  172. package/templates/vite/.howone/skills/impeccable/reference/cognitive-load.md +0 -106
  173. package/templates/vite/.howone/skills/impeccable/reference/color-and-contrast.md +0 -105
  174. package/templates/vite/.howone/skills/impeccable/reference/colorize.md +0 -154
  175. package/templates/vite/.howone/skills/impeccable/reference/craft.md +0 -123
  176. package/templates/vite/.howone/skills/impeccable/reference/critique.md +0 -273
  177. package/templates/vite/.howone/skills/impeccable/reference/delight.md +0 -302
  178. package/templates/vite/.howone/skills/impeccable/reference/distill.md +0 -111
  179. package/templates/vite/.howone/skills/impeccable/reference/document.md +0 -427
  180. package/templates/vite/.howone/skills/impeccable/reference/extract.md +0 -69
  181. package/templates/vite/.howone/skills/impeccable/reference/harden.md +0 -347
  182. package/templates/vite/.howone/skills/impeccable/reference/heuristics-scoring.md +0 -234
  183. package/templates/vite/.howone/skills/impeccable/reference/interaction-design.md +0 -195
  184. package/templates/vite/.howone/skills/impeccable/reference/layout.md +0 -141
  185. package/templates/vite/.howone/skills/impeccable/reference/live.md +0 -622
  186. package/templates/vite/.howone/skills/impeccable/reference/motion-design.md +0 -109
  187. package/templates/vite/.howone/skills/impeccable/reference/onboard.md +0 -234
  188. package/templates/vite/.howone/skills/impeccable/reference/optimize.md +0 -258
  189. package/templates/vite/.howone/skills/impeccable/reference/overdrive.md +0 -130
  190. package/templates/vite/.howone/skills/impeccable/reference/personas.md +0 -179
  191. package/templates/vite/.howone/skills/impeccable/reference/polish.md +0 -242
  192. package/templates/vite/.howone/skills/impeccable/reference/product.md +0 -62
  193. package/templates/vite/.howone/skills/impeccable/reference/quieter.md +0 -99
  194. package/templates/vite/.howone/skills/impeccable/reference/responsive-design.md +0 -114
  195. package/templates/vite/.howone/skills/impeccable/reference/shape.md +0 -165
  196. package/templates/vite/.howone/skills/impeccable/reference/spatial-design.md +0 -100
  197. package/templates/vite/.howone/skills/impeccable/reference/teach.md +0 -156
  198. package/templates/vite/.howone/skills/impeccable/reference/typeset.md +0 -124
  199. package/templates/vite/.howone/skills/impeccable/reference/typography.md +0 -159
  200. package/templates/vite/.howone/skills/impeccable/reference/ux-writing.md +0 -107
  201. package/templates/vite/.howone/skills/impeccable/scripts/cleanup-deprecated.mjs +0 -284
  202. package/templates/vite/.howone/skills/impeccable/scripts/command-metadata.json +0 -94
  203. package/templates/vite/.howone/skills/impeccable/scripts/critique-storage.mjs +0 -242
  204. package/templates/vite/.howone/skills/impeccable/scripts/design-parser.mjs +0 -820
  205. package/templates/vite/.howone/skills/impeccable/scripts/detect-csp.mjs +0 -198
  206. package/templates/vite/.howone/skills/impeccable/scripts/detect.mjs +0 -21
  207. package/templates/vite/.howone/skills/impeccable/scripts/impeccable-paths.mjs +0 -110
  208. package/templates/vite/.howone/skills/impeccable/scripts/is-generated.mjs +0 -69
  209. package/templates/vite/.howone/skills/impeccable/scripts/live-accept.mjs +0 -595
  210. package/templates/vite/.howone/skills/impeccable/scripts/live-browser-session.js +0 -123
  211. package/templates/vite/.howone/skills/impeccable/scripts/live-browser.js +0 -4860
  212. package/templates/vite/.howone/skills/impeccable/scripts/live-complete.mjs +0 -75
  213. package/templates/vite/.howone/skills/impeccable/scripts/live-completion.mjs +0 -18
  214. package/templates/vite/.howone/skills/impeccable/scripts/live-inject.mjs +0 -446
  215. package/templates/vite/.howone/skills/impeccable/scripts/live-poll.mjs +0 -200
  216. package/templates/vite/.howone/skills/impeccable/scripts/live-resume.mjs +0 -48
  217. package/templates/vite/.howone/skills/impeccable/scripts/live-server.mjs +0 -838
  218. package/templates/vite/.howone/skills/impeccable/scripts/live-session-store.mjs +0 -254
  219. package/templates/vite/.howone/skills/impeccable/scripts/live-status.mjs +0 -47
  220. package/templates/vite/.howone/skills/impeccable/scripts/live-wrap.mjs +0 -632
  221. package/templates/vite/.howone/skills/impeccable/scripts/live.mjs +0 -247
  222. package/templates/vite/.howone/skills/impeccable/scripts/load-context.mjs +0 -141
  223. package/templates/vite/.howone/skills/impeccable/scripts/modern-screenshot.umd.js +0 -14
  224. package/templates/vite/.howone/skills/impeccable/scripts/pin.mjs +0 -214
@@ -1,4886 +0,0 @@
1
- /* Hallmark — components */
2
-
3
- /* — Wordmark ——————————————————————————————————————— */
4
- .wordmark {
5
- font-family: var(--font-label);
6
- font-weight: 500;
7
- font-size: var(--text-sm);
8
- letter-spacing: 0.22em;
9
- text-transform: uppercase;
10
- color: var(--color-ink);
11
- }
12
-
13
- [data-theme="manifesto"] .wordmark {
14
- font-family: var(--font-display);
15
- font-weight: 800;
16
- letter-spacing: -0.02em;
17
- text-transform: uppercase;
18
- font-size: var(--text-md);
19
- }
20
-
21
- [data-theme="terminal"] .wordmark::before {
22
- content: "$ ";
23
- color: var(--color-accent);
24
- }
25
-
26
- /* — Banner (sticky top, thin, theme picker inline) ————————— */
27
- /* Uses --z-sticky-nav (above --z-sticky) so in-page sticky elements
28
- like Almanac's .section__head dock BELOW the banner instead of
29
- bleeding over it. Height stays in sync with --banner-height. */
30
- .banner {
31
- position: sticky;
32
- top: 0;
33
- z-index: var(--z-sticky-nav);
34
- display: flex;
35
- align-items: center;
36
- gap: var(--space-lg);
37
- padding: 0 var(--page-gutter);
38
- height: var(--banner-height);
39
- background: color-mix(in oklch, var(--color-paper) 88%, transparent);
40
- backdrop-filter: blur(14px) saturate(1.2);
41
- -webkit-backdrop-filter: blur(14px) saturate(1.2);
42
- border-block-end: var(--rule-hair) solid var(--color-rule);
43
- font-family: var(--font-label);
44
- font-size: 0.6875rem;
45
- letter-spacing: var(--tracking-label);
46
- text-transform: uppercase;
47
- color: var(--color-ink);
48
- }
49
-
50
- /* Spacer pushes the picker + theme-name to the right */
51
- .banner__spacer {
52
- flex: 1 1 auto;
53
- min-width: 0;
54
- }
55
-
56
- .banner__mark {
57
- display: inline-flex;
58
- align-items: baseline;
59
- gap: 0.55rem;
60
- text-decoration: none;
61
- color: var(--color-ink);
62
- }
63
-
64
- .banner__ver {
65
- font-size: 0.625rem;
66
- color: var(--color-muted);
67
- letter-spacing: 0.14em;
68
- }
69
-
70
- /* Sticky Install link — sits between the wordmark and the spacer.
71
- Becomes the most prominent thing on the banner once the user
72
- scrolls past the hero. */
73
- .banner__install {
74
- margin-inline-start: var(--space-md);
75
- padding: 0.18rem 0.65rem;
76
- font-family: var(--font-label);
77
- font-weight: 500;
78
- font-size: 0.6875rem;
79
- letter-spacing: 0.14em;
80
- text-transform: uppercase;
81
- color: var(--color-ink);
82
- text-decoration: none;
83
- border: 1px solid var(--color-rule-2);
84
- border-radius: var(--radius-pill, 999px);
85
- transition: background-color var(--dur-micro) var(--ease-out),
86
- color var(--dur-micro) var(--ease-out),
87
- border-color var(--dur-micro) var(--ease-out);
88
- }
89
-
90
- /* Hover scoped to true mouse devices so a tap on touch never sticks
91
- the inverted hover state across the rest of the session. */
92
- @media (hover: hover) and (pointer: fine) {
93
- .banner__install:hover {
94
- background: var(--color-ink);
95
- color: var(--color-paper);
96
- border-color: var(--color-ink);
97
- }
98
- }
99
-
100
- .banner__install:focus-visible {
101
- outline: 2px solid var(--color-focus);
102
- outline-offset: 2px;
103
- }
104
-
105
- /* Released after click — the JS blur handler removes :focus, but we
106
- also belt-and-brace via :focus:not(:focus-visible) so any browser
107
- that synthesises mouse-focus on click can't keep an inverted look. */
108
- .banner__install:focus:not(:focus-visible) {
109
- background: transparent;
110
- color: var(--color-ink);
111
- border-color: var(--color-rule-2);
112
- }
113
-
114
- @media (max-width: 50rem) {
115
- .banner__install { display: none; }
116
- /* Without the Install button to pair with, the star's negative
117
- start margin (sized for the install/star pair) pulls it too
118
- close to the wordmark. Loosen by +8px so the two CTAs read as
119
- bookends, not crowded. */
120
- .banner__star { margin-inline-start: -0.25rem; }
121
- }
122
-
123
- /* GitHub star button — sits next to Install in the banner, shows
124
- the live star count fetched from the GitHub API on load (cached
125
- in localStorage for 1 hour to avoid rate-limit). Click → repo. */
126
- .banner__star {
127
- display: inline-flex;
128
- align-items: center;
129
- gap: 0.35rem;
130
- /* Sit close to the Install button — pull back against the banner's
131
- flex gap so the two read as a CTA pair. */
132
- margin-inline-start: calc(-1 * var(--space-md) + 0.25rem);
133
- padding: 0.18rem 0.65rem;
134
- font-family: var(--font-label);
135
- font-weight: 500;
136
- font-size: 0.6875rem;
137
- letter-spacing: 0.06em;
138
- color: var(--color-ink);
139
- text-decoration: none;
140
- background: var(--color-ink);
141
- color: var(--color-paper);
142
- border: 1px solid var(--color-ink);
143
- border-radius: var(--radius-pill, 999px);
144
- transition: background-color var(--dur-micro) var(--ease-out),
145
- color var(--dur-micro) var(--ease-out),
146
- border-color var(--dur-micro) var(--ease-out);
147
- }
148
-
149
- .banner__star-icon {
150
- flex-shrink: 0;
151
- display: block;
152
- /* GitHub-style golden-yellow star, theme-independent. */
153
- color: #f5b300;
154
- }
155
-
156
- .banner__star-count {
157
- font-feature-settings: "tnum" 1;
158
- letter-spacing: 0.04em;
159
- }
160
-
161
- .banner__star:hover {
162
- background: var(--color-paper);
163
- color: var(--color-ink);
164
- border-color: var(--color-ink);
165
- }
166
-
167
- /* Star icon stays yellow on hover — it's a brand mark, not a state. */
168
-
169
- .banner__star:focus-visible {
170
- outline: 2px solid var(--color-focus);
171
- outline-offset: 2px;
172
- }
173
-
174
- @media (max-width: 36rem) {
175
- .banner__star {
176
- padding: 0.18rem 0.5rem;
177
- gap: 0.3rem;
178
- }
179
- }
180
-
181
- /* Genre label — small text after the theme name in the banner. */
182
- .banner__theme {
183
- display: inline;
184
- }
185
-
186
- .banner__genre {
187
- display: inline;
188
- margin-inline-start: 0.5em;
189
- font-family: var(--font-mono);
190
- font-size: 0.6875rem;
191
- letter-spacing: 0.04em;
192
- text-transform: lowercase;
193
- color: var(--color-muted);
194
- font-style: normal;
195
- font-weight: 400;
196
- }
197
-
198
- .banner__genre::before {
199
- content: "· ";
200
- color: var(--color-rule-2);
201
- margin-inline-end: 0.1em;
202
- }
203
-
204
- @media (max-width: 38rem) {
205
- .banner__genre { display: none; }
206
- }
207
-
208
- /* T-key onboarding tooltip — appears after 5 s idle, dismisses on
209
- first T press. Anchored under the shuffle button. */
210
- .t-tooltip {
211
- position: absolute;
212
- top: calc(100% + 12px);
213
- right: var(--page-gutter);
214
- padding: 0.55rem 0.85rem;
215
- background: var(--color-ink);
216
- color: var(--color-paper);
217
- border-radius: 6px;
218
- font-family: var(--font-body);
219
- font-size: 0.8125rem;
220
- letter-spacing: 0;
221
- text-transform: none;
222
- line-height: 1.45;
223
- box-shadow: 0 8px 24px -8px oklch(20% 0.02 60 / 0.32);
224
- z-index: var(--z-sticky);
225
- animation: t-tooltip-in 320ms var(--ease-out) both;
226
- }
227
-
228
- .t-tooltip[hidden] { display: none; }
229
-
230
- .t-tooltip[data-state="closing"] {
231
- animation: t-tooltip-out 240ms var(--ease-in) forwards;
232
- }
233
-
234
- @keyframes t-tooltip-in {
235
- from { opacity: 0; transform: translateY(-6px); }
236
- to { opacity: 1; transform: none; }
237
- }
238
-
239
- @keyframes t-tooltip-out {
240
- from { opacity: 1; transform: none; }
241
- to { opacity: 0; transform: translateY(-4px); }
242
- }
243
-
244
- .t-tooltip__arrow {
245
- position: absolute;
246
- top: -5px;
247
- right: 28px;
248
- width: 10px;
249
- height: 10px;
250
- background: var(--color-ink);
251
- transform: rotate(45deg);
252
- border-radius: 1px;
253
- }
254
-
255
- .t-tooltip__body kbd {
256
- display: inline-block;
257
- padding: 0.1em 0.45em;
258
- margin-inline: 0.1em;
259
- background: var(--color-paper);
260
- color: var(--color-ink);
261
- border-radius: 3px;
262
- font-family: var(--font-mono);
263
- font-size: 0.85em;
264
- font-weight: 500;
265
- letter-spacing: 0;
266
- }
267
-
268
- .t-tooltip__body strong {
269
- font-weight: 600;
270
- }
271
-
272
- @media (prefers-reduced-motion: reduce) {
273
- .t-tooltip { animation: none; }
274
- }
275
-
276
- /* — Theme indicator + dropdown ————————————————————————————
277
- Replaces the inline 23-dot strip. The indicator reads "01 / 23 —
278
- Specimen" in the active theme's display face; clicking it opens
279
- a compact 6×4 grid of color swatches (no theme names, deliberately
280
- minimal). Dropdown is position: absolute below the indicator. */
281
- .banner__theme-wrap {
282
- position: relative;
283
- display: inline-flex;
284
- align-items: center;
285
- }
286
-
287
- .banner__theme-indicator {
288
- appearance: none;
289
- display: inline-flex;
290
- align-items: baseline;
291
- gap: 0.4rem;
292
- height: 28px;
293
- padding: 0 0.65rem;
294
- background: transparent;
295
- border: 1px solid transparent;
296
- border-radius: var(--radius-pill, 999px);
297
- color: var(--color-ink);
298
- cursor: pointer;
299
- font-family: var(--font-display);
300
- font-weight: var(--display-weight, 500);
301
- font-style: var(--display-style, normal);
302
- font-size: 0.95rem;
303
- letter-spacing: -0.005em;
304
- font-optical-sizing: auto;
305
- white-space: nowrap;
306
- transition: border-color var(--dur-micro) var(--ease-out),
307
- background var(--dur-micro) var(--ease-out);
308
- }
309
-
310
- @media (hover: hover) and (pointer: fine) {
311
- .banner__theme-indicator:hover {
312
- border-color: var(--color-rule-2);
313
- }
314
- }
315
-
316
- .banner__theme-indicator:focus-visible {
317
- outline: 2px solid var(--color-focus);
318
- outline-offset: 2px;
319
- }
320
-
321
- .banner__theme-indicator[aria-expanded="true"] {
322
- border-color: var(--color-rule-2);
323
- background: var(--color-paper-2);
324
- }
325
-
326
- /* "01 / 23" set in mono for tabular alignment + ledger feel. */
327
- .banner__ordinal {
328
- font-family: var(--font-mono);
329
- font-size: 0.6875rem;
330
- letter-spacing: 0.04em;
331
- color: var(--color-muted);
332
- font-feature-settings: "tnum" 1;
333
- text-transform: uppercase;
334
- }
335
-
336
- .banner__indicator-sep {
337
- color: var(--color-rule-2);
338
- font-family: var(--font-display);
339
- font-size: 0.95rem;
340
- }
341
-
342
- .banner__caret {
343
- flex-shrink: 0;
344
- align-self: center;
345
- color: var(--color-muted);
346
- margin-inline-start: 0.1rem;
347
- transition: transform var(--dur-micro) var(--ease-out);
348
- }
349
-
350
- .banner__theme-indicator[aria-expanded="true"] .banner__caret {
351
- transform: rotate(180deg);
352
- }
353
-
354
- /* Theme-aware overrides for the theme-name span (was on .banner__center). */
355
- [data-theme="manifesto"] .banner__theme-indicator,
356
- [data-theme="brutal"] .banner__theme-indicator,
357
- [data-theme="sport"] .banner__theme-indicator {
358
- text-transform: uppercase;
359
- letter-spacing: -0.01em;
360
- }
361
-
362
- [data-theme="terminal"] .banner__theme::before {
363
- content: "$ ";
364
- color: var(--color-accent);
365
- }
366
-
367
- [data-theme="terminal"] .banner__theme-indicator {
368
- font-family: var(--font-mono);
369
- }
370
-
371
- /* — Banner pill per-theme shape + voice ————————————————————————
372
- The banner is the only fixed surface that crosses every theme. If
373
- it stays the same shape on all 22 themes, the "switching themes
374
- rebuilds the page" claim leaks. Per-theme shape (border-radius) and
375
- font choice push the banner into the theme's register too. */
376
-
377
- /* HARD EDGES — square pill, no radius. Brutalist / manifesto / print register. */
378
- [data-theme="brutal"] .banner__install,
379
- [data-theme="brutal"] .banner__star,
380
- [data-theme="manifesto"] .banner__install,
381
- [data-theme="manifesto"] .banner__star,
382
- [data-theme="newsprint"] .banner__install,
383
- [data-theme="newsprint"] .banner__star,
384
- [data-theme="terminal"] .banner__install,
385
- [data-theme="terminal"] .banner__star,
386
- [data-theme="editorial"] .banner__install,
387
- [data-theme="editorial"] .banner__star {
388
- border-radius: 0;
389
- }
390
-
391
- /* Brutal / Manifesto — heavier border, display font, uppercase. */
392
- [data-theme="brutal"] .banner__install,
393
- [data-theme="manifesto"] .banner__install {
394
- border-width: 2px;
395
- font-family: var(--font-display);
396
- font-weight: 700;
397
- }
398
-
399
- /* Terminal — mono for everything in the banner. */
400
- [data-theme="terminal"] .banner__install,
401
- [data-theme="terminal"] .banner__star {
402
- font-family: var(--font-mono);
403
- }
404
- [data-theme="terminal"] .banner__install {
405
- border-color: var(--color-accent);
406
- }
407
-
408
- /* SLIGHT RADIUS — sport / almanac (record card register). */
409
- [data-theme="sport"] .banner__install,
410
- [data-theme="sport"] .banner__star,
411
- [data-theme="almanac"] .banner__install,
412
- [data-theme="almanac"] .banner__star {
413
- border-radius: 4px;
414
- }
415
- [data-theme="sport"] .banner__install,
416
- [data-theme="sport"] .banner__star {
417
- font-family: var(--font-mono);
418
- font-style: italic;
419
- }
420
-
421
- /* SOFT-CARD RADIUS — garden / halo / violet / studio. */
422
- [data-theme="garden"] .banner__install,
423
- [data-theme="garden"] .banner__star,
424
- [data-theme="halo"] .banner__install,
425
- [data-theme="halo"] .banner__star,
426
- [data-theme="violet"] .banner__install,
427
- [data-theme="violet"] .banner__star,
428
- [data-theme="studio"] .banner__install,
429
- [data-theme="studio"] .banner__star {
430
- border-radius: 6px;
431
- }
432
- [data-theme="halo"] .banner__install {
433
- box-shadow: inset 0 0 0 1px color-mix(in oklch, var(--color-accent) 35%, transparent);
434
- }
435
- [data-theme="studio"] .banner__install,
436
- [data-theme="studio"] .banner__star {
437
- font-family: var(--font-mono);
438
- font-weight: 500;
439
- }
440
-
441
- /* OFF-REGISTER STAMP — riso. 2px radius + duotone offset shadow. */
442
- [data-theme="riso"] .banner__install,
443
- [data-theme="riso"] .banner__star {
444
- border-radius: 2px;
445
- box-shadow: 1px 1px 0 var(--color-accent-2, var(--color-accent));
446
- }
447
-
448
- /* ATELIER / SALON — italic serif label, hairline only (atelier). */
449
- [data-theme="atelier"] .banner__install {
450
- border-color: var(--color-rule);
451
- font-family: var(--font-serif);
452
- font-style: italic;
453
- letter-spacing: 0;
454
- text-transform: none;
455
- }
456
- [data-theme="salon"] .banner__install {
457
- font-family: var(--font-serif);
458
- font-style: italic;
459
- letter-spacing: 0;
460
- text-transform: none;
461
- }
462
-
463
- /* Theme-indicator extra cases — extend the existing uppercase group. */
464
- [data-theme="almanac"] .banner__theme-indicator,
465
- [data-theme="newsprint"] .banner__theme-indicator,
466
- [data-theme="editorial"] .banner__theme-indicator {
467
- text-transform: uppercase;
468
- letter-spacing: -0.01em;
469
- }
470
- [data-theme="atelier"] .banner__theme-indicator,
471
- [data-theme="salon"] .banner__theme-indicator {
472
- font-style: italic;
473
- }
474
-
475
- /* Dropdown panel — appears under the indicator. Hidden by default. */
476
- .theme-dropdown {
477
- position: absolute;
478
- top: calc(100% + 8px);
479
- right: 0;
480
- z-index: var(--z-sticky);
481
- display: grid;
482
- grid-template-columns: repeat(6, 1fr);
483
- gap: 6px;
484
- padding: 10px;
485
- background: var(--color-paper);
486
- border: 1px solid var(--color-rule-2);
487
- border-radius: 4px;
488
- box-shadow: 0 12px 36px -10px oklch(20% 0.02 60 / 0.22);
489
- animation: theme-dropdown-in 140ms var(--ease-out);
490
- transform-origin: top right;
491
- }
492
-
493
- .theme-dropdown[hidden] { display: none; }
494
-
495
- @keyframes theme-dropdown-in {
496
- from { opacity: 0; transform: translateY(-4px) scale(0.98); }
497
- to { opacity: 1; transform: translateY(0) scale(1); }
498
- }
499
-
500
- @media (prefers-reduced-motion: reduce) {
501
- .theme-dropdown { animation: none; }
502
- }
503
-
504
- /* Dot inside the dropdown — same styling as the old .banner__dot. */
505
- .theme-dropdown__dot {
506
- appearance: none;
507
- width: 34px;
508
- height: 34px;
509
- padding: 0;
510
- background: var(--dot, var(--color-paper));
511
- border: 1px solid var(--color-rule-2);
512
- border-radius: 4px;
513
- cursor: pointer;
514
- position: relative;
515
- display: grid;
516
- place-items: center;
517
- overflow: hidden;
518
- isolation: isolate;
519
- transition: transform 100ms var(--ease-out),
520
- border-color var(--dur-micro) var(--ease-out),
521
- box-shadow var(--dur-micro) var(--ease-out);
522
- }
523
-
524
- .theme-dropdown__dot::after {
525
- content: "";
526
- position: absolute;
527
- inset: auto 0 0 0;
528
- height: 4px;
529
- background: var(--dot-edge, transparent);
530
- z-index: 0;
531
- }
532
-
533
- .theme-dropdown__num {
534
- position: relative;
535
- z-index: 1;
536
- font-family: "Geist Mono", ui-monospace, monospace;
537
- font-size: 11px;
538
- font-weight: 500;
539
- letter-spacing: 0.02em;
540
- color: color-mix(in oklch, var(--dot-edge, var(--color-ink)) 55%, var(--color-ink));
541
- font-feature-settings: "tnum";
542
- pointer-events: none;
543
- }
544
-
545
- @media (hover: hover) and (pointer: fine) {
546
- .theme-dropdown__dot:hover {
547
- transform: translateY(-1px);
548
- border-color: var(--color-ink);
549
- }
550
- }
551
-
552
- .theme-dropdown__dot:focus-visible {
553
- outline: 2px solid var(--color-focus);
554
- outline-offset: 2px;
555
- }
556
-
557
- .theme-dropdown__dot[aria-pressed="true"] {
558
- border-color: var(--color-ink);
559
- box-shadow: 0 0 0 2px var(--color-paper), 0 0 0 3px var(--color-ink);
560
- }
561
-
562
- /* Combined shuffle button: icon + T kbd hint inside a single pill.
563
- Click randomises; the T inside reads as a keyboard hint, not a separate
564
- pill. Replaces the old .banner__random + .banner__kbd combo. */
565
- .banner__shuffle {
566
- appearance: none;
567
- display: inline-flex;
568
- align-items: center;
569
- justify-content: center;
570
- gap: 0.4rem;
571
- height: 26px;
572
- padding: 0 0.6rem 0 0.55rem;
573
- /* Pull tight to the theme indicator — same math as .banner__star pulls
574
- against Install, so the right-side picker↔shuffle gap mirrors the
575
- left-side Install↔Star gap. */
576
- margin-inline-start: calc(-1 * var(--space-md) + 0.25rem);
577
- background: transparent;
578
- border: 1px solid var(--color-rule);
579
- border-radius: var(--radius-pill, 999px);
580
- color: var(--color-muted);
581
- cursor: pointer;
582
- font-family: var(--font-label);
583
- font-size: 0.625rem;
584
- letter-spacing: 0.08em;
585
- text-transform: uppercase;
586
- transition: color var(--dur-micro) var(--ease-out),
587
- border-color var(--dur-micro) var(--ease-out),
588
- background var(--dur-micro) var(--ease-out),
589
- transform 80ms var(--ease-out);
590
- }
591
-
592
- .banner__shuffle svg {
593
- flex-shrink: 0;
594
- display: block;
595
- }
596
-
597
- .banner__shuffle-key {
598
- display: inline-block;
599
- font-weight: 500;
600
- letter-spacing: 0.04em;
601
- color: var(--color-muted);
602
- padding-inline-start: 0.4rem;
603
- border-inline-start: 1px solid var(--color-rule);
604
- margin-inline-start: 0.05rem;
605
- height: 14px;
606
- line-height: 14px;
607
- }
608
-
609
- @media (hover: hover) and (pointer: fine) {
610
- .banner__shuffle:hover {
611
- color: var(--color-ink);
612
- border-color: var(--color-ink);
613
- }
614
- .banner__shuffle:hover .banner__shuffle-key {
615
- color: var(--color-ink);
616
- border-color: var(--color-ink);
617
- }
618
- .banner__shuffle:hover svg {
619
- transform: rotate(15deg);
620
- transition: transform 200ms var(--ease-out);
621
- }
622
- }
623
-
624
- .banner__shuffle:active {
625
- transform: scale(0.96);
626
- transition-duration: 60ms;
627
- }
628
-
629
- .banner__shuffle:focus-visible {
630
- outline: 2px solid var(--color-focus);
631
- outline-offset: 2px;
632
- }
633
-
634
- @media (max-width: 60rem) {
635
- .banner { gap: var(--space-md); }
636
- .banner__theme-indicator { font-size: 0.85rem; padding: 0 0.5rem; }
637
- .banner__ordinal { font-size: 0.625rem; }
638
- }
639
-
640
- @media (max-width: 44rem) {
641
- .banner__ver { display: none; }
642
- .banner__shuffle-key { display: none; }
643
- .banner__shuffle { padding: 0 0.5rem; height: 24px; }
644
- /* Hide ordinal on small viewports — keep just the theme name + caret. */
645
- .banner__ordinal,
646
- .banner__indicator-sep { display: none; }
647
- }
648
-
649
- @media (max-width: 26rem) {
650
- .banner__theme-indicator .banner__theme { display: none; }
651
- }
652
-
653
- /* — Section label (01 / FOUNDATIONS) —————————————————— */
654
- .section-label {
655
- font-family: var(--font-label);
656
- font-size: var(--text-xs);
657
- font-weight: 400;
658
- letter-spacing: var(--tracking-label);
659
- text-transform: uppercase;
660
- color: var(--color-muted);
661
- display: flex;
662
- align-items: baseline;
663
- gap: var(--space-sm);
664
- }
665
-
666
- .section-label .num { color: var(--color-ink); font-weight: 500; }
667
- .section-label .divider { color: var(--color-rule-2); font-weight: 300; }
668
-
669
- /* Terminal — vary the prompt prefix per section so the "//" gag doesn't get old.
670
- Cycles through > , //, # , -- across the run of sections. */
671
- [data-theme="terminal"] .section-label::before {
672
- content: "> ";
673
- color: var(--color-accent);
674
- }
675
- [data-theme="terminal"] .section:nth-of-type(4n+2) .section-label::before { content: "// "; }
676
- [data-theme="terminal"] .section:nth-of-type(4n+3) .section-label::before { content: "# "; }
677
- [data-theme="terminal"] .section:nth-of-type(4n+4) .section-label::before { content: "-- "; }
678
-
679
- [data-theme="manifesto"] .section-label .num {
680
- color: var(--color-accent);
681
- font-family: var(--font-display);
682
- font-weight: 800;
683
- font-size: var(--text-md);
684
- }
685
-
686
- [data-theme="sport"] .section-label .num {
687
- color: var(--color-accent);
688
- font-weight: 700;
689
- font-family: var(--font-display);
690
- font-size: var(--text-md);
691
- font-style: italic;
692
- }
693
-
694
- [data-theme="almanac"] .section-label {
695
- font-family: var(--font-mono);
696
- }
697
-
698
- /* — Button (outlined default) ————————————————————————— */
699
- .btn {
700
- display: inline-flex;
701
- align-items: center;
702
- gap: var(--space-sm);
703
- padding: var(--space-sm) var(--space-lg);
704
- font-family: var(--font-label);
705
- font-size: var(--text-sm);
706
- font-weight: 500;
707
- letter-spacing: 0.04em;
708
- color: var(--color-ink);
709
- background: transparent;
710
- border: var(--rule-fine) solid var(--color-ink);
711
- border-radius: var(--radius-pill, 0);
712
- min-height: 44px;
713
- /* explicit properties — never `transition: all` */
714
- transition: transform 100ms var(--ease-out),
715
- background-color var(--dur-micro) var(--ease-out),
716
- color var(--dur-micro) var(--ease-out),
717
- border-color var(--dur-micro) var(--ease-out);
718
- cursor: pointer;
719
- }
720
-
721
- @media (hover: hover) and (pointer: fine) {
722
- .btn:hover {
723
- background: var(--color-ink);
724
- color: var(--color-paper);
725
- transform: translateY(-1px);
726
- }
727
- }
728
- .btn:active { transform: translateY(1px); transition-duration: 60ms; }
729
-
730
- /* — Inline link ————————————————————————————————————— */
731
- .link {
732
- color: var(--color-ink);
733
- text-decoration: none;
734
- background-image: linear-gradient(var(--color-accent), var(--color-accent));
735
- background-repeat: no-repeat;
736
- background-position: 0 100%;
737
- background-size: 100% 1px;
738
- padding-bottom: 0.08em;
739
- transition: background-size var(--dur-short) var(--ease-out);
740
- }
741
-
742
- @media (hover: hover) and (pointer: fine) {
743
- .link:hover { background-size: 100% 2px; }
744
- }
745
-
746
- [data-theme="terminal"] .link {
747
- background: none;
748
- text-decoration: underline;
749
- text-underline-offset: 2px;
750
- }
751
-
752
- /* — Code block ——————————————————————————————————————— */
753
- .code {
754
- font-family: var(--font-mono);
755
- font-size: var(--text-sm);
756
- font-weight: 400;
757
- color: var(--color-ink);
758
- background: var(--color-paper-2);
759
- border: var(--rule-hair) solid var(--color-rule);
760
- border-radius: var(--radius-input, 0);
761
- padding: var(--space-md) var(--space-lg);
762
- overflow-x: auto;
763
- white-space: nowrap;
764
- line-height: 1.7;
765
- display: flex;
766
- align-items: center;
767
- gap: var(--space-md);
768
- position: relative;
769
- box-shadow: var(--shadow-card, none);
770
- }
771
-
772
- .code .prompt { color: var(--color-muted); user-select: none; }
773
- .code--block { white-space: pre; display: block; }
774
-
775
- /* — Copy-to-clipboard button (silent success pattern) ————— */
776
- .code__copy {
777
- position: absolute;
778
- top: 50%;
779
- right: var(--space-sm);
780
- transform: translateY(-50%);
781
- font-family: var(--font-label);
782
- font-size: 0.6875rem;
783
- letter-spacing: 0.14em;
784
- text-transform: uppercase;
785
- color: var(--color-muted);
786
- background: var(--color-paper);
787
- border: var(--rule-hair) solid var(--color-rule);
788
- border-radius: var(--radius-input, 0);
789
- padding: 0.35rem 0.65rem;
790
- cursor: pointer;
791
- opacity: 0;
792
- transition: opacity var(--dur-short) var(--ease-out),
793
- color var(--dur-short) var(--ease-out),
794
- border-color var(--dur-short) var(--ease-out);
795
- min-height: 28px;
796
- display: inline-flex;
797
- align-items: center;
798
- gap: 0.4rem;
799
- }
800
-
801
- .code:hover .code__copy,
802
- .code:focus-within .code__copy,
803
- .code__copy:focus-visible {
804
- opacity: 1;
805
- }
806
-
807
- @media (pointer: coarse) {
808
- .code__copy { opacity: 1; }
809
- }
810
-
811
- .code__copy:hover { color: var(--color-ink); border-color: var(--color-rule-2); }
812
-
813
- .code__copy[data-state="copied"] {
814
- color: var(--color-accent);
815
- border-color: var(--color-accent);
816
- opacity: 1;
817
- }
818
-
819
- .code__copy-default { display: inline; }
820
- .code__copy-done { display: none; }
821
-
822
- .code__copy[data-state="copied"] .code__copy-default { display: none; }
823
- .code__copy[data-state="copied"] .code__copy-done { display: inline; }
824
-
825
- /* Mobile · drop the copy button entirely and make the whole pre
826
- tap-to-copy. The button at narrow widths overflowed the frame; on
827
- coarse-pointer devices a full-width tap target is the right
828
- pattern (matches `gh repo clone` / npmjs / Vercel install panes).
829
- The pre keeps its flex + center alignment so the command sits
830
- vertically centred regardless of frame height. */
831
- @media (max-width: 45rem) {
832
- .code__copy { display: none; }
833
-
834
- .code[data-copy-source] { cursor: pointer; }
835
-
836
- /* Transient "Copied ✓" badge inside the pre, anchored top-right.
837
- Replaces the button's label-swap on mobile. Fades automatically
838
- when JS removes data-state after 2.2 s. */
839
- .code[data-copy-source][data-state="copied"] {
840
- position: relative;
841
- }
842
- .code[data-copy-source][data-state="copied"]::after {
843
- content: "Copied ✓";
844
- position: absolute;
845
- top: 50%;
846
- right: var(--space-sm);
847
- transform: translateY(-50%);
848
- padding: 0.25rem 0.55rem;
849
- font-family: var(--font-label);
850
- font-size: 0.6875rem;
851
- letter-spacing: 0.14em;
852
- text-transform: uppercase;
853
- color: var(--color-accent);
854
- background: var(--color-paper);
855
- border: var(--rule-hair) solid var(--color-accent);
856
- border-radius: var(--radius-input, 0);
857
- pointer-events: none;
858
- animation: copy-flash var(--dur-short) var(--ease-out);
859
- }
860
- @keyframes copy-flash {
861
- from { opacity: 0; transform: translateY(-50%) scale(0.96); }
862
- to { opacity: 1; transform: translateY(-50%) scale(1); }
863
- }
864
- @media (prefers-reduced-motion: reduce) {
865
- .code[data-copy-source][data-state="copied"]::after { animation: none; }
866
- }
867
- }
868
-
869
- [data-theme="terminal"] .code__copy {
870
- background: var(--color-paper-2);
871
- border-color: var(--color-rule);
872
- }
873
-
874
- [data-theme="manifesto"] .code__copy {
875
- background: var(--color-paper);
876
- color: var(--color-paper);
877
- border-color: var(--color-paper);
878
- font-weight: 500;
879
- }
880
-
881
- [data-theme="manifesto"] .code__copy:hover {
882
- color: var(--color-paper);
883
- background: var(--color-accent);
884
- border-color: var(--color-accent);
885
- }
886
-
887
- [data-theme="terminal"] .code {
888
- background: var(--color-paper-3);
889
- border-color: var(--color-rule-2);
890
- }
891
-
892
- [data-theme="manifesto"] .code {
893
- background: var(--color-ink);
894
- color: var(--color-paper);
895
- border-color: var(--color-ink);
896
- }
897
-
898
- [data-theme="manifesto"] .code .prompt { color: var(--color-accent); }
899
-
900
- /* — Specimen card ——————————————————————————————————— */
901
- .spec {
902
- display: flex;
903
- flex-direction: column;
904
- gap: var(--space-lg);
905
- padding: var(--space-xl) 0;
906
- border-top: var(--rule-hair) solid var(--color-rule);
907
- }
908
-
909
- .spec__head {
910
- display: flex;
911
- align-items: baseline;
912
- justify-content: space-between;
913
- gap: var(--space-md);
914
- }
915
-
916
- .spec__name {
917
- font-family: var(--font-display);
918
- font-weight: var(--display-weight, 400);
919
- font-style: var(--display-style, normal);
920
- font-size: var(--text-xl);
921
- letter-spacing: var(--tracking-tight);
922
- color: var(--color-ink);
923
- line-height: 1;
924
- font-optical-sizing: auto;
925
- }
926
-
927
- .spec__num {
928
- font-family: var(--font-label);
929
- font-size: var(--text-xs);
930
- color: var(--color-muted);
931
- letter-spacing: var(--tracking-label);
932
- }
933
-
934
- .spec__rule {
935
- font-family: var(--font-serif);
936
- font-weight: 400;
937
- font-size: var(--text-md);
938
- line-height: var(--lh-snug);
939
- color: var(--color-ink-2);
940
- max-width: 40ch;
941
- }
942
-
943
- [data-theme="brutal"] .spec__rule,
944
- [data-theme="manifesto"] .spec__rule,
945
- [data-theme="terminal"] .spec__rule,
946
- [data-theme="sport"] .spec__rule,
947
- [data-theme="almanac"] .spec__rule {
948
- font-style: normal;
949
- font-family: var(--font-body);
950
- font-weight: 500;
951
- }
952
-
953
- [data-theme="manifesto"] .spec__name { text-transform: uppercase; }
954
-
955
- .spec__body { margin-top: var(--space-xs); }
956
-
957
- /* — Foundations nav (left column of the spec sheet) ——————————
958
- Each item is a clickable label. The active item shows an accent
959
- dot, slightly bolder name, and a subtle inset background. */
960
- .found-nav__btn {
961
- display: grid;
962
- grid-template-columns: 2.5rem 1fr 0.5rem;
963
- align-items: baseline;
964
- gap: var(--space-sm);
965
- padding: var(--space-md) 0 var(--space-md) var(--space-sm);
966
- border-block-end: var(--rule-hair) solid var(--color-rule);
967
- cursor: pointer;
968
- user-select: none;
969
- transition: background-color var(--dur-micro) var(--ease-out),
970
- padding-inline-start var(--dur-short) var(--ease-out);
971
- }
972
-
973
- .found-nav__btn:hover {
974
- background: var(--color-paper-2);
975
- }
976
-
977
- .found-nav__num {
978
- font-family: var(--font-label);
979
- font-size: var(--text-xs);
980
- letter-spacing: var(--tracking-label);
981
- color: var(--color-muted);
982
- font-feature-settings: "tnum";
983
- }
984
-
985
- .found-nav__name {
986
- font-family: var(--font-display);
987
- font-style: var(--display-style, normal);
988
- font-weight: var(--display-weight, 500);
989
- font-size: var(--text-lg);
990
- letter-spacing: var(--tracking-tight);
991
- color: var(--color-ink-2);
992
- line-height: 1;
993
- }
994
-
995
- .found-nav__dot {
996
- display: inline-block;
997
- width: 6px;
998
- height: 6px;
999
- border-radius: 50%;
1000
- background: transparent;
1001
- align-self: center;
1002
- justify-self: end;
1003
- transition: background-color var(--dur-short) var(--ease-out);
1004
- }
1005
-
1006
- [data-theme="riso"] .found-nav__name { text-transform: lowercase; }
1007
- [data-theme="brutal"] .found-nav__name,
1008
- [data-theme="manifesto"] .found-nav__name,
1009
- [data-theme="sport"] .found-nav__name { text-transform: uppercase; }
1010
-
1011
- /* Active state — driven by which radio is :checked */
1012
- #f-type:checked ~ .found-grid .found-nav__btn[for="f-type"],
1013
- #f-colour:checked ~ .found-grid .found-nav__btn[for="f-colour"],
1014
- #f-space:checked ~ .found-grid .found-nav__btn[for="f-space"],
1015
- #f-motion:checked ~ .found-grid .found-nav__btn[for="f-motion"],
1016
- #f-voice:checked ~ .found-grid .found-nav__btn[for="f-voice"] {
1017
- background: color-mix(in oklch, var(--color-accent) 5%, transparent);
1018
- padding-inline-start: var(--space-md);
1019
- }
1020
-
1021
- #f-type:checked ~ .found-grid .found-nav__btn[for="f-type"] .found-nav__name,
1022
- #f-colour:checked ~ .found-grid .found-nav__btn[for="f-colour"] .found-nav__name,
1023
- #f-space:checked ~ .found-grid .found-nav__btn[for="f-space"] .found-nav__name,
1024
- #f-motion:checked ~ .found-grid .found-nav__btn[for="f-motion"] .found-nav__name,
1025
- #f-voice:checked ~ .found-grid .found-nav__btn[for="f-voice"] .found-nav__name {
1026
- color: var(--color-ink);
1027
- }
1028
-
1029
- #f-type:checked ~ .found-grid .found-nav__btn[for="f-type"] .found-nav__dot,
1030
- #f-colour:checked ~ .found-grid .found-nav__btn[for="f-colour"] .found-nav__dot,
1031
- #f-space:checked ~ .found-grid .found-nav__btn[for="f-space"] .found-nav__dot,
1032
- #f-motion:checked ~ .found-grid .found-nav__btn[for="f-motion"] .found-nav__dot,
1033
- #f-voice:checked ~ .found-grid .found-nav__btn[for="f-voice"] .found-nav__dot {
1034
- background: var(--color-accent);
1035
- }
1036
-
1037
- /* Focus-visible outline on the *button* when its corresponding radio
1038
- is focused (radios are off-screen but keyboard-focusable). */
1039
- #f-type:focus-visible ~ .found-grid .found-nav__btn[for="f-type"],
1040
- #f-colour:focus-visible ~ .found-grid .found-nav__btn[for="f-colour"],
1041
- #f-space:focus-visible ~ .found-grid .found-nav__btn[for="f-space"],
1042
- #f-motion:focus-visible ~ .found-grid .found-nav__btn[for="f-motion"],
1043
- #f-voice:focus-visible ~ .found-grid .found-nav__btn[for="f-voice"] {
1044
- outline: 2px solid var(--color-focus);
1045
- outline-offset: -2px;
1046
- }
1047
-
1048
- /* — Foundations panels (right column) —————————————————————— */
1049
- .found-panels {
1050
- position: relative;
1051
- min-height: 24rem;
1052
- }
1053
-
1054
- .found-panel {
1055
- display: none;
1056
- padding-inline-start: var(--space-xl);
1057
- border-inline-start: var(--rule-hair) solid var(--color-rule);
1058
- }
1059
-
1060
- @media (max-width: 60rem) {
1061
- .found-panel {
1062
- padding-inline-start: 0;
1063
- border-inline-start: 0;
1064
- padding-block: var(--space-md) var(--space-xl);
1065
- }
1066
- }
1067
-
1068
- #f-type:checked ~ .found-grid .found-panels .found-panel[data-panel="type"],
1069
- #f-colour:checked ~ .found-grid .found-panels .found-panel[data-panel="colour"],
1070
- #f-space:checked ~ .found-grid .found-panels .found-panel[data-panel="space"],
1071
- #f-motion:checked ~ .found-grid .found-panels .found-panel[data-panel="motion"],
1072
- #f-voice:checked ~ .found-grid .found-panels .found-panel[data-panel="voice"] {
1073
- display: grid;
1074
- gap: var(--space-lg);
1075
- animation: found-fade-in 280ms var(--ease-out);
1076
- }
1077
-
1078
- @keyframes found-fade-in {
1079
- from { opacity: 0; transform: translateY(4px); }
1080
- to { opacity: 1; transform: none; }
1081
- }
1082
-
1083
- @media (prefers-reduced-motion: reduce) {
1084
- .found-panel { animation: none !important; }
1085
- }
1086
-
1087
- .found-panel__rule {
1088
- margin: 0;
1089
- font-family: var(--font-serif);
1090
- font-size: var(--text-md);
1091
- line-height: var(--lh-normal);
1092
- color: var(--color-ink-2);
1093
- max-width: 56ch;
1094
- }
1095
-
1096
- [data-theme="brutal"] .found-panel__rule,
1097
- [data-theme="manifesto"] .found-panel__rule,
1098
- [data-theme="terminal"] .found-panel__rule,
1099
- [data-theme="sport"] .found-panel__rule,
1100
- [data-theme="almanac"] .found-panel__rule,
1101
- [data-theme="quiet"] .found-panel__rule,
1102
- [data-theme="bloom"] .found-panel__rule,
1103
- [data-theme="aurora"] .found-panel__rule,
1104
- [data-theme="halo"] .found-panel__rule,
1105
- [data-theme="coral"] .found-panel__rule,
1106
- [data-theme="violet"] .found-panel__rule {
1107
- font-family: var(--font-body);
1108
- font-style: normal;
1109
- }
1110
-
1111
- .found-panel__viz {
1112
- margin-block-start: 0;
1113
- }
1114
-
1115
- /* Mobile accordion — each panel tucks under its corresponding nav row */
1116
- @media (max-width: 60rem) {
1117
- .found-grid > .found-panels { display: contents; }
1118
- .found-panel { order: 0; }
1119
- .found-nav__btn[for="f-type"] { order: 1; }
1120
- .found-panel[data-panel="type"] { order: 2; }
1121
- .found-nav__btn[for="f-colour"] { order: 3; }
1122
- .found-panel[data-panel="colour"] { order: 4; }
1123
- .found-nav__btn[for="f-space"] { order: 5; }
1124
- .found-panel[data-panel="space"] { order: 6; }
1125
- .found-nav__btn[for="f-motion"] { order: 7; }
1126
- .found-panel[data-panel="motion"] { order: 8; }
1127
- .found-nav__btn[for="f-voice"] { order: 9; }
1128
- .found-panel[data-panel="voice"] { order: 10; }
1129
- }
1130
-
1131
- /* — Swatches ——————————————————————————————————————— */
1132
- .swatch-row {
1133
- display: grid;
1134
- grid-template-columns: repeat(5, 1fr);
1135
- gap: var(--space-2xs);
1136
- height: 3rem;
1137
- }
1138
-
1139
- .swatch {
1140
- display: flex;
1141
- align-items: flex-end;
1142
- padding: var(--space-2xs) var(--space-xs);
1143
- font-family: var(--font-label);
1144
- font-size: 0.625rem;
1145
- letter-spacing: 0.08em;
1146
- color: var(--color-paper);
1147
- text-transform: uppercase;
1148
- }
1149
-
1150
- .swatch--light { color: var(--color-ink); }
1151
-
1152
- /* — Type specimen ——————————————————————————————————— */
1153
- .type-spec { display: grid; gap: var(--space-xs); }
1154
-
1155
- .type-spec__display {
1156
- font-family: var(--font-display);
1157
- font-size: var(--text-2xl);
1158
- font-weight: var(--display-weight, 400);
1159
- font-style: var(--display-style, normal);
1160
- line-height: var(--lh-tight);
1161
- letter-spacing: var(--tracking-display);
1162
- font-optical-sizing: auto;
1163
- }
1164
-
1165
- .type-spec__body {
1166
- font-family: var(--font-serif);
1167
- font-size: var(--text-md);
1168
- line-height: var(--lh-normal);
1169
- color: var(--color-ink-2);
1170
- max-width: 32ch;
1171
- }
1172
-
1173
- [data-theme="brutal"] .type-spec__body,
1174
- [data-theme="manifesto"] .type-spec__body,
1175
- [data-theme="terminal"] .type-spec__body,
1176
- [data-theme="sport"] .type-spec__body,
1177
- [data-theme="almanac"] .type-spec__body {
1178
- font-style: normal;
1179
- font-family: var(--font-body);
1180
- }
1181
-
1182
- /* — Easing curve SVG ——————————————————————————————— */
1183
- .curve {
1184
- width: 100%;
1185
- height: 4.5rem;
1186
- color: var(--color-ink);
1187
- }
1188
-
1189
- /* — Without / With panels (parity demo) —————————————————
1190
- Both panels render the same eyebrow + H1 + sub + CTA structure.
1191
- The `data-variant` attribute drives every visual difference. */
1192
- .vs__panel {
1193
- display: grid;
1194
- gap: 0.75rem;
1195
- padding: var(--space-xl);
1196
- min-height: 16rem;
1197
- background: var(--color-paper);
1198
- border: var(--rule-hair) solid var(--color-rule-2);
1199
- align-content: start;
1200
- }
1201
-
1202
- .vs__panel-eyebrow {
1203
- font-size: 0.75rem;
1204
- margin: 0;
1205
- }
1206
-
1207
- .vs__panel-title {
1208
- margin: 0;
1209
- font-size: 2rem;
1210
- line-height: 1.05;
1211
- }
1212
-
1213
- .vs__panel-sub {
1214
- margin: 0;
1215
- font-size: 0.875rem;
1216
- line-height: 1.45;
1217
- }
1218
-
1219
- .vs__panel-cta {
1220
- display: inline-flex;
1221
- align-items: center;
1222
- justify-self: start;
1223
- margin-top: 0.5rem;
1224
- font-size: 0.875rem;
1225
- }
1226
-
1227
- /* — "Without Hallmark" — the slop stack —————————————————
1228
- The bg uses theme paper so the panel integrates on dark themes
1229
- (otherwise a pure-white card looks like a glitch on Manifesto /
1230
- Midnight / Terminal). The AI-slop tells are still carried by the
1231
- centred layout, Inter font, gradient title, and gradient pill. */
1232
- .vs__panel[data-variant="slop"] {
1233
- text-align: center;
1234
- align-content: center;
1235
- justify-items: center;
1236
- background: var(--color-paper);
1237
- border-color: var(--color-rule);
1238
- font-family: "Inter", system-ui, sans-serif;
1239
- }
1240
-
1241
- .vs__panel[data-variant="slop"] .vs__panel-eyebrow {
1242
- color: var(--color-muted);
1243
- font-family: inherit;
1244
- font-weight: 500;
1245
- letter-spacing: 0;
1246
- text-transform: none;
1247
- }
1248
-
1249
- .vs__panel[data-variant="slop"] .vs__panel-title {
1250
- font-family: inherit;
1251
- font-weight: 800;
1252
- letter-spacing: -0.025em;
1253
- background: linear-gradient(95deg, #8b5dff 0%, #c14de0 50%, #e04db4 100%);
1254
- -webkit-background-clip: text;
1255
- background-clip: text;
1256
- color: transparent;
1257
- max-width: 14ch;
1258
- }
1259
-
1260
- .vs__panel[data-variant="slop"] .vs__panel-sub {
1261
- color: var(--color-muted);
1262
- font-family: inherit;
1263
- max-width: 28ch;
1264
- }
1265
-
1266
- .vs__panel[data-variant="slop"] .vs__panel-cta {
1267
- justify-self: center;
1268
- padding: 0.55rem 1.4rem;
1269
- background: linear-gradient(95deg, #6366f1, #a855f7);
1270
- color: #fff;
1271
- border-radius: 9999px;
1272
- font-weight: 600;
1273
- letter-spacing: 0;
1274
- }
1275
-
1276
- /* — "With Hallmark" — the considered version ————————————— */
1277
- .vs__panel[data-variant="hallmark"] {
1278
- text-align: left;
1279
- background: var(--color-paper);
1280
- border-color: var(--color-rule-2);
1281
- border-left: 2px solid var(--color-accent);
1282
- padding-left: calc(var(--space-xl) - 2px);
1283
- }
1284
-
1285
- .vs__panel[data-variant="hallmark"] .vs__panel-eyebrow {
1286
- display: inline-flex;
1287
- align-items: center;
1288
- gap: 0.55em;
1289
- color: var(--color-muted);
1290
- font-family: var(--font-label);
1291
- font-size: var(--text-xs);
1292
- letter-spacing: var(--tracking-label);
1293
- text-transform: uppercase;
1294
- font-weight: 400;
1295
- }
1296
-
1297
- .vs__panel[data-variant="hallmark"] .vs__panel-mark {
1298
- width: 6px;
1299
- height: 6px;
1300
- background: var(--color-accent);
1301
- display: inline-block;
1302
- }
1303
-
1304
- .vs__panel[data-variant="hallmark"] .vs__panel-title {
1305
- font-family: var(--font-display);
1306
- font-weight: var(--display-weight, 400);
1307
- font-style: var(--display-style, normal);
1308
- letter-spacing: -0.02em;
1309
- color: var(--color-ink);
1310
- max-width: 14ch;
1311
- font-optical-sizing: auto;
1312
- }
1313
-
1314
- .vs__panel[data-variant="hallmark"] .vs__panel-title em {
1315
- font-family: var(--font-serif);
1316
- font-style: italic;
1317
- font-weight: 400;
1318
- color: var(--color-ink);
1319
- }
1320
-
1321
- .vs__panel[data-variant="hallmark"] .vs__panel-sub {
1322
- font-family: var(--font-body);
1323
- color: var(--color-ink-2);
1324
- max-width: 32ch;
1325
- }
1326
-
1327
- .vs__panel[data-variant="hallmark"] .vs__panel-cta {
1328
- margin-top: var(--space-sm);
1329
- padding: 0.55rem 1.1rem;
1330
- background: var(--color-ink);
1331
- color: var(--color-paper);
1332
- font-family: var(--font-label);
1333
- font-size: var(--text-xs);
1334
- letter-spacing: var(--tracking-label);
1335
- text-transform: uppercase;
1336
- border-radius: 0;
1337
- }
1338
-
1339
- /* Dashboard W/W variant — slop = glass widget, hallmark = considered. */
1340
- .vs__panel--dash {
1341
- min-height: 18rem;
1342
- }
1343
-
1344
- /* Slop dashboard — glassmorphic, gradient, centered, badged. */
1345
- .vs__panel--dash[data-variant="slop"] {
1346
- position: relative;
1347
- background:
1348
- linear-gradient(135deg,
1349
- color-mix(in srgb, #6366f1 14%, transparent) 0%,
1350
- color-mix(in srgb, #c14de0 14%, transparent) 60%,
1351
- color-mix(in srgb, #f97316 12%, transparent) 100%),
1352
- rgba(255, 255, 255, 0.65);
1353
- backdrop-filter: blur(6px);
1354
- -webkit-backdrop-filter: blur(6px);
1355
- border-color: rgba(0, 0, 0, 0.06);
1356
- border-radius: 16px;
1357
- text-align: center;
1358
- align-content: center;
1359
- justify-items: center;
1360
- box-shadow: 0 12px 32px -16px rgba(99, 102, 241, 0.35);
1361
- font-family: "Inter", system-ui, sans-serif;
1362
- }
1363
-
1364
- .vs__panel--dash[data-variant="slop"] .vs__panel-stat {
1365
- margin: 0;
1366
- font-family: inherit;
1367
- font-weight: 800;
1368
- font-size: clamp(2.75rem, 4vw + 1rem, 3.75rem);
1369
- letter-spacing: -0.03em;
1370
- line-height: 1;
1371
- background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
1372
- -webkit-background-clip: text;
1373
- background-clip: text;
1374
- color: transparent;
1375
- }
1376
-
1377
- .vs__panel--dash[data-variant="slop"] .vs__panel-stat-label {
1378
- margin: 0.4rem 0 0;
1379
- font-family: inherit;
1380
- font-size: 0.875rem;
1381
- color: #6b6b76;
1382
- }
1383
-
1384
- .vs__panel--dash[data-variant="slop"] .vs__panel-badge {
1385
- display: inline-flex;
1386
- align-items: center;
1387
- margin: 0.6rem 0 0.4rem;
1388
- padding: 0.18rem 0.65rem;
1389
- font-family: inherit;
1390
- font-size: 0.75rem;
1391
- font-weight: 600;
1392
- color: #16a34a;
1393
- background: rgba(34, 197, 94, 0.12);
1394
- border-radius: 999px;
1395
- box-shadow: 0 0 12px -2px rgba(34, 197, 94, 0.5);
1396
- }
1397
-
1398
- /* Hallmark dashboard — hairline rule, mono numerals, asymmetric. */
1399
- .vs__panel--dash[data-variant="hallmark"] {
1400
- text-align: left;
1401
- padding-top: var(--space-2xl);
1402
- border-top: 2px solid var(--color-ink);
1403
- border-left: var(--rule-hair) solid var(--color-rule-2);
1404
- border-right: var(--rule-hair) solid var(--color-rule-2);
1405
- border-bottom: var(--rule-hair) solid var(--color-rule-2);
1406
- background: var(--color-paper);
1407
- border-radius: 0;
1408
- }
1409
-
1410
- .vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-line {
1411
- display: flex;
1412
- align-items: baseline;
1413
- gap: var(--space-md);
1414
- margin: 0;
1415
- }
1416
-
1417
- .vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-num {
1418
- font-family: var(--font-mono);
1419
- font-feature-settings: "tnum";
1420
- font-variant-numeric: tabular-nums;
1421
- font-size: clamp(2.75rem, 4vw + 1rem, 3.75rem);
1422
- font-weight: 500;
1423
- letter-spacing: -0.03em;
1424
- color: var(--color-ink);
1425
- line-height: 1;
1426
- }
1427
-
1428
- .vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-delta {
1429
- display: inline-flex;
1430
- align-items: center;
1431
- gap: 0.4em;
1432
- font-family: var(--font-label);
1433
- font-size: var(--text-xs);
1434
- letter-spacing: var(--tracking-label);
1435
- text-transform: uppercase;
1436
- color: var(--color-muted);
1437
- }
1438
-
1439
- .vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-dot {
1440
- display: inline-block;
1441
- width: 6px;
1442
- height: 6px;
1443
- background: var(--color-accent);
1444
- border-radius: 50%;
1445
- }
1446
-
1447
- .vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-label {
1448
- margin: var(--space-md) 0 0;
1449
- font-family: var(--font-body);
1450
- font-size: 0.9375rem;
1451
- line-height: 1.5;
1452
- color: var(--color-ink-2);
1453
- max-width: 32ch;
1454
- }
1455
-
1456
- /* Pricing W/W variant — slop = popular badge + glow + emoji,
1457
- hallmark = editorial tier card with hairline rule and mono price. */
1458
- .vs__panel--pricing { min-height: 22rem; }
1459
-
1460
- .vs__panel--pricing[data-variant="slop"] {
1461
- position: relative;
1462
- text-align: center;
1463
- align-content: start;
1464
- justify-items: center;
1465
- padding-top: 2.4rem;
1466
- background:
1467
- linear-gradient(135deg,
1468
- color-mix(in srgb, #6366f1 8%, transparent) 0%,
1469
- color-mix(in srgb, #ec4899 8%, transparent) 100%),
1470
- rgba(255, 255, 255, 0.85);
1471
- border: 1px solid rgba(99, 102, 241, 0.25);
1472
- border-radius: 18px;
1473
- box-shadow: 0 16px 36px -16px rgba(99, 102, 241, 0.4);
1474
- font-family: "Inter", system-ui, sans-serif;
1475
- }
1476
-
1477
- .vs__panel--pricing[data-variant="slop"] .vs__panel-pop {
1478
- position: absolute;
1479
- top: -0.7rem;
1480
- left: 50%;
1481
- transform: translateX(-50%);
1482
- padding: 0.25rem 0.85rem;
1483
- background: linear-gradient(95deg, #6366f1, #a855f7, #ec4899);
1484
- color: #fff;
1485
- border-radius: 999px;
1486
- font-family: inherit;
1487
- font-size: 0.7rem;
1488
- font-weight: 600;
1489
- letter-spacing: 0.04em;
1490
- text-transform: uppercase;
1491
- box-shadow: 0 4px 12px -2px rgba(168, 85, 247, 0.5);
1492
- white-space: nowrap;
1493
- }
1494
-
1495
- .vs__panel--pricing[data-variant="slop"] .vs__panel-eyebrow {
1496
- font-family: inherit;
1497
- font-weight: 600;
1498
- font-size: 0.75rem;
1499
- letter-spacing: 0.08em;
1500
- text-transform: uppercase;
1501
- color: #6366f1;
1502
- margin: 0;
1503
- }
1504
-
1505
- .vs__panel--pricing[data-variant="slop"] .vs__panel-price {
1506
- margin: 0.4rem 0;
1507
- font-family: inherit;
1508
- font-weight: 800;
1509
- font-size: 2.5rem;
1510
- letter-spacing: -0.025em;
1511
- line-height: 1;
1512
- }
1513
-
1514
- .vs__panel--pricing[data-variant="slop"] .vs__panel-price-num {
1515
- background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
1516
- -webkit-background-clip: text;
1517
- background-clip: text;
1518
- color: transparent;
1519
- }
1520
-
1521
- .vs__panel--pricing[data-variant="slop"] .vs__panel-price-unit {
1522
- font-size: 0.875rem;
1523
- font-weight: 500;
1524
- color: #6b6b76;
1525
- letter-spacing: 0;
1526
- margin-inline-start: 0.25em;
1527
- }
1528
-
1529
- .vs__panel--pricing[data-variant="slop"] .vs__panel-sub {
1530
- margin: 0;
1531
- font-family: inherit;
1532
- font-size: 0.8125rem;
1533
- color: #6b6b76;
1534
- max-width: 28ch;
1535
- }
1536
-
1537
- .vs__panel--pricing[data-variant="slop"] .vs__panel-bullets {
1538
- list-style: none;
1539
- margin: 0.6rem 0 0.3rem;
1540
- padding: 0;
1541
- display: grid;
1542
- gap: 0.4rem;
1543
- font-family: inherit;
1544
- font-size: 0.8125rem;
1545
- color: #2a2a32;
1546
- text-align: left;
1547
- }
1548
-
1549
- /* Hallmark pricing — editorial tier card. */
1550
- .vs__panel--pricing[data-variant="hallmark"] {
1551
- text-align: left;
1552
- align-content: start;
1553
- }
1554
-
1555
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-tier {
1556
- margin: 0;
1557
- font-family: var(--font-display);
1558
- font-weight: var(--display-weight, 500);
1559
- font-style: var(--display-style, normal);
1560
- font-size: var(--text-xl);
1561
- letter-spacing: var(--tracking-tight);
1562
- color: var(--color-ink);
1563
- padding-block-end: var(--space-sm);
1564
- border-block-end: var(--rule-hair) solid var(--color-rule-2);
1565
- font-optical-sizing: auto;
1566
- }
1567
-
1568
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-price {
1569
- display: flex;
1570
- align-items: baseline;
1571
- gap: 0.4rem;
1572
- margin: var(--space-md) 0 0;
1573
- }
1574
-
1575
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-price-num {
1576
- font-family: var(--font-mono);
1577
- font-feature-settings: "tnum";
1578
- font-variant-numeric: tabular-nums;
1579
- font-size: clamp(2.25rem, 3vw + 1rem, 3rem);
1580
- font-weight: 500;
1581
- letter-spacing: -0.025em;
1582
- color: var(--color-ink);
1583
- line-height: 1;
1584
- }
1585
-
1586
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-price-unit {
1587
- font-family: var(--font-mono);
1588
- font-size: 0.875rem;
1589
- color: var(--color-muted);
1590
- letter-spacing: 0;
1591
- }
1592
-
1593
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-sub {
1594
- margin: var(--space-sm) 0 0;
1595
- max-width: 30ch;
1596
- }
1597
-
1598
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets {
1599
- list-style: none;
1600
- margin: var(--space-md) 0 0;
1601
- padding: 0;
1602
- display: grid;
1603
- gap: 0;
1604
- font-family: var(--font-body);
1605
- font-size: 0.9375rem;
1606
- color: var(--color-ink-2);
1607
- }
1608
-
1609
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets li {
1610
- padding-block: var(--space-sm);
1611
- border-block-end: var(--rule-hair) solid var(--color-rule);
1612
- }
1613
-
1614
- .vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets li:last-child {
1615
- border-block-end: 0;
1616
- }
1617
-
1618
- /* Personal-site W/W variant — slop = avatar + gradient name + pills,
1619
- hallmark = letter format with italic name and text links. */
1620
- .vs__panel--personal { min-height: 22rem; }
1621
-
1622
- .vs__panel--personal[data-variant="slop"] {
1623
- text-align: center;
1624
- align-content: center;
1625
- justify-items: center;
1626
- background:
1627
- linear-gradient(160deg,
1628
- color-mix(in srgb, #ec4899 6%, transparent) 0%,
1629
- color-mix(in srgb, #6366f1 8%, transparent) 100%),
1630
- rgba(255, 255, 255, 0.92);
1631
- border-color: rgba(0, 0, 0, 0.06);
1632
- border-radius: 16px;
1633
- font-family: "Inter", system-ui, sans-serif;
1634
- }
1635
-
1636
- .vs__panel--personal[data-variant="slop"] .vs__panel-avatar {
1637
- display: grid;
1638
- place-items: center;
1639
- width: 4.5rem;
1640
- height: 4.5rem;
1641
- border-radius: 50%;
1642
- background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
1643
- color: #fff;
1644
- font-family: inherit;
1645
- font-weight: 700;
1646
- font-size: 1.75rem;
1647
- letter-spacing: -0.02em;
1648
- box-shadow: 0 8px 22px -10px rgba(168, 85, 247, 0.5);
1649
- margin-bottom: 0.6rem;
1650
- }
1651
-
1652
- .vs__panel--personal[data-variant="slop"] .vs__panel-name {
1653
- margin: 0;
1654
- font-family: inherit;
1655
- font-weight: 800;
1656
- font-size: 1.875rem;
1657
- letter-spacing: -0.025em;
1658
- background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
1659
- -webkit-background-clip: text;
1660
- background-clip: text;
1661
- color: transparent;
1662
- }
1663
-
1664
- .vs__panel--personal[data-variant="slop"] .vs__panel-sub {
1665
- margin: 0.4rem 0 0.9rem;
1666
- font-family: inherit;
1667
- font-size: 0.875rem;
1668
- color: #6b6b76;
1669
- max-width: 28ch;
1670
- }
1671
-
1672
- .vs__panel--personal[data-variant="slop"] .vs__panel-pills {
1673
- display: flex;
1674
- gap: 0.4rem;
1675
- flex-wrap: wrap;
1676
- justify-content: center;
1677
- }
1678
-
1679
- .vs__panel--personal[data-variant="slop"] .vs__panel-pill {
1680
- padding: 0.4rem 0.95rem;
1681
- background: rgba(255, 255, 255, 0.9);
1682
- border: 1px solid rgba(99, 102, 241, 0.25);
1683
- border-radius: 999px;
1684
- font-family: inherit;
1685
- font-size: 0.8125rem;
1686
- font-weight: 500;
1687
- color: #6366f1;
1688
- box-shadow: 0 2px 6px -2px rgba(99, 102, 241, 0.2);
1689
- }
1690
-
1691
- /* Hallmark personal — letter format. */
1692
- .vs__panel--personal[data-variant="hallmark"] {
1693
- text-align: left;
1694
- align-content: start;
1695
- }
1696
-
1697
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-name {
1698
- margin: var(--space-sm) 0 0;
1699
- font-family: var(--font-display);
1700
- font-weight: var(--display-weight, 500);
1701
- font-style: italic;
1702
- font-size: clamp(2rem, 3vw + 1rem, 2.875rem);
1703
- line-height: 1.05;
1704
- letter-spacing: -0.02em;
1705
- color: var(--color-ink);
1706
- font-optical-sizing: auto;
1707
- }
1708
-
1709
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-name em {
1710
- font-family: var(--font-display);
1711
- font-style: normal;
1712
- font-weight: var(--display-weight, 500);
1713
- }
1714
-
1715
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-bio {
1716
- margin: var(--space-md) 0 0;
1717
- font-family: var(--font-serif);
1718
- font-size: 1rem;
1719
- line-height: var(--lh-relaxed);
1720
- color: var(--color-ink-2);
1721
- max-width: 38ch;
1722
- }
1723
-
1724
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-links {
1725
- margin: var(--space-lg) 0 0;
1726
- font-family: var(--font-label);
1727
- font-size: var(--text-xs);
1728
- letter-spacing: var(--tracking-label);
1729
- text-transform: uppercase;
1730
- color: var(--color-muted);
1731
- display: flex;
1732
- flex-wrap: wrap;
1733
- gap: 0.5rem;
1734
- align-items: center;
1735
- }
1736
-
1737
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-linkitem {
1738
- color: var(--color-ink);
1739
- text-decoration: none;
1740
- background-image: linear-gradient(var(--color-accent), var(--color-accent));
1741
- background-repeat: no-repeat;
1742
- background-position: 0 100%;
1743
- background-size: 100% 1px;
1744
- transition: background-size var(--dur-short) var(--ease-out);
1745
- }
1746
-
1747
- .vs__panel--personal[data-variant="hallmark"] .vs__panel-linkitem:hover {
1748
- background-size: 100% 2px;
1749
- }
1750
-
1751
- /* — Install pane internals ——————————————————————————— */
1752
-
1753
- /* Row label — "I · Run" */
1754
- .install-pane__label {
1755
- margin: 0;
1756
- font-family: var(--font-label);
1757
- font-size: var(--text-xs);
1758
- letter-spacing: var(--tracking-label);
1759
- text-transform: uppercase;
1760
- color: var(--color-muted);
1761
- display: flex;
1762
- align-items: baseline;
1763
- gap: 0.5rem;
1764
- }
1765
-
1766
- .install-pane__step {
1767
- font-family: var(--font-display);
1768
- font-style: var(--display-style, normal);
1769
- font-weight: var(--display-weight, 500);
1770
- font-size: var(--text-md);
1771
- letter-spacing: 0.04em;
1772
- color: var(--color-ink);
1773
- font-optical-sizing: auto;
1774
- }
1775
-
1776
- [data-theme="riso"] .install-pane__step,
1777
- [data-theme="brutal"] .install-pane__step,
1778
- [data-theme="manifesto"] .install-pane__step,
1779
- [data-theme="sport"] .install-pane__step {
1780
- text-transform: uppercase;
1781
- }
1782
-
1783
- [data-theme="riso"] .install-pane__step { text-transform: lowercase; }
1784
-
1785
- /* Row I — the install command, presented prominently */
1786
- .install-pane__cmd {
1787
- display: flex;
1788
- align-items: center;
1789
- gap: var(--space-md);
1790
- padding: var(--space-md) var(--space-lg);
1791
- background: var(--color-paper-2);
1792
- border: var(--rule-hair) solid var(--color-rule);
1793
- border-radius: var(--radius-input, 0);
1794
- font-family: var(--font-mono);
1795
- font-size: clamp(1rem, 1.6vw, 1.25rem);
1796
- color: var(--color-ink);
1797
- line-height: 1.5;
1798
- position: relative;
1799
- min-height: 56px;
1800
- transition: border-color var(--dur-micro) var(--ease-out);
1801
- }
1802
-
1803
- @media (hover: hover) and (pointer: fine) {
1804
- .install-pane__cmd:hover { border-color: var(--color-ink); }
1805
- }
1806
-
1807
- .install-pane__prompt {
1808
- color: var(--color-accent);
1809
- user-select: none;
1810
- flex-shrink: 0;
1811
- font-weight: 500;
1812
- }
1813
-
1814
- .install-pane__cmd-text {
1815
- flex: 1;
1816
- font-weight: 400;
1817
- letter-spacing: 0;
1818
- user-select: all;
1819
- cursor: text;
1820
- }
1821
-
1822
- .install-pane__copy {
1823
- flex-shrink: 0;
1824
- appearance: none;
1825
- display: inline-flex;
1826
- align-items: center;
1827
- justify-content: center;
1828
- min-height: 36px;
1829
- padding: 0.4rem 0.85rem;
1830
- background: var(--color-paper);
1831
- border: var(--rule-hair) solid var(--color-rule);
1832
- font-family: var(--font-label);
1833
- font-size: 0.6875rem;
1834
- letter-spacing: 0.14em;
1835
- text-transform: uppercase;
1836
- color: var(--color-muted);
1837
- cursor: pointer;
1838
- transition: color var(--dur-short) var(--ease-out),
1839
- border-color var(--dur-short) var(--ease-out),
1840
- background-color var(--dur-short) var(--ease-out);
1841
- }
1842
-
1843
- .install-pane__copy:hover {
1844
- color: var(--color-ink);
1845
- border-color: var(--color-ink);
1846
- }
1847
-
1848
- .install-pane__copy:focus-visible {
1849
- outline: 2px solid var(--color-focus);
1850
- outline-offset: 2px;
1851
- }
1852
-
1853
- .install-pane__copy[data-state="copied"] {
1854
- color: var(--color-paper);
1855
- background: var(--color-accent);
1856
- border-color: var(--color-accent);
1857
- }
1858
-
1859
- .install-pane__copy-default { display: inline; }
1860
- .install-pane__copy-done { display: none; }
1861
-
1862
- .install-pane__copy[data-state="copied"] .install-pane__copy-default { display: none; }
1863
- .install-pane__copy[data-state="copied"] .install-pane__copy-done { display: inline; }
1864
-
1865
- [data-theme="terminal"] .install-pane__cmd {
1866
- background: var(--color-paper-3);
1867
- border-color: var(--color-rule-2);
1868
- }
1869
-
1870
- [data-theme="manifesto"] .install-pane__cmd {
1871
- background: var(--color-ink);
1872
- color: var(--color-paper);
1873
- border-color: var(--color-ink);
1874
- }
1875
- [data-theme="manifesto"] .install-pane__prompt { color: var(--color-accent); }
1876
- [data-theme="manifesto"] .install-pane__copy {
1877
- background: var(--color-accent);
1878
- color: var(--color-paper);
1879
- border-color: var(--color-accent);
1880
- font-weight: 500;
1881
- }
1882
-
1883
- /* Row II — harness list */
1884
- .install-pane__harnesses {
1885
- list-style: none;
1886
- margin: 0;
1887
- padding: 0;
1888
- display: grid;
1889
- gap: var(--space-md);
1890
- }
1891
-
1892
- .harness {
1893
- display: grid;
1894
- grid-template-columns: 11rem 1fr auto;
1895
- gap: var(--space-md) var(--space-lg);
1896
- align-items: baseline;
1897
- padding-block: var(--space-sm);
1898
- border-block-end: var(--rule-hair) solid var(--color-rule);
1899
- }
1900
-
1901
- .harness:last-child { border-block-end: 0; }
1902
-
1903
- @media (max-width: 38rem) {
1904
- .harness {
1905
- grid-template-columns: 1fr;
1906
- gap: 0.25rem;
1907
- padding-block: var(--space-md);
1908
- }
1909
- }
1910
-
1911
- .harness__name {
1912
- font-family: var(--font-display);
1913
- font-weight: var(--display-weight, 500);
1914
- font-style: var(--display-style, normal);
1915
- font-size: var(--text-md);
1916
- letter-spacing: var(--tracking-tight);
1917
- color: var(--color-ink);
1918
- font-optical-sizing: auto;
1919
- }
1920
-
1921
- [data-theme="riso"] .harness__name,
1922
- [data-theme="brutal"] .harness__name,
1923
- [data-theme="manifesto"] .harness__name,
1924
- [data-theme="sport"] .harness__name { text-transform: uppercase; }
1925
-
1926
- [data-theme="riso"] .harness__name { text-transform: lowercase; }
1927
-
1928
- .harness__path {
1929
- font-family: var(--font-mono);
1930
- font-size: var(--text-sm);
1931
- color: var(--color-ink-2);
1932
- background: transparent;
1933
- border: 0;
1934
- padding: 0;
1935
- letter-spacing: 0;
1936
- white-space: nowrap;
1937
- overflow: hidden;
1938
- text-overflow: ellipsis;
1939
- }
1940
-
1941
- .harness__status {
1942
- font-family: var(--font-label);
1943
- font-size: var(--text-xs);
1944
- letter-spacing: var(--tracking-label);
1945
- text-transform: uppercase;
1946
- color: var(--color-muted);
1947
- display: inline-flex;
1948
- align-items: center;
1949
- gap: 0.4em;
1950
- }
1951
-
1952
- .harness__status--ok { color: var(--color-accent); }
1953
-
1954
- .harness__status--ok::before {
1955
- content: "";
1956
- display: inline-block;
1957
- width: 6px;
1958
- height: 6px;
1959
- background: var(--color-accent);
1960
- border-radius: 50%;
1961
- }
1962
-
1963
- /* Row III — the next step */
1964
- .install-pane__next {
1965
- margin: 0;
1966
- font-family: var(--font-serif);
1967
- font-size: var(--text-md);
1968
- line-height: var(--lh-normal);
1969
- color: var(--color-ink-2);
1970
- max-width: 56ch;
1971
- }
1972
-
1973
- .install-pane__next code {
1974
- font-family: var(--font-mono);
1975
- font-style: normal;
1976
- font-size: 0.875em;
1977
- color: var(--color-ink);
1978
- background: var(--color-paper-2);
1979
- padding: 0.05em 0.35em;
1980
- border: var(--rule-hair) solid var(--color-rule);
1981
- }
1982
-
1983
- [data-theme="brutal"] .install-pane__next,
1984
- [data-theme="manifesto"] .install-pane__next,
1985
- [data-theme="terminal"] .install-pane__next,
1986
- [data-theme="sport"] .install-pane__next,
1987
- [data-theme="almanac"] .install-pane__next {
1988
- font-family: var(--font-body);
1989
- font-style: normal;
1990
- }
1991
-
1992
- [data-theme="manifesto"] .install-pane__next { text-transform: uppercase; font-weight: 500; }
1993
-
1994
- /* — Per-theme install-pane overrides ———————————————————— */
1995
- [data-theme="terminal"] .install-pane {
1996
- background: var(--color-paper-2);
1997
- }
1998
-
1999
- [data-theme="brutal"] .install-pane,
2000
- [data-theme="manifesto"] .install-pane {
2001
- border-width: 2px;
2002
- }
2003
-
2004
- [data-theme="atelier"] .install-pane,
2005
- [data-theme="salon"] .install-pane {
2006
- border: 0;
2007
- background: transparent;
2008
- box-shadow: none;
2009
- }
2010
-
2011
- [data-theme="atelier"] .install-pane__row,
2012
- [data-theme="salon"] .install-pane__row {
2013
- padding-inline: 0;
2014
- }
2015
-
2016
- [data-theme="atelier"] .install-pane__row + .install-pane__row,
2017
- [data-theme="salon"] .install-pane__row + .install-pane__row {
2018
- border-block-start: var(--rule-hair) solid var(--color-rule);
2019
- }
2020
-
2021
- /* — Easter egg overlay ——————————————————————————————————
2022
- Hidden by default. Revealed when the user spams T faster than the
2023
- site can keep up — see js/main.js. Pure white full-screen, system
2024
- mono font, dark text — deliberately decoupled from the active
2025
- theme so it reads as the page itself stepping in. Auto-dismisses
2026
- after ~4.2s; while it's open, all keystrokes are swallowed. */
2027
- .easter {
2028
- position: fixed;
2029
- inset: 0;
2030
- z-index: 9999;
2031
- display: grid;
2032
- place-items: center;
2033
- padding: var(--space-xl);
2034
- background: #fff;
2035
- color: #111;
2036
- font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
2037
- font-size: 0.95rem;
2038
- line-height: 1.65;
2039
- /* Smoother arrival — fade + tiny scale-in. Feels like the page
2040
- gently steps aside rather than a hard cut. */
2041
- animation: easter-arrive 420ms cubic-bezier(0.16, 1, 0.3, 1) both;
2042
- }
2043
-
2044
- .easter[hidden] { display: none; }
2045
-
2046
- .easter[data-state="closing"] {
2047
- animation: easter-leave 360ms cubic-bezier(0.7, 0, 0.84, 0) forwards;
2048
- }
2049
-
2050
- @keyframes easter-arrive {
2051
- from {
2052
- opacity: 0;
2053
- backdrop-filter: blur(0);
2054
- -webkit-backdrop-filter: blur(0);
2055
- transform: scale(1.015);
2056
- }
2057
- to {
2058
- opacity: 1;
2059
- backdrop-filter: blur(0);
2060
- -webkit-backdrop-filter: blur(0);
2061
- transform: scale(1);
2062
- }
2063
- }
2064
-
2065
- @keyframes easter-leave {
2066
- from { opacity: 1; transform: scale(1); }
2067
- to { opacity: 0; transform: scale(0.985); }
2068
- }
2069
-
2070
- /* Reduced motion — opacity only, no scale. */
2071
- @media (prefers-reduced-motion: reduce) {
2072
- .easter {
2073
- animation: easter-fade-in 200ms ease-out both;
2074
- }
2075
- .easter[data-state="closing"] {
2076
- animation: easter-fade-out 200ms ease-in forwards;
2077
- }
2078
- @keyframes easter-fade-in { from { opacity: 0; } to { opacity: 1; } }
2079
- @keyframes easter-fade-out { from { opacity: 1; } to { opacity: 0; } }
2080
- }
2081
-
2082
- /* Page-shrink under the easter overlay — runs on the <body> while
2083
- the easter is open. The page recedes slightly, making the easter
2084
- feel like a brief teleport. */
2085
- body.easter-open > main,
2086
- body.easter-open > header,
2087
- body.easter-open > footer {
2088
- transform: scale(0.985);
2089
- filter: blur(2px);
2090
- transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1),
2091
- filter 420ms cubic-bezier(0.16, 1, 0.3, 1);
2092
- transform-origin: center center;
2093
- }
2094
-
2095
- body:not(.easter-open) > main,
2096
- body:not(.easter-open) > header,
2097
- body:not(.easter-open) > footer {
2098
- transition: transform 360ms cubic-bezier(0.7, 0, 0.84, 0),
2099
- filter 360ms cubic-bezier(0.7, 0, 0.84, 0);
2100
- }
2101
-
2102
- @media (prefers-reduced-motion: reduce) {
2103
- body.easter-open > main,
2104
- body.easter-open > header,
2105
- body.easter-open > footer {
2106
- transform: none;
2107
- filter: none;
2108
- }
2109
- }
2110
-
2111
- .easter__panel {
2112
- display: grid;
2113
- gap: 1.4rem;
2114
- max-width: 38rem;
2115
- width: 100%;
2116
- }
2117
-
2118
- .easter__lines {
2119
- list-style: none;
2120
- margin: 0;
2121
- padding: 0;
2122
- display: grid;
2123
- gap: 0.45rem;
2124
- }
2125
-
2126
- .easter__line {
2127
- margin: 0;
2128
- opacity: 0;
2129
- transform: translateY(6px);
2130
- animation: easter-line 360ms ease-out forwards;
2131
- }
2132
-
2133
- .easter__line:nth-child(1) { animation-delay: 180ms; }
2134
- .easter__line:nth-child(2) { animation-delay: 380ms; }
2135
- .easter__line:nth-child(3) { animation-delay: 700ms; }
2136
-
2137
- @keyframes easter-line {
2138
- to { opacity: 1; transform: none; }
2139
- }
2140
-
2141
- .easter__line--cmd {
2142
- font-size: 1rem;
2143
- font-weight: 500;
2144
- color: #111;
2145
- margin-block-end: 0.6rem;
2146
- letter-spacing: 0;
2147
- }
2148
-
2149
- .easter__prompt,
2150
- .easter__arrow {
2151
- color: #b0b0b0;
2152
- user-select: none;
2153
- margin-inline-end: 0.5rem;
2154
- }
2155
-
2156
- .easter__num {
2157
- color: #111;
2158
- font-weight: 600;
2159
- font-feature-settings: "tnum";
2160
- font-variant-numeric: tabular-nums;
2161
- }
2162
-
2163
- .easter__line--punchline {
2164
- margin-block-start: 0.8rem;
2165
- font-size: clamp(1.75rem, 4.5vw, 2.5rem);
2166
- line-height: 1.1;
2167
- letter-spacing: -0.02em;
2168
- font-weight: 500;
2169
- color: #111;
2170
- }
2171
-
2172
- .easter__line--punchline .easter__arrow {
2173
- font-size: 0.9rem;
2174
- vertical-align: 0.25em;
2175
- font-weight: 400;
2176
- }
2177
-
2178
- .easter__cursor {
2179
- display: inline-block;
2180
- width: 0.42em;
2181
- height: 0.95em;
2182
- background: #111;
2183
- margin-inline-start: 0.18em;
2184
- vertical-align: -0.08em;
2185
- opacity: 0;
2186
- animation: easter-blink 1.05s steps(2) infinite;
2187
- animation-delay: 1.15s;
2188
- }
2189
-
2190
- @keyframes easter-blink {
2191
- 0%, 49% { opacity: 1; }
2192
- 50%, 100% { opacity: 0; }
2193
- }
2194
-
2195
- .easter__hint {
2196
- margin: 0;
2197
- padding-block-start: 1.2rem;
2198
- border-block-start: 1px solid #e5e5e5;
2199
- font-size: 0.7rem;
2200
- letter-spacing: 0.14em;
2201
- text-transform: uppercase;
2202
- color: #888;
2203
- display: flex;
2204
- flex-wrap: wrap;
2205
- gap: 0.6rem;
2206
- align-items: center;
2207
- }
2208
-
2209
- @media (prefers-reduced-motion: reduce) {
2210
- .easter,
2211
- .easter[data-state="closing"],
2212
- .easter__line { animation: none; }
2213
- .easter__line { opacity: 1; transform: none; }
2214
- .easter__cursor { animation: none; opacity: 1; }
2215
- }
2216
-
2217
- /* — Reveals (disabled) ——————————————————————————————————
2218
- Scroll-in animation removed by product decision — landing reads
2219
- cleaner without staggered fades. Class kept so JS + markup stay
2220
- stable; element renders in its final state with no transform/fade. */
2221
- .reveal,
2222
- .reveal.is-in {
2223
- opacity: 1;
2224
- transform: none;
2225
- animation: none;
2226
- }
2227
-
2228
- @media (prefers-reduced-motion: reduce) {
2229
- .reveal { transform: none; animation-duration: 150ms !important; }
2230
- @keyframes reveal { to { opacity: 1; } }
2231
- *, *::before, *::after {
2232
- animation-duration: 150ms !important;
2233
- transition-duration: 150ms !important;
2234
- }
2235
- }
2236
-
2237
- /* — View transitions ————————————————————————————————— */
2238
- ::view-transition-old(root),
2239
- ::view-transition-new(root) {
2240
- animation-duration: 280ms;
2241
- animation-timing-function: var(--ease-out);
2242
- }
2243
-
2244
- /* ───────────── STUDIO — Fraunces italic display ───────────── */
2245
-
2246
- [data-theme="studio"] .hero__display,
2247
- [data-theme="studio"] .section__title,
2248
- [data-theme="studio"] .foot__wordmark,
2249
- [data-theme="studio"] .hero__quote p,
2250
- [data-theme="studio"] .hero__salutation,
2251
- [data-theme="studio"] .spec__name,
2252
- [data-theme="studio"] .tell__name {
2253
- font-style: italic;
2254
- letter-spacing: -0.02em;
2255
- font-variation-settings: "opsz" 144, "SOFT" 30;
2256
- }
2257
-
2258
- [data-theme="studio"] .banner__center {
2259
- font-style: italic;
2260
- letter-spacing: 0;
2261
- font-variation-settings: "opsz" 24;
2262
- }
2263
-
2264
- [data-theme="studio"] .hero__lede,
2265
- [data-theme="studio"] .hero__letter-body,
2266
- [data-theme="studio"] .spec__rule,
2267
- [data-theme="studio"] .tell__why,
2268
- [data-theme="studio"] .hero__attrib,
2269
- [data-theme="studio"] .foot__tagline {
2270
- font-family: var(--font-body);
2271
- font-style: normal;
2272
- }
2273
-
2274
- [data-theme="studio"] .hero__eyebrow,
2275
- [data-theme="studio"] .label,
2276
- [data-theme="studio"] .section-label {
2277
- font-feature-settings: "ss01";
2278
- }
2279
-
2280
- /* Portfolio / gallery rhythm — Studio's editorial-magazine register. */
2281
-
2282
- [data-theme="studio"] .ex-card {
2283
- background: var(--color-paper-2);
2284
- border-color: var(--color-rule-2);
2285
- }
2286
-
2287
- [data-theme="studio"] .ex-card__name {
2288
- font-style: italic;
2289
- }
2290
-
2291
- [data-theme="studio"] .hero__quote p {
2292
- font-size: clamp(2.5rem, 4vw + 1rem, 4.75rem);
2293
- font-variation-settings: "opsz" 144, "SOFT" 50;
2294
- }
2295
-
2296
- /* ───────────── ATELIER — sketchbook / working-archive ─────────────
2297
- Plate-numeral marginalia beside section heads, old-style figures in
2298
- body text, an italic display optical-size axis for hand-set feel.
2299
- Earns the workshop name without slipping into the salon-formal
2300
- register that Salon owns. */
2301
-
2302
- [data-theme="atelier"] .section-label .num {
2303
- font-family: var(--font-display);
2304
- font-style: italic;
2305
- font-weight: 400;
2306
- font-size: var(--text-md);
2307
- font-variation-settings: "opsz" 96;
2308
- color: var(--color-ink);
2309
- }
2310
-
2311
- [data-theme="atelier"] .section-label::after {
2312
- content: " · plate";
2313
- color: var(--color-muted);
2314
- font-style: italic;
2315
- text-transform: lowercase;
2316
- letter-spacing: 0;
2317
- margin-inline-start: 0.4em;
2318
- }
2319
-
2320
- [data-theme="atelier"] .section__title {
2321
- font-variation-settings: "opsz" 144, "SOFT" 60;
2322
- }
2323
-
2324
- [data-theme="atelier"] .hero__display,
2325
- [data-theme="atelier"] .hero__quote p,
2326
- [data-theme="atelier"] .hero__salutation {
2327
- font-variation-settings: "opsz" 144, "SOFT" 70;
2328
- }
2329
-
2330
- /* Hero quote uses the upright display face (matching the "Atelier"
2331
- wordmark in the banner and every section title), not the italic
2332
- serif default. Atelier's voice is workshop-declarative — the
2333
- header reads as a statement, not a quotation. */
2334
- [data-theme="atelier"] .hero__quote p {
2335
- font-family: var(--font-display);
2336
- font-style: normal;
2337
- font-weight: var(--display-weight, 900);
2338
- }
2339
-
2340
- /* Old-style figures in body text — reads as hand-set, not synthesised */
2341
- [data-theme="atelier"] .hero__lede,
2342
- [data-theme="atelier"] .hero__letter-body,
2343
- [data-theme="atelier"] .spec__rule,
2344
- [data-theme="atelier"] .found-panel__rule,
2345
- [data-theme="atelier"] .install-pane__next,
2346
- [data-theme="atelier"] .ex-card__brief {
2347
- font-variant-numeric: oldstyle-nums;
2348
- }
2349
-
2350
- /* Tabular numerals in the example tile counter — reads as catalogue */
2351
- [data-theme="atelier"] .ex-card__num,
2352
- [data-theme="atelier"] .gallery__num,
2353
- [data-theme="atelier"] .found-nav__num {
2354
- font-variant-numeric: tabular-nums;
2355
- font-feature-settings: "tnum";
2356
- }
2357
-
2358
- [data-theme="atelier"] .ex-card {
2359
- border-style: solid;
2360
- border-color: var(--color-rule);
2361
- background: var(--color-paper-2);
2362
- }
2363
-
2364
-
2365
- /* ───────────── RISO — bold lowercase, off-register print ───────────── */
2366
-
2367
- [data-theme="riso"] .hero__display,
2368
- [data-theme="riso"] .hero__quote p,
2369
- [data-theme="riso"] .hero__salutation,
2370
- [data-theme="riso"] .hero__qualifier,
2371
- [data-theme="riso"] .hero__stat,
2372
- [data-theme="riso"] .section__title,
2373
- [data-theme="riso"] .foot__wordmark,
2374
- [data-theme="riso"] .spec__name,
2375
- [data-theme="riso"] .tell__name {
2376
- font-family: var(--font-display);
2377
- font-weight: 800;
2378
- font-style: normal;
2379
- text-transform: lowercase;
2380
- letter-spacing: -0.04em;
2381
- }
2382
-
2383
- /* The riso off-register effect — a 2px cyan ghost behind the headline.
2384
- Subtle, not garish. Reduced-motion + browsers without text-shadow are fine. */
2385
- [data-theme="riso"] .hero__display,
2386
- [data-theme="riso"] .hero__quote p,
2387
- [data-theme="riso"] .hero__stat {
2388
- text-shadow: 2px 2px 0 var(--color-accent),
2389
- -2px 0 0 var(--color-accent-2, oklch(78% 0.18 95));
2390
- }
2391
-
2392
- [data-theme="riso"] .hero__lede,
2393
- [data-theme="riso"] .hero__letter-body,
2394
- [data-theme="riso"] .spec__rule,
2395
- [data-theme="riso"] .tell__why,
2396
- [data-theme="riso"] .foot__tagline {
2397
- font-family: var(--font-serif);
2398
- font-weight: 400;
2399
- }
2400
-
2401
- [data-theme="riso"] .hero__attrib,
2402
- [data-theme="riso"] .label,
2403
- [data-theme="riso"] .section-label,
2404
- [data-theme="riso"] .banner__center {
2405
- text-transform: lowercase;
2406
- letter-spacing: 0.02em;
2407
- }
2408
-
2409
- [data-theme="riso"] .banner__center {
2410
- font-family: var(--font-display);
2411
- font-weight: 700;
2412
- font-size: var(--text-md);
2413
- }
2414
-
2415
- /* Subtle paper grain — a tiny stipple via repeating radial-gradient.
2416
- Cheap, no image asset, and disappears under prefers-reduced-data. */
2417
- [data-theme="riso"] body::before {
2418
- content: "";
2419
- position: fixed;
2420
- inset: 0;
2421
- pointer-events: none;
2422
- z-index: 0;
2423
- background-image: radial-gradient(circle at 1px 1px, oklch(0% 0 0 / 0.045) 1px, transparent 0);
2424
- background-size: 3px 3px;
2425
- mix-blend-mode: multiply;
2426
- }
2427
-
2428
- @media (prefers-reduced-data: reduce) {
2429
- [data-theme="riso"] body::before { display: none; }
2430
- }
2431
-
2432
- /* ───────────── HERO ARCHETYPES ─────────────
2433
- The hero slot picks one shape per theme, from the cookbook.
2434
- Each archetype is a different fingerprint — not a re-skin. */
2435
-
2436
- .hero { display: grid; }
2437
-
2438
- /* — Hero moment slot —————————————————————————————————————————
2439
- Marquee / letter / quote / stat archetypes get an optional right-side
2440
- "moment" — a small per-theme typographic or geometric accent that
2441
- stops the right column from reading as dead space at desktop. Hidden
2442
- by default (most themes don't need it); shown via per-theme opt-in. */
2443
- .hero__main { display: contents; }
2444
- .hero__moment { display: none; }
2445
-
2446
- @media (min-width: 60rem) {
2447
- /* Themes that opt in: 2-column grid, moment in column 2. */
2448
- [data-theme="terminal"] .hero--marquee,
2449
- [data-theme="manifesto"] .hero--marquee,
2450
- [data-theme="aurora"] .hero--marquee,
2451
- [data-theme="atelier"] .hero--quote,
2452
- [data-theme="riso"] .hero--quote,
2453
- [data-theme="midnight"] .hero--stat,
2454
- [data-theme="sport"] .hero--stat {
2455
- grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
2456
- column-gap: var(--space-2xl);
2457
- align-items: center;
2458
- }
2459
- [data-theme="terminal"] .hero--marquee .hero__main,
2460
- [data-theme="manifesto"] .hero--marquee .hero__main,
2461
- [data-theme="aurora"] .hero--marquee .hero__main,
2462
- [data-theme="atelier"] .hero--quote .hero__main,
2463
- [data-theme="riso"] .hero--quote .hero__main,
2464
- [data-theme="midnight"] .hero--stat .hero__main,
2465
- [data-theme="sport"] .hero--stat .hero__main {
2466
- display: grid;
2467
- gap: var(--space-lg);
2468
- grid-column: 1;
2469
- }
2470
- [data-theme="terminal"] .hero__moment,
2471
- [data-theme="manifesto"] .hero__moment,
2472
- [data-theme="aurora"] .hero__moment,
2473
- [data-theme="atelier"] .hero__moment,
2474
- [data-theme="riso"] .hero__moment,
2475
- [data-theme="midnight"] .hero__moment,
2476
- [data-theme="sport"] .hero__moment {
2477
- display: grid;
2478
- place-items: center;
2479
- grid-column: 2;
2480
- align-self: center;
2481
- justify-self: end;
2482
- color: var(--color-ink-2);
2483
- }
2484
- }
2485
-
2486
- /* Per-theme moment content — a typographic glyph or simple geometric
2487
- accent. CSS-only (no extra HTML), pure ::before content + a few
2488
- shapes. Each moment is small + restrained — punctuation, not focus. */
2489
-
2490
- /* TERMINAL — ASCII prompt block in phosphor green. */
2491
- [data-theme="terminal"] .hero__moment::before {
2492
- content: "[\A █ \A]";
2493
- white-space: pre;
2494
- font-family: var(--font-mono);
2495
- font-size: clamp(2rem, 3vw, 3rem);
2496
- line-height: 1.2;
2497
- color: var(--color-accent);
2498
- letter-spacing: 0.05em;
2499
- }
2500
-
2501
- /* MANIFESTO — single uppercase declarative phrase. */
2502
- [data-theme="manifesto"] .hero__moment::before {
2503
- content: "NO\ASLOP.";
2504
- white-space: pre;
2505
- font-family: var(--font-display);
2506
- font-weight: 400;
2507
- font-size: clamp(3rem, 6vw, 5rem);
2508
- line-height: 0.92;
2509
- letter-spacing: -0.02em;
2510
- color: var(--color-accent);
2511
- }
2512
-
2513
- /* AURORA — soft secondary radial accent. */
2514
- [data-theme="aurora"] .hero__moment {
2515
- width: clamp(14rem, 24vw, 22rem);
2516
- aspect-ratio: 1 / 1;
2517
- background:
2518
- radial-gradient(circle at 50% 50%,
2519
- color-mix(in oklch, var(--color-accent) 28%, transparent) 0%,
2520
- transparent 65%);
2521
- filter: blur(4px);
2522
- opacity: 0.85;
2523
- }
2524
-
2525
- /* ATELIER — italic Roman numeral plate. */
2526
- [data-theme="atelier"] .hero__moment::before {
2527
- content: "I";
2528
- font-family: var(--font-serif);
2529
- font-style: italic;
2530
- font-size: clamp(6rem, 10vw, 10rem);
2531
- line-height: 1;
2532
- color: var(--color-ink);
2533
- padding: var(--space-2xl) var(--space-3xl);
2534
- border: 1px solid var(--color-rule);
2535
- display: block;
2536
- }
2537
- [data-theme="atelier"] .hero__moment::after {
2538
- content: "Plate I";
2539
- font-family: var(--font-label);
2540
- font-size: var(--text-xs);
2541
- letter-spacing: var(--tracking-label);
2542
- text-transform: uppercase;
2543
- color: var(--color-muted);
2544
- margin-block-start: var(--space-xs);
2545
- }
2546
-
2547
- /* RISO — two overlapping circles in duotone (off-register). */
2548
- [data-theme="riso"] .hero__moment {
2549
- position: relative;
2550
- width: clamp(10rem, 16vw, 16rem);
2551
- aspect-ratio: 1 / 1;
2552
- }
2553
- [data-theme="riso"] .hero__moment::before,
2554
- [data-theme="riso"] .hero__moment::after {
2555
- content: "";
2556
- position: absolute;
2557
- inset: 0;
2558
- border-radius: 50%;
2559
- mix-blend-mode: multiply;
2560
- }
2561
- [data-theme="riso"] .hero__moment::before {
2562
- background: var(--color-accent);
2563
- transform: translate(-8%, -6%);
2564
- }
2565
- [data-theme="riso"] .hero__moment::after {
2566
- background: var(--color-accent-2, oklch(78% 0.18 95));
2567
- transform: translate(8%, 6%);
2568
- }
2569
-
2570
- /* MIDNIGHT — three concentric rings + centre dot. */
2571
- [data-theme="midnight"] .hero__moment {
2572
- position: relative;
2573
- width: clamp(10rem, 14vw, 14rem);
2574
- aspect-ratio: 1 / 1;
2575
- border-radius: 50%;
2576
- border: 1px solid color-mix(in oklch, var(--color-accent) 35%, transparent);
2577
- box-shadow:
2578
- inset 0 0 0 1px transparent,
2579
- 0 0 0 12px transparent,
2580
- 0 0 0 13px color-mix(in oklch, var(--color-accent) 22%, transparent),
2581
- 0 0 0 28px transparent,
2582
- 0 0 0 29px color-mix(in oklch, var(--color-accent) 12%, transparent);
2583
- }
2584
- [data-theme="midnight"] .hero__moment::before {
2585
- content: "";
2586
- position: absolute;
2587
- inset: 50%;
2588
- width: 6px;
2589
- height: 6px;
2590
- margin: -3px 0 0 -3px;
2591
- border-radius: 50%;
2592
- background: var(--color-accent);
2593
- box-shadow: 0 0 12px 3px color-mix(in oklch, var(--color-accent) 50%, transparent);
2594
- }
2595
-
2596
- /* SPORT — three-bar lap chart (horizontal bars in accent). */
2597
- [data-theme="sport"] .hero__moment {
2598
- width: clamp(8rem, 12vw, 12rem);
2599
- display: grid;
2600
- gap: var(--space-xs);
2601
- }
2602
- [data-theme="sport"] .hero__moment::before,
2603
- [data-theme="sport"] .hero__moment::after {
2604
- content: "";
2605
- height: 0.55rem;
2606
- background: var(--color-accent);
2607
- }
2608
- [data-theme="sport"] .hero__moment::before { width: 90%; }
2609
- [data-theme="sport"] .hero__moment::after { width: 55%; }
2610
-
2611
- .hero__eyebrow {
2612
- display: inline-flex;
2613
- align-items: center;
2614
- gap: 0.6rem;
2615
- font-family: var(--font-label);
2616
- font-size: var(--text-xs);
2617
- letter-spacing: var(--tracking-label);
2618
- text-transform: uppercase;
2619
- color: var(--color-muted);
2620
- margin-bottom: var(--space-lg);
2621
- }
2622
-
2623
- .hero__eyebrow .mark {
2624
- width: 6px; height: 6px;
2625
- background: var(--color-accent);
2626
- display: inline-block;
2627
- }
2628
-
2629
- .hero__display {
2630
- font-family: var(--font-display);
2631
- font-weight: var(--display-weight, 400);
2632
- font-style: var(--display-style, normal);
2633
- font-size: var(--text-display);
2634
- line-height: var(--lh-tight);
2635
- letter-spacing: var(--tracking-display);
2636
- color: var(--color-ink);
2637
- font-optical-sizing: auto;
2638
- margin: 0;
2639
- }
2640
-
2641
- .hero__display--small {
2642
- font-size: var(--text-display-s);
2643
- }
2644
-
2645
- .hero__lede {
2646
- font-family: var(--font-serif);
2647
- font-size: var(--text-md);
2648
- line-height: var(--lh-normal);
2649
- color: var(--color-ink-2);
2650
- max-width: 56ch;
2651
- margin-block: var(--space-lg) 0;
2652
- }
2653
-
2654
- [data-theme="brutal"] .hero__lede,
2655
- [data-theme="manifesto"] .hero__lede,
2656
- [data-theme="terminal"] .hero__lede,
2657
- [data-theme="sport"] .hero__lede,
2658
- [data-theme="almanac"] .hero__lede {
2659
- font-style: normal;
2660
- font-family: var(--font-body);
2661
- }
2662
-
2663
- [data-theme="manifesto"] .hero__display {
2664
- /* Anton is a tall narrow condensed face — at the default 1.02
2665
- tight line-height, the words stack with no breathing room.
2666
- Bump line-height so multi-line headlines have visual rhythm. */
2667
- line-height: 1.05;
2668
- }
2669
-
2670
- [data-theme="manifesto"] .hero__display,
2671
- [data-theme="brutal"] .hero__display,
2672
- [data-theme="sport"] .hero__display {
2673
- text-transform: uppercase;
2674
- }
2675
-
2676
- .hero__link {
2677
- margin-top: var(--space-lg);
2678
- display: inline-block;
2679
- font-family: var(--font-label);
2680
- font-size: var(--text-sm);
2681
- letter-spacing: var(--tracking-label);
2682
- text-transform: uppercase;
2683
- }
2684
-
2685
- /* H1 — Marquee. Display fills the fold, install code below. */
2686
- .hero--marquee {
2687
- padding-block: var(--space-2xl) var(--space-xl);
2688
- gap: var(--space-lg);
2689
- }
2690
-
2691
- .hero--marquee .hero__display {
2692
- max-width: 18ch;
2693
- }
2694
-
2695
- .hero--marquee .hero__cta {
2696
- margin-top: var(--space-xl);
2697
- display: grid;
2698
- gap: var(--space-sm);
2699
- max-width: 30rem;
2700
- }
2701
-
2702
- .hero--marquee .hero__cta .label {
2703
- font-family: var(--font-label);
2704
- font-size: var(--text-xs);
2705
- letter-spacing: var(--tracking-label);
2706
- text-transform: uppercase;
2707
- color: var(--color-muted);
2708
- }
2709
-
2710
- /* H2 — Split Diptych. Title left, proof right. */
2711
- .hero--split {
2712
- grid-template-columns: 7fr 5fr;
2713
- gap: var(--space-2xl);
2714
- padding-block: var(--space-2xl) var(--space-xl);
2715
- align-items: end;
2716
- }
2717
-
2718
- @media (max-width: 60rem) {
2719
- .hero--split { grid-template-columns: 1fr; gap: var(--space-xl); align-items: start; }
2720
- }
2721
-
2722
- .hero--split .hero__col { display: grid; gap: 0; }
2723
-
2724
- .hero--split .hero__proof {
2725
- display: grid;
2726
- gap: var(--space-xs);
2727
- padding-block-start: var(--space-md);
2728
- border-block-start: var(--rule-hair) solid var(--color-rule);
2729
- }
2730
-
2731
- .hero--split .hero__proof .label {
2732
- font-family: var(--font-label);
2733
- font-size: var(--text-xs);
2734
- letter-spacing: var(--tracking-label);
2735
- text-transform: uppercase;
2736
- color: var(--color-muted);
2737
- margin-bottom: var(--space-xs);
2738
- }
2739
-
2740
- .hero__proof-line {
2741
- font-family: var(--font-body);
2742
- font-size: var(--text-sm);
2743
- color: var(--color-ink-2);
2744
- line-height: var(--lh-snug);
2745
- font-variant-numeric: tabular-nums;
2746
- }
2747
-
2748
- .hero--split .hero__proof a { margin-top: var(--space-sm); }
2749
-
2750
- /* Editorial: the proof block reads cleaner with just the CTA + a giant
2751
- Roman numeral set above it as the visual anchor for the right column. */
2752
- [data-theme="editorial"] .hero--split .hero__proof .label,
2753
- [data-theme="editorial"] .hero--split .hero__proof .hero__proof-line { display: none; }
2754
- [data-theme="editorial"] .hero--split .hero__proof {
2755
- padding-block-start: 0;
2756
- border-block-start: 0;
2757
- display: grid;
2758
- gap: var(--space-md);
2759
- align-content: end;
2760
- }
2761
- [data-theme="editorial"] .hero--split .hero__proof::before {
2762
- content: "XXIII";
2763
- font-family: var(--font-serif);
2764
- font-style: italic;
2765
- font-weight: 400;
2766
- font-size: clamp(5rem, 9vw, 8rem);
2767
- line-height: 0.85;
2768
- letter-spacing: -0.02em;
2769
- color: var(--color-ink);
2770
- }
2771
-
2772
- /* Quiet: collapse the proof-block down to one italic note + the CTA, so
2773
- the right column reads as a quiet annotation instead of a sign-up form. */
2774
- [data-theme="quiet"] .hero--split .hero__proof .label,
2775
- [data-theme="quiet"] .hero--split .hero__proof .hero__proof-line:nth-child(3),
2776
- [data-theme="quiet"] .hero--split .hero__proof .hero__proof-line:nth-child(4) { display: none; }
2777
- [data-theme="quiet"] .hero--split .hero__proof {
2778
- padding-block-start: var(--space-md);
2779
- border-block-start: var(--rule-hair) solid var(--color-rule);
2780
- }
2781
- [data-theme="quiet"] .hero--split .hero__proof .hero__proof-line {
2782
- font-family: var(--font-serif);
2783
- font-style: italic;
2784
- color: var(--color-muted);
2785
- max-width: 24ch;
2786
- }
2787
-
2788
-
2789
- /* H3 — Stat-Led. Giant number + qualifier. */
2790
- .hero--stat {
2791
- padding-block: var(--space-2xl) var(--space-xl);
2792
- gap: 0;
2793
- }
2794
-
2795
- .hero__stat {
2796
- font-family: var(--font-display);
2797
- font-weight: var(--display-weight, 400);
2798
- font-style: var(--display-style, normal);
2799
- font-size: clamp(7rem, 22vw, 16rem);
2800
- line-height: 0.85;
2801
- letter-spacing: -0.04em;
2802
- color: var(--color-ink);
2803
- font-optical-sizing: auto;
2804
- display: block;
2805
- margin-block: var(--space-md) 0;
2806
- }
2807
-
2808
- .hero__qualifier {
2809
- font-family: var(--font-display);
2810
- font-weight: var(--display-weight, 400);
2811
- font-style: var(--display-style, normal);
2812
- font-size: var(--text-2xl);
2813
- letter-spacing: var(--tracking-display);
2814
- color: var(--color-ink);
2815
- margin-block: var(--space-md) 0;
2816
- font-optical-sizing: auto;
2817
- }
2818
-
2819
- [data-theme="manifesto"] .hero__stat,
2820
- [data-theme="sport"] .hero__stat {
2821
- color: var(--color-accent);
2822
- }
2823
-
2824
- /* H4 — Quote-Led. Pull quote in italic display. */
2825
- .hero--quote {
2826
- padding-block: var(--space-2xl) var(--space-xl);
2827
- max-width: 56rem;
2828
- }
2829
-
2830
- .hero__quote {
2831
- margin: 0;
2832
- padding: 0;
2833
- }
2834
-
2835
- .hero__quote p {
2836
- font-family: var(--font-serif);
2837
- font-style: italic;
2838
- font-weight: 400;
2839
- font-size: clamp(2.25rem, 4vw + 1rem, 4.25rem);
2840
- line-height: 1.08;
2841
- letter-spacing: -0.015em;
2842
- color: var(--color-ink);
2843
- margin: 0;
2844
- }
2845
-
2846
- .hero__attrib {
2847
- margin-block-start: var(--space-lg);
2848
- font-family: var(--font-label);
2849
- font-size: var(--text-xs);
2850
- letter-spacing: var(--tracking-label);
2851
- text-transform: uppercase;
2852
- color: var(--color-muted);
2853
- }
2854
-
2855
- [data-theme="brutal"] .hero__quote p,
2856
- [data-theme="manifesto"] .hero__quote p,
2857
- [data-theme="terminal"] .hero__quote p,
2858
- [data-theme="sport"] .hero__quote p,
2859
- [data-theme="almanac"] .hero__quote p {
2860
- font-style: normal;
2861
- font-family: var(--font-display);
2862
- }
2863
-
2864
- /* H5 — Letter. First-person greeting, paragraph body, signoff. */
2865
- .hero--letter {
2866
- padding-block: var(--space-2xl) var(--space-xl);
2867
- max-width: 52rem;
2868
- gap: 0;
2869
- }
2870
-
2871
- .hero__salutation {
2872
- font-family: var(--font-display);
2873
- font-weight: var(--display-weight, 400);
2874
- font-style: italic;
2875
- font-size: clamp(2rem, 3vw + 1rem, 3.25rem);
2876
- line-height: 1.15;
2877
- letter-spacing: -0.01em;
2878
- color: var(--color-ink);
2879
- margin-block: var(--space-md) var(--space-lg);
2880
- font-optical-sizing: auto;
2881
- }
2882
-
2883
- .hero__letter-body {
2884
- font-family: var(--font-serif);
2885
- font-size: var(--text-md);
2886
- line-height: var(--lh-relaxed);
2887
- color: var(--color-ink-2);
2888
- max-width: 60ch;
2889
- margin: 0;
2890
- }
2891
-
2892
- [data-theme="brutal"] .hero__letter-body,
2893
- [data-theme="terminal"] .hero__letter-body,
2894
- [data-theme="sport"] .hero__letter-body,
2895
- [data-theme="almanac"] .hero__letter-body {
2896
- font-family: var(--font-body);
2897
- }
2898
-
2899
- .hero__signoff {
2900
- margin-block: var(--space-xl) 0;
2901
- font-family: var(--font-serif);
2902
- font-size: var(--text-md);
2903
- color: var(--color-ink-2);
2904
- line-height: var(--lh-snug);
2905
- }
2906
-
2907
- .hero__sign {
2908
- font-style: normal;
2909
- font-family: var(--font-display);
2910
- color: var(--color-ink);
2911
- letter-spacing: var(--tracking-display);
2912
- }
2913
-
2914
- /* H9 — Bloom hero. Layered watercolor wash + oversized italic
2915
- wordmark + small geometric accents. Painterly composition for
2916
- warm-rose / playful themes (Plume). */
2917
- .hero--bloom {
2918
- display: grid;
2919
- grid-template-columns: minmax(20rem, 1fr) minmax(0, 1.1fr);
2920
- gap: var(--space-2xl);
2921
- padding-block: var(--space-2xl) var(--space-xl);
2922
- align-items: center;
2923
- }
2924
-
2925
- .hero--bloom .hero__copy { display: grid; gap: 0; }
2926
- .hero--bloom .hero__display { max-width: 16ch; margin: 0; }
2927
- .hero--bloom .hero__lede { max-width: 42ch; }
2928
-
2929
- .hero__bloom-stage {
2930
- position: relative;
2931
- margin: 0;
2932
- aspect-ratio: 5 / 6;
2933
- display: grid;
2934
- place-items: center;
2935
- isolation: isolate;
2936
- overflow: visible;
2937
- }
2938
-
2939
- .hero__bloom-wash {
2940
- position: absolute;
2941
- inset: -8% -12% -8% -8%;
2942
- width: auto;
2943
- height: auto;
2944
- color: var(--color-accent);
2945
- z-index: 0;
2946
- pointer-events: none;
2947
- filter: blur(0.5px);
2948
- }
2949
-
2950
- .hero__bloom-glyph {
2951
- position: relative;
2952
- z-index: 1;
2953
- font-family: var(--font-serif, "Newsreader"), ui-serif, Georgia, serif;
2954
- font-size: clamp(4rem, 9vw, 7.5rem);
2955
- line-height: 1;
2956
- color: var(--color-ink);
2957
- letter-spacing: -0.02em;
2958
- user-select: none;
2959
- font-optical-sizing: auto;
2960
- }
2961
-
2962
- .hero__bloom-glyph em {
2963
- font-style: italic;
2964
- font-weight: 500;
2965
- }
2966
-
2967
- .hero__bloom-dot {
2968
- position: absolute;
2969
- z-index: 2;
2970
- bottom: 12%;
2971
- right: 22%;
2972
- width: 14px;
2973
- height: 14px;
2974
- border-radius: 50%;
2975
- background: var(--color-ink);
2976
- }
2977
-
2978
- .hero__bloom-line {
2979
- position: absolute;
2980
- z-index: 2;
2981
- top: 18%;
2982
- right: 8%;
2983
- width: 1px;
2984
- height: 38%;
2985
- background: var(--color-ink);
2986
- opacity: 0.5;
2987
- }
2988
-
2989
- .hero__bloom-circle {
2990
- position: absolute;
2991
- z-index: 2;
2992
- top: 8%;
2993
- left: 12%;
2994
- width: 22px;
2995
- height: 22px;
2996
- border-radius: 50%;
2997
- border: 1px solid var(--color-ink);
2998
- opacity: 0.6;
2999
- }
3000
-
3001
- @media (max-width: 60rem) {
3002
- .hero--bloom { grid-template-columns: 1fr; gap: var(--space-xl); }
3003
- .hero__bloom-stage { aspect-ratio: 4 / 3; }
3004
- .hero__bloom-glyph { font-size: clamp(3rem, 14vw, 5rem); }
3005
- }
3006
-
3007
- /* H10 — Orbit hero. Concentric rings + glowing centre dot.
3008
- Atmospheric composition for warm-glow themes (Halo). The rings
3009
- slow-rotate via @keyframes; reduced-motion stops them. */
3010
- .hero--orbit {
3011
- display: grid;
3012
- grid-template-columns: minmax(20rem, 1fr) minmax(0, 0.7fr);
3013
- gap: var(--space-xl);
3014
- padding-block: var(--space-2xl) var(--space-xl);
3015
- align-items: center;
3016
- }
3017
-
3018
- .hero--orbit .hero__copy { display: grid; gap: 0; }
3019
- .hero--orbit .hero__display { max-width: 16ch; margin: 0; }
3020
- .hero--orbit .hero__lede { max-width: 42ch; }
3021
-
3022
- .hero__orbit-stage {
3023
- position: relative;
3024
- margin: 0;
3025
- aspect-ratio: 1 / 1;
3026
- display: grid;
3027
- place-items: center;
3028
- isolation: isolate;
3029
- }
3030
-
3031
- .hero__orbit-rings {
3032
- position: absolute;
3033
- inset: 0;
3034
- display: grid;
3035
- place-items: center;
3036
- z-index: 0;
3037
- color: var(--color-rule-2);
3038
- animation: orbit-spin 80s linear infinite;
3039
- }
3040
-
3041
- .hero__orbit-rings svg {
3042
- width: 100%;
3043
- height: 100%;
3044
- }
3045
-
3046
- @keyframes orbit-spin {
3047
- from { transform: rotate(0deg); }
3048
- to { transform: rotate(360deg); }
3049
- }
3050
-
3051
- @media (prefers-reduced-motion: reduce) {
3052
- .hero__orbit-rings { animation: none; }
3053
- }
3054
-
3055
- .hero__orbit-dot {
3056
- position: relative;
3057
- z-index: 1;
3058
- width: 10px;
3059
- height: 10px;
3060
- border-radius: 50%;
3061
- background: var(--color-accent);
3062
- box-shadow:
3063
- 0 0 0 4px color-mix(in oklch, var(--color-accent) 18%, transparent),
3064
- 0 0 22px 4px color-mix(in oklch, var(--color-accent) 35%, transparent);
3065
- }
3066
-
3067
- .hero__orbit-rule {
3068
- position: absolute;
3069
- z-index: 2;
3070
- bottom: 7%;
3071
- left: 18%;
3072
- right: 18%;
3073
- height: 1px;
3074
- background: var(--color-rule-2);
3075
- }
3076
-
3077
- .hero__orbit-spec {
3078
- position: absolute;
3079
- z-index: 2;
3080
- bottom: 2%;
3081
- left: 0;
3082
- right: 0;
3083
- margin: 0;
3084
- text-align: center;
3085
- font-family: var(--font-label);
3086
- font-size: var(--text-xs);
3087
- letter-spacing: var(--tracking-label);
3088
- text-transform: uppercase;
3089
- color: var(--color-muted);
3090
- font-feature-settings: "tnum";
3091
- }
3092
-
3093
- @media (max-width: 60rem) {
3094
- .hero--orbit { grid-template-columns: 1fr; gap: var(--space-xl); }
3095
- .hero__orbit-stage { aspect-ratio: 1.4 / 1; max-width: 24rem; margin: 0 auto; }
3096
- }
3097
-
3098
- /* ───────────── FOOTER — editorial colophon ─────────────
3099
- The publisher's signature page. Same shape across every theme;
3100
- theme variation comes from typography rendering, not layout.
3101
- Composed of three rhythms:
3102
- 1. masthead: oversized wordmark + tiny version stamp on a baseline
3103
- 2. grid: three meta blocks separated by hairline dividers
3104
- 3. base: thin centered credit line below a hairline
3105
- Generous whitespace; type carries the work, not boxes. */
3106
- .foot.foot--colophon {
3107
- display: grid;
3108
- grid-template-columns: 1fr;
3109
- gap: var(--space-3xl);
3110
- /* Bottom padding capped at ~16 px — the credit line should never
3111
- sit more than ~20 px from the viewport edge regardless of the
3112
- theme. The page-wrapper no longer adds bottom padding either. */
3113
- padding-block: var(--space-3xl) var(--space-md);
3114
- border-block-start: var(--rule-hair) solid var(--color-rule);
3115
- border-top-width: var(--rule-hair);
3116
- margin: 0;
3117
- width: 100%;
3118
- font-family: inherit;
3119
- font-size: inherit;
3120
- letter-spacing: 0;
3121
- color: inherit;
3122
- }
3123
-
3124
- /* — Masthead row ———————————————————————————————————————— */
3125
- .foot__masthead {
3126
- display: flex;
3127
- align-items: baseline;
3128
- justify-content: space-between;
3129
- gap: var(--space-lg);
3130
- padding-block-end: var(--space-xl);
3131
- border-block-end: var(--rule-hair) solid var(--color-rule);
3132
- }
3133
-
3134
- .foot--colophon .foot__wordmark {
3135
- display: inline-flex;
3136
- color: var(--color-ink);
3137
- line-height: 1;
3138
- }
3139
-
3140
- /* The brand mark is locked to Fraunces in every theme — themes still
3141
- re-render everything else, but the wordmark is brand-locked so the
3142
- site is always recognisable as "Hallmark" regardless of the theme. */
3143
- .brand-mark {
3144
- font-family: "Fraunces", "Newsreader", "Playfair Display", serif;
3145
- font-optical-sizing: auto;
3146
- font-style: normal;
3147
- text-transform: none;
3148
- display: inline-flex;
3149
- align-items: baseline;
3150
- font-size: 1.05rem;
3151
- line-height: 1;
3152
- color: inherit;
3153
- }
3154
-
3155
- .brand-mark__slash {
3156
- font-weight: 900;
3157
- letter-spacing: 0.20em;
3158
- display: inline-block;
3159
- }
3160
-
3161
- .brand-mark__name {
3162
- font-weight: 300;
3163
- letter-spacing: 0;
3164
- margin-inline-start: 0.05em;
3165
- }
3166
-
3167
- /* Footer wordmark variant — same proportions, much larger. */
3168
- .brand-mark--lg {
3169
- font-size: clamp(3rem, 7vw + 0.5rem, 6.5rem);
3170
- line-height: 0.85;
3171
- }
3172
-
3173
- /* Keep manifesto/brutal/sport from upper-casing the brand mark — the
3174
- wordmark is locked, theme typography lives elsewhere. */
3175
- [data-theme="manifesto"] .foot--colophon .foot__wordmark,
3176
- [data-theme="brutal"] .foot--colophon .foot__wordmark,
3177
- [data-theme="sport"] .foot--colophon .foot__wordmark { text-transform: none; }
3178
-
3179
- .foot__version {
3180
- font-family: var(--font-mono);
3181
- font-size: var(--text-xs);
3182
- letter-spacing: var(--tracking-label);
3183
- text-transform: uppercase;
3184
- color: var(--color-muted);
3185
- white-space: nowrap;
3186
- }
3187
-
3188
- /* — Three-block grid ——————————————————————————————————— */
3189
- .foot__grid {
3190
- display: grid;
3191
- grid-template-columns: repeat(3, minmax(0, 1fr));
3192
- gap: var(--space-3xl);
3193
- }
3194
-
3195
- .foot__block {
3196
- display: grid;
3197
- gap: var(--space-md);
3198
- align-content: start;
3199
- margin: 0;
3200
- min-width: 0;
3201
- }
3202
-
3203
- .foot__label {
3204
- margin: 0;
3205
- font-family: var(--font-label);
3206
- font-size: var(--text-xs);
3207
- letter-spacing: var(--tracking-label);
3208
- text-transform: uppercase;
3209
- color: var(--color-muted);
3210
- }
3211
-
3212
- .foot__value {
3213
- margin: 0;
3214
- font-family: var(--font-display);
3215
- font-weight: var(--display-weight, 500);
3216
- font-style: var(--display-style, normal);
3217
- font-size: var(--text-xl);
3218
- line-height: 1;
3219
- letter-spacing: var(--tracking-tight);
3220
- color: var(--color-ink);
3221
- }
3222
-
3223
- .foot__value strong { font-weight: inherit; }
3224
-
3225
- .foot__hint {
3226
- margin: 0;
3227
- font-family: var(--font-body);
3228
- font-size: var(--text-sm);
3229
- line-height: var(--lh-snug);
3230
- color: var(--color-muted);
3231
- max-width: 32ch;
3232
- }
3233
-
3234
- /* Catalog stat list — mono numerals + small caps key. */
3235
- .foot__stats {
3236
- list-style: none;
3237
- margin: 0;
3238
- padding: 0;
3239
- display: grid;
3240
- gap: var(--space-xs);
3241
- }
3242
-
3243
- .foot__stats li {
3244
- display: grid;
3245
- grid-template-columns: 3.5rem 1fr;
3246
- align-items: baseline;
3247
- gap: var(--space-md);
3248
- padding-block: var(--space-2xs);
3249
- border-block-end: var(--rule-hair) solid var(--color-rule);
3250
- }
3251
-
3252
- .foot__stats li:last-child { border-block-end: 0; }
3253
-
3254
- .foot__stat-num {
3255
- font-family: var(--font-mono);
3256
- font-size: var(--text-xl);
3257
- font-weight: 500;
3258
- color: var(--color-ink);
3259
- line-height: 1;
3260
- font-feature-settings: "tnum";
3261
- text-align: end;
3262
- }
3263
-
3264
- .foot__stat-key {
3265
- font-family: var(--font-body);
3266
- font-size: var(--text-sm);
3267
- color: var(--color-ink-2);
3268
- line-height: var(--lh-snug);
3269
- }
3270
-
3271
- /* Resources list — link rows, hairline-divided. */
3272
- .foot__nav {
3273
- list-style: none;
3274
- margin: 0;
3275
- padding: 0;
3276
- display: grid;
3277
- }
3278
-
3279
- .foot__nav li {
3280
- padding-block: var(--space-xs);
3281
- border-block-end: var(--rule-hair) solid var(--color-rule);
3282
- }
3283
-
3284
- .foot__nav li:last-child { border-block-end: 0; }
3285
-
3286
- .foot__nav .link {
3287
- display: inline-block;
3288
- font-family: var(--font-body);
3289
- font-size: var(--text-md);
3290
- color: var(--color-ink);
3291
- text-decoration: none;
3292
- border-block-end: 1px solid transparent;
3293
- transition: border-color var(--dur-micro) var(--ease-out);
3294
- }
3295
-
3296
- @media (hover: hover) and (pointer: fine) {
3297
- .foot__nav .link:hover { border-block-end-color: var(--color-ink); }
3298
- }
3299
-
3300
- /* — Base credit line ——————————————————————————————————— */
3301
- .foot__base {
3302
- margin: 0;
3303
- padding: 0;
3304
- max-width: none;
3305
- font-family: var(--font-label);
3306
- font-size: var(--text-xs);
3307
- letter-spacing: var(--tracking-label);
3308
- text-transform: uppercase;
3309
- color: var(--color-muted);
3310
- text-align: start;
3311
- width: 100%;
3312
- }
3313
-
3314
- /* Mobile collapse — single column, generous gaps. Bottom padding
3315
- stays capped at --space-md so the credit line hugs the viewport
3316
- bottom on phones too. */
3317
- @media (max-width: 60rem) {
3318
- .foot--colophon { gap: var(--space-2xl); padding-block: var(--space-2xl) var(--space-md); }
3319
- .foot__masthead { flex-direction: column; align-items: flex-start; gap: var(--space-sm); padding-block-end: var(--space-lg); }
3320
- .foot__grid { grid-template-columns: 1fr; gap: var(--space-2xl); }
3321
- }
3322
-
3323
- /* ───────────── SLOT REVEALS ─────────────
3324
- The slot fades when its archetype is replaced — supplements the
3325
- View Transition and gives a graceful enter on first paint. */
3326
-
3327
- .slot[data-populating] > * {
3328
- animation: slot-in calc(var(--dur-long) * 0.7) var(--ease-out) forwards;
3329
- opacity: 0;
3330
- }
3331
-
3332
- @keyframes slot-in { to { opacity: 1; } }
3333
-
3334
- @media (prefers-reduced-motion: reduce) {
3335
- .slot[data-populating] > * { animation: none; opacity: 1; }
3336
- }
3337
-
3338
- /* ───────────── QUIET — polished minimalism ─────────────
3339
- The "modern enterprise" theme: Geist sans, pure white, large
3340
- confident display, generous space, pill CTAs. Reads like the
3341
- ElevenLabs / Stripe school of restraint. Reveals stay off — the
3342
- page is composed, not animated in. */
3343
-
3344
- [data-theme="quiet"] .reveal,
3345
- [data-theme="quiet"] .reveal.is-in,
3346
- [data-theme="quiet"] .slot[data-populating] > * {
3347
- opacity: 1;
3348
- transform: none;
3349
- animation: none;
3350
- }
3351
-
3352
- [data-theme="quiet"] .hero__display,
3353
- [data-theme="quiet"] .hero__quote p,
3354
- [data-theme="quiet"] .hero__stat,
3355
- [data-theme="quiet"] .section__title,
3356
- [data-theme="quiet"] .foot__wordmark,
3357
- [data-theme="quiet"] .spec__name,
3358
- [data-theme="quiet"] .ex-card__name,
3359
- [data-theme="quiet"] .harness__name {
3360
- font-family: var(--font-display);
3361
- font-weight: 600;
3362
- font-style: normal;
3363
- text-transform: none;
3364
- letter-spacing: -0.025em;
3365
- text-shadow: none;
3366
- }
3367
-
3368
- [data-theme="quiet"] .hero__display { font-weight: 600; }
3369
-
3370
- [data-theme="quiet"] .hero__lede,
3371
- [data-theme="quiet"] .hero__letter-body,
3372
- [data-theme="quiet"] .spec__rule,
3373
- [data-theme="quiet"] .foot__tagline,
3374
- [data-theme="quiet"] .install-pane__next {
3375
- font-family: var(--font-body);
3376
- font-style: normal;
3377
- font-weight: 400;
3378
- color: var(--color-neutral);
3379
- }
3380
-
3381
- [data-theme="quiet"] .hero__salutation {
3382
- font-family: var(--font-display);
3383
- font-style: normal;
3384
- font-weight: 600;
3385
- font-size: var(--text-2xl);
3386
- letter-spacing: -0.02em;
3387
- }
3388
-
3389
- [data-theme="quiet"] .hero__sign,
3390
- [data-theme="quiet"] .hero__signoff {
3391
- font-family: var(--font-body);
3392
- font-style: normal;
3393
- }
3394
-
3395
- [data-theme="quiet"] .hero__attrib,
3396
- [data-theme="quiet"] .section-label,
3397
- [data-theme="quiet"] .label,
3398
- [data-theme="quiet"] .install-pane__label,
3399
- [data-theme="quiet"] .vs__label,
3400
- [data-theme="quiet"] .ex-card__num {
3401
- font-family: var(--font-label);
3402
- font-weight: 500;
3403
- }
3404
-
3405
- [data-theme="quiet"] .banner__center {
3406
- font-family: var(--font-display);
3407
- font-weight: 500;
3408
- font-size: 0.875rem;
3409
- letter-spacing: -0.005em;
3410
- text-transform: none;
3411
- }
3412
-
3413
- [data-theme="quiet"] .banner {
3414
- background: color-mix(in oklch, var(--color-paper) 94%, transparent);
3415
- border-block-end-color: var(--color-rule);
3416
- }
3417
-
3418
- /* Pill CTAs — Quiet's signature button. Black-filled primary, white-
3419
- outlined secondary. Applied to anything that reads as a CTA. */
3420
- [data-theme="quiet"] .install-pane__copy {
3421
- border-radius: 999px;
3422
- background: var(--color-ink);
3423
- color: var(--color-paper);
3424
- border-color: var(--color-ink);
3425
- font-weight: 600;
3426
- }
3427
- [data-theme="quiet"] .install-pane__copy:hover {
3428
- background: var(--color-ink-2);
3429
- color: var(--color-paper);
3430
- border-color: var(--color-ink-2);
3431
- }
3432
- [data-theme="quiet"] .install-pane__copy[data-state="copied"] {
3433
- background: var(--color-ink);
3434
- color: var(--color-paper);
3435
- border-color: var(--color-ink);
3436
- }
3437
-
3438
- /* Quiet's install command bar — refined card surface, clean typography. */
3439
- [data-theme="quiet"] .install-pane {
3440
- background: var(--color-paper-2);
3441
- border-color: var(--color-rule);
3442
- }
3443
- [data-theme="quiet"] .install-pane__cmd {
3444
- background: var(--color-paper);
3445
- border-color: var(--color-rule);
3446
- }
3447
- [data-theme="quiet"] .install-pane__prompt {
3448
- color: var(--color-muted);
3449
- }
3450
-
3451
- /* The "without/with" demo on Quiet — soft, monochrome panels. */
3452
- [data-theme="quiet"] .vs__panel[data-variant="hallmark"] {
3453
- border-left-color: var(--color-rule-2);
3454
- border-color: var(--color-rule);
3455
- }
3456
-
3457
- /* No reveal animation on Quiet — the page is intentionally still. */
3458
- [data-theme="quiet"] .hero,
3459
- [data-theme="quiet"] .hero > * {
3460
- animation: none !important;
3461
- }
3462
-
3463
- /* ───────────── BLOOM — atmospheric dark, warm bloom ─────────────
3464
- Suno-school: dark canvas with two soft radial colour blooms behind
3465
- the content, confident sans display, single warm accent on small
3466
- surfaces, pill CTAs. Reads like an AI-creative product page. */
3467
-
3468
- html[data-theme="bloom"] {
3469
- background: var(--color-paper);
3470
- }
3471
-
3472
- html[data-theme="bloom"] body {
3473
- background:
3474
- radial-gradient(ellipse 80% 60% at 90% 0%,
3475
- color-mix(in oklch, var(--color-accent) 18%, transparent) 0%,
3476
- transparent 55%),
3477
- radial-gradient(ellipse 70% 55% at 5% 95%,
3478
- color-mix(in oklch, var(--color-accent-2) 16%, transparent) 0%,
3479
- transparent 55%),
3480
- var(--color-paper);
3481
- background-attachment: fixed;
3482
- min-height: 100dvh;
3483
- }
3484
-
3485
- [data-theme="bloom"] .hero__display,
3486
- [data-theme="bloom"] .hero__quote p,
3487
- [data-theme="bloom"] .hero__stat,
3488
- [data-theme="bloom"] .section__title,
3489
- [data-theme="bloom"] .foot__wordmark,
3490
- [data-theme="bloom"] .spec__name,
3491
- [data-theme="bloom"] .ex-card__name,
3492
- [data-theme="bloom"] .harness__name {
3493
- font-family: var(--font-display);
3494
- font-weight: 600;
3495
- font-style: normal;
3496
- text-transform: none;
3497
- letter-spacing: -0.03em;
3498
- text-shadow: none;
3499
- }
3500
-
3501
- /* Bloom — hero centered, every other section left-aligned. */
3502
- [data-theme="bloom"] .hero--marquee {
3503
- text-align: center;
3504
- justify-items: center;
3505
- }
3506
- [data-theme="bloom"] .hero--marquee .hero__display,
3507
- [data-theme="bloom"] .hero--marquee .hero__lede {
3508
- margin-inline: auto;
3509
- }
3510
- [data-theme="bloom"] .hero--marquee .hero__cta {
3511
- justify-self: center;
3512
- }
3513
-
3514
- [data-theme="bloom"] .hero__lede,
3515
- [data-theme="bloom"] .hero__letter-body,
3516
- [data-theme="bloom"] .spec__rule,
3517
- [data-theme="bloom"] .foot__tagline,
3518
- [data-theme="bloom"] .install-pane__next,
3519
- [data-theme="bloom"] .ex-card__brief {
3520
- font-family: var(--font-body);
3521
- font-style: normal;
3522
- color: var(--color-ink-2);
3523
- }
3524
-
3525
- [data-theme="bloom"] .hero__salutation {
3526
- font-family: var(--font-display);
3527
- font-weight: 600;
3528
- font-size: var(--text-2xl);
3529
- letter-spacing: -0.025em;
3530
- font-style: normal;
3531
- }
3532
-
3533
- /* Bloom's hero — centered, generous, with a glow behind the type. */
3534
- [data-theme="bloom"] .hero--marquee {
3535
- text-align: center;
3536
- align-items: center;
3537
- justify-items: center;
3538
- padding-block: var(--space-3xl) var(--space-2xl);
3539
- }
3540
-
3541
- [data-theme="bloom"] .hero--marquee .hero__display {
3542
- margin-inline: auto;
3543
- max-width: 22ch;
3544
- }
3545
-
3546
- [data-theme="bloom"] .hero--marquee .hero__lede {
3547
- margin-inline: auto;
3548
- text-align: center;
3549
- max-width: 52ch;
3550
- }
3551
-
3552
- [data-theme="bloom"] .hero__eyebrow {
3553
- margin-inline: auto;
3554
- justify-content: center;
3555
- }
3556
-
3557
- [data-theme="bloom"] .hero--marquee .hero__cta {
3558
- margin-inline: auto;
3559
- justify-self: center;
3560
- }
3561
-
3562
- /* Bloom — left-aligned section heads (hero stays centered above). The
3563
- atmospheric glow does the centering work — re-centering section heads
3564
- reads as a templated AI fingerprint. Tag stays above the title in the
3565
- same column (matches slop-test gate 66). */
3566
- [data-theme="bloom"] .section__head {
3567
- grid-template-columns: 1fr;
3568
- text-align: left;
3569
- border-bottom: 0;
3570
- padding-bottom: var(--space-md);
3571
- }
3572
- [data-theme="bloom"] .section-label {
3573
- justify-content: flex-start;
3574
- }
3575
- [data-theme="bloom"] .section__title {
3576
- margin-inline: 0;
3577
- max-width: 26ch;
3578
- }
3579
-
3580
- /* Bloom's banner — tinted dark glass over the canvas. */
3581
- [data-theme="bloom"] .banner {
3582
- background: color-mix(in oklch, var(--color-paper) 70%, transparent);
3583
- border-block-end-color: var(--color-rule);
3584
- }
3585
- [data-theme="bloom"] .banner__center {
3586
- font-family: var(--font-display);
3587
- font-weight: 500;
3588
- font-size: 0.875rem;
3589
- letter-spacing: -0.005em;
3590
- text-transform: none;
3591
- }
3592
-
3593
- /* Bloom's install command bar — feels like a Suno input field. */
3594
- [data-theme="bloom"] .install-pane {
3595
- background: var(--color-paper-2);
3596
- border-color: var(--color-rule);
3597
- }
3598
- [data-theme="bloom"] .install-pane__cmd {
3599
- background: var(--color-paper-3);
3600
- border-color: var(--color-rule);
3601
- }
3602
- [data-theme="bloom"] .install-pane__copy {
3603
- background: var(--color-accent);
3604
- color: var(--color-paper);
3605
- border-color: var(--color-accent);
3606
- border-radius: 999px;
3607
- font-weight: 600;
3608
- text-transform: uppercase;
3609
- }
3610
- [data-theme="bloom"] .install-pane__copy:hover {
3611
- background: color-mix(in oklch, var(--color-accent) 88%, var(--color-paper));
3612
- color: var(--color-paper);
3613
- border-color: transparent;
3614
- }
3615
-
3616
- /* Bloom's example rail tiles — elevated cards floating on the canvas. */
3617
- [data-theme="bloom"] .ex-card {
3618
- background: var(--color-paper-2);
3619
- border-color: var(--color-rule);
3620
- }
3621
-
3622
- /* Without/With on Bloom — the slop panel still uses the white-AI
3623
- look against the dark canvas, which actually demonstrates "the AI
3624
- reaches for the same generic page even on a dark site." */
3625
- [data-theme="bloom"] .vs__panel[data-variant="hallmark"] {
3626
- background: var(--color-paper-2);
3627
- border-left-color: var(--color-accent);
3628
- border-color: var(--color-rule);
3629
- }
3630
-
3631
- /* Bloom's reveal — fade only, no slide. The atmosphere does the work. */
3632
- [data-theme="bloom"] .reveal { transform: none; }
3633
- [data-theme="bloom"] .reveal.is-in {
3634
- animation: reveal-fade calc(var(--dur-long) * 1.2) var(--ease-out) forwards;
3635
- animation-delay: calc(var(--i, 0) * 70ms);
3636
- }
3637
-
3638
- /* ───────────── CORAL — modern-minimal · Stripe-not-Linear ─────────────
3639
- Inherits the Quiet "polished minimal" structure but with a warm-grey
3640
- paper and a coral accent on focus rings + small marks. */
3641
-
3642
- [data-theme="coral"] .reveal,
3643
- [data-theme="coral"] .reveal.is-in,
3644
- [data-theme="coral"] .slot[data-populating] > * {
3645
- opacity: 1;
3646
- transform: none;
3647
- animation: none;
3648
- }
3649
-
3650
- [data-theme="coral"] .hero__display,
3651
- [data-theme="coral"] .hero__quote p,
3652
- [data-theme="coral"] .hero__stat,
3653
- [data-theme="coral"] .section__title,
3654
- [data-theme="coral"] .foot__wordmark,
3655
- [data-theme="coral"] .spec__name,
3656
- [data-theme="coral"] .ex-card__name,
3657
- [data-theme="coral"] .harness__name {
3658
- font-family: var(--font-display);
3659
- font-weight: 600;
3660
- font-style: normal;
3661
- letter-spacing: -0.025em;
3662
- }
3663
-
3664
-
3665
- [data-theme="coral"] .install-pane__copy {
3666
- background: var(--color-ink);
3667
- color: var(--color-paper);
3668
- border-color: var(--color-ink);
3669
- border-radius: 999px;
3670
- }
3671
-
3672
- /* ───────────── VIOLET — modern-minimal · Linear voice ─────────────
3673
- Tighter typographic feel than Coral. Near-white paper, near-black
3674
- ink, single quiet violet accent on focus + small marks. */
3675
-
3676
- [data-theme="violet"] .reveal,
3677
- [data-theme="violet"] .reveal.is-in,
3678
- [data-theme="violet"] .slot[data-populating] > * {
3679
- opacity: 1;
3680
- transform: none;
3681
- animation: none;
3682
- }
3683
-
3684
-
3685
- [data-theme="violet"] .hero__display,
3686
- [data-theme="violet"] .hero__quote p,
3687
- [data-theme="violet"] .hero__stat,
3688
- [data-theme="violet"] .section__title,
3689
- [data-theme="violet"] .foot__wordmark,
3690
- [data-theme="violet"] .spec__name,
3691
- [data-theme="violet"] .ex-card__name,
3692
- [data-theme="violet"] .harness__name {
3693
- font-family: var(--font-display);
3694
- font-weight: 600;
3695
- font-style: normal;
3696
- letter-spacing: -0.035em;
3697
- }
3698
-
3699
- [data-theme="violet"] .install-pane__copy {
3700
- background: var(--color-ink);
3701
- color: var(--color-paper);
3702
- border-color: var(--color-ink);
3703
- border-radius: 999px;
3704
- }
3705
-
3706
- /* ───────────── AURORA — atmospheric · cool blue-green dark ─────────────
3707
- Two cool blooms behind the content (cyan top-right, teal-green
3708
- bottom-left). Sentient body for warmth. */
3709
-
3710
- html[data-theme="aurora"] {
3711
- background: var(--color-paper);
3712
- }
3713
-
3714
- html[data-theme="aurora"] body {
3715
- background:
3716
- radial-gradient(ellipse 75% 55% at 92% 0%,
3717
- color-mix(in oklch, var(--color-accent) 28%, transparent) 0%,
3718
- transparent 55%),
3719
- radial-gradient(ellipse 70% 60% at 5% 100%,
3720
- color-mix(in oklch, var(--color-accent-2) 30%, transparent) 0%,
3721
- transparent 60%),
3722
- var(--color-paper);
3723
- background-attachment: fixed;
3724
- min-height: 100dvh;
3725
- }
3726
-
3727
- /* Aurora — soft accent bloom punctuates each section title (not just the
3728
- hero). Adds rhythm without competing with the hero's bigger glow. */
3729
- [data-theme="aurora"] .section {
3730
- position: relative;
3731
- }
3732
- [data-theme="aurora"] .section > .section__head::after {
3733
- content: "";
3734
- position: absolute;
3735
- inset-inline-start: -8%;
3736
- inset-block-start: -2rem;
3737
- width: 22rem;
3738
- height: 22rem;
3739
- background:
3740
- radial-gradient(circle at 50% 50%,
3741
- color-mix(in oklch, var(--color-accent) 14%, transparent) 0%,
3742
- transparent 65%);
3743
- pointer-events: none;
3744
- z-index: -1;
3745
- filter: blur(6px);
3746
- }
3747
-
3748
- [data-theme="aurora"] .hero__display,
3749
- [data-theme="aurora"] .hero__quote p,
3750
- [data-theme="aurora"] .hero__stat,
3751
- [data-theme="aurora"] .section__title,
3752
- [data-theme="aurora"] .foot__wordmark,
3753
- [data-theme="aurora"] .spec__name,
3754
- [data-theme="aurora"] .ex-card__name,
3755
- [data-theme="aurora"] .harness__name {
3756
- font-family: var(--font-display);
3757
- font-weight: 600;
3758
- letter-spacing: -0.03em;
3759
- }
3760
-
3761
- [data-theme="aurora"] .hero__lede,
3762
- [data-theme="aurora"] .install-pane__next,
3763
- [data-theme="aurora"] .ex-card__brief {
3764
- font-family: var(--font-body);
3765
- font-style: normal;
3766
- color: var(--color-ink-2);
3767
- }
3768
-
3769
- [data-theme="aurora"] .banner {
3770
- background: color-mix(in oklch, var(--color-paper) 68%, transparent);
3771
- border-block-end-color: var(--color-rule);
3772
- }
3773
-
3774
- [data-theme="aurora"] .reveal { transform: none; }
3775
- [data-theme="aurora"] .reveal.is-in {
3776
- animation: reveal-fade calc(var(--dur-long) * 1.2) var(--ease-out) forwards;
3777
- animation-delay: calc(var(--i, 0) * 70ms);
3778
- }
3779
-
3780
- [data-theme="aurora"] .ex-card,
3781
- [data-theme="aurora"] .install-pane,
3782
- [data-theme="aurora"] .vs__panel[data-variant="hallmark"] {
3783
- background: var(--color-paper-2);
3784
- }
3785
-
3786
- [data-theme="aurora"] .install-pane__copy {
3787
- background: var(--color-accent);
3788
- color: var(--color-paper);
3789
- border-color: var(--color-accent);
3790
- border-radius: 999px;
3791
- }
3792
-
3793
- /* ───────────── HALO — atmospheric · hero-only amber bloom ─────────────
3794
- The bloom is a single moment near the top. Below the hero the page
3795
- is content-led on charcoal — less Suno, more "tool you actually
3796
- work in." Implemented as a fixed-position pseudo-element clipped
3797
- to the top ~80vh. */
3798
-
3799
- html[data-theme="halo"] {
3800
- background: var(--color-paper);
3801
- }
3802
-
3803
- html[data-theme="halo"] body {
3804
- position: relative;
3805
- background: var(--color-paper);
3806
- min-height: 100dvh;
3807
- }
3808
-
3809
- html[data-theme="halo"] body::before {
3810
- content: "";
3811
- position: fixed;
3812
- inset: 0 0 auto 0;
3813
- height: 80vh;
3814
- pointer-events: none;
3815
- z-index: 0;
3816
- background:
3817
- radial-gradient(ellipse 60% 80% at 70% 0%,
3818
- color-mix(in oklch, var(--color-accent) 22%, transparent) 0%,
3819
- transparent 60%);
3820
- opacity: 1;
3821
- }
3822
-
3823
- /* Lift content above the halo body::before glow.
3824
- Banner is excluded so it keeps its sticky z-index (200) — the
3825
- theme-dropdown lives inside .banner and needs that elevation
3826
- to render above the orbit + glow layers below. */
3827
- html[data-theme="halo"] main,
3828
- html[data-theme="halo"] .easter,
3829
- html[data-theme="halo"] aside {
3830
- position: relative;
3831
- z-index: 1;
3832
- }
3833
-
3834
- [data-theme="halo"] .hero__display,
3835
- [data-theme="halo"] .hero__quote p,
3836
- [data-theme="halo"] .hero__stat,
3837
- [data-theme="halo"] .section__title,
3838
- [data-theme="halo"] .foot__wordmark,
3839
- [data-theme="halo"] .spec__name,
3840
- [data-theme="halo"] .ex-card__name,
3841
- [data-theme="halo"] .harness__name {
3842
- font-family: var(--font-display);
3843
- font-weight: 600;
3844
- letter-spacing: -0.025em;
3845
- }
3846
-
3847
- [data-theme="halo"] .banner {
3848
- background: color-mix(in oklch, var(--color-paper) 72%, transparent);
3849
- border-block-end-color: var(--color-rule);
3850
- }
3851
-
3852
- [data-theme="halo"] .ex-card,
3853
- [data-theme="halo"] .install-pane,
3854
- [data-theme="halo"] .vs__panel[data-variant="hallmark"] {
3855
- background: var(--color-paper-2);
3856
- }
3857
-
3858
- [data-theme="halo"] .reveal { transform: none; }
3859
- [data-theme="halo"] .reveal.is-in {
3860
- animation: reveal-fade calc(var(--dur-long) * 1.1) var(--ease-out) forwards;
3861
- animation-delay: calc(var(--i, 0) * 60ms);
3862
- }
3863
-
3864
- /* ───────────── PLUME — playful · warm cream + tinted bands ─────────────
3865
- Alternating section backgrounds (paper vs paper-2), hover-lift on
3866
- cards, soft drop shadows, friendly motion — the playful canon. */
3867
-
3868
- /* Hero only — drop the right-side bloom stage and centre the copy.
3869
- The rest of the page keeps its asymmetric rhythm; only the hero
3870
- reads as a centred lede. */
3871
- [data-theme="plume"] .hero--bloom {
3872
- grid-template-columns: 1fr;
3873
- justify-items: center;
3874
- text-align: center;
3875
- padding-block: var(--space-3xl) var(--space-2xl);
3876
- }
3877
- [data-theme="plume"] .hero--bloom .hero__bloom-stage { display: none; }
3878
- [data-theme="plume"] .hero--bloom .hero__copy {
3879
- justify-items: center;
3880
- align-items: center;
3881
- }
3882
- [data-theme="plume"] .hero--bloom .hero__display,
3883
- [data-theme="plume"] .hero--bloom .hero__lede {
3884
- margin-inline: auto;
3885
- }
3886
- [data-theme="plume"] .hero--bloom .hero__cta-row,
3887
- [data-theme="plume"] .hero--bloom .hero__eyebrow,
3888
- [data-theme="plume"] .hero--bloom .hero__proof {
3889
- justify-content: center;
3890
- }
3891
-
3892
- [data-theme="plume"] .page > .section:nth-child(even) {
3893
- background: var(--color-paper-2);
3894
- margin-inline: calc(-1 * var(--page-gutter));
3895
- padding-inline: var(--page-gutter);
3896
- padding-block: var(--space-2xl);
3897
- border-radius: 0;
3898
- }
3899
-
3900
- [data-theme="plume"] .hero__display,
3901
- [data-theme="plume"] .hero__quote p,
3902
- [data-theme="plume"] .hero__stat,
3903
- [data-theme="plume"] .section__title,
3904
- [data-theme="plume"] .foot__wordmark,
3905
- [data-theme="plume"] .spec__name,
3906
- [data-theme="plume"] .ex-card__name,
3907
- [data-theme="plume"] .harness__name {
3908
- font-family: var(--font-display);
3909
- font-weight: 700;
3910
- letter-spacing: -0.025em;
3911
- }
3912
-
3913
- [data-theme="plume"] .hero__lede,
3914
- [data-theme="plume"] .ex-card__brief,
3915
- [data-theme="plume"] .install-pane__next,
3916
- [data-theme="plume"] .spec__rule,
3917
- [data-theme="plume"] .foot__tagline {
3918
- font-family: var(--font-body);
3919
- font-style: normal;
3920
- }
3921
-
3922
- [data-theme="plume"] .ex-card,
3923
- [data-theme="plume"] .install-pane,
3924
- [data-theme="plume"] .vs__panel[data-variant="hallmark"] {
3925
- background: var(--color-paper);
3926
- border-color: var(--color-rule-2);
3927
- }
3928
-
3929
- [data-theme="plume"] .install-pane__copy {
3930
- background: var(--color-accent);
3931
- color: var(--color-paper);
3932
- border-color: var(--color-accent);
3933
- border-radius: 999px;
3934
- }
3935
-
3936
- /* ───────────── EXAMPLES RAIL — TILES ─────────────
3937
- Each tile in the horizontal scroll-snap rail. Cards inherit the
3938
- active theme's --radius-card, --rule-card, and --shadow-card so
3939
- switching themes restyles them along with everything else. */
3940
- .ex-card {
3941
- flex: 0 0 clamp(32rem, 60vw, 44rem);
3942
- scroll-snap-align: start;
3943
- display: grid;
3944
- grid-template-rows: auto auto;
3945
- min-width: 0;
3946
- color: inherit;
3947
- /* When the card is rendered as <a>, strip the default link underline so
3948
- the card surface reads as a card, not as linked text. */
3949
- text-decoration: none;
3950
- background: var(--color-paper);
3951
- border: var(--rule-card, 1px) solid var(--color-rule);
3952
- border-radius: var(--radius-card, 0);
3953
- box-shadow: var(--shadow-card, none);
3954
- overflow: hidden;
3955
- position: relative;
3956
- }
3957
-
3958
- @media (max-width: 60rem) {
3959
- .ex-card { flex-basis: 26rem; }
3960
- }
3961
-
3962
- @media (max-width: 36rem) {
3963
- .ex-card { flex-basis: 84vw; }
3964
- }
3965
-
3966
- .ex-card:focus-visible {
3967
- outline: 2px solid var(--color-focus);
3968
- outline-offset: 3px;
3969
- }
3970
-
3971
- .ex-card__thumb {
3972
- display: block;
3973
- width: 100%;
3974
- aspect-ratio: 16 / 10;
3975
- background: var(--color-paper-2);
3976
- border-block-end: var(--rule-card, 1px) solid var(--color-rule);
3977
- overflow: hidden;
3978
- font-size: 0;
3979
- }
3980
-
3981
- .ex-card__thumb img,
3982
- .ex-card__thumb video {
3983
- display: block;
3984
- width: 100%;
3985
- height: 100%;
3986
- object-fit: cover;
3987
- object-position: top left;
3988
- }
3989
-
3990
- @media (prefers-reduced-motion: reduce) {
3991
- .ex-card__thumb video { animation-play-state: paused; }
3992
- .ex-card__thumb img,
3993
- .ex-card__thumb video { transition: none; }
3994
- }
3995
-
3996
- /* New card meta — single-line prompt only, mono. The card is the prompt
3997
- that produced the output above it. */
3998
- .ex-card__prompt {
3999
- margin: 0;
4000
- padding: var(--space-sm) var(--space-lg);
4001
- font-family: var(--font-mono);
4002
- font-size: var(--text-sm);
4003
- color: var(--color-ink-2);
4004
- line-height: 1.4;
4005
- white-space: nowrap;
4006
- overflow: hidden;
4007
- text-overflow: ellipsis;
4008
- font-feature-settings: "tnum";
4009
- }
4010
-
4011
- .ex-card__prompt-mark {
4012
- color: var(--color-accent);
4013
- margin-inline-end: 0.4em;
4014
- font-weight: 500;
4015
- }
4016
-
4017
- /* — Study gallery card ————————————————————————————————
4018
- Each card pairs a video-shaped media tile with a structured DNA
4019
- panel below it. The video uses poster as the static fallback when
4020
- no <source> is supplied — drop one in to enable playback. The DNA
4021
- panel renders as an editorial table: mono numeral key, body value,
4022
- hairline divider per row. Theme-adaptive throughout. */
4023
- .study-card {
4024
- display: grid;
4025
- gap: var(--space-md);
4026
- background: var(--color-paper);
4027
- border: var(--rule-card, 1px) solid var(--color-rule);
4028
- border-radius: var(--radius-card, 0);
4029
- box-shadow: var(--shadow-card, none);
4030
- overflow: hidden;
4031
- transition: border-color var(--dur-micro) var(--ease-out);
4032
- }
4033
-
4034
- @media (hover: hover) and (pointer: fine) {
4035
- .study-card:hover { border-color: var(--color-rule-2); }
4036
- }
4037
-
4038
- .study-card[data-user-content] {
4039
- border-style: dashed;
4040
- }
4041
-
4042
- .study-card__media {
4043
- position: relative;
4044
- aspect-ratio: 16 / 7;
4045
- background: var(--color-paper-2);
4046
- border-block-end: var(--rule-card, 1px) solid var(--color-rule);
4047
- overflow: hidden;
4048
- }
4049
-
4050
- .study-card__img,
4051
- .study-card__video {
4052
- display: block;
4053
- width: 100%;
4054
- height: 100%;
4055
- object-fit: cover;
4056
- object-position: top left;
4057
- background: var(--color-paper-2);
4058
- }
4059
-
4060
- .study-card__badge {
4061
- position: absolute;
4062
- bottom: var(--space-sm);
4063
- left: var(--space-sm);
4064
- padding: 0.25rem 0.55rem;
4065
- font-family: var(--font-label);
4066
- font-size: 0.625rem;
4067
- letter-spacing: var(--tracking-label);
4068
- text-transform: uppercase;
4069
- color: var(--color-paper);
4070
- background: color-mix(in oklch, var(--color-ink) 85%, transparent);
4071
- backdrop-filter: blur(4px);
4072
- -webkit-backdrop-filter: blur(4px);
4073
- font-feature-settings: "tnum";
4074
- }
4075
-
4076
- .study-card[data-user-content] .study-card__badge {
4077
- background: color-mix(in oklch, var(--color-accent) 80%, transparent);
4078
- }
4079
-
4080
- [data-theme="riso"] .study-card__badge,
4081
- [data-theme="brutal"] .study-card__badge,
4082
- [data-theme="manifesto"] .study-card__badge,
4083
- [data-theme="sport"] .study-card__badge { text-transform: uppercase; }
4084
-
4085
- [data-theme="riso"] .study-card__badge { text-transform: lowercase; }
4086
-
4087
- /* DNA panel — structured 10-field key/value table. Tightened vertical
4088
- rhythm so the study card doesn't dominate the page: panel padding
4089
- one step lighter, per-row padding-block reduced from sm → xs. */
4090
- .study-card__dna {
4091
- list-style: none;
4092
- margin: 0;
4093
- padding: var(--space-sm) var(--space-md) var(--space-md);
4094
- display: grid;
4095
- gap: 0;
4096
- }
4097
-
4098
- .study-card__dna .dna__row {
4099
- padding-block: var(--space-xs);
4100
- }
4101
-
4102
- .dna__row {
4103
- display: grid;
4104
- grid-template-columns: 8.5rem 1fr;
4105
- gap: var(--space-sm);
4106
- align-items: baseline;
4107
- padding-block: var(--space-sm);
4108
- border-block-end: var(--rule-hair) solid var(--color-rule);
4109
- }
4110
-
4111
- .dna__row:last-child { border-block-end: 0; }
4112
-
4113
- @media (max-width: 36rem) {
4114
- .dna__row { grid-template-columns: 1fr; gap: 0.15rem; padding-block: var(--space-xs); }
4115
- }
4116
-
4117
- .dna__k {
4118
- font-family: var(--font-label);
4119
- font-size: var(--text-xs);
4120
- letter-spacing: var(--tracking-label);
4121
- text-transform: uppercase;
4122
- color: var(--color-muted);
4123
- font-feature-settings: "tnum";
4124
- }
4125
-
4126
- .dna__v {
4127
- font-family: var(--font-mono);
4128
- font-size: 0.8125rem;
4129
- line-height: 1.45;
4130
- color: var(--color-ink);
4131
- letter-spacing: 0;
4132
- }
4133
-
4134
- .study-card[data-user-content] .dna__v {
4135
- color: var(--color-rule-2);
4136
- }
4137
-
4138
- [data-theme="brutal"] .study-card,
4139
- [data-theme="manifesto"] .study-card { border-width: 2px; }
4140
-
4141
- [data-theme="atelier"] .study-card,
4142
- [data-theme="salon"] .study-card {
4143
- border: 0;
4144
- background: transparent;
4145
- box-shadow: none;
4146
- border-block-end: var(--rule-hair) solid var(--color-rule);
4147
- border-radius: 0;
4148
- }
4149
-
4150
- [data-theme="atelier"] .study-card__media,
4151
- [data-theme="salon"] .study-card__media {
4152
- border-block-end: 0;
4153
- }
4154
-
4155
-
4156
- /* ───────────── FOUNDATION VIZ — illustrations ─────────────
4157
- Eight different visual demos, one per spec card. Each one prefers
4158
- real demonstration over decoration: real type for F/01, real space
4159
- ratio for F/02, real motion for F/04, real states for F/05. */
4160
-
4161
- .spec__viz {
4162
- display: grid;
4163
- gap: var(--space-md);
4164
- margin-block-start: var(--space-sm);
4165
- }
4166
-
4167
- /* F/01 Type — three real specimens, baseline-aligned. */
4168
- .spec__viz--type {
4169
- gap: var(--space-md);
4170
- }
4171
-
4172
- .spec__viz-row {
4173
- display: flex;
4174
- align-items: baseline;
4175
- justify-content: space-between;
4176
- gap: var(--space-md);
4177
- padding-block: var(--space-xs);
4178
- border-block-end: var(--rule-hair) solid var(--color-rule);
4179
- transition: padding-inline-start 220ms var(--ease-out);
4180
- }
4181
-
4182
- .spec__viz-row > span {
4183
- flex: 0 1 auto;
4184
- color: var(--color-ink);
4185
- line-height: 1;
4186
- }
4187
-
4188
- .spec__viz-row--display > span {
4189
- font-family: var(--font-serif);
4190
- font-style: italic;
4191
- font-weight: 400;
4192
- font-size: clamp(2rem, 4vw, 2.75rem);
4193
- letter-spacing: -0.02em;
4194
- }
4195
-
4196
- .spec__viz-row--body > span {
4197
- font-family: var(--font-body);
4198
- font-weight: 300;
4199
- font-size: 1.5rem;
4200
- letter-spacing: -0.005em;
4201
- }
4202
-
4203
- .spec__viz-row--mono > span {
4204
- font-family: var(--font-mono);
4205
- font-weight: 500;
4206
- font-size: 1.2rem;
4207
- letter-spacing: 0;
4208
- }
4209
-
4210
- @media (hover: hover) and (pointer: fine) {
4211
- .spec__viz-row:hover {
4212
- padding-inline-start: var(--space-md);
4213
- }
4214
- }
4215
-
4216
- .spec__viz-tag {
4217
- font-family: var(--font-label);
4218
- font-style: normal;
4219
- font-size: var(--text-xs);
4220
- letter-spacing: var(--tracking-label);
4221
- text-transform: uppercase;
4222
- color: var(--color-muted);
4223
- flex: 0 0 auto;
4224
- }
4225
-
4226
- /* F/02 Colour — accent dot in a paper field, then small swatches. */
4227
- .spec__viz--colour {
4228
- position: relative;
4229
- aspect-ratio: 4 / 1;
4230
- background: var(--color-paper-2);
4231
- border: var(--rule-hair) solid var(--color-rule);
4232
- display: block;
4233
- padding: 0;
4234
- margin-block-end: var(--space-sm);
4235
- }
4236
-
4237
- .spec__viz-dot {
4238
- position: absolute;
4239
- top: 28%;
4240
- left: 22%;
4241
- width: 14px;
4242
- height: 14px;
4243
- background: var(--color-accent);
4244
- border-radius: 50%;
4245
- }
4246
-
4247
- .spec__viz-caption {
4248
- position: absolute;
4249
- right: var(--space-md);
4250
- bottom: var(--space-sm);
4251
- margin: 0;
4252
- font-family: var(--font-label);
4253
- font-size: var(--text-xs);
4254
- letter-spacing: var(--tracking-label);
4255
- text-transform: uppercase;
4256
- color: var(--color-muted);
4257
- max-width: 22ch;
4258
- text-align: right;
4259
- line-height: 1.4;
4260
- }
4261
-
4262
- .spec__viz-swatches {
4263
- height: 2rem;
4264
- }
4265
-
4266
- /* F/03 Space — symmetric (greyed) vs asymmetric (ink). */
4267
- .spec__viz--space {
4268
- display: grid;
4269
- grid-template-columns: 1fr 1fr;
4270
- gap: var(--space-md);
4271
- height: 5rem;
4272
- align-items: end;
4273
- }
4274
-
4275
- .spec__viz-grid {
4276
- display: flex;
4277
- align-items: end;
4278
- justify-content: center;
4279
- gap: 0.4rem;
4280
- height: 100%;
4281
- padding-inline: var(--space-sm);
4282
- border-block-end: var(--rule-hair) solid var(--color-rule);
4283
- }
4284
-
4285
- .spec__viz-grid--bad .vg-bar { background: var(--color-rule-2); }
4286
- .spec__viz-grid--good { justify-content: flex-start; gap: 0.55rem; }
4287
- .spec__viz-grid--good .vg-bar { background: var(--color-ink); }
4288
-
4289
- .vg-bar { width: 8px; }
4290
- .vg-bar--xl { height: 88%; }
4291
- .vg-bar--md { height: 56%; }
4292
- .vg-bar--sm { height: 30%; }
4293
-
4294
- .spec__viz-pair {
4295
- display: grid;
4296
- grid-template-columns: 1fr 1fr;
4297
- gap: var(--space-md);
4298
- margin: 0;
4299
- font-family: var(--font-label);
4300
- font-size: var(--text-xs);
4301
- letter-spacing: var(--tracking-label);
4302
- text-transform: uppercase;
4303
- color: var(--color-muted);
4304
- text-align: center;
4305
- }
4306
-
4307
- /* F/04 Motion — a real fade+slide on click/hover. */
4308
- .spec__viz--motion {
4309
- display: grid;
4310
- grid-template-columns: auto 1fr;
4311
- gap: var(--space-md);
4312
- align-items: center;
4313
- }
4314
-
4315
- .spec__viz-play {
4316
- appearance: none;
4317
- display: inline-flex;
4318
- align-items: center;
4319
- gap: 0.5rem;
4320
- padding: 0.45rem 0.85rem;
4321
- background: transparent;
4322
- border: var(--rule-hair) solid var(--color-rule);
4323
- font-family: var(--font-label);
4324
- font-size: var(--text-xs);
4325
- letter-spacing: var(--tracking-label);
4326
- text-transform: uppercase;
4327
- color: var(--color-ink);
4328
- cursor: pointer;
4329
- min-height: 32px;
4330
- transition: border-color var(--dur-micro) var(--ease-out),
4331
- background-color var(--dur-micro) var(--ease-out);
4332
- }
4333
-
4334
- .spec__viz-play:hover { border-color: var(--color-ink); }
4335
- .spec__viz-play:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
4336
-
4337
- .spec__viz-play-icon {
4338
- width: 0;
4339
- height: 0;
4340
- border-style: solid;
4341
- border-width: 5px 0 5px 8px;
4342
- border-color: transparent transparent transparent currentColor;
4343
- display: inline-block;
4344
- }
4345
-
4346
- .spec__viz-stage {
4347
- position: relative;
4348
- height: 3rem;
4349
- background: var(--color-paper-2);
4350
- border: var(--rule-hair) dashed var(--color-rule);
4351
- overflow: hidden;
4352
- }
4353
-
4354
- .spec__viz-block {
4355
- position: absolute;
4356
- top: 50%;
4357
- left: 12%;
4358
- width: 32px;
4359
- height: 32px;
4360
- background: var(--color-accent);
4361
- transform: translate(-12px, -50%);
4362
- opacity: 0;
4363
- }
4364
-
4365
- .spec__viz-block.is-running {
4366
- animation: spec-motion-demo 420ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
4367
- }
4368
-
4369
- @keyframes spec-motion-demo {
4370
- from { transform: translate(-12px, -50%); opacity: 0; }
4371
- to { transform: translate(160px, -50%); opacity: 1; }
4372
- }
4373
-
4374
- @media (prefers-reduced-motion: reduce) {
4375
- .spec__viz-block.is-running {
4376
- animation: none;
4377
- transform: translate(160px, -50%);
4378
- opacity: 1;
4379
- }
4380
- }
4381
-
4382
- /* F/05 States — a real interactive button that reports its own state. */
4383
- .spec__viz--states {
4384
- display: grid;
4385
- gap: var(--space-sm);
4386
- }
4387
-
4388
- .spec__viz-button {
4389
- appearance: none;
4390
- display: inline-flex;
4391
- align-items: center;
4392
- justify-content: center;
4393
- min-height: 44px;
4394
- padding: var(--space-sm) var(--space-lg);
4395
- font-family: var(--font-label);
4396
- font-size: var(--text-sm);
4397
- letter-spacing: 0.04em;
4398
- background: transparent;
4399
- border: var(--rule-fine) solid var(--color-ink);
4400
- color: var(--color-ink);
4401
- cursor: pointer;
4402
- transition: background-color 120ms var(--ease-out),
4403
- color 120ms var(--ease-out),
4404
- transform 80ms var(--ease-out);
4405
- align-self: start;
4406
- justify-self: start;
4407
- }
4408
-
4409
- .spec__viz-button:hover { background: var(--color-paper-3); }
4410
- .spec__viz-button:active { transform: translateY(1px); }
4411
- .spec__viz-button:focus-visible {
4412
- outline: 2px solid var(--color-focus);
4413
- outline-offset: 2px;
4414
- }
4415
- .spec__viz-button[data-state="loading"] {
4416
- background: var(--color-paper-2);
4417
- color: var(--color-muted);
4418
- cursor: wait;
4419
- }
4420
-
4421
- .spec__viz-state-readout {
4422
- margin: 0;
4423
- font-family: var(--font-mono);
4424
- font-size: var(--text-xs);
4425
- letter-spacing: 0.02em;
4426
- color: var(--color-muted);
4427
- }
4428
-
4429
- .spec__viz-state-readout::before {
4430
- content: "→ state: ";
4431
- color: var(--color-rule-2);
4432
- }
4433
-
4434
- /* F/06 Responsive — three frames showing same content reflowing. */
4435
- .spec__viz--responsive {
4436
- display: grid;
4437
- grid-template-columns: 1fr 1.6fr 2.4fr;
4438
- gap: var(--space-md);
4439
- align-items: end;
4440
- height: 5rem;
4441
- }
4442
-
4443
- .vg-frame {
4444
- display: flex;
4445
- flex-direction: column;
4446
- gap: 4px;
4447
- padding: 8px;
4448
- background: var(--color-paper-2);
4449
- border: var(--rule-hair) solid var(--color-rule);
4450
- height: 100%;
4451
- justify-content: flex-start;
4452
- }
4453
-
4454
- .vg-line {
4455
- height: 4px;
4456
- background: var(--color-rule-2);
4457
- border-radius: 1px;
4458
- width: 100%;
4459
- }
4460
-
4461
- .vg-line--head {
4462
- background: var(--color-ink);
4463
- height: 6px;
4464
- width: 70%;
4465
- }
4466
-
4467
- .vg-line--short { width: 40%; }
4468
-
4469
- /* F/07 Copy — bad vs good column comparison. */
4470
- .spec__viz--copy {
4471
- display: grid;
4472
- grid-template-columns: 1fr 1fr;
4473
- gap: var(--space-md);
4474
- }
4475
-
4476
- .spec__viz-copy-col {
4477
- display: grid;
4478
- gap: 0.4rem;
4479
- padding: var(--space-sm) var(--space-md);
4480
- border: var(--rule-hair) solid var(--color-rule);
4481
- background: var(--color-paper-2);
4482
- }
4483
-
4484
- .spec__viz-copy-col[data-variant="good"] {
4485
- border-color: var(--color-rule-2);
4486
- background: var(--color-paper);
4487
- }
4488
-
4489
- .spec__viz-copy-label {
4490
- margin: 0;
4491
- font-family: var(--font-label);
4492
- font-size: var(--text-xs);
4493
- letter-spacing: var(--tracking-label);
4494
- text-transform: uppercase;
4495
- color: var(--color-muted);
4496
- }
4497
-
4498
- .spec__viz-copy-col[data-variant="good"] .spec__viz-copy-label {
4499
- color: var(--color-accent);
4500
- }
4501
-
4502
- .spec__viz-copy-line {
4503
- margin: 0;
4504
- font-family: var(--font-body);
4505
- font-size: var(--text-sm);
4506
- line-height: 1.4;
4507
- }
4508
-
4509
- .spec__viz-copy-col[data-variant="bad"] .spec__viz-copy-line {
4510
- color: var(--color-muted);
4511
- text-decoration: line-through;
4512
- text-decoration-color: var(--color-rule-2);
4513
- text-decoration-thickness: 1px;
4514
- }
4515
-
4516
- .spec__viz-copy-col[data-variant="good"] .spec__viz-copy-line {
4517
- color: var(--color-ink);
4518
- }
4519
-
4520
- /* F/08 Anti-patterns — 9-tile mini-grid of the named tells. */
4521
- .spec__viz--tells {
4522
- display: grid;
4523
- grid-template-columns: repeat(9, 1fr);
4524
- gap: var(--space-2xs);
4525
- height: 4.5rem;
4526
- }
4527
-
4528
- @media (max-width: 50rem) {
4529
- .spec__viz--tells {
4530
- grid-template-columns: repeat(5, 1fr);
4531
- grid-auto-rows: 1fr;
4532
- height: auto;
4533
- }
4534
- }
4535
-
4536
- .vt {
4537
- display: block;
4538
- background: var(--color-paper-2);
4539
- border: var(--rule-hair) solid var(--color-rule);
4540
- position: relative;
4541
- overflow: hidden;
4542
- aspect-ratio: 1;
4543
- }
4544
-
4545
- .vt--purple {
4546
- background: linear-gradient(135deg, #6b4de0, #e04db4);
4547
- }
4548
-
4549
- .vt--gradtext {
4550
- background: var(--color-paper);
4551
- }
4552
- .vt--gradtext::after {
4553
- content: "Aa";
4554
- position: absolute;
4555
- inset: 0;
4556
- display: grid;
4557
- place-items: center;
4558
- font-family: "Inter", sans-serif;
4559
- font-weight: 800;
4560
- font-size: 1.2rem;
4561
- background: linear-gradient(90deg, #8a3fe0, #e03f8a);
4562
- -webkit-background-clip: text;
4563
- background-clip: text;
4564
- color: transparent;
4565
- }
4566
-
4567
- .vt--icontile {
4568
- background:
4569
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 0/100% 1px no-repeat,
4570
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 33.33% 0/1px 100% no-repeat,
4571
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 66.66% 0/1px 100% no-repeat,
4572
- var(--color-paper);
4573
- }
4574
-
4575
- .vt--centered {
4576
- background: var(--color-paper);
4577
- }
4578
- .vt--centered::after {
4579
- content: "";
4580
- position: absolute;
4581
- inset: 25% 30%;
4582
- background:
4583
- linear-gradient(var(--color-ink), var(--color-ink)) 0 0/100% 30% no-repeat,
4584
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 50%/100% 14% no-repeat,
4585
- linear-gradient(var(--color-accent), var(--color-accent)) 25% 80%/50% 14% no-repeat;
4586
- }
4587
-
4588
- .vt--glass {
4589
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(168, 85, 247, 0.15));
4590
- backdrop-filter: blur(2px);
4591
- border-color: rgba(255, 255, 255, 0.3);
4592
- }
4593
-
4594
- .vt--pill {
4595
- background: var(--color-paper);
4596
- }
4597
- .vt--pill::after {
4598
- content: "";
4599
- position: absolute;
4600
- inset: 38% 18%;
4601
- background: linear-gradient(90deg, #6366f1, #a855f7);
4602
- border-radius: 999px;
4603
- }
4604
-
4605
- .vt--bigfeat {
4606
- background:
4607
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 30%/30% 4px no-repeat,
4608
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 50%/50% 4px no-repeat,
4609
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 70%/40% 4px no-repeat,
4610
- var(--color-paper);
4611
- background-position: center 30%, center 50%, center 70%;
4612
- }
4613
-
4614
- .vt--threecard {
4615
- background:
4616
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 25%/30% 50% no-repeat,
4617
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 35% 25%/30% 50% no-repeat,
4618
- linear-gradient(var(--color-rule-2), var(--color-rule-2)) 70% 25%/30% 50% no-repeat,
4619
- var(--color-paper);
4620
- }
4621
-
4622
- .vt--moremore {
4623
- background: var(--color-ink);
4624
- color: var(--color-paper);
4625
- display: grid;
4626
- place-items: center;
4627
- font-family: var(--font-label);
4628
- font-size: var(--text-xs);
4629
- letter-spacing: 0.04em;
4630
- border-color: var(--color-ink);
4631
- }
4632
-
4633
- @media (max-width: 50rem) {
4634
- .vt { aspect-ratio: 4 / 3; }
4635
- }
4636
-
4637
- /* ───────────── SPORT — section title fix ─────────────
4638
- The italic display + tight tracking + uppercase + weight 700
4639
- produced cramped, almost-touching letterforms. Loosen the
4640
- tracking just for section titles, give a tiny pad for the
4641
- italic slant overhang, and bump line-height for breathing room. */
4642
-
4643
- [data-theme="sport"] .section__title {
4644
- letter-spacing: -0.005em; /* loosened from -0.04em */
4645
- line-height: 1.12;
4646
- padding-inline-end: 0.15em; /* slack for italic slant overhang */
4647
- max-width: 26ch;
4648
- word-spacing: 0.04em;
4649
- }
4650
-
4651
- [data-theme="sport"] .spec__name,
4652
- [data-theme="sport"] .tell__name {
4653
- letter-spacing: 0;
4654
- line-height: 1.05;
4655
- }
4656
-
4657
- /* Sport — kinetic / scoreboard register.
4658
- Tabular numerals everywhere a number appears (counter, stat,
4659
- pricing, plate numbers); a top-bordered "leaderboard cell" treatment
4660
- on the section numeral; sharper sweep easing on .reveal. */
4661
-
4662
- [data-theme="sport"] .hero__stat,
4663
- [data-theme="sport"] .ex-card__num,
4664
- [data-theme="sport"] .gallery__num,
4665
- [data-theme="sport"] .spec__num,
4666
- [data-theme="sport"] .found-nav__num,
4667
- [data-theme="sport"] .vs-toggle__num,
4668
- [data-theme="sport"] .vs__panel-stat-num,
4669
- [data-theme="sport"] .vs__panel-price-num,
4670
- [data-theme="sport"] .install-pane__step,
4671
- [data-theme="sport"] .dna__v {
4672
- font-variant-numeric: tabular-nums;
4673
- font-feature-settings: "tnum";
4674
- }
4675
-
4676
- /* Section numeral as a leaderboard-style cell with a thin top rule */
4677
- [data-theme="sport"] .section-label .num {
4678
- display: inline-block;
4679
- padding: 0.15em 0.45em 0.05em;
4680
- border-block-start: 2px solid var(--color-accent);
4681
- background: color-mix(in oklch, var(--color-accent) 6%, transparent);
4682
- font-variant-numeric: tabular-nums;
4683
- font-feature-settings: "tnum";
4684
- }
4685
-
4686
- /* Sharper sweep easing on Sport reveals — sportier */
4687
- [data-theme="sport"] .reveal.is-in {
4688
- animation-timing-function: cubic-bezier(0.86, 0, 0.07, 1);
4689
- }
4690
-
4691
- /* Hero stat-row treatment — "MIN · 47 · LAP 12" register, when present */
4692
- [data-theme="sport"] .hero__qualifier {
4693
- font-family: var(--font-mono);
4694
- font-style: normal;
4695
- font-size: var(--text-md);
4696
- letter-spacing: 0.04em;
4697
- text-transform: uppercase;
4698
- color: var(--color-muted);
4699
- }
4700
-
4701
- /* ───────────── SALON — left-aligned, italic title, fleuron divider ───────────── */
4702
-
4703
- [data-theme="salon"] .section__head {
4704
- gap: var(--space-sm);
4705
- padding-block-end: var(--space-2xl);
4706
- }
4707
-
4708
- [data-theme="salon"] .section__title {
4709
- max-width: 32ch;
4710
- font-style: italic;
4711
- }
4712
-
4713
- [data-theme="salon"] .section__head::after {
4714
- content: "❦";
4715
- display: block;
4716
- color: var(--color-accent);
4717
- font-size: 1.7rem;
4718
- margin-block-start: var(--space-xl);
4719
- padding-block-start: var(--space-md);
4720
- border-block-start: var(--rule-hair) solid var(--color-rule);
4721
- font-family: var(--font-serif);
4722
- line-height: 1;
4723
- opacity: 0.85;
4724
- }
4725
-
4726
- /* ───────────── NEWSPRINT — justified prose blocks ─────────────
4727
- Print discipline. Long-form copy gets justified + hyphenated where
4728
- the column is wide enough to render evenly. Headlines stay
4729
- left-aligned (only the prose justifies). */
4730
-
4731
- [data-theme="newsprint"] .opening__sub,
4732
- [data-theme="newsprint"] .vs__caption,
4733
- [data-theme="newsprint"] .step__sub {
4734
- text-align: justify;
4735
- hyphens: auto;
4736
- }
4737
-
4738
- /* ───────────── BRUTAL / MANIFESTO — heavier card borders ─────────────
4739
- --rule-card is set to 2px on these themes (in tokens.css). The .tell
4740
- cards already use --rule-card. For other elements that have hairline
4741
- borders by default, give Brutal/Manifesto a touch more weight so the
4742
- theme's voice carries through. */
4743
-
4744
- [data-theme="brutal"] .code,
4745
- [data-theme="manifesto"] .code {
4746
- border-width: 1.5px;
4747
- }
4748
-
4749
- /* ──────────────────────────────────────────────────────────────
4750
- EDITORIAL THEME — open-design-inspired structural overrides (v0.9.0)
4751
-
4752
- The 23rd theme. Editorial-premium voice: mixed serif italic
4753
- inside sans display, Roman-numeral marginalia, hairline rules,
4754
- asymmetric grids. Inspired by github.com/nexu-io/open-design.
4755
- ────────────────────────────────────────────────────────────── */
4756
-
4757
- /* Mixed display: italic Playfair word inside Inter Tight headline */
4758
- [data-theme="editorial"] .hero__display em,
4759
- [data-theme="editorial"] .section__title em,
4760
- [data-theme="editorial"] .opening__title em {
4761
- font-family: var(--font-serif);
4762
- font-style: italic;
4763
- font-weight: 500;
4764
- letter-spacing: -0.02em;
4765
- }
4766
-
4767
- /* Roman-numeral section heads — replaces the leading number */
4768
- [data-theme="editorial"] .section-label .num {
4769
- font-family: var(--font-serif);
4770
- font-style: italic;
4771
- font-weight: 500;
4772
- letter-spacing: 0;
4773
- }
4774
- [data-theme="editorial"] .section-label .divider {
4775
- opacity: 0.55;
4776
- }
4777
-
4778
- /* Quieter rules and accents */
4779
- [data-theme="editorial"] .section__head {
4780
- border-bottom-color: var(--color-rule);
4781
- border-bottom-width: 0.5px;
4782
- }
4783
-
4784
- /* Tighten body in editorial — Inter is dense, less line-height needed */
4785
- [data-theme="editorial"] .examples__intro,
4786
- [data-theme="editorial"] .study__intro,
4787
- [data-theme="editorial"] .install-pane__next {
4788
- font-family: var(--font-body);
4789
- }
4790
-
4791
- /* ──────────────────────────────────────────────────────────────
4792
- OPEN-DESIGN STEALS — reusable utilities (v0.9.0)
4793
-
4794
- Six patterns extracted from open-design. NOT theme-only — these
4795
- are utilities any theme can use. Skill rules cross-reference them
4796
- in component-cookbook.md and microinteractions.md.
4797
- ────────────────────────────────────────────────────────────── */
4798
-
4799
- /* — Tabular numerals utility ———————————————————————————————
4800
- Apply to anything that mixes numbers with text — versions, dates,
4801
- stats, code stamps — so digit widths align like a ledger. */
4802
- .tnum {
4803
- font-variant-numeric: tabular-nums;
4804
- font-feature-settings: "tnum" 1;
4805
- }
4806
-
4807
- /* — Corner-bracket image annotation —————————————————————————
4808
- Wrap any image with .fig-corners; four 18px brackets appear at
4809
- the corners. Lightweight alternative to a full frame. */
4810
- .fig-corners {
4811
- position: relative;
4812
- display: block;
4813
- }
4814
- .fig-corners::before,
4815
- .fig-corners::after,
4816
- .fig-corners > .fig-corners__br,
4817
- .fig-corners > .fig-corners__bl {
4818
- content: "";
4819
- position: absolute;
4820
- width: 18px;
4821
- height: 18px;
4822
- border: 1px solid var(--color-rule-2);
4823
- pointer-events: none;
4824
- }
4825
- .fig-corners::before { top: -4px; left: -4px; border-right: 0; border-bottom: 0; }
4826
- .fig-corners::after { top: -4px; right: -4px; border-left: 0; border-bottom: 0; }
4827
- .fig-corners > .fig-corners__bl { bottom: -4px; left: -4px; border-right: 0; border-top: 0; }
4828
- .fig-corners > .fig-corners__br { bottom: -4px; right: -4px; border-left: 0; border-top: 0; }
4829
-
4830
- /* — Pulse animation utility ————————————————————————————————
4831
- Subtle ambient breathing pulse for status dots / live indicators.
4832
- 2.4s ease-in-out, opacity-only. Reduced-motion fallback is steady. */
4833
- .pulse {
4834
- animation: pulse-breathe 2.4s var(--ease-in-out, ease-in-out) infinite;
4835
- }
4836
- @keyframes pulse-breathe {
4837
- 0%, 100% { opacity: 0.45; }
4838
- 50% { opacity: 1; }
4839
- }
4840
- @media (prefers-reduced-motion: reduce) {
4841
- .pulse { animation: none; opacity: 0.85; }
4842
- }
4843
-
4844
- /* — Dark-slab section reversal —————————————————————————————
4845
- Wrap any .section in `.section--invert` to flip paper/ink colours
4846
- for that one section. Useful for breaking page rhythm. */
4847
- .section--invert {
4848
- background: var(--color-ink);
4849
- color: var(--color-paper);
4850
- margin-inline: calc(-1 * var(--page-gutter));
4851
- padding-inline: var(--page-gutter);
4852
- padding-block: var(--space-2xl);
4853
- }
4854
- .section--invert .section__title,
4855
- .section--invert .section-label,
4856
- .section--invert .section__head { color: var(--color-paper); }
4857
- .section--invert .section__head { border-bottom-color: oklch(50% 0.02 60 / 0.4); }
4858
-
4859
- /* — Asymmetric hero ratio knob ——————————————————————————————
4860
- Default split-hero ratio is 50/50; this knob swaps it to 0.78/1.22
4861
- per the open-design move. Apply to `.hero--split[data-ratio="asym"]`. */
4862
- .hero--split[data-ratio="asym"] {
4863
- grid-template-columns: 0.78fr 1.22fr;
4864
- }
4865
-
4866
- /* — Roman-numeral section-label variant —————————————————————
4867
- `<span class="num num--roman">XII</span>` rendered in italic serif. */
4868
- .section-label .num--roman {
4869
- font-family: var(--font-serif);
4870
- font-style: italic;
4871
- font-weight: 500;
4872
- letter-spacing: 0;
4873
- }
4874
-
4875
- /* — Smart sticky nav (reveal on scroll-up) ———————————————————
4876
- Apply to .banner with class `banner--smart`. Hidden when scrolling
4877
- down, slid back in when scrolling up. JS toggles the class on scroll. */
4878
- .banner--smart {
4879
- transition: transform 220ms var(--ease-out);
4880
- }
4881
- .banner--smart.is-hidden {
4882
- transform: translateY(-100%);
4883
- }
4884
- @media (prefers-reduced-motion: reduce) {
4885
- .banner--smart { transition: none; }
4886
- }