@stylecrib/cli 0.3.1 → 0.3.3

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 (314) hide show
  1. package/README.md +94 -9
  2. package/agents/MANIFEST.yml +136 -0
  3. package/agents/README.md +75 -0
  4. package/agents/art-director.md +168 -0
  5. package/agents/audacity-director.md +109 -0
  6. package/agents/brand-identity.md +179 -0
  7. package/agents/brand-precedent.md +119 -0
  8. package/agents/brief-enforcer.md +136 -0
  9. package/agents/component-qa.md +167 -0
  10. package/agents/cto.md +49 -0
  11. package/agents/design-director.md +184 -0
  12. package/agents/design-systems-engineer.md +162 -0
  13. package/agents/direction-curator.md +133 -0
  14. package/agents/homogeneity-detector.md +104 -0
  15. package/agents/logo-designer.md +240 -0
  16. package/agents/marketing-designer.md +156 -0
  17. package/agents/media-curator.md +165 -0
  18. package/agents/motion-engineer.md +270 -0
  19. package/agents/qa-conductor.md +143 -0
  20. package/agents/render-qa.md +133 -0
  21. package/agents/upgrade-simulator.md +123 -0
  22. package/agents/vp-architecture.md +49 -0
  23. package/agents/vp-engineering.md +49 -0
  24. package/dist/index.js +1606 -467
  25. package/package.json +12 -4
  26. package/themes/README.md +70 -0
  27. package/themes/acrylic-soft/THEME.md +142 -0
  28. package/themes/acrylic-soft/tokens.ts +180 -0
  29. package/themes/agency-creative/THEME.md +91 -0
  30. package/themes/agency-creative/tokens.ts +202 -0
  31. package/themes/agency-portfolio/THEME.md +109 -0
  32. package/themes/agency-portfolio/tokens.ts +159 -0
  33. package/themes/ai-startup/THEME.md +95 -0
  34. package/themes/ai-startup/tokens.ts +162 -0
  35. package/themes/airline-modern/THEME.md +104 -0
  36. package/themes/airline-modern/tokens.ts +179 -0
  37. package/themes/arc-stack/THEME.md +125 -0
  38. package/themes/arc-stack/tailwind.snippet.ts +17 -0
  39. package/themes/arc-stack/theme.yml +153 -0
  40. package/themes/arc-stack/tokens.ts +29 -0
  41. package/themes/architectural/THEME.md +102 -0
  42. package/themes/architectural/tokens.ts +159 -0
  43. package/themes/atelier-radiance/THEME.md +93 -0
  44. package/themes/atelier-radiance/tailwind.snippet.ts +15 -0
  45. package/themes/atelier-radiance/theme.yml +130 -0
  46. package/themes/atelier-radiance/tokens.ts +29 -0
  47. package/themes/automotive-ev/THEME.md +87 -0
  48. package/themes/automotive-ev/tokens.ts +183 -0
  49. package/themes/automotive-luxury/THEME.md +88 -0
  50. package/themes/automotive-luxury/tokens.ts +175 -0
  51. package/themes/baby-modern/THEME.md +79 -0
  52. package/themes/baby-modern/tokens.ts +184 -0
  53. package/themes/banking-gravity/THEME.md +171 -0
  54. package/themes/banking-gravity/tokens.ts +169 -0
  55. package/themes/beauty-clean/THEME.md +92 -0
  56. package/themes/beauty-clean/tokens.ts +176 -0
  57. package/themes/beauty-luxury/THEME.md +96 -0
  58. package/themes/beauty-luxury/tokens.ts +178 -0
  59. package/themes/bento-modular/BUILD_BRIEF.md +171 -0
  60. package/themes/bento-modular/THEME.md +80 -0
  61. package/themes/bento-modular/tailwind.snippet.ts +17 -0
  62. package/themes/bento-modular/theme.yml +83 -0
  63. package/themes/bento-modular/tokens.ts +27 -0
  64. package/themes/bookstore-indie/THEME.md +78 -0
  65. package/themes/bookstore-indie/tokens.ts +147 -0
  66. package/themes/brutalist/THEME.md +96 -0
  67. package/themes/brutalist/tokens.ts +151 -0
  68. package/themes/business-tiles/THEME.md +141 -0
  69. package/themes/business-tiles/tokens.ts +178 -0
  70. package/themes/cabana-poster/THEME.md +158 -0
  71. package/themes/cabana-poster/tailwind.snippet.ts +16 -0
  72. package/themes/cabana-poster/theme.yml +221 -0
  73. package/themes/cabana-poster/tokens.ts +34 -0
  74. package/themes/case-panel/THEME.md +126 -0
  75. package/themes/case-panel/tailwind.snippet.ts +15 -0
  76. package/themes/case-panel/theme.yml +153 -0
  77. package/themes/case-panel/tokens.ts +28 -0
  78. package/themes/cinematic-dark/THEME.md +97 -0
  79. package/themes/cinematic-dark/tokens.ts +195 -0
  80. package/themes/classic-car/THEME.md +86 -0
  81. package/themes/classic-car/tokens.ts +173 -0
  82. package/themes/cloud-friendly/THEME.md +152 -0
  83. package/themes/cloud-friendly/tokens.ts +181 -0
  84. package/themes/community-niche/THEME.md +102 -0
  85. package/themes/community-niche/tokens.ts +177 -0
  86. package/themes/corporate-grid/THEME.md +154 -0
  87. package/themes/corporate-grid/tokens.ts +182 -0
  88. package/themes/couture-luxury/THEME.md +85 -0
  89. package/themes/couture-luxury/tokens.ts +146 -0
  90. package/themes/creator-social/THEME.md +131 -0
  91. package/themes/creator-social/tokens.ts +249 -0
  92. package/themes/crypto-onchain/THEME.md +100 -0
  93. package/themes/crypto-onchain/tokens.ts +207 -0
  94. package/themes/cycling-brand/THEME.md +78 -0
  95. package/themes/cycling-brand/tokens.ts +185 -0
  96. package/themes/dating-friendly/THEME.md +102 -0
  97. package/themes/dating-friendly/tokens.ts +178 -0
  98. package/themes/dense-utility/THEME.md +85 -0
  99. package/themes/dense-utility/tokens.ts +155 -0
  100. package/themes/devtool-cli/THEME.md +100 -0
  101. package/themes/devtool-cli/tokens.ts +195 -0
  102. package/themes/devtool-docs/THEME.md +105 -0
  103. package/themes/devtool-docs/tokens.ts +177 -0
  104. package/themes/editorial/THEME.md +129 -0
  105. package/themes/editorial/tailwind.snippet.ts +15 -0
  106. package/themes/editorial/theme.yml +173 -0
  107. package/themes/editorial/tokens.ts +29 -0
  108. package/themes/education-formal/THEME.md +154 -0
  109. package/themes/education-formal/tailwind.snippet.ts +15 -0
  110. package/themes/education-formal/theme.yml +186 -0
  111. package/themes/education-formal/tokens.ts +29 -0
  112. package/themes/education-warm/THEME.md +91 -0
  113. package/themes/education-warm/tokens.ts +185 -0
  114. package/themes/ember-poster/README.md +79 -0
  115. package/themes/ember-poster/THEME.md +101 -0
  116. package/themes/ember-poster/package.json +34 -0
  117. package/themes/ember-poster/tailwind.snippet.ts +17 -0
  118. package/themes/ember-poster/theme.yml +109 -0
  119. package/themes/ember-poster/tokens.ts +27 -0
  120. package/themes/enterprise-cloud/THEME.md +139 -0
  121. package/themes/enterprise-cloud/tokens.ts +179 -0
  122. package/themes/enterprise-tech/THEME.md +167 -0
  123. package/themes/enterprise-tech/tailwind.snippet.ts +15 -0
  124. package/themes/enterprise-tech/theme.yml +202 -0
  125. package/themes/enterprise-tech/tokens.ts +29 -0
  126. package/themes/ev-charging/THEME.md +94 -0
  127. package/themes/ev-charging/tokens.ts +185 -0
  128. package/themes/farm-direct/THEME.md +92 -0
  129. package/themes/farm-direct/tokens.ts +180 -0
  130. package/themes/fintech-card/THEME.md +96 -0
  131. package/themes/fintech-card/tokens.ts +191 -0
  132. package/themes/fintech-trust/THEME.md +94 -0
  133. package/themes/fintech-trust/tokens.ts +192 -0
  134. package/themes/food-blog/THEME.md +98 -0
  135. package/themes/food-blog/tokens.ts +183 -0
  136. package/themes/forum-classic/THEME.md +100 -0
  137. package/themes/forum-classic/tokens.ts +168 -0
  138. package/themes/fresh-plate/THEME.md +144 -0
  139. package/themes/fresh-plate/tailwind.snippet.ts +16 -0
  140. package/themes/fresh-plate/theme.yml +189 -0
  141. package/themes/fresh-plate/tokens.ts +30 -0
  142. package/themes/furniture-modern/THEME.md +94 -0
  143. package/themes/furniture-modern/tokens.ts +176 -0
  144. package/themes/gaming-esports/THEME.md +146 -0
  145. package/themes/gaming-esports/tokens.ts +199 -0
  146. package/themes/gaming-streamer/THEME.md +139 -0
  147. package/themes/gaming-streamer/tokens.ts +201 -0
  148. package/themes/glassmorphic-modern/THEME.md +119 -0
  149. package/themes/glassmorphic-modern/tokens.ts +174 -0
  150. package/themes/government-civic/THEME.md +138 -0
  151. package/themes/government-civic/tokens.ts +164 -0
  152. package/themes/gym-chain/THEME.md +79 -0
  153. package/themes/gym-chain/tokens.ts +196 -0
  154. package/themes/healthcare-bright/THEME.md +95 -0
  155. package/themes/healthcare-bright/tokens.ts +184 -0
  156. package/themes/home-decor/THEME.md +94 -0
  157. package/themes/home-decor/tokens.ts +177 -0
  158. package/themes/hotel-boutique/THEME.md +110 -0
  159. package/themes/hotel-boutique/tokens.ts +179 -0
  160. package/themes/hyperminimal-mono/THEME.md +91 -0
  161. package/themes/hyperminimal-mono/tokens.ts +150 -0
  162. package/themes/indie-art-game/THEME.md +107 -0
  163. package/themes/indie-art-game/tokens.ts +216 -0
  164. package/themes/insurance-legacy/THEME.md +101 -0
  165. package/themes/insurance-legacy/tokens.ts +182 -0
  166. package/themes/insurance-modern/THEME.md +103 -0
  167. package/themes/insurance-modern/tokens.ts +192 -0
  168. package/themes/kaiju-reveal/THEME.md +97 -0
  169. package/themes/kaiju-reveal/tokens.ts +185 -0
  170. package/themes/kinetic-data/THEME.md +172 -0
  171. package/themes/kinetic-data/tailwind.snippet.ts +16 -0
  172. package/themes/kinetic-data/theme.yml +207 -0
  173. package/themes/kinetic-data/tokens.ts +30 -0
  174. package/themes/kinetic-headline/BUILD_BRIEF.md +156 -0
  175. package/themes/kinetic-headline/THEME.md +78 -0
  176. package/themes/kinetic-headline/tailwind.snippet.ts +16 -0
  177. package/themes/kinetic-headline/theme.yml +81 -0
  178. package/themes/kinetic-headline/tokens.ts +26 -0
  179. package/themes/law-firm/THEME.md +108 -0
  180. package/themes/law-firm/tokens.ts +158 -0
  181. package/themes/lawtech-modern/THEME.md +107 -0
  182. package/themes/lawtech-modern/tokens.ts +192 -0
  183. package/themes/linkedin-pro/THEME.md +102 -0
  184. package/themes/linkedin-pro/tokens.ts +174 -0
  185. package/themes/logistics-modern/THEME.md +94 -0
  186. package/themes/logistics-modern/tokens.ts +187 -0
  187. package/themes/magazine-glossy/THEME.md +74 -0
  188. package/themes/magazine-glossy/tokens.ts +158 -0
  189. package/themes/marker-mag/THEME.md +128 -0
  190. package/themes/marker-mag/tailwind.snippet.ts +15 -0
  191. package/themes/marker-mag/theme.yml +159 -0
  192. package/themes/marker-mag/tokens.ts +27 -0
  193. package/themes/marketplace-modern/THEME.md +135 -0
  194. package/themes/marketplace-modern/tokens.ts +186 -0
  195. package/themes/marketplace-vintage/THEME.md +110 -0
  196. package/themes/marketplace-vintage/tokens.ts +185 -0
  197. package/themes/maximalist/THEME.md +96 -0
  198. package/themes/maximalist/tokens.ts +168 -0
  199. package/themes/mid-century/THEME.md +109 -0
  200. package/themes/mid-century/tokens.ts +162 -0
  201. package/themes/motorcycle-brand/THEME.md +86 -0
  202. package/themes/motorcycle-brand/tokens.ts +174 -0
  203. package/themes/museum/THEME.md +83 -0
  204. package/themes/museum/tokens.ts +147 -0
  205. package/themes/music-streaming/THEME.md +101 -0
  206. package/themes/music-streaming/tokens.ts +187 -0
  207. package/themes/music-vinyl/THEME.md +98 -0
  208. package/themes/music-vinyl/tokens.ts +167 -0
  209. package/themes/nature-distilled/BUILD_BRIEF.md +158 -0
  210. package/themes/nature-distilled/THEME.md +81 -0
  211. package/themes/nature-distilled/tailwind.snippet.ts +16 -0
  212. package/themes/nature-distilled/theme.yml +91 -0
  213. package/themes/nature-distilled/tokens.ts +26 -0
  214. package/themes/news-tabloid/THEME.md +72 -0
  215. package/themes/news-tabloid/tokens.ts +158 -0
  216. package/themes/news-tech/THEME.md +75 -0
  217. package/themes/news-tech/tokens.ts +149 -0
  218. package/themes/newsletter/THEME.md +82 -0
  219. package/themes/newsletter/tokens.ts +138 -0
  220. package/themes/newspaper-classic/THEME.md +74 -0
  221. package/themes/newspaper-classic/tokens.ts +159 -0
  222. package/themes/nonprofit-arts/THEME.md +78 -0
  223. package/themes/nonprofit-arts/tokens.ts +157 -0
  224. package/themes/nonprofit-warm/THEME.md +105 -0
  225. package/themes/nonprofit-warm/tokens.ts +188 -0
  226. package/themes/outdoor-adventure/THEME.md +113 -0
  227. package/themes/outdoor-adventure/tokens.ts +181 -0
  228. package/themes/overland-broadside/THEME.md +119 -0
  229. package/themes/overland-broadside/tailwind.snippet.ts +17 -0
  230. package/themes/overland-broadside/theme.yml +138 -0
  231. package/themes/overland-broadside/tokens.ts +27 -0
  232. package/themes/performance-engineered/THEME.md +162 -0
  233. package/themes/performance-engineered/tailwind.snippet.ts +15 -0
  234. package/themes/performance-engineered/theme.yml +193 -0
  235. package/themes/performance-engineered/tokens.ts +29 -0
  236. package/themes/pet-food/THEME.md +78 -0
  237. package/themes/pet-food/tokens.ts +185 -0
  238. package/themes/pharma-clinical/THEME.md +164 -0
  239. package/themes/pharma-clinical/tailwind.snippet.ts +15 -0
  240. package/themes/pharma-clinical/theme.yml +201 -0
  241. package/themes/pharma-clinical/tokens.ts +29 -0
  242. package/themes/pill-editorial/THEME.md +125 -0
  243. package/themes/pill-editorial/tailwind.snippet.ts +15 -0
  244. package/themes/pill-editorial/theme.yml +168 -0
  245. package/themes/pill-editorial/tokens.ts +31 -0
  246. package/themes/podcast-warm/THEME.md +103 -0
  247. package/themes/podcast-warm/tokens.ts +192 -0
  248. package/themes/publisher-indie/THEME.md +78 -0
  249. package/themes/publisher-indie/tokens.ts +148 -0
  250. package/themes/raw-concrete/BUILD_BRIEF.md +157 -0
  251. package/themes/raw-concrete/THEME.md +76 -0
  252. package/themes/raw-concrete/tailwind.snippet.ts +16 -0
  253. package/themes/raw-concrete/theme.yml +88 -0
  254. package/themes/raw-concrete/tokens.ts +27 -0
  255. package/themes/realestate-luxury/THEME.md +94 -0
  256. package/themes/realestate-luxury/tokens.ts +169 -0
  257. package/themes/realestate-marketplace/THEME.md +106 -0
  258. package/themes/realestate-marketplace/tokens.ts +183 -0
  259. package/themes/restaurant-modern/THEME.md +109 -0
  260. package/themes/restaurant-modern/tokens.ts +172 -0
  261. package/themes/runway-fashion/THEME.md +99 -0
  262. package/themes/runway-fashion/tokens.ts +167 -0
  263. package/themes/saturday-morning/THEME.md +117 -0
  264. package/themes/saturday-morning/tokens.ts +281 -0
  265. package/themes/schema.ts +235 -0
  266. package/themes/signal-dark/BUILD_BRIEF.md +168 -0
  267. package/themes/signal-dark/THEME.md +107 -0
  268. package/themes/signal-dark/tokens.ts +181 -0
  269. package/themes/soft-modern/THEME.md +91 -0
  270. package/themes/soft-modern/tokens.ts +166 -0
  271. package/themes/solar-residential/THEME.md +92 -0
  272. package/themes/solar-residential/tokens.ts +176 -0
  273. package/themes/sports-league/THEME.md +180 -0
  274. package/themes/sports-league/tailwind.snippet.ts +15 -0
  275. package/themes/sports-league/theme.yml +213 -0
  276. package/themes/sports-league/tokens.ts +32 -0
  277. package/themes/stadium-sport/THEME.md +114 -0
  278. package/themes/stadium-sport/tokens.ts +187 -0
  279. package/themes/streetwear-hype/THEME.md +100 -0
  280. package/themes/streetwear-hype/tokens.ts +174 -0
  281. package/themes/studio-architect/THEME.md +108 -0
  282. package/themes/studio-architect/tokens.ts +162 -0
  283. package/themes/studio-photographer/THEME.md +88 -0
  284. package/themes/studio-photographer/tokens.ts +164 -0
  285. package/themes/team-kanban/THEME.md +167 -0
  286. package/themes/team-kanban/tailwind.snippet.ts +15 -0
  287. package/themes/team-kanban/theme.yml +209 -0
  288. package/themes/team-kanban/tokens.ts +35 -0
  289. package/themes/telehealth-modern/THEME.md +95 -0
  290. package/themes/telehealth-modern/tokens.ts +197 -0
  291. package/themes/tourism-board/THEME.md +111 -0
  292. package/themes/tourism-board/tokens.ts +173 -0
  293. package/themes/toys-modern/THEME.md +79 -0
  294. package/themes/toys-modern/tokens.ts +200 -0
  295. package/themes/travel-luxury/THEME.md +95 -0
  296. package/themes/travel-luxury/tokens.ts +162 -0
  297. package/themes/vacation-rental/THEME.md +105 -0
  298. package/themes/vacation-rental/tokens.ts +174 -0
  299. package/themes/vault-reel/THEME.md +134 -0
  300. package/themes/vault-reel/tailwind.snippet.ts +16 -0
  301. package/themes/vault-reel/theme.yml +167 -0
  302. package/themes/vault-reel/tokens.ts +30 -0
  303. package/themes/vet-modern/THEME.md +79 -0
  304. package/themes/vet-modern/tokens.ts +194 -0
  305. package/themes/web3-restraint/THEME.md +87 -0
  306. package/themes/web3-restraint/tokens.ts +154 -0
  307. package/themes/wellness-active/THEME.md +102 -0
  308. package/themes/wellness-active/tokens.ts +203 -0
  309. package/themes/wellness-spa/THEME.md +93 -0
  310. package/themes/wellness-spa/tokens.ts +173 -0
  311. package/themes/y2k-chrome/THEME.md +118 -0
  312. package/themes/y2k-chrome/tokens.ts +249 -0
  313. package/themes/yoga-studio/THEME.md +76 -0
  314. package/themes/yoga-studio/tokens.ts +163 -0
@@ -0,0 +1,168 @@
1
+ import type { Direction } from "../schema";
2
+
3
+ // forum-classic — Reddit / Hacker News dense link-first community. Mono-leaning
4
+ // type, upvote orange + Verdana-feel body, near-white surface, hairline borders,
5
+ // vote arrows as a primitive. Tool-first language: text rivers and link lists,
6
+ // no decoration.
7
+ export const forumClassic: Direction = {
8
+ name: "forum-classic",
9
+ ethos:
10
+ "Reddit upvote-orange + density · Hacker News beige + Verdana · Lobste.rs muted indie · Tildes restraint + serif accents · Metafilter blue link tradition",
11
+ references: [
12
+ { brand: "Reddit (old.reddit)", trait: "upvote orange + dense link list + small avatar + nested-comment indent" },
13
+ { brand: "Hacker News", trait: "beige page wash + Verdana-feel body + orange wordmark + flat link list" },
14
+ { brand: "Lobste.rs", trait: "muted indie palette + categorized tags + density" },
15
+ { brand: "Tildes", trait: "restraint + serif accents + group-driven nav" },
16
+ { brand: "Metafilter", trait: "blue link tradition + community-driven thread weight" },
17
+ ],
18
+ feel:
19
+ "Dense, link-first, text-river. The page is a list of titles with vote counts and a small handle — " +
20
+ "no hero images, no cards with shadows, no decoration earned by composition. Mono-leaning sans for everything; " +
21
+ "the only color worth spending is the upvote arrow and the link blue. " +
22
+ "Reads as community-archive — the same shape you'd recognize across Reddit, HN, Lobste.rs, and Metafilter.",
23
+
24
+ fonts: {
25
+ display: {
26
+ family: "IBM Plex Sans",
27
+ fallback: ["Verdana", "Geneva", "Tahoma", "sans-serif"],
28
+ from: "HN/Reddit Verdana lineage — system-sans humanist, condensed enough for dense titles",
29
+ googleFont: "IBM+Plex+Sans",
30
+ weights: [400, 500, 600, 700],
31
+ },
32
+ body: {
33
+ family: "IBM Plex Sans",
34
+ fallback: ["Verdana", "Geneva", "Tahoma", "sans-serif"],
35
+ from: "same family — single-face forum convention",
36
+ googleFont: "IBM+Plex+Sans",
37
+ weights: [400, 500, 600],
38
+ },
39
+ mono: {
40
+ family: "IBM Plex Mono",
41
+ fallback: ["ui-monospace", "Consolas", "SFMono-Regular", "monospace"],
42
+ from: "post-meta, code-block in comments, vote-counts — forum tabular feel",
43
+ googleFont: "IBM+Plex+Mono",
44
+ weights: [400, 500, 700],
45
+ },
46
+ },
47
+
48
+ typography: {
49
+ headingTracking: "-0.005em",
50
+ bodyTracking: "0",
51
+ fontFeatureSettings: '"tnum", "ss01"',
52
+ h1ScaleClamp: "clamp(1.5rem, 3vw, 2rem)", // forums don't do marketing-hero sizes
53
+ bodyBaseSize: "0.875rem", // 14px — forum-density default
54
+ bodyLineHeight: "1.45",
55
+ },
56
+
57
+ colors: {
58
+ background: { hsl: "36 30% 96%", from: "HN beige page wash — warm off-white, never gray" },
59
+ foreground: { hsl: "0 0% 12%", from: "near-black ink — Reddit text, high contrast on beige" },
60
+ card: { hsl: "0 0% 100%", from: "white thread/comment card — minimal lift" },
61
+ popover: { hsl: "0 0% 100%", from: "same as card" },
62
+ primary: { hsl: "16 100% 50%", from: "Reddit upvote orange — also HN wordmark orange, the community color" },
63
+ primaryForeground: { hsl: "0 0% 100%", from: "white on orange — used for selected/active states only" },
64
+ secondary: { hsl: "36 20% 92%", from: "deeper beige — visited row, alt-row striping" },
65
+ secondaryForeground: { hsl: "0 0% 18%", from: "ink on beige" },
66
+ muted: { hsl: "36 20% 92%", from: "same as secondary — quiet panels, code-block bg" },
67
+ mutedForeground: { hsl: "0 0% 42%", from: "Reddit meta-gray — submitted-by, time-ago" },
68
+ accent: { hsl: "16 100% 94%", from: "primary-tinted bg — selected row, hover-hint" },
69
+ accentForeground: { hsl: "16 90% 32%", from: "deeper orange on tinted accent" },
70
+ border: { hsl: "36 15% 86%", from: "warm hairline — visible but not assertive" },
71
+ input: { hsl: "36 15% 86%", from: "same as border" },
72
+ ring: { hsl: "16 100% 50%", from: "primary, focus only" },
73
+ destructive: { hsl: "0 70% 45%", from: "downvote-deeper / report / removed-comment" },
74
+ destructiveForeground: { hsl: "0 0% 100%", from: "white on red" },
75
+ brand: {
76
+ "upvote-orange": { hsl: "16 100% 50%", from: "= primary; Reddit arrow + HN wordmark + upvoted state" },
77
+ "downvote-blue": { hsl: "232 60% 48%", from: "Reddit downvote indigo-blue — also Metafilter classic link blue" },
78
+ "link-blue": { hsl: "232 70% 42%", from: "Metafilter / pre-2010 web link blue — unvisited link" },
79
+ "link-purple": { hsl: "278 50% 38%", from: "visited-link purple — preserved web tradition" },
80
+ beige: { hsl: "36 30% 96%", from: "= background; HN page wash, the canvas itself" },
81
+ "tag-green": { hsl: "142 35% 38%", from: "Lobste.rs category-tag muted green" },
82
+ "tag-purple": { hsl: "270 30% 45%", from: "Lobste.rs category-tag muted purple" },
83
+ "mod-distinguished": { hsl: "142 55% 32%", from: "Reddit moderator-distinguished green name" },
84
+ },
85
+ },
86
+
87
+ spacing: {
88
+ base: 4,
89
+ scale: [2, 4, 6, 8, 10, 12, 16, 20, 24, 32, 40], // tight — forum density
90
+ containerMax: "max-w-5xl",
91
+ containerPadding: "px-3 lg:px-4",
92
+ sectionPadding: {
93
+ hero: "pt-8 pb-6 lg:pt-12 lg:pb-8", // forums barely have heroes
94
+ default: "py-8 lg:py-12",
95
+ tight: "py-6 lg:py-8",
96
+ },
97
+ },
98
+
99
+ radius: {
100
+ base: "0.2rem", // 3px — barely-rounded, HN/old-reddit chrome
101
+ pillsAllowed: false, // tags are tiny bordered rects, not pills
102
+ },
103
+
104
+ shadows: {
105
+ style: "minimal",
106
+ utilities: {
107
+ "thread-row-hover":
108
+ "inset 0 0 0 1px hsl(36 15% 80%)", // hover state is a deeper border, not a drop shadow
109
+ "hairline-rule":
110
+ "0 1px 0 hsl(36 15% 86%)", // single dividing hairline between rows
111
+ },
112
+ },
113
+
114
+ motion: {
115
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)",
116
+ durations: {
117
+ reveal: 200, // fast — pages of threads should render immediately
118
+ loop: 1000,
119
+ ambient: 0, // forums have no ambient motion
120
+ },
121
+ keyframes: {
122
+ "vote-bounce": {
123
+ css:
124
+ "0% { transform: translateY(0); }\n" +
125
+ "40% { transform: translateY(-3px); }\n" +
126
+ "100% { transform: translateY(0); }",
127
+ defaultDuration: 240,
128
+ iteration: "once",
129
+ purpose: "upvote/downvote tap — small bounce on the arrow only",
130
+ },
131
+ "row-flash": {
132
+ css:
133
+ "0% { background-color: hsl(16 100% 94%); }\n" +
134
+ "100% { background-color: transparent; }",
135
+ defaultDuration: 1000,
136
+ iteration: "once",
137
+ purpose: "newly-loaded thread row flash — orange-tinted, then fades to baseline",
138
+ },
139
+ },
140
+ respectsReducedMotion: true,
141
+ },
142
+
143
+ density: "high",
144
+
145
+ patterns: {
146
+ button:
147
+ "Default = small bordered rect, foreground text, near-square (rounded-sm only). " +
148
+ "Primary action = orange-bordered rect with orange text (filled-orange reserved for the upvoted/selected state). " +
149
+ "No pills. No gradients. Buttons are inline-sized to their label.",
150
+ card:
151
+ "Threads and comments are rows, not cards — hairline-top dividers, no fill. " +
152
+ "Where a true card is needed (sidebar widget), use white bg with 1px border and rounded-sm. " +
153
+ "Padding is tight (p-3 lg:p-4). No drop shadows.",
154
+ input:
155
+ "Full bordered box, rounded-sm. Focus = 1px orange border swap. " +
156
+ "Textarea for comment-compose is full-width with mono helper text below ('formatting help').",
157
+ cta:
158
+ "Inline text-link in link-blue is the dominant CTA — every thread title is a link, not a button. " +
159
+ "Vote arrows are the action primitive; the upvote count next to them is the score.",
160
+ },
161
+
162
+ details: {
163
+ selectionBg: "hsl(var(--primary) / 0.3)",
164
+ selectionFg: "hsl(var(--foreground))",
165
+ focusRing: "1px solid hsl(var(--ring))",
166
+ scrollbarStyle: "auto",
167
+ },
168
+ };
@@ -0,0 +1,144 @@
1
+ # Fresh Plate
2
+
3
+ > Monochromatic cleantech-brand register — warm light-beige canvas at
4
+
5
+ **Slug:** `fresh-plate` — **Surface:** web — **Density:** airy
6
+
7
+ ## Influence
8
+
9
+ Modern European cleantech and design-forward hardware brands (the
10
+ register held by category-leading appliance makers who dress like
11
+ design brands instead of like appliance brands — Dyson at its most
12
+ minimal, Aesop for the type discipline, Vitra for the neutral
13
+ restraint). Distinct from other Family D bases through the SINGLE-
14
+ HUE monochrome discipline: no accent-color trio, no secondary
15
+ gradient, no candy-palette punctuation. One dark-saturated ink hue
16
+ does 100% of the work.
17
+
18
+
19
+ ## Signature move
20
+
21
+ Warm light-beige canvas at #faf7f0 — the register's non-negotiable
22
+ base (deliberately NOT #F4F1EA claude-cream, deliberately NOT
23
+ #ffffff white). Every card, button, input, border, arrow, divider
24
+ ships at 0px border radius. Every ink color is a single deep-
25
+ forest-green hue (#053725) with hover / active variants (#005d3b,
26
+ #002e1d) — NO candy accent palette, NO secondary gradient. The hero
27
+ is a 3-line stacked MONUMENTAL display: line 1 = "THE" (~120px),
28
+ line 2 = "QUIET" (~120px), line 3 = "REFRESH." (~120px), all
29
+ Altform-style 900-weight uppercase at -1px tracking, centered
30
+ horizontally, ink deep-forest-green. Directly beneath the type
31
+ block: a SINGLE FULL-BLEED PRODUCT PHOTOGRAPH of the physical
32
+ device, extending vertically past the type — the type sits ON TOP
33
+ of the product image with a subtle offset. To the right of the
34
+ type block (bottom-right column): a single body-copy paragraph in
35
+ 15px Altform mixed case, forest ink, ~200px wide. Below the type
36
+ and next to the product: a SINGLE CIRCULAR "DISCOVER ↓" AFFORDANCE
37
+ (~64px diameter, deep-forest fill, cream arrow, sharp exterior
38
+ boundary but the disc itself is round — the ONE circle in the
39
+ composition, deliberately misfit as a discovery cue).
40
+ Top nav strip: wordmark left (Altform 900 uppercase with a small
41
+ drop icon in the accent color to the left), horizontal link row
42
+ center (Product / Range / Simulate / FAQ / Join / Lang), a filled
43
+ deep-forest-green rectangular "Contact →" button right-aligned.
44
+ Below the hero: sections alternate between DARK-INK-ON-CREAM
45
+ and INVERTED FOREST-CANVAS-WITH-CREAM-INK bands, with big
46
+ monumental section headlines and full-bleed product photography.
47
+ A stat callout runs a real-time-feeling counter from 0 to 12,483
48
+ homes. Footer: dark forest canvas with a giant Altform wordmark,
49
+ a stack of utility links, and a small acknowledgement paragraph.
50
+ Six bespoke SVG marks (drop icon, arrow-down, arrow-right,
51
+ temperature-line, home-outline, leaf-outline) are dropped as
52
+ PUNCTUATION at specific compositional moments — never as a uniform
53
+ icon row.
54
+
55
+ ## Palette
56
+
57
+ - **bg:** `#faf7f0`
58
+ - **surface:** `#f2f7f5`
59
+ - **ink:** `#053725`
60
+ - **accent:** `#005d3b`
61
+ - **secondary:** `#f9f7e7`
62
+
63
+ ## Typography
64
+
65
+ - **Display:** Altform (reference proprietary face — a broad geometric sans with a slightly-expanded proportion and quirky letterforms at 900 weight). Free fallback stack — "Archivo Black", "Anton", "Bebas Neue", "Space Grotesk", system-ui, sans-serif. Weight 900, UPPERCASE always, letter-spacing -1px (tight negative tracking is the register's typographic fingerprint). Top of scale ~45px in the reference but I'll scale higher for the site-mockup context — up to 128px hero at the section-renderer scale, since the mockup viewport gives more type real estate than the reference's ~1440px browser width.
66
+ - **Body:** Altform 400-700 mixed case, 15-16px body, line-height 1.5. The reference uses Altform for both display and body — one type family doing everything. Free fallback keeps the family — Archivo 400/700, then Space Grotesk. Small labels get 12px 600 sentence case.
67
+ - **Mono:** none. Fresh Plate is a consumer product-brand surface. Mono has no role.
68
+ - **Scale:** 1.25 (perfect fourth — restrained, so composition and product photography carry the drama)
69
+
70
+ ## Motion
71
+
72
+ Ships live in the section renderer (no external dependencies):
73
+ 1. Hero type stagger reveal — the 3-line stacked "THE / QUIET / REFRESH." display type animates up from translateY(40px) + opacity 0 → 1 with 140ms per-line stagger + 900ms cubic-bezier(0.23,1,0.32,1) on first paint.
74
+ 2. Product photograph subtle scale-in — the full-bleed product image opens from scale(0.98) + opacity 0.85 → scale(1) + opacity 1 over 1200ms cubic-bezier(0.23,1,0.32,1) on first paint.
75
+ 3. Découvrir arrow bounce — the circular "Découvrir ↓" affordance bounces its arrow 4px down and back on a 2s ease-in-out loop, subtle attention pull.
76
+ 4. Section reveals on IntersectionObserver — each below-fold section (product feature, split section, testimonials) fades in from opacity 0 + translateY(24px) → 0 over 700ms cubic-bezier(0.23,1,0.32,1) at 25% visibility threshold.
77
+ 5. Stat counter — the featured stat "12,483 homes" rolls up from 0 → target on first scroll into view via requestAnimationFrame, 2000ms ease-out.
78
+ 6. Nav CTA hover — background darkens from #053725 to #002e1d and the arrow translates 4px right over 200ms cubic-bezier(0.23,1,0.32,1).
79
+ 7. Section image parallax — the full-bleed product photograph in the mid-page split translates -8% Y as the user scrolls past it, tied to scroll position via a single passive scroll listener.
80
+ 8. prefers-reduced-motion: reduce — hero type shows at final position, product photo shows at scale 1, arrow doesn't bounce, section reveals become instant, stat counter shows final value, parallax disabled. Hover state changes still fire.
81
+
82
+ Customer installs these for the deeper tier:
83
+ - Lenis — smooth inertial scroll (the tall product-photo page benefits from inertial cadence).
84
+ - GSAP for the display-type letter-by-letter draw on the hero wordmark on first paint.
85
+ - Real Vimeo/Cloudinary video player for a product-demo hero video if the customer has one.
86
+
87
+ Motion character: quiet, confident, restrained — cleantech-premium.
88
+ Custom cubic-bezier(0.23,1,0.32,1) for all reveals (matches the
89
+ reference's own --ease-out variable). The register lives at
90
+ premium-cleantech, not marketing-startup — motion should feel like
91
+ a Muji product page, not a SaaS product tour.
92
+
93
+
94
+ ## Imagery
95
+
96
+ FULL-BLEED product photography of the physical device — the reference
97
+ uses a matte-white A/C-alternative appliance shot in soft directional
98
+ light against the cream canvas, cropped at chest-height to bleed
99
+ vertically past the display type. FPO imagery here should read as
100
+ studio product photography (not warehouse-catalog stock, not
101
+ gradient placeholders, not warm-radial glow decoration). The product
102
+ photo IS the composition anchor — every section that shows the
103
+ device shows it as the primary visual, with type as caption.
104
+ Secondary imagery: warm interior photography (kitchen, living room
105
+ scenes with the device installed). NO warehouse-technical
106
+ photography. NO 3D-rendered product mockups with soft-drop-shadows.
107
+ NO warm-radial-gradient placeholder fills.
108
+
109
+ ## Best for
110
+
111
+ - Cleantech and green-hardware brands (heat pumps, solar, EV chargers, home battery)
112
+ - Modern European appliance brands with a design-forward register
113
+ - Boutique consumer-hardware brands (audio, kitchen, home automation)
114
+ - Design-forward small-appliance brands (coffee, water filtration, air quality)
115
+ - Direct-to-consumer premium hardware (mattresses, furniture, home goods) leaning restraint
116
+ - Architecture and interior-product brands with a cleantech-adjacent register
117
+
118
+ ## Reject if
119
+
120
+ _Director grades each of the following as a pass/fail check. Any violation blocks the theme._
121
+
122
+ - Dark canvas as the primary background — the reference's canvas is CREAM at #faf7f0. Swapping to a dark canvas collapses the register into generic-atmospheric slop and inverts the entire type/ink relationship.
123
+ - White canvas (#FFFFFF) or claude-cream (#F4F1EA) — #faf7f0 is measured and deliberately WARMER than pure white but LESS warm than claude-cream. Swapping to either kills the specific warmth this base carries.
124
+ - Multi-color accent palette (yellow, lime, orange, pink) as punctuation — the whole register's move is SINGLE-HUE MONOCHROME. Every ink color on the page is deep forest green (#053725, #005d3b, #002e1d). Introducing any accent color from another hue family collapses the discipline.
125
+ - Rounded corners on cards, buttons, inputs, borders, or dividers — 0px radius everywhere. The ONE circular affordance is the DISCOVER button, which is a full disc, not a border-radius.
126
+ - Sans-serif display at low weight — the display face MUST be a 900-weight bold-geometric sans (Altform reference; Archivo Black / Anton / Bebas Neue fallback). Inter Display at regular weight has the wrong register.
127
+ - Mono-caps eyebrow labels — the reference has ZERO eyebrow slop. No 'SECTION · X' plates, no 'ISSUE 04' metadata rows, no 'BY R.IWASAKI' bylines. The monumental display type carries the register, not eyebrow chrome.
128
+ - Uniform 3-column feature grids — sections alternate rhythm (image-left / image-right, full-bleed / banded). Uniform grids collapse this into generic-marketing slop.
129
+ - Warm-radial gradient fills as image fallbacks — the FPO photography must read as studio product photography. Warm-glow gradients are the AI-tell for placeholder imagery.
130
+ - Drop shadows, glassmorphism, blur — the reference has ZERO. Every surface sits FLAT on the canvas.
131
+ - Cycling headline words / auto-advancing sliders — the reference has none. The monumental type is STATIC; the product photograph is STATIC. Motion here is reveal-on-scroll + one bouncing arrow + one counter. Any cycling-word or auto-slider collapses the register into marketing slop.
132
+
133
+ ## Banned defaults (inherited + theme-specific)
134
+
135
+ - claude-cream (#F4F1EA + serif + #D97757) — this theme's canvas is DELIBERATELY #faf7f0, warmer than pure white but distinct from claude-cream.
136
+ - void+acid (near-black bg + single bright acid-green or vermilion accent)
137
+ - broadsheet-on-noneditorial (hairline rules + zero border-radius + newspaper columns on non-editorial content)
138
+ - tech-bro purple gradient (purple→blue gradient hero + centered headline + double CTA + emoji icons)
139
+ - uniform-everything (identical padding + one weight of one sans doing every job + rounded-2xl + shadow-md cards)
140
+ - multi-hue-accent-flood (this theme's whole discipline is SINGLE-HUE MONOCHROME forest green. Introducing yellow / pink / cyan / any other hue collapses the register into candy-slop.)
141
+ - dark-canvas-inversion (canvas is warm CREAM at #faf7f0. Swapping to dark canvas inverts the type/ink relationship and collapses the register into generic-atmospheric slop.)
142
+ - eyebrow-any (this theme's reference has ZERO eyebrow chrome. Any 'SECTION · X' / 'CH.04' / mono-caps meta label is a violation of the closed CHROME INVENTORY.)
143
+ - static-uniform-composition (this theme requires visible motion — hero type stagger, product-photo scale-in, discover-arrow bounce, section reveal on scroll, stat counter. A static composition without any of these fails the register.)
144
+ - warm-radial-fpo (image fallbacks must read as studio product photography. Warm-glow radial gradients are the AI-tell for placeholder decoration.)
@@ -0,0 +1,16 @@
1
+ // Generated from theme.yml. Merge into your tailwind.config.ts under theme.extend.
2
+ // slug: fresh-plate
3
+ export const freshPlateTailwindExtend = {
4
+ colors: {
5
+ bg: "#faf7f0",
6
+ surface: "#f2f7f5",
7
+ ink: "#053725",
8
+ accent: "#005d3b",
9
+ secondary: "#f9f7e7",
10
+ },
11
+ fontFamily: {
12
+ display: ["Altform (reference proprietary face — a broad geometric sans with a slightly-expanded proportion and quirky letterforms at 900 weight). Free fallback stack — \"Archivo Black\", \"Anton\", \"Bebas Neue\", \"Space Grotesk\", system-ui, sans-serif. Weight 900, UPPERCASE always, letter-spacing -1px (tight negative tracking is the register's typographic fingerprint). Top of scale ~45px in the reference but I'll scale higher for the site-mockup context — up to 128px hero at the section-renderer scale, since the mockup viewport gives more type real estate than the reference's ~1440px browser width."],
13
+ body: ["Altform 400-700 mixed case, 15-16px body, line-height 1.5. The reference uses Altform for both display and body — one type family doing everything. Free fallback keeps the family — Archivo 400/700, then Space Grotesk. Small labels get 12px 600 sentence case."],
14
+ mono: ["none. Fresh Plate is a consumer product-brand surface. Mono has no role."],
15
+ },
16
+ };
@@ -0,0 +1,189 @@
1
+ # Fresh Plate — Family D, Contemporary Web.
2
+ #
3
+ # Monochromatic cleantech-brand register. Warm light-beige canvas
4
+ # (#faf7f0) with deep-forest-green ink (#053725) doing 100% of the
5
+ # work — display type, buttons, borders, dividers, arrow marks, all
6
+ # in the same forest hue. No candy accents. No secondary palette.
7
+ # Sharp corners everywhere (0px radius).
8
+ #
9
+ # The screenshot is the ground truth. The auto-generated spec has
10
+ # canvas/ink roles inverted — it labels #053725 as the background,
11
+ # but the reference clearly renders that color as the ink of the
12
+ # monumental display type on a warm CREAM canvas. Building to the
13
+ # pixels, not the mislabeled tokens.
14
+ #
15
+ # Authored from Matt's provided design brief (2026-07-04,
16
+ # caeli-energie.com reference — a French clean-tech HVAC brand
17
+ # building A/C-alternative appliances). Placeholder brand: "BRISE" —
18
+ # a fictional refresh/cooling brand. Original name, original copy —
19
+ # no reproductions. The register expresses "quiet cleantech confidence"
20
+ # through monumental Altform-style display + full-bleed product
21
+ # photography + one confident forest hue.
22
+ #
23
+ # Fourteenth theme via the v2 harness. First Family D cleantech-brand
24
+ # base. Ninth NEW BASE.
25
+ #
26
+ # Alternative slugs considered — verdant-plate (florid), forest-plate
27
+ # (too literal), fresh-broadside (broadside used by overland), canopy-
28
+ # block (drops the poster-plate register), cleantech-monochrome (too
29
+ # jargon). Fresh Plate picked because "fresh" carries the fraîche-
30
+ # without-attribution register and "plate" carries the print-plate
31
+ # poster composition register. Both common-noun and aesthetic — no
32
+ # right-of-publicity exposure.
33
+
34
+ name: Fresh Plate
35
+ concept: Monochromatic cleantech-brand register — warm light-beige canvas at #faf7f0 (never white) with deep-forest-green ink (#053725) doing 100% of the design work. Monumental Altform-style 900-weight uppercase display at -1px tracking, full-bleed product photography under directional light, and every button / border / arrow / divider set in the same forest green — no candy accents, no secondary palette, one confident hue.
36
+ influence: |
37
+ Modern European cleantech and design-forward hardware brands (the
38
+ register held by category-leading appliance makers who dress like
39
+ design brands instead of like appliance brands — Dyson at its most
40
+ minimal, Aesop for the type discipline, Vitra for the neutral
41
+ restraint). Distinct from other Family D bases through the SINGLE-
42
+ HUE monochrome discipline: no accent-color trio, no secondary
43
+ gradient, no candy-palette punctuation. One dark-saturated ink hue
44
+ does 100% of the work.
45
+
46
+ family: D
47
+ base_number: 35
48
+ base_note: |
49
+ New-base candidate in Family D, cleantech-brand subregion. Distinct
50
+ from other Family D bases through the SINGLE-HUE MONOCHROME
51
+ DISCIPLINE and MONUMENTAL DISPLAY-FIRST composition. Dark-Premium
52
+ (signal-dark) is dark canvas + cyan glow + technical bento. Kinetic
53
+ Headline is kinetic-marketing display. Bento Modular is grid-driven
54
+ dashboard. Nature Distilled is earthy grounded warmth. Arc Stack is
55
+ dark protocol infrastructure. Fresh Plate fills the LIGHT-CREAM
56
+ MONOCHROMATIC-CLEANTECH slot the family has been missing.
57
+
58
+ render_url: http://localhost:5173/themes/fresh-plate
59
+
60
+ surface: web
61
+
62
+ typography:
63
+ display: Altform (reference proprietary face — a broad geometric sans with a slightly-expanded proportion and quirky letterforms at 900 weight). Free fallback stack — "Archivo Black", "Anton", "Bebas Neue", "Space Grotesk", system-ui, sans-serif. Weight 900, UPPERCASE always, letter-spacing -1px (tight negative tracking is the register's typographic fingerprint). Top of scale ~45px in the reference but I'll scale higher for the site-mockup context — up to 128px hero at the section-renderer scale, since the mockup viewport gives more type real estate than the reference's ~1440px browser width.
64
+ body: Altform 400-700 mixed case, 15-16px body, line-height 1.5. The reference uses Altform for both display and body — one type family doing everything. Free fallback keeps the family — Archivo 400/700, then Space Grotesk. Small labels get 12px 600 sentence case.
65
+ mono: none. Fresh Plate is a consumer product-brand surface. Mono has no role.
66
+ scale: 1.25 (perfect fourth — restrained, so composition and product photography carry the drama)
67
+ eyebrow_exception: |
68
+ Fresh Plate does NOT need a mono-caps eyebrow exception. The
69
+ reference has no mono-caps meta labels or eyebrow chrome — the
70
+ monumental display type carries the register, not eyebrow slop.
71
+ Any use of a mono-caps eyebrow in this theme is a slop-blocklist
72
+ violation and must be caught in the harness grade.
73
+
74
+ palette:
75
+ bg: "#faf7f0" # canvas — warm light beige (light-beige from author's own CSS vars)
76
+ surface: "#f2f7f5" # very slightly cooler cream for section bands
77
+ ink: "#053725" # deep forest green — primary ink + display type + buttons + borders
78
+ accent: "#005d3b" # slightly-brighter forest — hover state + secondary emphasis
79
+ cream: "#faf7f0" # alias for bg
80
+ darkInk: "#002e1d" # darker forest — pressed / active states
81
+ mute: "#6c8c81" # gray-green — secondary text + captions
82
+ secondary: "#f9f7e7" # deeper beige — inverted band card on cream
83
+
84
+ density: airy
85
+
86
+ motion: |
87
+ Ships live in the section renderer (no external dependencies):
88
+ 1. Hero type stagger reveal — the 3-line stacked "THE / QUIET / REFRESH." display type animates up from translateY(40px) + opacity 0 → 1 with 140ms per-line stagger + 900ms cubic-bezier(0.23,1,0.32,1) on first paint.
89
+ 2. Product photograph subtle scale-in — the full-bleed product image opens from scale(0.98) + opacity 0.85 → scale(1) + opacity 1 over 1200ms cubic-bezier(0.23,1,0.32,1) on first paint.
90
+ 3. Découvrir arrow bounce — the circular "Découvrir ↓" affordance bounces its arrow 4px down and back on a 2s ease-in-out loop, subtle attention pull.
91
+ 4. Section reveals on IntersectionObserver — each below-fold section (product feature, split section, testimonials) fades in from opacity 0 + translateY(24px) → 0 over 700ms cubic-bezier(0.23,1,0.32,1) at 25% visibility threshold.
92
+ 5. Stat counter — the featured stat "12,483 homes" rolls up from 0 → target on first scroll into view via requestAnimationFrame, 2000ms ease-out.
93
+ 6. Nav CTA hover — background darkens from #053725 to #002e1d and the arrow translates 4px right over 200ms cubic-bezier(0.23,1,0.32,1).
94
+ 7. Section image parallax — the full-bleed product photograph in the mid-page split translates -8% Y as the user scrolls past it, tied to scroll position via a single passive scroll listener.
95
+ 8. prefers-reduced-motion: reduce — hero type shows at final position, product photo shows at scale 1, arrow doesn't bounce, section reveals become instant, stat counter shows final value, parallax disabled. Hover state changes still fire.
96
+
97
+ Customer installs these for the deeper tier:
98
+ - Lenis — smooth inertial scroll (the tall product-photo page benefits from inertial cadence).
99
+ - GSAP for the display-type letter-by-letter draw on the hero wordmark on first paint.
100
+ - Real Vimeo/Cloudinary video player for a product-demo hero video if the customer has one.
101
+
102
+ Motion character: quiet, confident, restrained — cleantech-premium.
103
+ Custom cubic-bezier(0.23,1,0.32,1) for all reveals (matches the
104
+ reference's own --ease-out variable). The register lives at
105
+ premium-cleantech, not marketing-startup — motion should feel like
106
+ a Muji product page, not a SaaS product tour.
107
+
108
+ signature: |
109
+ Warm light-beige canvas at #faf7f0 — the register's non-negotiable
110
+ base (deliberately NOT #F4F1EA claude-cream, deliberately NOT
111
+ #ffffff white). Every card, button, input, border, arrow, divider
112
+ ships at 0px border radius. Every ink color is a single deep-
113
+ forest-green hue (#053725) with hover / active variants (#005d3b,
114
+ #002e1d) — NO candy accent palette, NO secondary gradient. The hero
115
+ is a 3-line stacked MONUMENTAL display: line 1 = "THE" (~120px),
116
+ line 2 = "QUIET" (~120px), line 3 = "REFRESH." (~120px), all
117
+ Altform-style 900-weight uppercase at -1px tracking, centered
118
+ horizontally, ink deep-forest-green. Directly beneath the type
119
+ block: a SINGLE FULL-BLEED PRODUCT PHOTOGRAPH of the physical
120
+ device, extending vertically past the type — the type sits ON TOP
121
+ of the product image with a subtle offset. To the right of the
122
+ type block (bottom-right column): a single body-copy paragraph in
123
+ 15px Altform mixed case, forest ink, ~200px wide. Below the type
124
+ and next to the product: a SINGLE CIRCULAR "DISCOVER ↓" AFFORDANCE
125
+ (~64px diameter, deep-forest fill, cream arrow, sharp exterior
126
+ boundary but the disc itself is round — the ONE circle in the
127
+ composition, deliberately misfit as a discovery cue).
128
+ Top nav strip: wordmark left (Altform 900 uppercase with a small
129
+ drop icon in the accent color to the left), horizontal link row
130
+ center (Product / Range / Simulate / FAQ / Join / Lang), a filled
131
+ deep-forest-green rectangular "Contact →" button right-aligned.
132
+ Below the hero: sections alternate between DARK-INK-ON-CREAM
133
+ and INVERTED FOREST-CANVAS-WITH-CREAM-INK bands, with big
134
+ monumental section headlines and full-bleed product photography.
135
+ A stat callout runs a real-time-feeling counter from 0 to 12,483
136
+ homes. Footer: dark forest canvas with a giant Altform wordmark,
137
+ a stack of utility links, and a small acknowledgement paragraph.
138
+ Six bespoke SVG marks (drop icon, arrow-down, arrow-right,
139
+ temperature-line, home-outline, leaf-outline) are dropped as
140
+ PUNCTUATION at specific compositional moments — never as a uniform
141
+ icon row.
142
+
143
+ imagery: |
144
+ FULL-BLEED product photography of the physical device — the reference
145
+ uses a matte-white A/C-alternative appliance shot in soft directional
146
+ light against the cream canvas, cropped at chest-height to bleed
147
+ vertically past the display type. FPO imagery here should read as
148
+ studio product photography (not warehouse-catalog stock, not
149
+ gradient placeholders, not warm-radial glow decoration). The product
150
+ photo IS the composition anchor — every section that shows the
151
+ device shows it as the primary visual, with type as caption.
152
+ Secondary imagery: warm interior photography (kitchen, living room
153
+ scenes with the device installed). NO warehouse-technical
154
+ photography. NO 3D-rendered product mockups with soft-drop-shadows.
155
+ NO warm-radial-gradient placeholder fills.
156
+
157
+ best_for:
158
+ - Cleantech and green-hardware brands (heat pumps, solar, EV chargers, home battery)
159
+ - Modern European appliance brands with a design-forward register
160
+ - Boutique consumer-hardware brands (audio, kitchen, home automation)
161
+ - Design-forward small-appliance brands (coffee, water filtration, air quality)
162
+ - Direct-to-consumer premium hardware (mattresses, furniture, home goods) leaning restraint
163
+ - Architecture and interior-product brands with a cleantech-adjacent register
164
+
165
+ avoid:
166
+ - "Dark canvas as the primary background — the reference's canvas is CREAM at #faf7f0. Swapping to a dark canvas collapses the register into generic-atmospheric slop and inverts the entire type/ink relationship."
167
+ - "White canvas (#FFFFFF) or claude-cream (#F4F1EA) — #faf7f0 is measured and deliberately WARMER than pure white but LESS warm than claude-cream. Swapping to either kills the specific warmth this base carries."
168
+ - "Multi-color accent palette (yellow, lime, orange, pink) as punctuation — the whole register's move is SINGLE-HUE MONOCHROME. Every ink color on the page is deep forest green (#053725, #005d3b, #002e1d). Introducing any accent color from another hue family collapses the discipline."
169
+ - "Rounded corners on cards, buttons, inputs, borders, or dividers — 0px radius everywhere. The ONE circular affordance is the DISCOVER button, which is a full disc, not a border-radius."
170
+ - "Sans-serif display at low weight — the display face MUST be a 900-weight bold-geometric sans (Altform reference; Archivo Black / Anton / Bebas Neue fallback). Inter Display at regular weight has the wrong register."
171
+ - "Mono-caps eyebrow labels — the reference has ZERO eyebrow slop. No 'SECTION · X' plates, no 'ISSUE 04' metadata rows, no 'BY R.IWASAKI' bylines. The monumental display type carries the register, not eyebrow chrome."
172
+ - "Uniform 3-column feature grids — sections alternate rhythm (image-left / image-right, full-bleed / banded). Uniform grids collapse this into generic-marketing slop."
173
+ - "Warm-radial gradient fills as image fallbacks — the FPO photography must read as studio product photography. Warm-glow gradients are the AI-tell for placeholder imagery."
174
+ - "Drop shadows, glassmorphism, blur — the reference has ZERO. Every surface sits FLAT on the canvas."
175
+ - "Cycling headline words / auto-advancing sliders — the reference has none. The monumental type is STATIC; the product photograph is STATIC. Motion here is reveal-on-scroll + one bouncing arrow + one counter. Any cycling-word or auto-slider collapses the register into marketing slop."
176
+
177
+ banned_defaults:
178
+ # Global blocklist from BESPOKE_THEME_SYSTEM.md
179
+ - "claude-cream (#F4F1EA + serif + #D97757) — this theme's canvas is DELIBERATELY #faf7f0, warmer than pure white but distinct from claude-cream."
180
+ - "void+acid (near-black bg + single bright acid-green or vermilion accent)"
181
+ - "broadsheet-on-noneditorial (hairline rules + zero border-radius + newspaper columns on non-editorial content)"
182
+ - "tech-bro purple gradient (purple→blue gradient hero + centered headline + double CTA + emoji icons)"
183
+ - "uniform-everything (identical padding + one weight of one sans doing every job + rounded-2xl + shadow-md cards)"
184
+ # Base-specific
185
+ - "multi-hue-accent-flood (this theme's whole discipline is SINGLE-HUE MONOCHROME forest green. Introducing yellow / pink / cyan / any other hue collapses the register into candy-slop.)"
186
+ - "dark-canvas-inversion (canvas is warm CREAM at #faf7f0. Swapping to dark canvas inverts the type/ink relationship and collapses the register into generic-atmospheric slop.)"
187
+ - "eyebrow-any (this theme's reference has ZERO eyebrow chrome. Any 'SECTION · X' / 'CH.04' / mono-caps meta label is a violation of the closed CHROME INVENTORY.)"
188
+ - "static-uniform-composition (this theme requires visible motion — hero type stagger, product-photo scale-in, discover-arrow bounce, section reveal on scroll, stat counter. A static composition without any of these fails the register.)"
189
+ - "warm-radial-fpo (image fallbacks must read as studio product photography. Warm-glow radial gradients are the AI-tell for placeholder decoration.)"
@@ -0,0 +1,30 @@
1
+ // Generated from theme.yml. Do not edit by hand — edit theme.yml + re-materialize.
2
+
3
+ export const tokens = {
4
+ slug: "fresh-plate",
5
+ family: "D",
6
+ base: "35",
7
+ palette: {
8
+ "bg": "#faf7f0",
9
+ "surface": "#f2f7f5",
10
+ "ink": "#053725",
11
+ "accent": "#005d3b",
12
+ "cream": "#faf7f0",
13
+ "darkInk": "#002e1d",
14
+ "mute": "#6c8c81",
15
+ "secondary": "#f9f7e7"
16
+ },
17
+ typography: {
18
+ "display": "Altform (reference proprietary face — a broad geometric sans with a slightly-expanded proportion and quirky letterforms at 900 weight). Free fallback stack — \"Archivo Black\", \"Anton\", \"Bebas Neue\", \"Space Grotesk\", system-ui, sans-serif. Weight 900, UPPERCASE always, letter-spacing -1px (tight negative tracking is the register's typographic fingerprint). Top of scale ~45px in the reference but I'll scale higher for the site-mockup context — up to 128px hero at the section-renderer scale, since the mockup viewport gives more type real estate than the reference's ~1440px browser width.",
19
+ "body": "Altform 400-700 mixed case, 15-16px body, line-height 1.5. The reference uses Altform for both display and body — one type family doing everything. Free fallback keeps the family — Archivo 400/700, then Space Grotesk. Small labels get 12px 600 sentence case.",
20
+ "mono": "none. Fresh Plate is a consumer product-brand surface. Mono has no role.",
21
+ "scale": "1.25 (perfect fourth — restrained, so composition and product photography carry the drama)",
22
+ "eyebrow_exception": "Fresh Plate does NOT need a mono-caps eyebrow exception. The\nreference has no mono-caps meta labels or eyebrow chrome — the\nmonumental display type carries the register, not eyebrow slop.\nAny use of a mono-caps eyebrow in this theme is a slop-blocklist\nviolation and must be caught in the harness grade.\n"
23
+ },
24
+ surface: "web",
25
+ density: "airy",
26
+ motion: "Ships live in the section renderer (no external dependencies):\n1. Hero type stagger reveal — the 3-line stacked \"THE / QUIET / REFRESH.\" display type animates up from translateY(40px) + opacity 0 → 1 with 140ms per-line stagger + 900ms cubic-bezier(0.23,1,0.32,1) on first paint.\n2. Product photograph subtle scale-in — the full-bleed product image opens from scale(0.98) + opacity 0.85 → scale(1) + opacity 1 over 1200ms cubic-bezier(0.23,1,0.32,1) on first paint.\n3. Découvrir arrow bounce — the circular \"Découvrir ↓\" affordance bounces its arrow 4px down and back on a 2s ease-in-out loop, subtle attention pull.\n4. Section reveals on IntersectionObserver — each below-fold section (product feature, split section, testimonials) fades in from opacity 0 + translateY(24px) → 0 over 700ms cubic-bezier(0.23,1,0.32,1) at 25% visibility threshold.\n5. Stat counter — the featured stat \"12,483 homes\" rolls up from 0 → target on first scroll into view via requestAnimationFrame, 2000ms ease-out.\n6. Nav CTA hover — background darkens from #053725 to #002e1d and the arrow translates 4px right over 200ms cubic-bezier(0.23,1,0.32,1).\n7. Section image parallax — the full-bleed product photograph in the mid-page split translates -8% Y as the user scrolls past it, tied to scroll position via a single passive scroll listener.\n8. prefers-reduced-motion: reduce — hero type shows at final position, product photo shows at scale 1, arrow doesn't bounce, section reveals become instant, stat counter shows final value, parallax disabled. Hover state changes still fire.\n\nCustomer installs these for the deeper tier:\n- Lenis — smooth inertial scroll (the tall product-photo page benefits from inertial cadence).\n- GSAP for the display-type letter-by-letter draw on the hero wordmark on first paint.\n- Real Vimeo/Cloudinary video player for a product-demo hero video if the customer has one.\n\nMotion character: quiet, confident, restrained — cleantech-premium.\nCustom cubic-bezier(0.23,1,0.32,1) for all reveals (matches the\nreference's own --ease-out variable). The register lives at\npremium-cleantech, not marketing-startup — motion should feel like\na Muji product page, not a SaaS product tour.\n",
27
+ signature: "Warm light-beige canvas at #faf7f0 — the register's non-negotiable\nbase (deliberately NOT #F4F1EA claude-cream, deliberately NOT\n#ffffff white). Every card, button, input, border, arrow, divider\nships at 0px border radius. Every ink color is a single deep-\nforest-green hue (#053725) with hover / active variants (#005d3b,\n#002e1d) — NO candy accent palette, NO secondary gradient. The hero\nis a 3-line stacked MONUMENTAL display: line 1 = \"THE\" (~120px),\nline 2 = \"QUIET\" (~120px), line 3 = \"REFRESH.\" (~120px), all\nAltform-style 900-weight uppercase at -1px tracking, centered\nhorizontally, ink deep-forest-green. Directly beneath the type\nblock: a SINGLE FULL-BLEED PRODUCT PHOTOGRAPH of the physical\ndevice, extending vertically past the type — the type sits ON TOP\nof the product image with a subtle offset. To the right of the\ntype block (bottom-right column): a single body-copy paragraph in\n15px Altform mixed case, forest ink, ~200px wide. Below the type\nand next to the product: a SINGLE CIRCULAR \"DISCOVER ↓\" AFFORDANCE\n(~64px diameter, deep-forest fill, cream arrow, sharp exterior\nboundary but the disc itself is round — the ONE circle in the\ncomposition, deliberately misfit as a discovery cue).\nTop nav strip: wordmark left (Altform 900 uppercase with a small\ndrop icon in the accent color to the left), horizontal link row\ncenter (Product / Range / Simulate / FAQ / Join / Lang), a filled\ndeep-forest-green rectangular \"Contact →\" button right-aligned.\nBelow the hero: sections alternate between DARK-INK-ON-CREAM\nand INVERTED FOREST-CANVAS-WITH-CREAM-INK bands, with big\nmonumental section headlines and full-bleed product photography.\nA stat callout runs a real-time-feeling counter from 0 to 12,483\nhomes. Footer: dark forest canvas with a giant Altform wordmark,\na stack of utility links, and a small acknowledgement paragraph.\nSix bespoke SVG marks (drop icon, arrow-down, arrow-right,\ntemperature-line, home-outline, leaf-outline) are dropped as\nPUNCTUATION at specific compositional moments — never as a uniform\nicon row.\n",
28
+ } as const;
29
+
30
+ export type Tokens = typeof tokens;