@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,192 @@
1
+ import type { Direction } from "../schema";
2
+
3
+ export const fintechTrust: Direction = {
4
+ name: "fintech-trust",
5
+ ethos:
6
+ "Robinhood signal-green · Wealthfront soft elevation · Wise warm sans · Brex deep navy canvas · Public charts as hero",
7
+ references: [
8
+ { brand: "Robinhood", trait: "dark-mode signal-green confirmations" },
9
+ { brand: "Wealthfront", trait: "Plus Jakarta Sans + soft elevated cards" },
10
+ { brand: "Wise", trait: "warm sans + currency-data tables" },
11
+ { brand: "Brex (marketing site)", trait: "deep navy canvas + sage signal" },
12
+ { brand: "Public.com", trait: "charts treated as hero element, not afterthought" },
13
+ ],
14
+ feel:
15
+ "Deep navy canvas with sage-green signal accents and breathing chart surfaces. " +
16
+ "Soft elevated cards, generous tabular numerics, restrained typographic confidence. " +
17
+ "Reads as quiet competence — the brokerage that holds your retirement, not the crypto exchange that wants your attention.",
18
+
19
+ fonts: {
20
+ display: {
21
+ family: "Plus Jakarta Sans",
22
+ fallback: ["Inter", "system-ui", "-apple-system", "BlinkMacSystemFont", "sans-serif"],
23
+ from: "Wealthfront display face — geometric, slightly humanist, trustworthy without being cold",
24
+ googleFont: "Plus+Jakarta+Sans",
25
+ weights: [500, 600, 700],
26
+ },
27
+ body: {
28
+ family: "Inter",
29
+ fallback: ["system-ui", "-apple-system", "BlinkMacSystemFont", "Segoe UI", "sans-serif"],
30
+ from: "Brex/Robinhood marketing body — neutral, readable at small sizes against dark navy",
31
+ googleFont: "Inter",
32
+ weights: [400, 500, 600],
33
+ },
34
+ mono: {
35
+ family: "JetBrains Mono",
36
+ fallback: ["IBM Plex Mono", "ui-monospace", "SFMono-Regular", "Consolas", "monospace"],
37
+ from: "tabular numerics for prices, balances, percentage moves — instrument-cluster heritage",
38
+ googleFont: "JetBrains+Mono",
39
+ weights: [400, 500],
40
+ },
41
+ },
42
+
43
+ typography: {
44
+ headingTracking: "-0.02em", // Plus Jakarta tightens nicely at display sizes
45
+ bodyTracking: "0",
46
+ fontFeatureSettings: '"tnum", "cv11", "ss01"', // tabular nums everywhere — money never shifts width
47
+ h1ScaleClamp: "clamp(2.5rem, 6vw, 4.5rem)", // confident, not theatrical
48
+ bodyBaseSize: "1rem",
49
+ bodyLineHeight: "1.6",
50
+ },
51
+
52
+ colors: {
53
+ background: { hsl: "220 38% 8%", from: "Brex deep navy canvas — almost-black with strong blue bias" },
54
+ foreground: { hsl: "210 30% 96%", from: "cool off-white — readable on navy without harsh contrast" },
55
+ card: { hsl: "220 32% 12%", from: "elevated card surface — Wealthfront soft lift above navy" },
56
+ popover: { hsl: "220 30% 14%", from: "popover/menu surface, one tier above card" },
57
+ primary: { hsl: "152 56% 50%", from: "Robinhood signal-green — the gains-up confirmation color" },
58
+ primaryForeground: { hsl: "220 38% 8%", from: "navy on sage — high-contrast positive action" },
59
+ secondary: { hsl: "220 24% 18%", from: "navy-shadowed surface, secondary tier" },
60
+ secondaryForeground: { hsl: "210 30% 96%", from: "cool white on navy secondary" },
61
+ muted: { hsl: "220 22% 20%", from: "muted surface — backgrounds for quiet panels inside the dashboard" },
62
+ mutedForeground: { hsl: "215 14% 68%", from: "cool gray secondary text — captions, timestamps, table meta" },
63
+ accent: { hsl: "220 22% 22%", from: "hover surface — one stop lighter than muted" },
64
+ accentForeground: { hsl: "210 30% 96%", from: "cool white on accent" },
65
+ border: { hsl: "220 20% 24%", from: "soft navy hairline — visible at card edges, never assertive" },
66
+ input: { hsl: "220 20% 24%", from: "same as border — single hairline language across inputs" },
67
+ ring: { hsl: "152 56% 50%", from: "primary sage — focus ring matches the signal, not a separate color" },
68
+ destructive: { hsl: "358 70% 56%", from: "Robinhood loss-red — restrained, never neon" },
69
+ destructiveForeground: { hsl: "210 30% 96%", from: "cool white on loss-red" },
70
+ brand: {
71
+ sage: { hsl: "152 56% 50%", from: "= primary; Robinhood signal-green, also the brand-mark" },
72
+ "sage-deep": { hsl: "150 48% 38%", from: "darker sage — chart fill underneath the line, hover state" },
73
+ "sage-soft": { hsl: "152 40% 88%", from: "pale sage tint — chart axis gridlines, success-toast bg" },
74
+ navy: { hsl: "220 38% 8%", from: "= background; the canvas itself, semantic for void/shadow" },
75
+ "navy-mid": { hsl: "220 30% 18%", from: "mid-navy — gradient anchor and chart background fill" },
76
+ "chart-up": { hsl: "152 56% 50%", from: "= sage; explicit semantic token for positive deltas" },
77
+ "chart-down": { hsl: "358 70% 56%", from: "= destructive; explicit semantic token for negative deltas" },
78
+ gold: { hsl: "42 78% 62%", from: "Wise warm gold — currency-conversion accent, used sparingly" },
79
+ },
80
+ },
81
+
82
+ spacing: {
83
+ base: 4,
84
+ scale: [4, 6, 8, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96], // medium density — charts need breathing room
85
+ containerMax: "max-w-7xl", // wide — dashboard hero charts span full bleed
86
+ containerPadding: "px-6 lg:px-10",
87
+ sectionPadding: {
88
+ hero: "pt-24 pb-16 lg:pt-32 lg:pb-24",
89
+ default: "py-16 lg:py-24",
90
+ tight: "py-12 lg:py-16",
91
+ },
92
+ },
93
+
94
+ radius: {
95
+ base: "0.625rem", // 10px — softer than fintech-card, never pillowy
96
+ pillsAllowed: true, // pills for ticker chips, percentage badges, status
97
+ },
98
+
99
+ shadows: {
100
+ style: "soft",
101
+ utilities: {
102
+ "shadow-elevated":
103
+ "0 1px 0 hsl(210 30% 96% / 0.04), " +
104
+ "0 8px 24px hsl(220 38% 4% / 0.4), " +
105
+ "0 24px 64px hsl(220 38% 4% / 0.5)",
106
+ "shadow-card":
107
+ "0 1px 0 hsl(210 30% 96% / 0.03), " +
108
+ "0 2px 8px hsl(220 38% 4% / 0.3)",
109
+ "glow-sage":
110
+ "0 0 0 1px hsl(var(--sage) / 0.3), " +
111
+ "0 8px 32px hsl(var(--sage) / 0.18)",
112
+ },
113
+ },
114
+
115
+ motion: {
116
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)",
117
+ durations: {
118
+ reveal: 500, // crisp — finance UI confirms quickly
119
+ loop: 1800, // ticker pulse cadence
120
+ ambient: 8000, // chart-line drawing speed
121
+ },
122
+ keyframes: {
123
+ "fade-rise": {
124
+ css:
125
+ "from { opacity: 0; transform: translateY(8px); }\n" +
126
+ "to { opacity: 1; transform: translateY(0); }",
127
+ defaultDuration: 500,
128
+ iteration: "once",
129
+ purpose: "standard content entrance — short, confident, no theatrics",
130
+ },
131
+ "chart-draw": {
132
+ css:
133
+ "from { stroke-dashoffset: 100%; }\n" +
134
+ "to { stroke-dashoffset: 0; }",
135
+ defaultDuration: 1800,
136
+ iteration: "once",
137
+ purpose: "line-chart entrance — SVG stroke-dashoffset reveal, the signature gesture",
138
+ },
139
+ "ticker-pulse": {
140
+ css:
141
+ "0%, 100% { opacity: 1; }\n" +
142
+ "50% { opacity: 0.6; }",
143
+ defaultDuration: 1800,
144
+ iteration: "infinite",
145
+ purpose: "live-price dot indicator — subtle heartbeat next to current quote",
146
+ },
147
+ "number-roll": {
148
+ css:
149
+ "from { opacity: 0; transform: translateY(-8px); }\n" +
150
+ "to { opacity: 1; transform: translateY(0); }",
151
+ defaultDuration: 300,
152
+ iteration: "once",
153
+ purpose: "price/balance value change — replace-and-rise; tabular nums hold width",
154
+ },
155
+ "shimmer": {
156
+ css:
157
+ "0% { background-position: -200% 0; }\n" +
158
+ "100% { background-position: 200% 0; }",
159
+ defaultDuration: 1600,
160
+ iteration: "infinite",
161
+ purpose: "loading skeleton for chart panels and table rows",
162
+ },
163
+ },
164
+ respectsReducedMotion: true,
165
+ },
166
+
167
+ density: "medium",
168
+
169
+ patterns: {
170
+ button:
171
+ "Solid sage primary (sage bg, navy fg, rounded-lg, shadow-card) for the single positive action per surface. " +
172
+ "Secondary is ghost — border, foreground text, transparent fill. Tertiary is a text-link in sage. " +
173
+ "Hover deepens fill to sage-deep; never grows in scale — finance UI does not bounce.",
174
+ card:
175
+ "Rounded-[0.625rem], hairline border (--border), bg-card lifted off navy with shadow-elevated. " +
176
+ "Internal padding p-6 lg:p-8. Numbers always tabular, mono for prices, sans for labels. " +
177
+ "Chart cards span full width with the chart treated as primary content, not a sidebar widget.",
178
+ input:
179
+ "Full rounded-lg box, 1px --input border, bg-card. Label above in sans-medium. " +
180
+ "Focus = 2px sage ring at 40% opacity. Helper text below in muted-foreground. Currency inputs are mono-aligned right.",
181
+ cta:
182
+ "Primary sage button for the positive action (Deposit, Invest, Trade). " +
183
+ "Text-link sage for secondary navigation. Never red on a CTA — red is reserved for losses and destructive actions.",
184
+ },
185
+
186
+ details: {
187
+ selectionBg: "hsl(var(--sage) / 0.3)",
188
+ selectionFg: "hsl(var(--foreground))",
189
+ focusRing: "2px solid hsl(var(--ring) / 0.5)",
190
+ scrollbarStyle: "thin",
191
+ },
192
+ };
@@ -0,0 +1,98 @@
1
+ # Design Direction — Food-Blog
2
+
3
+ ## Ethos
4
+ Bon Appétit cream-and-serif · Smitten Kitchen warm density · Serious Eats structured recipes · NYT Cooking Georgia hierarchy · Eater deep editorial
5
+
6
+ ## Feel
7
+ Warm cream paper, serif headlines that look like a cookbook spine, generous step-typography you can read with floured hands. Photographic food anchors at the top of every recipe, mono tabular numbers for ingredient quantities. The page smells faintly of butter. This is *cookbook-on-the-counter* energy — designed to be read while cooking, not while commuting.
8
+
9
+ ## Reference brands
10
+ - **Bon Appétit** → cream paper + Playfair Display + food-photography editorial. The hero photo is the headline; the title sits beneath in serif.
11
+ - **Smitten Kitchen** → warm cream + serif + dense recipe layout. Personal essay flows into method without ceremony.
12
+ - **Serious Eats** → structured recipe cards + dense info-tables. Equipment notes, prep timers, why-it-works boxes treated as first-class content.
13
+ - **NYT Cooking** → warm cream + Georgia-feel serif + structured ingredient cards with serving-size scalers.
14
+ - **Eater** → deep cream + dense editorial + photographic anchors. The publication voice; the restaurant-review register.
15
+
16
+ ## Tokens
17
+ All tokens live in `src/index.css` as HSL triples. Every token's `from:` comment names its brand origin. Do not introduce numbered or generic tokens — if a new color is needed, name a brand it traces to.
18
+
19
+ Surface stack is **warm cream** (background) → lighter cream (card) → deeper cream (secondary/muted/accent). Depth comes from hairline borders and a soft drop shadow on recipe cards and hero photos — never from saturated fills.
20
+
21
+ Brand tokens: `--cream`, `--cocoa`, `--paprika`, `--butter`, `--basil`, `--ink-soft`. Primary is NYT Cooking paprika — the recipe-mark and save-button color. Basil is reserved for ingredient/diet tags (vegan, gluten-free, 30-minute). Butter is the saved/starred state. Cocoa replaces black.
22
+
23
+ ## Typography
24
+ - **Display:** Playfair Display (Bon Appétit / Eater cookbook serif). h1–h4, high-contrast didone for recipe titles. Tracking `-0.02em` — Playfair tightens noticeably at display size, cookbook-spine feel.
25
+ - **Body:** Source Serif 4 (NYT Cooking / Smitten Kitchen reading serif). Body base **18px** with **line-height 1.75** — read-at-arms-length, kitchen counter legible.
26
+ - **Mono:** JetBrains Mono. Ingredient quantities, oven temps, prep/cook timers — Serious Eats tabular precision.
27
+
28
+ H1 uses `clamp(2.75rem, 7vw, 5.5rem)` — generous recipe-title scale, never broadcast-huge. Numbers and fractions get `font-variant-numeric: tabular-nums` plus the `"frac"` feature so `1/2 tsp` renders as a proper vulgar fraction. Font features: `"ss01"`, `"calt"`, `"tnum"`, `"frac"`.
29
+
30
+ ## Spacing
31
+ - **Container:** `max-w-3xl px-6 lg:px-10` — prose-and-recipe column. 768px reads like a cookbook page; wider breaks the recipe flow.
32
+ - **Section padding tiers:**
33
+ - Hero: `pt-20 pb-12 lg:pt-32 lg:pb-20` (oversized for hero food photo + title block)
34
+ - Default: `py-16 lg:py-28`
35
+ - Tight: `py-10 lg:py-16`
36
+ - **Allowed scale values:** 4 6 8 12 16 20 24 32 40 48 64 96 128.
37
+
38
+ ## Color
39
+ No hex anywhere in component files. All color via tokens. Opacity via `/N` modifier on token.
40
+
41
+ The palette is warm-paper-first: cream, cocoa, paprika are the load-bearing tokens. Basil and butter are garnish — used sparingly, never in primary action. Pure white and pure black are forbidden — `--cream` and `--cocoa` replace them.
42
+
43
+ ## Radius
44
+ `--radius: 0.25rem`. Slight softening — recipe cards aren't sharp print, they're glossy-magazine-cards. Pills ARE allowed (`pillsAllowed: true`) — ingredient tags, dietary tags and time-to-cook chips read as pills.
45
+
46
+ ## Shadows
47
+ **Soft.** Three utilities:
48
+ - `.hairline-rule` — 1px border-bottom, parchment crease for section dividers
49
+ - `.recipe-card` — hairline + soft cocoa-tinted drop (12px blur), cookbook-spread feel
50
+ - `.photo-frame` — hairline + heavier cocoa drop (24px blur, 60px spread), hero food photo lift
51
+
52
+ Shadows are cocoa-tinted, never gray — neutral shadows on cream paper look cold.
53
+
54
+ ## Motion
55
+ Four keyframes — restrained but warmer than editorial:
56
+ - `fade-rise` (900ms) — recipe step entrance, settles into place at reading pace
57
+ - `step-number` (600ms) — numbered step circle pops into place beside its instruction
58
+ - `timer-pulse` (3200ms, infinite) — active cook-timer cell pulses warm, like an oven indicator
59
+ - `photo-pan` (24000ms, infinite) — hero food photography slow drift, Bon Appétit cover-shot
60
+
61
+ Easing: `cubic-bezier(0.22, 1, 0.36, 1)`. `prefers-reduced-motion` honored — timer-pulse collapses to a static highlighted cell, photo-pan disables.
62
+
63
+ ## Component patterns
64
+ - **Buttons:** primary save/start-cooking = paprika filled rectangle, cream text, sentence-case label in display serif. Secondary = transparent + 1px cocoa border, cocoa text. Tertiary = serif text-link in paprika with underline-on-hover.
65
+ - **Cards:** `0.25rem` radius, hairline border, bg-card a hair lighter than the page. Recipe cards use `.recipe-card` shadow; hero photo blocks use `.photo-frame`. Padding `p-6 lg:p-10`. Title in Playfair, byline/dateline in mono uppercase tracking `0.08em`.
66
+ - **Inputs:** border-bottom only for inline prose forms (newsletter signup, search). Full-box variant for structured forms (recipe scaling, serving-size adjuster). Label sits above in display serif. Focus ring is paprika, 1px.
67
+ - **CTA:** save-recipe and start-cooking get the paprika fill — one per page maximum. Inline recipe-step CTAs (jump to ingredients, print, save) are serif text-links in paprika. **Never a basil-green fill** — basil is for tags only.
68
+
69
+ ## Recommended rich media
70
+ Food-Blog is photography-led the way Bon Appétit and Eater are. Lead media is **food photography color-graded to Fuji Pro 400H** (warm highlights, soft greens, painterly shadow) — overhead flat-lays for finished dishes, 45-degree on-the-stove for process shots, hands-in-frame for kneading/folding/plating. Avoid the harsh top-light "Instagram food" look; the reference is editorial cookbook photography.
71
+
72
+ Illustrations, where used, are **gouache-style food illustrations** (Bon Appétit's recurring style) or **woodcut-style spot illustrations** (NYT Cooking-adjacent) — never 3D-rendered food, never AI-glossy plate-on-marble stock.
73
+
74
+ **AI tool recommendations:** **Midjourney / Flux** prompts like *"overhead food photography, Fuji Pro 400H, natural window light, linen tablecloth, hands at edge of frame, Bon Appétit cookbook style"* for hero shots; *"gouache illustration of [ingredient], loose brush strokes, cookbook spot illustration, cream background"* for illustrations. Explicitly prompt for film grain and natural light — Midjourney's default food output is plastic.
75
+
76
+ **Aspect ratios:** 4:5 portrait for hero (cookbook-page convention); 3:2 landscape for process shots; 1:1 square only inside step-cards (icon-scale). Never 16:9 widescreen (cinematic, wrong register).
77
+
78
+ **Video:** short cooking-process loops are welcome — autoplay muted, ≤8s, AV1 ≤3 MB. Hands-only POV process shots work best. Avoid talking-head video; if a chef speaks, transcribe and use the prose.
79
+
80
+ **Performance:** hero AVIF ≤180 KB at 2000w; step-card photos ≤70 KB; recipe page total media budget ≤1.5 MB. LCP under 2s. Cream backgrounds and warm-graded photos compress well in AVIF — exploit that.
81
+
82
+ **Avoid:** dark moody food photography (cinematic territory), top-light Instagram food (wrong register), stock food photography with watermarks, 3D-rendered food, gradient backgrounds behind food (overlay shadows are fine, gradients are not), generic restaurant interior stock.
83
+
84
+ **Accessibility:** long-form alt-text for food photography — describe the dish, the plating, the apparent cooking stage. *"A finished bowl of mushroom risotto, topped with shaved parmesan and parsley, on a linen tablecloth in window light."* Ingredient quantities are read by screen readers in proper units — never rely on visual layout to convey amounts.
85
+
86
+ ## Component families
87
+ None at install time. Expect early conventions around `<RecipeCard>`, `<IngredientList>`, `<MethodStep>`, `<ServingScaler>`, `<NutritionTable>`, `<CookTimer>`.
88
+
89
+ ## Details
90
+ - **Selection:** `hsl(var(--paprika) / 0.2)` background, foreground text.
91
+ - **Focus ring:** `1px solid hsl(var(--ring))` — quiet, cookbook-page calm.
92
+ - **Scrollbar:** thin.
93
+
94
+ ## Exceptions
95
+ None yet. When an intentional one-of-one violation lands, add it here with the reason.
96
+
97
+ ## Revisions
98
+ - Initial direction, generated at install time.
@@ -0,0 +1,183 @@
1
+ import type { Direction } from "../schema";
2
+
3
+ export const foodBlog: Direction = {
4
+ name: "food-blog",
5
+ ethos:
6
+ "Bon Appétit cream-and-serif · Smitten Kitchen warm density · Serious Eats structured recipes · NYT Cooking Georgia hierarchy · Eater deep editorial",
7
+ references: [
8
+ { brand: "Bon Appétit", trait: "cream paper + Playfair Display + food-photography editorial" },
9
+ { brand: "Smitten Kitchen", trait: "warm cream + serif + dense recipe layout" },
10
+ { brand: "Serious Eats", trait: "cream + structured recipe cards + dense info-tables" },
11
+ { brand: "NYT Cooking", trait: "warm cream + Georgia serif + structured ingredient cards" },
12
+ { brand: "Eater", trait: "deep cream + dense editorial + photographic anchors" },
13
+ ],
14
+ feel:
15
+ "Warm cream paper, serif headlines that look like a cookbook spine, generous step-typography " +
16
+ "you can read with floured hands. Photographic food anchors at the top of every recipe, mono " +
17
+ "tabular numbers for ingredient quantities. The page smells faintly of butter.",
18
+
19
+ fonts: {
20
+ display: {
21
+ family: "Playfair Display",
22
+ fallback: ["EB Garamond", "Iowan Old Style", "Georgia", "Times New Roman", "serif"],
23
+ from: "Bon Appétit / Eater cookbook serif — high-contrast didone for recipe titles and section heads",
24
+ googleFont: "Playfair+Display",
25
+ weights: [400, 600, 700, 900],
26
+ },
27
+ body: {
28
+ family: "Source Serif 4",
29
+ fallback: ["Source Serif Pro", "Iowan Old Style", "Georgia", "Times New Roman", "serif"],
30
+ from: "NYT Cooking / Smitten Kitchen reading serif — Georgia-feel body, kitchen-counter legible at distance",
31
+ googleFont: "Source+Serif+4",
32
+ weights: [400, 600, 700],
33
+ },
34
+ mono: {
35
+ family: "JetBrains Mono",
36
+ fallback: ["Berkeley Mono", "ui-monospace", "SFMono-Regular", "Consolas", "monospace"],
37
+ from: "ingredient quantities, oven temps, prep/cook timers — Serious Eats tabular precision",
38
+ googleFont: "JetBrains+Mono",
39
+ weights: [400, 500],
40
+ },
41
+ },
42
+
43
+ typography: {
44
+ headingTracking: "-0.02em", // Playfair tightens noticeably at display size — cookbook-spine feel
45
+ bodyTracking: "0",
46
+ fontFeatureSettings: '"ss01", "calt", "tnum", "frac"',
47
+ h1ScaleClamp: "clamp(2.75rem, 7vw, 5.5rem)", // generous recipe-title scale, never broadcast-huge
48
+ bodyBaseSize: "1.125rem", // 18px — read-at-arms-length, kitchen counter
49
+ bodyLineHeight: "1.75", // generous step spacing — fingers find their place
50
+ },
51
+
52
+ colors: {
53
+ background: { hsl: "36 38% 94%", from: "Bon Appétit warm cream — pastry-paper, not bone" },
54
+ foreground: { hsl: "24 22% 14%", from: "deep cocoa ink — chocolate, never pure black on cream" },
55
+ card: { hsl: "36 45% 97%", from: "lighter cream — recipe card sits a hair brighter than the page" },
56
+ popover: { hsl: "36 45% 97%", from: "same as card — depth from hairline border only" },
57
+ primary: { hsl: "12 68% 42%", from: "NYT Cooking paprika red — the recipe-mark and save-button color" },
58
+ primaryForeground: { hsl: "36 38% 94%", from: "cream on paprika" },
59
+ secondary: { hsl: "36 28% 89%", from: "warm cream, one tier deeper — ingredient-list backdrop" },
60
+ secondaryForeground: { hsl: "24 22% 14%", from: "cocoa ink on warm cream" },
61
+ muted: { hsl: "36 24% 88%", from: "muted surface — sidebar/aside backdrop, same family as secondary" },
62
+ mutedForeground: { hsl: "24 14% 38%", from: "secondary text — coffee-with-milk gray, never neutral" },
63
+ accent: { hsl: "36 30% 86%", from: "warm cream deeper still — hover surface only" },
64
+ accentForeground: { hsl: "24 22% 14%", from: "cocoa ink on hover" },
65
+ border: { hsl: "24 18% 78%", from: "Eater editorial hairline — visible but soft, like a parchment crease" },
66
+ input: { hsl: "24 18% 78%", from: "same as border — single hairline language across forms" },
67
+ ring: { hsl: "12 68% 42%", from: "paprika — focus is the recipe-mark color" },
68
+ destructive: { hsl: "0 70% 44%", from: "alert red — more saturated than paprika, only for errors and deletes" },
69
+ destructiveForeground: { hsl: "36 38% 94%", from: "cream on alert" },
70
+ brand: {
71
+ cream: { hsl: "36 38% 94%", from: "Bon Appétit pastry-paper — the canvas, also background" },
72
+ cocoa: { hsl: "24 22% 14%", from: "deep cocoa ink — the foreground type color, also semantic" },
73
+ paprika: { hsl: "12 68% 42%", from: "NYT Cooking recipe-mark — primary action color" },
74
+ butter: { hsl: "44 78% 62%", from: "buttercream yellow — saved/starred state, garnish accent only" },
75
+ basil: { hsl: "92 32% 38%", from: "deep basil green — herb chips, ingredient-tag color, never primary" },
76
+ "ink-soft": { hsl: "24 18% 32%", from: "softer cocoa — captions, datelines, byline rules" },
77
+ },
78
+ },
79
+
80
+ spacing: {
81
+ base: 4,
82
+ scale: [4, 6, 8, 12, 16, 20, 24, 32, 40, 48, 64, 96, 128], // editorial breathing for recipe steps
83
+ containerMax: "max-w-3xl", // prose-and-recipe column; 768px reads like a cookbook page
84
+ containerPadding: "px-6 lg:px-10",
85
+ sectionPadding: {
86
+ hero: "pt-20 pb-12 lg:pt-32 lg:pb-20", // oversized hero photo + title block
87
+ default: "py-16 lg:py-28",
88
+ tight: "py-10 lg:py-16",
89
+ },
90
+ },
91
+
92
+ radius: {
93
+ base: "0.25rem", // slight softening — recipe cards aren't sharp print
94
+ pillsAllowed: true, // ingredient tags (vegan, gluten-free, 30-min) read as pills
95
+ },
96
+
97
+ shadows: {
98
+ style: "soft",
99
+ utilities: {
100
+ "hairline-rule":
101
+ "0 1px 0 0 hsl(var(--border))", // section divider — parchment crease
102
+ "recipe-card":
103
+ "0 1px 0 0 hsl(var(--border)), " +
104
+ "0 12px 32px hsl(24 22% 14% / 0.06)", // recipe card lifts off the page just barely — cookbook spread
105
+ "photo-frame":
106
+ "0 1px 0 0 hsl(var(--border)), " +
107
+ "0 24px 60px hsl(24 22% 14% / 0.12)", // hero food photo carries more weight
108
+ },
109
+ },
110
+
111
+ motion: {
112
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)",
113
+ durations: {
114
+ reveal: 900, // step-by-step entrance, unhurried — recipe reading pace
115
+ loop: 3200, // timer pulses
116
+ ambient: 24000, // slow drift on hero photography
117
+ },
118
+ keyframes: {
119
+ "fade-rise": {
120
+ css:
121
+ "from { opacity: 0; transform: translateY(16px); }\n" +
122
+ "to { opacity: 1; transform: translateY(0); }",
123
+ defaultDuration: 900,
124
+ iteration: "once",
125
+ purpose: "recipe step entrance — settles into place as you scroll the method",
126
+ },
127
+ "step-number": {
128
+ css:
129
+ "from { opacity: 0; transform: scale(0.92); }\n" +
130
+ "to { opacity: 1; transform: scale(1); }",
131
+ defaultDuration: 600,
132
+ iteration: "once",
133
+ purpose: "numbered step circle pops into place beside its instruction",
134
+ },
135
+ "timer-pulse": {
136
+ css:
137
+ "0%, 100% { background-color: hsl(var(--paprika) / 0.0); }\n" +
138
+ "50% { background-color: hsl(var(--paprika) / 0.12); }",
139
+ defaultDuration: 3200,
140
+ iteration: "infinite",
141
+ purpose: "active cook-timer cell pulses warm — like an oven indicator light, never harsh",
142
+ },
143
+ "photo-pan": {
144
+ css:
145
+ "0% { transform: scale(1.04) translate(0, 0); }\n" +
146
+ "100% { transform: scale(1.12) translate(-1.5%, -0.8%); }",
147
+ defaultDuration: 24000,
148
+ iteration: "infinite",
149
+ purpose: "hero food photography slow drift — Bon Appétit cover-shot camera push",
150
+ },
151
+ },
152
+ respectsReducedMotion: true,
153
+ },
154
+
155
+ density: "low",
156
+
157
+ patterns: {
158
+ button:
159
+ "Primary save/start-cooking action = paprika filled rectangle, cream text, 0.25rem radius, sentence-case label in display serif. " +
160
+ "Secondary = transparent with 1px cocoa border, cocoa text. " +
161
+ "Tertiary = serif text-link in paprika, underline-on-hover. " +
162
+ "Ingredient/diet tags = basil-bordered pills with cocoa text on cream — chip, not button.",
163
+ card:
164
+ "0.25rem radius, hairline border (--border), bg-card a hair lighter than the page. " +
165
+ "Recipe cards use recipe-card shadow; hero photo blocks use photo-frame. " +
166
+ "Padding p-6 lg:p-10. Title in Playfair Display, byline/dateline in mono uppercase tracking 0.08em.",
167
+ input:
168
+ "Border-bottom only (1px ink-soft) for inline prose forms (search, newsletter signup). " +
169
+ "Full-box variant for structured forms (recipe scaling, serving-size adjuster): 1px --border, bg-card. " +
170
+ "Label sits above in display serif. Focus ring is paprika, 1px.",
171
+ cta:
172
+ "Save-recipe and start-cooking get the paprika fill — one per page maximum. " +
173
+ "Inline recipe-step CTAs (jump to ingredients, print, save) are serif text-links in paprika. " +
174
+ "Never a green fill (basil is for tags only).",
175
+ },
176
+
177
+ details: {
178
+ selectionBg: "hsl(var(--paprika) / 0.2)",
179
+ selectionFg: "hsl(var(--foreground))",
180
+ focusRing: "1px solid hsl(var(--ring))",
181
+ scrollbarStyle: "thin",
182
+ },
183
+ };
@@ -0,0 +1,100 @@
1
+ # Design Direction — Forum-Classic
2
+
3
+ ## Ethos
4
+ Reddit upvote-orange + density · Hacker News beige + Verdana · Lobste.rs muted indie · Tildes restraint + serif accents · Metafilter blue link tradition
5
+
6
+ ## Feel
7
+ Dense, link-first, text-river. The page is a list of titles with vote counts and a small handle — no hero images, no cards with shadows, no decoration earned by composition. Mono-leaning sans for everything; the only color worth spending is the upvote arrow and the link blue. Reads as community-archive — the same shape you'd recognize across Reddit, HN, Lobste.rs, and Metafilter.
8
+
9
+ Where `dense-utility` is Bloomberg-terminal financial-instrument density, forum-classic is text-and-link community density. Both share a tight scale, but forum-classic uses warm-beige humanism where dense-utility goes cool-grid.
10
+
11
+ ## Reference brands
12
+ - **Reddit (old.reddit)** → upvote orange + dense link list + small avatar + nested-comment indent. The shape of the community web.
13
+ - **Hacker News** → beige page wash + Verdana-feel body + orange wordmark + flat link list. Maximum signal-to-decoration ratio.
14
+ - **Lobste.rs** → muted indie palette + categorized tags + density. The smart younger cousin of HN.
15
+ - **Tildes** → restraint + serif accents + group-driven nav. The reformed, lower-noise alternative.
16
+ - **Metafilter** → blue link tradition + community-driven thread weight. The original web-community blue.
17
+
18
+ ## Tokens
19
+ HSL triples in `src/index.css`. Every token's `from:` comment names its brand origin.
20
+
21
+ Surface stack: **beige page wash** (`36 30% 96%`, HN's page color) → **white card** (`0 0% 100%`) → **deeper beige** (`36 20% 92%`, alt-row striping + visited rows). Warm-neutral throughout — pure gray reads cold-corporate and breaks the community-archive feel.
22
+
23
+ Primary is **Reddit upvote orange** (`16 100% 50%`) — also HN's wordmark orange. The single saturated color in the whole palette. Used for: upvote arrows, the active/upvoted state, the wordmark, focus rings.
24
+
25
+ Brand tokens — community web traditions, preserved:
26
+ - `--upvote-orange` (= primary) — Reddit arrow, HN wordmark, the action color.
27
+ - `--downvote-blue` — Reddit's indigo-blue downvote (also Metafilter link blue).
28
+ - `--link-blue` — unvisited link blue, pre-2010 web tradition.
29
+ - `--link-purple` — visited link purple. **This direction honors visited-link styling** — that's part of the forum feel.
30
+ - `--tag-green` / `--tag-purple` — Lobste.rs category-tag colors. Used for inline category chips.
31
+ - `--mod-distinguished` — Reddit's distinguished-mod green name color.
32
+
33
+ ## Typography
34
+ - **Display:** IBM Plex Sans — Verdana lineage, humanist, condensed enough for dense titles. h1–h4 weights 600/700.
35
+ - **Body:** IBM Plex Sans (same family — single-face forum convention, like HN). Base **14px** with **line-height 1.45** — the forum-density default.
36
+ - **Mono:** IBM Plex Mono — post-meta, vote counts, code blocks in comments. Tabular numerics (`"tnum"`) globally on for score columns.
37
+
38
+ H1 uses `clamp(1.5rem, 3vw, 2rem)` — forums don't do marketing-hero sizes. The largest type on the page is the post title, and that lives at body-size + 2px.
39
+
40
+ ## Spacing
41
+ - **Container:** `max-w-5xl px-3 lg:px-4` — narrow horizontal padding; the page edges in.
42
+ - **Section padding tiers:**
43
+ - Hero: `pt-8 pb-6 lg:pt-12 lg:pb-8` — forums barely have heroes.
44
+ - Default: `py-8 lg:py-12`
45
+ - Tight: `py-6 lg:py-8`
46
+ - **Allowed scale values:** 2 4 6 8 10 12 16 20 24 32 40. **Includes 2px** — vote arrows and chrome use it.
47
+
48
+ ## Color
49
+ No hex in components. All color via tokens. Opacity via `/N`.
50
+
51
+ The palette is **beige-and-ink with one orange + the link blues**. Resist adding any second saturated color. Tag chips can use `--tag-green` / `--tag-purple`, but only inline at small size, never as a surface fill.
52
+
53
+ **Visited links render in `--link-purple`** — this is a feature, not a relic. Forum users rely on it to triage which threads they've already read.
54
+
55
+ ## Radius
56
+ `--radius: 0.2rem` (3px). **Barely rounded** — HN / old-reddit chrome. Pills are **disallowed** (`pillsAllowed: false`) — they read web-app, not forum. Tags are tiny bordered rects, not pills.
57
+
58
+ ## Shadows
59
+ Minimal — two utilities only:
60
+ - `.thread-row-hover` — inset 1px border on hover (deeper than the resting hairline). The row hover state is a border darken, not a drop shadow.
61
+ - `.hairline-rule` — single 1px dividing rule between rows.
62
+
63
+ **No drop shadows, no glows.** Depth comes from row hairlines.
64
+
65
+ ## Motion
66
+ Two keyframes, fast and quiet:
67
+ - `vote-bounce` (240ms) — small upward bounce on the arrow when an upvote/downvote is tapped. Confirms the action; nothing more.
68
+ - `row-flash` (1000ms once) — newly-loaded thread rows flash orange-tinted then fade to baseline. Helps the eye find what's new in a paginated list.
69
+
70
+ **Ambient duration is 0** — forums don't have ambient motion. No parallax, no marquee, no skeleton shimmer (forums render so fast they don't need skeletons).
71
+
72
+ ## Component patterns
73
+ - **Buttons:** default = small bordered rect, foreground text, near-square (rounded-sm only). Primary = orange-bordered rect with orange text. Filled-orange is reserved for the **upvoted/selected** state. No pills. No gradients. Buttons are inline-sized to their label, never full-width.
74
+ - **Cards:** **threads and comments are rows, not cards** — hairline-top dividers, no fill differentiation. Where a true card is needed (sidebar widget), use white bg with 1px border and rounded-sm. Padding tight (`p-3 lg:p-4`). No drop shadows.
75
+ - **Inputs:** full bordered box, rounded-sm. Focus = 1px orange border swap. Comment textarea is full-width with mono helper text below.
76
+ - **CTAs:** the thread title IS the CTA — an inline text-link in `--link-blue`. Vote arrows are the action primitive. Every "reply", "share", "save", "report" is an inline small text-link in `--mutedForeground`, never a button.
77
+
78
+ ## Component families
79
+ - `*ThreadRow` — vote-column + title-link + meta-row (handle + sub + time + comment-count).
80
+ - `*Comment` — indented (1.5rem per depth) with hairline-left rule + vote-column + body + reply-row.
81
+ - `*SidebarWidget` — white card with 1px border, small heading in display.
82
+
83
+ ## Recommended rich media
84
+ **Almost none.** Forums are text-and-link surfaces. Where media is allowed:
85
+ - **Thread thumbnails:** tiny 4:3 thumbnails at 70x52px next to a link row (Reddit-style preview chip). Never a hero image.
86
+ - **Embedded comments:** quoted blocks in `--muted` background with a 3px left border in `--link-blue`.
87
+ - **Sub-icons:** 24x24 square avatars (favicon-sized) for the subreddit/group identity in the meta row.
88
+
89
+ **AVOID:** hero photography, illustration, video, gradients, any cinematic image treatment. The page is the list — adding decoration breaks the archive feel.
90
+
91
+ ## Details
92
+ - **Selection:** `hsl(var(--primary) / 0.3)` background, foreground text.
93
+ - **Focus ring:** `1px solid hsl(var(--ring))`. Thin orange — matches the chrome.
94
+ - **Scrollbar:** auto. Forums use the native scrollbar; restyling it reads over-designed.
95
+
96
+ ## Exceptions
97
+ None yet.
98
+
99
+ ## Revisions
100
+ - Initial direction, generated at install time.