Files
hallmark/site/css/components.css
T
YoussefandClaude Opus 4.7 8bdb3ef4bd Three more themes — Studio, Pastel, Riso — for 2026 voice gaps
Twelve themes covered editorial, technical, soft, bold. Three voices were
missing: modern italic-display agency (Studio), post-Linear soft-tech (Pastel),
and analog/print rebellion (Riso). Each uses fonts from Google Fonts that
the existing twelve don't touch.

Studio. Instrument Serif italic display + Geist body + Geist Mono labels.
Cream-white paper, forest-green accent. Photographic hero archetype + index
footer — confident agency portfolio aesthetic. Inspiration: 14islands, Frame,
Mathieu Triay, Gretel.

Pastel. Geist sans display + body, Geist Mono labels. Soft lavender-cream
paper, low-chroma indigo accent (deliberately not slop purple). Letter hero
archetype + masthead footer — the post-Linear / Resend / Cron aesthetic.

Riso. Bricolage Grotesque 800-weight display, all lowercase + Newsreader
italic body. Warm peach paper with a subtle dot-grain overlay, riso cyan
+ yellow off-register text-shadow on display headlines for the
print-misregistration feel. Quote-Led hero + dense colophon footer.
Inspiration: Are.na, e-flux, Frieze, indie magazine sites.

Each theme adds a banner dot and an ARCHETYPES + COPY entry. The page is
now a 15-theme demonstration; THEMES count and supporting structure
updated throughout. Riso's body::before grain layer respects
prefers-reduced-data.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 12:57:46 +01:00

1369 lines
36 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: grid;
grid-template-columns: auto 1fr auto;
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);
}
.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;
}
/* The active theme name — the centre marker. Lives in the banner so the
page restructure registers as a deliberate event, not a passive repaint. */
.banner__center {
justify-self: center;
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-md);
letter-spacing: 0.04em;
text-transform: none;
color: var(--color-ink);
font-optical-sizing: auto;
transition: opacity var(--dur-short) var(--ease-out);
}
[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;
}
.banner__random {
appearance: none;
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
padding: 0;
background: transparent;
border: 1px solid var(--color-rule);
color: var(--color-muted);
cursor: pointer;
transition: color var(--dur-micro) var(--ease-out),
border-color var(--dur-micro) var(--ease-out),
transform 80ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.banner__random:hover { color: var(--color-ink); border-color: var(--color-ink); }
}
.banner__random:active { transform: rotate(180deg); transition-duration: 220ms; }
.banner__random:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
.banner__kbd {
display: inline-flex;
align-items: center;
justify-content: center;
margin-inline-start: 0.25rem;
padding: 0.1rem 0.4rem;
font-family: var(--font-label);
font-size: 0.625rem;
letter-spacing: 0.08em;
color: var(--color-muted);
border: 1px solid var(--color-rule);
border-radius: 3px;
min-width: 18px;
min-height: 18px;
}
@media (max-width: 60rem) {
.banner { grid-template-columns: auto 1fr auto; gap: var(--space-md); }
.banner__center { font-size: var(--text-sm); }
.banner__kbd { display: none; }
}
@media (max-width: 44rem) {
.banner__ver { display: none; }
.banner__center { display: none; }
.banner__picker { gap: 0.3rem; }
.banner__dot { width: 14px; height: 14px; }
.banner__sep { 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: 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);
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;
}
.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);
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);
}
/* — Tell card (gallery) ————————————————————————————— */
.tell {
flex: 0 0 18rem;
display: grid;
grid-template-rows: 13rem auto;
border: var(--rule-hair) solid var(--color-rule);
scroll-snap-align: start;
background: var(--color-paper);
}
.tell__viz {
position: relative;
overflow: hidden;
background: var(--color-paper-2);
}
.tell__meta {
padding: var(--space-md) var(--space-md) var(--space-lg);
display: grid;
gap: var(--space-xs);
border-top: var(--rule-hair) solid var(--color-rule);
}
.tell__name {
font-family: var(--font-display);
font-weight: var(--display-weight, 400);
font-style: var(--display-style, normal);
font-size: var(--text-lg);
color: var(--color-ink);
letter-spacing: var(--tracking-tight);
line-height: 1;
font-optical-sizing: auto;
}
[data-theme="manifesto"] .tell__name { text-transform: uppercase; }
.tell__why {
font-family: var(--font-serif);
font-style: italic;
font-weight: 400;
font-size: var(--text-sm);
color: var(--color-neutral);
max-width: 34ch;
line-height: var(--lh-snug);
}
[data-theme="brutal"] .tell__why,
[data-theme="manifesto"] .tell__why,
[data-theme="terminal"] .tell__why,
[data-theme="sport"] .tell__why,
[data-theme="almanac"] .tell__why {
font-style: normal;
font-family: var(--font-body);
}
/* — Tell visualisations (intentional anti-pattern demos) ————————— */
.viz-purple-hero {
position: absolute; inset: 0;
background: linear-gradient(135deg, #6b4de0 0%, #e04db4 60%, #e0904d 100%);
display: grid; place-items: center;
color: #fff;
font-family: "Inter", sans-serif;
font-size: 1rem; font-weight: 700;
letter-spacing: -0.02em;
}
.viz-purple-hero::after { content: "Unleash the future"; }
.viz-gradient-text {
position: absolute; inset: 0;
display: grid; place-items: center;
background: #fff;
}
.viz-gradient-text::after {
content: "Supercharged";
font-family: "Inter", sans-serif;
font-weight: 800; font-size: 2rem;
letter-spacing: -0.03em;
background: linear-gradient(90deg, #8a3fe0, #e03f8a);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
.viz-icon-tile {
position: absolute; inset: 0;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
gap: 0.5rem; padding: 0.75rem;
background: #fff;
}
.viz-icon-tile > div {
background: #f7f7f9;
border-radius: 8px; padding: 0.5rem;
display: grid; gap: 0.35rem;
align-content: start;
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.viz-icon-tile .icon {
width: 1.4rem; height: 1.4rem;
background: #e5e4ff; border-radius: 6px;
}
.viz-icon-tile .h { height: 0.45rem; background: #222; border-radius: 2px; width: 80%; }
.viz-icon-tile .t { height: 0.3rem; background: #d7d8df; border-radius: 2px; }
.viz-centered-hero {
position: absolute; inset: 0;
background: #fff;
display: grid; place-items: center; align-content: center;
gap: 0.5rem; text-align: center;
font-family: "Inter", sans-serif; padding: 1rem;
}
.viz-centered-hero .h { font-size: 1.3rem; font-weight: 800; color: #111; letter-spacing: -0.03em; }
.viz-centered-hero .s { font-size: 0.8rem; color: #666; max-width: 20ch; margin: 0 auto; }
.viz-centered-hero .c {
display: inline-block;
padding: 0.5rem 1rem;
background: linear-gradient(90deg, #6366f1, #a855f7);
color: #fff;
border-radius: 9999px;
font-size: 0.72rem; font-weight: 600;
margin-top: 0.25rem;
}
/* — Install block ————————————————————————————————————— */
.install { display: grid; gap: var(--space-sm); }
.install__head {
font-family: var(--font-label);
font-size: var(--text-xs);
letter-spacing: var(--tracking-label);
text-transform: uppercase;
color: var(--color-muted);
}
.install__body {
font-family: var(--font-mono);
font-size: var(--text-sm);
color: var(--color-ink);
padding: var(--space-md) 0;
border-top: var(--rule-hair) solid var(--color-rule);
border-bottom: var(--rule-hair) solid var(--color-rule);
line-height: 1.7;
white-space: pre-wrap;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--space-md);
}
.install__body .code__copy--block {
position: static;
transform: none;
flex-shrink: 0;
}
/* — 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 — italic Instrument Serif 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;
}
[data-theme="studio"] .banner__center {
font-style: italic;
letter-spacing: 0;
}
[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; }
/* ───────────── 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; }
}