/* Nate Sage — warm cream and Madison blue */

:root {
  --bg: #efe8dc;            /* cream */
  --surface: #e5dccc;       /* cream, one step deeper */
  --ink: #1e2733;
  --muted: #4f5660;
  --madison: #2e4565;       /* muted Madison blue */
  --madison-deep: #24364f;
  --madison-ink: #f1ebe0;
  --madison-muted: #b9c4d2;
  --dusty: #cdd6df;         /* pale dusty blue */
  --print: #f8f3ea;         /* the mat around a print */
  --accent-text: #2e4565;   /* Madison as a text colour */

  --font: "Chivo", system-ui, sans-serif;

  --step-small: clamp(0.875rem, 0.84rem + 0.1vw, 0.9375rem);
  --step-body: clamp(1.0625rem, 1rem + 0.25vw, 1.1875rem);
  --step-lead: clamp(1.25rem, 1.05rem + 0.75vw, 1.625rem);
  --step-head: clamp(2.5rem, 1.4rem + 3.6vw, 4.5rem);
  --step-mega: clamp(2.75rem, 0.9rem + 4.8vw, 6.5rem);

  --margin: clamp(1.25rem, 2.2vw, 2rem);
  --gutter: clamp(1rem, 2vw, 2rem);
  --section: clamp(6.5rem, 11vw, 12rem);

  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);
  --ease-soft: cubic-bezier(0.33, 1, 0.68, 1);
  --t-press: 120ms;
  --t-hover: 180ms;
  --t-ui: 240ms;
}


/* Dark theme: warm charcoal with the same Madison blue. It follows the visitor's
   system setting unless they pick one with the toggle (saved as data-theme on <html>). */
:root[data-theme="dark"] {
  --bg: #191816; --surface: #23211e; --ink: #ece5d8; --muted: #a8a196;
  --madison: #3a5677; --madison-deep: #2d4560; --madison-ink: #f1ebe0; --madison-muted: #c3cddb;
  --dusty: #222831; --print: #2b2824; --accent-text: #9db4d1;
  color-scheme: dark;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #191816; --surface: #23211e; --ink: #ece5d8; --muted: #a8a196;
    --madison: #3a5677; --madison-deep: #2d4560; --madison-ink: #f1ebe0; --madison-muted: #c3cddb;
    --dusty: #222831; --print: #2b2824; --accent-text: #9db4d1;
    color-scheme: dark;
  }
}

/* ---------- reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; }
body { margin: 0; transition: background-color 300ms ease, color 300ms ease; background: var(--bg); color: var(--ink); font-family: var(--font); font-size: var(--step-body); font-weight: 400; line-height: 1.5; -webkit-font-smoothing: antialiased; }
h1, h2, h3, p, ul, ol, dl, dd, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
a { color: inherit; }
a, button { touch-action: manipulation; }
button, .button { -webkit-user-select: none; user-select: none; }
::selection { background: var(--madison); color: var(--madison-ink); }
:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.wrap { padding-inline: var(--margin); }
.small { font-size: var(--step-small); line-height: 1.5; letter-spacing: 0.005em; }
.lead { font-size: var(--step-lead); line-height: 1.4; letter-spacing: -0.012em; }
h1, h2, h3, .head { font-weight: 500; letter-spacing: -0.045em; line-height: 0.95; text-wrap: balance; }
.head { font-size: var(--step-head); }

.link { text-decoration: underline; text-decoration-color: transparent; text-underline-offset: 0.22em; text-decoration-thickness: 0.06em; transition: text-decoration-color var(--t-hover) ease; }
@media (hover: hover) and (pointer: fine) { .link:hover { text-decoration-color: currentColor; } }

.link-arrow { display: inline-flex; align-items: center; gap: 0.5em; font-weight: 500; text-decoration: none; padding-block: 0.5rem; }
.link-arrow::after { content: "→"; transition: transform var(--t-ui) var(--ease-out); }
@media (hover: hover) and (pointer: fine) { .link-arrow:hover::after { transform: translateX(4px); } }

.button { display: inline-flex; align-items: center; justify-content: center; min-height: 3rem; padding: 0 1.5rem; background: var(--madison); color: var(--madison-ink); font-weight: 500; font-size: 0.9375rem; letter-spacing: 0.01em; text-decoration: none; white-space: nowrap; transition: transform var(--t-press) var(--ease-out), background-color var(--t-hover) ease; }
.button:active { transform: scale(0.97); }
@media (hover: hover) and (pointer: fine) { .button:hover { background: var(--madison-deep); } }

/* ---------- hero: a window that opens to the edges, prints around it ---------- */
.hero {
  --wh: min(36vw, 100svh - 15rem);
  --ww: calc(var(--wh) * 1.3);
  --t: calc((100svh - var(--wh)) / 2);
  --b: var(--t);
  --s: calc(50vw - var(--ww) / 2);
  position: relative;
  height: 170svh;
}
.hero__stage { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.hero__pic { position: absolute; inset: 0; z-index: 1; background: #1a1030; clip-path: inset(var(--t) var(--s) var(--b)); }
/* While the window is small the photo is panned so Nate's face sits in it. */
.hero__pic img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 100%; transform: translateX(-6vw) scale(1.06); }

/* Prints: photos on a cream mat, laid around the window. They drift apart and fade as it opens. */
.hero__prints { position: absolute; inset: 0; z-index: 2; pointer-events: none; }
.print { position: absolute; padding: 0.4rem; background: var(--print); }
.print img { width: 100%; height: 100%; object-fit: cover; }
.print--nord { left: 6vw; top: 10svh; width: 20vw; aspect-ratio: 1320 / 924; }
.print--mirror { left: 20vw; top: max(34svh, 10svh + 14vw + 1rem); width: 9vw; aspect-ratio: 1; } /* always clear of the Nord print above */
.print--console { right: 6vw; top: 9svh; width: 13vw; aspect-ratio: 3 / 4; }
/* Anchored to the photo window's top-right corner (not the screen), so it can never meet the text above "Get in touch". */
.print--studio { left: calc(50vw + var(--ww) / 2 - 4vw); top: calc(var(--t) + 2svh); width: 8vw; aspect-ratio: 536 / 856; }

.nav { position: absolute; top: 0; left: 0; right: 0; display: flex; justify-content: space-between; align-items: baseline; padding: max(1.5rem, env(safe-area-inset-top)) var(--margin) 1.5rem; font-size: 0.9375rem; z-index: 3; }
.nav__mark { text-decoration: none; font-weight: 500; letter-spacing: -0.02em; }
.nav__links { display: flex; align-items: center; gap: 1.75rem; margin-right: 2.75rem; }
/* Nav links: the underline draws in from the left and leaves to the right. */
.nav__links .link { position: relative; text-decoration: none; }
.nav__links .link::after { content: ""; position: absolute; left: 0; right: 0; bottom: -0.2em; height: 1px; background: currentColor; transform: scaleX(0); transform-origin: right; transition: transform 320ms var(--ease-out); } /* taste-skill-ignore: a link underline that appears only on hover, not a divider */
@media (hover: hover) and (pointer: fine) { .nav__links .link:hover::after { transform: scaleX(1); transform-origin: left; } }
.nav__links .link:focus-visible::after { transform: scaleX(1); }
/* Light/dark toggle: fixed at the top right so it's always reachable. The icons cross-fade
   with a small turn when the theme changes. */
.theme-toggle { position: fixed; z-index: 70; top: max(0.85rem, env(safe-area-inset-top)); right: calc(var(--margin) - 0.4rem); width: 2.5rem; height: 2.5rem; display: grid; place-items: center; border-radius: 50%; background: var(--bg); color: var(--ink); transition: background-color 300ms ease, color 300ms ease, transform var(--t-press) var(--ease-out); }
.theme-toggle:active { transform: scale(0.92); }
.theme-toggle svg { grid-area: 1 / 1; width: 1.15rem; height: 1.15rem; transition: opacity 260ms ease, transform 420ms var(--ease-out); }
.theme-toggle .sun { opacity: 0; transform: rotate(-90deg) scale(0.6); }
:root[data-theme="dark"] .theme-toggle .sun { opacity: 1; transform: none; }
:root[data-theme="dark"] .theme-toggle .moon { opacity: 0; transform: rotate(90deg) scale(0.6); }
@media (hover: hover) and (pointer: fine) { .theme-toggle:hover { background: var(--surface); } }

.hero__copy, .hero__side { position: absolute; z-index: 3; }
.hero__copy { left: var(--margin); bottom: var(--b); width: calc(var(--s) - var(--margin) - var(--gutter)); }
.hero__title { font-size: clamp(2.5rem, 0.5rem + 3.7vw, 4.5rem); line-height: 0.95; }
.hero__name, .hero__role { display: block; }
.hero__name { overflow: hidden; padding-bottom: 0.06em; margin-bottom: -0.06em; }
.hero__line { display: block; }
.hero__role { overflow: hidden; height: 1.02em; margin-bottom: -0.07em; }
.hero__word { display: block; color: var(--accent-text); }
.hero__side { right: var(--margin); bottom: var(--b); width: calc(var(--s) - var(--margin) - var(--gutter)); max-width: 26ch; display: grid; gap: 1.5rem; justify-items: start; font-size: 1.0625rem; line-height: 1.5; }

@media (max-width: 63.99em) {
  /* Sized by width on phones, but capped by height so tablets and short windows still fit. */
  .hero { --ww: min(70vw, 42svh); --wh: calc(var(--ww) * 1.25); --t: 27svh; --b: calc(73svh - var(--wh)); --s: calc(50vw - var(--ww) / 2); height: 160svh; }
  .hero__pic img { object-position: 62% 0%; transform: translateY(-12svh) scale(1.06); }
  .nav__links { gap: 0.9rem; margin-right: 2.4rem; font-size: 0.875rem; }
  .hero__copy { top: calc(1.5rem + 3.5rem); bottom: auto; width: auto; right: var(--margin); }
  .hero__title { font-size: min(11vw, 7svh); }
  .hero__side { top: calc(100svh - var(--b) + 1rem); bottom: auto; left: var(--margin); width: auto; max-width: none; gap: 1rem; font-size: 1rem; }
  .hero__side .button { width: 100%; }
  .print { padding: 0.25rem; }
  .print--nord { left: auto; right: max(4vw, var(--s) - 12vw); top: max(22svh, 6rem + 2.1 * min(11vw, 7svh)); width: min(40vw, 30svh); } /* always below the headline */
  .print--studio { right: auto; left: max(4vw, var(--s) - 6vw); top: calc(var(--t) + var(--wh) * 0.52); width: min(20vw, 15svh); }
  .print--mirror, .print--console { display: none; }
}

/* ---------- about ---------- */
.about { position: relative; z-index: 3; margin-top: -65svh; background: var(--bg); padding-block: var(--section); }
.about__title { margin-bottom: clamp(3rem, 6vw, 5rem); }
.about__row { display: grid; grid-template-columns: calc(34vw - var(--margin)) minmax(0, 1fr); padding-right: max(0px, 10vw - var(--margin)); }
.about__facts { display: grid; gap: 1.25rem; align-content: start; max-width: 15rem; }
.about__facts dt { color: var(--muted); }
.about__facts dd { font-weight: 500; }
.about__story .lead { max-width: 52ch; }

.picker { margin-top: clamp(4.5rem, 9vw, 7.5rem); background: var(--dusty); padding: clamp(1.75rem, 3.5vw, 3rem); display: grid; grid-template-columns: calc(34vw - var(--margin) * 2 - clamp(1.75rem, 3.5vw, 3rem)) minmax(0, 1fr); column-gap: var(--gutter); }
.picker__head { display: grid; gap: 0.75rem; align-content: start; }
.picker__label { font-size: var(--step-lead); font-weight: 500; letter-spacing: -0.03em; line-height: 1.1; color: var(--accent-text); }
.picker__hint { color: var(--muted); font-size: var(--step-small); max-width: 22ch; }
.picker__body { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: 3rem; align-items: start; }
.picker__roles { display: flex; flex-wrap: wrap; gap: 0.4rem; }
.chip { min-height: 2.5rem; padding: 0 1rem; background: var(--bg); font-size: 0.875rem; font-weight: 500; letter-spacing: 0.005em; transition: background-color var(--t-hover) ease, color var(--t-hover) ease, transform var(--t-press) var(--ease-out); }
.chip:active { transform: scale(0.97); }
.chip[aria-pressed="true"] { background: var(--madison); color: var(--madison-ink); }
@media (hover: hover) and (pointer: fine) { .chip[aria-pressed="false"]:hover { background: var(--print); } }
.picker__result { display: grid; gap: 1rem; justify-items: start; }
.picker__count { font-weight: 500; }
.picker__list { display: grid; gap: 0.55rem; width: 100%; }
.picker__list:empty { display: none; }
.picker__list li { display: flex; justify-content: space-between; gap: 1rem; }
.picker__list li span:last-child { color: var(--muted); text-align: right; }
.picker__send { margin-top: 0.5rem; }
.picker__list li.is-new { animation: pick-in 260ms var(--ease-out) both; animation-delay: calc(var(--i, 0) * 40ms); }
@keyframes pick-in { from { opacity: 0; transform: translateY(6px); } }

@media (max-width: 63.99em) {
  .about__row { grid-template-columns: 1fr; padding-right: 0; row-gap: 2.5rem; }
  .about__story { order: -1; }
  .about__facts { grid-template-columns: 1fr 1fr; max-width: none; }
  .picker { grid-template-columns: 1fr; row-gap: 1.5rem; margin-inline: calc(var(--margin) * -1); }
  .picker__body { grid-template-columns: 1fr; row-gap: 1.75rem; }
  .picker__send { width: 100%; }
}

/* ---------- discography: one chapter per artist ---------- */
.disco__intro { padding-block: var(--section) clamp(2.5rem, 5vw, 4rem); }

.artist { --a-bg: var(--surface); --a-ink: var(--ink); --a-muted: var(--muted); background: var(--a-bg); color: var(--a-ink); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: calc(var(--gutter) * 2); padding: clamp(4rem, 7vw, 7rem) var(--margin); }
.js .artist { padding-block: 0; }
/* The artist's text starts at the top of its section and sticks near the top of the screen,
   so it travels down through the section beside the cover stage. */
.js .artist__side { top: 0; padding-top: 14svh; }
/* Section colours alternate: Madison blue, cream, dusty blue, Madison blue, cream. */
.artist--rhfg, .artist--aasmi { --a-bg: var(--madison); --a-ink: var(--madison-ink); --a-muted: var(--madison-muted); }
.artist--abner { --a-bg: var(--dusty); }
.artist__side { position: sticky; top: 12svh; align-self: start; display: grid; gap: 1.75rem; padding-right: 3vw; }
.artist__name { font-size: var(--step-mega); letter-spacing: -0.055em; line-height: 0.92; }
.artist__about { font-size: clamp(1.125rem, 1rem + 0.5vw, 1.375rem); line-height: 1.45; letter-spacing: -0.01em; max-width: 34ch; }
.artist__releases { display: grid; gap: 0.6rem; max-width: 22rem; }
.artist__releases li { display: flex; justify-content: space-between; gap: 1rem; }
.artist__releases span { color: var(--a-muted); }
/* The release whose cover is on screen is set in full ink; the others step back. */
.js .artist__releases.has-current li { opacity: 0.5; transition: opacity 360ms ease; }
.js .artist__releases.has-current li.is-current { opacity: 1; }

.artist__media { --cover: min(100%, 64svh); display: grid; gap: clamp(3rem, 6vw, 5rem); align-content: start; justify-items: start; }
.artist__media > .release, .artist__stage > .release { width: var(--cover); }
.artist__stage { display: grid; gap: clamp(3rem, 6vw, 5rem); justify-items: start; }

/* One release at a time: the stage pins for the artist's scroll track (one screen plus half a
   screen per extra release) and the release for the current stretch of that track takes the stage. Artists change
   with a hard cut: the next section's own colour simply scrolls in. */
.js .artist__media { display: block; height: calc(100svh + (var(--n, 1) - 1) * 60svh); overflow-x: clip; }
.js .artist__stage { position: sticky; top: 0; height: 100svh; display: grid; align-items: center; justify-items: start; gap: 0; }
.js .artist__stage > .release { grid-area: 1 / 1; opacity: 0; visibility: hidden; transform: translateY(28px) scale(0.985); filter: blur(4px); transition: opacity 460ms var(--ease-out), transform 620ms var(--ease-out), filter 460ms ease, visibility 0s linear 620ms; }
.js .artist__stage > .release.is-past { transform: translateY(-28px) scale(0.985); }
.js .artist__stage > .release.is-active { opacity: 1; visibility: visible; transform: none; filter: none; transition-delay: 0s; z-index: 1; }
/* The next release waits behind the current one, its cover peeking out at the top-right like the
   next card in a stack, so it's clear there's more before you scroll to it. */
.js .artist__stage > .release { transform-origin: top right; }
.js .artist__stage > .release.is-next { opacity: 0.32; visibility: visible; filter: none; transform: translate(5%, -5%) scale(0.92); transition-delay: 0s; z-index: 0; }
.js .artist__stage > .release.is-next figcaption { opacity: 0; visibility: hidden; }
.js .artist__stage > .release figcaption { transition: opacity 300ms ease; }
@media (hover: hover) and (pointer: fine) { .js .artist__stage > .release.is-next { cursor: pointer; } }
@media (prefers-reduced-motion: reduce) {
  .js .artist__stage > .release, .js .artist__stage > .release.is-past { transform: none; filter: none; transition: opacity 300ms ease, visibility 0s linear 300ms; }
  .js .artist__stage > .release.is-next { transform: translate(5%, -5%) scale(0.92); }
  .js .artist__stage > .release.is-active { transition-delay: 0s; }
}
.release { display: grid; gap: 1.1rem; }
.release__cover { overflow: hidden; background: color-mix(in srgb, var(--a-ink) 10%, transparent); }
.release__cover img { width: 100%; aspect-ratio: 1; object-fit: cover; transition: transform 900ms var(--ease-soft); }
@media (hover: hover) and (pointer: fine) { .release:hover .release__cover img { transform: scale(1.025); } }
.release figcaption { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 1rem; row-gap: 0.2rem; }
.release__title { font-size: var(--step-lead); font-weight: 500; letter-spacing: -0.02em; line-height: 1.2; }
.release__kind { grid-column: 1 / -1; color: var(--a-muted); font-size: var(--step-small); }
/* Listening links: sit on the title's line, to its right, in the section's own ink. */
.release__links { grid-column: 2; grid-row: 1; align-self: center; display: flex; gap: 0.15rem; margin-right: -0.4rem; }
.release__links a { display: grid; place-items: center; width: 2.25rem; height: 2.25rem; border-radius: 50%; color: var(--a-muted); transition: color var(--t-hover) ease, background-color var(--t-hover) ease, transform var(--t-press) var(--ease-out); }
.release__links a:active { transform: scale(0.92); }
.release__links svg { width: 1.1rem; height: 1.1rem; fill: currentColor; }
@media (hover: hover) and (pointer: fine) { .release__links a:hover { color: var(--a-ink); background: color-mix(in srgb, var(--a-ink) 8%, transparent); } }
.release__year:not(:empty)::before { content: " · "; }
em { font-style: italic; }
.release__roles { grid-column: 1 / -1; color: var(--a-muted); font-size: var(--step-small); }
.artist__pair { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gutter); align-items: start; width: min(100%, 80svh); }
.artist__pair .release__title { font-size: 1.125rem; }
.artist__photos { display: grid; grid-template-columns: 3fr 2fr; gap: var(--gutter); align-items: end; width: min(100%, 80svh); }
.photo { overflow: hidden; }
.photo img { width: 100%; object-fit: cover; }
.photo--wide img { aspect-ratio: 822 / 716; }
.photo--tall img { aspect-ratio: 3 / 4; }

@media (max-width: 63.99em) {
  .disco__intro { grid-template-columns: 1fr; row-gap: 1rem; }
  .artist { grid-template-columns: 1fr; row-gap: 3rem; }
  .artist__side { position: static; padding-right: 0; }
  .artist__name { font-size: 12vw; }
  .artist__media { --cover: 100%; }
  .js .artist { padding-top: clamp(4rem, 12vw, 6rem); row-gap: 0; }
  .js .artist__side { padding-top: 0; }
  .js .artist__media { --cover: min(100%, 52svh); }
  .js .artist__stage { justify-items: center; }
  .artist__pair, .artist__photos { width: 100%; }
  .artist__pair { gap: 0.75rem; }
  .artist__pair .release__title { font-size: 1rem; }
}

/* ---------- footer: the name first ---------- */
.footer { background: var(--bg); color: var(--ink); padding: clamp(2.5rem, 5vw, 4rem) var(--margin) max(var(--margin), env(safe-area-inset-bottom)); min-height: 70svh; display: grid; grid-template-rows: auto 1fr auto; }
.footer__mark { font-size: 18.5vw; font-weight: 500; letter-spacing: -0.065em; line-height: 0.8; white-space: nowrap; margin-left: -0.05em; color: var(--accent-text); }
.footer__mark .ch { display: inline-block; }
.footer__row { display: grid; grid-template-columns: 5fr 7fr; column-gap: var(--gutter); padding-top: 4.5rem; align-items: start; }
.footer__places { display: grid; gap: 0.4rem; font-size: var(--step-lead); letter-spacing: -0.012em; }
.footer__links { display: grid; gap: 0.5rem; font-size: 0.9375rem; }
.footer__legal { display: flex; justify-content: space-between; font-size: var(--step-small); padding-top: 6rem; color: var(--muted); }
@media (max-width: 63.99em) {
  .footer { min-height: 0; }
  .footer__row { grid-template-columns: 1fr; row-gap: 2.5rem; padding-top: 3rem; }
  .footer__legal { padding-top: 4rem; }
}


/* ---------- surface texture: a speaker-grille dot pattern ----------
   Each background surface carries a .tex layer as its first child, stacked beneath that
   surface's own content (isolation + z-index: -1), so the pattern never covers text or images.
   ::before is the faint, slowly breathing base; ::after is a stronger copy shown only in a
   soft circle around the cursor (its centre is set by main.js on the layer itself). */
:root { --dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Ccircle cx='4.5' cy='4.5' r='0.85' fill='%231e2733'/%3E%3C/svg%3E"); --tex-o: 0.032; --tex-spot-o: 0.09; }
:root[data-theme="dark"] { --dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Ccircle cx='4.5' cy='4.5' r='0.85' fill='%23f1ebe0'/%3E%3C/svg%3E"); --tex-o: 0.016; --tex-spot-o: 0.045; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Ccircle cx='4.5' cy='4.5' r='0.85' fill='%23f1ebe0'/%3E%3C/svg%3E"); --tex-o: 0.016; --tex-spot-o: 0.045; } }
.artist--rhfg, .artist--aasmi { --dots: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='9'%3E%3Ccircle cx='4.5' cy='4.5' r='0.85' fill='%23f1ebe0'/%3E%3C/svg%3E"); --tex-o: 0.02; --tex-spot-o: 0.052; }
.hero__stage, .about, .picker, .disco__intro, .artist, .footer { position: relative; isolation: isolate; }
.hero__stage { position: sticky; }
.tex { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; --mx: -999px; --my: -999px; }
.hero__stage > .tex { z-index: 0; }
.tex::before, .tex::after { content: ""; position: absolute; inset: 0; background-image: var(--dots); background-size: 9px 9px; }
.tex::before { opacity: var(--tex-o); }
/* A radial mask, not a visible gradient: it shapes the cursor's pool of light. */
.tex::after { opacity: 0; transition: opacity 700ms ease; -webkit-mask-image: radial-gradient(circle 260px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.5) 40%, transparent 100%); mask-image: radial-gradient(circle 260px at var(--mx) var(--my), #000 0%, rgba(0,0,0,0.5) 40%, transparent 100%); } /* taste-skill-ignore */
.tex.is-lit::after { opacity: var(--tex-spot-o); }
@media (prefers-reduced-motion: no-preference) {
  .tex::before { animation: tex-breathe 9s ease-in-out infinite alternate; }
}
@keyframes tex-breathe { from { opacity: calc(var(--tex-o) * 0.6); } to { opacity: var(--tex-o); } }

/* ---------- entrances (content stays visible without script) ---------- */
@media (prefers-reduced-motion: no-preference) {
  /* First load: the headline rises out of its lines, the window develops open, the prints settle.
     Fill mode is backwards so the scroll script owns transform and clip-path once each ends. */
  .js .hero__line { animation: line-rise 1000ms var(--ease-out) backwards; animation-delay: 120ms; }
  .js .hero__role .hero__line { animation-delay: 220ms; }
  .js .hero__side, .js .nav { animation: soft-in 900ms var(--ease-out) backwards; animation-delay: 420ms; }
  .js .hero__pic { animation: window-in 1300ms var(--ease-out) backwards; }
  .js .print { animation: print-in 1000ms var(--ease-out) backwards; animation-delay: calc(500ms + var(--n, 0) * 90ms); }
  .print--nord { --n: 0; } .print--console { --n: 1; } .print--mirror { --n: 2; } .print--studio { --n: 3; }
  .js .theme-toggle { animation: soft-in 900ms var(--ease-out) backwards; animation-delay: 600ms; }
  @keyframes line-rise { from { transform: translateY(105%); } }
  @keyframes soft-in { from { opacity: 0; transform: translateY(8px); } }
  @keyframes window-in { from { opacity: 0; clip-path: inset(calc(var(--t) + 3rem) calc(var(--s) + 3rem) calc(var(--b) + 3rem)); } }
  @keyframes print-in { from { opacity: 0; transform: translateY(14px) scale(0.97); } }
  /* Footer name: letters rise once, in a quick stagger, when the footer arrives. */
  .js [data-letters] .ch { transform: translateY(0.25em); opacity: 0; transition: transform 900ms var(--ease-out), opacity 700ms ease; transition-delay: calc(var(--c) * 40ms); }
  .js [data-letters].is-in .ch { transform: none; opacity: 1; }
  .js [data-reveal] { opacity: 0; transform: translateY(20px); transition: opacity 700ms var(--ease-out), transform 900ms var(--ease-out); transition-delay: calc(var(--i, 0) * 80ms); }
  .js [data-reveal].is-in { opacity: 1; transform: none; }
  /* Covers and photos open like a shutter from the bottom as they arrive. */
  .js [data-shutter] { clip-path: inset(18% 0 0 0); opacity: 0; transition: clip-path 600ms var(--ease-out), opacity 400ms ease; }
  .js [data-shutter] img { transform: scale(1.04); transition: transform 900ms var(--ease-soft); }
  .js [data-shutter].is-in { clip-path: inset(0); opacity: 1; }
  .js [data-shutter].is-in img { transform: none; }
  .hero__word.is-leaving { animation: word-out 360ms var(--ease-in-out) forwards; }
  .hero__word.is-entering { animation: word-in 520ms var(--ease-out) both; }
  @keyframes word-out { to { transform: translateY(-70%); opacity: 0; filter: blur(3px); } }
  @keyframes word-in { from { transform: translateY(70%); opacity: 0; filter: blur(3px); } }
}

/* ---------- reduced motion: no pin, the window stays a window ---------- */
@media (prefers-reduced-motion: reduce) {
  .hero { height: 100svh; }
  .about { margin-top: 0; }
}
