/* 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); border-radius: var(--radius-pill, 0); 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: 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); } /* — Tell card (gallery) ————————————————————————————— */ .tell { flex: 0 0 18rem; display: grid; grid-template-rows: 13rem auto; border: var(--rule-card, 1px) solid var(--color-rule); border-radius: var(--radius-card, 0); scroll-snap-align: start; background: var(--color-paper); overflow: hidden; box-shadow: var(--shadow-card, none); } .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 — 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 — restraint as the design ───────────── Override every "expressive" treatment on the page when Quiet is active. No reveals, no per-theme display weight tricks, no shadow glows. System fonts inherit naturally; just make sure nothing yells. */ [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"] .tell__name { font-family: var(--font-display); font-weight: 500; font-style: normal; text-transform: none; letter-spacing: -0.015em; text-shadow: none; /* override Riso's off-register if a user toggled */ } [data-theme="quiet"] .hero__lede, [data-theme="quiet"] .hero__letter-body, [data-theme="quiet"] .spec__rule, [data-theme="quiet"] .tell__why, [data-theme="quiet"] .foot__tagline { font-family: var(--font-body); font-style: normal; color: var(--color-neutral); } [data-theme="quiet"] .hero__salutation { font-family: var(--font-body); font-style: normal; font-weight: 500; font-size: var(--text-xl); letter-spacing: 0; } [data-theme="quiet"] .hero__sign, [data-theme="quiet"] .hero__signoff { font-family: var(--font-body); font-style: normal; } [data-theme="quiet"] .banner__center { font-family: var(--font-display); font-weight: 500; font-size: var(--text-sm); letter-spacing: 0; text-transform: none; } [data-theme="quiet"] .banner { background: color-mix(in oklch, var(--color-paper) 92%, transparent); } /* 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; } /* ───────────── EXAMPLE GALLERY ───────────── Cards link to the six self-contained test pages under site/_tests/. The cards inherit the active theme's --radius-card, --rule-card, and --shadow-card so switching themes restyles them along with everything else. */ .examples__intro, .examples__outro { font-family: var(--font-serif); font-style: italic; font-size: var(--text-md); line-height: var(--lh-snug); color: var(--color-ink-2); max-width: 56ch; margin-block-end: var(--space-2xl); } .examples__outro { margin-block: var(--space-xl) 0; } .examples__intro code { font-family: var(--font-mono); font-style: normal; font-size: 0.875em; background: var(--color-paper-2); padding: 0.1em 0.4em; border-radius: var(--radius-input, 0); border: var(--rule-hair) solid var(--color-rule); color: var(--color-ink); } [data-theme="brutal"] .examples__intro, [data-theme="manifesto"] .examples__intro, [data-theme="terminal"] .examples__intro, [data-theme="sport"] .examples__intro, [data-theme="almanac"] .examples__intro, [data-theme="brutal"] .examples__outro, [data-theme="manifesto"] .examples__outro, [data-theme="terminal"] .examples__outro, [data-theme="sport"] .examples__outro, [data-theme="almanac"] .examples__outro { font-family: var(--font-body); font-style: normal; } .gallery { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--space-lg); } @media (max-width: 60rem) { .gallery { grid-template-columns: 1fr; } } .gallery__item { display: grid; grid-template-areas: "thumb thumb" "num name" "num shape" "num desc" "num open"; grid-template-columns: 4rem 1fr; grid-template-rows: auto repeat(4, auto); gap: 0 var(--space-md); padding: var(--space-lg); 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); transition: transform 100ms var(--ease-out), border-color var(--dur-micro) var(--ease-out), box-shadow var(--dur-short) var(--ease-out); position: relative; overflow: hidden; } @media (hover: hover) and (pointer: fine) { .gallery__item:hover { border-color: var(--color-ink); transform: translateY(-1px); } } .gallery__item:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 3px; } .gallery__thumb { grid-area: thumb; display: block; width: 100%; margin: calc(-1 * var(--space-lg)) calc(-1 * var(--space-lg)) var(--space-lg); border-block-end: var(--rule-card, 1px) solid var(--color-rule); background: var(--color-paper-2); overflow: hidden; position: relative; font-size: 0; /* kill any inline-element gap */ } .gallery__thumb img { display: block; width: 100%; height: auto; transition: transform 500ms cubic-bezier(0.2, 0.8, 0.2, 1); } @media (hover: hover) and (pointer: fine) { .gallery__item:hover .gallery__thumb img, .gallery__item:focus-visible .gallery__thumb img { transform: scale(1.025); } } @media (prefers-reduced-motion: reduce) { .gallery__thumb img { transition: none; } .gallery__item:hover .gallery__thumb img { transform: none; } } .gallery__num { grid-area: num; font-family: var(--font-label); font-size: var(--text-sm); letter-spacing: var(--tracking-label); color: var(--color-muted); align-self: start; font-feature-settings: "tnum"; } .gallery__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-xl); letter-spacing: var(--tracking-tight); color: var(--color-ink); line-height: 1.05; font-optical-sizing: auto; } .gallery__shape { grid-area: shape; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: 0.04em; color: var(--color-accent); margin-block-start: 0.4em; } .gallery__desc { grid-area: desc; font-family: var(--font-body); font-size: var(--text-sm); color: var(--color-ink-2); line-height: var(--lh-snug); margin-block-start: var(--space-sm); max-width: 36ch; } .gallery__open { grid-area: open; font-family: var(--font-label); font-size: var(--text-xs); letter-spacing: var(--tracking-label); color: var(--color-muted); margin-block-start: var(--space-md); align-self: end; justify-self: start; text-transform: uppercase; transition: color var(--dur-micro) var(--ease-out), transform var(--dur-short) var(--ease-out); } .gallery__item:hover .gallery__open { color: var(--color-ink); transform: translateX(2px); } [data-theme="riso"] .gallery__name, [data-theme="brutal"] .gallery__name, [data-theme="manifesto"] .gallery__name, [data-theme="sport"] .gallery__name { text-transform: uppercase; } [data-theme="riso"] .gallery__name { text-transform: lowercase; } /* ───────────── 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; } /* ───────────── 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, [data-theme="brutal"] .install__body, [data-theme="manifesto"] .install__body { border-width: 1.5px; } [data-theme="brutal"] .install__body, [data-theme="manifesto"] .install__body { border-color: var(--color-ink); }