/* =====================================================================
   Novera Records. styles.css

   Black glass with a gold thread. Every colour, size and easing on the page
   comes from the tokens below; no component hard-codes one.

   SHAPE LOCK. Three radii and nothing else:
     pills  (--radius-pill)  buttons, tags, the nav, the toast
     cards  (--radius-card)  glass panels, release cards, journal entries, covers
     inputs (--radius-input) the partner badges (the text fields are flat, on a rule)
   The card core is concentric: --radius-core = card minus its padding.

   Every animation carries a one-line comment answering the four questions:
   should it move at all, why, which curve, how fast.
   ===================================================================== */

@layer reset, tokens, base, components, sections, motion, utilities;

/* Type lives here, not on a third-party server: no request leaves the site.
   Three faces on Caelure's model, chosen by the label in September 2026:
   Nohemi for display, at 600 alone (the label asked for less weight than
   Caelure's 800), Hanken Grotesk for text (one variable file, 100 to 900),
   DM Mono for data, the nav and the buttons. Instrument Serif stays in its
   italic alone, the accent voice: the claim under the wordmark, the second
   half of the statement, the numerals of the process, the roles of the
   partners. 88 KB in all. */
@font-face { font-family: "Nohemi"; font-style: normal; font-weight: 600; font-display: swap; src: url("assets/fonts/nohemi-600.woff2") format("woff2"); }
@font-face { font-family: "Hanken Grotesk"; font-style: normal; font-weight: 100 900; font-display: swap; src: url("assets/fonts/hanken-grotesk.woff2") format("woff2"); }
@font-face { font-family: "DM Mono"; font-style: normal; font-weight: 400; font-display: swap; src: url("assets/fonts/dm-mono-400.woff2") format("woff2"); }
@font-face { font-family: "Instrument Serif"; font-style: italic; font-weight: 400; font-display: swap; src: url("assets/fonts/instrument-serif-italic.woff2") format("woff2"); }

/* ---------------------------------------------------------------- tokens */
@layer tokens {
  :root {
    color-scheme: dark;

    /* surfaces */
    --bg-0: #0b0b0d;
    --bg-1: #111114;
    --bg-2: #17171b;
    /* glass */
    --glass-fill: rgb(255 255 255 / 0.04);
    --glass-fill-strong: rgb(255 255 255 / 0.07);
    --glass-edge: rgb(255 255 255 / 0.10);
    --glass-edge-inner: rgb(255 255 255 / 0.06);
    --glass-highlight: rgb(255 255 255 / 0.18);
    /* the hairlines between rows, the same white as the glass edge */
    --line: var(--glass-edge);
    /* text */
    --fg-0: #f2efe9;
    --fg-1: #b9b5ad;
    /* the brief's #7c7872 reads at 3.3:1 on the glass panels and 4.3:1 on
       --bg-1; the brief's own floor is 4.5:1 and says to raise, never to
       lower the requirement. Measured on rendered pixels. */
    --fg-2: #a09c95;
    /* accent: the label's gold, calibrated */
    --gold: #d9b86a;
    --gold-deep: #b8953f;
    --gold-soft: rgb(217 184 106 / 0.14);
    /* semantic */
    --ok: #8fbf9a;
    --error: #d98a7a;
    --focus: #e8cf8d;

    /* type */
    --serif: "Instrument Serif", "Times New Roman", Georgia, serif; /* italic only: the accents */
    --sans: "Hanken Grotesk", system-ui, -apple-system, "Segoe UI", sans-serif;
    --mono: "DM Mono", ui-monospace, "SF Mono", Menlo, monospace;
    --display: "Nohemi", "Arial Black", var(--sans);
    --step--1: clamp(0.83rem, 0.79rem + 0.2vw, 0.94rem);
    --step-0:  clamp(1rem, 0.95rem + 0.25vw, 1.125rem);
    --step-1:  clamp(1.25rem, 1.15rem + 0.5vw, 1.5rem);
    --step-2:  clamp(1.6rem, 1.4rem + 1vw, 2.1rem);
    --step-3:  clamp(2.1rem, 1.7rem + 2vw, 3.2rem);
    --step-4:  clamp(2.8rem, 2rem + 4vw, 5rem);
    --step-5:  clamp(3.6rem, 2.4rem + 6.5vw, 7.5rem);

    /* space, shape, layout */
    --space-1: 0.5rem;  --space-2: 1rem;   --space-3: 1.5rem; --space-4: 2.5rem;
    --space-5: 4rem;    --space-6: 6rem;   --space-7: 8rem;   --space-8: 12rem;
    --radius-pill: 999px;
    --radius-card: 1.5rem;
    --radius-core: calc(var(--radius-card) - 0.5rem);
    --radius-input: 0.75rem;
    --container: 1360px;
    --gutter: clamp(1rem, 4vw, 3rem);
    --nav-h: 56px;

    /* motion */
    --ease-out:     cubic-bezier(0.23, 1, 0.32, 1);
    --ease-in-out:  cubic-bezier(0.77, 0, 0.175, 1);
    --ease-drawer:  cubic-bezier(0.32, 0.72, 0, 1);
    --ease-rise:    cubic-bezier(0.2, 0.7, 0.2, 1);  /* the rises on scroll, the same curve as Ventor's */
    --dur-press: 140ms;
    --dur-hover: 180ms;
    --dur-ui: 220ms;
    --dur-panel: 420ms;
    --stagger: 55ms;
  }
}

/* ----------------------------------------------------------------- reset */
@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; }
  body { margin: 0; }
  h1, h2, h3, h4, p, figure, ul, ol { margin: 0; }
  ul, ol { padding: 0; list-style: none; }
  img, svg { display: block; max-width: 100%; }
  img { height: auto; }
  button, input, textarea { font: inherit; color: inherit; }
  button { background: none; border: 0; padding: 0; cursor: pointer; }
  a { color: inherit; text-decoration: none; }
  [hidden] { display: none !important; }
}

/* ------------------------------------------------------------------ base */
@layer base {
  html { scroll-behavior: smooth; scroll-padding-top: calc(var(--nav-h) + 2.5rem); }
  html.is-locked { overflow: hidden; scrollbar-gutter: stable; }
  body {
    background: var(--bg-0);
    color: var(--fg-1);
    font: 400 var(--step-0) / 1.6 var(--sans);
    font-feature-settings: "kern", "liga", "onum";
    -webkit-font-smoothing: antialiased;
    overflow-x: clip;
  }
  h1, h2, h3 {
    font-family: var(--display);
    font-weight: 600;
    color: var(--fg-0);
    letter-spacing: -0.02em;
    line-height: 1.05;
    font-feature-settings: "kern", "liga";
    text-wrap: balance;
  }
  h2 { font-size: var(--step-3); text-transform: uppercase; letter-spacing: -0.01em; }
  h3 { font-size: var(--step-2); font-weight: 600; line-height: 1.15; }
  p { max-width: 62ch; text-wrap: pretty; }
  strong { font-weight: 500; color: var(--fg-0); }
  .mono { font-family: var(--mono); font-size: var(--step--1); font-feature-settings: "lnum", "tnum"; }
  ::selection { background: var(--gold); color: var(--bg-0); }
  :focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: 2px; }

  /* the page sits above the fixed background, below the grain */
  .page { position: relative; z-index: 1; }
  .container { width: calc(100% - 2 * var(--gutter)); max-width: var(--container); margin-inline: auto; }

  /* ---- fixed layers ---- */
  .bg { position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; background: var(--bg-0); }
  .bg-poster { position: absolute; inset: 0; background: url("assets/bg-poster.webp") center / cover no-repeat; }
  .bg-canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; }
  /* why: the live field replaces its own poster; enter -> ease-out; 900ms, the brief's step 1 */
  .bg.is-live .bg-canvas { opacity: 1; transition: opacity 900ms var(--ease-out); }
  /* the aurora exists only when WebGL does not: two gold and grey-violet
     lights on one layer, moved by transform alone */
  .bg-aurora { display: none; position: absolute; inset: -25%; }
  .bg.is-aurora .bg-poster, .bg.is-aurora .bg-canvas { display: none; }
  .bg.is-aurora .bg-aurora {
    display: block;
    background:
      radial-gradient(38% 42% at 72% 28%, rgb(217 184 106 / 0.12) 0%, transparent 70%),
      radial-gradient(34% 40% at 24% 68%, rgb(120 110 150 / 0.10) 0%, transparent 72%),
      radial-gradient(30% 30% at 58% 78%, rgb(217 184 106 / 0.07) 0%, transparent 70%);
    /* why: the fallback still breathes; constant motion -> ease-in-out loop; 50s, never noticed as a loop */
    animation: aurora 50s var(--ease-in-out) infinite alternate;
    will-change: transform;
  }
  @keyframes aurora { from { transform: translate3d(-4%, 2%, 0); } to { transform: translate3d(4%, -3%, 0); } }

  .grain {
    position: fixed; inset: 0; z-index: 50; pointer-events: none; opacity: 0.035;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  }

  /* the gold thread along the top: how far down the page you are. It follows
     the scroll timeline itself, so there is no script and no scroll listener;
     a browser without scroll-driven animations simply does not show it */
  .progress { position: fixed; top: 0; left: 0; z-index: 45; width: 100%; height: 2px; background: var(--gold); transform-origin: 0 50%; transform: scaleX(0); pointer-events: none; }
  @supports (animation-timeline: scroll()) { .progress { animation: progress linear both; animation-timeline: scroll(root); } }
  @keyframes progress { from { transform: scaleX(0); } to { transform: scaleX(1); } }

  .skip {
    position: fixed; top: 0.75rem; left: 0.75rem; z-index: 60;
    padding: 0.7rem 1rem; border-radius: var(--radius-pill);
    background: var(--fg-0); color: var(--bg-0); font-weight: 500;
    transform: translateY(-200%);
    /* why: a keyboard action, so it is quick; enter -> ease-out; 160ms */
    transition: transform 160ms var(--ease-out);
  }
  .skip:focus { transform: none; }
}

/* ------------------------------------------------------------ components */
@layer components {

  /* ---- glass: the one recipe. --r lets the nav be a pill without a variant ---- */
  .glass {
    --r: var(--radius-card);
    position: relative;
    isolation: isolate;
    border-radius: var(--r);
    background:
      linear-gradient(135deg, rgb(255 255 255 / 0.09), rgb(255 255 255 / 0.02)),
      var(--glass-fill);
    border: 1px solid var(--glass-edge);
    box-shadow:
      inset 0 1px 0 var(--glass-highlight),
      inset 0 -1px 0 rgb(255 255 255 / 0.03),
      0 24px 80px rgb(0 0 0 / 0.45);
    backdrop-filter: blur(18px) saturate(160%);
    -webkit-backdrop-filter: blur(18px) saturate(160%);
  }
  /* inner concentric hairline: the double bezel */
  .glass::after {
    content: ""; position: absolute; inset: 1px;
    border-radius: calc(var(--r) - 1px);
    border: 1px solid var(--glass-edge-inner);
    pointer-events: none;
  }
  /* top-left specular highlight, very faint */
  .glass::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    border-radius: inherit;
    background: radial-gradient(120% 60% at 15% 0%, rgb(255 255 255 / 0.10), transparent 55%);
    pointer-events: none;
  }
  @media (prefers-reduced-transparency: reduce) {
    .glass { backdrop-filter: none; -webkit-backdrop-filter: none; background: var(--bg-2); }
  }
  @supports not (backdrop-filter: blur(1px)) {
    .glass { background: rgb(23 23 27 / 0.96); }
  }

  /* ---- buttons ---- */
  .btn {
    display: inline-flex; align-items: center; gap: 0.75rem;
    min-height: 48px; padding: 0.85rem 0.6rem 0.85rem 1.4rem;
    border-radius: var(--radius-pill);
    background: var(--gold); color: var(--bg-0);
    font-family: var(--mono); font-size: 0.78rem; font-weight: 400; letter-spacing: 0.1em; text-transform: uppercase; line-height: 1;
    white-space: nowrap;
    /* why: the press must be felt; enter/response -> ease-out; 140ms press, 180ms hover */
    transition: transform var(--dur-press) var(--ease-out), background-color var(--dur-hover) ease, color var(--dur-hover) ease;
  }
  .btn-arrow {
    display: grid; place-items: center; width: 28px; height: 28px;
    border-radius: var(--radius-pill); background: rgb(0 0 0 / 0.12);
    /* why: the arrow leans where the button goes; response -> ease-out; 180ms */
    transition: transform var(--dur-hover) var(--ease-out);
  }
  .btn svg, .icon { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
  .btn:active { transform: scale(0.97); }
  .btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; border-radius: var(--radius-pill); }
  .btn--ghost { background: transparent; color: var(--fg-0); border: 1px solid var(--glass-edge); padding-right: 1.4rem; }
  .btn--small { min-height: 40px; padding: 0.6rem 0.4rem 0.6rem 1rem; font-size: 0.72rem; }
  .btn--small .btn-arrow { width: 24px; height: 24px; }
  .btn--icon { width: 44px; height: 44px; min-height: 0; padding: 0; justify-content: center; background: transparent; color: var(--fg-1); border: 1px solid var(--glass-edge); }
  @media (hover: hover) and (pointer: fine) {
    .btn:hover { transform: translateY(-1px); }
    .btn:hover .btn-arrow { transform: translate(2px, -1px); }
    .btn--ghost:hover { background: var(--glass-fill-strong); }
    .btn--icon:hover { color: var(--fg-0); background: var(--glass-fill-strong); }
  }

  /* ---- text links: the underline draws left to right, retreats faster ---- */
  .link {
    color: var(--fg-0);
    background-image: linear-gradient(var(--gold), var(--gold));
    background-size: 0% 1px; background-repeat: no-repeat; background-position: left calc(100% - 1px);
    padding-bottom: 2px;
    /* why: shows the link heard the pointer; retreat -> ease-out 120ms, draw 180ms */
    transition: background-size 120ms var(--ease-out), color var(--dur-hover) ease;
  }
  .link:active { transform: scale(0.98); }
  @media (hover: hover) and (pointer: fine) {
    .link:hover { background-size: 100% 1px; transition-duration: 180ms; }
  }
  .link--quiet { color: var(--fg-1); }
  @media (hover: hover) and (pointer: fine) { .link--quiet:hover { color: var(--fg-0); } }

  /* ---- tags ---- */
  .tag {
    display: inline-flex; align-items: center; min-height: 28px; padding: 0.25rem 0.7rem;
    border-radius: var(--radius-pill); background: var(--glass-fill); border: 1px solid var(--glass-edge);
    font-family: var(--mono); font-size: var(--step--1); color: var(--fg-1); font-feature-settings: "lnum";
  }

  /* ---- inputs: flat, on a rule that lights with focus ---- */
  .field { display: grid; gap: 0.45rem; }
  .field label { color: var(--fg-0); font-size: var(--step--1); font-weight: 500; }
  .field input, .field textarea {
    width: 100%; min-height: 52px; padding: 0.85rem 1rem 0.75rem;
    border: 0; border-bottom: 2px solid rgb(242 239 233 / 0.35); border-radius: 0;
    background: var(--bg-2); color: var(--fg-0);
    /* why: the rule lights when the field has focus; response -> ease-out; 180ms */
    transition: border-color var(--dur-hover) var(--ease-out), background-color var(--dur-hover) var(--ease-out);
  }
  .field textarea { min-height: 120px; resize: vertical; }
  .field input:focus-visible, .field textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-bottom-color: var(--gold); }
  .field input[aria-invalid="true"], .field textarea[aria-invalid="true"] { border-bottom-color: var(--error); }
  .hint { font-size: var(--step--1); color: var(--fg-2); }
  .error { font-size: var(--step--1); color: var(--error); min-height: 1.3em; }
  .error:empty { display: none; }
  .trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

  /* ---- release card: hairline shell around a flat core ---- */
  .card {
    position: relative; padding: 6px; border-radius: var(--radius-card);
    background: var(--glass-fill); border: 1px solid var(--glass-edge);
    /* why: the card answers the press; response -> ease-out; 140ms */
    transition: transform var(--dur-press) var(--ease-out), border-color var(--dur-hover) ease;
  }
  .card:active { transform: scale(0.98); }
  .card-core { border-radius: var(--radius-core); background: var(--bg-2); overflow: hidden; }
  .card-cover { position: relative; aspect-ratio: 1; overflow: hidden; }
  .card-cover img { width: 100%; height: 100%; object-fit: cover; }
  .card-lift { /* why: the cover lifts under the pointer; response -> ease-out; 180ms */ transition: transform var(--dur-hover) var(--ease-out); }
  .card-sheen {
    position: absolute; inset: 0; pointer-events: none; opacity: 0;
    background: linear-gradient(135deg, rgb(255 255 255 / 0.12), rgb(255 255 255 / 0.02) 45%, transparent 70%);
    /* why: a glass sheen appears, not a permanent blur; response -> ease-out; 180ms */
    transition: opacity var(--dur-hover) var(--ease-out);
  }
  .card-shadow {
    content: ""; position: absolute; inset: 8% 6% -6% 6%; z-index: -1; border-radius: var(--radius-card);
    box-shadow: 0 24px 60px rgb(0 0 0 / 0.5); opacity: 0;
    /* why: the shadow deepens with the lift, on its own layer so box-shadow never animates; 180ms */
    transition: opacity var(--dur-hover) var(--ease-out);
  }
  .card-body { padding: 1rem 1rem 1.1rem; display: grid; gap: 0.25rem; }
  .card-title { font-family: var(--display); font-size: var(--step-1); color: var(--fg-0); font-weight: 600; letter-spacing: -0.01em; line-height: 1.15; }
  .card-title span { background-image: linear-gradient(var(--gold), var(--gold)); background-size: 0% 1px; background-repeat: no-repeat; background-position: left bottom; transition: background-size 120ms var(--ease-out); }
  .card-meta { display: flex; gap: 0.6rem; align-items: center; color: var(--fg-2); font-family: var(--mono); font-size: var(--step--1); }
  @media (hover: hover) and (pointer: fine) {
    .card:hover .card-lift { transform: translateY(-4px); }
    .card:hover .card-sheen, .card:hover .card-shadow { opacity: 1; }
    .card:hover .card-title span { background-size: 100% 1px; transition-duration: 180ms; }
  }

  /* ---- filter tabs: the active pill is a clipped copy of the list ---- */
  .tabs { position: relative; display: inline-flex; padding: 4px; border-radius: var(--radius-pill); background: var(--glass-fill); border: 1px solid var(--glass-edge); }
  .tabs-layer { display: flex; }
  .tabs-layer button, .tabs-active span { padding: 0.55rem 1rem; border-radius: var(--radius-pill); font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; color: var(--fg-1); }
  .tabs-layer button { /* why: the press; response -> ease-out; 140ms */ transition: transform var(--dur-press) var(--ease-out); }
  .tabs-layer button:active { transform: scale(0.97); }
  .tabs-active {
    position: absolute; inset: 4px; display: flex; pointer-events: none;
    background: var(--gold); border-radius: var(--radius-pill);
    clip-path: inset(0 var(--clip-r, 100%) 0 var(--clip-l, 0%) round 999px);
    /* why: the active state slides instead of jumping; on-screen movement -> ease-in-out; 220ms */
    transition: clip-path var(--dur-ui) var(--ease-in-out);
  }
  .tabs-active span { color: var(--bg-0); }

  /* ---- morphing submit button: three layers in one box, the box never changes width ---- */
  .morph { display: grid; }
  .morph > span {
    grid-area: 1 / 1; display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
    /* why: state indication; the outgoing layer blurs so the two states read as one thing changing; 200ms ease */
    transition: opacity 200ms ease, filter 200ms ease, transform 200ms ease;
  }
  .morph > span:not(.is-on) { opacity: 0; filter: blur(2px); transform: scale(0.96); pointer-events: none; }
  /* why: a fast spinner makes the wait feel shorter; constant motion -> linear; 600ms per turn */
  .spin { animation: spin 600ms linear infinite; }
  @keyframes spin { to { transform: rotate(360deg); } }
  .btn[data-state="sent"] { background: var(--gold); }
  .btn[data-state="sent"] .icon { color: var(--bg-0); }

  /* ---- toast ---- */
  .toast {
    position: fixed; left: 50%; bottom: 1.25rem; z-index: 55; translate: -50% 0;
    display: inline-flex; align-items: center; gap: 0.6rem; padding: 0.8rem 1.2rem;
    border-radius: var(--radius-pill); background: var(--bg-2); border: 1px solid var(--glass-edge);
    color: var(--fg-0); font-size: var(--step--1); white-space: nowrap;
    opacity: 0; transform: translateY(calc(100% + 1.25rem));
    /* why: enters from the same edge it leaves by; transitions so rapid triggers retarget; exit 200ms, enter 320ms, ease-out */
    transition: transform 200ms var(--ease-out), opacity 200ms var(--ease-out);
  }
  .toast.is-in { opacity: 1; transform: none; transition-duration: 320ms; }
  .toast .icon { color: var(--gold); }

  /* ---- monogram ---- */
  .mark { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 12; stroke-linecap: round; stroke-linejoin: round; }
}

/* -------------------------------------------------------------- sections */
@layer sections {
  /* Flat sections on the page, one rhythm: the head, then the content on
     hairlines. No panels, no tinted bands between them: the structure comes
     from the rules inside each section, the way Ventor's page is built. */
  /* every section sits on the field, under a shade of the page's black at 78%: the ink shows through
     everywhere, dimmed enough for the text grey to read (measured on the pixels, hero excluded) */
  .section { position: relative; padding-block: var(--space-6); background: rgb(11 11 13 / 0.78); }
  /* ---- section head: the title left, one line about the section right, on one baseline ---- */
  .section-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.4rem var(--space-3); margin-bottom: var(--space-4); }
  .section-head .lead { max-width: 34ch; color: var(--fg-1); }
  .section-head--tight { margin-bottom: 0; }
  /* ---- the accent inside a line: italic serif, gold ---- */
  .accent { font-family: var(--serif); font-style: italic; color: var(--gold); }

  /* ---- eyebrow: a mono label with a gold point, above the wordmark ---- */
  .eyebrow { display: inline-flex; align-items: center; gap: 0.6rem; font-family: var(--mono); font-size: var(--step--1); letter-spacing: 0.14em; text-transform: uppercase; color: var(--fg-2); }
  .eyebrow::before { content: ""; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--gold); flex: none; }

  /* ---- hero rail: what is true today, along the bottom edge of the hero ---- */
  .status { position: relative; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0.75rem 2rem; margin-top: var(--space-5); padding-top: var(--space-3); border-top: 1px solid var(--line); font-family: var(--mono); font-size: var(--step--1); letter-spacing: 0.12em; text-transform: uppercase; color: var(--fg-1); /* fg-1, not fg-2: this sits on the field, whose light can lift the backdrop to ~#383737 */ }
  .status li { display: inline-flex; align-items: center; gap: 0.6rem; }
  .dot { position: relative; width: 6px; height: 6px; border-radius: var(--radius-pill); background: var(--fg-2); flex: none; }
  .dot--live { background: var(--gold); } /* static on purpose: a pulsing ring here cost ~25 fps on a software GPU (measured), and the gold alone already reads as "open" */

  /* ---- lists with a gold point: the offer, the ask, how to send ---- */
  .dots { display: grid; gap: 0.5rem; }
  .dots li { position: relative; padding-left: 1.25rem; color: var(--fg-1); }
  .dots li::before { content: ""; position: absolute; left: 2px; top: 0.66em; width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--gold); }

  /* ---- the pointer: one gold point on the mouse, no lag; over a link it opens into a soft disc ----
     On a fine pointer with motion on, main.js sets html.has-cursor: the native
     arrow goes and the point takes its place. Over a text field the native caret
     is the right tool, so it steps aside there. Touch, reduced motion and the
     switch never see it. */
  .cursor { display: none; position: fixed; top: 0; left: 0; z-index: 90; width: 8px; height: 8px; border-radius: var(--radius-pill); background: var(--gold); border: 1px solid transparent; pointer-events: none; will-change: transform; /* why: it opens over a link and shrinks under the press; response -> ease-out; 200ms, press 140ms */ transition: width 200ms var(--ease-out), height 200ms var(--ease-out), background-color 200ms var(--ease-out), border-color 200ms var(--ease-out), scale var(--dur-press) var(--ease-out), opacity 200ms ease; }
  html.has-cursor .cursor { display: block; }
  html.has-cursor, html.has-cursor * { cursor: none; }
  html.has-cursor :is(input, textarea) { cursor: auto; }
  .cursor.is-hover { width: 40px; height: 40px; background: rgb(217 184 106 / 0.16); border-color: rgb(217 184 106 / 0.6); }
  .cursor.is-down { scale: 0.7; }
  .cursor.is-hidden, .cursor.is-text { opacity: 0; }

  /* ---- loading screen: the first visit of the session, raised by the head script (html.is-loading) ----
     The page's black with its grain, the name wiped in once its face is there,
     the claim in the accent italic after it, and the gold thread as the measure
     of the load. At the end the words step back and the veil rises as a curtain,
     the hero entering behind it. */
  .loader { display: none; }
  html.is-loading { overflow: hidden; }
  html.is-loading .loader, .loader.is-leaving { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; padding: var(--gutter); pointer-events: none; }
  .loader-veil { position: absolute; inset: 0; background: var(--bg-0); /* why: the curtain rises and the hero enters behind it; on-screen movement -> ease-in-out; 900ms after a 150ms beat */ transition: transform 900ms var(--ease-in-out) 150ms; }
  .loader-veil::after { content: ""; position: absolute; inset: 0; opacity: 0.035; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); }
  .loader.is-leaving .loader-veil { transform: translate3d(0, -100%, 0); }
  .loader-inner { position: relative; display: grid; justify-items: center; gap: var(--space-3); text-align: center; /* why: the words step back before the curtain rises; exit -> ease-out; 300ms */ transition: opacity 300ms var(--ease-out), transform 300ms var(--ease-out); }
  .loader.is-leaving .loader-inner { opacity: 0; transform: translateY(-8px); }
  .loader-name { margin: 0; max-width: none; font-family: var(--display); font-weight: 600; font-size: clamp(2rem, 8.4vw, 5.5rem); line-height: 1; letter-spacing: -0.02em; text-transform: uppercase; color: var(--fg-0); white-space: nowrap; }
  .loader-name span, .loader-claim span { display: block; clip-path: inset(0 100% 0 0); /* why: the words are wiped in from the left once the face is in; enter -> ease-out; 1100ms, the claim 500ms after the name */ transition: clip-path 1100ms var(--ease-out); }
  .loader-claim { margin: 0; max-width: none; font-family: var(--serif); font-style: italic; font-size: clamp(1.25rem, 1rem + 1.4vw, 2rem); line-height: 1.25; color: var(--gold); }
  .loader-claim span { transition-delay: 500ms; }
  .loader.is-type .loader-name span, .loader.is-type .loader-claim span { clip-path: inset(0 0 0 0); }
  /* the thread: the page's gold line, here as the measure of the load, grown from the left by --loader-p */
  .loader-bar { position: relative; display: block; width: min(240px, 60vw); height: 1px; margin-top: var(--space-2); background: rgb(242 239 233 / 0.14); overflow: hidden; }
  .loader-bar span { position: absolute; inset: 0; background: var(--gold); transform: scaleX(var(--loader-p, 0)); transform-origin: left; }

  /* ---- nav: a floating pill ---- */
  .nav {
    position: fixed; top: 1.25rem; left: 50%; z-index: 40; translate: -50% 0;
    --r: var(--radius-pill);
    display: flex; align-items: center; gap: 0.5rem;
    height: var(--nav-h); width: max-content; max-width: calc(100% - 2 * var(--gutter));
    padding: 0 0.5rem;
    /* why: compresses on scroll; response -> ease-out; 220ms. The entrance is in the motion layer, on `translate`, so the two never share a property */
    transition: scale var(--dur-ui) var(--ease-out), backdrop-filter var(--dur-ui) var(--ease-out);
  }
  .nav.is-scrolled { scale: 0.97; backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%); }
  .brand { display: inline-flex; align-items: center; gap: 0.6rem; color: var(--fg-0); font-family: var(--display); font-size: 0.9rem; font-weight: 600; letter-spacing: 0.02em; text-transform: uppercase; white-space: nowrap; min-height: 44px; }
  /* the mark alone, bare: the name is in the title, the footer and the mark
     itself; in the bar it was only weight. 44px of target, no disc */
  .brand--mark { width: 44px; height: 44px; min-height: 0; justify-content: center; border-radius: var(--radius-pill); color: var(--fg-0); transition: transform var(--dur-press) var(--ease-out), color var(--dur-hover) ease; }
  .brand--mark .mark { width: 22px; height: 22px; }
  .brand--mark:active { transform: scale(0.97); }
  @media (hover: hover) and (pointer: fine) { .brand--mark:hover { color: var(--gold); } }
  /* the motion switch: a wave while things move, a flat line once stopped. Needs script, so hidden without it */
  .nav-motion { display: none; place-items: center; width: 44px; height: 44px; border-radius: var(--radius-pill); color: var(--fg-1); /* why: hover colour and the press; hover -> ease 180ms, press -> ease-out 140ms */ transition: color var(--dur-hover) ease, background-color var(--dur-hover) ease, transform var(--dur-press) var(--ease-out); }
  .js .nav-motion { display: grid; }
  .nav-motion .icon { width: 18px; height: 18px; }
  .nav-motion .off, .nav-motion[aria-pressed="true"] .on { display: none; }
  .nav-motion[aria-pressed="true"] .off { display: inline; }
  .nav-motion:active { transform: scale(0.97); }
  @media (hover: hover) and (pointer: fine) { .nav-motion:hover { color: var(--fg-0); background: var(--glass-fill-strong); } }
  /* the language: EN | IT, the current one in the text colour. Needs script, so hidden without it */
  .nav-lang { display: none; align-items: center; gap: 0.45rem; min-height: 44px; padding: 0 0.7rem; border-radius: var(--radius-pill); font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; color: var(--fg-1); /* why: hover and the press; hover -> ease 180ms, press -> ease-out 140ms */ transition: background-color var(--dur-hover) ease, transform var(--dur-press) var(--ease-out); }
  .js .nav-lang { display: inline-flex; }
  .nav-lang span.is-on { color: var(--fg-0); }
  .nav-lang i { width: 1px; height: 12px; background: var(--glass-edge); }
  .nav-lang:active { transform: scale(0.97); }
  @media (hover: hover) and (pointer: fine) { .nav-lang:hover { background: var(--glass-fill-strong); } }
  /* the divider between the mark and the links */
  .nav-sep { width: 1px; height: 22px; background: var(--glass-edge); flex: none; }
  /* the links, and over them a copy of the list in the inverted colours, clipped to the
     section on screen: the active pill slides between the links instead of two states
     swapping, the same device as the catalogue tabs */
  .nav-links { position: relative; display: flex; align-items: center; gap: 0.15rem; padding-inline: 0.15rem; }
  .nav-links a, .nav-active span { display: inline-flex; align-items: center; min-height: 44px; padding: 0 0.95rem; border-radius: var(--radius-pill); font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; white-space: nowrap; }
  .nav-links a { color: var(--fg-1); /* why: hover colour and the press; hover -> ease 180ms, press -> ease-out 140ms */ transition: color var(--dur-hover) ease, transform var(--dur-press) var(--ease-out); }
  .nav-links a:active { transform: scale(0.97); }
  .nav-active {
    position: absolute; inset: 0; display: flex; align-items: center; gap: 0.15rem; padding-inline: 0.15rem; pointer-events: none;
    background: var(--fg-0); color: var(--bg-0); border-radius: var(--radius-pill);
    clip-path: inset(0 var(--clip-r, 100%) 0 var(--clip-l, 0%) round 999px);
    /* why: the pill follows the reader down the page; on-screen movement -> ease-in-out; 220ms */
    transition: clip-path var(--dur-ui) var(--ease-in-out);
  }
  @media (hover: hover) and (pointer: fine) { .nav-links a:hover { color: var(--fg-0); } }
  .nav-toggle { display: none; position: relative; width: 44px; height: 44px; border-radius: var(--radius-pill); color: var(--fg-0); /* why: the press; response -> ease-out; 140ms */ transition: transform var(--dur-press) var(--ease-out); }
  .nav-toggle:active { transform: scale(0.97); }
  .nav-toggle i {
    position: absolute; left: 13px; width: 18px; height: 1.5px; background: currentColor; border-radius: 1px;
    /* why: two lines become a cross so the button explains itself; morph -> ease-in-out; 220ms */
    transition: transform var(--dur-ui) var(--ease-in-out), top var(--dur-ui) var(--ease-in-out);
  }
  .nav-toggle i:nth-child(1) { top: 18px; }
  .nav-toggle i:nth-child(2) { top: 25px; }
  .nav-toggle[aria-expanded="true"] i:nth-child(1) { top: 21.5px; transform: rotate(45deg); }
  .nav-toggle[aria-expanded="true"] i:nth-child(2) { top: 21.5px; transform: rotate(-45deg); }
  .sentinel { position: absolute; top: 8px; left: 0; width: 1px; height: 1px; pointer-events: none; } /* 8px down: the bar compresses once the page has moved, not at rest */

  /* ---- menu overlay ---- */
  .menu {
    position: fixed; inset: 0; z-index: 39; display: grid; place-items: center;
    background: rgb(11 11 13 / 0.55);
    opacity: 0; visibility: hidden;
    backdrop-filter: blur(0) saturate(100%); -webkit-backdrop-filter: blur(0) saturate(100%);
    /* why: the menu is a rare, deliberate moment; drawer curve; 420ms in, 260ms out */
    transition: opacity 260ms var(--ease-drawer), backdrop-filter 260ms var(--ease-drawer), visibility 0s linear 260ms;
  }
  .menu.is-open {
    opacity: 1; visibility: visible;
    backdrop-filter: blur(32px) saturate(160%); -webkit-backdrop-filter: blur(32px) saturate(160%);
    transition: opacity var(--dur-panel) var(--ease-drawer), backdrop-filter var(--dur-panel) var(--ease-drawer), visibility 0s;
  }
  .menu ul { display: grid; gap: 0.25rem; text-align: center; }
  .menu a {
    display: inline-block; padding: 0.6rem 1rem; font-family: var(--display); font-weight: 600; font-size: var(--step-3); letter-spacing: -0.01em; text-transform: uppercase; color: var(--fg-0); line-height: 1.1;
    opacity: 0; transform: translateY(24px);
    /* why: links arrive one after another; enter -> ease-out; 320ms, stagger 55ms. The press is on `scale`, 140ms, so it never waits for the entrance */
    transition: opacity 320ms var(--ease-out), transform 320ms var(--ease-out), scale var(--dur-press) var(--ease-out);
  }
  .menu.is-open a { opacity: 1; transform: none; transition-delay: calc(var(--i, 0) * var(--stagger) + 120ms); }
  .menu a:active { scale: 0.97; }
  @media (prefers-reduced-transparency: reduce) { .menu { background: rgb(11 11 13 / 0.96); } .menu.is-open { backdrop-filter: none; } }

  /* ---- hero: the wordmark left, the thread right, the field all around ---- */
  .hero {
    position: relative; min-height: 100dvh; display: grid; grid-template-rows: minmax(0, 1fr) auto;
    padding-block: calc(var(--nav-h) + var(--space-6)) var(--space-4);
    background: transparent; overflow: clip;
  }
  /* the copy sits in a pool of shadow so the field never fights the type; the
     ink stays visible around it and brightest behind the mark, upper right */
  .hero::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background:
      radial-gradient(46% 62% at 26% 50%, rgb(11 11 13 / 0.86) 0%, rgb(11 11 13 / 0.6) 42%, rgb(11 11 13 / 0.1) 78%, transparent 100%),
      linear-gradient(180deg, transparent 62%, rgb(11 11 13 / 0.78) 85%);
  }
  .hero-grid { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; align-self: center; gap: var(--space-5); }
  .hero-copy { display: grid; justify-items: start; }
  .hero .eyebrow { color: var(--fg-1); } /* measured 4.18:1 at fg-2 on the field's light, above the pool: fg-1, like the rail */
  .wordmark { margin-top: var(--space-3); font-size: clamp(3.2rem, 0.8rem + 6.4vw, 7.4rem); line-height: 0.9; letter-spacing: -0.03em; text-transform: uppercase; max-width: 8ch; }
  .subline { margin-top: var(--space-3); max-width: 24ch; font-family: var(--serif); font-style: italic; font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.5rem); line-height: 1.2; letter-spacing: -0.01em; color: var(--fg-0); }
  .hero-actions { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
  .hero-object { position: relative; display: grid; justify-items: end; }
  .hero-object > .thread { grid-area: 1 / 1; } /* the strands and the line share one cell: two layers, one object */
  .thread { width: 100%; height: auto; aspect-ratio: 100 / 60; overflow: visible; fill: none; stroke-linecap: round; stroke-linejoin: round; will-change: transform; /* its own layer: the line repaints under the pointer, and the page behind it must not */ }
  .th-line { stroke: var(--gold); stroke-width: 1.5; }
  .th-strand { stroke: var(--gold); stroke-width: 0.7; stroke-linejoin: bevel; stroke-linecap: butt; opacity: var(--o, 0.2); } /* plain joins: fourteen of them repaint per frame under the pointer */
  .hero-object:has(.cascade:not([hidden])) .thread { display: none; }
  .cascade { position: relative; aspect-ratio: 1; width: min(100%, 420px); }
  .cascade img {
    position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
    border-radius: var(--radius-card); box-shadow: 0 30px 80px rgb(0 0 0 / 0.55);
    clip-path: inset(0 0 100% 0);
    /* why: real cover art is the reason to look; enter -> ease-in-out; 900ms, staggered 90ms */
    transition: clip-path 900ms var(--ease-in-out);
  }
  .cascade img:nth-child(1) { transform: rotate(-3deg) translate(-6%, 4%) scale(0.92); z-index: 1; transition-delay: 200ms; }
  .cascade img:nth-child(2) { transform: rotate(2deg) translate(4%, -2%) scale(0.96); z-index: 2; transition-delay: 290ms; }
  .cascade img:nth-child(3) { transform: none; z-index: 3; transition-delay: 380ms; }
  .is-mounted .cascade img { clip-path: inset(0); }

  /* ---- featured release ---- */
  .featured-wrap { position: relative; border-radius: var(--radius-card); overflow: hidden; padding: var(--space-3); }
  .featured-bg { position: absolute; inset: -10%; background-size: cover; background-position: center; filter: blur(40px) brightness(0.5); }
  .featured { display: grid; grid-template-columns: 5fr 7fr; gap: var(--space-5); padding: var(--space-4); overflow: hidden; }
  .featured-cover { border-radius: var(--radius-core); overflow: hidden; aspect-ratio: 1; clip-path: inset(0 0 100% 0); /* why: the cover is revealed like a sleeve pulled; enter -> ease-in-out; 900ms */ transition: clip-path 900ms var(--ease-in-out); }
  .featured-cover.is-in { clip-path: inset(0); }
  .featured-cover img { width: 100%; height: 100%; object-fit: cover; }
  .featured-body { display: grid; gap: var(--space-2); align-content: center; }
  .featured-body h3 { font-size: var(--step-3); }
  .featured-notes { display: grid; gap: 0.35rem; color: var(--fg-1); }
  .featured-links { display: flex; flex-wrap: wrap; gap: 0.5rem 1.2rem; margin-top: var(--space-2); }
  .sweep {
    position: absolute; inset: 0; pointer-events: none;
    background: linear-gradient(115deg, transparent 42%, rgb(217 184 106 / 0.09) 50%, transparent 58%);
    transform: translateX(-100%);
    /* why: a lamp passing over glass, once every 20s; constant motion -> linear; transform only */
    animation: sweep 20s linear infinite;
  }
  @keyframes sweep { 0% { transform: translateX(-100%); } 12% { transform: translateX(100%); } 100% { transform: translateX(100%); } }
  .player { display: inline-flex; align-items: center; gap: 0.8rem; padding: 0.4rem 1rem 0.4rem 0.4rem; --r: var(--radius-pill); }
  .player-btn { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--radius-pill); background: var(--gold); color: var(--bg-0); transition: transform var(--dur-press) var(--ease-out); }
  .player-btn:active { transform: scale(0.95); }
  .player-meta { display: grid; line-height: 1.25; }
  .player-meta b { font-weight: 500; color: var(--fg-0); font-size: var(--step--1); }
  .player-meta span { color: var(--fg-2); font-size: var(--step--1); }
  .embed { margin-top: var(--space-2); border-radius: var(--radius-input); overflow: hidden; }
  .embed iframe { display: block; width: 100%; height: 152px; border: 0; }

  /* ---- catalogue ---- */
  .catalogue-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); }
  .grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-3); }
  .empty { font-family: var(--display); font-size: var(--step-2); color: var(--fg-0); font-weight: 600; letter-spacing: -0.01em; line-height: 1.15; }
  /* ---- the record to come, while the catalogue is in preparation: a blank sleeve, hatched, with the disc behind it ---- */
  .next { display: grid; grid-template-columns: 5fr 7fr; gap: var(--space-4) var(--space-5); align-items: center; }
  .next-record { position: relative; width: min(80%, 300px); aspect-ratio: 541 / 640; } /* Ventor's sleeve, portrait; the disc reaches 120% of its width and stays inside the column */
  .sleeve { position: relative; z-index: 1; display: grid; place-items: center; width: 100%; height: 100%; border: 1px dashed rgb(217 184 106 / 0.5); background: repeating-linear-gradient(135deg, rgb(217 184 106 / 0.06) 0 1px, transparent 1px 14px), var(--bg-1); }
  .sleeve-word { padding: 0 8%; font-size: clamp(3.5rem, 2.5rem + 3vw, 6.5rem); line-height: 1; text-align: center; color: rgb(217 184 106 / 0.6); }
  /* the disc: grooves in the two golds, a black label with a gold rim, the hole the page's black; behind the sleeve, a quarter out */
  .vinyl {
    position: absolute; z-index: 0; top: 50%; left: 32%; width: 88%; aspect-ratio: 1; border-radius: var(--radius-pill); translate: 0 -50%; rotate: -14deg;
    background:
      radial-gradient(circle closest-side, var(--bg-0) 0 10%, var(--gold-deep) 10% calc(10% + 1px), #0f0e0b calc(10% + 1px) 42%, var(--gold-deep) 42% calc(42% + 2px), transparent calc(42% + 2px)),
      conic-gradient(from 200deg, rgb(255 243 191 / 0.16) 0 7%, transparent 7% 50%, rgb(255 243 191 / 0.1) 50% 56%, transparent 56%),
      repeating-radial-gradient(circle closest-side, var(--gold) 0 2px, var(--gold-deep) 2px 3px);
    /* why: the record slides out a little under the pointer, once; response -> ease-out; 800ms */
    transition: translate 800ms var(--ease-out), rotate 800ms var(--ease-out);
  }
  @media (hover: hover) and (pointer: fine) { .next-record:hover .vinyl { translate: 9% -50%; rotate: 50deg; } }
  .next-copy { display: grid; gap: var(--space-2); justify-items: start; max-width: 60ch; }
  .next-lede { color: var(--fg-1); max-width: 40ch; }
  .next-cta { margin-top: var(--space-2); }
  .more { margin-top: var(--space-4); }

  /* ---- artists ---- */
  .roster { display: grid; grid-template-columns: 4fr 8fr; gap: var(--space-5); align-items: start; }
  .roster-intro { position: sticky; top: calc(var(--nav-h) + var(--space-4)); display: grid; gap: var(--space-2); }
  .artist { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 0.4rem var(--space-4); align-items: baseline; padding-block: var(--space-3); border-top: 1px solid var(--line); }
  .artist:last-child { border-bottom: 1px solid var(--line); }
  .artist h3 { font-size: var(--step-2); }
  .artist p { color: var(--fg-1); grid-column: 1; }
  .artist .tag { grid-row: 1 / 3; align-self: center; }
  .artist-portrait { display: none; }
  .trail {
    position: fixed; top: 0; left: 0; z-index: 30; width: 200px; aspect-ratio: 4 / 5;
    border-radius: var(--radius-card); object-fit: cover; pointer-events: none; opacity: 0;
    /* why: the portrait arrives with the pointer; it is decorative, so it must have momentum (JS lerp), and fades; 180ms */
    transition: opacity var(--dur-hover) var(--ease-out);
  }
  .trail.is-on { opacity: 1; }
  @media (hover: none) { .artist-portrait { display: block; width: 72px; aspect-ratio: 4 / 5; border-radius: var(--radius-input); object-fit: cover; grid-row: 1 / 3; grid-column: 2; } .artist .tag { grid-row: auto; grid-column: 1; justify-self: start; } }

  /* ---- about: the title in the first of four columns, the statement and the text in the rest ---- */
  .about { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--space-3); align-items: baseline; }
  .about h2 { grid-column: 1; }
  .about-body { grid-column: 2 / -1; }
  .statement { max-width: 30ch; font-family: var(--display); font-weight: 600; font-size: clamp(1.5rem, 1rem + 1.7vw, 2.4rem); line-height: 1.15; letter-spacing: -0.02em; color: var(--fg-0); text-wrap: balance; }
  .statement .accent { font-size: 1.08em; } /* the serif italic sits smaller on the same body: a notch up and the two halves read as one line */
  .about-body p:not(.statement) { margin-top: var(--space-2); max-width: 58ch; color: var(--fg-1); }
  .about-body .statement + p { margin-top: var(--space-4); }
  .about-body p.founded { margin-top: var(--space-3); font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; } /* "Founded … in …", once the label fills it */

  /* ---- principles: four rows on hairlines, the term in the first column, the line in the next two ---- */
  .rows { border-bottom: 1px solid var(--line); }
  .row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); column-gap: var(--space-3); align-items: baseline; padding-block: 1.4rem; border-top: 1px solid var(--line); }
  .row h3 { grid-column: 1; font-size: var(--step-1); }
  .row p { grid-column: 2 / 4; max-width: 60ch; color: var(--fg-1); }

  /* ---- process: four stages side by side, each on its own rule with a gold point at the start ---- */
  .process { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4) var(--space-3); }
  .stage { position: relative; display: grid; gap: 0.75rem; align-content: start; padding-top: var(--space-2); border-top: 1px solid var(--line); }
  .stage::before { content: ""; position: absolute; top: -4px; left: 0; width: 7px; height: 7px; border-radius: var(--radius-pill); background: var(--gold); }
  .stage-n { font-family: var(--serif); font-style: italic; font-size: var(--step-3); line-height: 1; color: var(--gold); }
  .stage h3 { font-size: var(--step-1); }
  .stage p { max-width: 34ch; color: var(--fg-1); }

  /* ---- for artists: two plain columns ---- */
  .offer { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4) var(--space-3); }
  .offer h3 { font-size: var(--step-1); margin-bottom: var(--space-2); }
  .offer-foot { margin-top: var(--space-4); }
  .offer-foot a { display: inline-flex; align-items: center; min-height: 44px; }

  /* ---- partners: three tiles, the mark large on its own, the name and the role under it; then the stores on a band ---- */
  .carriers { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-3); }
  .carrier { display: grid; align-content: space-between; gap: var(--space-4); min-height: 300px; padding: var(--space-4); border-radius: var(--radius-card); background: var(--bg-1); border: 1px solid var(--line); /* why: the edge answers the pointer; hover -> ease; 180ms */ transition: border-color var(--dur-hover) ease; }
  @media (hover: hover) and (pointer: fine) { .carrier:hover { border-color: rgb(217 184 106 / 0.4); } }
  .carrier-badge { display: grid; place-items: center; min-height: 96px; }
  .carrier-text { display: grid; gap: 0.25rem; min-width: 0; }
  .carrier-title { font-family: var(--display); font-weight: 600; font-size: var(--step-2); letter-spacing: -0.01em; line-height: 1.1; color: var(--fg-0); }
  .carrier-role { font-size: var(--step-1); line-height: 1.25; }
  /* the marks are masks: the file's alpha is the shape, the colour is ours */
  .logo { display: block; width: 100%; max-width: 220px; max-height: 72px; background: var(--fg-0); -webkit-mask: var(--m) center / contain no-repeat; mask: var(--m) center / contain no-repeat; }
  .logo--orchard { --m: url("assets/partner-orchard.png"); aspect-ratio: 288 / 104; }
  .logo--believe { --m: url("assets/partner-believe.png"); aspect-ratio: 460 / 104; }
  .logo--toolost { --m: url("assets/partner-toolost.png"); aspect-ratio: 118 / 104; }
  /* where the records end up: a band on two rules, the label at the left, the five stores spread along it */
  .reach { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 3fr); align-items: center; gap: var(--space-2) var(--space-4); margin-top: var(--space-5); padding-block: var(--space-3); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
  .reach-label { font-family: var(--mono); font-size: 0.72rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--fg-1); }
  .stores { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 0.6rem 1.6rem; color: var(--fg-0); font-size: var(--step-0); }
  .stores li { display: inline-flex; align-items: center; gap: 0.6rem; min-height: 32px; white-space: nowrap; }
  .store { width: 24px; height: 24px; flex: none; fill: currentColor; stroke: none; }

  /* ---- journal ---- */
  .journal { display: grid; grid-template-columns: 7fr 5fr; grid-auto-rows: auto; gap: var(--space-3); }
  .entry { display: grid; gap: 0.6rem; align-content: end; padding: var(--space-4); border-radius: var(--radius-card); background: var(--bg-2); border: 1px solid var(--line); transition: border-color var(--dur-hover) ease; }
  @media (hover: hover) and (pointer: fine) { .entry:hover, .card:hover { border-color: rgb(217 184 106 / 0.4); } }
  .entry:first-child { grid-row: span 2; min-height: 360px; }
  .entry time { font-family: var(--mono); font-size: var(--step--1); color: var(--fg-2); font-feature-settings: "lnum"; }
  .entry h3 { font-size: var(--step-2); }
  .entry:first-child h3 { font-size: var(--step-3); }
  .entry p { color: var(--fg-1); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

  /* ---- questions: open, in two columns, each on its own rule ---- */
  .faq-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: var(--space-3); margin: 0; }
  .faq-item { padding-block: 1.25rem; border-top: 1px solid var(--line); }
  .faq-item dt { font-family: var(--display); font-weight: 600; font-size: var(--step-1); letter-spacing: -0.01em; line-height: 1.2; color: var(--fg-0); text-wrap: balance; }
  .faq-item dd { margin: 0.4rem 0 0; max-width: 52ch; color: var(--fg-1); }

  /* ---- send a demo: the intro left, the form right, flat on the field ---- */
  .demo-grid { position: relative; display: grid; grid-template-columns: 5fr 7fr; gap: var(--space-4) var(--space-6); align-items: start; }
  .demo-lede { margin-top: var(--space-2); max-width: 36ch; color: var(--fg-1); }
  .demo-steps-title { margin-top: var(--space-4); font-size: var(--step-1); }
  .demo-steps { margin-top: var(--space-2); max-width: 44ch; }
  .demo-direct { display: flex; flex-direction: column; align-items: flex-start; margin-top: var(--space-3); max-width: none; }
  .demo-direct a { display: inline-flex; align-items: center; min-height: 40px; color: var(--fg-0); text-decoration: underline; text-decoration-color: var(--gold-deep); text-decoration-thickness: 1px; text-underline-offset: 0.3em; /* why: the underline turns gold under the pointer; hover -> ease; 180ms */ transition: text-decoration-color var(--dur-hover) ease; }
  .demo-direct a:first-child { font-family: var(--display); font-weight: 600; font-size: var(--step-1); letter-spacing: -0.01em; }
  @media (hover: hover) and (pointer: fine) { .demo-direct a:hover { text-decoration-color: var(--gold); } }
  .demo .hint { color: var(--fg-1); } /* measured 4.35:1 at fg-2: the section is translucent over the field, which lifts the backdrop */
  .form { display: grid; gap: var(--space-3); }
  .form-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-1); }
  .form-foot .hint { max-width: 40ch; }

  /* ---- colophon ---- */
  /* the footer sits on the flat page, not on the field: without this the
     ink showed through and a footer link measured 1.6:1 */
  .footer { position: relative; background: rgb(11 11 13 / 0.78); padding-block: var(--space-5) calc(var(--space-5) + env(safe-area-inset-bottom, 0px)); }
  .colophon { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--space-4) var(--space-3); padding-top: var(--space-4); border-top: 1px solid var(--line); font-size: var(--step--1); color: var(--fg-1); }
  .colophon a { display: inline-flex; align-items: center; min-height: 2.25rem; color: var(--fg-0); /* why: hover colour; hover -> ease; 180ms */ transition: color var(--dur-hover) ease; }
  @media (hover: hover) and (pointer: fine) { .colophon a:hover { color: var(--gold); } }
  .colophon .brand { min-height: 0; }
  .colophon-line { margin-top: var(--space-2); max-width: 30ch; color: var(--fg-0); }
  .colophon ul { display: grid; }
  .colophon-copy { margin-top: var(--space-2); }
  .colophon-note { display: grid; gap: var(--space-2); justify-items: start; }

  /* ---- responsive ---- */
  @media (max-width: 1023px) {
    .nav { gap: var(--space-2); padding: 0 0.35rem 0 0.5rem; }
    .nav-links, .nav-sep { display: none; }
    .nav-toggle { display: block; }
    .hero-grid { gap: var(--space-4); }
    .grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .next { grid-template-columns: 1fr 1fr; }
    .roster { grid-template-columns: 1fr; }
    .roster-intro { position: static; }
    .about { grid-template-columns: 1fr; row-gap: var(--space-3); }
    .about h2, .about-body { grid-column: 1; }
    .row { grid-template-columns: 1fr 2fr; }
    .row p { grid-column: 2; }
    .process { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .carriers { grid-template-columns: 1fr; }
    .carrier { min-height: 0; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: var(--space-3); padding: var(--space-3); }
    .carrier-badge { min-height: 0; width: 120px; }
    .logo { max-width: 120px; max-height: 48px; }
    .reach { grid-template-columns: 1fr; }
    .stores { justify-content: flex-start; }
    .journal { grid-template-columns: 1fr; }
    .entry:first-child { grid-row: auto; min-height: 0; }
    .demo-grid { grid-template-columns: 1fr; gap: var(--space-5); }
    .featured { grid-template-columns: 1fr; }
    .colophon { grid-template-columns: 1fr 1fr; }
  }
  @media (max-width: 767px) {
    .section { padding-block: var(--space-5); }
    /* the hero as a cover: the copy at the top under the bar, the mark lower right,
       the rail along the bottom edge; nothing centred in a void */
    .hero { padding-block: calc(var(--nav-h) + var(--space-4)) var(--space-3); }
    .hero-grid { grid-template-columns: 1fr; gap: var(--space-3); align-self: start; align-items: start; }
    .hero-object { justify-items: stretch; margin-top: var(--space-2); }
    .hero::before { background: radial-gradient(75% 45% at 30% 30%, rgb(11 11 13 / 0.86) 0%, rgb(11 11 13 / 0.55) 55%, transparent 100%), linear-gradient(180deg, transparent 62%, rgb(11 11 13 / 0.78) 85%); }
    .wordmark { margin-top: var(--space-2); font-size: clamp(3.4rem, 15.5vw, 4.3rem); max-width: none; }
    .subline { margin-top: var(--space-2); font-size: clamp(1.35rem, 6vw, 1.7rem); }
    .hero-actions { margin-top: var(--space-3); }
    .status { flex-direction: column; gap: 0.55rem; margin-top: var(--space-4); }
    .section-head { margin-bottom: var(--space-3); }
    .cascade { width: min(100%, 280px); }
    .row { grid-template-columns: 1fr; row-gap: 0.35rem; padding-block: 1.1rem; }
    .row p { grid-column: 1; }
    .process { grid-template-columns: 1fr; }
    .offer { grid-template-columns: 1fr; }
    .faq-list { grid-template-columns: 1fr; }
    .next { grid-template-columns: 1fr; overflow: clip; } /* the disc's rotated box sticks out past the page edge on a phone; the clip takes only its empty corners */
    .next-record { width: 62%; }
    .faq-item:last-child { border-bottom: 1px solid var(--line); }
    .grid { grid-template-columns: 1fr; }
    .colophon { grid-template-columns: 1fr; gap: var(--space-3); padding-top: var(--space-4); }
  }
}

/* ---------------------------------------------------------------- motion */
@layer motion {
  /* The one orchestrated moment: page load. Each step is opacity + transform,
     ease-out, and starts from a state @starting-style describes, so the
     sequence needs no script and cannot leave the page hidden. */
  /* why: the hero is the one place that may take its time; enter -> ease-out; 700ms after 80ms */
  .wordmark { transition: opacity 700ms var(--ease-out) 80ms, transform 700ms var(--ease-out) 80ms; }
  .subline { transition: opacity 500ms var(--ease-out) 260ms, transform 500ms var(--ease-out) 260ms; }
  .hero-actions > :nth-child(1) { transition: opacity 500ms var(--ease-out) 360ms, transform 500ms var(--ease-out) 360ms; }
  .hero-actions > :nth-child(2) { transition: opacity 500ms var(--ease-out) 415ms, transform 500ms var(--ease-out) 415ms; }
  .nav { transition: translate 500ms var(--ease-out) 500ms, opacity 500ms var(--ease-out) 500ms, scale var(--dur-ui) var(--ease-out), backdrop-filter var(--dur-ui) var(--ease-out); } /* the entrance on translate and opacity, the compression on scale: one property each */
  /* why: the thread draws itself once, the middle line first and the strands outward, as part of the same load; on-screen drawing -> ease-in-out; 1400ms the line, 1000ms each strand, each carrying its own --d */
  .thread path { stroke-dasharray: 100; stroke-dashoffset: 0; transition: stroke-dashoffset 1000ms var(--ease-in-out) var(--d, 0ms); }
  .thread .th-line { --d: 200ms; transition-duration: 1400ms; }
  @starting-style {
    .wordmark, .subline, .hero-actions > * { opacity: 0; transform: translateY(16px); }
    .nav { opacity: 0; translate: -50% -8px; }
    .thread path { stroke-dashoffset: 100; }
  }
  /* behind the loading screen the hero holds its starting state, and enters
     when html.is-loading goes, as the panel parts */
  html.is-loading .wordmark, html.is-loading .subline, html.is-loading .hero-actions > * { opacity: 0; transform: translateY(16px); }
  html.is-loading .nav { opacity: 0; translate: -50% -8px; }
  html.is-loading .thread path { stroke-dashoffset: 100; }

  /* The rises on scroll are not here: every block below the fold carries data-rise and
     main.js plays them with the Web Animations API, 600ms on the rise curve, so nothing
     is ever hidden by a stylesheet rule waiting for a script. */

  /* Reduced motion: opacity and colour may still change, in 200ms or less.
     Nothing translates, scales, clips or drifts. */
  @media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
      transition-property: opacity, color, background-color, border-color !important;
      transition-duration: 200ms !important;
      transition-delay: 0ms !important;
      animation: none !important;
    }
    .cascade img { clip-path: inset(0); }
    .featured-cover { clip-path: inset(0); }
    .trail { display: none !important; }
    .cursor, .loader { display: none !important; }
    html, html * { cursor: auto; }
    .bg-aurora { animation: none !important; }
    .menu a { transform: none; }
    .toast { transform: none; }
  }

  /* The switch in the nav sets html.motion-off: the same rules as the media
     query, for people whose system does not say it for them */
  html.motion-off { scroll-behavior: auto; }
  .motion-off *, .motion-off *::before, .motion-off *::after {
    transition-property: opacity, color, background-color, border-color !important;
    transition-duration: 200ms !important;
    transition-delay: 0ms !important;
    animation: none !important;
  }
  .motion-off .menu a, .motion-off .toast { transform: none; }
  .motion-off .cascade img, .motion-off .featured-cover { clip-path: inset(0); }
  .motion-off .trail, .motion-off .cursor, .motion-off .loader { display: none !important; }
  @media print { .loader { display: none !important; } }

  /* the thread along the top follows the scroll position, not the clock: it stays in both cases */
  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: reduce) { .progress { animation: progress linear both !important; animation-timeline: scroll(root) !important; } }
    .motion-off .progress { animation: progress linear both !important; animation-timeline: scroll(root) !important; }
  }
}

/* ------------------------------------------------------------- utilities */
@layer utilities {
  .sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
  .stack-2 { display: grid; gap: var(--space-2); }
}
