howone 0.1.20 → 0.1.23

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 (298) hide show
  1. package/package.json +1 -1
  2. package/templates/nextjs/lib/sdk.ts +3 -0
  3. package/templates/vite/.howone/skills/hallmark/LICENSE +21 -0
  4. package/templates/vite/.howone/skills/hallmark/README.md +147 -0
  5. package/templates/vite/.howone/skills/hallmark/ROADMAP.md +201 -0
  6. package/templates/vite/.howone/skills/hallmark/SKILL.md +551 -0
  7. package/templates/vite/.howone/skills/hallmark/docs/recipes.md +186 -0
  8. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-anya.jpg +0 -0
  9. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-bananastudio.jpg +0 -0
  10. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-hyperlane.jpg +0 -0
  11. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-najm.jpg +0 -0
  12. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-slow-pour.jpg +0 -0
  13. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-soroe.jpg +0 -0
  14. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-tally.jpg +0 -0
  15. package/templates/vite/.howone/skills/hallmark/docs/screenshots/hero-wayfare.jpg +0 -0
  16. package/templates/vite/.howone/skills/hallmark/docs/study-examples.md +176 -0
  17. package/templates/vite/.howone/skills/hallmark/docs/talk-slides.md +364 -0
  18. package/templates/vite/.howone/skills/hallmark/package.json +36 -0
  19. package/templates/vite/.howone/skills/hallmark/references/anti-patterns.md +412 -0
  20. package/templates/vite/.howone/skills/hallmark/references/assets.md +399 -0
  21. package/templates/vite/.howone/skills/hallmark/references/color.md +95 -0
  22. package/templates/vite/.howone/skills/hallmark/references/component-cookbook.md +256 -0
  23. package/templates/vite/.howone/skills/hallmark/references/components/c1-outlined-chip.md +12 -0
  24. package/templates/vite/.howone/skills/hallmark/references/components/c2-inline-form-as-cta.md +16 -0
  25. package/templates/vite/.howone/skills/hallmark/references/components/c3-typographic-link.md +8 -0
  26. package/templates/vite/.howone/skills/hallmark/references/components/c4-sticky-bottom-bar.md +16 -0
  27. package/templates/vite/.howone/skills/hallmark/references/components/f1-bento-grid.md +20 -0
  28. package/templates/vite/.howone/skills/hallmark/references/components/f2-sticky-scroll-stack.md +20 -0
  29. package/templates/vite/.howone/skills/hallmark/references/components/f3-tabular-spec-sheet.md +11 -0
  30. package/templates/vite/.howone/skills/hallmark/references/components/f4-step-sequence.md +11 -0
  31. package/templates/vite/.howone/skills/hallmark/references/components/f5-annotated-screenshot.md +11 -0
  32. package/templates/vite/.howone/skills/hallmark/references/components/f6-product-card-grid.md +41 -0
  33. package/templates/vite/.howone/skills/hallmark/references/components/ft1-mast-headed.md +13 -0
  34. package/templates/vite/.howone/skills/hallmark/references/components/ft2-inline-rule-single-line.md +10 -0
  35. package/templates/vite/.howone/skills/hallmark/references/components/ft3-index-style-category-list.md +12 -0
  36. package/templates/vite/.howone/skills/hallmark/references/components/ft4-dense-typographic.md +10 -0
  37. package/templates/vite/.howone/skills/hallmark/references/components/ft5-statement.md +21 -0
  38. package/templates/vite/.howone/skills/hallmark/references/components/ft6-letter-close.md +19 -0
  39. package/templates/vite/.howone/skills/hallmark/references/components/ft7-newsletter-first.md +27 -0
  40. package/templates/vite/.howone/skills/hallmark/references/components/ft8-marquee-scroll.md +25 -0
  41. package/templates/vite/.howone/skills/hallmark/references/components/h1-marquee.md +15 -0
  42. package/templates/vite/.howone/skills/hallmark/references/components/h2-split-diptych.md +15 -0
  43. package/templates/vite/.howone/skills/hallmark/references/components/h3-quote-led.md +11 -0
  44. package/templates/vite/.howone/skills/hallmark/references/components/h4-stat-led.md +14 -0
  45. package/templates/vite/.howone/skills/hallmark/references/components/h5-letter-hero.md +11 -0
  46. package/templates/vite/.howone/skills/hallmark/references/components/h6-photographic-fold.md +16 -0
  47. package/templates/vite/.howone/skills/hallmark/references/components/h7-demo-video-clipped-by-viewport-edge.md +27 -0
  48. package/templates/vite/.howone/skills/hallmark/references/components/h8-mockup-split-browser-framed.md +23 -0
  49. package/templates/vite/.howone/skills/hallmark/references/components/h9-custom-illustration-centerpiece.md +27 -0
  50. package/templates/vite/.howone/skills/hallmark/references/components/n1-wordmark-2-links.md +12 -0
  51. package/templates/vite/.howone/skills/hallmark/references/components/n10-floating-on-scroll-morph.md +19 -0
  52. package/templates/vite/.howone/skills/hallmark/references/components/n2-floating-chip.md +14 -0
  53. package/templates/vite/.howone/skills/hallmark/references/components/n3-side-rail.md +14 -0
  54. package/templates/vite/.howone/skills/hallmark/references/components/n4-hidden-behind-k.md +9 -0
  55. package/templates/vite/.howone/skills/hallmark/references/components/n5-floating-pill.md +28 -0
  56. package/templates/vite/.howone/skills/hallmark/references/components/n6-newspaper-masthead.md +24 -0
  57. package/templates/vite/.howone/skills/hallmark/references/components/n7-brutal-slab.md +22 -0
  58. package/templates/vite/.howone/skills/hallmark/references/components/n8-terminal-command.md +21 -0
  59. package/templates/vite/.howone/skills/hallmark/references/components/n9-edge-aligned-minimal.md +17 -0
  60. package/templates/vite/.howone/skills/hallmark/references/components/s1-left-margin-numbered.md +15 -0
  61. package/templates/vite/.howone/skills/hallmark/references/components/s2-hanging.md +13 -0
  62. package/templates/vite/.howone/skills/hallmark/references/components/s3-sticky-pinned.md +19 -0
  63. package/templates/vite/.howone/skills/hallmark/references/components/s4-inline-no-break.md +11 -0
  64. package/templates/vite/.howone/skills/hallmark/references/components/s5-bottom-anchored.md +13 -0
  65. package/templates/vite/.howone/skills/hallmark/references/components/t1-pull-quote-with-marginalia.md +12 -0
  66. package/templates/vite/.howone/skills/hallmark/references/components/t2-logo-wall-hairline.md +19 -0
  67. package/templates/vite/.howone/skills/hallmark/references/components/t3-single-huge-quote.md +11 -0
  68. package/templates/vite/.howone/skills/hallmark/references/components/t4-numbered-stat-strip.md +14 -0
  69. package/templates/vite/.howone/skills/hallmark/references/contract.md +24 -0
  70. package/templates/vite/.howone/skills/hallmark/references/copy.md +182 -0
  71. package/templates/vite/.howone/skills/hallmark/references/custom-craft.md +626 -0
  72. package/templates/vite/.howone/skills/hallmark/references/custom-theme.md +329 -0
  73. package/templates/vite/.howone/skills/hallmark/references/design-md.md +116 -0
  74. package/templates/vite/.howone/skills/hallmark/references/export-formats.md +328 -0
  75. package/templates/vite/.howone/skills/hallmark/references/floating-nav.md +89 -0
  76. package/templates/vite/.howone/skills/hallmark/references/genres/atmospheric.md +65 -0
  77. package/templates/vite/.howone/skills/hallmark/references/genres/editorial.md +70 -0
  78. package/templates/vite/.howone/skills/hallmark/references/genres/modern-minimal.md +67 -0
  79. package/templates/vite/.howone/skills/hallmark/references/genres/playful.md +65 -0
  80. package/templates/vite/.howone/skills/hallmark/references/hero-enrichment.md +474 -0
  81. package/templates/vite/.howone/skills/hallmark/references/imagery-kit.md +170 -0
  82. package/templates/vite/.howone/skills/hallmark/references/interaction-and-states.md +207 -0
  83. package/templates/vite/.howone/skills/hallmark/references/layout-and-space.md +111 -0
  84. package/templates/vite/.howone/skills/hallmark/references/macrostructures/01-bento-grid.md +35 -0
  85. package/templates/vite/.howone/skills/hallmark/references/macrostructures/02-long-document.md +34 -0
  86. package/templates/vite/.howone/skills/hallmark/references/macrostructures/03-marquee-hero.md +31 -0
  87. package/templates/vite/.howone/skills/hallmark/references/macrostructures/04-stat-led.md +32 -0
  88. package/templates/vite/.howone/skills/hallmark/references/macrostructures/05-workbench.md +32 -0
  89. package/templates/vite/.howone/skills/hallmark/references/macrostructures/06-conversational-faq.md +33 -0
  90. package/templates/vite/.howone/skills/hallmark/references/macrostructures/07-manifesto.md +32 -0
  91. package/templates/vite/.howone/skills/hallmark/references/macrostructures/08-photographic.md +34 -0
  92. package/templates/vite/.howone/skills/hallmark/references/macrostructures/09-quote-led.md +32 -0
  93. package/templates/vite/.howone/skills/hallmark/references/macrostructures/10-specimen.md +32 -0
  94. package/templates/vite/.howone/skills/hallmark/references/macrostructures/11-catalogue.md +23 -0
  95. package/templates/vite/.howone/skills/hallmark/references/macrostructures/12-letter.md +23 -0
  96. package/templates/vite/.howone/skills/hallmark/references/macrostructures/13-index-first.md +23 -0
  97. package/templates/vite/.howone/skills/hallmark/references/macrostructures/14-narrative-workflow.md +23 -0
  98. package/templates/vite/.howone/skills/hallmark/references/macrostructures/15-split-studio.md +23 -0
  99. package/templates/vite/.howone/skills/hallmark/references/macrostructures/16-feature-stack.md +23 -0
  100. package/templates/vite/.howone/skills/hallmark/references/macrostructures/17-type-specimen.md +23 -0
  101. package/templates/vite/.howone/skills/hallmark/references/macrostructures/18-portfolio-grid.md +23 -0
  102. package/templates/vite/.howone/skills/hallmark/references/macrostructures/19-map-diagram.md +23 -0
  103. package/templates/vite/.howone/skills/hallmark/references/macrostructures/20-ecosystem-index.md +23 -0
  104. package/templates/vite/.howone/skills/hallmark/references/macrostructures/21-component-playground.md +23 -0
  105. package/templates/vite/.howone/skills/hallmark/references/macrostructures.md +89 -0
  106. package/templates/vite/.howone/skills/hallmark/references/microinteractions.md +260 -0
  107. package/templates/vite/.howone/skills/hallmark/references/motion.md +109 -0
  108. package/templates/vite/.howone/skills/hallmark/references/preview-examples.md +49 -0
  109. package/templates/vite/.howone/skills/hallmark/references/responsive.md +138 -0
  110. package/templates/vite/.howone/skills/hallmark/references/slop-test.md +205 -0
  111. package/templates/vite/.howone/skills/hallmark/references/structure.md +164 -0
  112. package/templates/vite/.howone/skills/hallmark/references/study.md +486 -0
  113. package/templates/vite/.howone/skills/hallmark/references/typography.md +243 -0
  114. package/templates/vite/.howone/skills/hallmark/references/verbs/audit.md +25 -0
  115. package/templates/vite/.howone/skills/hallmark/references/verbs/redesign.md +269 -0
  116. package/templates/vite/.howone/skills/hallmark/site/OG-hallmark.png +0 -0
  117. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/brief.md +71 -0
  118. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/index.html +64 -0
  119. package/templates/vite/.howone/skills/hallmark/site/_tests/01-tide-podcast/style.css +240 -0
  120. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/brief.md +65 -0
  121. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/index.html +105 -0
  122. package/templates/vite/.howone/skills/hallmark/site/_tests/02-streampipe-cli/style.css +250 -0
  123. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/brief.md +64 -0
  124. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/index.html +131 -0
  125. package/templates/vite/.howone/skills/hallmark/site/_tests/03-maple-bakery/style.css +240 -0
  126. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/brief.md +67 -0
  127. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/index.html +86 -0
  128. package/templates/vite/.howone/skills/hallmark/site/_tests/04-meridian-manifesto/style.css +262 -0
  129. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/brief.md +63 -0
  130. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/index.html +167 -0
  131. package/templates/vite/.howone/skills/hallmark/site/_tests/05-tracejam-saas/style.css +457 -0
  132. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/brief.md +65 -0
  133. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/index.html +159 -0
  134. package/templates/vite/.howone/skills/hallmark/site/_tests/06-anya-portfolio/style.css +288 -0
  135. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/brief.md +64 -0
  136. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/index.html +146 -0
  137. package/templates/vite/.howone/skills/hallmark/site/_tests/07-foundry-compliance/style.css +484 -0
  138. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/brief.md +64 -0
  139. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/index.html +116 -0
  140. package/templates/vite/.howone/skills/hallmark/site/_tests/08-cohort-courses/style.css +354 -0
  141. package/templates/vite/.howone/skills/hallmark/site/_tests/09-slow-pour/index.html +638 -0
  142. package/templates/vite/.howone/skills/hallmark/site/_tests/10-owl-hours/index.html +515 -0
  143. package/templates/vite/.howone/skills/hallmark/site/_tests/11-soroe-ceramics/index.html +515 -0
  144. package/templates/vite/.howone/skills/hallmark/site/_tests/12-loafer/index.html +608 -0
  145. package/templates/vite/.howone/skills/hallmark/site/_tests/13-alma/index.html +587 -0
  146. package/templates/vite/.howone/skills/hallmark/site/_tests/README.md +157 -0
  147. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-loop.mp4 +0 -0
  148. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/BananaStudio-still.jpg +0 -0
  149. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-example.mp4 +0 -0
  150. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Hyperlane-still.jpg +0 -0
  151. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-loop.mp4 +0 -0
  152. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Najm-still.jpg +0 -0
  153. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Podcast-loop.mp4 +0 -0
  154. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-loop.mp4 +0 -0
  155. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/SaaS-still.jpg +0 -0
  156. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-loop.mp4 +0 -0
  157. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/Soroe-still.jpg +0 -0
  158. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/after-quiet-hour.png +0 -0
  159. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-loop.mp4 +0 -0
  160. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/anya-still.jpg +0 -0
  161. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/audit-example.png +0 -0
  162. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/before-quiet-hour.png +0 -0
  163. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/example-redesign-uractivation.png +0 -0
  164. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-loop.mp4 +0 -0
  165. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/slow-pour-still.jpg +0 -0
  166. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/study-example.png +0 -0
  167. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/uractivation-after-loop.mp4 +0 -0
  168. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-loop.mp4 +0 -0
  169. package/templates/vite/.howone/skills/hallmark/site/_tests/_thumbs/wayfare-still.jpg +0 -0
  170. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/index.html +77 -0
  171. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/01-coffeebox/style.css +238 -0
  172. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/index.html +110 -0
  173. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/02-loop/style.css +326 -0
  174. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/index.html +134 -0
  175. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/03-mossroot/style.css +262 -0
  176. package/templates/vite/.howone/skills/hallmark/site/_tests/custom/README.md +30 -0
  177. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/README.md +17 -0
  178. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/audit-report.md +56 -0
  179. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/input.html +160 -0
  180. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/audit/notes.md +29 -0
  181. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/input.html +63 -0
  182. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/notes.md +72 -0
  183. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/redesign/output.html +374 -0
  184. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/diagnosis.md +52 -0
  185. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/input-description.md +29 -0
  186. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/notes.md +61 -0
  187. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.css +193 -0
  188. package/templates/vite/.howone/skills/hallmark/site/_tests/verbs/study/output.html +66 -0
  189. package/templates/vite/.howone/skills/hallmark/site/css/base.css +194 -0
  190. package/templates/vite/.howone/skills/hallmark/site/css/components.css +4886 -0
  191. package/templates/vite/.howone/skills/hallmark/site/css/sections.css +2072 -0
  192. package/templates/vite/.howone/skills/hallmark/site/css/tokens.css +1129 -0
  193. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/index.html +475 -0
  194. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/styles.css +1584 -0
  195. package/templates/vite/.howone/skills/hallmark/site/examples/bananastudio/tokens.css +96 -0
  196. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/index.html +344 -0
  197. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/script.js +103 -0
  198. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/styles.css +1103 -0
  199. package/templates/vite/.howone/skills/hallmark/site/examples/hyperlane/tokens.css +83 -0
  200. package/templates/vite/.howone/skills/hallmark/site/examples/najm/index.html +368 -0
  201. package/templates/vite/.howone/skills/hallmark/site/examples/najm/script.js +133 -0
  202. package/templates/vite/.howone/skills/hallmark/site/examples/najm/styles.css +1062 -0
  203. package/templates/vite/.howone/skills/hallmark/site/examples/najm/tokens.css +97 -0
  204. package/templates/vite/.howone/skills/hallmark/site/examples/tally/app.js +84 -0
  205. package/templates/vite/.howone/skills/hallmark/site/examples/tally/index.html +446 -0
  206. package/templates/vite/.howone/skills/hallmark/site/examples/tally/styles.css +1087 -0
  207. package/templates/vite/.howone/skills/hallmark/site/examples/tally/tokens.css +101 -0
  208. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/index.html +359 -0
  209. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/style.css +1168 -0
  210. package/templates/vite/.howone/skills/hallmark/site/examples/wayfare/tokens.css +81 -0
  211. package/templates/vite/.howone/skills/hallmark/site/favicon-dark.svg +5 -0
  212. package/templates/vite/.howone/skills/hallmark/site/favicon-light.svg +5 -0
  213. package/templates/vite/.howone/skills/hallmark/site/index.html +1043 -0
  214. package/templates/vite/.howone/skills/hallmark/site/js/main.js +1175 -0
  215. package/templates/vite/.howone/skills/hallmark/vercel.json +6 -0
  216. package/templates/vite/.howone/skills/howone-sdk/01-architect/01-app-generation.md +126 -0
  217. package/templates/vite/.howone/skills/howone-sdk/{references/08-manifest-codegen.md → 01-architect/02-manifest-codegen.md} +31 -19
  218. package/templates/vite/.howone/skills/howone-sdk/02-database/01-schema-design.md +147 -0
  219. package/templates/vite/.howone/skills/howone-sdk/02-database/02-schema-operations.md +96 -0
  220. package/templates/vite/.howone/skills/howone-sdk/02-database/03-data-access-patterns.md +172 -0
  221. package/templates/vite/.howone/skills/howone-sdk/{references → 03-sdk}/01-client-setup.md +3 -3
  222. package/templates/vite/.howone/skills/howone-sdk/{references/04-auth.md → 03-sdk/03-auth.md} +120 -3
  223. package/templates/vite/.howone/skills/howone-sdk/{references/06-react-integration.md → 03-sdk/04-react-integration.md} +2 -4
  224. package/templates/vite/.howone/skills/howone-sdk/{references/03-ai-actions.md → 03-sdk/07-ai-action-calls.md} +31 -34
  225. package/templates/vite/.howone/skills/howone-sdk/04-ai/.gitkeep +1 -0
  226. package/templates/vite/.howone/skills/howone-sdk/04-ai/01-ai-capability-architecture.md +142 -0
  227. package/templates/vite/.howone/skills/howone-sdk/04-ai/02-workflow-contract-rules.md +169 -0
  228. package/templates/vite/.howone/skills/howone-sdk/04-ai/03-ai-sdk-handoff.md +80 -0
  229. package/templates/vite/.howone/skills/howone-sdk/SKILL.md +118 -93
  230. package/templates/vite/.howone/skills/howone-sdk/agents/openai.yaml +3 -3
  231. package/templates/vite/.howone/skills/impeccable/SKILL.md +168 -0
  232. package/templates/vite/.howone/skills/impeccable/agents/impeccable-asset-producer.md +101 -0
  233. package/templates/vite/.howone/skills/impeccable/reference/adapt.md +190 -0
  234. package/templates/vite/.howone/skills/impeccable/reference/animate.md +175 -0
  235. package/templates/vite/.howone/skills/impeccable/reference/audit.md +133 -0
  236. package/templates/vite/.howone/skills/impeccable/reference/bolder.md +113 -0
  237. package/templates/vite/.howone/skills/impeccable/reference/brand.md +118 -0
  238. package/templates/vite/.howone/skills/impeccable/reference/clarify.md +174 -0
  239. package/templates/vite/.howone/skills/impeccable/reference/codex.md +105 -0
  240. package/templates/vite/.howone/skills/impeccable/reference/cognitive-load.md +106 -0
  241. package/templates/vite/.howone/skills/impeccable/reference/color-and-contrast.md +105 -0
  242. package/templates/vite/.howone/skills/impeccable/reference/colorize.md +154 -0
  243. package/templates/vite/.howone/skills/impeccable/reference/craft.md +123 -0
  244. package/templates/vite/.howone/skills/impeccable/reference/critique.md +273 -0
  245. package/templates/vite/.howone/skills/impeccable/reference/delight.md +302 -0
  246. package/templates/vite/.howone/skills/impeccable/reference/distill.md +111 -0
  247. package/templates/vite/.howone/skills/impeccable/reference/document.md +427 -0
  248. package/templates/vite/.howone/skills/impeccable/reference/extract.md +69 -0
  249. package/templates/vite/.howone/skills/impeccable/reference/harden.md +347 -0
  250. package/templates/vite/.howone/skills/impeccable/reference/heuristics-scoring.md +234 -0
  251. package/templates/vite/.howone/skills/impeccable/reference/interaction-design.md +195 -0
  252. package/templates/vite/.howone/skills/impeccable/reference/layout.md +141 -0
  253. package/templates/vite/.howone/skills/impeccable/reference/live.md +622 -0
  254. package/templates/vite/.howone/skills/impeccable/reference/motion-design.md +109 -0
  255. package/templates/vite/.howone/skills/impeccable/reference/onboard.md +234 -0
  256. package/templates/vite/.howone/skills/impeccable/reference/optimize.md +258 -0
  257. package/templates/vite/.howone/skills/impeccable/reference/overdrive.md +130 -0
  258. package/templates/vite/.howone/skills/impeccable/reference/personas.md +179 -0
  259. package/templates/vite/.howone/skills/impeccable/reference/polish.md +242 -0
  260. package/templates/vite/.howone/skills/impeccable/reference/product.md +62 -0
  261. package/templates/vite/.howone/skills/impeccable/reference/quieter.md +99 -0
  262. package/templates/vite/.howone/skills/impeccable/reference/responsive-design.md +114 -0
  263. package/templates/vite/.howone/skills/impeccable/reference/shape.md +165 -0
  264. package/templates/vite/.howone/skills/impeccable/reference/spatial-design.md +100 -0
  265. package/templates/vite/.howone/skills/impeccable/reference/teach.md +156 -0
  266. package/templates/vite/.howone/skills/impeccable/reference/typeset.md +124 -0
  267. package/templates/vite/.howone/skills/impeccable/reference/typography.md +159 -0
  268. package/templates/vite/.howone/skills/impeccable/reference/ux-writing.md +107 -0
  269. package/templates/vite/.howone/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  270. package/templates/vite/.howone/skills/impeccable/scripts/command-metadata.json +94 -0
  271. package/templates/vite/.howone/skills/impeccable/scripts/critique-storage.mjs +242 -0
  272. package/templates/vite/.howone/skills/impeccable/scripts/design-parser.mjs +820 -0
  273. package/templates/vite/.howone/skills/impeccable/scripts/detect-csp.mjs +198 -0
  274. package/templates/vite/.howone/skills/impeccable/scripts/detect.mjs +21 -0
  275. package/templates/vite/.howone/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  276. package/templates/vite/.howone/skills/impeccable/scripts/is-generated.mjs +69 -0
  277. package/templates/vite/.howone/skills/impeccable/scripts/live-accept.mjs +595 -0
  278. package/templates/vite/.howone/skills/impeccable/scripts/live-browser-session.js +123 -0
  279. package/templates/vite/.howone/skills/impeccable/scripts/live-browser.js +4860 -0
  280. package/templates/vite/.howone/skills/impeccable/scripts/live-complete.mjs +75 -0
  281. package/templates/vite/.howone/skills/impeccable/scripts/live-completion.mjs +18 -0
  282. package/templates/vite/.howone/skills/impeccable/scripts/live-inject.mjs +446 -0
  283. package/templates/vite/.howone/skills/impeccable/scripts/live-poll.mjs +200 -0
  284. package/templates/vite/.howone/skills/impeccable/scripts/live-resume.mjs +48 -0
  285. package/templates/vite/.howone/skills/impeccable/scripts/live-server.mjs +838 -0
  286. package/templates/vite/.howone/skills/impeccable/scripts/live-session-store.mjs +254 -0
  287. package/templates/vite/.howone/skills/impeccable/scripts/live-status.mjs +47 -0
  288. package/templates/vite/.howone/skills/impeccable/scripts/live-wrap.mjs +632 -0
  289. package/templates/vite/.howone/skills/impeccable/scripts/live.mjs +247 -0
  290. package/templates/vite/.howone/skills/impeccable/scripts/load-context.mjs +141 -0
  291. package/templates/vite/.howone/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  292. package/templates/vite/.howone/skills/impeccable/scripts/pin.mjs +214 -0
  293. package/templates/vite/AGENTS.md +2 -12
  294. package/templates/vite/package.json +1 -1
  295. package/templates/vite/src/lib/sdk.ts +3 -0
  296. /package/templates/vite/.howone/skills/howone-sdk/{references → 03-sdk}/02-entity-operations.md +0 -0
  297. /package/templates/vite/.howone/skills/howone-sdk/{references → 03-sdk}/05-file-upload.md +0 -0
  298. /package/templates/vite/.howone/skills/howone-sdk/{references/07-raw-http.md → 03-sdk/06-raw-http.md} +0 -0
@@ -0,0 +1,4886 @@
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
+ }