@stylecrib/cli 0.3.1 → 0.3.2

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 (348) 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 +1577 -463
  25. package/package.json +11 -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/.anchor-render.png +0 -0
  38. package/themes/arc-stack/THEME.md +125 -0
  39. package/themes/arc-stack/audit.log.jsonl +6 -0
  40. package/themes/arc-stack/dismissals.jsonl +3 -0
  41. package/themes/arc-stack/tailwind.snippet.ts +17 -0
  42. package/themes/arc-stack/theme.yml +153 -0
  43. package/themes/arc-stack/tokens.ts +29 -0
  44. package/themes/architectural/THEME.md +102 -0
  45. package/themes/architectural/tokens.ts +159 -0
  46. package/themes/atelier-radiance/THEME.md +93 -0
  47. package/themes/atelier-radiance/audit.log.jsonl +1 -0
  48. package/themes/atelier-radiance/tailwind.snippet.ts +15 -0
  49. package/themes/atelier-radiance/theme.yml +130 -0
  50. package/themes/atelier-radiance/tokens.ts +29 -0
  51. package/themes/automotive-ev/THEME.md +87 -0
  52. package/themes/automotive-ev/tokens.ts +183 -0
  53. package/themes/automotive-luxury/THEME.md +88 -0
  54. package/themes/automotive-luxury/tokens.ts +175 -0
  55. package/themes/baby-modern/THEME.md +79 -0
  56. package/themes/baby-modern/tokens.ts +184 -0
  57. package/themes/banking-gravity/THEME.md +171 -0
  58. package/themes/banking-gravity/tokens.ts +169 -0
  59. package/themes/beauty-clean/THEME.md +92 -0
  60. package/themes/beauty-clean/tokens.ts +176 -0
  61. package/themes/beauty-luxury/THEME.md +96 -0
  62. package/themes/beauty-luxury/tokens.ts +178 -0
  63. package/themes/bento-modular/.anchor-render.png +0 -0
  64. package/themes/bento-modular/BUILD_BRIEF.md +171 -0
  65. package/themes/bento-modular/THEME.md +80 -0
  66. package/themes/bento-modular/audit.log.jsonl +3 -0
  67. package/themes/bento-modular/dismissals.jsonl +1 -0
  68. package/themes/bento-modular/tailwind.snippet.ts +17 -0
  69. package/themes/bento-modular/theme.yml +83 -0
  70. package/themes/bento-modular/tokens.ts +27 -0
  71. package/themes/bookstore-indie/THEME.md +78 -0
  72. package/themes/bookstore-indie/tokens.ts +147 -0
  73. package/themes/brutalist/THEME.md +96 -0
  74. package/themes/brutalist/tokens.ts +151 -0
  75. package/themes/business-tiles/THEME.md +141 -0
  76. package/themes/business-tiles/tokens.ts +178 -0
  77. package/themes/cabana-poster/THEME.md +158 -0
  78. package/themes/cabana-poster/audit.log.jsonl +1 -0
  79. package/themes/cabana-poster/tailwind.snippet.ts +16 -0
  80. package/themes/cabana-poster/theme.yml +221 -0
  81. package/themes/cabana-poster/tokens.ts +34 -0
  82. package/themes/case-panel/THEME.md +126 -0
  83. package/themes/case-panel/audit.log.jsonl +2 -0
  84. package/themes/case-panel/tailwind.snippet.ts +15 -0
  85. package/themes/case-panel/theme.yml +153 -0
  86. package/themes/case-panel/tokens.ts +28 -0
  87. package/themes/cinematic-dark/THEME.md +97 -0
  88. package/themes/cinematic-dark/tokens.ts +195 -0
  89. package/themes/classic-car/THEME.md +86 -0
  90. package/themes/classic-car/tokens.ts +173 -0
  91. package/themes/cloud-friendly/THEME.md +152 -0
  92. package/themes/cloud-friendly/tokens.ts +181 -0
  93. package/themes/community-niche/THEME.md +102 -0
  94. package/themes/community-niche/tokens.ts +177 -0
  95. package/themes/corporate-grid/THEME.md +154 -0
  96. package/themes/corporate-grid/tokens.ts +182 -0
  97. package/themes/couture-luxury/THEME.md +85 -0
  98. package/themes/couture-luxury/tokens.ts +146 -0
  99. package/themes/creator-social/THEME.md +131 -0
  100. package/themes/creator-social/tokens.ts +249 -0
  101. package/themes/crypto-onchain/THEME.md +100 -0
  102. package/themes/crypto-onchain/tokens.ts +207 -0
  103. package/themes/cycling-brand/THEME.md +78 -0
  104. package/themes/cycling-brand/tokens.ts +185 -0
  105. package/themes/dating-friendly/THEME.md +102 -0
  106. package/themes/dating-friendly/tokens.ts +178 -0
  107. package/themes/dense-utility/THEME.md +85 -0
  108. package/themes/dense-utility/tokens.ts +155 -0
  109. package/themes/devtool-cli/THEME.md +100 -0
  110. package/themes/devtool-cli/tokens.ts +195 -0
  111. package/themes/devtool-docs/THEME.md +105 -0
  112. package/themes/devtool-docs/tokens.ts +177 -0
  113. package/themes/editorial/THEME.md +129 -0
  114. package/themes/editorial/audit.log.jsonl +2 -0
  115. package/themes/editorial/tailwind.snippet.ts +15 -0
  116. package/themes/editorial/theme.yml +173 -0
  117. package/themes/editorial/tokens.ts +29 -0
  118. package/themes/education-formal/THEME.md +154 -0
  119. package/themes/education-formal/audit.log.jsonl +1 -0
  120. package/themes/education-formal/tailwind.snippet.ts +15 -0
  121. package/themes/education-formal/theme.yml +186 -0
  122. package/themes/education-formal/tokens.ts +29 -0
  123. package/themes/education-warm/THEME.md +91 -0
  124. package/themes/education-warm/tokens.ts +185 -0
  125. package/themes/ember-poster/README.md +79 -0
  126. package/themes/ember-poster/THEME.md +101 -0
  127. package/themes/ember-poster/audit.log.jsonl +17 -0
  128. package/themes/ember-poster/package.json +34 -0
  129. package/themes/ember-poster/tailwind.snippet.ts +17 -0
  130. package/themes/ember-poster/theme.yml +109 -0
  131. package/themes/ember-poster/tokens.ts +27 -0
  132. package/themes/enterprise-cloud/THEME.md +139 -0
  133. package/themes/enterprise-cloud/tokens.ts +179 -0
  134. package/themes/enterprise-tech/.anchor-render.png +0 -0
  135. package/themes/enterprise-tech/THEME.md +167 -0
  136. package/themes/enterprise-tech/audit.log.jsonl +1 -0
  137. package/themes/enterprise-tech/tailwind.snippet.ts +15 -0
  138. package/themes/enterprise-tech/theme.yml +202 -0
  139. package/themes/enterprise-tech/tokens.ts +29 -0
  140. package/themes/ev-charging/THEME.md +94 -0
  141. package/themes/ev-charging/tokens.ts +185 -0
  142. package/themes/farm-direct/THEME.md +92 -0
  143. package/themes/farm-direct/tokens.ts +180 -0
  144. package/themes/fintech-card/THEME.md +96 -0
  145. package/themes/fintech-card/tokens.ts +191 -0
  146. package/themes/fintech-trust/THEME.md +94 -0
  147. package/themes/fintech-trust/tokens.ts +192 -0
  148. package/themes/food-blog/THEME.md +98 -0
  149. package/themes/food-blog/tokens.ts +183 -0
  150. package/themes/forum-classic/THEME.md +100 -0
  151. package/themes/forum-classic/tokens.ts +168 -0
  152. package/themes/fresh-plate/.anchor-render.png +0 -0
  153. package/themes/fresh-plate/THEME.md +144 -0
  154. package/themes/fresh-plate/audit.log.jsonl +2 -0
  155. package/themes/fresh-plate/dismissals.jsonl +3 -0
  156. package/themes/fresh-plate/tailwind.snippet.ts +16 -0
  157. package/themes/fresh-plate/theme.yml +189 -0
  158. package/themes/fresh-plate/tokens.ts +30 -0
  159. package/themes/furniture-modern/THEME.md +94 -0
  160. package/themes/furniture-modern/tokens.ts +176 -0
  161. package/themes/gaming-esports/THEME.md +146 -0
  162. package/themes/gaming-esports/tokens.ts +199 -0
  163. package/themes/gaming-streamer/THEME.md +139 -0
  164. package/themes/gaming-streamer/tokens.ts +201 -0
  165. package/themes/glassmorphic-modern/THEME.md +119 -0
  166. package/themes/glassmorphic-modern/tokens.ts +174 -0
  167. package/themes/government-civic/THEME.md +138 -0
  168. package/themes/government-civic/tokens.ts +164 -0
  169. package/themes/gym-chain/THEME.md +79 -0
  170. package/themes/gym-chain/tokens.ts +196 -0
  171. package/themes/healthcare-bright/THEME.md +95 -0
  172. package/themes/healthcare-bright/tokens.ts +184 -0
  173. package/themes/home-decor/THEME.md +94 -0
  174. package/themes/home-decor/tokens.ts +177 -0
  175. package/themes/hotel-boutique/THEME.md +110 -0
  176. package/themes/hotel-boutique/tokens.ts +179 -0
  177. package/themes/hyperminimal-mono/THEME.md +91 -0
  178. package/themes/hyperminimal-mono/tokens.ts +150 -0
  179. package/themes/indie-art-game/THEME.md +107 -0
  180. package/themes/indie-art-game/tokens.ts +216 -0
  181. package/themes/insurance-legacy/THEME.md +101 -0
  182. package/themes/insurance-legacy/tokens.ts +182 -0
  183. package/themes/insurance-modern/THEME.md +103 -0
  184. package/themes/insurance-modern/tokens.ts +192 -0
  185. package/themes/kaiju-reveal/THEME.md +97 -0
  186. package/themes/kaiju-reveal/tokens.ts +185 -0
  187. package/themes/kinetic-data/THEME.md +172 -0
  188. package/themes/kinetic-data/audit.log.jsonl +1 -0
  189. package/themes/kinetic-data/tailwind.snippet.ts +16 -0
  190. package/themes/kinetic-data/theme.yml +207 -0
  191. package/themes/kinetic-data/tokens.ts +30 -0
  192. package/themes/kinetic-headline/.anchor-render.png +0 -0
  193. package/themes/kinetic-headline/BUILD_BRIEF.md +156 -0
  194. package/themes/kinetic-headline/THEME.md +78 -0
  195. package/themes/kinetic-headline/audit.log.jsonl +4 -0
  196. package/themes/kinetic-headline/dismissals.jsonl +1 -0
  197. package/themes/kinetic-headline/tailwind.snippet.ts +16 -0
  198. package/themes/kinetic-headline/theme.yml +81 -0
  199. package/themes/kinetic-headline/tokens.ts +26 -0
  200. package/themes/law-firm/THEME.md +108 -0
  201. package/themes/law-firm/tokens.ts +158 -0
  202. package/themes/lawtech-modern/THEME.md +107 -0
  203. package/themes/lawtech-modern/tokens.ts +192 -0
  204. package/themes/linkedin-pro/THEME.md +102 -0
  205. package/themes/linkedin-pro/tokens.ts +174 -0
  206. package/themes/logistics-modern/THEME.md +94 -0
  207. package/themes/logistics-modern/tokens.ts +187 -0
  208. package/themes/magazine-glossy/THEME.md +74 -0
  209. package/themes/magazine-glossy/tokens.ts +158 -0
  210. package/themes/marker-mag/THEME.md +128 -0
  211. package/themes/marker-mag/audit.log.jsonl +1 -0
  212. package/themes/marker-mag/tailwind.snippet.ts +15 -0
  213. package/themes/marker-mag/theme.yml +159 -0
  214. package/themes/marker-mag/tokens.ts +27 -0
  215. package/themes/marketplace-modern/THEME.md +135 -0
  216. package/themes/marketplace-modern/tokens.ts +186 -0
  217. package/themes/marketplace-vintage/THEME.md +110 -0
  218. package/themes/marketplace-vintage/tokens.ts +185 -0
  219. package/themes/maximalist/THEME.md +96 -0
  220. package/themes/maximalist/tokens.ts +168 -0
  221. package/themes/mid-century/THEME.md +109 -0
  222. package/themes/mid-century/tokens.ts +162 -0
  223. package/themes/motorcycle-brand/THEME.md +86 -0
  224. package/themes/motorcycle-brand/tokens.ts +174 -0
  225. package/themes/museum/THEME.md +83 -0
  226. package/themes/museum/tokens.ts +147 -0
  227. package/themes/music-streaming/THEME.md +101 -0
  228. package/themes/music-streaming/tokens.ts +187 -0
  229. package/themes/music-vinyl/THEME.md +98 -0
  230. package/themes/music-vinyl/tokens.ts +167 -0
  231. package/themes/nature-distilled/.anchor-render.png +0 -0
  232. package/themes/nature-distilled/BUILD_BRIEF.md +158 -0
  233. package/themes/nature-distilled/THEME.md +81 -0
  234. package/themes/nature-distilled/audit.log.jsonl +2 -0
  235. package/themes/nature-distilled/tailwind.snippet.ts +16 -0
  236. package/themes/nature-distilled/theme.yml +91 -0
  237. package/themes/nature-distilled/tokens.ts +26 -0
  238. package/themes/news-tabloid/THEME.md +72 -0
  239. package/themes/news-tabloid/tokens.ts +158 -0
  240. package/themes/news-tech/THEME.md +75 -0
  241. package/themes/news-tech/tokens.ts +149 -0
  242. package/themes/newsletter/THEME.md +82 -0
  243. package/themes/newsletter/tokens.ts +138 -0
  244. package/themes/newspaper-classic/THEME.md +74 -0
  245. package/themes/newspaper-classic/tokens.ts +159 -0
  246. package/themes/nonprofit-arts/THEME.md +78 -0
  247. package/themes/nonprofit-arts/tokens.ts +157 -0
  248. package/themes/nonprofit-warm/THEME.md +105 -0
  249. package/themes/nonprofit-warm/tokens.ts +188 -0
  250. package/themes/outdoor-adventure/THEME.md +113 -0
  251. package/themes/outdoor-adventure/tokens.ts +181 -0
  252. package/themes/overland-broadside/THEME.md +119 -0
  253. package/themes/overland-broadside/audit.log.jsonl +1 -0
  254. package/themes/overland-broadside/tailwind.snippet.ts +17 -0
  255. package/themes/overland-broadside/theme.yml +138 -0
  256. package/themes/overland-broadside/tokens.ts +27 -0
  257. package/themes/performance-engineered/THEME.md +162 -0
  258. package/themes/performance-engineered/audit.log.jsonl +1 -0
  259. package/themes/performance-engineered/tailwind.snippet.ts +15 -0
  260. package/themes/performance-engineered/theme.yml +193 -0
  261. package/themes/performance-engineered/tokens.ts +29 -0
  262. package/themes/pet-food/THEME.md +78 -0
  263. package/themes/pet-food/tokens.ts +185 -0
  264. package/themes/pharma-clinical/THEME.md +164 -0
  265. package/themes/pharma-clinical/audit.log.jsonl +1 -0
  266. package/themes/pharma-clinical/tailwind.snippet.ts +15 -0
  267. package/themes/pharma-clinical/theme.yml +201 -0
  268. package/themes/pharma-clinical/tokens.ts +29 -0
  269. package/themes/pill-editorial/THEME.md +125 -0
  270. package/themes/pill-editorial/audit.log.jsonl +1 -0
  271. package/themes/pill-editorial/tailwind.snippet.ts +15 -0
  272. package/themes/pill-editorial/theme.yml +168 -0
  273. package/themes/pill-editorial/tokens.ts +31 -0
  274. package/themes/podcast-warm/THEME.md +103 -0
  275. package/themes/podcast-warm/tokens.ts +192 -0
  276. package/themes/publisher-indie/THEME.md +78 -0
  277. package/themes/publisher-indie/tokens.ts +148 -0
  278. package/themes/raw-concrete/BUILD_BRIEF.md +157 -0
  279. package/themes/raw-concrete/THEME.md +76 -0
  280. package/themes/raw-concrete/audit.log.jsonl +10 -0
  281. package/themes/raw-concrete/tailwind.snippet.ts +16 -0
  282. package/themes/raw-concrete/theme.yml +88 -0
  283. package/themes/raw-concrete/tokens.ts +27 -0
  284. package/themes/realestate-luxury/THEME.md +94 -0
  285. package/themes/realestate-luxury/tokens.ts +169 -0
  286. package/themes/realestate-marketplace/THEME.md +106 -0
  287. package/themes/realestate-marketplace/tokens.ts +183 -0
  288. package/themes/restaurant-modern/THEME.md +109 -0
  289. package/themes/restaurant-modern/tokens.ts +172 -0
  290. package/themes/runway-fashion/THEME.md +99 -0
  291. package/themes/runway-fashion/tokens.ts +167 -0
  292. package/themes/saturday-morning/THEME.md +117 -0
  293. package/themes/saturday-morning/tokens.ts +281 -0
  294. package/themes/schema.ts +235 -0
  295. package/themes/signal-dark/BUILD_BRIEF.md +168 -0
  296. package/themes/signal-dark/THEME.md +107 -0
  297. package/themes/signal-dark/tokens.ts +181 -0
  298. package/themes/soft-modern/THEME.md +91 -0
  299. package/themes/soft-modern/tokens.ts +166 -0
  300. package/themes/solar-residential/THEME.md +92 -0
  301. package/themes/solar-residential/tokens.ts +176 -0
  302. package/themes/sports-league/THEME.md +180 -0
  303. package/themes/sports-league/audit.log.jsonl +1 -0
  304. package/themes/sports-league/tailwind.snippet.ts +15 -0
  305. package/themes/sports-league/theme.yml +213 -0
  306. package/themes/sports-league/tokens.ts +32 -0
  307. package/themes/stadium-sport/THEME.md +114 -0
  308. package/themes/stadium-sport/tokens.ts +187 -0
  309. package/themes/streetwear-hype/THEME.md +100 -0
  310. package/themes/streetwear-hype/tokens.ts +174 -0
  311. package/themes/studio-architect/THEME.md +108 -0
  312. package/themes/studio-architect/tokens.ts +162 -0
  313. package/themes/studio-photographer/THEME.md +88 -0
  314. package/themes/studio-photographer/tokens.ts +164 -0
  315. package/themes/team-kanban/.anchor-render.png +0 -0
  316. package/themes/team-kanban/THEME.md +167 -0
  317. package/themes/team-kanban/audit.log.jsonl +2 -0
  318. package/themes/team-kanban/dismissals.jsonl +1 -0
  319. package/themes/team-kanban/tailwind.snippet.ts +15 -0
  320. package/themes/team-kanban/theme.yml +209 -0
  321. package/themes/team-kanban/tokens.ts +35 -0
  322. package/themes/telehealth-modern/THEME.md +95 -0
  323. package/themes/telehealth-modern/tokens.ts +197 -0
  324. package/themes/tourism-board/THEME.md +111 -0
  325. package/themes/tourism-board/tokens.ts +173 -0
  326. package/themes/toys-modern/THEME.md +79 -0
  327. package/themes/toys-modern/tokens.ts +200 -0
  328. package/themes/travel-luxury/THEME.md +95 -0
  329. package/themes/travel-luxury/tokens.ts +162 -0
  330. package/themes/vacation-rental/THEME.md +105 -0
  331. package/themes/vacation-rental/tokens.ts +174 -0
  332. package/themes/vault-reel/THEME.md +134 -0
  333. package/themes/vault-reel/audit.log.jsonl +3 -0
  334. package/themes/vault-reel/tailwind.snippet.ts +16 -0
  335. package/themes/vault-reel/theme.yml +167 -0
  336. package/themes/vault-reel/tokens.ts +30 -0
  337. package/themes/vet-modern/THEME.md +79 -0
  338. package/themes/vet-modern/tokens.ts +194 -0
  339. package/themes/web3-restraint/THEME.md +87 -0
  340. package/themes/web3-restraint/tokens.ts +154 -0
  341. package/themes/wellness-active/THEME.md +102 -0
  342. package/themes/wellness-active/tokens.ts +203 -0
  343. package/themes/wellness-spa/THEME.md +93 -0
  344. package/themes/wellness-spa/tokens.ts +173 -0
  345. package/themes/y2k-chrome/THEME.md +118 -0
  346. package/themes/y2k-chrome/tokens.ts +249 -0
  347. package/themes/yoga-studio/THEME.md +76 -0
  348. package/themes/yoga-studio/tokens.ts +163 -0
@@ -0,0 +1,174 @@
1
+ import type { Direction } from "../schema";
2
+
3
+ export const vacationRental: Direction = {
4
+ name: "vacation-rental",
5
+ ethos: "Airbnb soft pink consumer marketing · Vrbo family-warm · Plum Guide curated charcoal · Whimstay last-minute coral · Sonder modern-stay rounded chrome",
6
+ references: [
7
+ { brand: "Airbnb", trait: "Cereal wordmark, soft coral-pink hover state, rounded photo-card grid" },
8
+ { brand: "Vrbo", trait: "family-warm photography, deep-blue trust accent" },
9
+ { brand: "Plum Guide", trait: "curated charcoal headers, hand-picked editorial captions" },
10
+ { brand: "Whimstay", trait: "last-minute coral signal, percent-off badge language" },
11
+ { brand: "Sonder", trait: "modern-stay rounded chrome, hospitality dashboard pacing" },
12
+ ],
13
+ feel:
14
+ "Friendly consumer marketplace. Soft pink primary, generous rounded corners, warm photography-led product cards. " +
15
+ "Search density up front — filter row, photo grid, wishlist hearts. Reads productive and warm at once: " +
16
+ "the page you would actually book a cabin on for next weekend, not a luxury portfolio.",
17
+
18
+ fonts: {
19
+ display: {
20
+ family: "DM Sans",
21
+ fallback: ["Plus Jakarta Sans", "Inter", "system-ui", "sans-serif"],
22
+ from: "Airbnb Cereal stand-in — friendly geometric, photo-card-friendly weight",
23
+ googleFont: "DM+Sans",
24
+ weights: [400, 500, 700],
25
+ },
26
+ body: {
27
+ family: "Inter",
28
+ fallback: ["system-ui", "-apple-system", "BlinkMacSystemFont", "sans-serif"],
29
+ from: "Vrbo/Sonder body sans — neutral, dense, dashboard-readable at small sizes",
30
+ googleFont: "Inter",
31
+ weights: [400, 500, 600],
32
+ },
33
+ mono: {
34
+ family: "JetBrains Mono",
35
+ fallback: ["ui-monospace", "monospace"],
36
+ from: "small only — guest counts, night counts, price-per-night tabular numerics",
37
+ googleFont: "JetBrains+Mono",
38
+ weights: [400, 500],
39
+ },
40
+ },
41
+
42
+ typography: {
43
+ headingTracking: "-0.018em",
44
+ bodyTracking: "0",
45
+ fontFeatureSettings: '"cv11", "ss01", "tnum"',
46
+ h1ScaleClamp: "clamp(2rem, 4.5vw, 3.25rem)",
47
+ bodyBaseSize: "0.9375rem",
48
+ bodyLineHeight: "1.55",
49
+ },
50
+
51
+ colors: {
52
+ background: { hsl: "0 0% 100%", from: "Airbnb pure white — photography reads truest on white" },
53
+ foreground: { hsl: "0 0% 14%", from: "Airbnb near-black — Cereal ink, never pure black" },
54
+ card: { hsl: "0 0% 100%", from: "same as background — cards lift via shadow, not fill" },
55
+ popover: { hsl: "0 0% 100%", from: "same as card" },
56
+ primary: { hsl: "351 78% 56%", from: "Airbnb Rausch — the canonical soft coral-pink" },
57
+ primaryForeground: { hsl: "0 0% 100%", from: "white on Rausch pink" },
58
+ secondary: { hsl: "20 30% 96%", from: "soft warm-blush surface — wishlist tile bg" },
59
+ secondaryForeground: { hsl: "0 0% 14%", from: "near-black on warm blush" },
60
+ muted: { hsl: "20 18% 95%", from: "muted blush — chips and filter inactive states" },
61
+ mutedForeground: { hsl: "0 0% 44%", from: "neutral gray — meta, ratings count, address" },
62
+ accent: { hsl: "351 86% 96%", from: "primary-tinted blush — hover fill for soft cards" },
63
+ accentForeground: { hsl: "351 62% 36%", from: "deepened coral on blush bg" },
64
+ border: { hsl: "0 0% 88%", from: "soft border — photo-card hairline" },
65
+ input: { hsl: "0 0% 86%", from: "input border — slightly deeper than card border" },
66
+ ring: { hsl: "351 78% 56%", from: "Rausch focus ring" },
67
+ destructive: { hsl: "354 80% 52%", from: "warm error red — sibling of primary, not enterprise red" },
68
+ destructiveForeground: { hsl: "0 0% 100%", from: "white on warm red" },
69
+ brand: {
70
+ "rausch-pink": { hsl: "351 78% 56%", from: "Airbnb Rausch — the canonical accent" },
71
+ "rausch-deep": { hsl: "351 72% 44%", from: "pressed coral, button:active" },
72
+ "blush-soft": { hsl: "20 30% 96%", from: "warm-blush secondary surface" },
73
+ "vrbo-blue": { hsl: "215 70% 38%", from: "Vrbo trust-blue — used only on Verified Host / Superhost chips" },
74
+ "wishlist-rose": { hsl: "351 86% 96%", from: "wishlist-tile fill, heart hover bg" },
75
+ "whimstay-coral": { hsl: "12 88% 60%", from: "last-minute deal coral — never primary, only percent-off badges" },
76
+ "rating-gold": { hsl: "42 78% 50%", from: "Airbnb star rating — used only on ★ glyphs" },
77
+ },
78
+ },
79
+
80
+ spacing: {
81
+ base: 4,
82
+ scale: [4, 6, 8, 10, 12, 16, 20, 24, 32, 40, 48, 64, 80, 96],
83
+ containerMax: "max-w-7xl",
84
+ containerPadding: "px-4 lg:px-10",
85
+ sectionPadding: {
86
+ hero: "pt-12 pb-8 lg:pt-16 lg:pb-12",
87
+ default: "py-12 lg:py-16",
88
+ tight: "py-8 lg:py-10",
89
+ },
90
+ },
91
+
92
+ radius: {
93
+ base: "0.75rem",
94
+ pillsAllowed: true,
95
+ },
96
+
97
+ shadows: {
98
+ style: "soft",
99
+ utilities: {
100
+ "shadow-card":
101
+ "0 1px 2px hsl(0 0% 0% / 0.04), 0 4px 16px hsl(0 0% 0% / 0.06)",
102
+ "shadow-card-hover":
103
+ "0 2px 6px hsl(0 0% 0% / 0.06), 0 16px 36px hsl(0 0% 0% / 0.10)",
104
+ "shadow-sticky":
105
+ "0 1px 0 0 hsl(0 0% 0% / 0.06), 0 12px 24px hsl(0 0% 0% / 0.06)",
106
+ },
107
+ },
108
+
109
+ motion: {
110
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)",
111
+ durations: {
112
+ reveal: 400,
113
+ loop: 1600,
114
+ ambient: 12000,
115
+ },
116
+ keyframes: {
117
+ "fade-up": {
118
+ css:
119
+ "from { opacity: 0; transform: translateY(8px); }\n" +
120
+ "to { opacity: 1; transform: translateY(0); }",
121
+ defaultDuration: 400,
122
+ iteration: "once",
123
+ purpose: "card-grid entrance — short, consumer-fast",
124
+ },
125
+ "heart-pop": {
126
+ css:
127
+ "0% { transform: scale(1); }\n" +
128
+ "40% { transform: scale(1.35); }\n" +
129
+ "100% { transform: scale(1); }",
130
+ defaultDuration: 360,
131
+ iteration: "once",
132
+ purpose: "wishlist heart toggle — Airbnb-signature interaction",
133
+ },
134
+ "shimmer": {
135
+ css:
136
+ "0% { background-position: -200% 0; }\n" +
137
+ "100% { background-position: 200% 0; }",
138
+ defaultDuration: 1600,
139
+ iteration: "infinite",
140
+ purpose: "photo-card skeleton on initial load",
141
+ },
142
+ },
143
+ respectsReducedMotion: true,
144
+ },
145
+
146
+ density: "medium",
147
+
148
+ patterns: {
149
+ button:
150
+ "Primary = solid Rausch-pink fill, rounded-xl (12px), weight 600. " +
151
+ "Secondary = outlined ghost (foreground border, white bg). " +
152
+ "Tertiary = underline text-link in foreground (never pink links inline — pink is reserved for actions). " +
153
+ "Filter chips are pills; status chips (Superhost, Free cancellation) are pills with subtle bg.",
154
+ card:
155
+ "Property card = rounded-xl, no border, white bg, .shadow-card. " +
156
+ "Photo is the lead (4:3 or 5:4 image, rounded-xl, top-corner heart). " +
157
+ "Title in DM Sans 500, subtitle in muted-foreground, ★ rating row, price row with /night. " +
158
+ "Hover lifts to .shadow-card-hover and the heart fills.",
159
+ input:
160
+ "Pill-shape rounded-full search bar with embedded filter columns (Where · When · Guests). " +
161
+ "Compact inputs (h-10) rounded-md, soft border, white bg. " +
162
+ "Focus uses ring (2px Rausch at 45%).",
163
+ cta:
164
+ "Filled Rausch-pink rect is the primary action — 'Reserve', 'Continue', 'Show on Map'. " +
165
+ "Wishlist heart is the icon-CTA. Never a gradient button — coral solid is the language.",
166
+ },
167
+
168
+ details: {
169
+ selectionBg: "hsl(var(--primary) / 0.22)",
170
+ selectionFg: "hsl(var(--foreground))",
171
+ focusRing: "2px solid hsl(var(--ring) / 0.5)",
172
+ scrollbarStyle: "thin",
173
+ },
174
+ };
@@ -0,0 +1,134 @@
1
+ # Vault Reel
2
+
3
+ > Cinema-archive director-portfolio register — extreme dark canvas at
4
+
5
+ **Slug:** `vault-reel` — **Surface:** web — **Density:** dense
6
+
7
+ ## Influence
8
+
9
+ Commercial-director and cinematographer portfolios (the register held by working directors between production seasons — extreme minimalism, one confident video reel front-and-center, everything else stripped to a broadcast console). Also archival cinema microsites (Criterion Channel at its darkest, Metrograph program guides), and the diegetic-UI language of film-industry tools (Frame.io comment bars, Avid timeline scrubbers). Distinct from other Family E bases through the extreme-dark canvas + broadcast-console chrome + the deliberate empty-scroll abyss that separates the hero from the vault teaser.
10
+
11
+
12
+ ## Signature move
13
+
14
+ Extreme dark canvas at #0a0a0a — the register's non-negotiable base.
15
+ Every card, button, control, video tile, input, and nav link ships at
16
+ 0px border radius — sharp edges are the second non-negotiable move.
17
+ A single widescreen VIDEO REEL tile dominates the hero at ~1200x675px
18
+ (16:9), positioned dead-center of a 3-column composition. Left column
19
+ holds two diegetic broadcast widgets (CART / SORT BY labels stacked
20
+ in a tight utility grid). Right column holds the reel index — a small
21
+ "REEL 2026" title in the display face, a two-line description in
22
+ Times italic, and a numeric pagination readout (01 / 15) in the
23
+ display face. The reel tile itself renders a matte-black video
24
+ surface with two small red heart-shape SVG markers as annotation
25
+ cues in the top corners, a "SUBSCRIBE NOW" pill button (the ONE
26
+ pill in the theme, deliberately misfit as a broadcast affordance)
27
+ at bottom-left, and a scrubber timeline strip at the bottom with a
28
+ red pulse marker at ~63% position. Below the reel: a static-noise
29
+ divider band (subtle SVG grain pattern) separates hero from vault
30
+ teaser. The VAULT TEASER is a small centered "THE VAULT →" label
31
+ after a deliberate extreme scroll gap (5-6x viewport of black
32
+ abyss). The VAULT INDEX itself is a 4-column grid of matte-black
33
+ film-strip thumbnails, each showing a project title in the display
34
+ face + a two-line credit line in Times italic + the film-strip
35
+ sprocket-hole SVG decoration on the left and right edges. A
36
+ FILMOGRAPHY MARQUEE scrolls horizontally across the bottom third —
37
+ the projects loop across the viewport in the display face at 20s
38
+ per loop. A DIEGETIC TIMESTAMP CLOCK renders at the very bottom of
39
+ the page in the display face — HH:MM:SS updating in real time,
40
+ positioned centered, reading as broadcast-console UI. Footer
41
+ strip shows a © THE FRIEND wordmark on the left, INSTAGRAM / IMDB
42
+ utility labels centered, and the THE FRIEND display wordmark
43
+ right-aligned. Small mono-caps 11px 0.18em-tracked eyebrow labels
44
+ are LEGITIMATELY USED throughout as diegetic widget labels
45
+ (this theme's rare exception to the universal slop-blocklist —
46
+ see eyebrow_exception in typography). Brand character sits in the
47
+ extreme black canvas, the tight geometric display, the burning-red
48
+ accent, and the broadcast-console chrome — not in decoration,
49
+ not in warmth, not in polish.
50
+
51
+ ## Palette
52
+
53
+ - **bg:** `#0a0a0a`
54
+ - **surface:** `#141414`
55
+ - **ink:** `#d4ceb8`
56
+ - **accent:** `#8a1106`
57
+ - **secondary:** `#b01608`
58
+
59
+ ## Typography
60
+
61
+ - **Display:** BNDimeDisplay (reference proprietary face — tight geometric bold uppercase sans with a slightly-condensed proportion). Free fallback stack — Space Grotesk 700, Barlow Condensed 700, system-ui, sans-serif. Weight 400-700, ALWAYS UPPERCASE, letter-spacing -0.68px (tight negative tracking — this is the register's typographic fingerprint). Scale — 34px is the measured top-of-scale in the reference, deliberately restrained rather than monumental. This is a small-display theme, not a monumental-display theme — the drama lives in the composition and the black abyss, not in headline size.
62
+ - **Body:** Times (system serif — deliberately anti-modern, cinematic old-media). Fallback — "Times New Roman", Georgia, serif. Weight 400, mixed case, 14-16px body copy, line-height 1.5. Times is the anti-tech signal — every SaaS site uses Inter; this uses Times, which reads as film-industry / cinema-archive rather than tech-product.
63
+ - **Mono:** none. Vault Reel is a consumer director-portfolio surface. Mono has no role here (the timestamp clock uses the display face, not a mono).
64
+ - **Scale:** 1.25 (perfect fourth — deliberately compressed scale so the composition reads as dense broadcast-console rather than marketing-hero)
65
+
66
+ ## Motion
67
+
68
+ Ships live in the section renderer (no external dependencies):
69
+ 1. Video-reel scrubber timeline pulses — the red progress mark on the reel scrubber breathes 0.85 → 1 opacity on a 2s ease-in-out loop, signaling active-playback status without actually playing video.
70
+ 2. Timestamp clock — the diegetic HH:MM:SS clock at the bottom of the composition updates every second in real time (setInterval 1000). Reads as broadcast-console UI. Not a marketing motion — a state readout.
71
+ 3. Nav active-word — the currently-selected top nav word (HOME / REEL / ABOUT / CONTACT) is red; hovering another word transitions its color to red over 200ms.
72
+ 4. Scroll-triggered reel reveal — the vault-teaser text at the bottom of the scroll gap fades in from opacity 0 to 1 over 600ms when the IntersectionObserver fires at 40% visibility. No slide-up, no scale — pure opacity.
73
+ 5. Vault thumbnail hover — each vault-grid thumbnail dims its non-hovered siblings to opacity 0.4 over 240ms while the hovered thumbnail stays full opacity + shows a red micro-underline beneath the title.
74
+ 6. Static-noise band — the mid-page divider band shows a 3-frame CSS animation that steps through three subtle grain-noise SVG patterns at 250ms per frame (grain-1 / grain-2 / grain-3 / grain-1 loop), reading as film-grain flicker.
75
+ 7. prefers-reduced-motion: reduce — timestamp still ticks (this is a state readout, not decoration); scrubber breathe paused; static-noise band frozen on a single frame; vault-thumbnail dim disabled. State changes still fire.
76
+
77
+ Customer installs these as dependencies for the deeper motion tier:
78
+ - Lenis — smooth inertial scroll (the extreme 8000px+ page benefits from inertial cadence).
79
+ - Custom scroll-triggered chapter markers as the user scrolls past each vault section.
80
+ - A real HLS.js video player wired into the featured reel tile (currently an FPO SVG that mimics the video-player chrome).
81
+
82
+ Motion character: broadcast-console, diegetic, functional. Custom cubic-bezier(0.19,1,0.22,1) for opacity reveals. The register lives in production-tool authenticity — motion should feel like a Frame.io comment cue, not a marketing headline animation.
83
+
84
+
85
+ ## Imagery
86
+
87
+ Photographic + video-still imagery of directorial subjects — the
88
+ reference uses stills from actual commercial + music-video reels
89
+ shot under directional light. FPO imagery here should read as
90
+ matte cinematic still-frames — colored surface panels with subtle
91
+ gradient masks that suggest a video-player rendering, not literal
92
+ photography. Every video/reel tile masks to a SHARP-CORNERED
93
+ rectangle at exactly 16:9. NO gradient blobs, NO glassmorphism,
94
+ NO stock cinema-cliche photography (the "clapperboard + film reel
95
+ spinning" tell). NO warm-glow FPO fills (the warm-radial gradient
96
+ tell). Film-strip sprocket-hole SVG ornaments on vault-index tile
97
+ edges are permitted per the CHROME INVENTORY.
98
+
99
+ ## Best for
100
+
101
+ - Commercial-director and music-video-director portfolios
102
+ - Cinematographer + director-of-photography sites
103
+ - Production-house imprints and small studio landing pages
104
+ - Editorial reels for creative agencies with a cinema-adjacent register
105
+ - Film-festival and program-guide microsites (Metrograph-style)
106
+ - Photographer portfolios with a cinematic register (not editorial-magazine)
107
+
108
+ ## Reject if
109
+
110
+ _Director grades each of the following as a pass/fail check. Any violation blocks the theme._
111
+
112
+ - Non-0px border radius — sharp edges are the register's second non-negotiable move. Rounded corners on cards, video tiles, buttons, or inputs immediately break the register.
113
+ - Light canvas (white / cream / gray) as the primary background — canvas IS extreme black. Swapping to a light canvas collapses this into generic-photographer-portfolio slop.
114
+ - Multiple accent colors flooding the composition — RED is the only accent, used sparingly for interactive emphasis. Introducing amber / cream / any additional color as an accent collapses the register.
115
+ - Monumental display type at 200px+ — this theme's display scale is deliberately RESTRAINED (top at 34px). The drama lives in the composition and the black abyss, not in headline size.
116
+ - Rounded pill buttons in the SUBSCRIBE NOW spot — the reference uses a SHARP-CORNERED chip. The one 'pill' is deliberately misfit as a broadcast affordance, but its actual radius is 0px.
117
+ - Corporate polish — no drop-shadow-md, no soft-glow, no gradient backdrop. Video tiles are FLAT matte-black rectangles with color fills only.
118
+ - Warm-glow FPO gradients — the register is COLD and matte. Warm radials collapse it into editorial-luxury slop.
119
+ - Uniform 3- or 4-column feature-card grids in the vault index — the vault tiles alternate size, orientation, and layout. Not a template.
120
+ - Emoji or decorative unicode marks — bespoke SVG (film-strip sprockets, heart markers, static-noise patterns) carry all the ornamentation.
121
+ - Marketing headline animations — the reveals here are DIEGETIC (timestamp ticking, scrubber pulsing, static flicker). Slide-up + fade-in stagger animations collapse the register into marketing slop.
122
+
123
+ ## Banned defaults (inherited + theme-specific)
124
+
125
+ - claude-cream (#F4F1EA + serif + #D97757)
126
+ - void+acid (near-black bg + single bright acid-green or vermilion accent — this theme's accent is deep BURNING RED, not acid)
127
+ - broadsheet-on-noneditorial (hairline rules + zero border-radius + newspaper columns — Vault Reel is 0px radius but composition is broadcast-console, not broadsheet)
128
+ - tech-bro purple gradient (purple→blue gradient hero + centered headline + double CTA + emoji icons)
129
+ - uniform-everything (identical padding + one weight of one sans doing every job + rounded-2xl + shadow-md cards)
130
+ - rounded-corner-anywhere (this theme's whole point is the sharp-cornered broadcast-console chrome. A rounded card, button, or input anywhere on the page immediately breaks the register.)
131
+ - cream-canvas-flood (cream is INK + INVERTED-BAND color, not a canvas primary. Making cream the whole page background collapses the theme into generic-photographer-portfolio.)
132
+ - warm-radial-gradient-fpo (the FPO video/reel tiles must be MATTE BLACK with subtle gradient masks that suggest a video-player rendering, not warm-glow decoration.)
133
+ - monumental-display-slop (headlines above ~40px collapse this into a monumental-editorial base — the register requires RESTRAINED display scale so the composition and the abyss carry the drama.)
134
+ - clapperboard-cinema-cliche (imagery that reads as 'film reel spinning' or 'clapperboard' is stock cinema-cliche. FPO here must read as matte cinematic still-frames from directorial work, not from a stock cinema-decoration library.)
@@ -0,0 +1,3 @@
1
+ {"slug":"vault-reel","gates":[{"gate":"slop-blocklist","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:12.364Z","dismissed":[]},{"gate":"regression-scan","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:12.372Z","dismissed":[]},{"gate":"avoid-rubric","verdict":{"passed":true,"failures":[],"skipped":"ANTHROPIC_API_KEY not set — avoid-rubric gate skipped. Set the key to grade against theme.avoid array."},"ran_at":"2026-07-04T08:42:12.372Z","dismissed":[]},{"gate":"anchor-compare","verdict":{"passed":true,"failures":[],"skipped":"Family E rubric.md missing at /Users/mattfrischer/Taste/site/design-system/golden-set/E/rubric.md — anchor-compare skipped."},"ran_at":"2026-07-04T08:42:12.372Z","dismissed":[]}],"overall":"PASS","ran_at":"2026-07-04T08:42:12.364Z"}
2
+ {"slug":"vault-reel","gates":[{"gate":"slop-blocklist","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:20.458Z","dismissed":[]},{"gate":"regression-scan","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:20.466Z","dismissed":[]},{"gate":"avoid-rubric","verdict":{"passed":true,"failures":[],"skipped":"ANTHROPIC_API_KEY not set — avoid-rubric gate skipped. Set the key to grade against theme.avoid array."},"ran_at":"2026-07-04T08:42:20.466Z","dismissed":[]},{"gate":"anchor-compare","verdict":{"passed":true,"failures":[],"skipped":"Family E rubric.md missing at /Users/mattfrischer/Taste/site/design-system/golden-set/E/rubric.md — anchor-compare skipped."},"ran_at":"2026-07-04T08:42:20.466Z","dismissed":[]}],"overall":"PASS","ran_at":"2026-07-04T08:42:20.458Z"}
3
+ {"slug":"vault-reel","gates":[{"gate":"slop-blocklist","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:34.312Z","dismissed":[]},{"gate":"regression-scan","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:42:34.320Z","dismissed":[]},{"gate":"avoid-rubric","verdict":{"passed":true,"failures":[]},"ran_at":"2026-07-04T08:43:13.009Z","dismissed":[]},{"gate":"anchor-compare","verdict":{"passed":true,"failures":[],"skipped":"Family E rubric.md missing at /Users/mattfrischer/Taste/site/design-system/golden-set/E/rubric.md — anchor-compare skipped."},"ran_at":"2026-07-04T08:43:13.010Z","dismissed":[]}],"overall":"PASS","ran_at":"2026-07-04T08:42:34.312Z"}
@@ -0,0 +1,16 @@
1
+ // Generated from theme.yml. Merge into your tailwind.config.ts under theme.extend.
2
+ // slug: vault-reel
3
+ export const vaultReelTailwindExtend = {
4
+ colors: {
5
+ bg: "#0a0a0a",
6
+ surface: "#141414",
7
+ ink: "#d4ceb8",
8
+ accent: "#8a1106",
9
+ secondary: "#b01608",
10
+ },
11
+ fontFamily: {
12
+ display: ["BNDimeDisplay (reference proprietary face — tight geometric bold uppercase sans with a slightly-condensed proportion). Free fallback stack — Space Grotesk 700, Barlow Condensed 700, system-ui, sans-serif. Weight 400-700, ALWAYS UPPERCASE, letter-spacing -0.68px (tight negative tracking — this is the register's typographic fingerprint). Scale — 34px is the measured top-of-scale in the reference, deliberately restrained rather than monumental. This is a small-display theme, not a monumental-display theme — the drama lives in the composition and the black abyss, not in headline size."],
13
+ body: ["Times (system serif — deliberately anti-modern, cinematic old-media). Fallback — \"Times New Roman\", Georgia, serif. Weight 400, mixed case, 14-16px body copy, line-height 1.5. Times is the anti-tech signal — every SaaS site uses Inter; this uses Times, which reads as film-industry / cinema-archive rather than tech-product."],
14
+ mono: ["none. Vault Reel is a consumer director-portfolio surface. Mono has no role here (the timestamp clock uses the display face, not a mono)."],
15
+ },
16
+ };
@@ -0,0 +1,167 @@
1
+ # Vault Reel — Family E, Luxury & Brand-Tier.
2
+ #
3
+ # Cinema-archive director-portfolio register. Extreme dark canvas
4
+ # (#0a0a0a) with a single widescreen reel dominating the hero, warm
5
+ # cream ink, and a burning-red accent used ONLY for interactive
6
+ # emphasis. Sharp edges everywhere — 0px border radius across every
7
+ # card, control, tile, input, wordmark, and nav link. Body copy in
8
+ # Times, display in a tight geometric bold sans (BNDimeDisplay
9
+ # reference; Space Grotesk 700 + Barlow Condensed as free fallbacks).
10
+ #
11
+ # Authored from Matt's provided design brief (2026-07-04,
12
+ # drewkirsch.com reference — a working commercial-director portfolio).
13
+ # Placeholder brand: a fictional director's imprint called "THE FRIEND"
14
+ # — original name, original copy, no reproductions of the source
15
+ # director's identity or the source site's copy. The register expresses
16
+ # "auteur portfolio" through the extreme black canvas + video-reel
17
+ # hero + timestamp clock + diegetic UI widgets (CART, SORT BY,
18
+ # THE VAULT) that read as broadcast-console chrome rather than
19
+ # marketing chrome.
20
+ #
21
+ # Twelfth theme via the v2 harness. First Family E cinema/director
22
+ # base. Seventh NEW BASE.
23
+ #
24
+ # Alternative slugs considered — cinema-reel (too generic), directors-cut
25
+ # (cliché + attribution-adjacent), midnight-reel (evocative but drops
26
+ # the archive metaphor), auteur-black (attribution-adjacent, banned),
27
+ # reel-house (imprecise), strip-cut (film-strip too literal). Vault Reel
28
+ # picked because "vault" captures the archive-of-past-work register
29
+ # that anchors the composition, and "reel" carries the video-hero
30
+ # signature. Both words are common-noun and aesthetic — no
31
+ # right-of-publicity or trademark exposure.
32
+
33
+ name: Vault Reel
34
+ concept: Cinema-archive director-portfolio register — extreme dark canvas at #0a0a0a with a single widescreen reel dominating the hero and burning-red accent used sparingly for interactive emphasis. Sharp edges everywhere (0px radius). Diegetic broadcast-console widgets — CART, SORT BY, real-time timestamp — that read as production chrome instead of marketing chrome. Body copy in Times, display in a tight geometric bold uppercase sans with letter-spacing -0.68px.
35
+ influence: |
36
+ Commercial-director and cinematographer portfolios (the register held by working directors between production seasons — extreme minimalism, one confident video reel front-and-center, everything else stripped to a broadcast console). Also archival cinema microsites (Criterion Channel at its darkest, Metrograph program guides), and the diegetic-UI language of film-industry tools (Frame.io comment bars, Avid timeline scrubbers). Distinct from other Family E bases through the extreme-dark canvas + broadcast-console chrome + the deliberate empty-scroll abyss that separates the hero from the vault teaser.
37
+
38
+ family: E
39
+ base_number: 44
40
+ base_note: |
41
+ New-base candidate in Family E, Luxury & Brand-Tier, cinema/portfolio subregion. Distinct from other Family E bases through the DIEGETIC BROADCAST-CONSOLE chrome — utility widgets that read as production tools rather than marketing components — and the deliberate long-scroll dark abyss between the hero reel and the vault teaser. Existing Family E bases lean editorial-luxury (Atelier Radiance) or monumental-broadside (Overland Broadside). Vault Reel occupies the CINEMA-ARCHIVE slot the family has been missing.
42
+
43
+ render_url: http://localhost:5173/themes/vault-reel
44
+
45
+ surface: web
46
+
47
+ typography:
48
+ display: BNDimeDisplay (reference proprietary face — tight geometric bold uppercase sans with a slightly-condensed proportion). Free fallback stack — Space Grotesk 700, Barlow Condensed 700, system-ui, sans-serif. Weight 400-700, ALWAYS UPPERCASE, letter-spacing -0.68px (tight negative tracking — this is the register's typographic fingerprint). Scale — 34px is the measured top-of-scale in the reference, deliberately restrained rather than monumental. This is a small-display theme, not a monumental-display theme — the drama lives in the composition and the black abyss, not in headline size.
49
+ body: Times (system serif — deliberately anti-modern, cinematic old-media). Fallback — "Times New Roman", Georgia, serif. Weight 400, mixed case, 14-16px body copy, line-height 1.5. Times is the anti-tech signal — every SaaS site uses Inter; this uses Times, which reads as film-industry / cinema-archive rather than tech-product.
50
+ mono: none. Vault Reel is a consumer director-portfolio surface. Mono has no role here (the timestamp clock uses the display face, not a mono).
51
+ scale: 1.25 (perfect fourth — deliberately compressed scale so the composition reads as dense broadcast-console rather than marketing-hero)
52
+ eyebrow_exception: |
53
+ The universal slop-blocklist bans mono-caps eyebrows as a general defensive rule. Vault Reel LEGITIMATELY uses small uppercase 0.18em-tracked 11px labels as diegetic UI widget labels (CART, SORT BY, THE VAULT, INSTAGRAM, IMDB) because the reference site uses them EXACTLY in this register — they read as broadcast-console labels, not marketing eyebrows. This is a THEME-SPECIFIC EXCEPTION that must be manually preserved during harness grading.
54
+
55
+ palette:
56
+ bg: "#0a0a0a" # canvas — deep near-black, the measured base
57
+ surface: "#141414" # slightly-lifted panel for video reel background
58
+ ink: "#d4ceb8" # warm cream — primary text on the dark canvas
59
+ accent: "#8a1106" # deep-red — burning-red accent for hover/active nav word
60
+ secondary: "#b01608" # brighter-red — hover-brighten state
61
+ cream: "#d4ceb8" # alias for the ink cream — kept for downstream tokens
62
+ darkInk: "#0a0a0a" # near-black — ink for text on cream inverted bands
63
+ mute: "#6b6864" # dimmed cream — secondary text, timestamp seconds
64
+
65
+ density: dense
66
+
67
+ motion: |
68
+ Ships live in the section renderer (no external dependencies):
69
+ 1. Video-reel scrubber timeline pulses — the red progress mark on the reel scrubber breathes 0.85 → 1 opacity on a 2s ease-in-out loop, signaling active-playback status without actually playing video.
70
+ 2. Timestamp clock — the diegetic HH:MM:SS clock at the bottom of the composition updates every second in real time (setInterval 1000). Reads as broadcast-console UI. Not a marketing motion — a state readout.
71
+ 3. Nav active-word — the currently-selected top nav word (HOME / REEL / ABOUT / CONTACT) is red; hovering another word transitions its color to red over 200ms.
72
+ 4. Scroll-triggered reel reveal — the vault-teaser text at the bottom of the scroll gap fades in from opacity 0 to 1 over 600ms when the IntersectionObserver fires at 40% visibility. No slide-up, no scale — pure opacity.
73
+ 5. Vault thumbnail hover — each vault-grid thumbnail dims its non-hovered siblings to opacity 0.4 over 240ms while the hovered thumbnail stays full opacity + shows a red micro-underline beneath the title.
74
+ 6. Static-noise band — the mid-page divider band shows a 3-frame CSS animation that steps through three subtle grain-noise SVG patterns at 250ms per frame (grain-1 / grain-2 / grain-3 / grain-1 loop), reading as film-grain flicker.
75
+ 7. prefers-reduced-motion: reduce — timestamp still ticks (this is a state readout, not decoration); scrubber breathe paused; static-noise band frozen on a single frame; vault-thumbnail dim disabled. State changes still fire.
76
+
77
+ Customer installs these as dependencies for the deeper motion tier:
78
+ - Lenis — smooth inertial scroll (the extreme 8000px+ page benefits from inertial cadence).
79
+ - Custom scroll-triggered chapter markers as the user scrolls past each vault section.
80
+ - A real HLS.js video player wired into the featured reel tile (currently an FPO SVG that mimics the video-player chrome).
81
+
82
+ Motion character: broadcast-console, diegetic, functional. Custom cubic-bezier(0.19,1,0.22,1) for opacity reveals. The register lives in production-tool authenticity — motion should feel like a Frame.io comment cue, not a marketing headline animation.
83
+
84
+ signature: |
85
+ Extreme dark canvas at #0a0a0a — the register's non-negotiable base.
86
+ Every card, button, control, video tile, input, and nav link ships at
87
+ 0px border radius — sharp edges are the second non-negotiable move.
88
+ A single widescreen VIDEO REEL tile dominates the hero at ~1200x675px
89
+ (16:9), positioned dead-center of a 3-column composition. Left column
90
+ holds two diegetic broadcast widgets (CART / SORT BY labels stacked
91
+ in a tight utility grid). Right column holds the reel index — a small
92
+ "REEL 2026" title in the display face, a two-line description in
93
+ Times italic, and a numeric pagination readout (01 / 15) in the
94
+ display face. The reel tile itself renders a matte-black video
95
+ surface with two small red heart-shape SVG markers as annotation
96
+ cues in the top corners, a "SUBSCRIBE NOW" pill button (the ONE
97
+ pill in the theme, deliberately misfit as a broadcast affordance)
98
+ at bottom-left, and a scrubber timeline strip at the bottom with a
99
+ red pulse marker at ~63% position. Below the reel: a static-noise
100
+ divider band (subtle SVG grain pattern) separates hero from vault
101
+ teaser. The VAULT TEASER is a small centered "THE VAULT →" label
102
+ after a deliberate extreme scroll gap (5-6x viewport of black
103
+ abyss). The VAULT INDEX itself is a 4-column grid of matte-black
104
+ film-strip thumbnails, each showing a project title in the display
105
+ face + a two-line credit line in Times italic + the film-strip
106
+ sprocket-hole SVG decoration on the left and right edges. A
107
+ FILMOGRAPHY MARQUEE scrolls horizontally across the bottom third —
108
+ the projects loop across the viewport in the display face at 20s
109
+ per loop. A DIEGETIC TIMESTAMP CLOCK renders at the very bottom of
110
+ the page in the display face — HH:MM:SS updating in real time,
111
+ positioned centered, reading as broadcast-console UI. Footer
112
+ strip shows a © THE FRIEND wordmark on the left, INSTAGRAM / IMDB
113
+ utility labels centered, and the THE FRIEND display wordmark
114
+ right-aligned. Small mono-caps 11px 0.18em-tracked eyebrow labels
115
+ are LEGITIMATELY USED throughout as diegetic widget labels
116
+ (this theme's rare exception to the universal slop-blocklist —
117
+ see eyebrow_exception in typography). Brand character sits in the
118
+ extreme black canvas, the tight geometric display, the burning-red
119
+ accent, and the broadcast-console chrome — not in decoration,
120
+ not in warmth, not in polish.
121
+
122
+ imagery: |
123
+ Photographic + video-still imagery of directorial subjects — the
124
+ reference uses stills from actual commercial + music-video reels
125
+ shot under directional light. FPO imagery here should read as
126
+ matte cinematic still-frames — colored surface panels with subtle
127
+ gradient masks that suggest a video-player rendering, not literal
128
+ photography. Every video/reel tile masks to a SHARP-CORNERED
129
+ rectangle at exactly 16:9. NO gradient blobs, NO glassmorphism,
130
+ NO stock cinema-cliche photography (the "clapperboard + film reel
131
+ spinning" tell). NO warm-glow FPO fills (the warm-radial gradient
132
+ tell). Film-strip sprocket-hole SVG ornaments on vault-index tile
133
+ edges are permitted per the CHROME INVENTORY.
134
+
135
+ best_for:
136
+ - Commercial-director and music-video-director portfolios
137
+ - Cinematographer + director-of-photography sites
138
+ - Production-house imprints and small studio landing pages
139
+ - Editorial reels for creative agencies with a cinema-adjacent register
140
+ - Film-festival and program-guide microsites (Metrograph-style)
141
+ - Photographer portfolios with a cinematic register (not editorial-magazine)
142
+
143
+ avoid:
144
+ - "Non-0px border radius — sharp edges are the register's second non-negotiable move. Rounded corners on cards, video tiles, buttons, or inputs immediately break the register."
145
+ - "Light canvas (white / cream / gray) as the primary background — canvas IS extreme black. Swapping to a light canvas collapses this into generic-photographer-portfolio slop."
146
+ - "Multiple accent colors flooding the composition — RED is the only accent, used sparingly for interactive emphasis. Introducing amber / cream / any additional color as an accent collapses the register."
147
+ - "Monumental display type at 200px+ — this theme's display scale is deliberately RESTRAINED (top at 34px). The drama lives in the composition and the black abyss, not in headline size."
148
+ - "Rounded pill buttons in the SUBSCRIBE NOW spot — the reference uses a SHARP-CORNERED chip. The one 'pill' is deliberately misfit as a broadcast affordance, but its actual radius is 0px."
149
+ - "Corporate polish — no drop-shadow-md, no soft-glow, no gradient backdrop. Video tiles are FLAT matte-black rectangles with color fills only."
150
+ - "Warm-glow FPO gradients — the register is COLD and matte. Warm radials collapse it into editorial-luxury slop."
151
+ - "Uniform 3- or 4-column feature-card grids in the vault index — the vault tiles alternate size, orientation, and layout. Not a template."
152
+ - "Emoji or decorative unicode marks — bespoke SVG (film-strip sprockets, heart markers, static-noise patterns) carry all the ornamentation."
153
+ - "Marketing headline animations — the reveals here are DIEGETIC (timestamp ticking, scrubber pulsing, static flicker). Slide-up + fade-in stagger animations collapse the register into marketing slop."
154
+
155
+ banned_defaults:
156
+ # Global blocklist from BESPOKE_THEME_SYSTEM.md
157
+ - "claude-cream (#F4F1EA + serif + #D97757)"
158
+ - "void+acid (near-black bg + single bright acid-green or vermilion accent — this theme's accent is deep BURNING RED, not acid)"
159
+ - "broadsheet-on-noneditorial (hairline rules + zero border-radius + newspaper columns — Vault Reel is 0px radius but composition is broadcast-console, not broadsheet)"
160
+ - "tech-bro purple gradient (purple→blue gradient hero + centered headline + double CTA + emoji icons)"
161
+ - "uniform-everything (identical padding + one weight of one sans doing every job + rounded-2xl + shadow-md cards)"
162
+ # Base-specific
163
+ - "rounded-corner-anywhere (this theme's whole point is the sharp-cornered broadcast-console chrome. A rounded card, button, or input anywhere on the page immediately breaks the register.)"
164
+ - "cream-canvas-flood (cream is INK + INVERTED-BAND color, not a canvas primary. Making cream the whole page background collapses the theme into generic-photographer-portfolio.)"
165
+ - "warm-radial-gradient-fpo (the FPO video/reel tiles must be MATTE BLACK with subtle gradient masks that suggest a video-player rendering, not warm-glow decoration.)"
166
+ - "monumental-display-slop (headlines above ~40px collapse this into a monumental-editorial base — the register requires RESTRAINED display scale so the composition and the abyss carry the drama.)"
167
+ - "clapperboard-cinema-cliche (imagery that reads as 'film reel spinning' or 'clapperboard' is stock cinema-cliche. FPO here must read as matte cinematic still-frames from directorial work, not from a stock cinema-decoration library.)"
@@ -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: "vault-reel",
5
+ family: "E",
6
+ base: "44",
7
+ palette: {
8
+ "bg": "#0a0a0a",
9
+ "surface": "#141414",
10
+ "ink": "#d4ceb8",
11
+ "accent": "#8a1106",
12
+ "secondary": "#b01608",
13
+ "cream": "#d4ceb8",
14
+ "darkInk": "#0a0a0a",
15
+ "mute": "#6b6864"
16
+ },
17
+ typography: {
18
+ "display": "BNDimeDisplay (reference proprietary face — tight geometric bold uppercase sans with a slightly-condensed proportion). Free fallback stack — Space Grotesk 700, Barlow Condensed 700, system-ui, sans-serif. Weight 400-700, ALWAYS UPPERCASE, letter-spacing -0.68px (tight negative tracking — this is the register's typographic fingerprint). Scale — 34px is the measured top-of-scale in the reference, deliberately restrained rather than monumental. This is a small-display theme, not a monumental-display theme — the drama lives in the composition and the black abyss, not in headline size.",
19
+ "body": "Times (system serif — deliberately anti-modern, cinematic old-media). Fallback — \"Times New Roman\", Georgia, serif. Weight 400, mixed case, 14-16px body copy, line-height 1.5. Times is the anti-tech signal — every SaaS site uses Inter; this uses Times, which reads as film-industry / cinema-archive rather than tech-product.",
20
+ "mono": "none. Vault Reel is a consumer director-portfolio surface. Mono has no role here (the timestamp clock uses the display face, not a mono).",
21
+ "scale": "1.25 (perfect fourth — deliberately compressed scale so the composition reads as dense broadcast-console rather than marketing-hero)",
22
+ "eyebrow_exception": "The universal slop-blocklist bans mono-caps eyebrows as a general defensive rule. Vault Reel LEGITIMATELY uses small uppercase 0.18em-tracked 11px labels as diegetic UI widget labels (CART, SORT BY, THE VAULT, INSTAGRAM, IMDB) because the reference site uses them EXACTLY in this register — they read as broadcast-console labels, not marketing eyebrows. This is a THEME-SPECIFIC EXCEPTION that must be manually preserved during harness grading.\n"
23
+ },
24
+ surface: "web",
25
+ density: "dense",
26
+ motion: "Ships live in the section renderer (no external dependencies):\n1. Video-reel scrubber timeline pulses — the red progress mark on the reel scrubber breathes 0.85 → 1 opacity on a 2s ease-in-out loop, signaling active-playback status without actually playing video.\n2. Timestamp clock — the diegetic HH:MM:SS clock at the bottom of the composition updates every second in real time (setInterval 1000). Reads as broadcast-console UI. Not a marketing motion — a state readout.\n3. Nav active-word — the currently-selected top nav word (HOME / REEL / ABOUT / CONTACT) is red; hovering another word transitions its color to red over 200ms.\n4. Scroll-triggered reel reveal — the vault-teaser text at the bottom of the scroll gap fades in from opacity 0 to 1 over 600ms when the IntersectionObserver fires at 40% visibility. No slide-up, no scale — pure opacity.\n5. Vault thumbnail hover — each vault-grid thumbnail dims its non-hovered siblings to opacity 0.4 over 240ms while the hovered thumbnail stays full opacity + shows a red micro-underline beneath the title.\n6. Static-noise band — the mid-page divider band shows a 3-frame CSS animation that steps through three subtle grain-noise SVG patterns at 250ms per frame (grain-1 / grain-2 / grain-3 / grain-1 loop), reading as film-grain flicker.\n7. prefers-reduced-motion: reduce — timestamp still ticks (this is a state readout, not decoration); scrubber breathe paused; static-noise band frozen on a single frame; vault-thumbnail dim disabled. State changes still fire.\n\nCustomer installs these as dependencies for the deeper motion tier:\n- Lenis — smooth inertial scroll (the extreme 8000px+ page benefits from inertial cadence).\n- Custom scroll-triggered chapter markers as the user scrolls past each vault section.\n- A real HLS.js video player wired into the featured reel tile (currently an FPO SVG that mimics the video-player chrome).\n\nMotion character: broadcast-console, diegetic, functional. Custom cubic-bezier(0.19,1,0.22,1) for opacity reveals. The register lives in production-tool authenticity — motion should feel like a Frame.io comment cue, not a marketing headline animation.\n",
27
+ signature: "Extreme dark canvas at #0a0a0a — the register's non-negotiable base.\nEvery card, button, control, video tile, input, and nav link ships at\n0px border radius — sharp edges are the second non-negotiable move.\nA single widescreen VIDEO REEL tile dominates the hero at ~1200x675px\n(16:9), positioned dead-center of a 3-column composition. Left column\nholds two diegetic broadcast widgets (CART / SORT BY labels stacked\nin a tight utility grid). Right column holds the reel index — a small\n\"REEL 2026\" title in the display face, a two-line description in\nTimes italic, and a numeric pagination readout (01 / 15) in the\ndisplay face. The reel tile itself renders a matte-black video\nsurface with two small red heart-shape SVG markers as annotation\ncues in the top corners, a \"SUBSCRIBE NOW\" pill button (the ONE\npill in the theme, deliberately misfit as a broadcast affordance)\nat bottom-left, and a scrubber timeline strip at the bottom with a\nred pulse marker at ~63% position. Below the reel: a static-noise\ndivider band (subtle SVG grain pattern) separates hero from vault\nteaser. The VAULT TEASER is a small centered \"THE VAULT →\" label\nafter a deliberate extreme scroll gap (5-6x viewport of black\nabyss). The VAULT INDEX itself is a 4-column grid of matte-black\nfilm-strip thumbnails, each showing a project title in the display\nface + a two-line credit line in Times italic + the film-strip\nsprocket-hole SVG decoration on the left and right edges. A\nFILMOGRAPHY MARQUEE scrolls horizontally across the bottom third —\nthe projects loop across the viewport in the display face at 20s\nper loop. A DIEGETIC TIMESTAMP CLOCK renders at the very bottom of\nthe page in the display face — HH:MM:SS updating in real time,\npositioned centered, reading as broadcast-console UI. Footer\nstrip shows a © THE FRIEND wordmark on the left, INSTAGRAM / IMDB\nutility labels centered, and the THE FRIEND display wordmark\nright-aligned. Small mono-caps 11px 0.18em-tracked eyebrow labels\nare LEGITIMATELY USED throughout as diegetic widget labels\n(this theme's rare exception to the universal slop-blocklist —\nsee eyebrow_exception in typography). Brand character sits in the\nextreme black canvas, the tight geometric display, the burning-red\naccent, and the broadcast-console chrome — not in decoration,\nnot in warmth, not in polish.\n",
28
+ } as const;
29
+
30
+ export type Tokens = typeof tokens;
@@ -0,0 +1,79 @@
1
+ # Design Direction — Vet-Modern
2
+
3
+ ## Ethos
4
+ Bond Vet sage-and-cream walk-in · Modern Animal hotel-lobby clinical · Small Door Veterinary membership-friendly chrome · Heart + Paw spa-meets-clinic warmth · GoodVets neighborhood-clinic candor
5
+
6
+ ## Feel
7
+ Walk-in-friendly clinical. Cream-tinted surfaces with one principled sage-green accent — never two competing colors. Friendly Inter, dense-but-soft booking chrome, tabular numerics for times and prices. The page is a tool: locations grid resolves to hours, services list resolves to a price range, booking widget resolves to a Tuesday-2:30 slot in two taps. Clinical competence without the EHR coldness.
8
+
9
+ ## Reference brands
10
+ - **Bond Vet** → soft sage on cream + walk-in-friendly booking chrome. The principal reference for surfaces and the single-accent rule.
11
+ - **Modern Animal** → hotel-lobby clinical, generous whitespace, membership-first IA.
12
+ - **Small Door Veterinary** → membership-friendly chrome, app-led scheduling, tabular pricing.
13
+ - **Heart + Paw** → spa-meets-clinic warmth, pet-portrait photography over hospital stock.
14
+ - **GoodVets** → neighborhood-clinic candor, locations-first information architecture.
15
+
16
+ ## Tokens
17
+ Surface stack is **warm cream** (background) → **white** (card) → **deeper cream / sage tint** (secondary / muted / accent). Brand tokens: `--sage`, `--sage-deep`, `--cream`, `--kraft`, `--sun`, `--ink`. Primary is `--sage` — the single brand color (no competing brand-blue, no brand-purple). `--sage-deep` is hover/active. `--sun` is reserved for walk-in-available / clinic-open-now indicators — **chip only**, never a button face.
18
+
19
+ ## Typography
20
+ - **Display:** Inter 500–700. Tool-first competence; no serif theater on a clinical booking site.
21
+ - **Body:** Inter 400–600. Same family. **15px** base (denser than marketing), line-height 1.55.
22
+ - **Mono:** JetBrains Mono. Reserved for appointment times ("2:30 PM"), prices ("$185"), clinic hours ("8a–8p"), MRN/patient IDs. Tabular numerics everywhere — `font-variant-numeric: tabular-nums`.
23
+
24
+ H1 uses `clamp(1.875rem, 4vw, 3rem)` — restrained, never magazine-large. Tracking `-0.015em` on headings, `0` on body.
25
+
26
+ ## Spacing
27
+ - **Container:** `max-w-7xl px-4 lg:px-6` — tool-wide; booking grids run edge-to-edge.
28
+ - **Section padding tiers:**
29
+ - Hero: `pt-16 pb-10 lg:pt-20 lg:pb-14`
30
+ - Default: `py-12 lg:py-18`
31
+ - Tight: `py-8 lg:py-12`
32
+ - **Allowed scale values:** 2 4 6 8 10 12 14 16 20 24 32 40 48 64 80 — dashboard micro-steps included (no editorial restriction).
33
+
34
+ ## Color
35
+ No hex in components — tokens only. Pure white is permitted only for card surfaces. Pure black is forbidden — use `--ink` (deep evergreen). **One accent rule:** sage is the single brand color. No brand-blue, brand-purple, brand-orange. Sun (amber) appears only as a chip background for walk-in-available state — never a button, never a heading color. Alert-red is `--destructive` only (cancel appointment, urgent care).
36
+
37
+ ## Radius
38
+ `--radius: 0.625rem` (10px). Softer than dense-utility, less pillowy than DTC. Pills core for appointment-status, service-type, availability chips. Square corners forbidden on interactive surfaces; allowed on info banners and table containers.
39
+
40
+ ## Shadows
41
+ **Soft.** `.shadow-clinic` for standard cards, `.shadow-clinic-lg` for hover, `.shadow-booking` for the booking widget (the primary tool on the page — deserves emphasis). No glows.
42
+
43
+ ## Motion
44
+ Four keyframes: `fade-rise` (380ms entrance — dashboard-quick), `scale-in` (180ms modal/slot-picker), `soft-pulse` (1800ms loop for open-now indicators), `shimmer` (1400ms loading skeleton). **No ambient motion** — this is a tool, not marketing. `prefers-reduced-motion` honored.
45
+
46
+ Easing `cubic-bezier(0.22, 1, 0.36, 1)`.
47
+
48
+ ## Component patterns
49
+ - **Buttons:** primary = sage solid + white text, rounded-md (10px), shadow-clinic. Secondary = white + warm border + ink text. Tertiary = sage text-link. Destructive = warm-red ghost → upgrades to solid only on confirm step. Hover darkens to sage-deep; **no scale animation** (jumpiness reads error-prone in clinical chrome).
50
+ - **Cards:** rounded-md, white on cream, 1px warm border, shadow-clinic. Internal padding p-5 lg:p-6.
51
+ - **Location-card variant:** 4px **sage** top-border when **open-now**, 4px kraft top-border when **closed-today**. City + neighborhood in display 600, hours in mono tabular, "Book here" in sage text-link.
52
+ - **Service-row variant:** kraft hairline divider between rows, service name in display, price-range in mono right-aligned ("$95–$240"), friendly one-line description below, "Learn more" sage text-link.
53
+ - **Booking-widget:** the largest surface on the page. shadow-booking, pet-picker at top (segmented pill: Dog / Cat / Other), reason-for-visit chips, date strip with mono dates, time-slot grid (available = white + border, selected = sage solid, unavailable = muted-fg strikethrough). Sage "Confirm Tuesday 2:30" CTA spans the bottom.
54
+ - **Inputs:** rounded-md, 1px warm border, white fill, h-9. Pet-name and reason-for-visit may show a small paw glyph in left padding. Focus = 2px sage ring at 40% opacity.
55
+
56
+ ## Recommended rich media
57
+ Photography is the lead medium: real pets in exam rooms (not stock-photo dogs on white seamless), staff portraits in scrubs with natural light, clinic interiors with warm wood + sage-painted walls. Color graded to warm-cream highlight. Aspect ratios 3:2 landscape for environmental shots, 1:1 square for staff portraits, 4:5 portrait for pet-with-vet hero. Never 16:9 cinematic. No hospital-stock "vet examining puppy on metal table".
58
+
59
+ **AI tool recommendations:** Midjourney with *"warm exam room, natural window light, sage green walls, wood floor, golden retriever on padded table, vet in scrubs, Kodak Portra 400, slight grain"*. Avoid bright clinical hospital stock and any "happy vet team in lab coats" shot — that is corporate-hospital territory.
60
+
61
+ **Performance:** hero ≤140 KB AVIF; location photo ≤90 KB; staff portrait ≤60 KB. LCP ≤2s (it's a booking site — must be fast).
62
+
63
+ **Avoid:** scary medical equipment shots, blood/needle imagery, "before & after surgery" photos (move to private/auth surface, never marketing), cartoon paw-print decoration, "vet voted #1" badges (we earn trust through transparent hours/pricing/locations, not laurels), dark-mode toggle (clinical tools stay light), glassmorphic anything, gradient backgrounds.
64
+
65
+ **Accessibility:** alt-text describes the staff and pet, not the clinic. *"Dr. Saito, a veterinarian in dark scrubs, listens to a tabby cat's heart with a stethoscope."* Tap targets ≥44×44 for slot-picker grid. All prices and times must use `font-variant-numeric: tabular-nums` for proper alignment.
66
+
67
+ ## Component families
68
+ None at install time. Location-card, service-row, and booking-widget are the three canonical bespoke families — codified by the Director as they get reused.
69
+
70
+ ## Details
71
+ - **Selection:** `hsl(var(--sage) / 0.22)` background, ink foreground.
72
+ - **Focus ring:** `2px solid hsl(var(--ring) / 0.5)` — visible, restrained.
73
+ - **Scrollbar:** thin.
74
+
75
+ ## Exceptions
76
+ None yet.
77
+
78
+ ## Revisions
79
+ - Initial direction, generated at install time.