Files
hallmark/site/css/components.css
T
YoussefandClaude Opus 4.7 e63e28b782 Add 5 themes (Coral · Violet · Aurora · Halo · Plume) → 22 themes total · study tiles use <img>
Themes:
- Coral (modern-minimal) — warm-grey paper, single coral accent, Geist + General Sans pair, pill CTAs. The "Stripe-not-Linear" register.
- Violet (modern-minimal) — near-white + near-black, single quiet violet accent, tight Geist. The Linear voice without copying it.
- Aurora (atmospheric) — dark cool canvas with two cool blooms (cyan top-right, teal-green bottom-left), Sentient body, single cyan accent. The dev-tool-after-dark register.
- Halo (atmospheric) — neutral charcoal canvas with a single warm-amber bloom positioned ONLY around the hero (fixed-attached pseudo-element clipped to top 80vh). Below the hero the page is content-led — less Suno, more "tool you actually work in."
- Plume (playful) — warm cream paper with alternating tinted bands on sections, soft rose accent, hover-lift on cards, friendly motion. Closer to actual playful than Pastel's post-Linear-soft.

Catalog totals: editorial 12 · modern-minimal 3 · atmospheric 5 · playful 2 = 22 themes. Banner picker, THEMES, ARCHETYPES, COPY, and THEME_GENRES maps all updated. README cluster list reorganised by genre.

Study gallery:
- Replaced <video> with <img> in all 4 cards (videos deferred until production-ready). Existing test-page thumbnails serve as the visual; tiles 03 and 04 keep the data-user-content placeholder + DNA scaffold for the user to fill later.
- CSS .study-card__video class kept alongside new .study-card__img selector so the future video swap is one-line.

Theme-count refs (17 → 22) updated across SKILL.md, README, index.html, main.js, T-tooltip, easter-egg punchlines.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 23:01:00 +01:00

4062 lines
106 KiB
CSS

/* Hallmark — components */
/* — Wordmark ——————————————————————————————————————— */
.wordmark {
font-family: var(--font-label);
font-weight: 500;
font-size: var(--text-sm);
letter-spacing: 0.22em;
text-transform: uppercase;
color: var(--color-ink);
}
[data-theme="manifesto"] .wordmark {
font-family: var(--font-display);
font-weight: 800;
letter-spacing: -0.02em;
text-transform: uppercase;
font-size: var(--text-md);
}
[data-theme="terminal"] .wordmark::before {
content: "$ ";
color: var(--color-accent);
}
/* — Banner (sticky top, thin, theme picker inline) ————————— */
.banner {
position: sticky;
top: 0;
z-index: var(--z-sticky);
display: flex;
align-items: center;
gap: var(--space-lg);
padding: 0 var(--page-gutter);
height: 44px;
background: color-mix(in oklch, var(--color-paper) 88%, transparent);
backdrop-filter: blur(14px) saturate(1.2);
-webkit-backdrop-filter: blur(14px) saturate(1.2);
border-block-end: var(--rule-hair) solid var(--color-rule);
font-family: var(--font-label);
font-size: 0.6875rem;
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-ink);
}
/* Spacer pushes the picker + theme-name to the right */
.banner__spacer {
flex: 1 1 auto;
min-width: 0;
}
.banner__mark {
display: inline-flex;
align-items: baseline;
gap: 0.55rem;
text-decoration: none;
color: var(--color-ink);
}
.banner__name {
font-weight: 500;
letter-spacing: 0.22em;
}
.banner__ver {
font-size: 0.625rem;
color: var(--color-muted);
letter-spacing: 0.14em;
}
/* Sticky Install link — sits between the wordmark and the spacer.
Becomes the most prominent thing on the banner once the user
scrolls past the hero. */
.banner__install {
margin-inline-start: var(--space-md);
padding: 0.18rem 0.65rem;
font-family: var(--font-label);
font-weight: 500;
font-size: 0.6875rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-ink);
text-decoration: none;
border: 1px solid var(--color-rule-2);
border-radius: var(--radius-pill, 999px);
transition: background-color var(--dur-micro) var(--ease-out),
color var(--dur-micro) var(--ease-out),
border-color var(--dur-micro) var(--ease-out);
}
.banner__install:hover {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
}
.banner__install:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
@media (max-width: 50rem) {
.banner__install { display: none; }
}
/* Live stamp callout — small mono annotation showing what Hallmark
is currently rendering. Hover expands to the full stamp comment.
Sits between the install link and the spacer; hides on narrow. */
.banner__stamp {
position: relative;
margin-inline-start: var(--space-sm);
padding: 0.18rem 0.55rem;
font-family: var(--font-mono);
font-size: 0.625rem;
letter-spacing: 0;
text-transform: lowercase;
color: var(--color-muted);
border: 1px dashed var(--color-rule);
border-radius: 2px;
user-select: text;
cursor: default;
}
@media (hover: hover) and (pointer: fine) {
.banner__stamp:hover { color: var(--color-ink); border-color: var(--color-rule-2); }
.banner__stamp:hover .banner__stamp-detail { opacity: 1; pointer-events: auto; transform: translateY(0); }
}
.banner__stamp-detail {
position: absolute;
top: calc(100% + 6px);
left: 0;
white-space: nowrap;
padding: 0.5rem 0.75rem;
font-family: var(--font-mono);
font-size: 0.6875rem;
color: var(--color-ink-2);
background: var(--color-paper);
border: 1px solid var(--color-rule-2);
border-radius: 2px;
box-shadow: 0 4px 12px -4px oklch(20% 0.02 60 / 0.16);
opacity: 0;
pointer-events: none;
transform: translateY(-4px);
transition: opacity 140ms var(--ease-out), transform 140ms var(--ease-out);
z-index: 10;
}
@media (max-width: 64rem) {
.banner__stamp { display: none; }
}
/* Genre label — small text after the theme name in the banner. */
.banner__theme {
display: inline;
}
.banner__genre {
display: inline;
margin-inline-start: 0.5em;
font-family: var(--font-mono);
font-size: 0.6875rem;
letter-spacing: 0.04em;
text-transform: lowercase;
color: var(--color-muted);
font-style: normal;
font-weight: 400;
}
.banner__genre::before {
content: "· ";
color: var(--color-rule-2);
margin-inline-end: 0.1em;
}
@media (max-width: 38rem) {
.banner__genre { display: none; }
}
/* T-key onboarding tooltip — appears after 5 s idle, dismisses on
first T press. Anchored under the shuffle button. */
.t-tooltip {
position: absolute;
top: calc(100% + 12px);
right: var(--page-gutter);
padding: 0.55rem 0.85rem;
background: var(--color-ink);
color: var(--color-paper);
border-radius: 6px;
font-family: var(--font-body);
font-size: 0.8125rem;
letter-spacing: 0;
text-transform: none;
line-height: 1.45;
box-shadow: 0 8px 24px -8px oklch(20% 0.02 60 / 0.32);
z-index: var(--z-sticky);
animation: t-tooltip-in 320ms var(--ease-out) both;
}
.t-tooltip[hidden] { display: none; }
.t-tooltip[data-state="closing"] {
animation: t-tooltip-out 240ms var(--ease-in) forwards;
}
@keyframes t-tooltip-in {
from { opacity: 0; transform: translateY(-6px); }
to { opacity: 1; transform: none; }
}
@keyframes t-tooltip-out {
from { opacity: 1; transform: none; }
to { opacity: 0; transform: translateY(-4px); }
}
.t-tooltip__arrow {
position: absolute;
top: -5px;
right: 28px;
width: 10px;
height: 10px;
background: var(--color-ink);
transform: rotate(45deg);
border-radius: 1px;
}
.t-tooltip__body kbd {
display: inline-block;
padding: 0.1em 0.45em;
margin-inline: 0.1em;
background: var(--color-paper);
color: var(--color-ink);
border-radius: 3px;
font-family: var(--font-mono);
font-size: 0.85em;
font-weight: 500;
letter-spacing: 0;
}
.t-tooltip__body strong {
font-weight: 600;
}
@media (prefers-reduced-motion: reduce) {
.t-tooltip { animation: none; }
}
/* The active theme name — sits to the LEFT of the theme picker so the
page restructure registers as a deliberate event, not a passive repaint.
Smaller text + closer to the picker on desktop; hidden on narrow viewports. */
.banner__center {
font-family: var(--font-display);
font-weight: var(--display-weight, 500);
font-style: var(--display-style, normal);
font-size: 0.95rem;
letter-spacing: -0.005em;
text-transform: none;
color: var(--color-ink);
font-optical-sizing: auto;
transition: opacity var(--dur-short) var(--ease-out);
white-space: nowrap;
margin-inline-end: var(--space-xs);
}
[data-theme="manifesto"] .banner__center,
[data-theme="brutal"] .banner__center,
[data-theme="sport"] .banner__center {
text-transform: uppercase;
letter-spacing: -0.01em;
}
[data-theme="terminal"] .banner__center::before {
content: "$ ";
color: var(--color-accent);
}
[data-theme="terminal"] .banner__center {
font-family: var(--font-mono);
}
.banner__picker {
display: inline-flex;
align-items: center;
gap: 0.4rem;
}
.banner__dot {
appearance: none;
width: 16px;
height: 16px;
padding: 0;
background: var(--dot, var(--color-paper));
border: 1px solid var(--color-rule-2);
border-radius: 4px;
cursor: pointer;
position: relative;
transition: transform 100ms var(--ease-out),
border-color var(--dur-micro) var(--ease-out),
box-shadow var(--dur-micro) var(--ease-out);
}
.banner__dot::after {
content: "";
position: absolute;
inset: 3px;
background: var(--dot-edge, transparent);
border-radius: 2px;
opacity: 0.85;
}
@media (hover: hover) and (pointer: fine) {
.banner__dot:hover {
transform: translateY(-1px);
border-color: var(--color-ink);
}
}
.banner__dot:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
.banner__dot[aria-pressed="true"] {
border-color: var(--color-ink);
box-shadow: 0 0 0 2px var(--color-paper), 0 0 0 3px var(--color-ink);
}
.banner__sep {
width: 1px;
height: 14px;
background: var(--color-rule);
margin-inline: 0.25rem;
}
/* Combined shuffle button: icon + T kbd hint inside a single pill.
Click randomises; the T inside reads as a keyboard hint, not a separate
pill. Replaces the old .banner__random + .banner__kbd combo. */
.banner__shuffle {
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
height: 26px;
padding: 0 0.6rem 0 0.55rem;
background: transparent;
border: 1px solid var(--color-rule);
border-radius: var(--radius-pill, 999px);
color: var(--color-muted);
cursor: pointer;
font-family: var(--font-label);
font-size: 0.625rem;
letter-spacing: 0.08em;
text-transform: uppercase;
transition: color var(--dur-micro) var(--ease-out),
border-color var(--dur-micro) var(--ease-out),
background var(--dur-micro) var(--ease-out),
transform 80ms var(--ease-out);
}
.banner__shuffle svg {
flex-shrink: 0;
display: block;
}
.banner__shuffle-key {
display: inline-block;
font-weight: 500;
letter-spacing: 0.04em;
color: var(--color-muted);
padding-inline-start: 0.4rem;
border-inline-start: 1px solid var(--color-rule);
margin-inline-start: 0.05rem;
height: 14px;
line-height: 14px;
}
@media (hover: hover) and (pointer: fine) {
.banner__shuffle:hover {
color: var(--color-ink);
border-color: var(--color-ink);
}
.banner__shuffle:hover .banner__shuffle-key {
color: var(--color-ink);
border-color: var(--color-ink);
}
.banner__shuffle:hover svg {
transform: rotate(15deg);
transition: transform 200ms var(--ease-out);
}
}
.banner__shuffle:active {
transform: scale(0.96);
transition-duration: 60ms;
}
.banner__shuffle:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
@media (max-width: 60rem) {
.banner { gap: var(--space-md); }
.banner__center { font-size: 0.825rem; }
}
@media (max-width: 50rem) {
.banner__picker { gap: 0.28rem; }
.banner__dot { width: 14px; height: 14px; }
.banner__sep { display: none; }
}
/* Below 44rem: hide the dot grid (would overflow); keep mark + theme name + shuffle */
@media (max-width: 44rem) {
.banner__ver { display: none; }
.banner__picker { display: none; }
.banner__shuffle-key { display: none; }
.banner__shuffle { padding: 0 0.5rem; height: 24px; }
}
/* Below 26rem (very small phones): hide center label too — pure click-to-shuffle */
@media (max-width: 26rem) {
.banner__center { display: none; }
}
/* — Section label (01 / FOUNDATIONS) —————————————————— */
.section-label {
font-family: var(--font-label);
font-size: var(--text-xs);
font-weight: 400;
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
display: flex;
align-items: baseline;
gap: var(--space-sm);
}
.section-label .num { color: var(--color-ink); font-weight: 500; }
.section-label .divider { color: var(--color-rule-2); font-weight: 300; }
[data-theme="terminal"] .section-label::before {
content: "> ";
color: var(--color-accent);
}
[data-theme="manifesto"] .section-label .num {
color: var(--color-accent);
font-family: var(--font-display);
font-weight: 800;
font-size: var(--text-md);
}
[data-theme="sport"] .section-label .num {
color: var(--color-accent);
font-weight: 700;
font-family: var(--font-display);
font-size: var(--text-md);
font-style: italic;
}
[data-theme="almanac"] .section-label {
font-family: var(--font-mono);
}
/* — Button (outlined default) ————————————————————————— */
.btn {
display: inline-flex;
align-items: center;
gap: var(--space-sm);
padding: var(--space-sm) var(--space-lg);
font-family: var(--font-label);
font-size: var(--text-sm);
font-weight: 500;
letter-spacing: 0.04em;
color: var(--color-ink);
background: transparent;
border: var(--rule-fine) solid var(--color-ink);
border-radius: var(--radius-pill, 0);
min-height: 44px;
/* explicit properties — never `transition: all` */
transition: transform 100ms var(--ease-out),
background-color var(--dur-micro) var(--ease-out),
color var(--dur-micro) var(--ease-out),
border-color var(--dur-micro) var(--ease-out);
cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
.btn:hover {
background: var(--color-ink);
color: var(--color-paper);
transform: translateY(-1px);
}
}
.btn:active { transform: translateY(1px); transition-duration: 60ms; }
/* — Inline link ————————————————————————————————————— */
.link {
color: var(--color-ink);
text-decoration: none;
background-image: linear-gradient(var(--color-accent), var(--color-accent));
background-repeat: no-repeat;
background-position: 0 100%;
background-size: 100% 1px;
padding-bottom: 0.08em;
transition: background-size var(--dur-short) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.link:hover { background-size: 100% 2px; }
}
[data-theme="terminal"] .link {
background: none;
text-decoration: underline;
text-underline-offset: 2px;
}
/* — Code block ——————————————————————————————————————— */
.code {
font-family: var(--font-mono);
font-size: var(--text-sm);
font-weight: 400;
color: var(--color-ink);
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
border-radius: var(--radius-input, 0);
padding: var(--space-md) var(--space-lg);
overflow-x: auto;
white-space: nowrap;
line-height: 1.7;
display: flex;
align-items: center;
gap: var(--space-md);
position: relative;
box-shadow: var(--shadow-card, none);
}
.code .prompt { color: var(--color-muted); user-select: none; }
.code--block { white-space: pre; display: block; }
/* — Copy-to-clipboard button (silent success pattern) ————— */
.code__copy {
position: absolute;
top: 50%;
right: var(--space-sm);
transform: translateY(-50%);
font-family: var(--font-label);
font-size: 0.6875rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-muted);
background: var(--color-paper);
border: var(--rule-hair) solid var(--color-rule);
border-radius: var(--radius-input, 0);
padding: 0.35rem 0.65rem;
cursor: pointer;
opacity: 0;
transition: opacity var(--dur-short) var(--ease-out),
color var(--dur-short) var(--ease-out),
border-color var(--dur-short) var(--ease-out);
min-height: 28px;
display: inline-flex;
align-items: center;
gap: 0.4rem;
}
.code:hover .code__copy,
.code:focus-within .code__copy,
.code__copy:focus-visible {
opacity: 1;
}
@media (pointer: coarse) {
.code__copy { opacity: 1; }
}
.code__copy:hover { color: var(--color-ink); border-color: var(--color-rule-2); }
.code__copy[data-state="copied"] {
color: var(--color-accent);
border-color: var(--color-accent);
opacity: 1;
}
.code__copy-default { display: inline; }
.code__copy-done { display: none; }
.code__copy[data-state="copied"] .code__copy-default { display: none; }
.code__copy[data-state="copied"] .code__copy-done { display: inline; }
[data-theme="terminal"] .code__copy {
background: var(--color-paper-2);
border-color: var(--color-rule);
}
[data-theme="manifesto"] .code__copy {
background: var(--color-paper);
color: var(--color-paper);
border-color: var(--color-paper);
font-weight: 500;
}
[data-theme="manifesto"] .code__copy:hover {
color: var(--color-paper);
background: var(--color-accent);
border-color: var(--color-accent);
}
[data-theme="terminal"] .code {
background: var(--color-paper-3);
border-color: var(--color-rule-2);
}
[data-theme="manifesto"] .code {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
}
[data-theme="manifesto"] .code .prompt { color: var(--color-accent); }
/* — Specimen card ——————————————————————————————————— */
.spec {
display: flex;
flex-direction: column;
gap: var(--space-lg);
padding: var(--space-xl) 0;
border-top: var(--rule-hair) solid var(--color-rule);
}
.spec__head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-md);
}
.spec__name {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-xl);
letter-spacing: var(--tracking-tight);
color: var(--color-ink);
line-height: 1;
font-optical-sizing: auto;
}
.spec__num {
font-family: var(--font-label);
font-size: var(--text-xs);
color: var(--color-muted);
letter-spacing: var(--tracking-label);
}
.spec__rule {
font-family: var(--font-serif);
font-weight: 400;
font-size: var(--text-md);
line-height: var(--lh-snug);
color: var(--color-ink-2);
font-style: italic;
max-width: 40ch;
}
[data-theme="brutal"] .spec__rule,
[data-theme="manifesto"] .spec__rule,
[data-theme="terminal"] .spec__rule,
[data-theme="sport"] .spec__rule,
[data-theme="almanac"] .spec__rule {
font-style: normal;
font-family: var(--font-body);
font-weight: 500;
}
[data-theme="manifesto"] .spec__name { text-transform: uppercase; }
.spec__body { margin-top: var(--space-xs); }
/* — Swatches ——————————————————————————————————————— */
.swatch-row {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: var(--space-2xs);
height: 3rem;
}
.swatch {
display: flex;
align-items: flex-end;
padding: var(--space-2xs) var(--space-xs);
font-family: var(--font-label);
font-size: 0.625rem;
letter-spacing: 0.08em;
color: var(--color-paper);
text-transform: uppercase;
}
.swatch--light { color: var(--color-ink); }
/* — Type specimen ——————————————————————————————————— */
.type-spec { display: grid; gap: var(--space-xs); }
.type-spec__display {
font-family: var(--font-display);
font-size: var(--text-2xl);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
line-height: var(--lh-tight);
letter-spacing: var(--tracking-display);
font-optical-sizing: auto;
}
.type-spec__body {
font-family: var(--font-serif);
font-style: italic;
font-size: var(--text-md);
line-height: var(--lh-normal);
color: var(--color-ink-2);
max-width: 32ch;
}
[data-theme="brutal"] .type-spec__body,
[data-theme="manifesto"] .type-spec__body,
[data-theme="terminal"] .type-spec__body,
[data-theme="sport"] .type-spec__body,
[data-theme="almanac"] .type-spec__body {
font-style: normal;
font-family: var(--font-body);
}
/* — Easing curve SVG ——————————————————————————————— */
.curve {
width: 100%;
height: 4.5rem;
color: var(--color-ink);
}
/* — Without / With panels (parity demo) —————————————————
Both panels render the same eyebrow + H1 + sub + CTA structure.
The `data-variant` attribute drives every visual difference. */
.vs__panel {
display: grid;
gap: 0.75rem;
padding: var(--space-xl);
min-height: 16rem;
background: var(--color-paper);
border: var(--rule-hair) solid var(--color-rule-2);
align-content: start;
}
.vs__panel-eyebrow {
font-size: 0.75rem;
margin: 0;
}
.vs__panel-title {
margin: 0;
font-size: 2rem;
line-height: 1.05;
}
.vs__panel-sub {
margin: 0;
font-size: 0.875rem;
line-height: 1.45;
}
.vs__panel-cta {
display: inline-flex;
align-items: center;
justify-self: start;
margin-top: 0.5rem;
font-size: 0.875rem;
}
/* — "Without Hallmark" — the slop stack —————————————————
The bg uses theme paper so the panel integrates on dark themes
(otherwise a pure-white card looks like a glitch on Manifesto /
Midnight / Terminal). The AI-slop tells are still carried by the
centred layout, Inter font, gradient title, and gradient pill. */
.vs__panel[data-variant="slop"] {
text-align: center;
align-content: center;
justify-items: center;
background: var(--color-paper);
border-color: var(--color-rule);
font-family: "Inter", system-ui, sans-serif;
}
.vs__panel[data-variant="slop"] .vs__panel-eyebrow {
color: var(--color-muted);
font-family: inherit;
font-weight: 500;
letter-spacing: 0;
text-transform: none;
}
.vs__panel[data-variant="slop"] .vs__panel-title {
font-family: inherit;
font-weight: 800;
letter-spacing: -0.025em;
background: linear-gradient(95deg, #8b5dff 0%, #c14de0 50%, #e04db4 100%);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
max-width: 14ch;
}
.vs__panel[data-variant="slop"] .vs__panel-sub {
color: var(--color-muted);
font-family: inherit;
max-width: 28ch;
}
.vs__panel[data-variant="slop"] .vs__panel-cta {
justify-self: center;
padding: 0.55rem 1.4rem;
background: linear-gradient(95deg, #6366f1, #a855f7);
color: #fff;
border-radius: 9999px;
font-weight: 600;
letter-spacing: 0;
}
/* — "With Hallmark" — the considered version ————————————— */
.vs__panel[data-variant="hallmark"] {
text-align: left;
background: var(--color-paper);
border-color: var(--color-rule-2);
border-left: 2px solid var(--color-accent);
padding-left: calc(var(--space-xl) - 2px);
}
.vs__panel[data-variant="hallmark"] .vs__panel-eyebrow {
display: inline-flex;
align-items: center;
gap: 0.55em;
color: var(--color-muted);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
font-weight: 400;
}
.vs__panel[data-variant="hallmark"] .vs__panel-mark {
width: 6px;
height: 6px;
background: var(--color-accent);
display: inline-block;
}
.vs__panel[data-variant="hallmark"] .vs__panel-title {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
letter-spacing: -0.02em;
color: var(--color-ink);
max-width: 14ch;
font-optical-sizing: auto;
}
.vs__panel[data-variant="hallmark"] .vs__panel-title em {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
color: var(--color-ink);
}
.vs__panel[data-variant="hallmark"] .vs__panel-sub {
font-family: var(--font-body);
color: var(--color-ink-2);
max-width: 32ch;
}
.vs__panel[data-variant="hallmark"] .vs__panel-cta {
margin-top: var(--space-sm);
padding: 0.55rem 1.1rem;
background: var(--color-ink);
color: var(--color-paper);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
border-radius: 0;
}
/* Dashboard W/W variant — slop = glass widget, hallmark = considered. */
.vs__panel--dash {
min-height: 18rem;
}
/* Slop dashboard — glassmorphic, gradient, centered, badged. */
.vs__panel--dash[data-variant="slop"] {
position: relative;
background:
linear-gradient(135deg,
color-mix(in srgb, #6366f1 14%, transparent) 0%,
color-mix(in srgb, #c14de0 14%, transparent) 60%,
color-mix(in srgb, #f97316 12%, transparent) 100%),
rgba(255, 255, 255, 0.65);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
border-color: rgba(0, 0, 0, 0.06);
border-radius: 16px;
text-align: center;
align-content: center;
justify-items: center;
box-shadow: 0 12px 32px -16px rgba(99, 102, 241, 0.35);
font-family: "Inter", system-ui, sans-serif;
}
.vs__panel--dash[data-variant="slop"] .vs__panel-stat {
margin: 0;
font-family: inherit;
font-weight: 800;
font-size: clamp(2.75rem, 4vw + 1rem, 3.75rem);
letter-spacing: -0.03em;
line-height: 1;
background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.vs__panel--dash[data-variant="slop"] .vs__panel-stat-label {
margin: 0.4rem 0 0;
font-family: inherit;
font-size: 0.875rem;
color: #6b6b76;
}
.vs__panel--dash[data-variant="slop"] .vs__panel-badge {
display: inline-flex;
align-items: center;
margin: 0.6rem 0 0.4rem;
padding: 0.18rem 0.65rem;
font-family: inherit;
font-size: 0.75rem;
font-weight: 600;
color: #16a34a;
background: rgba(34, 197, 94, 0.12);
border-radius: 999px;
box-shadow: 0 0 12px -2px rgba(34, 197, 94, 0.5);
}
/* Hallmark dashboard — hairline rule, mono numerals, asymmetric. */
.vs__panel--dash[data-variant="hallmark"] {
text-align: left;
padding-top: var(--space-2xl);
border-top: 2px solid var(--color-ink);
border-left: var(--rule-hair) solid var(--color-rule-2);
border-right: var(--rule-hair) solid var(--color-rule-2);
border-bottom: var(--rule-hair) solid var(--color-rule-2);
background: var(--color-paper);
border-radius: 0;
}
.vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-line {
display: flex;
align-items: baseline;
gap: var(--space-md);
margin: 0;
}
.vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-num {
font-family: var(--font-mono);
font-feature-settings: "tnum";
font-variant-numeric: tabular-nums;
font-size: clamp(2.75rem, 4vw + 1rem, 3.75rem);
font-weight: 500;
letter-spacing: -0.03em;
color: var(--color-ink);
line-height: 1;
}
.vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-delta {
display: inline-flex;
align-items: center;
gap: 0.4em;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
.vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-dot {
display: inline-block;
width: 6px;
height: 6px;
background: var(--color-accent);
border-radius: 50%;
}
.vs__panel--dash[data-variant="hallmark"] .vs__panel-stat-label {
margin: var(--space-md) 0 0;
font-family: var(--font-body);
font-size: 0.9375rem;
line-height: 1.5;
color: var(--color-ink-2);
max-width: 32ch;
}
/* Pricing W/W variant — slop = popular badge + glow + emoji,
hallmark = editorial tier card with hairline rule and mono price. */
.vs__panel--pricing { min-height: 22rem; }
.vs__panel--pricing[data-variant="slop"] {
position: relative;
text-align: center;
align-content: start;
justify-items: center;
padding-top: 2.4rem;
background:
linear-gradient(135deg,
color-mix(in srgb, #6366f1 8%, transparent) 0%,
color-mix(in srgb, #ec4899 8%, transparent) 100%),
rgba(255, 255, 255, 0.85);
border: 1px solid rgba(99, 102, 241, 0.25);
border-radius: 18px;
box-shadow: 0 16px 36px -16px rgba(99, 102, 241, 0.4);
font-family: "Inter", system-ui, sans-serif;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-pop {
position: absolute;
top: -0.7rem;
left: 50%;
transform: translateX(-50%);
padding: 0.25rem 0.85rem;
background: linear-gradient(95deg, #6366f1, #a855f7, #ec4899);
color: #fff;
border-radius: 999px;
font-family: inherit;
font-size: 0.7rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
box-shadow: 0 4px 12px -2px rgba(168, 85, 247, 0.5);
white-space: nowrap;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-eyebrow {
font-family: inherit;
font-weight: 600;
font-size: 0.75rem;
letter-spacing: 0.08em;
text-transform: uppercase;
color: #6366f1;
margin: 0;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-price {
margin: 0.4rem 0;
font-family: inherit;
font-weight: 800;
font-size: 2.5rem;
letter-spacing: -0.025em;
line-height: 1;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-price-num {
background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-price-unit {
font-size: 0.875rem;
font-weight: 500;
color: #6b6b76;
letter-spacing: 0;
margin-inline-start: 0.25em;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-sub {
margin: 0;
font-family: inherit;
font-size: 0.8125rem;
color: #6b6b76;
max-width: 28ch;
}
.vs__panel--pricing[data-variant="slop"] .vs__panel-bullets {
list-style: none;
margin: 0.6rem 0 0.3rem;
padding: 0;
display: grid;
gap: 0.4rem;
font-family: inherit;
font-size: 0.8125rem;
color: #2a2a32;
text-align: left;
}
/* Hallmark pricing — editorial tier card. */
.vs__panel--pricing[data-variant="hallmark"] {
text-align: left;
align-content: start;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-tier {
margin: 0;
font-family: var(--font-display);
font-weight: var(--display-weight, 500);
font-style: var(--display-style, normal);
font-size: var(--text-xl);
letter-spacing: var(--tracking-tight);
color: var(--color-ink);
padding-block-end: var(--space-sm);
border-block-end: var(--rule-hair) solid var(--color-rule-2);
font-optical-sizing: auto;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-price {
display: flex;
align-items: baseline;
gap: 0.4rem;
margin: var(--space-md) 0 0;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-price-num {
font-family: var(--font-mono);
font-feature-settings: "tnum";
font-variant-numeric: tabular-nums;
font-size: clamp(2.25rem, 3vw + 1rem, 3rem);
font-weight: 500;
letter-spacing: -0.025em;
color: var(--color-ink);
line-height: 1;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-price-unit {
font-family: var(--font-mono);
font-size: 0.875rem;
color: var(--color-muted);
letter-spacing: 0;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-sub {
margin: var(--space-sm) 0 0;
max-width: 30ch;
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets {
list-style: none;
margin: var(--space-md) 0 0;
padding: 0;
display: grid;
gap: 0;
font-family: var(--font-body);
font-size: 0.9375rem;
color: var(--color-ink-2);
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets li {
padding-block: var(--space-sm);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.vs__panel--pricing[data-variant="hallmark"] .vs__panel-bullets li:last-child {
border-block-end: 0;
}
/* Personal-site W/W variant — slop = avatar + gradient name + pills,
hallmark = letter format with italic name and text links. */
.vs__panel--personal { min-height: 22rem; }
.vs__panel--personal[data-variant="slop"] {
text-align: center;
align-content: center;
justify-items: center;
background:
linear-gradient(160deg,
color-mix(in srgb, #ec4899 6%, transparent) 0%,
color-mix(in srgb, #6366f1 8%, transparent) 100%),
rgba(255, 255, 255, 0.92);
border-color: rgba(0, 0, 0, 0.06);
border-radius: 16px;
font-family: "Inter", system-ui, sans-serif;
}
.vs__panel--personal[data-variant="slop"] .vs__panel-avatar {
display: grid;
place-items: center;
width: 4.5rem;
height: 4.5rem;
border-radius: 50%;
background: linear-gradient(135deg, #6366f1, #a855f7, #ec4899);
color: #fff;
font-family: inherit;
font-weight: 700;
font-size: 1.75rem;
letter-spacing: -0.02em;
box-shadow: 0 8px 22px -10px rgba(168, 85, 247, 0.5);
margin-bottom: 0.6rem;
}
.vs__panel--personal[data-variant="slop"] .vs__panel-name {
margin: 0;
font-family: inherit;
font-weight: 800;
font-size: 1.875rem;
letter-spacing: -0.025em;
background: linear-gradient(95deg, #6366f1, #a855f7 50%, #ec4899);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.vs__panel--personal[data-variant="slop"] .vs__panel-sub {
margin: 0.4rem 0 0.9rem;
font-family: inherit;
font-size: 0.875rem;
color: #6b6b76;
max-width: 28ch;
}
.vs__panel--personal[data-variant="slop"] .vs__panel-pills {
display: flex;
gap: 0.4rem;
flex-wrap: wrap;
justify-content: center;
}
.vs__panel--personal[data-variant="slop"] .vs__panel-pill {
padding: 0.4rem 0.95rem;
background: rgba(255, 255, 255, 0.9);
border: 1px solid rgba(99, 102, 241, 0.25);
border-radius: 999px;
font-family: inherit;
font-size: 0.8125rem;
font-weight: 500;
color: #6366f1;
box-shadow: 0 2px 6px -2px rgba(99, 102, 241, 0.2);
}
/* Hallmark personal — letter format. */
.vs__panel--personal[data-variant="hallmark"] {
text-align: left;
align-content: start;
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-name {
margin: var(--space-sm) 0 0;
font-family: var(--font-display);
font-weight: var(--display-weight, 500);
font-style: italic;
font-size: clamp(2rem, 3vw + 1rem, 2.875rem);
line-height: 1.05;
letter-spacing: -0.02em;
color: var(--color-ink);
font-optical-sizing: auto;
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-name em {
font-family: var(--font-display);
font-style: normal;
font-weight: var(--display-weight, 500);
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-bio {
margin: var(--space-md) 0 0;
font-family: var(--font-serif);
font-style: italic;
font-size: 1rem;
line-height: var(--lh-relaxed);
color: var(--color-ink-2);
max-width: 38ch;
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-links {
margin: var(--space-lg) 0 0;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
align-items: center;
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-linkitem {
color: var(--color-ink);
text-decoration: none;
background-image: linear-gradient(var(--color-accent), var(--color-accent));
background-repeat: no-repeat;
background-position: 0 100%;
background-size: 100% 1px;
transition: background-size var(--dur-short) var(--ease-out);
}
.vs__panel--personal[data-variant="hallmark"] .vs__panel-linkitem:hover {
background-size: 100% 2px;
}
/* — Install pane internals ——————————————————————————— */
/* Row label — "I · Run" */
.install-pane__label {
margin: 0;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
display: flex;
align-items: baseline;
gap: 0.5rem;
}
.install-pane__step {
font-family: var(--font-display);
font-style: var(--display-style, normal);
font-weight: var(--display-weight, 500);
font-size: var(--text-md);
letter-spacing: 0.04em;
color: var(--color-ink);
font-optical-sizing: auto;
}
[data-theme="riso"] .install-pane__step,
[data-theme="brutal"] .install-pane__step,
[data-theme="manifesto"] .install-pane__step,
[data-theme="sport"] .install-pane__step {
text-transform: uppercase;
}
[data-theme="riso"] .install-pane__step { text-transform: lowercase; }
/* Row I — the install command, presented prominently */
.install-pane__cmd {
display: flex;
align-items: center;
gap: var(--space-md);
padding: var(--space-md) var(--space-lg);
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
border-radius: var(--radius-input, 0);
font-family: var(--font-mono);
font-size: clamp(1rem, 1.6vw, 1.25rem);
color: var(--color-ink);
line-height: 1.5;
position: relative;
min-height: 56px;
transition: border-color var(--dur-micro) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.install-pane__cmd:hover { border-color: var(--color-ink); }
}
.install-pane__prompt {
color: var(--color-accent);
user-select: none;
flex-shrink: 0;
font-weight: 500;
}
.install-pane__cmd-text {
flex: 1;
font-weight: 400;
letter-spacing: 0;
user-select: all;
cursor: text;
}
.install-pane__copy {
flex-shrink: 0;
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 36px;
padding: 0.4rem 0.85rem;
background: var(--color-paper);
border: var(--rule-hair) solid var(--color-rule);
font-family: var(--font-label);
font-size: 0.6875rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-muted);
cursor: pointer;
transition: color var(--dur-short) var(--ease-out),
border-color var(--dur-short) var(--ease-out),
background-color var(--dur-short) var(--ease-out);
}
.install-pane__copy:hover {
color: var(--color-ink);
border-color: var(--color-ink);
}
.install-pane__copy:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
.install-pane__copy[data-state="copied"] {
color: var(--color-paper);
background: var(--color-accent);
border-color: var(--color-accent);
}
.install-pane__copy-default { display: inline; }
.install-pane__copy-done { display: none; }
.install-pane__copy[data-state="copied"] .install-pane__copy-default { display: none; }
.install-pane__copy[data-state="copied"] .install-pane__copy-done { display: inline; }
[data-theme="terminal"] .install-pane__cmd {
background: var(--color-paper-3);
border-color: var(--color-rule-2);
}
[data-theme="manifesto"] .install-pane__cmd {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
}
[data-theme="manifesto"] .install-pane__prompt { color: var(--color-accent); }
[data-theme="manifesto"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
font-weight: 500;
}
/* Row II — harness list */
.install-pane__harnesses {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: var(--space-md);
}
.harness {
display: grid;
grid-template-columns: 11rem 1fr auto;
gap: var(--space-md) var(--space-lg);
align-items: baseline;
padding-block: var(--space-sm);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.harness:last-child { border-block-end: 0; }
@media (max-width: 38rem) {
.harness {
grid-template-columns: 1fr;
gap: 0.25rem;
padding-block: var(--space-md);
}
}
.harness__name {
font-family: var(--font-display);
font-weight: var(--display-weight, 500);
font-style: var(--display-style, normal);
font-size: var(--text-md);
letter-spacing: var(--tracking-tight);
color: var(--color-ink);
font-optical-sizing: auto;
}
[data-theme="riso"] .harness__name,
[data-theme="brutal"] .harness__name,
[data-theme="manifesto"] .harness__name,
[data-theme="sport"] .harness__name { text-transform: uppercase; }
[data-theme="riso"] .harness__name { text-transform: lowercase; }
.harness__path {
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--color-ink-2);
background: transparent;
border: 0;
padding: 0;
letter-spacing: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.harness__status {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
display: inline-flex;
align-items: center;
gap: 0.4em;
}
.harness__status--ok { color: var(--color-accent); }
.harness__status--ok::before {
content: "";
display: inline-block;
width: 6px;
height: 6px;
background: var(--color-accent);
border-radius: 50%;
}
/* Row III — the next step */
.install-pane__next {
margin: 0;
font-family: var(--font-serif);
font-style: italic;
font-size: var(--text-md);
line-height: var(--lh-normal);
color: var(--color-ink-2);
max-width: 56ch;
}
.install-pane__next code {
font-family: var(--font-mono);
font-style: normal;
font-size: 0.875em;
color: var(--color-ink);
background: var(--color-paper-2);
padding: 0.05em 0.35em;
border: var(--rule-hair) solid var(--color-rule);
}
[data-theme="brutal"] .install-pane__next,
[data-theme="manifesto"] .install-pane__next,
[data-theme="terminal"] .install-pane__next,
[data-theme="sport"] .install-pane__next,
[data-theme="almanac"] .install-pane__next {
font-family: var(--font-body);
font-style: normal;
}
[data-theme="manifesto"] .install-pane__next { text-transform: uppercase; font-weight: 500; }
/* — Per-theme install-pane overrides ———————————————————— */
[data-theme="terminal"] .install-pane {
background: var(--color-paper-2);
}
[data-theme="brutal"] .install-pane,
[data-theme="manifesto"] .install-pane {
border-width: 2px;
}
[data-theme="atelier"] .install-pane,
[data-theme="salon"] .install-pane {
border: 0;
background: transparent;
box-shadow: none;
}
[data-theme="atelier"] .install-pane__row,
[data-theme="salon"] .install-pane__row {
padding-inline: 0;
}
[data-theme="atelier"] .install-pane__row + .install-pane__row,
[data-theme="salon"] .install-pane__row + .install-pane__row {
border-block-start: var(--rule-hair) solid var(--color-rule);
}
/* — Easter egg overlay ——————————————————————————————————
Hidden by default. Revealed when the user spams T faster than the
site can keep up — see js/main.js. Pure white full-screen, system
mono font, dark text — deliberately decoupled from the active
theme so it reads as the page itself stepping in. Auto-dismisses
after ~4.2s; while it's open, all keystrokes are swallowed. */
.easter {
position: fixed;
inset: 0;
z-index: 9999;
display: grid;
place-items: center;
padding: var(--space-xl);
background: #fff;
color: #111;
font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 0.95rem;
line-height: 1.65;
animation: easter-fade-in 240ms ease-out both;
}
.easter[hidden] { display: none; }
.easter[data-state="closing"] {
animation: easter-fade-out 360ms ease-in forwards;
}
@keyframes easter-fade-in {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes easter-fade-out {
from { opacity: 1; }
to { opacity: 0; }
}
.easter__panel {
display: grid;
gap: 1.4rem;
max-width: 38rem;
width: 100%;
}
.easter__lines {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: 0.45rem;
}
.easter__line {
margin: 0;
opacity: 0;
transform: translateY(6px);
animation: easter-line 360ms ease-out forwards;
}
.easter__line:nth-child(1) { animation-delay: 180ms; }
.easter__line:nth-child(2) { animation-delay: 380ms; }
.easter__line:nth-child(3) { animation-delay: 700ms; }
@keyframes easter-line {
to { opacity: 1; transform: none; }
}
.easter__line--cmd {
font-size: 1rem;
font-weight: 500;
color: #111;
margin-block-end: 0.6rem;
letter-spacing: 0;
}
.easter__prompt,
.easter__arrow {
color: #b0b0b0;
user-select: none;
margin-inline-end: 0.5rem;
}
.easter__num {
color: #111;
font-weight: 600;
font-feature-settings: "tnum";
font-variant-numeric: tabular-nums;
}
.easter__line--punchline {
margin-block-start: 0.8rem;
font-size: clamp(1.75rem, 4.5vw, 2.5rem);
line-height: 1.1;
letter-spacing: -0.02em;
font-weight: 500;
color: #111;
}
.easter__line--punchline .easter__arrow {
font-size: 0.9rem;
vertical-align: 0.25em;
font-weight: 400;
}
.easter__cursor {
display: inline-block;
width: 0.42em;
height: 0.95em;
background: #111;
margin-inline-start: 0.18em;
vertical-align: -0.08em;
opacity: 0;
animation: easter-blink 1.05s steps(2) infinite;
animation-delay: 1.15s;
}
@keyframes easter-blink {
0%, 49% { opacity: 1; }
50%, 100% { opacity: 0; }
}
.easter__hint {
margin: 0;
padding-block-start: 1.2rem;
border-block-start: 1px solid #e5e5e5;
font-size: 0.7rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: #888;
display: flex;
flex-wrap: wrap;
gap: 0.6rem;
align-items: center;
}
@media (prefers-reduced-motion: reduce) {
.easter,
.easter[data-state="closing"],
.easter__line { animation: none; }
.easter__line { opacity: 1; transform: none; }
.easter__cursor { animation: none; opacity: 1; }
}
/* — Reveals ————————————————————————————————————————— */
.reveal {
opacity: 0;
transform: translateY(10px);
}
.reveal.is-in {
animation: reveal var(--dur-long) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 60ms);
}
@keyframes reveal { to { opacity: 1; transform: none; } }
/* Theme-specific reveal patterns */
[data-theme="brutal"] .reveal,
[data-theme="manifesto"] .reveal,
[data-theme="sport"] .reveal {
transform: translateX(-16px);
}
@keyframes reveal-sweep { to { opacity: 1; transform: none; } }
[data-theme="brutal"] .reveal.is-in,
[data-theme="manifesto"] .reveal.is-in,
[data-theme="sport"] .reveal.is-in {
animation: reveal-sweep var(--dur-long) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 60ms);
}
[data-theme="atelier"] .reveal,
[data-theme="salon"] .reveal,
[data-theme="newsprint"] .reveal {
transform: none; /* no spatial reveal — fade only */
}
[data-theme="atelier"] .reveal.is-in,
[data-theme="salon"] .reveal.is-in,
[data-theme="newsprint"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.4) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 80ms);
}
@keyframes reveal-fade { to { opacity: 1; } }
[data-theme="terminal"] .reveal,
[data-theme="terminal"] .reveal.is-in {
transform: none;
opacity: 1;
animation: none;
}
@media (prefers-reduced-motion: reduce) {
.reveal { transform: none; animation-duration: 150ms !important; }
@keyframes reveal { to { opacity: 1; } }
*, *::before, *::after {
animation-duration: 150ms !important;
transition-duration: 150ms !important;
}
}
/* — View transitions ————————————————————————————————— */
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 280ms;
animation-timing-function: var(--ease-out);
}
/* ───────────── STUDIO — Fraunces italic display ───────────── */
[data-theme="studio"] .hero__display,
[data-theme="studio"] .section__title,
[data-theme="studio"] .foot__wordmark,
[data-theme="studio"] .hero__quote p,
[data-theme="studio"] .hero__salutation,
[data-theme="studio"] .spec__name,
[data-theme="studio"] .tell__name {
font-style: italic;
letter-spacing: -0.02em;
font-variation-settings: "opsz" 144, "SOFT" 30;
}
[data-theme="studio"] .banner__center {
font-style: italic;
letter-spacing: 0;
font-variation-settings: "opsz" 24;
}
[data-theme="studio"] .hero__lede,
[data-theme="studio"] .hero__letter-body,
[data-theme="studio"] .spec__rule,
[data-theme="studio"] .tell__why,
[data-theme="studio"] .hero__attrib,
[data-theme="studio"] .foot__tagline {
font-family: var(--font-body);
font-style: normal;
}
[data-theme="studio"] .hero__eyebrow,
[data-theme="studio"] .label,
[data-theme="studio"] .section-label {
font-feature-settings: "ss01";
}
/* ───────────── PASTEL — Geist sans display, soft surfaces ───────────── */
[data-theme="pastel"] .hero__display,
[data-theme="pastel"] .section__title,
[data-theme="pastel"] .foot__wordmark,
[data-theme="pastel"] .spec__name,
[data-theme="pastel"] .tell__name,
[data-theme="pastel"] .hero__quote p,
[data-theme="pastel"] .hero__salutation,
[data-theme="pastel"] .hero__qualifier {
font-family: var(--font-display);
font-style: normal;
font-weight: 600;
letter-spacing: -0.025em;
}
[data-theme="pastel"] .hero__display {
font-weight: 600;
letter-spacing: -0.035em;
}
[data-theme="pastel"] .hero__stat {
font-weight: 600;
letter-spacing: -0.04em;
}
[data-theme="pastel"] .hero__lede,
[data-theme="pastel"] .hero__letter-body,
[data-theme="pastel"] .spec__rule,
[data-theme="pastel"] .tell__why,
[data-theme="pastel"] .foot__tagline {
font-family: var(--font-body);
font-style: normal;
font-weight: 400;
color: var(--color-ink-2);
}
[data-theme="pastel"] .banner__center {
font-family: var(--font-display);
font-weight: 500;
font-size: 0.875rem;
letter-spacing: 0;
text-transform: none;
}
/* Pastel uses a subtle indigo on accent — never as a flood. */
[data-theme="pastel"] .hero__eyebrow .mark,
[data-theme="pastel"] .opening__eyebrow .mark {
background: var(--color-accent);
border-radius: 1px;
}
/* ───────────── RISO — bold lowercase, off-register print ───────────── */
[data-theme="riso"] .hero__display,
[data-theme="riso"] .hero__quote p,
[data-theme="riso"] .hero__salutation,
[data-theme="riso"] .hero__qualifier,
[data-theme="riso"] .hero__stat,
[data-theme="riso"] .section__title,
[data-theme="riso"] .foot__wordmark,
[data-theme="riso"] .spec__name,
[data-theme="riso"] .tell__name {
font-family: var(--font-display);
font-weight: 800;
font-style: normal;
text-transform: lowercase;
letter-spacing: -0.04em;
}
/* The riso off-register effect — a 2px cyan ghost behind the headline.
Subtle, not garish. Reduced-motion + browsers without text-shadow are fine. */
[data-theme="riso"] .hero__display,
[data-theme="riso"] .hero__quote p,
[data-theme="riso"] .hero__stat {
text-shadow: 2px 2px 0 var(--color-accent),
-2px 0 0 var(--color-accent-2, oklch(78% 0.18 95));
}
[data-theme="riso"] .hero__lede,
[data-theme="riso"] .hero__letter-body,
[data-theme="riso"] .spec__rule,
[data-theme="riso"] .tell__why,
[data-theme="riso"] .foot__tagline {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
}
[data-theme="riso"] .hero__attrib,
[data-theme="riso"] .label,
[data-theme="riso"] .section-label,
[data-theme="riso"] .banner__center {
text-transform: lowercase;
letter-spacing: 0.02em;
}
[data-theme="riso"] .banner__center {
font-family: var(--font-display);
font-weight: 700;
font-size: var(--text-md);
}
/* Subtle paper grain — a tiny stipple via repeating radial-gradient.
Cheap, no image asset, and disappears under prefers-reduced-data. */
[data-theme="riso"] body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
z-index: 0;
background-image: radial-gradient(circle at 1px 1px, oklch(0% 0 0 / 0.045) 1px, transparent 0);
background-size: 3px 3px;
mix-blend-mode: multiply;
}
@media (prefers-reduced-data: reduce) {
[data-theme="riso"] body::before { display: none; }
}
[data-theme="riso"] .hero__photo-grid > span {
filter: contrast(1.05) saturate(1.4);
}
/* ───────────── HERO ARCHETYPES ─────────────
The hero slot picks one shape per theme, from the cookbook.
Each archetype is a different fingerprint — not a re-skin. */
.hero { display: grid; }
.hero__eyebrow {
display: inline-flex;
align-items: center;
gap: 0.6rem;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
margin-bottom: var(--space-lg);
}
.hero__eyebrow .mark {
width: 6px; height: 6px;
background: var(--color-accent);
display: inline-block;
}
.hero__display {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-display);
line-height: var(--lh-tight);
letter-spacing: var(--tracking-display);
color: var(--color-ink);
font-optical-sizing: auto;
margin: 0;
}
.hero__display--small {
font-size: var(--text-display-s);
}
.hero__lede {
font-family: var(--font-serif);
font-style: italic;
font-size: var(--text-md);
line-height: var(--lh-normal);
color: var(--color-ink-2);
max-width: 56ch;
margin-block: var(--space-lg) 0;
}
[data-theme="brutal"] .hero__lede,
[data-theme="manifesto"] .hero__lede,
[data-theme="terminal"] .hero__lede,
[data-theme="sport"] .hero__lede,
[data-theme="almanac"] .hero__lede {
font-style: normal;
font-family: var(--font-body);
}
[data-theme="manifesto"] .hero__display,
[data-theme="brutal"] .hero__display,
[data-theme="sport"] .hero__display {
text-transform: uppercase;
}
.hero__link {
margin-top: var(--space-lg);
display: inline-block;
font-family: var(--font-label);
font-size: var(--text-sm);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
}
/* H1 — Marquee. Display fills the fold, install code below. */
.hero--marquee {
padding-block: var(--space-2xl) var(--space-xl);
gap: var(--space-lg);
}
.hero--marquee .hero__display {
max-width: 18ch;
}
.hero--marquee .hero__cta {
margin-top: var(--space-xl);
display: grid;
gap: var(--space-sm);
max-width: 30rem;
}
.hero--marquee .hero__cta .label {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
/* H2 — Split Diptych. Title left, proof right. */
.hero--split {
grid-template-columns: 7fr 5fr;
gap: var(--space-2xl);
padding-block: var(--space-2xl) var(--space-xl);
align-items: end;
}
@media (max-width: 60rem) {
.hero--split { grid-template-columns: 1fr; gap: var(--space-xl); align-items: start; }
}
.hero--split .hero__col { display: grid; gap: 0; }
.hero--split .hero__proof {
display: grid;
gap: var(--space-xs);
padding-block-start: var(--space-md);
border-block-start: var(--rule-hair) solid var(--color-rule);
}
.hero--split .hero__proof .label {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
margin-bottom: var(--space-xs);
}
.hero__proof-line {
font-family: var(--font-body);
font-size: var(--text-sm);
color: var(--color-ink-2);
line-height: var(--lh-snug);
font-variant-numeric: tabular-nums;
}
.hero--split .hero__proof a { margin-top: var(--space-sm); }
/* H3 — Stat-Led. Giant number + qualifier. */
.hero--stat {
padding-block: var(--space-2xl) var(--space-xl);
gap: 0;
}
.hero__stat {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: clamp(7rem, 22vw, 16rem);
line-height: 0.85;
letter-spacing: -0.04em;
color: var(--color-ink);
font-optical-sizing: auto;
display: block;
margin-block: var(--space-md) 0;
}
.hero__qualifier {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-2xl);
letter-spacing: var(--tracking-display);
color: var(--color-ink);
margin-block: var(--space-md) 0;
font-optical-sizing: auto;
}
[data-theme="manifesto"] .hero__stat,
[data-theme="sport"] .hero__stat {
color: var(--color-accent);
}
/* H4 — Quote-Led. Pull quote in italic display. */
.hero--quote {
padding-block: var(--space-2xl) var(--space-xl);
max-width: 56rem;
}
.hero__quote {
margin: 0;
padding: 0;
}
.hero__quote p {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
font-size: clamp(2.25rem, 4vw + 1rem, 4.25rem);
line-height: 1.08;
letter-spacing: -0.015em;
color: var(--color-ink);
margin: 0;
}
.hero__attrib {
margin-block-start: var(--space-lg);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
[data-theme="brutal"] .hero__quote p,
[data-theme="manifesto"] .hero__quote p,
[data-theme="terminal"] .hero__quote p,
[data-theme="sport"] .hero__quote p,
[data-theme="almanac"] .hero__quote p {
font-style: normal;
font-family: var(--font-display);
}
/* H5 — Letter. First-person greeting, paragraph body, signoff. */
.hero--letter {
padding-block: var(--space-2xl) var(--space-xl);
max-width: 52rem;
gap: 0;
}
.hero__salutation {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: italic;
font-size: clamp(2rem, 3vw + 1rem, 3.25rem);
line-height: 1.15;
letter-spacing: -0.01em;
color: var(--color-ink);
margin-block: var(--space-md) var(--space-lg);
font-optical-sizing: auto;
}
.hero__letter-body {
font-family: var(--font-serif);
font-size: var(--text-md);
line-height: var(--lh-relaxed);
color: var(--color-ink-2);
max-width: 60ch;
margin: 0;
}
[data-theme="brutal"] .hero__letter-body,
[data-theme="terminal"] .hero__letter-body,
[data-theme="sport"] .hero__letter-body,
[data-theme="almanac"] .hero__letter-body {
font-family: var(--font-body);
}
.hero__signoff {
margin-block: var(--space-xl) 0;
font-family: var(--font-serif);
font-size: var(--text-md);
font-style: italic;
color: var(--color-ink-2);
line-height: var(--lh-snug);
}
.hero__sign {
font-style: normal;
font-family: var(--font-display);
color: var(--color-ink);
letter-spacing: var(--tracking-display);
}
/* H6 — Photographic. Image area + small caption + text below. */
.hero--photo {
padding-block: var(--space-xl) var(--space-xl);
gap: var(--space-xl);
grid-template-columns: 1fr;
}
.hero__photo {
position: relative;
aspect-ratio: 16 / 7;
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
overflow: hidden;
}
.hero__photo-grid {
position: absolute;
inset: 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 1px;
background: var(--color-rule);
}
.hero__photo-grid > span {
background: linear-gradient(135deg,
color-mix(in oklch, var(--color-paper-3) 80%, var(--color-accent) 5%),
color-mix(in oklch, var(--color-neutral) 30%, var(--color-paper) 70%));
}
.hero__photo-grid > span:nth-child(2n) { background: linear-gradient(180deg, var(--color-paper-3), var(--color-paper-2)); }
.hero__photo-grid > span:nth-child(3n) { background: linear-gradient(45deg, var(--color-paper-2), var(--color-paper-3)); }
.hero__photo-grid > span:nth-child(5n) { background: linear-gradient(90deg, var(--color-paper-3), color-mix(in oklch, var(--color-accent) 10%, var(--color-paper))); }
.hero__photo-grid > span:nth-child(7n) { background: var(--color-neutral); }
.hero__photo-caption {
position: absolute;
left: var(--space-md);
bottom: var(--space-md);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-paper);
background: color-mix(in oklch, var(--color-ink) 78%, transparent);
padding: 0.35rem 0.65rem;
}
.hero__photo-text { display: grid; gap: 0; }
/* H7 — Demo Video Clipped-by-viewport-edge.
Pure-CSS dashboard mockup that extends past the right page edge.
No real video — this is a custom-craft demonstration of the clip layout. */
.hero--clipped {
display: grid;
grid-template-columns: minmax(20rem, 1fr) 1.4fr;
gap: var(--space-2xl);
padding-block: var(--space-2xl) var(--space-xl);
align-items: center;
position: relative;
}
.hero--clipped .hero__copy { display: grid; gap: 0; }
.hero--clipped .hero__display { max-width: 16ch; margin: 0; }
.hero--clipped .hero__lede { max-width: 42ch; }
.hero--clipped .hero__cta { margin-top: var(--space-xl); }
.hero__mock {
width: calc(100% + 12vw); /* the clip — 12% spills past viewport */
max-width: none;
aspect-ratio: 16 / 10;
margin: 0;
border-radius: max(var(--radius-card, 0), 8px); /* always slightly rounded — it's a browser-frame mockup */
overflow: hidden;
box-shadow: 0 30px 60px -28px oklch(20% 0.02 260 / 0.28),
0 1px 2px oklch(20% 0.02 260 / 0.06);
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
display: flex;
flex-direction: column;
transform: rotate(-0.4deg) translateY(-2px);
transform-origin: left center;
}
.hero__mock-chrome {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 14px;
background: color-mix(in oklch, var(--color-paper-2) 100%, var(--color-rule) 12%);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.hero__mock-dot {
width: 9px; height: 9px;
border-radius: 50%;
background: color-mix(in oklch, var(--color-rule-2) 80%, transparent);
}
.hero__mock-url {
margin-inline-start: 12px;
font-family: var(--font-mono);
font-size: 0.7rem;
color: var(--color-muted);
letter-spacing: 0.02em;
}
.hero__mock-body {
flex: 1;
display: grid;
grid-template-columns: 56px 1fr;
background: var(--color-paper);
min-height: 0;
}
.hero__mock-rail {
display: flex;
flex-direction: column;
gap: 10px;
padding: 16px 12px;
background: color-mix(in oklch, var(--color-paper) 100%, var(--color-paper-2) 60%);
border-inline-end: var(--rule-hair) solid var(--color-rule);
}
.hero__mock-rail-item {
width: 28px; height: 28px;
border-radius: 6px;
background: color-mix(in oklch, var(--color-rule) 100%, transparent);
}
.hero__mock-rail-item.is-active {
background: var(--color-accent);
opacity: 0.85;
}
.hero__mock-main {
padding: 18px 22px;
display: flex;
flex-direction: column;
gap: 16px;
min-height: 0;
}
.hero__mock-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.hero__mock-row--head { padding-block-end: 4px; }
.hero__mock-bar {
height: 8px;
border-radius: 2px;
background: color-mix(in oklch, var(--color-rule) 80%, transparent);
flex: 1;
}
.hero__mock-bar--lg { height: 12px; max-width: 180px; }
.hero__mock-bar--sm { max-width: 80px; }
.hero__mock-bar--xs { height: 6px; max-width: 56px; }
.hero__mock-bar--short { max-width: 50%; }
.hero__mock-pill {
display: inline-block;
width: 64px; height: 22px;
border-radius: 999px;
background: var(--color-accent);
opacity: 0.18;
}
.hero__mock-grid {
display: grid;
grid-template-columns: 1fr 1fr 1.4fr;
grid-template-rows: 1fr;
gap: 12px;
flex: 1;
min-height: 0;
}
.hero__mock-card {
background: color-mix(in oklch, var(--color-paper) 100%, var(--color-paper-2) 60%);
border: var(--rule-hair) solid var(--color-rule);
border-radius: 8px;
padding: 12px;
display: flex;
flex-direction: column;
gap: 8px;
min-height: 0;
}
.hero__mock-card--accent {
background: color-mix(in oklch, var(--color-paper) 100%, var(--color-accent) 8%);
border-color: color-mix(in oklch, var(--color-accent) 40%, var(--color-rule));
}
.hero__mock-card--wide {
/* spans larger column already */
}
.hero__mock-stat {
font-family: var(--font-display);
font-weight: 600;
font-size: 1.75rem;
letter-spacing: -0.02em;
color: var(--color-ink);
font-variant-numeric: tabular-nums;
line-height: 1;
}
.hero__mock-spark {
flex: 1;
background:
linear-gradient(95deg,
transparent 0 6%,
var(--color-accent) 6% 7%,
transparent 7% 14%,
var(--color-accent) 14% 15%,
transparent 15% 28%,
var(--color-accent) 28% 29%,
transparent 29% 42%,
var(--color-accent) 42% 43%,
transparent 43% 60%,
var(--color-accent) 60% 61%,
transparent 61% 80%,
var(--color-accent) 80% 81%,
transparent 81% 100%);
opacity: 0.55;
border-radius: 4px;
min-height: 36px;
align-self: stretch;
}
.hero__mock-rows { display: flex; flex-direction: column; gap: 8px; }
@media (max-width: 60rem) {
.hero--clipped { grid-template-columns: 1fr; gap: var(--space-xl); }
.hero__mock { width: 100%; transform: none; aspect-ratio: 16 / 11; }
}
@media (prefers-reduced-motion: reduce) {
.hero__mock { transform: none; }
}
/* ───────────── FOOTER ARCHETYPES ───────────── */
.foot { display: grid; gap: var(--space-md); padding-block: var(--space-2xl) var(--space-xl); border-block-start: var(--rule-hair) solid var(--color-rule); }
/* Ft1 — Masthead. Wordmark + tagline + links + powered. */
.foot--masthead {
grid-template-columns: 1fr;
gap: var(--space-md);
align-items: start;
}
.foot__wordmark {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-3xl);
letter-spacing: var(--tracking-display);
color: var(--color-ink);
font-optical-sizing: auto;
line-height: 1;
}
[data-theme="manifesto"] .foot__wordmark,
[data-theme="brutal"] .foot__wordmark,
[data-theme="sport"] .foot__wordmark { text-transform: uppercase; }
.foot__tagline {
font-family: var(--font-serif);
font-style: italic;
font-size: var(--text-md);
color: var(--color-ink-2);
max-width: 50ch;
margin: 0;
line-height: var(--lh-snug);
}
[data-theme="brutal"] .foot__tagline,
[data-theme="manifesto"] .foot__tagline,
[data-theme="terminal"] .foot__tagline,
[data-theme="sport"] .foot__tagline,
[data-theme="almanac"] .foot__tagline {
font-style: normal;
font-family: var(--font-body);
}
.foot__links {
display: flex;
flex-wrap: wrap;
gap: var(--space-md);
margin-block-start: var(--space-md);
font-family: var(--font-label);
font-size: var(--text-sm);
letter-spacing: 0.04em;
}
.foot__powered {
margin-block-start: var(--space-lg);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
.foot__powered-mark {
color: var(--color-ink);
font-weight: 500;
}
/* Ft2 — Inline. Single dense line. */
.foot--inline {
grid-template-columns: 1fr;
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--space-md);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
.foot__wordmark-small {
color: var(--color-ink);
font-weight: 500;
letter-spacing: 0.22em;
}
.foot__sep {
width: 1px; height: 12px; background: var(--color-rule-2);
}
/* Ft3 — Index columns. */
.foot--index {
grid-template-columns: repeat(4, 1fr);
gap: var(--space-xl);
}
@media (max-width: 60rem) {
.foot--index { grid-template-columns: repeat(2, 1fr); }
}
.foot__col-head {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
margin-block-end: var(--space-sm);
padding-block-end: var(--space-xs);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.foot--index ul {
list-style: none;
margin: 0;
padding: 0;
display: grid;
gap: var(--space-2xs);
font-family: var(--font-body);
font-size: var(--text-sm);
color: var(--color-ink-2);
}
/* Ft4 — Dense colophon (monospace). */
.foot--dense {
font-family: var(--font-mono);
font-size: var(--text-xs);
line-height: 1.7;
color: var(--color-ink-2);
white-space: pre-wrap;
margin: 0;
padding-block: var(--space-md);
}
/* ───────────── SLOT REVEALS ─────────────
The slot fades when its archetype is replaced — supplements the
View Transition and gives a graceful enter on first paint. */
.slot[data-populating] > * {
animation: slot-in calc(var(--dur-long) * 0.7) var(--ease-out) forwards;
opacity: 0;
}
@keyframes slot-in { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
.slot[data-populating] > * { animation: none; opacity: 1; }
}
/* ───────────── QUIET — polished minimalism ─────────────
The "modern enterprise" theme: Geist sans, pure white, large
confident display, generous space, pill CTAs. Reads like the
ElevenLabs / Stripe school of restraint. Reveals stay off — the
page is composed, not animated in. */
[data-theme="quiet"] .reveal,
[data-theme="quiet"] .reveal.is-in,
[data-theme="quiet"] .slot[data-populating] > * {
opacity: 1;
transform: none;
animation: none;
}
[data-theme="quiet"] .hero__display,
[data-theme="quiet"] .hero__quote p,
[data-theme="quiet"] .hero__stat,
[data-theme="quiet"] .section__title,
[data-theme="quiet"] .foot__wordmark,
[data-theme="quiet"] .spec__name,
[data-theme="quiet"] .ex-card__name,
[data-theme="quiet"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
text-transform: none;
letter-spacing: -0.025em;
text-shadow: none;
}
[data-theme="quiet"] .hero__display { font-weight: 600; }
[data-theme="quiet"] .hero__lede,
[data-theme="quiet"] .hero__letter-body,
[data-theme="quiet"] .spec__rule,
[data-theme="quiet"] .foot__tagline,
[data-theme="quiet"] .install-pane__next {
font-family: var(--font-body);
font-style: normal;
font-weight: 400;
color: var(--color-neutral);
}
[data-theme="quiet"] .hero__salutation {
font-family: var(--font-display);
font-style: normal;
font-weight: 600;
font-size: var(--text-2xl);
letter-spacing: -0.02em;
}
[data-theme="quiet"] .hero__sign,
[data-theme="quiet"] .hero__signoff {
font-family: var(--font-body);
font-style: normal;
}
[data-theme="quiet"] .hero__attrib,
[data-theme="quiet"] .section-label,
[data-theme="quiet"] .label,
[data-theme="quiet"] .install-pane__label,
[data-theme="quiet"] .vs__label,
[data-theme="quiet"] .ex-card__num {
font-family: var(--font-label);
font-weight: 500;
}
[data-theme="quiet"] .banner__center {
font-family: var(--font-display);
font-weight: 500;
font-size: 0.875rem;
letter-spacing: -0.005em;
text-transform: none;
}
[data-theme="quiet"] .banner {
background: color-mix(in oklch, var(--color-paper) 94%, transparent);
border-block-end-color: var(--color-rule);
}
/* Pill CTAs — Quiet's signature button. Black-filled primary, white-
outlined secondary. Applied to anything that reads as a CTA. */
[data-theme="quiet"] .install-pane__copy {
border-radius: 999px;
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
font-weight: 600;
}
[data-theme="quiet"] .install-pane__copy:hover {
background: var(--color-ink-2);
color: var(--color-paper);
border-color: var(--color-ink-2);
}
[data-theme="quiet"] .install-pane__copy[data-state="copied"] {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
}
/* Quiet's install command bar — refined card surface, clean typography. */
[data-theme="quiet"] .install-pane {
background: var(--color-paper-2);
border-color: var(--color-rule);
}
[data-theme="quiet"] .install-pane__cmd {
background: var(--color-paper);
border-color: var(--color-rule);
}
[data-theme="quiet"] .install-pane__prompt {
color: var(--color-muted);
}
/* The "without/with" demo on Quiet — soft, monochrome panels. */
[data-theme="quiet"] .vs__panel[data-variant="hallmark"] {
border-left-color: var(--color-rule-2);
border-color: var(--color-rule);
}
/* No reveal animation on Quiet — the page is intentionally still. */
[data-theme="quiet"] .hero,
[data-theme="quiet"] .hero > * {
animation: none !important;
}
/* Quiet's hero never shows the clipped mockup — even if forced. */
[data-theme="quiet"] .hero--clipped .hero__mock { display: none; }
[data-theme="quiet"] .hero--clipped { grid-template-columns: 1fr; }
/* ───────────── BLOOM — atmospheric dark, warm bloom ─────────────
Suno-school: dark canvas with two soft radial colour blooms behind
the content, confident sans display, single warm accent on small
surfaces, pill CTAs. Reads like an AI-creative product page. */
html[data-theme="bloom"] {
background: var(--color-paper);
}
html[data-theme="bloom"] body {
background:
radial-gradient(ellipse 80% 60% at 90% 0%,
color-mix(in oklch, var(--color-accent) 28%, transparent) 0%,
transparent 55%),
radial-gradient(ellipse 70% 55% at 5% 95%,
color-mix(in oklch, var(--color-accent-2) 26%, transparent) 0%,
transparent 55%),
var(--color-paper);
background-attachment: fixed;
min-height: 100dvh;
}
[data-theme="bloom"] .hero__display,
[data-theme="bloom"] .hero__quote p,
[data-theme="bloom"] .hero__stat,
[data-theme="bloom"] .section__title,
[data-theme="bloom"] .foot__wordmark,
[data-theme="bloom"] .spec__name,
[data-theme="bloom"] .ex-card__name,
[data-theme="bloom"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
text-transform: none;
letter-spacing: -0.03em;
text-shadow: none;
}
[data-theme="bloom"] .hero__lede,
[data-theme="bloom"] .hero__letter-body,
[data-theme="bloom"] .spec__rule,
[data-theme="bloom"] .foot__tagline,
[data-theme="bloom"] .install-pane__next,
[data-theme="bloom"] .ex-card__brief {
font-family: var(--font-body);
font-style: normal;
color: var(--color-ink-2);
}
[data-theme="bloom"] .hero__salutation {
font-family: var(--font-display);
font-weight: 600;
font-size: var(--text-2xl);
letter-spacing: -0.025em;
font-style: normal;
}
/* Bloom's hero — centered, generous, with a glow behind the type. */
[data-theme="bloom"] .hero--marquee,
[data-theme="bloom"] .hero--clipped {
text-align: center;
align-items: center;
justify-items: center;
padding-block: var(--space-3xl) var(--space-2xl);
}
[data-theme="bloom"] .hero--marquee .hero__display,
[data-theme="bloom"] .hero--clipped .hero__display {
margin-inline: auto;
max-width: 22ch;
}
[data-theme="bloom"] .hero--marquee .hero__lede,
[data-theme="bloom"] .hero--clipped .hero__lede {
margin-inline: auto;
text-align: center;
max-width: 52ch;
}
[data-theme="bloom"] .hero__eyebrow {
margin-inline: auto;
justify-content: center;
}
[data-theme="bloom"] .hero--marquee .hero__cta,
[data-theme="bloom"] .hero--clipped .hero__cta {
margin-inline: auto;
justify-self: center;
}
[data-theme="bloom"] .hero--clipped .hero__mock { display: none; }
[data-theme="bloom"] .hero--clipped { grid-template-columns: 1fr; }
/* Bloom's section heads — also centered for atmosphere. */
[data-theme="bloom"] .section__head {
grid-template-columns: 1fr;
text-align: center;
border-bottom: 0;
padding-bottom: var(--space-md);
}
[data-theme="bloom"] .section-label {
justify-content: center;
}
[data-theme="bloom"] .section__title {
margin-inline: auto;
max-width: 26ch;
}
/* Bloom's banner — tinted dark glass over the canvas. */
[data-theme="bloom"] .banner {
background: color-mix(in oklch, var(--color-paper) 70%, transparent);
border-block-end-color: var(--color-rule);
}
[data-theme="bloom"] .banner__center {
font-family: var(--font-display);
font-weight: 500;
font-size: 0.875rem;
letter-spacing: -0.005em;
text-transform: none;
}
/* Bloom's install command bar — feels like a Suno input field. */
[data-theme="bloom"] .install-pane {
background: var(--color-paper-2);
border-color: var(--color-rule);
}
[data-theme="bloom"] .install-pane__cmd {
background: var(--color-paper-3);
border-color: var(--color-rule);
}
[data-theme="bloom"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
border-radius: 999px;
font-weight: 600;
text-transform: uppercase;
}
[data-theme="bloom"] .install-pane__copy:hover {
background: color-mix(in oklch, var(--color-accent) 88%, var(--color-paper));
color: var(--color-paper);
border-color: transparent;
}
/* Bloom's example rail tiles — elevated cards floating on the canvas. */
[data-theme="bloom"] .ex-card {
background: var(--color-paper-2);
border-color: var(--color-rule);
}
/* Without/With on Bloom — the slop panel still uses the white-AI
look against the dark canvas, which actually demonstrates "the AI
reaches for the same generic page even on a dark site." */
[data-theme="bloom"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper-2);
border-left-color: var(--color-accent);
border-color: var(--color-rule);
}
/* Bloom's reveal — fade only, no slide. The atmosphere does the work. */
[data-theme="bloom"] .reveal { transform: none; }
[data-theme="bloom"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.2) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 70ms);
}
/* ───────────── CORAL — modern-minimal · Stripe-not-Linear ─────────────
Inherits the Quiet "polished minimal" structure but with a warm-grey
paper and a coral accent on focus rings + small marks. */
[data-theme="coral"] .reveal,
[data-theme="coral"] .reveal.is-in,
[data-theme="coral"] .slot[data-populating] > * {
opacity: 1;
transform: none;
animation: none;
}
[data-theme="coral"] .hero__display,
[data-theme="coral"] .hero__quote p,
[data-theme="coral"] .hero__stat,
[data-theme="coral"] .section__title,
[data-theme="coral"] .foot__wordmark,
[data-theme="coral"] .spec__name,
[data-theme="coral"] .ex-card__name,
[data-theme="coral"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
letter-spacing: -0.025em;
}
[data-theme="coral"] .install-pane__copy {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
border-radius: 999px;
}
/* ───────────── VIOLET — modern-minimal · Linear voice ─────────────
Tighter typographic feel than Coral. Near-white paper, near-black
ink, single quiet violet accent on focus + small marks. */
[data-theme="violet"] .reveal,
[data-theme="violet"] .reveal.is-in,
[data-theme="violet"] .slot[data-populating] > * {
opacity: 1;
transform: none;
animation: none;
}
[data-theme="violet"] .hero__display,
[data-theme="violet"] .hero__quote p,
[data-theme="violet"] .hero__stat,
[data-theme="violet"] .section__title,
[data-theme="violet"] .foot__wordmark,
[data-theme="violet"] .spec__name,
[data-theme="violet"] .ex-card__name,
[data-theme="violet"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
font-style: normal;
letter-spacing: -0.035em;
}
[data-theme="violet"] .install-pane__copy {
background: var(--color-ink);
color: var(--color-paper);
border-color: var(--color-ink);
border-radius: 999px;
}
/* ───────────── AURORA — atmospheric · cool blue-green dark ─────────────
Two cool blooms behind the content (cyan top-right, teal-green
bottom-left). Sentient body for warmth. */
html[data-theme="aurora"] {
background: var(--color-paper);
}
html[data-theme="aurora"] body {
background:
radial-gradient(ellipse 75% 55% at 92% 0%,
color-mix(in oklch, var(--color-accent) 28%, transparent) 0%,
transparent 55%),
radial-gradient(ellipse 70% 60% at 5% 100%,
color-mix(in oklch, var(--color-accent-2) 30%, transparent) 0%,
transparent 60%),
var(--color-paper);
background-attachment: fixed;
min-height: 100dvh;
}
[data-theme="aurora"] .hero__display,
[data-theme="aurora"] .hero__quote p,
[data-theme="aurora"] .hero__stat,
[data-theme="aurora"] .section__title,
[data-theme="aurora"] .foot__wordmark,
[data-theme="aurora"] .spec__name,
[data-theme="aurora"] .ex-card__name,
[data-theme="aurora"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
letter-spacing: -0.03em;
}
[data-theme="aurora"] .hero__lede,
[data-theme="aurora"] .install-pane__next,
[data-theme="aurora"] .ex-card__brief {
font-family: var(--font-body);
font-style: normal;
color: var(--color-ink-2);
}
[data-theme="aurora"] .banner {
background: color-mix(in oklch, var(--color-paper) 68%, transparent);
border-block-end-color: var(--color-rule);
}
[data-theme="aurora"] .reveal { transform: none; }
[data-theme="aurora"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.2) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 70ms);
}
[data-theme="aurora"] .ex-card,
[data-theme="aurora"] .install-pane,
[data-theme="aurora"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper-2);
}
[data-theme="aurora"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
border-radius: 999px;
}
/* ───────────── HALO — atmospheric · hero-only amber bloom ─────────────
The bloom is a single moment near the top. Below the hero the page
is content-led on charcoal — less Suno, more "tool you actually
work in." Implemented as a fixed-position pseudo-element clipped
to the top ~80vh. */
html[data-theme="halo"] {
background: var(--color-paper);
}
html[data-theme="halo"] body {
position: relative;
background: var(--color-paper);
min-height: 100dvh;
}
html[data-theme="halo"] body::before {
content: "";
position: fixed;
inset: 0 0 auto 0;
height: 80vh;
pointer-events: none;
z-index: 0;
background:
radial-gradient(ellipse 60% 80% at 70% 0%,
color-mix(in oklch, var(--color-accent) 22%, transparent) 0%,
transparent 60%);
opacity: 1;
}
html[data-theme="halo"] .banner,
html[data-theme="halo"] main,
html[data-theme="halo"] .easter,
html[data-theme="halo"] aside {
position: relative;
z-index: 1;
}
[data-theme="halo"] .hero__display,
[data-theme="halo"] .hero__quote p,
[data-theme="halo"] .hero__stat,
[data-theme="halo"] .section__title,
[data-theme="halo"] .foot__wordmark,
[data-theme="halo"] .spec__name,
[data-theme="halo"] .ex-card__name,
[data-theme="halo"] .harness__name {
font-family: var(--font-display);
font-weight: 600;
letter-spacing: -0.025em;
}
[data-theme="halo"] .banner {
background: color-mix(in oklch, var(--color-paper) 72%, transparent);
border-block-end-color: var(--color-rule);
}
[data-theme="halo"] .ex-card,
[data-theme="halo"] .install-pane,
[data-theme="halo"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper-2);
}
[data-theme="halo"] .reveal { transform: none; }
[data-theme="halo"] .reveal.is-in {
animation: reveal-fade calc(var(--dur-long) * 1.1) var(--ease-out) forwards;
animation-delay: calc(var(--i, 0) * 60ms);
}
/* ───────────── PLUME — playful · warm cream + tinted bands ─────────────
Alternating section backgrounds (paper vs paper-2), hover-lift on
cards, soft drop shadows, friendly motion. Closer to actual playful
than Pastel's post-Linear-soft. */
[data-theme="plume"] .page > .section:nth-child(even) {
background: var(--color-paper-2);
margin-inline: calc(-1 * var(--page-gutter));
padding-inline: var(--page-gutter);
padding-block: var(--space-2xl);
border-radius: 0;
}
[data-theme="plume"] .hero__display,
[data-theme="plume"] .hero__quote p,
[data-theme="plume"] .hero__stat,
[data-theme="plume"] .section__title,
[data-theme="plume"] .foot__wordmark,
[data-theme="plume"] .spec__name,
[data-theme="plume"] .ex-card__name,
[data-theme="plume"] .harness__name {
font-family: var(--font-display);
font-weight: 700;
letter-spacing: -0.025em;
}
[data-theme="plume"] .hero__lede,
[data-theme="plume"] .ex-card__brief,
[data-theme="plume"] .install-pane__next,
[data-theme="plume"] .spec__rule,
[data-theme="plume"] .foot__tagline {
font-family: var(--font-body);
font-style: normal;
}
[data-theme="plume"] .ex-card,
[data-theme="plume"] .install-pane,
[data-theme="plume"] .vs__panel[data-variant="hallmark"] {
background: var(--color-paper);
border-color: var(--color-rule-2);
}
@media (hover: hover) and (pointer: fine) {
[data-theme="plume"] .ex-card {
transition: transform 200ms var(--ease-out),
box-shadow 200ms var(--ease-out),
border-color 120ms var(--ease-out);
}
[data-theme="plume"] .ex-card:hover {
transform: translateY(-3px);
box-shadow: 0 14px 32px -14px oklch(45% 0.10 18 / 0.22);
}
}
[data-theme="plume"] .install-pane__copy {
background: var(--color-accent);
color: var(--color-paper);
border-color: var(--color-accent);
border-radius: 999px;
}
/* ───────────── EXAMPLES RAIL — TILES ─────────────
Each tile in the horizontal scroll-snap rail. Cards inherit the
active theme's --radius-card, --rule-card, and --shadow-card so
switching themes restyles them along with everything else. */
.ex-card {
flex: 0 0 32rem;
scroll-snap-align: start;
display: grid;
grid-template-rows: auto auto;
text-decoration: none;
color: inherit;
background: var(--color-paper);
border: var(--rule-card, 1px) solid var(--color-rule);
border-radius: var(--radius-card, 0);
box-shadow: var(--shadow-card, none);
overflow: hidden;
position: relative;
transition: transform 120ms var(--ease-out),
border-color var(--dur-micro) var(--ease-out),
box-shadow var(--dur-short) var(--ease-out);
}
@media (max-width: 60rem) {
.ex-card { flex-basis: 22rem; }
}
@media (max-width: 36rem) {
.ex-card { flex-basis: 80vw; }
}
@media (hover: hover) and (pointer: fine) {
.ex-card:hover {
border-color: var(--color-ink);
transform: translateY(-2px);
}
}
.ex-card:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 3px;
}
.ex-card__thumb {
display: block;
width: 100%;
aspect-ratio: 16 / 10;
background: var(--color-paper-2);
border-block-end: var(--rule-card, 1px) solid var(--color-rule);
overflow: hidden;
font-size: 0;
}
.ex-card__thumb img {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: top left;
transition: transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
@media (hover: hover) and (pointer: fine) {
.ex-card:hover .ex-card__thumb img { transform: scale(1.025); }
}
@media (prefers-reduced-motion: reduce) {
.ex-card__thumb img { transition: none; }
.ex-card:hover .ex-card__thumb img { transform: none; }
}
.ex-card__meta {
display: grid;
grid-template-areas:
"num name open"
"num brief brief";
grid-template-columns: 3rem 1fr auto;
align-items: baseline;
gap: var(--space-2xs) var(--space-md);
padding: var(--space-md) var(--space-lg);
}
.ex-card__num {
grid-area: num;
font-family: var(--font-label);
font-size: var(--text-sm);
letter-spacing: var(--tracking-label);
color: var(--color-muted);
font-feature-settings: "tnum";
}
.ex-card__name {
grid-area: name;
font-family: var(--font-display);
font-weight: var(--display-weight, 500);
font-style: var(--display-style, normal);
font-size: var(--text-lg);
letter-spacing: var(--tracking-tight);
color: var(--color-ink);
line-height: 1.05;
font-optical-sizing: auto;
}
.ex-card__brief {
grid-area: brief;
font-family: var(--font-body);
font-size: var(--text-sm);
color: var(--color-ink-2);
line-height: var(--lh-snug);
margin-block-start: 0.25em;
}
.ex-card__open {
grid-area: open;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
color: var(--color-muted);
text-transform: uppercase;
transition: color var(--dur-micro) var(--ease-out),
transform var(--dur-short) var(--ease-out);
}
.ex-card:hover .ex-card__open {
color: var(--color-ink);
transform: translateX(2px);
}
[data-theme="riso"] .ex-card__name,
[data-theme="brutal"] .ex-card__name,
[data-theme="manifesto"] .ex-card__name,
[data-theme="sport"] .ex-card__name {
text-transform: uppercase;
}
[data-theme="riso"] .ex-card__name { text-transform: lowercase; }
/* — Study gallery card ————————————————————————————————
Each card pairs a video-shaped media tile with a structured DNA
panel below it. The video uses poster as the static fallback when
no <source> is supplied — drop one in to enable playback. The DNA
panel renders as an editorial table: mono numeral key, body value,
hairline divider per row. Theme-adaptive throughout. */
.study-card {
display: grid;
gap: var(--space-md);
background: var(--color-paper);
border: var(--rule-card, 1px) solid var(--color-rule);
border-radius: var(--radius-card, 0);
box-shadow: var(--shadow-card, none);
overflow: hidden;
transition: border-color var(--dur-micro) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.study-card:hover { border-color: var(--color-rule-2); }
}
.study-card[data-user-content] {
border-style: dashed;
}
.study-card__media {
position: relative;
aspect-ratio: 16 / 10;
background: var(--color-paper-2);
border-block-end: var(--rule-card, 1px) solid var(--color-rule);
overflow: hidden;
}
.study-card__img,
.study-card__video {
display: block;
width: 100%;
height: 100%;
object-fit: cover;
object-position: top left;
background: var(--color-paper-2);
}
.study-card__badge {
position: absolute;
bottom: var(--space-sm);
left: var(--space-sm);
padding: 0.25rem 0.55rem;
font-family: var(--font-label);
font-size: 0.625rem;
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-paper);
background: color-mix(in oklch, var(--color-ink) 85%, transparent);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
font-feature-settings: "tnum";
}
.study-card[data-user-content] .study-card__badge {
background: color-mix(in oklch, var(--color-accent) 80%, transparent);
}
[data-theme="riso"] .study-card__badge,
[data-theme="brutal"] .study-card__badge,
[data-theme="manifesto"] .study-card__badge,
[data-theme="sport"] .study-card__badge { text-transform: uppercase; }
[data-theme="riso"] .study-card__badge { text-transform: lowercase; }
/* DNA panel — structured 10-field key/value table. */
.study-card__dna {
list-style: none;
margin: 0;
padding: var(--space-md) var(--space-lg) var(--space-lg);
display: grid;
gap: 0;
}
.dna__row {
display: grid;
grid-template-columns: 8.5rem 1fr;
gap: var(--space-sm);
align-items: baseline;
padding-block: var(--space-sm);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.dna__row:last-child { border-block-end: 0; }
@media (max-width: 36rem) {
.dna__row { grid-template-columns: 1fr; gap: 0.15rem; padding-block: var(--space-xs); }
}
.dna__k {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
font-feature-settings: "tnum";
}
.dna__v {
font-family: var(--font-mono);
font-size: 0.8125rem;
line-height: 1.45;
color: var(--color-ink);
letter-spacing: 0;
}
.study-card[data-user-content] .dna__v {
color: var(--color-rule-2);
}
[data-theme="brutal"] .study-card,
[data-theme="manifesto"] .study-card { border-width: 2px; }
[data-theme="atelier"] .study-card,
[data-theme="salon"] .study-card {
border: 0;
background: transparent;
box-shadow: none;
border-block-end: var(--rule-hair) solid var(--color-rule);
border-radius: 0;
}
[data-theme="atelier"] .study-card__media,
[data-theme="salon"] .study-card__media {
border-block-end: 0;
}
/* Decision-trail popover — appears after 600ms hover/focus on a tile.
Shows the routing chain Hallmark used to arrive at this output.
Pure CSS — no JS, just transition-delay on the show transition. */
.ex-card__trail {
position: absolute;
top: var(--space-md);
left: var(--space-md);
right: var(--space-md);
padding: var(--space-md) var(--space-lg);
display: grid;
gap: 0.4rem;
background: var(--color-paper);
border: 1px solid var(--color-ink);
border-radius: var(--radius-input, 0);
box-shadow: 0 12px 28px -10px oklch(20% 0.02 60 / 0.28);
font-family: var(--font-mono);
font-size: 0.75rem;
line-height: 1.4;
color: var(--color-ink);
opacity: 0;
transform: translateY(6px);
pointer-events: none;
transition: opacity 200ms var(--ease-out),
transform 200ms var(--ease-out);
z-index: 5;
}
@media (hover: hover) and (pointer: fine) {
.ex-card:hover .ex-card__trail,
.ex-card:focus-visible .ex-card__trail {
opacity: 1;
transform: none;
transition-delay: 600ms;
}
}
.trail__row {
display: grid;
grid-template-columns: 4rem 1fr;
gap: var(--space-sm);
margin: 0;
align-items: baseline;
}
.trail__k {
font-family: var(--font-label);
font-size: 0.625rem;
letter-spacing: 0.14em;
text-transform: uppercase;
color: var(--color-muted);
}
.trail__v {
font-family: var(--font-mono);
font-size: 0.8125rem;
color: var(--color-ink);
letter-spacing: 0;
}
@media (prefers-reduced-motion: reduce) {
.ex-card__trail { transition-duration: 0ms; transition-delay: 600ms; }
}
@media (hover: none) {
/* On touch devices the popover doesn't trigger — hide it entirely
so it doesn't clip badly. The trail is a desktop affordance. */
.ex-card__trail { display: none; }
}
/* ───────────── FOUNDATION VIZ — illustrations ─────────────
Eight different visual demos, one per spec card. Each one prefers
real demonstration over decoration: real type for F/01, real space
ratio for F/02, real motion for F/04, real states for F/05. */
.spec__viz {
display: grid;
gap: var(--space-md);
margin-block-start: var(--space-sm);
}
/* F/01 Type — three real specimens, baseline-aligned. */
.spec__viz--type {
gap: var(--space-md);
}
.spec__viz-row {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: var(--space-md);
padding-block: var(--space-xs);
border-block-end: var(--rule-hair) solid var(--color-rule);
transition: padding-inline-start 220ms var(--ease-out);
}
.spec__viz-row > span {
flex: 0 1 auto;
color: var(--color-ink);
line-height: 1;
}
.spec__viz-row--display > span {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
font-size: clamp(2rem, 4vw, 2.75rem);
letter-spacing: -0.02em;
}
.spec__viz-row--body > span {
font-family: var(--font-body);
font-weight: 300;
font-size: 1.5rem;
letter-spacing: -0.005em;
}
.spec__viz-row--mono > span {
font-family: var(--font-mono);
font-weight: 500;
font-size: 1.2rem;
letter-spacing: 0;
}
@media (hover: hover) and (pointer: fine) {
.spec__viz-row:hover {
padding-inline-start: var(--space-md);
}
}
.spec__viz-tag {
font-family: var(--font-label);
font-style: normal;
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
flex: 0 0 auto;
}
/* F/02 Colour — accent dot in a paper field, then small swatches. */
.spec__viz--colour {
position: relative;
aspect-ratio: 4 / 1;
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
display: block;
padding: 0;
margin-block-end: var(--space-sm);
}
.spec__viz-dot {
position: absolute;
top: 28%;
left: 22%;
width: 14px;
height: 14px;
background: var(--color-accent);
border-radius: 50%;
}
.spec__viz-caption {
position: absolute;
right: var(--space-md);
bottom: var(--space-sm);
margin: 0;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
max-width: 22ch;
text-align: right;
line-height: 1.4;
}
.spec__viz-swatches {
height: 2rem;
}
/* F/03 Space — symmetric (greyed) vs asymmetric (ink). */
.spec__viz--space {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
height: 5rem;
align-items: end;
}
.spec__viz-grid {
display: flex;
align-items: end;
justify-content: center;
gap: 0.4rem;
height: 100%;
padding-inline: var(--space-sm);
border-block-end: var(--rule-hair) solid var(--color-rule);
}
.spec__viz-grid--bad .vg-bar { background: var(--color-rule-2); }
.spec__viz-grid--good { justify-content: flex-start; gap: 0.55rem; }
.spec__viz-grid--good .vg-bar { background: var(--color-ink); }
.vg-bar { width: 8px; }
.vg-bar--xl { height: 88%; }
.vg-bar--md { height: 56%; }
.vg-bar--sm { height: 30%; }
.spec__viz-pair {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
margin: 0;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
text-align: center;
}
/* F/04 Motion — a real fade+slide on click/hover. */
.spec__viz--motion {
display: grid;
grid-template-columns: auto 1fr;
gap: var(--space-md);
align-items: center;
}
.spec__viz-play {
appearance: none;
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.45rem 0.85rem;
background: transparent;
border: var(--rule-hair) solid var(--color-rule);
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-ink);
cursor: pointer;
min-height: 32px;
transition: border-color var(--dur-micro) var(--ease-out),
background-color var(--dur-micro) var(--ease-out);
}
.spec__viz-play:hover { border-color: var(--color-ink); }
.spec__viz-play:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 2px; }
.spec__viz-play-icon {
width: 0;
height: 0;
border-style: solid;
border-width: 5px 0 5px 8px;
border-color: transparent transparent transparent currentColor;
display: inline-block;
}
.spec__viz-stage {
position: relative;
height: 3rem;
background: var(--color-paper-2);
border: var(--rule-hair) dashed var(--color-rule);
overflow: hidden;
}
.spec__viz-block {
position: absolute;
top: 50%;
left: 12%;
width: 32px;
height: 32px;
background: var(--color-accent);
transform: translate(-12px, -50%);
opacity: 0;
}
.spec__viz-block.is-running {
animation: spec-motion-demo 420ms cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes spec-motion-demo {
from { transform: translate(-12px, -50%); opacity: 0; }
to { transform: translate(160px, -50%); opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
.spec__viz-block.is-running {
animation: none;
transform: translate(160px, -50%);
opacity: 1;
}
}
/* F/05 States — a real interactive button that reports its own state. */
.spec__viz--states {
display: grid;
gap: var(--space-sm);
}
.spec__viz-button {
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 44px;
padding: var(--space-sm) var(--space-lg);
font-family: var(--font-label);
font-size: var(--text-sm);
letter-spacing: 0.04em;
background: transparent;
border: var(--rule-fine) solid var(--color-ink);
color: var(--color-ink);
cursor: pointer;
transition: background-color 120ms var(--ease-out),
color 120ms var(--ease-out),
transform 80ms var(--ease-out);
align-self: start;
justify-self: start;
}
.spec__viz-button:hover { background: var(--color-paper-3); }
.spec__viz-button:active { transform: translateY(1px); }
.spec__viz-button:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
.spec__viz-button[data-state="loading"] {
background: var(--color-paper-2);
color: var(--color-muted);
cursor: wait;
}
.spec__viz-state-readout {
margin: 0;
font-family: var(--font-mono);
font-size: var(--text-xs);
letter-spacing: 0.02em;
color: var(--color-muted);
}
.spec__viz-state-readout::before {
content: "→ state: ";
color: var(--color-rule-2);
}
/* F/06 Responsive — three frames showing same content reflowing. */
.spec__viz--responsive {
display: grid;
grid-template-columns: 1fr 1.6fr 2.4fr;
gap: var(--space-md);
align-items: end;
height: 5rem;
}
.vg-frame {
display: flex;
flex-direction: column;
gap: 4px;
padding: 8px;
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
height: 100%;
justify-content: flex-start;
}
.vg-line {
height: 4px;
background: var(--color-rule-2);
border-radius: 1px;
width: 100%;
}
.vg-line--head {
background: var(--color-ink);
height: 6px;
width: 70%;
}
.vg-line--short { width: 40%; }
/* F/07 Copy — bad vs good column comparison. */
.spec__viz--copy {
display: grid;
grid-template-columns: 1fr 1fr;
gap: var(--space-md);
}
.spec__viz-copy-col {
display: grid;
gap: 0.4rem;
padding: var(--space-sm) var(--space-md);
border: var(--rule-hair) solid var(--color-rule);
background: var(--color-paper-2);
}
.spec__viz-copy-col[data-variant="good"] {
border-color: var(--color-rule-2);
background: var(--color-paper);
}
.spec__viz-copy-label {
margin: 0;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
.spec__viz-copy-col[data-variant="good"] .spec__viz-copy-label {
color: var(--color-accent);
}
.spec__viz-copy-line {
margin: 0;
font-family: var(--font-body);
font-size: var(--text-sm);
line-height: 1.4;
}
.spec__viz-copy-col[data-variant="bad"] .spec__viz-copy-line {
color: var(--color-muted);
text-decoration: line-through;
text-decoration-color: var(--color-rule-2);
text-decoration-thickness: 1px;
}
.spec__viz-copy-col[data-variant="good"] .spec__viz-copy-line {
color: var(--color-ink);
}
/* F/08 Anti-patterns — 9-tile mini-grid of the named tells. */
.spec__viz--tells {
display: grid;
grid-template-columns: repeat(9, 1fr);
gap: var(--space-2xs);
height: 4.5rem;
}
@media (max-width: 50rem) {
.spec__viz--tells {
grid-template-columns: repeat(5, 1fr);
grid-auto-rows: 1fr;
height: auto;
}
}
.vt {
display: block;
background: var(--color-paper-2);
border: var(--rule-hair) solid var(--color-rule);
position: relative;
overflow: hidden;
aspect-ratio: 1;
}
.vt--purple {
background: linear-gradient(135deg, #6b4de0, #e04db4);
}
.vt--gradtext {
background: var(--color-paper);
}
.vt--gradtext::after {
content: "Aa";
position: absolute;
inset: 0;
display: grid;
place-items: center;
font-family: "Inter", sans-serif;
font-weight: 800;
font-size: 1.2rem;
background: linear-gradient(90deg, #8a3fe0, #e03f8a);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.vt--icontile {
background:
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 0/100% 1px no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 33.33% 0/1px 100% no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 66.66% 0/1px 100% no-repeat,
var(--color-paper);
}
.vt--centered {
background: var(--color-paper);
}
.vt--centered::after {
content: "";
position: absolute;
inset: 25% 30%;
background:
linear-gradient(var(--color-ink), var(--color-ink)) 0 0/100% 30% no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 50%/100% 14% no-repeat,
linear-gradient(var(--color-accent), var(--color-accent)) 25% 80%/50% 14% no-repeat;
}
.vt--glass {
background: linear-gradient(135deg, rgba(99, 102, 241, 0.15), rgba(168, 85, 247, 0.15));
backdrop-filter: blur(2px);
border-color: rgba(255, 255, 255, 0.3);
}
.vt--pill {
background: var(--color-paper);
}
.vt--pill::after {
content: "";
position: absolute;
inset: 38% 18%;
background: linear-gradient(90deg, #6366f1, #a855f7);
border-radius: 999px;
}
.vt--bigfeat {
background:
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 30%/30% 4px no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 50%/50% 4px no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 50% 70%/40% 4px no-repeat,
var(--color-paper);
background-position: center 30%, center 50%, center 70%;
}
.vt--threecard {
background:
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 0 25%/30% 50% no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 35% 25%/30% 50% no-repeat,
linear-gradient(var(--color-rule-2), var(--color-rule-2)) 70% 25%/30% 50% no-repeat,
var(--color-paper);
}
.vt--moremore {
background: var(--color-ink);
color: var(--color-paper);
display: grid;
place-items: center;
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: 0.04em;
border-color: var(--color-ink);
}
@media (max-width: 50rem) {
.vt { aspect-ratio: 4 / 3; }
}
/* ───────────── SPORT — section title fix ─────────────
The italic display + tight tracking + uppercase + weight 700
produced cramped, almost-touching letterforms. Loosen the
tracking just for section titles, give a tiny pad for the
italic slant overhang, and bump line-height for breathing room. */
[data-theme="sport"] .section__title {
letter-spacing: -0.005em; /* loosened from -0.04em */
line-height: 1.12;
padding-inline-end: 0.15em; /* slack for italic slant overhang */
max-width: 26ch;
word-spacing: 0.04em;
}
[data-theme="sport"] .spec__name,
[data-theme="sport"] .tell__name {
letter-spacing: 0;
line-height: 1.05;
}
/* ───────────── SALON — true-centred section heads + fleuron ─────────────
Salon's existing grid override (in sections.css) was fine but the
eyebrow + title weren't perfectly stacked. Tighten the gap between
them, give the title a comfortable measure, and make the fleuron
read as a divider rather than a stray glyph. */
[data-theme="salon"] .section__head {
gap: var(--space-sm);
padding-block-end: var(--space-2xl);
}
[data-theme="salon"] .section-label {
display: inline-flex;
justify-content: center;
margin-inline: auto;
}
[data-theme="salon"] .section__title {
max-width: 32ch;
margin-inline: auto;
font-style: italic;
}
[data-theme="salon"] .section__head::after {
content: "❦";
display: block;
text-align: center;
color: var(--color-accent);
font-size: 1.1rem;
margin-block-start: var(--space-lg);
font-family: var(--font-serif);
line-height: 1;
opacity: 0.65;
}
/* Section 07 lead paragraph + outro — Salon centers all flowing prose */
[data-theme="salon"] .examples__intro,
[data-theme="salon"] .examples__outro {
text-align: center;
margin-inline: auto;
}
/* ───────────── NEWSPRINT — justified prose blocks ─────────────
Print discipline. Long-form copy gets justified + hyphenated where
the column is wide enough to render evenly. Headlines stay
left-aligned (only the prose justifies). */
[data-theme="newsprint"] .opening__sub,
[data-theme="newsprint"] .vs__caption,
[data-theme="newsprint"] .step__sub,
[data-theme="newsprint"] .foot__credits,
[data-theme="newsprint"] .foot__tagline {
text-align: justify;
hyphens: auto;
}
/* ───────────── BRUTAL / MANIFESTO — heavier card borders ─────────────
--rule-card is set to 2px on these themes (in tokens.css). The .tell
cards already use --rule-card. For other elements that have hairline
borders by default, give Brutal/Manifesto a touch more weight so the
theme's voice carries through. */
[data-theme="brutal"] .code,
[data-theme="manifesto"] .code {
border-width: 1.5px;
}