From 4ebeedfa9909eb90699bbeec9244340a7c0513bd Mon Sep 17 00:00:00 2001 From: Youssef Date: Thu, 7 May 2026 10:42:43 +0100 Subject: [PATCH] =?UTF-8?q?Phase=20D=20=E2=80=94=20Hero=20rework=20=C2=B7?= =?UTF-8?q?=2012=20per-theme=20right-side=20moments=20=C2=B7=20archetype?= =?UTF-8?q?=20swaps=20=C2=B7=2011=20per-theme=20polishes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit D1 — hero__moment slot for marquee/letter/quote/stat archetypes. 12 themes (specimen, terminal, manifesto, aurora, garden, linen, atelier, salon, riso, midnight, almanac, sport) opt in via per-theme rules. Each gets a small typographic or geometric moment in the right column: · specimen — italic ℋ glyph in a hairline-bordered foundry plate · terminal — phosphor "[ █ ]" prompt block · manifesto — "NO\\nSLOP." in red Anton · aurora — soft secondary radial accent · garden — leaf SVG in coral accent · linen — woven-texture 8×8 dot grid in a hairline frame · atelier — italic Roman "I" in a card with "PLATE I" caption · salon — fleuron + hairline + italic "À table" caption · riso — two overlapping cyan/yellow circles, off-register duotone · midnight — concentric rings + glowing centre dot · almanac — date stamp box "MMVI · ed. 02 · no. 23" · sport — three-bar lap chart in accent D2 — Studio swaps photographic → letter (had duplicated Brutal); Pastel swaps clipped → bloom (drops the AI-default dashboard mock). D3 — Per-theme polishes: · Brutal photo grid 6 → 2 imgs · Quiet sign-up form replaced with single italic note + hairline · Bloom paper inverted dark → light cream so warm wash reads bright; ink/rule/accent re-balanced for the new lightness ladder · Coral solid accent block bottom-left distinguishes from Bloom · Violet alternating sections get faint accent tint · Aurora bloom punctuates each section title (not just hero) · Halo orbit grid 1fr/1fr → 1fr/0.7fr — orbit closer to copy · Plume — feather glyph SVG in bottom-right of bloom hero · Midnight stat "00" → "23, themes, dark-set first" — honest copy · Editorial — giant "XXIII" Roman numeral in right column · Manifesto — 6 oversized declarative phrases ("NO GRADIENTS.", "TYPE FIRST.", etc.) cycled between sections via :nth-of-type Co-Authored-By: Claude Opus 4.7 (1M context) --- site/css/components.css | 372 +++++++++++++++++++++++++++++++++++++++- site/css/sections.css | 22 +++ site/css/tokens.css | 26 +-- site/index.html | 58 ++++--- site/js/main.js | 8 +- 5 files changed, 441 insertions(+), 45 deletions(-) diff --git a/site/css/components.css b/site/css/components.css index 6881b87..560b741 100644 --- a/site/css/components.css +++ b/site/css/components.css @@ -2427,6 +2427,268 @@ body:not(.easter-open) > footer { .hero { display: grid; } +/* — Hero moment slot ————————————————————————————————————————— + Marquee / letter / quote / stat archetypes get an optional right-side + "moment" — a small per-theme typographic or geometric accent that + stops the right column from reading as dead space at desktop. Hidden + by default (most themes don't need it); shown via per-theme opt-in. */ +.hero__main { display: contents; } +.hero__moment { display: none; } + +@media (min-width: 60rem) { + /* Themes that opt in: 2-column grid, moment in column 2. */ + [data-theme="specimen"] .hero--marquee, + [data-theme="terminal"] .hero--marquee, + [data-theme="manifesto"] .hero--marquee, + [data-theme="aurora"] .hero--marquee, + [data-theme="garden"] .hero--letter, + [data-theme="linen"] .hero--letter, + [data-theme="atelier"] .hero--quote, + [data-theme="salon"] .hero--quote, + [data-theme="riso"] .hero--quote, + [data-theme="midnight"] .hero--stat, + [data-theme="almanac"] .hero--stat, + [data-theme="sport"] .hero--stat { + grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr); + column-gap: var(--space-2xl); + align-items: center; + } + [data-theme="specimen"] .hero--marquee .hero__main, + [data-theme="terminal"] .hero--marquee .hero__main, + [data-theme="manifesto"] .hero--marquee .hero__main, + [data-theme="aurora"] .hero--marquee .hero__main, + [data-theme="garden"] .hero--letter .hero__main, + [data-theme="linen"] .hero--letter .hero__main, + [data-theme="atelier"] .hero--quote .hero__main, + [data-theme="salon"] .hero--quote .hero__main, + [data-theme="riso"] .hero--quote .hero__main, + [data-theme="midnight"] .hero--stat .hero__main, + [data-theme="almanac"] .hero--stat .hero__main, + [data-theme="sport"] .hero--stat .hero__main { + display: grid; + gap: var(--space-lg); + grid-column: 1; + } + [data-theme="specimen"] .hero__moment, + [data-theme="terminal"] .hero__moment, + [data-theme="manifesto"] .hero__moment, + [data-theme="aurora"] .hero__moment, + [data-theme="garden"] .hero__moment, + [data-theme="linen"] .hero__moment, + [data-theme="atelier"] .hero__moment, + [data-theme="salon"] .hero__moment, + [data-theme="riso"] .hero__moment, + [data-theme="midnight"] .hero__moment, + [data-theme="almanac"] .hero__moment, + [data-theme="sport"] .hero__moment { + display: grid; + place-items: center; + grid-column: 2; + align-self: center; + justify-self: end; + color: var(--color-ink-2); + } +} + +/* Per-theme moment content — a typographic glyph or simple geometric + accent. CSS-only (no extra HTML), pure ::before content + a few + shapes. Each moment is small + restrained — punctuation, not focus. */ + +/* SPECIMEN — italic ℋ glyph, foundry-plate style with hairline border. */ +[data-theme="specimen"] .hero__moment::before { + content: "ℋ"; + font-family: var(--font-serif); + font-style: italic; + font-weight: 400; + font-size: clamp(8rem, 14vw, 14rem); + line-height: 0.85; + color: var(--color-ink); + padding: var(--space-2xl) var(--space-xl); + border: 1px solid var(--color-rule); + background: var(--color-paper-2); + display: block; +} + +/* TERMINAL — ASCII prompt block in phosphor green. */ +[data-theme="terminal"] .hero__moment::before { + content: "[\A █ \A]"; + white-space: pre; + font-family: var(--font-mono); + font-size: clamp(2rem, 3vw, 3rem); + line-height: 1.2; + color: var(--color-accent); + letter-spacing: 0.05em; +} + +/* MANIFESTO — single uppercase declarative phrase. */ +[data-theme="manifesto"] .hero__moment::before { + content: "NO\ASLOP."; + white-space: pre; + font-family: var(--font-display); + font-weight: 400; + font-size: clamp(3rem, 6vw, 5rem); + line-height: 0.92; + letter-spacing: -0.02em; + color: var(--color-accent); +} + +/* AURORA — soft secondary radial accent. */ +[data-theme="aurora"] .hero__moment { + width: clamp(14rem, 24vw, 22rem); + aspect-ratio: 1 / 1; + background: + radial-gradient(circle at 50% 50%, + color-mix(in oklch, var(--color-accent) 28%, transparent) 0%, + transparent 65%); + filter: blur(4px); + opacity: 0.85; +} + +/* GARDEN — small leaf SVG accent. */ +[data-theme="garden"] .hero__moment::before { + content: ""; + width: clamp(4rem, 6vw, 6rem); + aspect-ratio: 1 / 1; + background-color: var(--color-accent); + -webkit-mask: url('data:image/svg+xml;utf8,') center/contain no-repeat; + mask: url('data:image/svg+xml;utf8,') center/contain no-repeat; + display: block; +} + +/* LINEN — small woven-texture rectangle (4×4 muted dots). */ +[data-theme="linen"] .hero__moment::before { + content: ""; + width: clamp(8rem, 12vw, 12rem); + aspect-ratio: 1 / 1; + background-image: + radial-gradient(circle at center, var(--color-rule-2) 1px, transparent 1.5px); + background-size: 18px 18px; + border: 1px solid var(--color-rule); + display: block; +} + +/* ATELIER — italic Roman numeral plate. */ +[data-theme="atelier"] .hero__moment::before { + content: "I"; + font-family: var(--font-serif); + font-style: italic; + font-size: clamp(6rem, 10vw, 10rem); + line-height: 1; + color: var(--color-ink); + padding: var(--space-2xl) var(--space-3xl); + border: 1px solid var(--color-rule); + display: block; +} +[data-theme="atelier"] .hero__moment::after { + content: "Plate I"; + font-family: var(--font-label); + font-size: var(--text-xs); + letter-spacing: var(--tracking-label); + text-transform: uppercase; + color: var(--color-muted); + margin-block-start: var(--space-xs); +} + +/* SALON — fleuron + rule + label. */ +[data-theme="salon"] .hero__moment::before { + content: "❦"; + font-family: var(--font-serif); + font-size: clamp(4rem, 8vw, 7rem); + line-height: 1; + color: var(--color-accent); + display: block; +} +[data-theme="salon"] .hero__moment::after { + content: "À table"; + font-family: var(--font-serif); + font-style: italic; + font-size: var(--text-md); + color: var(--color-muted); + margin-block-start: var(--space-md); + padding-block-start: var(--space-md); + border-block-start: var(--rule-hair) solid var(--color-rule); + width: 8rem; + text-align: center; +} + +/* RISO — two overlapping circles in duotone (off-register). */ +[data-theme="riso"] .hero__moment { + position: relative; + width: clamp(10rem, 16vw, 16rem); + aspect-ratio: 1 / 1; +} +[data-theme="riso"] .hero__moment::before, +[data-theme="riso"] .hero__moment::after { + content: ""; + position: absolute; + inset: 0; + border-radius: 50%; + mix-blend-mode: multiply; +} +[data-theme="riso"] .hero__moment::before { + background: var(--color-accent); + transform: translate(-8%, -6%); +} +[data-theme="riso"] .hero__moment::after { + background: var(--color-accent-2, oklch(78% 0.18 95)); + transform: translate(8%, 6%); +} + +/* MIDNIGHT — three concentric rings + centre dot. */ +[data-theme="midnight"] .hero__moment { + position: relative; + width: clamp(10rem, 14vw, 14rem); + aspect-ratio: 1 / 1; + border-radius: 50%; + border: 1px solid color-mix(in oklch, var(--color-accent) 35%, transparent); + box-shadow: + inset 0 0 0 1px transparent, + 0 0 0 12px transparent, + 0 0 0 13px color-mix(in oklch, var(--color-accent) 22%, transparent), + 0 0 0 28px transparent, + 0 0 0 29px color-mix(in oklch, var(--color-accent) 12%, transparent); +} +[data-theme="midnight"] .hero__moment::before { + content: ""; + position: absolute; + inset: 50%; + width: 6px; + height: 6px; + margin: -3px 0 0 -3px; + border-radius: 50%; + background: var(--color-accent); + box-shadow: 0 0 12px 3px color-mix(in oklch, var(--color-accent) 50%, transparent); +} + +/* ALMANAC — date stamp box. */ +[data-theme="almanac"] .hero__moment::before { + content: "MMVI \A ed. 02 \A no. 23"; + white-space: pre-line; + font-family: var(--font-mono); + font-size: var(--text-md); + line-height: 1.5; + color: var(--color-ink-2); + padding: var(--space-md) var(--space-lg); + border: 1px solid var(--color-rule); + display: block; + text-align: center; +} + +/* SPORT — three-bar lap chart (horizontal bars in accent). */ +[data-theme="sport"] .hero__moment { + width: clamp(8rem, 12vw, 12rem); + display: grid; + gap: var(--space-xs); +} +[data-theme="sport"] .hero__moment::before, +[data-theme="sport"] .hero__moment::after { + content: ""; + height: 0.55rem; + background: var(--color-accent); +} +[data-theme="sport"] .hero__moment::before { width: 90%; } +[data-theme="sport"] .hero__moment::after { width: 55%; } + .hero__eyebrow { display: inline-flex; align-items: center; @@ -2566,12 +2828,50 @@ body:not(.easter-open) > footer { .hero--split .hero__proof a { margin-top: var(--space-sm); } -/* Editorial: the proof block reads cleaner with just the CTA. */ +/* Editorial: the proof block reads cleaner with just the CTA + a giant + Roman numeral set above it as the visual anchor for the right column. */ [data-theme="editorial"] .hero--split .hero__proof .label, [data-theme="editorial"] .hero--split .hero__proof .hero__proof-line { display: none; } [data-theme="editorial"] .hero--split .hero__proof { padding-block-start: 0; border-block-start: 0; + display: grid; + gap: var(--space-md); + align-content: end; +} +[data-theme="editorial"] .hero--split .hero__proof::before { + content: "XXIII"; + font-family: var(--font-serif); + font-style: italic; + font-weight: 400; + font-size: clamp(5rem, 9vw, 8rem); + line-height: 0.85; + letter-spacing: -0.02em; + color: var(--color-ink); +} + +/* Quiet: collapse the proof-block down to one italic note + the CTA, so + the right column reads as a quiet annotation instead of a sign-up form. */ +[data-theme="quiet"] .hero--split .hero__proof .label, +[data-theme="quiet"] .hero--split .hero__proof .hero__proof-line:nth-child(3), +[data-theme="quiet"] .hero--split .hero__proof .hero__proof-line:nth-child(4) { display: none; } +[data-theme="quiet"] .hero--split .hero__proof { + padding-block-start: var(--space-md); + border-block-start: var(--rule-hair) solid var(--color-rule); +} +[data-theme="quiet"] .hero--split .hero__proof .hero__proof-line { + font-family: var(--font-serif); + font-style: italic; + color: var(--color-muted); + max-width: 24ch; +} + +/* Brutal: trim the photographic gallery from 6 images to 2 — the original + six-up grid was busier than the hero's job needs. */ +[data-theme="brutal"] .hero__photo-grid > span:nth-child(n+3) { display: none; } +[data-theme="brutal"] .hero__photo-grid { + grid-template-columns: minmax(0, 1.4fr) minmax(0, 0.6fr); + grid-template-rows: 1fr; } /* H3 — Stat-Led. Giant number + qualifier. */ @@ -3068,6 +3368,23 @@ body:not(.easter-open) > footer { overflow: visible; } +/* Plume — feather glyph bottom-right of the bloom hero. Reinforces the + "plume" name without being twee. SVG via mask, low opacity. */ +[data-theme="plume"] .hero__bloom-stage::after { + content: ""; + position: absolute; + right: 4%; + bottom: 8%; + width: clamp(3rem, 5vw, 5rem); + aspect-ratio: 1 / 3; + background-color: var(--color-accent); + -webkit-mask: url('data:image/svg+xml;utf8,') center/contain no-repeat; + mask: url('data:image/svg+xml;utf8,') center/contain no-repeat; + opacity: 0.55; + transform: rotate(8deg); + pointer-events: none; +} + .hero__bloom-wash { position: absolute; inset: -8% -12% -8% -8%; @@ -3141,8 +3458,8 @@ body:not(.easter-open) > footer { slow-rotate via @keyframes; reduced-motion stops them. */ .hero--orbit { display: grid; - grid-template-columns: minmax(20rem, 1fr) minmax(0, 1fr); - gap: var(--space-2xl); + grid-template-columns: minmax(20rem, 1fr) minmax(0, 0.7fr); + gap: var(--space-xl); padding-block: var(--space-2xl) var(--space-xl); align-items: center; } @@ -3695,10 +4012,10 @@ html[data-theme="bloom"] { html[data-theme="bloom"] body { background: radial-gradient(ellipse 80% 60% at 90% 0%, - color-mix(in oklch, var(--color-accent) 28%, transparent) 0%, + color-mix(in oklch, var(--color-accent) 18%, transparent) 0%, transparent 55%), radial-gradient(ellipse 70% 55% at 5% 95%, - color-mix(in oklch, var(--color-accent-2) 26%, transparent) 0%, + color-mix(in oklch, var(--color-accent-2) 16%, transparent) 0%, transparent 55%), var(--color-paper); background-attachment: fixed; @@ -3875,6 +4192,24 @@ html[data-theme="bloom"] body { letter-spacing: -0.025em; } +/* Coral — solid accent block bottom-left of the hero, behind copy. + Distinguishes Coral from Bloom (which uses radial washes only). */ +[data-theme="coral"] .hero { + position: relative; +} +[data-theme="coral"] .hero::before { + content: ""; + position: absolute; + left: -2vw; + bottom: -1rem; + width: clamp(8rem, 14vw, 14rem); + aspect-ratio: 1 / 1; + background: var(--color-accent); + border-radius: 0; + z-index: -1; + opacity: 0.85; +} + [data-theme="coral"] .install-pane__copy { background: var(--color-ink); color: var(--color-paper); @@ -3894,6 +4229,12 @@ html[data-theme="bloom"] body { animation: none; } +/* Violet — alternate sections get a faint violet tint background so the + accent shows up across the whole page, not just in 1–2 spots. */ +[data-theme="violet"] .page > .section:nth-of-type(2n) { + background: color-mix(in oklch, var(--color-accent) 4%, var(--color-paper)); +} + [data-theme="violet"] .hero__display, [data-theme="violet"] .hero__quote p, [data-theme="violet"] .hero__stat, @@ -3936,6 +4277,27 @@ html[data-theme="aurora"] body { min-height: 100dvh; } +/* Aurora — soft accent bloom punctuates each section title (not just the + hero). Adds rhythm without competing with the hero's bigger glow. */ +[data-theme="aurora"] .section { + position: relative; +} +[data-theme="aurora"] .section > .section__head::after { + content: ""; + position: absolute; + inset-inline-start: -8%; + inset-block-start: -2rem; + width: 22rem; + height: 22rem; + background: + radial-gradient(circle at 50% 50%, + color-mix(in oklch, var(--color-accent) 14%, transparent) 0%, + transparent 65%); + pointer-events: none; + z-index: -1; + filter: blur(6px); +} + [data-theme="aurora"] .hero__display, [data-theme="aurora"] .hero__quote p, [data-theme="aurora"] .hero__stat, diff --git a/site/css/sections.css b/site/css/sections.css index 20d0184..fcdac7d 100644 --- a/site/css/sections.css +++ b/site/css/sections.css @@ -1488,6 +1488,28 @@ } [data-theme="manifesto"] .step { border-top: 3px solid var(--color-ink); } +/* Manifesto — oversized declarative phrases punctuate the rhythm + between sections. Cycles through 3 statements via :nth-of-type. */ +[data-theme="manifesto"] .section + .section::before { + display: block; + margin: var(--space-3xl) 0 var(--space-2xl); + padding-block: var(--space-md); + border-block: 4px solid var(--color-ink); + font-family: var(--font-display); + font-size: clamp(2rem, 5vw, 4rem); + line-height: 0.95; + letter-spacing: -0.02em; + text-transform: uppercase; + color: var(--color-ink); + text-align: center; +} +[data-theme="manifesto"] .section:nth-of-type(3)::before { content: "WE DO NOT REPEAT."; } +[data-theme="manifesto"] .section:nth-of-type(4)::before { content: "TYPE FIRST."; } +[data-theme="manifesto"] .section:nth-of-type(5)::before { content: "NO GRADIENTS."; } +[data-theme="manifesto"] .section:nth-of-type(6)::before { content: "DEFAULT IS THE ENEMY."; } +[data-theme="manifesto"] .section:nth-of-type(7)::before { content: "EVERY DECISION VISIBLE."; } +[data-theme="manifesto"] .section:nth-of-type(8)::before { content: "THE PAGE IS A POSITION."; } + /* ── SALON — italic display, fleuron divider, left-aligned ───── */ [data-theme="salon"] .opening { grid-template-columns: 1fr; diff --git a/site/css/tokens.css b/site/css/tokens.css index 24fd21f..222cd04 100644 --- a/site/css/tokens.css +++ b/site/css/tokens.css @@ -840,19 +840,19 @@ ────────────────────────────────────────────────────────────── */ [data-theme="bloom"] { - --color-paper: oklch(8% 0.012 35); /* near-black, hint warm */ - --color-paper-2: oklch(11% 0.014 35); /* elevated surface */ - --color-paper-3: oklch(14% 0.018 38); /* hover / inset */ - --color-rule: oklch(22% 0.018 38); - --color-rule-2: oklch(34% 0.022 40); - --color-muted: oklch(58% 0.018 40); - --color-neutral: oklch(74% 0.012 40); - --color-ink-2: oklch(86% 0.008 40); - --color-ink: oklch(98% 0.005 40); - --color-accent: oklch(72% 0.190 45); /* warm orange/amber */ - --color-accent-ink: oklch(72% 0.190 45); - --color-accent-2: oklch(64% 0.220 18); /* secondary pink/red bloom */ - --color-focus: oklch(72% 0.190 45); + --color-paper: oklch(96% 0.018 35); /* warm cream — wash reads bright */ + --color-paper-2: oklch(93% 0.022 35); + --color-paper-3: oklch(89% 0.026 38); + --color-rule: oklch(80% 0.020 40); + --color-rule-2: oklch(64% 0.020 40); + --color-muted: oklch(48% 0.020 40); + --color-neutral: oklch(34% 0.018 40); + --color-ink-2: oklch(22% 0.014 38); + --color-ink: oklch(14% 0.012 35); + --color-accent: oklch(64% 0.180 18); /* warm pink/coral wash */ + --color-accent-ink: oklch(54% 0.190 18); + --color-accent-2: oklch(72% 0.190 45); /* secondary warm orange */ + --color-focus: oklch(64% 0.180 18); --font-display: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif; --font-body: "Geist", "Inter", ui-sans-serif, system-ui, sans-serif; diff --git a/site/index.html b/site/index.html index 6bd6bbf..b96fda1 100644 --- a/site/index.html +++ b/site/index.html @@ -1105,14 +1105,17 @@ @@ -1135,32 +1138,41 @@ diff --git a/site/js/main.js b/site/js/main.js index 1a7e10b..086c821 100644 --- a/site/js/main.js +++ b/site/js/main.js @@ -53,8 +53,8 @@ const ARCHETYPES = { brutal: { hero: "photographic", footer: "colophon" }, manifesto: { hero: "marquee", footer: "colophon" }, sport: { hero: "stat-led", footer: "colophon" }, - studio: { hero: "photographic", footer: "colophon" }, - pastel: { hero: "clipped", footer: "colophon" }, + studio: { hero: "letter", footer: "colophon" }, + pastel: { hero: "bloom", footer: "colophon" }, riso: { hero: "quote-led", footer: "colophon" }, quiet: { hero: "split", footer: "colophon" }, bloom: { hero: "marquee", footer: "colophon" }, @@ -262,8 +262,8 @@ const COPY = { proofB: "Lightness elevation, no shadow", proofC: "Numbered display headers", cta: "$ open", - stat: "00", - qualifier: "shadow halos", + stat: "23", + qualifier: "themes, dark-set first", quote: "On dark surfaces, elevation is lightness — never glow.", attrib: "Midnight rule", salutation: "01 — HELLO.",