@charset "utf-8";
/* ============================================================================
   SKiN at The Collective — THE REGISTER
   Direction C. Build law is 03-DESIGN-SYSTEM.md; this file implements it.

   Prohibitions enforced here by construction:
   no border-radius, no box-shadow with a positive Y offset, no icons,
   no cards, no coloured left-border strips, and no pure white or black
   in any notation.
   ========================================================================= */

@layer reset, tokens, base, type, layout, rule, components, motion, util;

@view-transition { navigation: auto; }

/* ---------------------------------------------------------------- fonts */

@font-face {
  font-family: "Newsreader";
  src: url("../fonts/Newsreader[opsz,wght].woff2") format("woff2");
  font-weight: 280 640;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Newsreader";
  src: url("../fonts/Newsreader-Italic[wght].woff2") format("woff2");
  font-weight: 360 560;
  font-style: italic;          /* real italic. never a faux oblique. */
  font-display: swap;
}
@font-face {
  font-family: "Jost";
  src: url("../fonts/Jost[wght].woff2") format("woff2");
  font-weight: 200 520;
  font-style: normal;
  font-display: swap;
}
/* Metric-matched fallback so the swap does not move the page.
   Newsreader upm 2000: asc .735 desc .265 xH .426 · Georgia xH .484 */
@font-face {
  font-family: "Newsreader Fallback";
  src: local("Georgia"), local("Times New Roman"), local("Times");
  size-adjust: 88%;
  ascent-override: 83.5%;
  descent-override: 30.1%;
  line-gap-override: 0%;
}
@font-face {
  font-family: "Jost Fallback";
  src: local("Helvetica Neue"), local("Arial");
  size-adjust: 95%;
  ascent-override: 112.6%;
  descent-override: 39.5%;
  line-gap-override: 0%;
}

/* ---------------------------------------------------------------- reset */

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  html { -webkit-text-size-adjust: 100%; }
  body, h1, h2, h3, h4, p, figure, blockquote, dl, dd, ol, ul, fieldset {
    margin: 0; padding: 0;
  }
  ol[class], ul[class] { list-style: none; }
  img, picture, video, svg { display: block; max-inline-size: 100%; }
  img, video { block-size: auto; }
  button, input, select, textarea { font: inherit; color: inherit; }
  button { background: none; border: 0; cursor: pointer; }
  table { border-collapse: collapse; inline-size: 100%; }
  th { text-align: start; font-weight: inherit; }
  a { color: inherit; }
  summary::-webkit-details-marker { display: none; }
  summary::marker { content: ""; }
  :where(a, button, summary, input, [tabindex]):focus-visible {
    outline: 2px solid var(--c-ink);
    outline-offset: 3px;
  }
  ::selection { background: var(--c-sand); color: var(--c-ink); }
}

/* --------------------------------------------------------------- tokens */

@layer tokens {
  :root {
    /* colour — all nine round-trip to their oklch values exactly */
    --c-ivory:     #F4EDE1;
    --c-sand:      #E4D6BF;
    --c-taupe:     #D9C4B4;
    --c-ink:       #1C1A18;
    --c-grey:      #6E665C;
    --c-champagne: #C9A96A;
    --c-brass:     #A8843C;
    --c-woods:     #3A2E6B;

    --rule-rest: color-mix(in oklab, var(--c-grey) 34%, transparent);
    --rule-warm: var(--c-brass);
    --hairline: 1;

    /* per-ground text colours. set once by the ground classes below. */
    --ground:  var(--c-ivory);
    --fg:      var(--c-ink);
    --fg-soft: var(--c-grey);

    /* typefaces */
    --font-display: "Newsreader", "Newsreader Fallback", Georgia, serif;
    --font-label:   "Jost", "Jost Fallback", "Helvetica Neue", Arial, sans-serif;

    /* the grid, in rem so it survives a raised browser default size */
    --grid: 0.375rem;

    --t-micro:  0.75rem;    --lh-micro: 1.125rem;
    --t-label:  0.8125rem;  --lh-label: 1.125rem;
    --t-small:  0.9375rem;  --lh-small: 1.5rem;
    --t-body:   1.0625rem;  --lh-body:  1.875rem;
    --t-lede:   1.3125rem;  --lh-lede:  2.25rem;
    --t-h3:     1.75rem;    --lh-h3:    2.25rem;
    --t-h2:     clamp(2rem, 3.4vw, 2.75rem);      --lh-h2: 1.12;
    --t-h1:     clamp(2.35rem, 4.25vw, 3.9rem);   --lh-h1: 1.06;
    --t-figure: clamp(2.25rem, 4.4vw, 3.5rem);    --lh-figure: 1;

    --measure: 34em;

    /* space — multiples of six */
    --s1: calc(var(--grid) * 1);    /*  6 */
    --s2: calc(var(--grid) * 2);    /* 12 */
    --s3: calc(var(--grid) * 3);    /* 18 */
    --s4: calc(var(--grid) * 4);    /* 24 */
    --s6: calc(var(--grid) * 6);    /* 36 */
    --s8: calc(var(--grid) * 8);    /* 48 */
    --s12: calc(var(--grid) * 12);  /* 72 */
    --s16: calc(var(--grid) * 16);  /* 96 */
    --s24: calc(var(--grid) * 24);  /* 144 */
    --s36: calc(var(--grid) * 36);  /* 216 */

    --margin: 20px;
    --gutter: 24px;
    --header-h: 66px;

    /* motion */
    --ease-house: cubic-bezier(0.22, 1, 0.36, 1);   /* easeOutQuint  — reveals  */
    --ease-ui:    cubic-bezier(0.25, 1, 0.5, 1);    /* easeOutQuart  — controls */
    --ease-large: cubic-bezier(0.76, 0, 0.24, 1);   /* easeInOutQuart — big moves */
    --d-reveal: 700ms;
    --d-ui: 130ms;
    --d-overlay: 320ms;
  }

  @media (min-width: 768px)  { :root { --margin: 40px; --header-h: 74px; } }
  @media (min-width: 1280px) { :root { --margin: 72px; --header-h: 80px; } }

  /* one true device pixel on every display */
  @media (min-resolution: 2dppx)   { :root { --hairline: 0.5; } }
  @media (min-resolution: 3dppx)   { :root { --hairline: 0.34; } }
  @media (min-resolution: 3.5dppx) { :root { --hairline: 0.29; } }

  @media (prefers-contrast: more) {
    :root { --rule-rest: color-mix(in oklab, var(--c-grey) 60%, transparent); }
  }
}

/* ----------------------------------------------------------------- base */

@layer base {
  html {
    font-optical-sizing: auto;
    scrollbar-gutter: stable;
    scroll-behavior: smooth;
    scroll-padding-block-start: calc(var(--header-h) + var(--s4));
    background: var(--c-ivory);
  }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

  body {
    background: var(--c-ivory);
    color: var(--c-ink);
    font-family: var(--font-display);
    font-size: var(--t-body);
    line-height: var(--lh-body);
    font-feature-settings: "kern", "liga";
    text-rendering: optimizeLegibility;
    overflow-x: clip;
  }
  body.is-locked { overflow: hidden; }

  /* grounds. each sets its own secondary-text colour, because grey on sand
     measures 3.95:1 and fails AA — marginalia there is ink. */
  .g-ivory { background: var(--c-ivory); --ground: var(--c-ivory); --fg: var(--c-ink); --fg-soft: var(--c-grey); }
  .g-sand  { background: var(--c-sand);  --ground: var(--c-sand); --fg: var(--c-ink); --fg-soft: var(--c-ink); }
  .g-taupe { background: var(--c-taupe); --ground: var(--c-taupe); --fg: var(--c-ink); --fg-soft: var(--c-ink); }
  .g-ink   { background: var(--c-ink);   --ground: var(--c-ink); --fg: var(--c-ivory); --fg-soft: color-mix(in oklab, var(--c-ivory) 74%, var(--c-ink)); }
  .g-ivory, .g-sand, .g-taupe, .g-ink { color: var(--fg); }

  .skip {
    position: absolute; inset-block-start: -100%; inset-inline-start: var(--margin);
    z-index: 200; background: var(--c-ink); color: var(--c-ivory);
    padding: var(--s2) var(--s4);
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-label); letter-spacing: 0.26em; text-transform: uppercase;
  }
  .skip:focus { inset-block-start: var(--s2); }

  /* the materiality layer. grain kills 8-bit banding on a pale palette. */
  .grain {
    position: fixed; inset: 0; z-index: 60; pointer-events: none;
    mix-blend-mode: soft-light; opacity: 0.035;
    background-image: url("../img/grain.svg");
    background-size: 200px 200px;
  }
  @media (max-width: 767px) { .grain { opacity: 0.02; } }
  @media (prefers-contrast: more) { .grain { display: none; } }
}

/* ----------------------------------------------------------------- type */

@layer type {
  h1, h2, h3 { text-wrap: balance; font-weight: 400; }
  p, li, dd, blockquote { text-wrap: pretty; }

  @supports (text-box: trim-both cap alphabetic) {
    /* trim the invisible half-leading so equal padding finally looks equal.
       it moves the box edges, not the glyphs, so nothing that carries a
       descender may sit inside a clipping ancestor. */
    h1, h2, h3, .h2, .h3, .figure, .sig__line { text-box: trim-both cap alphabetic; }
  }

  .h1, h1 {
    font-size: var(--t-h1); line-height: var(--lh-h1);
    letter-spacing: -0.022em; font-weight: 380;
  }
  .h2, h2 {
    font-size: var(--t-h2); line-height: var(--lh-h2);
    letter-spacing: -0.018em; font-weight: 380;
  }
  .h3, h3 {
    font-size: var(--t-h3); line-height: var(--lh-h3);
    letter-spacing: -0.012em; font-weight: 400;
  }
  .lede {
    font-size: var(--t-lede); line-height: var(--lh-lede);
    letter-spacing: -0.006em; max-inline-size: 32em;
  }
  .small { font-size: var(--t-small); line-height: var(--lh-small); }
  .micro { font-size: var(--t-micro); line-height: var(--lh-micro); }

  .prose > * + * { margin-block-start: var(--s4); }
  .prose { max-inline-size: var(--measure); }
  .prose a { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }

  /* every "small cap" on this site is uppercase at a reduced size with
     positive tracking. neither font has smcp; synthesising them reads cheap. */
  .caps {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-label); line-height: var(--lh-label);
    letter-spacing: 0.26em; text-transform: uppercase;
    font-feature-settings: "kern";
  }
  .caps-micro {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-micro); line-height: var(--lh-micro);
    letter-spacing: 0.2em; text-transform: uppercase;
  }

  /* the Impost — small-caps eyebrow. ink, never brass. */
  .impost { color: var(--fg); display: block; }

  .figure {
    font-family: var(--font-display); font-size: var(--t-figure);
    line-height: var(--lh-figure); letter-spacing: -0.02em; font-weight: 300;
    font-variant-numeric: tabular-nums;
  }

  .tabular, .tariff, .hours, .spec { font-variant-numeric: tabular-nums; }

  .marginalia {
    font-size: var(--t-micro); line-height: 1.5;
    color: var(--fg-soft); max-inline-size: 22em; font-style: italic;
  }

  .folio {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-micro); letter-spacing: 0.2em; text-transform: uppercase;
  }

  em, i, .it { font-style: italic; }
  strong, b { font-weight: 560; }
  .woods { color: var(--c-woods); }
}

/* --------------------------------------------------------------- layout */

@layer layout {
  .wrap {
    inline-size: 100%;
    margin-inline: auto;
    padding-inline: var(--margin);
    max-inline-size: 1680px;
  }

  /* ---- the section head ----
     The label sits above the heading at the page margin, and the content
     below it uses the full measure of the page. A section never opens in the
     middle third of the screen with dead ground either side of it. */
  .head-block { max-inline-size: 22ch; }
  .sect__label { color: var(--fg-soft); }
  .sect__h {
    margin-block-start: var(--s4);
    max-inline-size: 18ch;
    font-size: clamp(2.1rem, 4vw, 3.4rem);
    line-height: 1.06;
    letter-spacing: -0.02em;
    font-weight: 380;
  }
  .sect__h--wide { max-inline-size: 26ch; }
  .sect__lede {
    margin-block-start: var(--s6);
    max-inline-size: 40ch;
    font-size: var(--t-lede); line-height: var(--lh-lede);
  }
  .sect__note { margin-block-start: var(--s4); max-inline-size: 46ch; }
  .sect__body { margin-block-start: var(--s12); }
  @media (max-width: 767px) { .sect__body { margin-block-start: var(--s8); } }

  /* a head that puts the note opposite the heading rather than under it */
  .head-split { display: grid; gap: var(--s6); align-items: end; }
  @media (min-width: 900px) {
    .head-split {
      grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
      column-gap: var(--s12);
    }
    .head-split > :last-child { padding-block-end: var(--s2); }
  }

  /* content grids that actually fill the page */
  .grid-3 { display: grid; gap: var(--s8) var(--gutter); }
  .grid-2 { display: grid; gap: var(--s8) var(--gutter); }
  @media (min-width: 700px) { .grid-2 { grid-template-columns: repeat(2, 1fr); } }
  @media (min-width: 900px) { .grid-3 { grid-template-columns: repeat(3, 1fr); } }

  /* ---- the spine ----
     The section label and its marginalia sit on one line above the heading,
     at the page margin, and the content below runs the full measure. An
     earlier version put them in a narrow left column, which left every
     section starting in the middle third of the screen with dead ground on
     both sides. This is the same information, arranged so the page fills. */
  .spread { display: block; }

  .spread > .rail {
    display: flex; flex-direction: row; flex-wrap: wrap;
    align-items: baseline;
    gap: var(--s2) var(--s8);
    margin-block-end: var(--s6);
  }
  .spread > .rail .marginalia {
    max-inline-size: 46ch; margin: 0;
    font-size: var(--t-small); line-height: 1.5;
  }
  .spread > .rail > .fig, .spread > .rail > figure { display: none; }

  .spread > .field > h2:not(.vh),
  .spread > .field > .h2 {
    max-inline-size: 20ch;
    font-size: clamp(2.1rem, 4vw, 3.4rem);
    line-height: 1.06;
    letter-spacing: -0.02em;
  }
  .spread > .field > h2.measure, .spread > .field > .h2.measure { max-inline-size: 20ch; }
  .spread > .field > .mt-8 { margin-block-start: var(--s12); }

  .rail { display: flex; flex-direction: column; gap: var(--s2); }

  /* section padding is never uniform: sections after a plate open tight,
     sections before one close wide. */
  .band { padding-block: var(--s16); position: relative; }
  .band--tight { padding-block: var(--s8) var(--s12); }
  .band--wide  { padding-block: var(--s16) var(--s24); }
  .band--close { padding-block: var(--s12) var(--s24); }
  .band--open  { padding-block: var(--s24) var(--s16); }
  /* two full exits stacked on a join read as a hole — keep the wide
     close before a plate, but don't restack a full entry on top of it */
  .band--tight + .band--close { padding-block-start: var(--s6); }
  .band--tight:has(+ .band--close) { padding-block-end: var(--s6); }
  @media (max-width: 767px) {
    .band { padding-block: var(--s12); }
    .band--wide, .band--open { padding-block: var(--s16) var(--s16); }
    .band--close { padding-block: var(--s8) var(--s16); }
    .band--tight + .band--close { padding-block-start: var(--s4); }
    .band--tight:has(+ .band--close) { padding-block-end: var(--s4); }
  }

  .cols { display: grid; gap: var(--s6) var(--gutter); }
  .cols-2 { grid-template-columns: 1fr; }
  .cols-3 { grid-template-columns: 1fr; }
  .cols-5 { grid-template-columns: 1fr; }
  @media (min-width: 640px) {
    .cols-2 { grid-template-columns: repeat(2, 1fr); }
    .cols-5 { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 900px) {
    .cols-3 { grid-template-columns: repeat(3, 1fr); }
    .cols-5 { grid-template-columns: repeat(3, 1fr); }
  }
  @media (min-width: 1100px) {
    /* five, where the eye expects four. one of the three deliberate breaks. */
    .cols-5 { grid-template-columns: repeat(5, 1fr); }
  }

  .stack > * + * { margin-block-start: var(--s4); }
  .stack-2 > * + * { margin-block-start: var(--s2); }
  .stack-6 > * + * { margin-block-start: var(--s6); }
  .stack-8 > * + * { margin-block-start: var(--s8); }
}

/* ----------------------------------------------------------------- rule */

@layer rule {
  /* a rule is one true device pixel on every display, and it is the thing
     that carries the Skirting. never a bare <hr>. */
  .rule {
    position: relative; display: block;
    block-size: 1px; border: 0; margin: 0;
    background: var(--rule-rest);
    transform: scaleY(var(--hairline));
    transform-origin: 0 100%;
  }
  .rule--warm { background: color-mix(in oklab, var(--c-brass) 46%, transparent); }
  .rule--ink  { background: color-mix(in oklab, var(--c-ivory) 26%, transparent); }
  .rule--woods { background: var(--c-woods); }

  /* rr — a ruled register row. ::before is the rule at rest, ::after is the
     warm state and its bloom, pre-composited so only opacity ever animates. */
  .rr { position: relative; }
  .rr::before {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
    block-size: 1px; background: var(--rule-rest);
    transform: scaleY(var(--hairline)); transform-origin: 0 100%;
    pointer-events: none;
  }
  .rr--top::before { inset-block-end: auto; inset-block-start: 0; transform-origin: 0 0; }
  .rr--woods::before { background: var(--c-woods); opacity: 0.85; }
  .rr--none::before { display: none; }

  .rule::after, .rr::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
    block-size: 1px; background: var(--rule-warm);
    box-shadow: 0 -1px 96px -32px color-mix(in oklab, var(--c-brass) 55%, transparent);
    opacity: 0; pointer-events: none;
    will-change: opacity;
  }
  .rr--top::after { inset-block-end: auto; inset-block-start: 0; }

  /* the Skirting. every rule beneath what you are reading warms from grey to
     brass and blooms upward, then cools behind you. compositor-only. */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .rule::after, .rr::after {
        animation: skirting linear both;
        animation-timeline: view();
        animation-range: cover 34% cover 66%;
      }
    }
  }
  @keyframes skirting { 0%, 100% { opacity: 0 } 50% { opacity: 1 } }

  @media (prefers-reduced-motion: reduce) {
    .rule::after, .rr::after { opacity: 0.45; }
  }

  /* on a dark ground the warm line reads as champagne, not brass */
  .g-ink .rule, .g-ink .rr::before { background: color-mix(in oklab, var(--c-ivory) 24%, transparent); }
  .g-ink .rule::after, .g-ink .rr::after {
    background: var(--c-champagne);
    box-shadow: 0 -1px 96px -32px color-mix(in oklab, var(--c-champagne) 60%, transparent);
  }
}

/* ----------------------------------------------------------- components */

@layer components {

  /* ---- buttons. one solid per viewport. every affordance is a word. ---- */
  .btn {
    display: inline-block;
    background: var(--c-ink); color: var(--c-ivory);
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-label); line-height: var(--lh-label);
    letter-spacing: 0.26em; text-transform: uppercase;
    padding: 16px 26px; border: 0; text-decoration: none;
    transition: background var(--d-ui) var(--ease-ui);
    min-block-size: 50px;
  }
  .btn:hover { background: oklch(28% 0.006 68); }
  .btn:focus-visible { outline: 2px solid var(--c-ink); outline-offset: 3px; }
  /* on a photograph the ring needs an ivory outer so it holds 3:1 anywhere */
  .on-plate .btn:focus-visible {
    outline: 2px solid var(--c-ink);
    outline-offset: 3px;
    box-shadow: 0 0 0 5px var(--c-ivory);
  }
  .btn--ivory { background: var(--c-ivory); color: var(--c-ink); }
  .btn--ivory:hover { background: color-mix(in oklab, var(--c-ivory) 88%, var(--c-ink)); }

  /* secondary actions are text links with a 1px underline, never outlined
     buttons. the underline draws in from the left on hover. */
  .tlink {
    position: relative; text-decoration: none; color: inherit;
    font-style: italic;
    padding-block-end: 2px;
  }
  .tlink::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
    block-size: 1px; background: currentColor; opacity: 0.42;
    transform-origin: 0 50%;
    transition: opacity var(--d-ui) var(--ease-ui), transform var(--d-ui) var(--ease-ui);
  }
  .tlink:hover::after { opacity: 1; transform: scaleX(1.04); }
  .tlink--caps { font-style: normal; }

  .actions {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: var(--s4) var(--s6);
  }

  /* ---- header ----
     Over the plate: one light backdrop blur (design system §8 — never three
     stacked layers). Solidifies into the ivory glass once the sentinel clears. */
  .head {
    position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 50;
    block-size: var(--header-h);
    display: flex; align-items: center;
    background: color-mix(in oklab, var(--c-ivory) 28%, transparent);
    -webkit-backdrop-filter: blur(12px) saturate(1.05);
    backdrop-filter: blur(12px) saturate(1.05);
    transition: background 260ms var(--ease-ui), color 260ms var(--ease-ui);
    color: var(--c-ink);
  }
  .head__in {
    inline-size: 100%; max-inline-size: 1680px; margin-inline: auto;
    padding-inline: var(--margin);
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s4);
  }
  .head::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
    block-size: 1px; background: var(--rule-rest);
    opacity: 0; transition: opacity 260ms var(--ease-ui);
  }
  .head.is-solid {
    background: color-mix(in oklab, var(--c-ivory) 88%, transparent);
    -webkit-backdrop-filter: blur(14px) saturate(1.1);
    backdrop-filter: blur(14px) saturate(1.1);
  }
  .head.is-solid::after { opacity: 1; }

  /* the wordmark is one cached SVG painted through a mask, so it takes
     currentColor without being inlined into twenty-two documents */
  .brand {
    display: block; line-height: 0; color: var(--c-champagne);
    inline-size: fit-content; flex-shrink: 0;
  }
  .head .brand { view-transition-name: brand; }
  .brand::before {
    content: ""; display: block;
    block-size: 28px; aspect-ratio: 237.85 / 85.87;
    background: currentColor;
    -webkit-mask: url("../brand/wordmark.svg") no-repeat center / contain;
    mask: url("../brand/wordmark.svg") no-repeat center / contain;
  }
  @media (min-width: 768px) { .brand::before { block-size: 32px; } }
  .brand--lockup::before {
    aspect-ratio: 237.85 / 126.62;
    block-size: 96px;
    -webkit-mask-image: url("../brand/lockup.svg");
    mask-image: url("../brand/lockup.svg");
  }

  .nav { display: none; }
  @media (min-width: 1024px) {
    .nav { display: flex; align-items: center; gap: var(--s6); }
  }
  .nav a {
    position: relative; text-decoration: none; padding-block: var(--s2);
    color: inherit;
  }
  .nav a::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 0;
    block-size: 1px; background: currentColor;
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform var(--d-ui) var(--ease-ui);
  }
  .nav a:hover::after, .nav a[aria-current="page"]::after { transform: scaleX(1); }
  .nav a[aria-current="page"]::after { background: var(--c-brass); }

  .head__end { display: flex; align-items: center; gap: var(--s3); }
  .head .btn { padding: 12px 20px; min-block-size: 44px; }
  @media (max-width: 1023px) { .head .btn { display: none; } }

  /* the opener is the word Menu. there are no icons on this site. */
  .menu-btn {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-label); letter-spacing: 0.26em; text-transform: uppercase;
    padding: 14px 2px; color: inherit; position: relative;
  }
  .menu-btn::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 10px;
    block-size: 1px; background: currentColor; opacity: 0.5;
    transition: opacity var(--d-ui) var(--ease-ui);
  }
  .menu-btn:hover::after { opacity: 1; }
  @media (min-width: 1024px) { .menu-btn { display: none; } }

  /* ---- the drawer. a register bound in ink. ---- */
  .drawer {
    position: fixed; inset: 0; z-index: 90;
    visibility: hidden;
    pointer-events: none;
  }
  .drawer[data-open="true"] { visibility: visible; pointer-events: auto; }
  .drawer__scrim {
    position: absolute; inset: 0;
    background: color-mix(in oklab, var(--c-ink) 62%, transparent);
    opacity: 0;
    transition: opacity var(--d-overlay) var(--ease-large);
  }
  .drawer[data-open="true"] .drawer__scrim { opacity: 1; }

  .drawer__panel {
    position: absolute; inset-block: 0; inset-inline-end: 0;
    inline-size: min(100%, 460px);
    background: var(--c-ink); color: var(--c-ivory);
    --fg: var(--c-ivory); --fg-soft: color-mix(in oklab, var(--c-ivory) 72%, var(--c-ink));
    display: flex; flex-direction: column;
    overflow-y: auto; overscroll-behavior: contain;
    padding: 0 var(--margin) calc(var(--s8) + env(safe-area-inset-bottom));
    transform: translateX(100%);
    transition: transform 520ms var(--ease-large);
  }
  .drawer[data-open="true"] .drawer__panel { transform: translateX(0); }

  /* the chevron of the batten wall, at the faintest legible strength */
  .drawer__panel::before {
    content: ""; position: absolute; inset: 0; pointer-events: none;
    background-image: url("../img/chevron.svg");
    background-size: 240px 140px; opacity: 0.16;
    mask-image: linear-gradient(to bottom, transparent 42%, var(--c-ink) 100%);
  }
  .drawer__panel > * { position: relative; }

  .drawer__top {
    block-size: var(--header-h); flex: 0 0 auto;
    display: flex; align-items: center; justify-content: space-between;
  }
  .drawer__top .brand svg { color: var(--c-champagne); }
  .drawer__close {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-label); letter-spacing: 0.26em; text-transform: uppercase;
    color: var(--c-ivory); padding: 14px 2px; position: relative;
  }
  .drawer__close::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: 10px;
    block-size: 1px; background: currentColor; opacity: 0.5;
  }

  .drawer__nav { margin-block-start: var(--s4); }
  .drawer__nav a {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s4);
    text-decoration: none;
    padding-block: var(--s3);
    font-size: 1.5rem; line-height: 1.2; letter-spacing: -0.012em;
    color: var(--c-ivory);
    transition: color var(--d-ui) var(--ease-ui);
  }
  .drawer__nav a:hover { color: var(--c-champagne); }
  .drawer__nav a span {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-micro); letter-spacing: 0.2em; text-transform: uppercase;
    color: color-mix(in oklab, var(--c-ivory) 56%, var(--c-ink));
  }
  /* the drawer's items arrive in sequence, at the house tempo */
  .drawer__nav .rr, .drawer__foot > * {
    opacity: 0; transform: translateY(14px);
  }
  .drawer[data-open="true"] .drawer__nav .rr,
  .drawer[data-open="true"] .drawer__foot > * {
    opacity: 1; transform: none;
    transition: opacity 560ms var(--ease-house) calc(90ms + var(--i, 0) * 42ms),
                transform 560ms var(--ease-house) calc(90ms + var(--i, 0) * 42ms);
  }
  .drawer__foot { margin-block-start: auto; padding-block-start: var(--s8); }
  .drawer__foot > *:nth-child(1) { --i: 6 }
  .drawer__foot > *:nth-child(2) { --i: 7 }
  .drawer__foot > *:nth-child(3) { --i: 8 }
  .drawer__foot > *:nth-child(4) { --i: 9 }
  .drawer__foot .btn { inline-size: 100%; text-align: center; }

  @media (prefers-reduced-motion: reduce) {
    .drawer__panel { transition: none; }
    .drawer__nav .rr, .drawer__foot > * { opacity: 1; transform: none; transition: opacity 200ms linear; }
  }

  /* ---- plates ---- */
  .plate {
    position: relative; overflow: clip; background: var(--c-sand);
    display: grid; isolation: isolate;
  }
  .plate > * { grid-area: 1 / 1; }
  .plate__fig { position: relative; overflow: clip; block-size: 100%; }
  .plate__fig img { inline-size: 100%; block-size: 100%; object-fit: cover; }

  .plate--ii, .plate--iii { aspect-ratio: 4 / 3; }
  @media (min-width: 768px) {
    .plate--ii  { aspect-ratio: auto; block-size: 72vh; min-block-size: 460px; }
    .plate--iii { aspect-ratio: auto; block-size: 62vh; min-block-size: 400px; }
  }

  .plate__folio {
    position: absolute; z-index: 3;
    inset-inline-start: var(--margin); inset-block-end: var(--s4);
    color: var(--c-ink);
  }
  .plate__caption { align-self: end; z-index: 3; padding-block-end: var(--s16); }
  .plate__line { color: var(--c-ink); max-inline-size: 22em; }
  @media (max-width: 767px) { .plate__caption { padding-block-end: var(--s12); } }

  /* a 30% ivory scrim lifts the type quadrant. never a dark overlay. */
  .scrim-ivory::before {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: linear-gradient(
      100deg,
      color-mix(in oklab, var(--c-ivory) 72%, transparent) 0%,
      color-mix(in oklab, var(--c-ivory) 60%, transparent) 30%,
      color-mix(in oklab, var(--c-ivory) 34%, transparent) 52%,
      transparent 72%);
  }
  .scrim-ivory--bottom::before {
    background: linear-gradient(to top,
      color-mix(in oklab, var(--c-ivory) 58%, transparent) 0%,
      transparent 46%);
  }
  /* right-hand type quadrant — Plate III's empty wall */
  .scrim-ivory--end::before {
    background: linear-gradient(to left,
      color-mix(in oklab, var(--c-ivory) 78%, transparent) 0%,
      color-mix(in oklab, var(--c-ivory) 52%, transparent) 34%,
      transparent 62%);
  }
  @media (max-width: 899px) {
    .scrim-ivory--end::before { background: none; }
  }

  /* ---- 01 · the threshold ---- */
  .hero { position: relative; }
  .hero__plate { position: relative; aspect-ratio: 16 / 9; overflow: clip; background: var(--c-sand); }
  .hero__plate img { inline-size: 100%; block-size: 100%; object-fit: cover; }
  .hero .wrap { position: relative; z-index: 3; }
  .hero__type { padding-block: var(--s8) var(--s12); }
  .hero__body { margin-block-start: var(--s6); }
  .hero__note { margin-block-start: var(--s4); color: var(--c-grey); }

  @media (min-width: 900px) {
    .hero {
      display: grid;
      min-block-size: 100dvh;
    }
    .hero > * { grid-area: 1 / 1; }
    .hero__plate { aspect-ratio: auto; block-size: 100%; }
    .hero .wrap { position: static; align-self: start; z-index: 3; }
    .hero__type {
      inline-size: min(52%, 760px);
      padding-block: max(calc(var(--header-h) + var(--s8)), 15vh) 0;
    }
    .hero__body { max-inline-size: 28em; }
  }
  @media (min-width: 1280px) { .hero__type { inline-size: min(50%, 800px); } }

  /* line reveal, by line, never by character */
  .ln {
    display: block; overflow: hidden;
    padding-block: 0.22em 0.22em;
    margin-block: -0.22em -0.22em;
  }
  .ln > i {
    display: block; font-style: inherit;
    transform: translateY(102%);
  }
  html.ready .ln > i {
    transform: translateY(0);
    transition: transform 900ms var(--ease-house) calc(var(--i, 0) * 92ms);
  }
  @media (prefers-reduced-motion: reduce) {
    .ln { overflow: visible; }
    .ln > i { transform: none; opacity: 0; }
    html.ready .ln > i { opacity: 1; transition: opacity 220ms linear calc(var(--i,0) * 60ms); }
  }

  /* ---- page heads (everything that is not the homepage) ---- */
  .pagehead { padding-block: calc(var(--header-h) + var(--s8)) var(--s8); }
  .pagehead__grid { display: grid; gap: var(--s8); }
  @media (min-width: 900px) {
    .pagehead { padding-block: calc(var(--header-h) + var(--s16)) var(--s12); }
    .pagehead__grid {
      grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
      column-gap: var(--s12); align-items: end;
    }
  }
  .pagehead h1 { margin-block-start: var(--s4); }
  .pagehead .lede { margin-block-start: var(--s6); }
  .pagehead__fig { overflow: clip; }
  .pagehead__fig img { inline-size: 100%; }

  /* the plate on a page head opens once, from the bottom edge */
  @media (prefers-reduced-motion: no-preference) {
    html.ready .pagehead__fig img {
      animation: head-open 1000ms var(--ease-house) 120ms both;
    }
  }
  @keyframes head-open {
    from { clip-path: inset(100% 0 0 0); transform: scale(1.06); }
    to   { clip-path: inset(0 0 0 0); transform: scale(1); }
  }

  /* ---- comparison register ---- */
  .compare th, .compare td {
    padding-block: var(--s3); vertical-align: baseline;
    font-size: var(--t-small); line-height: var(--lh-small);
  }
  .compare thead th {
    font-family: var(--font-label); font-weight: 300; font-size: var(--t-micro);
    letter-spacing: 0.2em; text-transform: uppercase; color: var(--fg-soft);
  }
  .compare th[scope="row"] { padding-inline-end: var(--s4); font-weight: 400; }
  .compare td { padding-inline-end: var(--s4); }
  .compare td:last-child, .compare th:last-child { padding-inline-end: 0; }
  .scroller { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .scroller table { min-inline-size: 34rem; }

  /* ---- fitzpatrick register ---- */
  .fitz { display: grid; gap: 0; }
  .fitz__row {
    display: grid; grid-template-columns: 3.2rem 1fr;
    gap: var(--s1) var(--s4); padding-block: var(--s4);
  }
  @media (min-width: 768px) {
    .fitz__row { grid-template-columns: 3.2rem minmax(0, 1fr) 13rem; align-items: baseline; }
  }
  .fitz__no { font-family: var(--font-label); font-weight: 300; font-size: var(--t-label); letter-spacing: 0.2em; color: var(--fg-soft); }
  .fitz__verdict {
    font-family: var(--font-label); font-weight: 300; font-size: var(--t-micro);
    letter-spacing: 0.2em; text-transform: uppercase; grid-column: 2 / -1;
  }
  @media (min-width: 768px) { .fitz__verdict { grid-column: 3; text-align: end; } }

  /* ---- treatment index (the hub) ---- */
  .entry { display: block; padding-block: var(--s8); text-decoration: none; color: inherit; }
  .entry__name { font-size: var(--t-h3); line-height: 1.18; letter-spacing: -0.012em; position: relative; display: inline-block; }
  .entry__name::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: -6px; block-size: 1px;
    background: var(--c-brass); transform: scaleX(0); transform-origin: 0 50%;
    transition: transform 320ms var(--ease-ui);
  }
  .entry:hover .entry__name::after, .entry:focus-visible .entry__name::after { transform: scaleX(1); }
  .entry__grid { display: grid; gap: var(--s4); }
  @media (min-width: 900px) {
    .entry__grid { grid-template-columns: 5rem minmax(0, 1fr) minmax(0, 1fr) 8rem; column-gap: var(--gutter); align-items: start; }
  }
  .entry__meta { font-family: var(--font-label); font-weight: 300; font-size: var(--t-label); letter-spacing: 0.16em; text-transform: uppercase; font-variant-numeric: tabular-nums; }
  @media (min-width: 900px) { .entry__meta { text-align: end; } }
  .entry__fig { overflow: clip; }
  .entry__fig img { inline-size: 100%; aspect-ratio: 3 / 2; object-fit: cover; transition: transform 900ms var(--ease-house); }
  .entry:hover .entry__fig img { transform: scale(1.04); }

  /* ---- team register ---- */
  .team { display: grid; gap: var(--s12) var(--gutter); }
  @media (min-width: 700px) { .team { grid-template-columns: repeat(2, 1fr); } }
  @media (min-width: 1180px) { .team { grid-template-columns: repeat(4, 1fr); } }
  .team__fig { overflow: clip; }
  .team__fig img { inline-size: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
  /* where we do not hold photography consent, the portrait is set rather than
     shot. same 4:5 frame, so the register still reads as one thing. */
  .team__plate {
    aspect-ratio: 4 / 5; background: var(--c-sand);
    display: grid; align-content: end;
    padding: var(--s6);
    --fg-soft: var(--c-ink);
  }
  .team__plate span {
    font-size: var(--t-h2); line-height: 1.06; letter-spacing: -0.018em;
    font-weight: 340;
  }
  .team__plate::before {
    content: ""; display: block; block-size: 1px; background: var(--c-brass);
    margin-block-end: var(--s4); inline-size: 2.4rem;
  }

  /* the Record on the plate. ink, because ivory measured 1.49:1 here. */
  .hero__record {
    display: none; z-index: 3; color: var(--c-ink);
    text-align: end;
  }
  .hero__record .caps-micro { color: var(--c-grey); display: block; margin-block-end: var(--s2); }
  .hero__record .figure { font-weight: 280; }
  @media (min-width: 900px) {
    .hero__record {
      display: block;
      position: sticky; inset-block-end: var(--s8);
      align-self: end; justify-self: end;
      inline-size: min(14em, 26vw);
      margin-inline-end: var(--margin);
      margin-block-end: var(--s8);
    }
  }
  .hero__record .rule { margin-block-end: var(--s2); inline-size: 100%; }
  .hero__record .ln { padding-block-end: 0.14em; margin-block-end: -0.14em; }
  html.ready .hero__record { animation: rec-in 900ms var(--ease-house) 520ms both; }
  @keyframes rec-in { from { opacity: 0 } to { opacity: 1 } }
  @media (prefers-reduced-motion: reduce) { html.ready .hero__record { animation-duration: 200ms; } }

  /* ---- the index band ---- */
  .index__col { padding-block-start: var(--s4); }
  .index__col .impost { margin-block-end: var(--s3); }
  .index__col p { font-size: var(--t-small); line-height: var(--lh-small); }

  /* ---- the protocols ----
     Label and note share one baseline; the H2 sits under them. That stops
     the old end-aligned head-split leaving a dead band under the impost. */
  .proto-head { margin: 0; }
  .proto-head__row {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s3) var(--s8);
    margin-block-end: var(--s3);
  }
  .proto-head .sect__h { margin-block-start: 0; }
  .proto-head__row .impost { margin: 0; }
  .proto-head__row .small {
    margin: 0;
    max-inline-size: 38em;
    text-wrap: pretty;
  }
  @media (min-width: 900px) {
    .proto-head__row .small { text-align: end; }
  }

  /* tip-ins down the left edge — laser takes the whole measure as a half-plate */
  .protocols { display: block; }

  .protocol {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: var(--s2) var(--s4);
    padding-block: var(--s6);
    text-decoration: none; color: inherit;
    align-items: start;
  }
  /* mobile: the plate spans, then number and name share a line, and the
     description and price take the full measure beneath. Without explicit
     placement the description lands in the 3.4rem number column. */
  .protocol__fig  { display: block; grid-column: 1 / -1; grid-row: 1;
                    overflow: clip; margin-block-end: var(--s4); }
  .protocol__no   { grid-column: 1; grid-row: 2; }
  .protocol__name { grid-column: 2; grid-row: 2; }
  .protocol__line { grid-column: 2; grid-row: 3; }
  .protocol__from { grid-column: 2; grid-row: 4; }
  .protocol__fig img {
    inline-size: 100%; aspect-ratio: 16 / 10; object-fit: cover;
    transition: transform 900ms var(--ease-house), filter 900ms var(--ease-house);
  }
  .protocol:hover .protocol__fig img { transform: scale(1.045); }

  @media (min-width: 900px) {
    .protocol {
      grid-template-columns:
        minmax(0, 3fr) 3.4rem minmax(0, 4fr) minmax(0, 4fr) 7rem;
      column-gap: var(--gutter);
      padding-block: var(--s8);
      align-items: center;
    }
    .protocol__fig  { grid-column: 1; grid-row: 1; margin-block-end: 0; }
    .protocol__fig img { aspect-ratio: 3 / 2; }
    .protocol__no   { grid-column: 2; grid-row: 1; padding-block-start: 0; align-self: center; }
    .protocol__name { grid-column: 3; grid-row: 1; }
    .protocol__line { grid-column: 4; grid-row: 1; }
    .protocol__from { grid-column: 5; grid-row: 1; }
  }

  /* deliberate break 1 — the only treatment that matters commercially takes
     the whole measure, and its plate is a band rather than a tipped-in crop.
     Padding lives on the text row (not the whole block) so the band between
     the plate edge and the next rule is even above and below the copy. */
  .protocol--break { display: block; padding-block: 0; }
  .protocol--break .protocol__fig { margin-block-end: 0; display: block; }
  .protocol--break .protocol__fig img { aspect-ratio: 16 / 7; }
  .protocol--break .protocol__name {
    font-size: var(--t-h2); line-height: 1.08; letter-spacing: -0.018em;
    justify-self: start; /* keep the hover rule the width of the words */
  }
  .protocol--break .protocol__row {
    display: grid; gap: var(--s2) var(--s4);
    grid-template-columns: 3.4rem minmax(0, 1fr);
    align-items: start;
    padding-block: var(--s8);
  }
  .protocol--break .protocol__no   { grid-column: 1; grid-row: 1; }
  .protocol--break .protocol__name { grid-column: 2; grid-row: 1; }
  .protocol--break .protocol__line { grid-column: 2; grid-row: 2; }
  .protocol--break .protocol__from { grid-column: 2; grid-row: 3; }
  @media (min-width: 900px) {
    /* the featured row has no tipped-in crop — its plate is the full-width
       band above it — so its columns start at the page margin instead.
       grid-row must be reset: the mobile rules park line/from on rows 2–3,
       which is what left the name hanging alone on row 1. */
    .protocol--break .protocol__row {
      grid-template-columns: 3.4rem minmax(0, 6fr) minmax(0, 5fr) 7rem;
      column-gap: var(--gutter);
      align-items: center;
      padding-block: var(--s8);
    }
    .protocol--break .protocol__no   { grid-column: 1; grid-row: 1; padding-block-start: 0; }
    .protocol--break .protocol__name { grid-column: 2; grid-row: 1; }
    .protocol--break .protocol__line { grid-column: 3; grid-row: 1; }
    .protocol--break .protocol__from { grid-column: 4; grid-row: 1; text-align: end; }
  }
  .protocol__no {
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-micro); letter-spacing: 0.2em;
    color: var(--fg-soft); padding-block-start: 0.55em;
  }
  .protocol__name {
    font-size: var(--t-h3); line-height: 1.18; letter-spacing: -0.012em;
    position: relative; display: inline-block;
  }
  .protocol__name::after {
    content: ""; position: absolute; inset-inline: 0; inset-block-end: -6px;
    block-size: 1px; background: var(--c-brass);
    transform: scaleX(0); transform-origin: 0 50%;
    transition: transform 320ms var(--ease-ui);
  }
  .protocol:hover .protocol__name::after,
  .protocol:focus-visible .protocol__name::after { transform: scaleX(1); }
  .protocol__line { color: var(--fg-soft); font-size: var(--t-small); line-height: var(--lh-small); }
  .protocol__from {
    font-family: var(--font-label); font-weight: 300; font-size: var(--t-label);
    letter-spacing: 0.16em; text-transform: uppercase;
    font-variant-numeric: tabular-nums;
  }
  @media (min-width: 900px) { .protocol__from { text-align: end; } }
  /* price lands a beat after the row — register ledger, not a second system */
  @media (prefers-reduced-motion: no-preference) {
    .protocol .protocol__from {
      opacity: 0;
      transform: translateY(8px);
    }
    .protocol.is-in .protocol__from {
      opacity: 1;
      transform: none;
      transition:
        opacity var(--d-reveal) var(--ease-house) 220ms,
        transform var(--d-reveal) var(--ease-house) 220ms;
    }
  }


  /* ---- the tariff ---- */
  .tariff caption {
    text-align: start; padding-block-end: var(--s4);
    color: var(--fg-soft);
  }
  .tariff th, .tariff td { padding-block: var(--s3); vertical-align: baseline; }
  .tariff th { font-weight: 400; }
  .tariff thead th {
    font-family: var(--font-label); font-weight: 300; font-size: var(--t-micro);
    letter-spacing: 0.2em; text-transform: uppercase; color: var(--fg-soft);
    padding-block-end: var(--s2);
  }
  .tariff td { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }
  .tariff th[scope="row"] { display: flex; align-items: baseline; gap: 6px; padding-inline-end: var(--s4); }
  /* dotted leaders live inside the one cell — they cannot span a boundary */
  .ldr {
    flex: 1 1 auto; min-inline-size: 24px; align-self: baseline;
    block-size: 1em;
    background-image: radial-gradient(circle at 1px 0.72em, currentColor 0.8px, transparent 0.9px);
    background-size: 6px 100%; background-repeat: repeat-x;
    opacity: 0.3;
    transition: opacity var(--d-ui) var(--ease-ui);
  }
  .tariff tr:hover .ldr { opacity: 0.62; color: var(--c-brass); }
  .tariff .is-course td, .tariff .is-course th { font-weight: 500; }
  .tariff .note { color: var(--fg-soft); font-size: var(--t-small); }

  /* ---- the record — one lead voice, two supporting, figure as mast ---- */
  .record {
    display: grid;
    gap: var(--s8);
    align-items: start;
  }
  @media (min-width: 900px) {
    .record {
      grid-template-columns: minmax(12rem, 0.8fr) minmax(0, 1.6fr) minmax(0, 1fr);
      column-gap: var(--s12);
      row-gap: var(--s8);
    }
    .record__mast { grid-column: 1; grid-row: 1 / span 2; }
    .review--lead { grid-column: 2; grid-row: 1 / span 2; }
    .record__side { grid-column: 3; grid-row: 1 / span 2; }
  }
  .record__mast .figure {
    margin-block-start: var(--s2);
    font-size: clamp(3rem, 6vw, 4.5rem);
    line-height: 1;
  }
  .record__mast .rule { max-inline-size: 4.5rem; }
  .record__side { display: grid; gap: 0; }
  .review { padding-block: var(--s6); }
  .review blockquote {
    font-size: var(--t-body); line-height: 1.55;
    letter-spacing: -0.006em; max-inline-size: 34em;
  }
  .review--lead { padding-block: var(--s6) var(--s8); }
  .review--lead blockquote {
    font-size: clamp(1.35rem, 2.2vw, 1.85rem);
    line-height: 1.35; letter-spacing: -0.014em;
    font-weight: 340; max-inline-size: 22em;
  }
  .review figcaption { margin-block-start: var(--s3); color: var(--fg-soft); }

  /* ---- passages — what happens next, as tip-ins not three equal cards ---- */
  .passages { display: block; }
  .passage {
    display: grid;
    grid-template-columns: 3.4rem minmax(0, 1fr);
    gap: var(--s2) var(--s4);
    padding-block: var(--s6);
    align-items: start;
  }
  .passage__fig {
    display: block; grid-column: 1 / -1; grid-row: 1;
    overflow: clip; margin-block-end: var(--s4);
  }
  .passage__fig img {
    inline-size: 100%; aspect-ratio: 16 / 10; object-fit: cover;
    transition: transform 900ms var(--ease-house), filter 900ms var(--ease-house);
  }
  .passage:hover .passage__fig img { transform: scale(1.045); }
  .passage__no {
    grid-column: 1; grid-row: 2;
    font-family: var(--font-label); font-weight: 300;
    font-size: var(--t-micro); letter-spacing: 0.2em;
    color: var(--fg-soft); padding-block-start: 0.55em;
  }
  .passage__copy { grid-column: 2; grid-row: 2; }
  .passage__copy h3 {
    font-size: var(--t-h3); line-height: 1.16; letter-spacing: -0.012em;
  }
  .passage__copy p {
    margin-block-start: var(--s3);
    color: var(--fg-soft);
    font-size: var(--t-small); line-height: var(--lh-small);
    max-inline-size: 36em;
  }
  @media (min-width: 900px) {
    .passage {
      grid-template-columns: minmax(0, 3fr) 3.4rem minmax(0, 8fr);
      column-gap: var(--gutter);
      padding-block: var(--s8);
      align-items: center;
    }
    .passage__fig { grid-column: 1; grid-row: 1; margin-block-end: 0; }
    .passage__fig img { aspect-ratio: 3 / 2; }
    .passage__no { grid-column: 2; grid-row: 1; padding-block-start: 0; align-self: center; }
    .passage__copy { grid-column: 3; grid-row: 1; }
  }

  /* ---- the argument — beige plate + longer right column that
     drops into the taupe Visit band below.
     Section height = plate height; copy overflows into Visit. ---- */
  .argument {
    --argument-reach: var(--s16);
    display: grid;
    background: transparent;
    color: var(--c-ink);
    position: relative;
    z-index: 1;
  }
  .argument__fig {
    position: relative;
    overflow: clip;
    background: var(--c-taupe);
  }
  .argument__fig img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    aspect-ratio: 16 / 10;
    display: block;
  }
  .argument__fig.rv--wipe { --ground: var(--c-taupe); }
  .argument__copy {
    background: var(--c-sand);
    padding: var(--s6) var(--margin) var(--s8);
    display: grid;
    align-content: center;
    gap: var(--s3);
  }
  .argument__copy > .rule { max-inline-size: 4.5rem; }
  .argument__line {
    margin: 0;
    font-size: clamp(1.45rem, 2.6vw, 2.1rem);
    line-height: 1.12;
    letter-spacing: -0.018em;
    font-weight: 380;
    max-inline-size: 18ch;
    text-wrap: balance;
  }
  .argument__body {
    margin: 0;
    max-inline-size: 34em;
    font-size: var(--t-small);
    line-height: var(--lh-small);
  }
  @media (min-width: 900px) {
    .argument {
      --argument-plate: 22rem;
      grid-template-columns: minmax(0, 1.15fr) minmax(16rem, 0.85fr);
      grid-template-rows: var(--argument-plate);
      align-items: start;
      overflow: visible;
    }
    .argument__fig {
      block-size: var(--argument-plate);
    }
    .argument__fig img {
      aspect-ratio: auto;
      block-size: 100%;
      min-block-size: 0;
    }
    .argument__copy {
      block-size: calc(var(--argument-plate) + var(--argument-reach));
      padding-block: var(--s8);
      padding-inline: var(--s6) var(--margin);
      gap: var(--s4);
    }
  }

  .protocols__note { max-inline-size: 46em; }

  /* ---- the clinician, at full scale ---- */
  .clinician { display: grid; gap: var(--s8); align-items: center; }
  @media (min-width: 900px) {
    .clinician {
      grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
      column-gap: var(--s12);
    }
  }
  .clinician__fig { overflow: clip; }
  .clinician__fig img { inline-size: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
  .clinician__copy { display: grid; gap: var(--s6); }
  .clinician__lead { display: grid; gap: var(--s6); }
  .clinician__meta { display: grid; gap: var(--s3); }
  .clinician__meta > :last-child { margin-block-start: var(--s3); }

  /* ---- a detail band: one photograph, one line, between two text sections */
  .detail { position: relative; overflow: clip; }
  .detail__fig { overflow: clip; }
  .detail__fig img { inline-size: 100%; aspect-ratio: 21 / 9; object-fit: cover; }
  @media (max-width: 767px) { .detail__fig img { aspect-ratio: 16 / 10; } }
  .detail__line { margin-block-start: var(--s4); color: var(--fg-soft); }

  /* ---- the clip band. one silent loop per page, never above the fold. ---- */
  .clipband { position: relative; overflow: clip; background: var(--c-sand); }
  .clipband video, .clipband img {
    inline-size: 100%; aspect-ratio: 16 / 9; object-fit: cover; display: block;
  }
  @media (min-width: 900px) { .clipband video, .clipband img { aspect-ratio: 21 / 9; } }
  .clipband__line { padding-block: var(--s4) 0; color: var(--fg-soft); }

  /* ---- the header carries a reading rule: how far through the page you are */
  .head__progress {
    position: absolute; inset-inline: 0; inset-block-end: 0; block-size: 3px;
    background: var(--c-brass); transform: scaleX(0); transform-origin: 0 50%;
    opacity: 0; transition: opacity 260ms var(--ease-ui);
  }
  .head.is-solid .head__progress { opacity: 1; }
  @supports (animation-timeline: scroll()) {
    @media (prefers-reduced-motion: no-preference) {
      .head__progress {
        animation: read linear both;
        animation-timeline: scroll(root block);
      }
    }
  }
  @keyframes read { from { transform: scaleX(0) } to { transform: scaleX(1) } }

  /* ---- the clinician. deliberate break 2 — the Woods rule, not the spacing. ---- */
  .quote {
    position: relative;
    padding-inline-start: var(--s6);
    margin: 0;
  }
  .quote::before {
    content: ""; position: absolute; inset-block: 0; inset-inline-start: 0;
    inline-size: 1px; background: var(--c-woods);
  }
  .quote blockquote {
    font-size: var(--t-h2); line-height: 1.2; letter-spacing: -0.018em;
    font-weight: 340; text-indent: -0.42em;
  }
  @supports (hanging-punctuation: first) {
    .quote blockquote { hanging-punctuation: first; text-indent: 0; }
  }

  /* ---- steps ---- */
  .step { display: grid; grid-template-columns: 2.6rem 1fr; gap: var(--s4); padding-block: var(--s6); }
  .step__no { font-family: var(--font-label); font-weight: 300; font-size: var(--t-micro); letter-spacing: 0.2em; color: var(--fg-soft); padding-block-start: 0.5em; }
  .step h3 { font-size: var(--t-h3); }
  .step p { margin-block-start: var(--s2); color: var(--fg-soft); max-inline-size: var(--measure); }

  /* ---- questions ---- */
  .q { }
  .q summary {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: var(--s4); cursor: pointer; list-style: none;
    padding-block: var(--s4);
    font-size: var(--t-lede); line-height: 1.35; letter-spacing: -0.008em;
  }
  .q summary:hover { color: var(--c-brass); }
  .q summary::after {
    content: "+";
    font-family: var(--font-label); font-weight: 300; font-size: 1.125rem;
    line-height: 1; flex: 0 0 auto; color: var(--fg-soft);
    transition: color var(--d-ui) var(--ease-ui);
  }
  .q[open] summary::after { content: "—"; }
  .q .a { padding-block: 0 var(--s6); color: var(--fg-soft); max-inline-size: var(--measure); }
  .q .a > * + * { margin-block-start: var(--s3); }

  @supports (interpolate-size: allow-keywords) {
    :root { interpolate-size: allow-keywords; }
  }
  @media (prefers-reduced-motion: no-preference) {
    .q::details-content {
      block-size: 0; overflow: hidden;
      transition: block-size var(--d-overlay) var(--ease-large),
                  content-visibility var(--d-overlay) allow-discrete;
    }
    .q[open]::details-content { block-size: auto; }
  }

  /* ---- spec register ---- */
  .spec dl { display: grid; }
  .specrow { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); padding-block: var(--s4); }
  .specrow dt { color: var(--fg-soft); font-size: var(--t-small); }
  .specrow dd { text-align: end; font-variant-numeric: tabular-nums; }
  /* a ruled row carrying one statement, at reading size */
  .line { padding-block: var(--s4); }
  .line p { max-inline-size: var(--measure); }

  /* ---- visit — map as the plate, hours as the register beside it ---- */
  .visit__head { display: grid; gap: var(--s3); margin-block-end: var(--s8); }
  .visit__h {
    margin: 0;
    font-size: clamp(1.85rem, 3.2vw, 2.75rem);
    line-height: 1.08;
    letter-spacing: -0.018em;
    font-weight: 380;
    max-inline-size: 22ch;
  }
  .visit__lede {
    margin: 0;
    max-inline-size: 46ch;
    color: var(--fg-soft);
  }
  .visit__head-row {
    display: grid; gap: var(--s6);
    align-items: end;
  }
  @media (min-width: 900px) {
    .visit__head-row {
      grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
      column-gap: var(--s12);
    }
    .visit__aside {
      text-align: end;
      max-inline-size: 32em;
      justify-self: end;
      padding-block-end: 0.35em;
    }
  }

  .visit__board {
    display: grid;
    gap: var(--s6);
    align-items: stretch;
  }
  @media (min-width: 900px) {
    .visit__board {
      grid-template-columns: minmax(16rem, 0.9fr) minmax(0, 1.4fr);
      column-gap: var(--s8);
    }
  }

  .visit__register {
    display: grid;
    gap: var(--s4);
    align-content: start;
  }
  .visit__register > .impost { margin: 0; }
  .visit__register .hours { margin-block-start: var(--s2); }

  .hours {
    inline-size: 100%;
    border-collapse: collapse;
  }
  .hours th, .hours td {
    padding-block: var(--s2);
    vertical-align: baseline;
    font-size: var(--t-small);
    line-height: var(--lh-small);
  }
  .hours th[scope="row"] {
    display: flex; align-items: baseline; gap: 6px;
    padding-inline-end: var(--s4); font-weight: 400;
  }
  .hours td {
    text-align: end;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
  }
  .hours tr:hover .ldr { opacity: 0.62; color: var(--c-brass); }

  .visit__facts {
    margin: 0;
    display: grid;
  }
  .visit__fact {
    display: grid;
    gap: var(--s2);
    padding-block: var(--s4);
  }
  .visit__fact dt { margin: 0; }
  .visit__fact dd { margin: 0; font-size: var(--t-small); line-height: var(--lh-small); }

  .visit__tel {
    display: inline-block;
    font-size: var(--t-lede);
    line-height: var(--lh-lede);
    letter-spacing: -0.01em;
    text-decoration: none;
    color: inherit;
  }
  .visit__tel:hover { color: var(--c-brass); }
  a.visit__tel.tlink,
  .visit__tel.tlink { font-size: var(--t-lede); }

  .visit__links {
    display: flex; flex-wrap: wrap;
    gap: var(--s3) var(--s6);
    padding-block-start: var(--s4);
    margin: 0;
  }

  .visit-map {
    position: relative;
    overflow: clip;
    background: color-mix(in oklab, var(--c-ink) 6%, var(--c-taupe));
    aspect-ratio: 16 / 10;
    isolation: isolate;
  }
  @media (min-width: 900px) {
    .visit-map {
      aspect-ratio: auto;
      min-block-size: 22rem;
      block-size: 100%;
    }
  }
  .visit-map iframe {
    position: absolute; inset: 0;
    inline-size: 100%; block-size: 100%;
    border: 0;
  }
  /* edge blur + taupe dissolve — centre of the map stays clean */
  .visit-map::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    background:
      linear-gradient(to bottom, var(--c-taupe) 0%, transparent 18%, transparent 82%, var(--c-taupe) 100%),
      linear-gradient(to right, var(--c-taupe) 0%, transparent 14%, transparent 86%, var(--c-taupe) 100%);
    -webkit-mask-image: radial-gradient(ellipse 72% 68% at 50% 50%, transparent 42%, var(--c-ink) 100%);
    mask-image: radial-gradient(ellipse 72% 68% at 50% 50%, transparent 42%, var(--c-ink) 100%);
  }
  /* wipe reveal needs a real child to scale; the iframe is absolute */
  .visit-map.rv--wipe > iframe { transform: none; }
  .visit-map.rv--wipe.is-in > iframe { transform: none; }

  /* homepage visit — pink starts flush with the lounge plate;
     top pad clears most of the beige overhang, kept tight */
  .visit--home.band--tight {
    padding-block: var(--s4) var(--s6);
  }
  .visit--home .visit__head {
    display: grid;
    gap: var(--s2);
    margin-block-end: var(--s3);
  }
  .visit--home .visit__h { max-inline-size: 22ch; }
  @media (min-width: 900px) {
    .visit--home.band--tight {
      padding-block-start: var(--s12);
      padding-block-end: var(--s6);
    }
    .visit--home .visit__board {
      grid-template-columns: minmax(0, 1.4fr) minmax(16rem, 0.85fr);
      column-gap: var(--s8);
    }
  }

  /* ---- signature ----
     The vault dissolves into the sand — atmosphere, not a stuck-on photo.
     Plate runs flush to the colophon; copy keeps its own bottom pad. */
  .sig-band {
    position: relative;
    overflow: clip;
    isolation: isolate;
  }
  .sig-band.band--close { padding-block-end: 0; }
  .sig-band__plate {
    position: absolute;
    inset-inline: 0;
    inset-block-start: 0;
    inset-block-end: 0;
    z-index: 0;
    pointer-events: none;
  }
  .sig-band__plate img {
    display: block;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    object-position: center 35%;
  }
  /* CTA stack unfolds after the ruled book — house stagger */
  @media (prefers-reduced-motion: no-preference) {
    .sig__book.is-in .btn,
    .sig__actions.is-in > * {
      opacity: 1;
      transform: none;
      transition:
        opacity var(--d-reveal) var(--ease-house) calc(var(--j, 0) * 90ms),
        transform var(--d-reveal) var(--ease-house) calc(var(--j, 0) * 90ms);
    }
    .sig__book .btn,
    .sig__actions > * {
      opacity: 0;
      transform: translateY(12px);
    }
    .sig__book .btn { --j: 0 }
    .sig__actions > *:nth-child(1) { --j: 1 }
    .sig__actions > *:nth-child(2) { --j: 2 }
  }
  .sig-band__plate::after {
    content: "";
    position: absolute; inset: 0;
    background: linear-gradient(
      180deg,
      color-mix(in oklab, var(--c-sand) 18%, transparent) 0%,
      color-mix(in oklab, var(--c-sand) 55%, transparent) 55%,
      var(--c-sand) 100%
    );
  }
  @media (max-width: 899px) {
    /* on small screens the plate is a top band; keep a hard dissolve, not a gap */
    .sig-band__plate { inset-block-end: auto; block-size: min(56vw, 300px); }
  }
  @media (min-width: 900px) {
    .sig-band.band--close { padding-block: var(--s12) 0; }
    .sig-band__plate {
      inset-inline-end: auto;
      /* stay under the empty left column — 54% was painting a vertical
         seam through the Signature copy as you scrolled */
      inline-size: 44%;
    }
    .sig-band__plate img { object-position: 42% center; }
    .sig-band__plate::after {
      background: linear-gradient(
        90deg,
        color-mix(in oklab, var(--c-sand) 12%, transparent) 0%,
        color-mix(in oklab, var(--c-sand) 48%, transparent) 38%,
        color-mix(in oklab, var(--c-sand) 92%, transparent) 72%,
        var(--c-sand) 88%,
        var(--c-sand) 100%
      );
    }
  }
  .sig-band > .wrap { position: relative; z-index: 1; }

  .sig {
    display: grid;
    padding-block-start: min(42vw, 220px);
    padding-block-end: var(--s12);
  }
  @media (min-width: 900px) {
    .sig {
      grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
      column-gap: var(--s12);
      padding-block-start: 0;
      padding-block-end: var(--s12);
      min-block-size: 28rem;
      align-items: end;
    }
    .sig__copy { grid-column: 2; }
  }
  .sig__copy {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s6);
  }
  .sig__copy .impost { margin: 0; }
  .sig__line {
    font-size: clamp(2.1rem, 4vw, 3.4rem); line-height: 1.06;
    letter-spacing: -0.02em; max-inline-size: 16ch; font-weight: 380;
    margin: 0;
  }
  /* one rule above the button — no rule below, and no Skirting bloom:
     the upward brass glow was reading as a vertical line through the copy */
  .sig__book {
    display: block;
    inline-size: 100%;
  }
  .sig__book .rule {
    display: block;
    width: 12rem;
    max-width: 100%;
    height: 1px;
    margin: 0;
  }
  .sig__book .rule::after { display: none; }
  .sig__book .btn {
    display: inline-flex;
    margin-block: var(--s6) 0;
  }
  .sig__actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--s3);
    margin: 0;
  }
  .sig__note { margin: 0; max-inline-size: 28em; }

  /* ---- colophon ----
     Flat black marble countertop — veined slab, not a photograph of a bowl.
     Light ink wash keeps type AA; ground is never pure black. */
  .colophon {
    position: relative;
    isolation: isolate;
    overflow: clip;
    padding-block: var(--s16) var(--s8);
    background-color: var(--c-ink);
  }
  .colophon::before {
    content: "";
    position: absolute;
    inset: -16px; /* bleed so the blur doesn't hard-edge */
    z-index: 0;
    pointer-events: none;
    background-color: var(--c-ink);
    background-image:
      linear-gradient(
        180deg,
        color-mix(in oklab, var(--c-ink) 72%, transparent) 0%,
        color-mix(in oklab, var(--c-ink) 55%, transparent) 40%,
        color-mix(in oklab, var(--c-ink) 68%, transparent) 100%
      ),
      url("../img/marble-footer-1920.webp");
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    filter: blur(12px);
    opacity: 0.78;
  }
  @supports (background-image: image-set(url("x") type("image/webp"))) {
    .colophon::before {
      background-image:
        linear-gradient(
          180deg,
          color-mix(in oklab, var(--c-ink) 72%, transparent) 0%,
          color-mix(in oklab, var(--c-ink) 55%, transparent) 40%,
          color-mix(in oklab, var(--c-ink) 68%, transparent) 100%
        ),
        image-set(
          url("../img/marble-footer-1920.avif") type("image/avif"),
          url("../img/marble-footer-1920.webp") type("image/webp")
        );
    }
  }
  @media (max-width: 899px) {
    .colophon::before {
      filter: blur(10px);
      opacity: 0.72;
      background-image:
        linear-gradient(
          180deg,
          color-mix(in oklab, var(--c-ink) 76%, transparent) 0%,
          color-mix(in oklab, var(--c-ink) 60%, transparent) 50%,
          color-mix(in oklab, var(--c-ink) 72%, transparent) 100%
        ),
        url("../img/marble-footer-1280.webp");
    }
  }
  @media (prefers-contrast: more) {
    .colophon::before { background-image: none; }
  }
  .colophon > .wrap { position: relative; z-index: 1; }
  .colophon__top { display: grid; gap: var(--s8); align-items: end; margin-block-end: var(--s12); }
  @media (min-width: 900px) {
    .colophon__top { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--s12); }
    .colophon__top > :last-child { justify-self: end; text-align: end; }
  }
  .colophon__say { font-size: clamp(1.4rem, 2.2vw, 2rem); line-height: 1.2; letter-spacing: -0.014em; max-inline-size: 20ch; }
  .colophon .cols-5 { column-gap: var(--gutter); }
  @media (max-width: 639px) {
    .colophon .cols-5 { grid-template-columns: repeat(2, 1fr); row-gap: var(--s8); }
    .colophon__top { gap: var(--s6); }
  }
  .colophon a { text-decoration: none; }
  .colophon ul { list-style: none; padding: 0; margin: 0; }
  .colophon a:hover { color: var(--c-champagne); }
  .colophon__col p, .colophon__col li { font-size: var(--t-small); line-height: var(--lh-small); color: var(--fg-soft); }
  .colophon__col .impost { margin-block-end: var(--s3); color: var(--fg); }
  .colophon__end { justify-content: space-between; }
  .nextstep { padding-block: var(--s6) var(--s8); }
  .nextstep h3 { font-size: var(--t-h3); line-height: 1.16; }
  .colophon__col li + li { margin-block-start: var(--s1); }
  .colophon__end { display: flex; flex-wrap: wrap; gap: var(--s2) var(--s6); padding-block-start: var(--s6); }

  /* ---- the sticky bar ---- */
  .bar {
    position: fixed; inset-inline: var(--margin);
    inset-block-end: calc(12px + env(safe-area-inset-bottom));
    z-index: 55;
    block-size: 56px;
    background: var(--c-ink); color: var(--c-ivory);
    display: grid; grid-template-columns: 1fr 1px 1fr;
    transform: translateY(calc(100% + 24px));
    transition: transform 420ms var(--ease-large);
  }
  .bar[data-shown="true"] { transform: translateY(0); }
  .bar a {
    display: flex; align-items: center; justify-content: center;
    text-decoration: none; color: var(--c-ivory);
    font-family: var(--font-label); font-weight: 300; font-size: var(--t-label);
    letter-spacing: 0.26em; text-transform: uppercase;
  }
  .bar__split { background: color-mix(in oklab, var(--c-ivory) 30%, transparent); }
  @media (min-width: 1024px) { .bar { display: none; } }
  @media (prefers-reduced-motion: reduce) { .bar { transition: none; } }

  /* ---- breadcrumb ---- */
  .crumb { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: baseline; color: var(--fg-soft); }
  .crumb a { text-decoration: none; }
  .crumb a:hover { color: var(--c-brass); }
  .crumb li + li::before { content: "—"; margin-inline-end: var(--s2); opacity: 0.5; }
  .crumb ol { display: flex; flex-wrap: wrap; gap: var(--s2); list-style: none; }

  /* ---- reviewed-by ---- */
  .reviewed { color: var(--fg-soft); }
  .nap { font-style: normal; }

  /* ---- figures ---- */
  .fig { position: relative; }
  .fig img { inline-size: 100%; }
  .fig figcaption { margin-block-start: var(--s2); color: var(--fg-soft); }

  /* ---- video ---- */
  .clip { position: relative; overflow: clip; background: var(--c-sand); }
  .clip video { inline-size: 100%; block-size: 100%; object-fit: cover; display: block; }

  /* ---- the gable. the batten chevron, opening. ---- */
  .gable { clip-path: polygon(0% 100%, 0% 37.5%, 50% 0%, 100% 37.5%, 100% 100%); }
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .gable {
        animation: gable-open linear both;
        animation-timeline: view();
        animation-range: entry 12% entry 96%;
        will-change: clip-path;
      }
    }
  }
  @keyframes gable-open {
    from { clip-path: polygon(0% 100%, 0% 37.5%, 50% 0%, 100% 37.5%, 100% 100%); }
    to   { clip-path: polygon(0% 100%, 0% 0%,    50% 0%, 100% 0%,    100% 100%); }
  }

  /* ---- forms (kept for later; nothing ships before the privacy notice) ---- */
  .inputline { display: flex; flex-wrap: wrap; gap: var(--s2); align-items: stretch; }
  .inputline input {
    flex: 1 1 16rem; min-inline-size: 0;
    background: transparent; border: 0;
    border-block-end: 1px solid var(--rule-rest);
    padding: 14px 2px; font-size: var(--t-body);
  }
  .inputline input:focus { outline: none; border-block-end-color: var(--c-ink); }
}

/* --------------------------------------------------------------- motion */

@layer components {
  /* =========================================================================
     THE THRESHOLD — the load sequence.
     SKiN is cut out of the consultation room: the letterforms are a window
     onto the photograph, the room drifts behind them, a brass rule draws
     underneath, and the mark then flies into the header slot as the page
     is revealed from the top down.
     Runs once per session. Never under prefers-reduced-motion. The overlay
     does not exist at all unless the inline head script asks for it, so a
     failed script can never leave the page covered.
     ====================================================================== */
  .threshold { display: none; }

  html.loading { overflow: hidden; }
  html.loading body { overflow: hidden; }
  html.loading .head .brand,
  html.loading .bar { opacity: 0; }

  html.loading .threshold {
    display: grid; position: fixed; inset: 0; z-index: 120;
    place-items: center;
  }
  .threshold > * { grid-area: 1 / 1; }

  .threshold__panel {
    inline-size: 100%; block-size: 100%;
    background: var(--c-ivory);
    clip-path: inset(0 0 0 0);
  }
  .threshold__stage {
    display: flex; flex-direction: column; align-items: center;
    gap: var(--s4);
    inline-size: min(74vw, 620px);
  }

  .threshold__mark {
    position: relative; overflow: clip;
    inline-size: 100%; aspect-ratio: 237.85 / 85.87;
    min-block-size: 0;
    -webkit-mask: url("../brand/wordmark.svg") no-repeat center / contain;
    mask: url("../brand/wordmark.svg") no-repeat center / contain;
    transform-origin: 0 0;
    clip-path: inset(100% 0 0 0);
    will-change: transform;
  }
  .threshold__mark picture,
  .threshold__mark img {
    position: absolute; inset: 0;
    inline-size: 100%; block-size: 100%;
    object-fit: cover; display: block;
    transform: scale(1.22);
  }
  /* champagne twin of the same cut — fades in mid-flight so the mark
     shapeshifts from room-through-letterforms into the header gold */
  .threshold__mark-gold {
    position: absolute; inset: 0;
    background: var(--c-champagne);
    opacity: 0;
  }
  .threshold__rule {
    display: block; inline-size: 100%; block-size: 1px;
    background: var(--c-brass);
    box-shadow: 0 -1px 96px -32px color-mix(in oklab, var(--c-brass) 55%, transparent);
    transform: scaleX(0); transform-origin: 0 50%;
  }
  .threshold__sub { color: var(--c-grey); opacity: 0; }

  /* the sequence */
  html.loading .threshold__mark {
    animation: th-open 820ms var(--ease-house) 60ms both;
  }
  html.loading .threshold__mark img {
    animation: th-drift 1900ms var(--ease-house) both;
  }
  html.loading .threshold__rule {
    animation: th-draw 760ms var(--ease-house) 300ms both;
  }
  html.loading .threshold__sub {
    animation: th-sub 620ms var(--ease-house) 540ms both;
  }
  @keyframes th-open  { from { clip-path: inset(100% 0 0 0) } to { clip-path: inset(0 0 0 0) } }
  @keyframes th-drift { from { transform: scale(1.22) } to { transform: scale(1) } }
  @keyframes th-draw  { from { transform: scaleX(0) } to { transform: scaleX(1) } }
  @keyframes th-sub   { from { opacity: 0; transform: translateY(6px) } to { opacity: .9; transform: none } }

  /* the lift: fly to the header slot while the fill becomes champagne */
  html.lifting .threshold__mark {
    transform: translate3d(var(--fx, 0), var(--fy, 0), 0) scale(var(--fs, .14));
    transition: transform 860ms var(--ease-large);
    animation: none;
    clip-path: inset(0 0 0 0);
  }
  html.lifting .threshold__mark img {
    animation: none;
    transform: scale(1);
    opacity: 0;
    transition: opacity 520ms var(--ease-large) 220ms;
  }
  html.lifting .threshold__mark-gold {
    opacity: 1;
    transition: opacity 520ms var(--ease-large) 180ms;
  }
  html.lifting .threshold__rule {
    animation: th-rule-out 860ms var(--ease-large) 80ms forwards;
  }
  html.lifting .threshold__sub {
    animation: th-sub-out 860ms var(--ease-large) 80ms forwards;
  }
  @keyframes th-rule-out {
    0%   { opacity: 1; transform: scaleX(1) translateY(0); }
    65%  { opacity: 0.85; transform: scaleX(1) translateY(30vh); }
    100% { opacity: 0; transform: scaleX(1) translateY(52vh); }
  }
  @keyframes th-sub-out {
    0%   { opacity: 0.9; transform: translateY(0); }
    65%  { opacity: 0.75; transform: translateY(30vh); }
    100% { opacity: 0; transform: translateY(52vh); }
  }
  html.lifting .threshold__panel {
    clip-path: inset(100% 0 0 0);
    transition: clip-path 860ms var(--ease-large) 80ms;
  }
  html.lifting .head .brand {
    opacity: 0;
    transition: opacity 240ms linear;
  }
  /* same pixels as the landed flyer — dissolve one into the other */
  html.lifting.settling .head .brand { opacity: 1; }
  html.lifting.settling .threshold__mark {
    opacity: 0;
    transition:
      transform 860ms var(--ease-large),
      opacity 240ms linear;
  }
  html.lifting .threshold { pointer-events: none; }

  html.lifted .threshold { display: none; }
}

@layer motion {
  /* the reveal system. discrete content reveals run at the house tempo on
     entry rather than being scrubbed, so a paused scroll never freezes a
     half-revealed page. everything scrubbed is in @layer rule. */
  @media (prefers-reduced-motion: no-preference) {
    .rv { opacity: 0; will-change: opacity, transform; }
    .rv--up    { transform: translateY(22px); }
    .rv--right { transform: translateX(-18px); }
    .rv--scale { transform: scale(1.055); }

    /* a masked reveal: the block wipes up from its own baseline.
       Resting state must NOT use a zero-area clip-path — Chromium then
       reports no intersection and the heading never gets .is-in, leaving
       a tall empty band where the type should be. Opacity already hides it. */
    .rv--mask { transform: translateY(0.18em); }

    /* the curtain: the ground lifts off the photograph, and the photograph
       settles back to true underneath it. the image is never clipped, so it
       still loads lazily. */
    .rv--wipe { position: relative; opacity: 1; transform: none; }
    .rv--wipe::after {
      content: ""; position: absolute; inset: 0; z-index: 2;
      background: var(--ground, var(--c-ivory));
      transform: scaleY(1); transform-origin: 50% 100%;
      will-change: transform;
    }
    .rv--wipe > * { transform: scale(1.06); transition: transform 1100ms var(--ease-house); }
    .rv--wipe.is-in::after {
      transform: scaleY(0);
      transition: transform 900ms var(--ease-house) calc(var(--i, 0) * 84ms);
    }
    .rv--wipe.is-in > * { transform: scale(1); }

    .rv.is-in {
      opacity: 1; transform: none;
      transition:
        opacity var(--d-reveal) var(--ease-house) calc(var(--i, 0) * 84ms),
        transform var(--d-reveal) var(--ease-house) calc(var(--i, 0) * 84ms);
      will-change: auto;
    }
    .rv--mask.is-in {
      animation: mask-in 900ms var(--ease-house) calc(var(--i, 0) * 84ms) both;
    }
    @keyframes mask-in {
      from { clip-path: inset(0 0 100% 0); }
      to   { clip-path: inset(-0.4em -0.4em -0.5em -0.4em); }
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .rv { opacity: 0; }
    .rv.is-in { opacity: 1; transition: opacity 200ms linear; }
  }

  /* stagger without inline style */
  .seq > *:nth-child(1)  { --i: 0 }
  .seq > *:nth-child(2)  { --i: 1 }
  .seq > *:nth-child(3)  { --i: 2 }
  .seq > *:nth-child(4)  { --i: 3 }
  .seq > *:nth-child(5)  { --i: 4 }
  .seq > *:nth-child(6)  { --i: 5 }
  .seq > *:nth-child(7)  { --i: 6 }
  .seq > *:nth-child(8)  { --i: 7 }
  .seq > *:nth-child(9)  { --i: 8 }
  .seq > *:nth-child(10) { --i: 9 }

  /* plates settle as they arrive: the frame holds, the photograph eases back
     to true. it ends when the plate is in view — nothing keeps moving. */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .plate__fig img,
      .sig-band__plate img {
        animation: settle linear both;
        animation-timeline: view();
        animation-range: entry 0% entry 100%;
      }
      /* folio softens in with Plate II — inventory mark, not a float */
      .plate--ii .plate__folio {
        animation: folio-in linear both;
        animation-timeline: view();
        animation-range: entry 30% entry 90%;
      }
    }
  }
  @keyframes settle {
    from { transform: scale(1.07); }
    to   { transform: scale(1); }
  }
  @keyframes folio-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* the index band rules itself up, column by column */
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .draw { transform-origin: 0 50%; animation: draw linear both; animation-timeline: view(); animation-range: entry 20% cover 12%; }
    }
  }
  @keyframes draw { from { transform: scaleX(0) scaleY(var(--hairline)); } to { transform: scaleX(1) scaleY(var(--hairline)); } }
}

/* ------------------------------------------------------------------ util */

@layer util {
  .vh {
    position: absolute !important; inline-size: 1px; block-size: 1px;
    padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%);
    white-space: nowrap; border: 0;
  }
  .nowrap { white-space: nowrap; }
  .end { text-align: end; }
  .mt-1 { margin-block-start: var(--s1) }
  .mt-2 { margin-block-start: var(--s2) }
  .mt-3 { margin-block-start: var(--s3) }
  .mt-4 { margin-block-start: var(--s4) }
  .mt-6 { margin-block-start: var(--s6) }
  .mt-8 { margin-block-start: var(--s8) }
  .mt-12 { margin-block-start: var(--s12) }
  .mb-4 { margin-block-end: var(--s4) }
  .mb-6 { margin-block-end: var(--s6) }
  .mb-8 { margin-block-end: var(--s8) }
  .soft { color: var(--fg-soft); }
  .measure { max-inline-size: var(--measure); }
  .measure-wide { max-inline-size: 46em; }
  .hide-lg { }
  @media (min-width: 900px) { .hide-lg { display: none; } }
  .show-lg { display: none; }
  @media (min-width: 900px) { .show-lg { display: block; } }
}

/* -------------------------------------------------- cross-document moves */
/* Navigation is a native cross-document view transition — no router, no
   client-side JS. Firefox gets an ordinary instant navigation and loses
   nothing. The wordmark carries a name so it holds still while the page
   changes underneath it. */

::view-transition-group(root) { animation-duration: 520ms; }
::view-transition-old(root) {
  animation: vt-out 300ms var(--ease-ui) both;
}
::view-transition-new(root) {
  animation: vt-in 560ms var(--ease-house) both;
}
::view-transition-group(brand) {
  animation-duration: 520ms;
  animation-timing-function: var(--ease-large);
}
@keyframes vt-out { to { opacity: 0; } }
@keyframes vt-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) {
    animation: vt-fade 180ms linear both;
  }
  @keyframes vt-fade { from { opacity: 0 } to { opacity: 1 } }
}

@media print {
  .head, .bar, .drawer, .grain, .plate { display: none !important; }
  body { background: none; color: var(--c-ink); }
}
