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