@import url("tokens.css");

/* =====================================================================
   Reset / base
   ===================================================================== */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  font-family: var(--f-text);
  font-size: var(--step-0);
  line-height: var(--lh-text);
  color: var(--tx);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
img, video { display: block; max-width: 100%; height: auto; }
/* A portrait crop for phones wraps its img in <picture class="pic">; the
   wrapper takes no box, so every img rule (absolute, cover, .media img)
   lays the img out exactly as without it. */
picture.pic { display: contents; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; cursor: pointer; background: none; border: 0; }
:focus-visible { outline: 2px solid var(--violet-500); outline-offset: 3px; }

.wrap { width: var(--wrap); margin-inline: auto; }
.gut  { padding-inline: var(--gutter); }
.skip { position: absolute; left: -999px; top: 0; z-index: 300;
  background: var(--ink); color: var(--tx-inv); padding: .7rem 1.1rem; }
.skip:focus { left: 1rem; top: 1rem; }

/* Film grain - fixed, subtle, above media, below UI */
.grain { position: fixed; inset: 0; z-index: 3; pointer-events: none; opacity: .07;
  mix-blend-mode: soft-light;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 160px 160px; }
@media (prefers-reduced-motion: reduce) { .grain { display: none; } }

/* Filmic media wrapper: graded, grain-cohered photography */
.media { position: relative; overflow: hidden; }
.media img, .media video { width: 100%; height: 100%; object-fit: cover; filter: var(--img-filter); }
.media--plum::after { content:""; position:absolute; inset:0; background: var(--grade-plum); }
.media--warm::after { content:""; position:absolute; inset:0; background: var(--grade-warm); }

/* =====================================================================
   Typography
   ===================================================================== */
.display, h1, h2, h3 { font-family: var(--f-display); font-weight: 380; line-height: var(--lh-snug);
  letter-spacing: -0.02em; font-optical-sizing: auto; }
.giant  { font-size: var(--step-5); font-weight: 330; line-height: var(--lh-tight); letter-spacing: -0.035em; }
.h-xl   { font-size: var(--step-4); font-weight: 340; line-height: 1.0; letter-spacing: -0.03em; }
.h-lg   { font-size: var(--step-3); font-weight: 360; letter-spacing: -0.022em; }
.h-md   { font-size: var(--step-2); font-weight: 380; letter-spacing: -0.015em; }
em, .italic { font-style: italic; }

.eyebrow { font-family: var(--f-text); font-size: var(--step--1); font-weight: 500;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--violet); }
.eyebrow--inv { color: var(--violet-300); }
.eyebrow--warm { color: var(--gold); }
.eyebrow--teal { color: var(--teal); }
.lead { font-size: var(--step-1); line-height: 1.42; color: var(--tx-soft); font-weight: 400; }
.lead--inv { color: var(--tx-inv-soft); }

/* =====================================================================
   Buttons / links
   ===================================================================== */
.btn { --_bg: var(--violet); --_fg:#fff; --_bd: var(--violet);
  display:inline-flex; align-items:center; gap:.6em; padding:1em 1.6em;
  font-family:var(--f-text); font-size:var(--step--1); font-weight:600; letter-spacing:.03em;
  background:var(--_bg); color:var(--_fg); border:1px solid var(--_bd); border-radius:var(--radius);
  transition: transform var(--dur-fast) var(--ease-out), background var(--dur-fast); will-change:transform; }
.btn:hover { transform: translateY(-2px); }
.btn--inv { --_bg:transparent; --_fg:var(--tx-inv); --_bd:var(--line-inv-strong); }
.btn--inv:hover { --_bg:var(--tx-inv); --_fg:var(--ink); --_bd:var(--tx-inv); }
.btn--ghost { --_bg:transparent; --_fg:var(--tx); --_bd:var(--line-strong); }
.btn--ghost:hover { --_bg:var(--ink); --_fg:var(--tx-inv); --_bd:var(--ink); }
.btn--lg { padding:1.15em 2em; font-size:var(--step-0); }

.textlink { display:inline-flex; align-items:center; gap:.5em; font-weight:600; font-size:var(--step--1);
  letter-spacing:.03em; padding-bottom:3px; border-bottom:1px solid currentColor;
  transition: gap var(--dur-fast) var(--ease-out); }
.textlink:hover { gap:.9em; }
.arrow { width:1.05em; height:1.05em; }

/* Cinematic play affordance */
.play { display:inline-flex; align-items:center; gap:1rem; color:var(--tx-inv); }
.play__ring { position:relative; width:4rem; height:4rem; border-radius:50%;
  border:1px solid var(--line-inv-strong); display:grid; place-items:center;
  transition: transform .18s var(--ease-out); }
.play__ring::before { content:""; position:absolute; inset:-1px; border-radius:50%;
  border:1.5px solid var(--violet-400); clip-path: inset(0 0 100% 0); transition: clip-path .26s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  .play:hover .play__ring { transform: scale(1.07); }
  .play:hover .play__ring::before { clip-path: inset(0 0 0 0); }
}
.play__ring svg { width:1.15rem; height:1.15rem; margin-left:3px; fill:currentColor; }
.play__label { font-family:var(--f-text); font-weight:600; font-size:var(--step-0); letter-spacing:.01em; }
.play__label small { display:block; font-weight:400; letter-spacing:.22em; text-transform:uppercase;
  font-size:.72rem; color:var(--tx-inv-faint); margin-top:3px; }

/* =====================================================================
   Loader intro
   ===================================================================== */
.loader { position: fixed; inset:0; z-index:250; background: var(--plum-2); color: var(--tx-inv);
  display:grid; place-items:center; transition: opacity .8s var(--ease-amb), visibility .8s; }
.loader__name { font-family:var(--f-display); font-weight:330; font-size:var(--step-3);
  letter-spacing:-0.02em; overflow:hidden; }
.loader__name span { display:inline-block; transform: translateY(110%); animation: rise .9s var(--ease-out) forwards; }
.loader__bar { position:absolute; left:0; bottom:0; height:2px; width:0; background:var(--violet-500); }
.loader.is-done { opacity:0; visibility:hidden; }
@keyframes rise { to { transform: translateY(0); } }
html.no-js .loader, .loader[hidden] { display:none; }
@media (prefers-reduced-motion: reduce) {
  .loader__name span { animation:none; transform:none; }
}

/* =====================================================================
   Nav - minimal floating chrome
   ===================================================================== */
.nav { position: fixed; inset: 0 0 auto 0; z-index: 90; display:flex; align-items:center;
  justify-content:space-between; padding: clamp(1.1rem,2vw,1.7rem) var(--gutter); color: var(--tx-inv);
  text-shadow: 0 1px 10px rgba(0,0,0,.32);
  transition: background var(--dur) var(--ease-amb), box-shadow var(--dur), padding var(--dur) var(--ease-amb); }
.nav.is-solid { background: var(--ink);
  box-shadow: 0 1px 0 color-mix(in oklab, var(--tx-inv) 14%, transparent);
  text-shadow: none; padding-block: clamp(.7rem,1.4vw,1rem); }
.brand { font-family:var(--f-display); font-size:1.28rem; font-weight:500; letter-spacing:-0.01em; }
.nav-right { display:flex; align-items:center; gap: clamp(1.1rem,2.4vw,2.4rem); }
.nav-links { display:flex; gap: clamp(1.2rem,2vw,2.3rem); font-size:var(--step--1); font-weight:500; letter-spacing:.01em; }
.nav-links a { position:relative; opacity:.85; padding:.2rem 0; transition:opacity .25s; }
.nav-links a::after { content:""; position:absolute; left:0; bottom:-2px; height:1px; width:0; background:currentColor;
  transition: width var(--dur-fast) var(--ease-out); }
.nav-links a:hover { opacity:1; } .nav-links a:hover::after { width:100%; }
.nav-cta { font-size:var(--step--1); font-weight:600; letter-spacing:.03em; padding:.6em 1.15em;
  border:1px solid currentColor; border-radius:var(--radius); transition: background var(--dur-fast); }
.nav-cta:hover { background: currentColor; } .nav-cta:hover span { color: var(--paper); }
.nav.is-solid .nav-cta { background:var(--violet); border-color:var(--violet); }
.nav.is-solid .nav-cta span { color:#fff; }
.menu-toggle { display:none; }

/* =====================================================================
   HERO - full-bleed cinematic
   ===================================================================== */
/* Static scene. The framed-card handoff lives in css|js/effects/frame-card.*
   and is no longer on this page; the hero is simply a full-bleed still that
   grows with its own content so the h1, the play button and the meta line
   can never be cropped on a short viewport. */
.hero { position:relative; min-height: 100svh; min-height: max(100svh, 620px);
  height:auto; color: var(--tx-inv); background: var(--plum-2); display:flex; }
.hero .media { position:absolute; inset:0; z-index:0; background: var(--plum-2); }
.hero .media img, .hero .media video { object-position: 70% 22%; }
.hero__poster, .hero__video, .spk-hero__video { position:absolute; inset:0; }
.hero__video, .spk-hero__video { opacity:0; transition: opacity 1s cubic-bezier(.4,0,.2,1); }
.hero__video.is-playing, .spk-hero__video.is-playing { opacity:1; }
.hero .media::after { content:""; position:absolute; inset:0;
  background:
    linear-gradient(90deg, rgba(14,8,22,0.92) 0%, rgba(14,8,22,0.55) 42%, rgba(14,8,22,0.05) 100%),
    linear-gradient(0deg, rgba(14,8,22,0.90) 2%, rgba(14,8,22,0.10) 46%); }
.hero__inner { position:relative; z-index:2; width:var(--wrap); margin-inline:auto;
  align-self:flex-end; padding-bottom: clamp(3rem,8vh,6rem); padding-top: 22vh; }
.hero__eyebrow { display:flex; align-items:center; gap:.9rem; margin-bottom:1.6rem;
  font-size:var(--step--1); letter-spacing:.22em; text-transform:uppercase; color:var(--tx-inv-soft); }
.hero__eyebrow .rule { height:1px; width:3.2rem; background:var(--violet-300); }
.hero h1 { font-size: var(--step-5); font-weight:320; line-height:.92; letter-spacing:-0.04em; max-width:16ch; }
.hero h1 em { color: var(--violet-300); }
.hero__actions { margin-top: clamp(2rem,4vh,3rem); display:flex; align-items:center; gap:2rem clamp(1.5rem,3vw,2.5rem); flex-wrap:wrap; }
.hero__meta { position:absolute; right:var(--gutter); bottom: clamp(3rem,8vh,6rem); z-index:2;
  text-align:right; color:var(--tx-inv-faint); font-size:var(--step--1); letter-spacing:.14em; text-transform:uppercase;
  display:flex; flex-direction:column; gap:.4rem;
  /* the actions column owns the left of the frame; the meta never crosses
     into it, so the two cannot collide between 1024 and 1440 */
  max-width: 34ch; }
.hero__meta b { color: var(--tx-inv-soft); font-weight:600; }
.hero__actions { max-width: min(100%, calc(66% - 2rem)); }

/* The entrance and the push-in (js module 10.A). The words are split at
   build time; the script arms .is-enter, then .is-go (the words), .is-ring
   (the play circle draws), .is-label, .is-meta. At rest (no script,
   reduced motion) every piece is simply there. */
.hero__w { display:inline-block; }
.hero.is-enter .hero__w { opacity:0; transform: translateY(.4em); filter: blur(6px); }
.hero.is-enter.is-go .hero__w { opacity:1; transform:none; filter: blur(0);
  transition: opacity 640ms var(--ease-out), transform 640ms var(--ease-out), filter 640ms var(--ease-out);
  transition-delay: calc(var(--i, 0) * var(--stagger, 110ms)); }
/* the ring is an SVG circle (it can draw itself), so the border goes */
.hero .play__ring { border-color: transparent; }
.hero .play__ring svg.play__circle { position:absolute; inset:0; width:100%; height:100%; margin:0;
  fill:none; stroke: var(--line-inv-strong); stroke-width:1; transform: rotate(-90deg);
  stroke-dasharray: 1; stroke-dashoffset: 0; overflow:visible; pointer-events:none; }
.hero.is-enter .play__circle circle { stroke-dashoffset: 1; }
.hero.is-enter .play__ring svg:not(.play__circle),
.hero.is-enter .play__label,
.hero.is-enter .hero__meta > span { opacity:0; }
.hero.is-enter .hero__meta > span { transform: translateY(10px); }
.hero.is-enter.is-ring .play__circle circle { stroke-dashoffset: 0;
  transition: stroke-dashoffset 700ms var(--ease-out); }
.hero.is-enter.is-ring .play__ring svg:not(.play__circle) { opacity:1; transition: opacity 700ms var(--ease-out); }
.hero.is-enter.is-label .play__label { opacity:1; transition: opacity 380ms var(--ease-out); }
.hero.is-enter.is-meta .hero__meta > span { opacity:1; transform:none;
  transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out); }
.hero.is-enter.is-meta .hero__meta > span + span { transition-delay: 110ms; }
/* the push-in: --hero-zoom and --hero-dim are written on .media */
.hero .hero__poster, .hero .hero__video { transform: scale(var(--hero-zoom, 1)); transform-origin: 70% 30%; }
.hero .media::after {
  background:
    linear-gradient(rgba(14,8,22,var(--hero-dim, 0)), rgba(14,8,22,var(--hero-dim, 0))),
    linear-gradient(90deg, rgba(14,8,22,0.92) 0%, rgba(14,8,22,0.55) 42%, rgba(14,8,22,0.05) 100%),
    linear-gradient(0deg, rgba(14,8,22,0.90) 2%, rgba(14,8,22,0.10) 46%); }
@media (prefers-reduced-motion: reduce) {
  .hero .hero__poster, .hero .hero__video { transform:none; }
}

/* Below 900 the meta leaves the corner and stacks under the actions. */
@media (max-width: 900px) {
  .hero { flex-direction:column; justify-content:flex-end; }
  .hero__inner { align-self:auto; padding-bottom: clamp(1.4rem,3vh,2.2rem); }
  .hero__actions { max-width:none; }
  .hero__meta { position:static; width:var(--wrap); max-width:none;
    margin: 0 auto clamp(2rem,6vh,4rem); text-align:left;
    flex-direction:row; flex-wrap:wrap; gap:.3rem 1.6rem; }
}

/* =====================================================================
   The through-line
   ===================================================================== */
.thread { position:relative; background: var(--plum); color: var(--tx-inv);
  padding-top:4rem; padding-bottom: clamp(3rem, 6vw, 6rem); overflow:hidden; }

/* Ambient ground: the station stills, blurred, one at a time ------ */
.thread__bg { position:absolute; inset:0; z-index:0; overflow:hidden; pointer-events:none; }
.thread__bg img { position:absolute; inset:-8%; width:116%; height:116%;
  object-fit:cover; object-position:center;
  filter: blur(44px) saturate(1.15) brightness(.72);
  opacity:0; transform: scale(1.02);
  transition: opacity 1.4s var(--ease-amb), transform 6s var(--ease-amb); }
.thread__bg img.is-on { opacity:.62; transform: scale(1.06); }

/* The seams stay solid plum, the middle lets the picture through -- */
.thread__veil { position:absolute; inset:0; z-index:0; pointer-events:none;
  background: linear-gradient(180deg,
    rgba(26,16,38,.96) 0%,
    rgba(26,16,38,.74) 14%,
    rgba(26,16,38,.70) 50%,
    rgba(26,16,38,.76) 86%,
    rgba(26,16,38,.97) 100%); }

/* Light that belongs to the dot, carried on --px / --py ----------- */
.thread__glow { position:absolute; inset:0; z-index:0; pointer-events:none;
  background: radial-gradient(30rem circle at var(--px, 50%) var(--py, 0px),
    rgba(169,133,230,.22), rgba(169,133,230,.06) 40%, transparent 68%); }

.thread__inner { position:relative; z-index:2; width: var(--wrap); margin-inline:auto; }

.thread .eyebrow { margin:0 0 2.5rem; font-family: var(--f-text); font-weight:500;
  font-size: var(--step--1); letter-spacing:.2em; text-transform:uppercase;
  color: rgba(245,240,231,.5); }

/* The line ------------------------------------------------------- */
.thread__svg { position:absolute; inset:0; width:100%; height:100%; pointer-events:none; z-index:1; }
.thread__svg .guide { fill:none; stroke: rgba(245,240,231,.14); stroke-width:1.25; }
.thread__svg .drawn { fill:none; stroke: var(--violet-300); stroke-width:2; stroke-opacity:.95;
  stroke-linecap:round; }
.thread .pulse { position:absolute; top:0; left:0; width:12px; height:12px; margin:-6px 0 0 -6px;
  border-radius:50%; background: var(--violet-300);
  box-shadow: 0 0 18px 6px rgba(169,133,230,.55), 0 0 48px 16px rgba(169,133,230,.18);
  opacity:0; pointer-events:none; z-index:3;
  transition: opacity .45s var(--ease-out); will-change: transform; }

/* Mobile rail (hidden on desktop) -------------------------------- */
.thread .rail { display:none; }

/* Stations ------------------------------------------------------- */
.thread .stations { position:relative; z-index:1; }
.station { position:relative; display:grid; grid-template-columns: repeat(12, minmax(0,1fr));
  gap:0 24px; align-items:center; min-height: clamp(300px, 38vh, 420px); }

.station .still { margin:0; grid-row:1; will-change: transform; }
.station .still img { width:100%; max-width:520px; aspect-ratio:4/3; object-fit:cover;
  /* No frame: the edges feather into the section and the still is graded
     toward plum until its station is active. */
  -webkit-mask-image: radial-gradient(ellipse 72% 70% at 50% 50%, #000 42%, rgba(0,0,0,.55) 68%, transparent 100%);
          mask-image: radial-gradient(ellipse 72% 70% at 50% 50%, #000 42%, rgba(0,0,0,.55) 68%, transparent 100%);
  filter: var(--img-filter) sepia(.22) hue-rotate(222deg) saturate(.7) brightness(.82);
  clip-path: inset(0 0 100% 0); transform: scale(1.04);
  transition: clip-path .9s var(--ease-out), transform 1.2s var(--ease-out), filter .5s var(--ease-out); }
.station.is-lit .still img { clip-path: inset(0); transform:none; }
.station.is-active .still img { filter: var(--img-filter) sepia(0) hue-rotate(0deg) saturate(1) brightness(1); }

.station .knot { grid-row:1; grid-column: 6 / 8; align-self:center; z-index:2; }
.station .dot { display:block; width:12px; height:12px; border-radius:50%;
  background: transparent; border:1.5px solid rgba(169,133,230,.35);
  box-shadow: 0 0 0 0 rgba(169,133,230,0);
  transition: border-color .5s var(--ease-out), box-shadow .5s var(--ease-out); }
.station.is-lit .dot { border-color: var(--violet-300); }

.station .body { grid-row:1; }
.station .idx { margin:0 0 .7rem; overflow:hidden; }
.station .idx span { display:block; font-size: var(--step--1); letter-spacing:.2em;
  color: rgba(245,240,231,.28); transform: translateY(105%);
  transition: transform .7s var(--ease-out), color .5s var(--ease-out); }
.station .label { margin:0; overflow:hidden; }
.station .label span { display:block; font-family: var(--f-display); font-weight:340;
  letter-spacing:-0.03em; line-height:1; font-size: var(--step-2); color: rgba(245,240,231,.28);
  padding-bottom:.16em;              /* descender room inside the mask */
  transform: translateY(105%);
  transition: transform .7s var(--ease-out), color .5s var(--ease-out); }
.station.is-pillar .label span { font-size: var(--step-3); }
.station.is-lit .idx span,
.station.is-lit .label span { transform:none; }
.station.is-lit .idx span { color: var(--violet-300); }
.station.is-lit .label span { color: var(--tx-inv); }
.station .gloss { margin:.9rem 0 0; max-width:26ch; text-wrap:balance; font-size: var(--step-0);
  color: var(--tx-inv-soft);
  opacity:0; transform: translateY(6px);
  transition: opacity .6s var(--ease-out) .2s, transform .6s var(--ease-out) .2s; }
.station.is-lit .gloss { opacity:1; transform:none; }

/* Odd stations: still left, dot at the seam, words right ---------- */
.station.is-odd .still { grid-column: 1 / 6; }
.station.is-odd .knot { justify-self: start; }
.station.is-odd .body { grid-column: 7 / 13; text-align:left; }
/* Even stations: mirrored ---------------------------------------- */
.station.is-even .body { grid-column: 1 / 7; text-align:right; }
.station.is-even .knot { justify-self: end; }
.station.is-even .still { grid-column: 8 / 13; justify-self:end; }
.station.is-even .still img { margin-left:auto; }
.station.is-even .gloss { margin-left:auto; }

/* Hover: colour returns, the node glows, the label takes the brand */
.station:hover .still img { filter: var(--img-filter) sepia(0) hue-rotate(0deg) saturate(1) brightness(1); }
.station:hover.is-lit .dot { box-shadow: 0 0 0 16px rgba(169,133,230,.14); }
.station:hover.is-lit .label span { color: var(--violet-300); }

/* Mobile --------------------------------------------------------- */
@media (max-width: 720px) {
  .thread__svg { display:none; }
  /* the eyebrow clears the rail, the way the station content does */
  .thread .eyebrow { padding-left:3rem; }
  .thread .rail { display:block; position:absolute; z-index:1;
    left: calc(50% - var(--wrap) / 2 + 1.5rem); top:0; bottom:0; width:1px; }
  .thread .rail i { position:absolute; inset:0; background: rgba(245,240,231,.14); }
  .thread .rail b { position:absolute; left:0; top:0; width:1px; height:0;
    background: var(--violet-300); }

  .station { grid-template-columns: 1fr; gap:0; min-height:0; padding-left:3rem;
    padding-block: clamp(1.75rem, 6vw, 2.5rem); align-items:start; }
  .station .knot { position:absolute; left:1.5rem; top: clamp(1.75rem, 6vw, 2.5rem);
    transform: translateX(-50%); grid-column:auto; justify-self:auto; }
  .station.is-odd .still, .station.is-even .still,
  .station.is-odd .body, .station.is-even .body { grid-column:auto; }
  /* the desktop places both in row 1; on one column they must stack */
  .station .still, .station .body { grid-row:auto; }
  .station .still { order:1; }
  .station .body { order:2; }
  .station.is-even .body { text-align:left; }
  .station.is-even .still { justify-self:stretch; }
  .station .still img { max-width:none; aspect-ratio:16/9; margin:0 0 1.1rem; }
  .station.is-even .still img { margin-left:0; }
  .station .label span, .station.is-pillar .label span { font-size: var(--step-2); }
  .station.is-even .gloss { margin-left:0; }
}

/* Reduced motion: everything settled, nothing moves, no pulse */
@media (prefers-reduced-motion: reduce) {
  .station .still img, .station .dot, .station .idx span,
  .station .label span, .station .gloss, .thread__bg img { transition:none; }
  .thread .pulse { display:none; }
}

/* =====================================================================
   Oversized statement moment
   ===================================================================== */
.statement { padding-block: clamp(6rem,14vw,16rem); }
.statement--plum { background: var(--plum); color: var(--tx-inv); }
.statement__inner { width: var(--wrap); margin-inline:auto; }
.statement p { font-family:var(--f-display); font-weight:330; font-size: var(--step-4);
  line-height:1.02; letter-spacing:-0.03em; max-width: 20ch; }
.statement p em { font-style:italic; }
.statement .accent { color: var(--violet); } .statement--plum .accent { color: var(--violet-300); }
.statement__foot { margin-top: clamp(2rem,4vw,3.5rem); max-width: 52ch; }

/* =====================================================================
   Recognition - line reveal over dim full-bleed image
   ===================================================================== */
.recog { position:relative; color: var(--tx-inv); background: var(--ink); min-height: 100svh;
  display:flex; align-items:center; overflow:hidden; }
.recog .media { position:absolute; inset:0; z-index:0; }
.recog .media img { object-position: 50% 30%; }
.recog .media::after { content:""; position:absolute; inset:0;
  background: linear-gradient(90deg, rgba(12,7,20,0.92), rgba(12,7,20,0.6) 55%, rgba(12,7,20,0.35)); }
.recog__inner { position:relative; z-index:2; width:var(--wrap); margin-inline:auto; padding-block: clamp(5rem,10vw,9rem); }
.recog__eyebrow { margin-bottom: clamp(2rem,4vw,3rem); }
.recog__lines { display:flex; flex-direction:column; gap: clamp(.6rem,1.4vw,1.3rem); }
.recog__lines p { font-family:var(--f-display); font-weight:340; font-size: var(--step-3);
  line-height:1.06; letter-spacing:-0.025em; max-width: 22ch; }
.recog__lines p .mute { color: var(--tx-inv-faint); }
.recog__foot { margin-top: clamp(2.2rem,4vw,3.2rem); max-width: 46ch; }

/* =====================================================================
   Full-bleed pinned / scaling cinematic moment
   ===================================================================== */
.bleed { position:relative; min-height: 108svh; display:grid; place-items:center; color:var(--tx-inv);
  overflow:hidden; text-align:center; }
.bleed .media { position:absolute; inset:0; z-index:0; }
.bleed .media img { transform: scale(1.15); will-change: transform; }
.bleed .media::after { content:""; position:absolute; inset:0;
  background: radial-gradient(130% 90% at 50% 45%, rgba(14,8,22,.30), rgba(14,8,22,.86)); }
.bleed__inner { position:relative; z-index:2; width:min(94vw,1100px); padding-block:4rem; }
.bleed__inner .eyebrow { margin-bottom:1.6rem; }
.bleed h2 { font-size: var(--step-5); font-weight:320; line-height:.96; letter-spacing:-0.035em; }
.bleed h2 em { color: var(--violet-300); }
.bleed__note { margin-top: 1.8rem; color:var(--tx-inv-soft); font-size:var(--step-1); max-width:44ch;
  margin-inline:auto; }

/* =====================================================================
   Why Stephen - full-bleed portrait, overlaid editorial
   ===================================================================== */
.why { position:relative; color: var(--tx-inv); background: var(--ink); overflow:hidden; }
.why__grid { position:relative; z-index:2; width:var(--wrap); margin-inline:auto;
  min-height: 100svh; display:grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,5rem);
  align-items:center; padding-block: clamp(5rem,9vw,9rem); }
.why .media { position:absolute; inset:0 auto 0 0; width: 46%; z-index:0; }
.why .media img { object-position: 50% 18%; }
.why .media::after { content:""; position:absolute; inset:0;
  background: linear-gradient(90deg, rgba(12,7,20,0) 55%, rgba(20,13,26,1) 100%),
              linear-gradient(0deg, rgba(12,7,20,0.55), rgba(12,7,20,0.10)); }
.why__body { grid-column: 2; }
.why__body h2 { font-size: var(--step-3); max-width: 15ch; }
.why__body .lead { margin-top: 1.4rem; color: var(--tx-inv-soft); max-width: 48ch; }
.creds { margin-top: clamp(2rem,3vw,2.6rem); display:flex; flex-direction:column; }
.cred { display:flex; align-items:baseline; gap:1rem; padding:.85rem 0; border-top:1px solid var(--line-inv);
  font-size: var(--step-0); }
.creds .cred:last-child { border-bottom:1px solid var(--line-inv); }
.cred .n { font-family:var(--f-display); font-size:var(--step--1); color:var(--violet-300);
  font-variant-numeric:tabular-nums; min-width:2ch; }
.cred b { font-weight:500; } .cred span { color: var(--tx-inv-soft); }
.why__link { margin-top: 2rem; }

/* Giant stats band */
.stats { background: var(--plum-2); color: var(--tx-inv); border-top:1px solid var(--line-inv); }
.stats__grid { width:var(--wrap); margin-inline:auto; display:grid; grid-template-columns:repeat(3,1fr);
  gap: clamp(2rem,4vw,4rem); padding-block: clamp(3.5rem,7vw,6.5rem); }
.stat { }
.stat__n { font-family:var(--f-display); font-weight:340; font-size: var(--step-4); line-height:.9;
  letter-spacing:-0.04em; }
.stat__l { margin-top:1rem; font-size:var(--step--1); letter-spacing:.16em; text-transform:uppercase;
  color: var(--tx-inv-faint); }

/* =====================================================================
   Keynotes - oversized editorial rows
   ===================================================================== */
.keynotes-sec { background: var(--plum-2); color: var(--tx-inv); padding-block: clamp(5rem,9vw,9rem); }
.keynotes-head { width:var(--wrap); margin-inline:auto; margin-bottom: clamp(2.5rem,5vw,4rem);
  display:flex; flex-direction:column; gap:1.2rem; }
.keynotes-head h2 { font-size: var(--step-3); max-width: 20ch; }
.keynotes { width:var(--wrap); margin-inline:auto; }
.keynote { position:relative; display:grid; grid-template-columns: 5rem 1fr auto; gap: clamp(1rem,3vw,3rem);
  align-items:center; padding-block: clamp(2rem,3.6vw,3.4rem); border-top:1px solid var(--line-inv);
  transition: padding-left var(--dur) var(--ease-out); }
.keynotes .keynote:last-child { border-bottom:1px solid var(--line-inv); }
.keynote__no { font-family:var(--f-display); font-size:var(--step-1); color:var(--tx-inv-faint); font-variant-numeric:tabular-nums; }
.keynote__main { display:flex; flex-direction:column; gap:.7rem; }
.keynote__title { display:block; margin:0; padding:0; background:none; border:0; border-radius:0; color:inherit;
  text-align:inherit; text-transform:inherit; text-indent:0; text-shadow:inherit; word-spacing:inherit;
  cursor:inherit; -webkit-tap-highlight-color:transparent; }
.keynote__title { font-family:var(--f-display); font-size: var(--step-3); font-weight:360; line-height:.98; letter-spacing:-0.03em; }
.keynote__title .tm { font-size:.38em; vertical-align:super; color:var(--tx-inv-faint); }
.keynote__tag { font-size:.72rem; letter-spacing:.2em; text-transform:uppercase; color:var(--violet-300); font-weight:600; }
.keynote__sub { color:var(--tx-inv-soft); max-width: 56ch; font-size: var(--step-0); }
.keynote__sub b { color: var(--tx-inv); font-weight: 600; }
.keynote__accent { width:0; height:2px; background: var(--_acc, var(--violet)); transition: width var(--dur) var(--ease-out); }
.keynote__cta { display:flex; align-items:center; gap:.5rem; color:var(--tx-inv-soft); font-size:var(--step--1);
  font-weight:600; white-space:nowrap; transition: color var(--dur-fast); }
.keynote:hover { padding-left: clamp(.5rem,1.6vw,1.6rem); }
.keynote:hover .keynote__accent { width: clamp(2.5rem,5vw,5rem); }
.keynote:hover .keynote__no, .keynote:hover .keynote__cta {
  color: var(--_acc, var(--violet));
  color: color-mix(in oklab, var(--_acc, var(--violet)) 55%, var(--tx-inv)); }

/* =====================================================================
   Healthcare - filmic teal-graded bleed
   ===================================================================== */
.care { position:relative; color:var(--tx-inv); background: var(--plum-2); overflow:hidden; }
.care .media { position:absolute; inset:0 0 0 auto; width:48%; z-index:0; }
.care .media img { object-position:50% 40%; }
.care .media::after { content:""; position:absolute; inset:0;
  background: linear-gradient(270deg, rgba(18,10,28,0) 50%, rgba(18,10,28,1) 100%),
              linear-gradient(200deg, rgba(20,120,110,0.25), rgba(18,10,28,0.35)); }
.care__inner { position:relative; z-index:2; width:var(--wrap); margin-inline:auto;
  min-height: 92svh; display:flex; align-items:center; padding-block: clamp(5rem,9vw,9rem); }
.care__body { max-width: 40rem; }
.care__body h2 { font-size: var(--step-3); max-width: 15ch; margin-top:1.2rem; }
.care__body h2 em { color: color-mix(in oklab, var(--teal) 72%, white); }
.care__list { margin-top:1.8rem; display:flex; flex-wrap:wrap; gap:.6rem 1.6rem; color:var(--tx-inv-soft);
  font-size:var(--step-0); list-style:none; padding:0; }
.care__list li { position:relative; padding-left:1.1rem; }
.care__list li::before { content:""; position:absolute; left:0; top:.62em; width:6px; height:6px; border-radius:50%; background:var(--teal); }
.care__cta { margin-top: 2.4rem; }

/* =====================================================================
   Final CTA + footer
   ===================================================================== */
.final { position:relative; background: var(--plum-2); color:var(--tx-inv); text-align:center; overflow:hidden; }
.final__inner { position:relative; z-index:2; width:min(94vw,1000px); margin-inline:auto; padding-block: clamp(6rem,12vw,12rem); }
.final h2 { font-size: var(--step-5); font-weight:320; line-height:.98; letter-spacing:-0.035em; }
.final h2 em { color: var(--violet-300); }
.final__actions { margin-top: clamp(2.5rem,4vw,3.5rem); display:flex; gap:1rem; justify-content:center; flex-wrap:wrap; }
.final__contact { margin-top:2.6rem; display:flex; gap:1.4rem 2.5rem; justify-content:center; flex-wrap:wrap;
  color:var(--tx-inv-soft); font-size:var(--step--1); }
.final__contact a:hover { color:var(--violet-300); }

.foot { position:relative; z-index:1; background: var(--plum-2); color:var(--tx-inv-soft); padding-block: 3.5rem 2.5rem; border-top:1px solid var(--line-inv); }
.foot__grid { width:var(--wrap); margin-inline:auto; display:grid; grid-template-columns:1.5fr 1fr 1fr; gap:2.5rem; }
.foot .brand { color:var(--tx-inv); margin-bottom:1rem; display:block; }
.foot h3 { font-family:var(--f-text); font-size:var(--step--1); letter-spacing:.16em; text-transform:uppercase;
  color:var(--tx-inv-faint); margin-bottom:1rem; font-weight:600; }
.foot ul { list-style:none; padding:0; display:flex; flex-direction:column; gap:.6rem; }
.foot a:hover { color:var(--tx-inv); }
.foot__base { width:var(--wrap); margin: 3rem auto 0; padding-top:1.5rem; border-top:1px solid var(--line-inv);
  display:flex; justify-content:space-between; gap:1rem; flex-wrap:wrap; font-size:var(--step--1); color:var(--tx-inv-faint); }

/* =====================================================================
   Video lightbox
   ===================================================================== */
.lb { position:fixed; inset:0; z-index:200; display:grid; place-items:center; background:rgba(8,4,14,.92);
  backdrop-filter:blur(8px); opacity:0; visibility:hidden; transition:opacity var(--dur) var(--ease-amb), visibility var(--dur); }
.lb.is-open { opacity:1; visibility:visible; }
.lb__frame { width:min(92vw,1100px); aspect-ratio:16/9; background:#000; border-radius:var(--radius); overflow:hidden;
  transform: translateY(16px) scale(.98); transition: transform var(--dur) var(--ease-out); display:grid; place-items:center;
  color:var(--tx-inv-soft); text-align:center; padding:2rem; }
.lb.is-open .lb__frame { transform:none; }
.lb__frame iframe, .lb__frame video { width:100%; height:100%; border:0; }
.lb__close { position:absolute; top:1.4rem; right:1.5rem; color:#fff; width:2.7rem; height:2.7rem;
  border:1px solid var(--line-inv-strong); border-radius:50%; display:grid; place-items:center; }
.lb__close:hover { background:rgba(255,255,255,.1); }
.lb__placeholder .eyebrow { color:var(--violet-300); } .lb__placeholder p { margin-top:.8rem; max-width:46ch; }

/* =====================================================================
   Motion - reveals
   ===================================================================== */
.reveal { opacity:0; transform: translateY(18px); transition: opacity .55s var(--ease-out), transform .55s var(--ease-out); }
.reveal.in { opacity:1; transform:none; }
/* no script: nothing is waiting to be revealed */
html.no-js .reveal, html.no-js .lines > * { opacity:1; transform:none; }
.reveal[data-d="1"]{transition-delay:.08s}.reveal[data-d="2"]{transition-delay:.16s}
.reveal[data-d="3"]{transition-delay:.24s}.reveal[data-d="4"]{transition-delay:.32s}

/* line-by-line reveal (recognition + statements) */
.lines > * { opacity:0; transform: translateY(16px); transition: opacity .5s var(--ease-out), transform .5s var(--ease-out); }
.lines.in > * { opacity:1; transform:none; }
.lines.in > *:nth-child(1){transition-delay:.05s}.lines.in > *:nth-child(2){transition-delay:.18s}
.lines.in > *:nth-child(3){transition-delay:.31s}.lines.in > *:nth-child(4){transition-delay:.44s}
.lines.in > *:nth-child(5){transition-delay:.57s}

@media (prefers-reduced-motion: reduce) {
  .reveal, .lines > * { opacity:1 !important; transform:none !important; transition:none; }
  .bleed .media img { transform: scale(1.02) !important; }
}

/* =====================================================================
   Mobile drawer
   ===================================================================== */
.drawer { position:fixed; inset:0; z-index:95; background:var(--plum); transform:translateY(-100%);
  transition: transform var(--dur) var(--ease-out); display:flex; flex-direction:column; justify-content:center;
  padding:var(--gutter); visibility:hidden; }
.drawer.is-open { transform:none; visibility:visible; }
.drawer nav { display:flex; flex-direction:column; gap:.2rem; }
.drawer nav a { font-family:var(--f-display); font-size:clamp(2rem,9vw,3rem); font-weight:340; color:var(--tx-inv); padding:.3rem 0; }
.drawer nav a:hover { color:var(--violet-300); }
.drawer__close { position:absolute; top:1.4rem; right:var(--gutter); color:var(--tx-inv); font-size:var(--step-0); }
.drawer__foot { margin-top:2.5rem; color:var(--tx-inv-soft); font-size:var(--step--1); display:flex; flex-direction:column; gap:.4rem; }
@media (prefers-reduced-motion: reduce){ .drawer{ transition:none; } }

/* =====================================================================
   Responsive
   ===================================================================== */
@media (max-width: 1024px) {
  .why__grid { grid-template-columns: 1fr; min-height:auto; }
  .why .media { position:relative; width:100%; height: 62vh; }
  .why .media::after { background: linear-gradient(0deg, rgba(12,7,20,.7), rgba(12,7,20,.1)); }
  .why__body { grid-column:1; }
  .care .media { position:relative; width:100%; height:56vh; }
  .care .media::after { background: linear-gradient(0deg, rgba(18,10,28,.65), rgba(18,10,28,.15)),
                        linear-gradient(200deg, rgba(20,120,110,0.22), rgba(18,10,28,0.3)); }
  .care__inner { min-height:auto; }
  .stats__grid { grid-template-columns:1fr; gap:0; }
  .stat { padding-block:1.4rem; border-top:1px solid var(--line-inv); }
}
@media (max-width: 720px) {
  .nav-links { display:none; }
  .nav .nav-cta { display:none; }
  .brand { font-size:1.06rem; }
  .menu-toggle { display:inline-flex; align-items:center; gap:.5rem; font-size:var(--step--1); font-weight:600; letter-spacing:.02em; }
  .menu-toggle .bars { display:inline-flex; flex-direction:column; gap:4px; }
  .menu-toggle .bars i { width:22px; height:1.5px; background:currentColor; display:block; }
  .hero .media img, .hero .media video { object-position: 62% 20%; }
  .keynote { grid-template-columns:auto 1fr; }
  .foot__grid { grid-template-columns:1fr; gap:2rem; }
}

/* =====================================================================
   INTERACTIVE MOMENTS (reduced-text, visual-led)
   ===================================================================== */

/* --- Same patterns: one rolling word, two cards that hide a photo ------
   "How [Word] shows up." on one line. Seven patterns roll on a 5s period;
   the gold underline under the word is the timer, and the word's slot
   eases to each new width so "How" and "shows up." glide. The controls
   sit centred under the line: prev, "03 / 07", next. An arrow or the
   word pins it; only the word resumes it. Below, two cards, each hiding
   a still of Stephen that the pointer lights. From 768 up the whole
   section fits one screen under the nav. Every rule is scoped under
   .patterns. */
.patterns { position:relative; overflow:hidden; color: var(--tx-inv); text-align:center;
  padding-block: clamp(2.5rem, 5vh, 4rem);
  background-color: var(--plum); }

/* Glow: one light, gold core in a violet halo, on a slow idle drift only.
   JS moves it with a transform; it does not react to the pointer. */
.patterns__spot { position:absolute; left:0; top:0; z-index:0; pointer-events:none;
  width:76vw; height:76vw; margin:-38vw 0 0 -38vw;
  background: radial-gradient(closest-side, rgba(227,169,60,.12), rgba(227,169,60,.04) 45%,
    rgba(124,77,224,.056) 65%, rgba(124,77,224,0));
  transform: translate3d(50vw, 40%, 0); will-change: transform; }

.patterns__sr { position:absolute !important; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space:nowrap; border:0; }

.patterns__inner { position:relative; z-index:1; width: var(--wrap); margin-inline:auto; }

/* Stage: title, word, underline, controls, the cards ------------------- */
.patterns__stage { min-width:0; container-type: inline-size; }

/* One line at every width: "How Responsibility shows up." is about 11.6em,
   so 8.2cqi keeps it inside the stage; the vh term keeps the section to
   one screen. Optical size is held so the width per em never changes. */
.patterns__title { margin:0; white-space:nowrap; text-align:center;
  font-family: var(--f-display); font-weight:330; font-style:normal;
  font-optical-sizing:none; font-variation-settings:"opsz" 144;
  font-size: min(8.6cqi, 11.5vh); line-height:1.12; letter-spacing:-0.025em; color: var(--tx-inv); }

/* The word's slot. Its width is set by script in em and eased, so the
   words either side glide; the underline is its width, the word only. */
.patterns .ctx { position:relative; display:inline-block; vertical-align:baseline; margin-right:.12em;
  transition: width .55s var(--ease-out); }

.patterns__word { position:relative; display:inline-flex; justify-content:center; width:100%;
  padding:0; border:0; background:none;
  font:inherit; font-style:italic; font-weight:460; letter-spacing:inherit; text-align:left;
  font-optical-sizing:none; font-variation-settings:"opsz" 144;
  color: var(--tx-inv); cursor:pointer; }
.patterns__word:focus-visible { outline:2px solid var(--violet-300); outline-offset:.08em; }

/* One span per word. The current one sits in flow; the others wait on
   top of it, centred in the slot like it, so a change cross-fades in
   place while the slot eases to the new width. */
.patterns__glyphs { display:inline-block; white-space:nowrap; hyphens:manual; flex:0 0 auto;
  position:absolute; top:0; opacity:0; transform: translateY(.06em);
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out); }
/* The word takes the colour of the room being lit: gold home, violet work. */
.patterns:has(.patterns__room--home.is-lit, .patterns__room--home.is-full) .patterns__glyphs { color:#E8BB68; }
.patterns:has(.patterns__room--work.is-lit, .patterns__room--work.is-full) .patterns__glyphs { color:#CDBDF2; }
.patterns__glyphs.is-on { position:relative; opacity:1; transform:none;
  transition: opacity .55s var(--ease-out) .12s, transform .55s var(--ease-out) .12s, color .35s var(--ease-out); }

.patterns .ctx__bar { position:absolute; left:0; right:0; bottom:0; height:2px;
  transform-origin:left center; transform: scaleX(1); opacity:.55;
  background-color: var(--gold); transition: opacity .35s var(--ease-out); }
.patterns.is-cycling .ctx__bar { animation: ctxTimer 5s linear infinite; }
.patterns.is-paused .ctx__bar { animation-play-state: paused; }
.patterns.is-pinned .ctx__bar { animation:none; transform: scaleX(1); opacity:1; }
.patterns .ctx:has(.patterns__word:hover) .ctx__bar,
.patterns .ctx:has(.patterns__word:focus-visible) .ctx__bar { opacity:1; }
@keyframes ctxTimer { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Controls: one centred 40px row under the underline, in DOM order:
   prev, the count (plain text), next. */
.patterns__ctrl { display:flex; justify-content:center; align-items:center; gap:1.25rem;
  height:40px; margin-top:.5rem; }
.patterns__arrow { flex:0 0 auto; width:44px; height:44px; padding:0; border:0; background:none;
  display:grid; place-items:center; cursor:pointer;
  color: rgba(244,236,222,.7); transition: color var(--dur-fast) var(--ease-out); }
.patterns__arrow svg { width:24px; height:24px; overflow:visible; }
.patterns__arrow path { stroke-width:1.25px; vector-effect: non-scaling-stroke; }
.patterns__arrow--prev svg { transform: scaleX(-1); }
.patterns__arrow:hover, .patterns__arrow:focus-visible { color: var(--gold); }
.patterns__arrow:focus-visible { outline:2px solid var(--violet-300); outline-offset:0; }

.patterns__count { font-family: var(--f-text); font-size:.875rem; font-weight:500; line-height:1; letter-spacing:.04em;
  font-variant-numeric: tabular-nums; color: rgba(244,236,222,.65); }

/* Cards: decorative containers, each hiding a still -------------------- */
@property --pat-lit   { syntax:"<number>"; inherits:true; initial-value:0; }
@property --pat-floor { syntax:"<number>"; inherits:true; initial-value:0; }

.patterns__cards { display:grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap:1.5rem;
  max-width:1120px; margin: 3vh auto 0; }
.patterns__card { position:relative; overflow:hidden; isolation:isolate;
  height: clamp(240px, 40vh, 400px); padding: clamp(1.25rem, 3vh, 2rem);
  display:flex; align-items:center; justify-content:center;
  border:1px solid rgba(227,169,60,.3); border-radius:4px;
  /* Bright layer only: --pat-lit = alpha inside the light, --pat-floor = alpha
     outside it. The dark layer underneath never changes. */
  --x:50%; --y:50%; --pat-lit:0; --pat-floor:0;
  transition: --pat-lit .55s var(--ease-out), --pat-floor .6s var(--ease-out); }
.patterns__card.is-lit { --pat-lit:1; transition: --pat-lit .35s var(--ease-out), --pat-floor .6s var(--ease-out); }
.patterns__card.is-full { --pat-lit:1; --pat-floor:1; }

/* The stills are darkened hard, lit and resting alike, so the words sit
   straight on the photo with no scrim or shadow: --pat-dim is set so the
   bone lines and both labels hold 4.5:1 over the brightest lit pixel. */
.patterns__photo { position:absolute; inset:0; z-index:0; --pat-dim:.16; --pat-r:210px;
  filter: brightness(var(--pat-dim)) saturate(.55); opacity:.2; }
/* The light: the same still at full brightness, shown only inside the
   pointer's pool (or everywhere when tapped on touch). */
.patterns__photo--lit { z-index:1; filter:none; opacity:1;
  -webkit-mask-image: radial-gradient(var(--pat-r) circle at var(--x) var(--y),
    rgba(0,0,0,var(--pat-lit)) 0%, rgba(0,0,0,calc(var(--pat-lit) * .72 + var(--pat-floor) * .28)) 28%, rgba(0,0,0,calc(var(--pat-lit) * .32 + var(--pat-floor) * .68)) 58%, rgba(0,0,0,var(--pat-floor)) 100%);
          mask-image: radial-gradient(var(--pat-r) circle at var(--x) var(--y),
    rgba(0,0,0,var(--pat-lit)) 0%, rgba(0,0,0,calc(var(--pat-lit) * .72 + var(--pat-floor) * .28)) 28%, rgba(0,0,0,calc(var(--pat-lit) * .32 + var(--pat-floor) * .68)) 58%, rgba(0,0,0,var(--pat-floor)) 100%); }
.patterns__photo img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  object-position: center 33%; opacity:0;
  transition: opacity .45s var(--ease-out); }
.patterns__photo img.is-on { opacity:1; transition-delay:.12s; }
.patterns__room--work .patterns__photo img.is-on { transition-delay:.2s; }

.patterns__text { position:relative; z-index:2; margin:0; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; }
.patterns__label { font-family: var(--f-display); font-style:italic; font-weight:460;
  font-optical-sizing:none; font-variation-settings:"opsz" 144;
  font-size: clamp(2.5rem, 5vh, 3.5rem); line-height:1.1; letter-spacing:-0.01em;
  /* --gold lifted 27% toward bone */
  color: #E8BB68; }
.patterns__room--work .patterns__label { color: #CDBDF2; }
.patterns__lines { display:grid; margin-top:.5rem; max-width:22ch; font-family: var(--f-display);
  font-size: clamp(1.5rem, 3vh, 2.125rem); font-weight:360; font-style:normal; line-height:1.25;
  letter-spacing:-0.01em; color: var(--tx-inv); text-align:center; }
.patterns__lines > span { grid-area:1/1; opacity:0; transform: translateY(.25rem);
  transition: opacity .26s var(--ease-out), transform .26s var(--ease-out); }
.patterns__lines > span.is-on { opacity:1; transform:none; }
.patterns__lines > span.is-out { opacity:0; transform: translateY(-.25rem); }
.patterns__room--work .patterns__lines > span { transition-delay:.08s; }

/* Roll pulse: on each word change both borders bloom and settle. */
.patterns__card.is-pulse { animation: patPulseHome .75s var(--ease-out); }
.patterns__room--work.is-pulse { animation-name: patPulseWork; }
@keyframes patPulseHome {
  0%   { box-shadow: 0 0 0 0 rgba(227,169,60,0); border-color: rgba(227,169,60,.3); }
  20%  { box-shadow: 0 0 12px 0 rgba(227,169,60,.22); border-color: rgba(227,169,60,1); }
  100% { box-shadow: 0 0 0 0 rgba(227,169,60,0); border-color: rgba(227,169,60,.3); } }
@keyframes patPulseWork {
  0%   { box-shadow: 0 0 0 0 rgba(169,133,230,0); border-color: rgba(227,169,60,.3); }
  20%  { box-shadow: 0 0 12px 0 rgba(169,133,230,.22); border-color: rgba(169,133,230,1); }
  100% { box-shadow: 0 0 0 0 rgba(169,133,230,0); border-color: rgba(227,169,60,.3); } }

/* Close: one centred line under a gold hairline the width of the cards. */
.patterns__cta { max-width:1120px; margin: 2.5vh auto 0; padding-top:1.5vh;
  border-top:1px solid rgba(227,169,60,.3);
  font-family: var(--f-display); font-size: clamp(1.25rem, 1.8vw, 1.625rem); font-weight:360;
  line-height:1.3; }
.patterns__cta-lead { color: rgba(244,236,222,.65); }
.patterns__cta-link { color: var(--tx-inv); white-space:nowrap;
  text-decoration: underline; text-decoration-thickness:1px; text-underline-offset:.2em;
  text-decoration-color: currentColor;
  transition: color var(--dur-fast) var(--ease-out); }
.patterns__cta-link .arrow { display:inline-block; width:1em; height:1em; vertical-align:-.12em; margin-left:.3em;
  transition: transform var(--dur-fast) var(--ease-out); }
.patterns__cta-link:hover, .patterns__cta-link:focus-visible { color: var(--gold); }
.patterns__cta-link:hover .arrow { transform: translateX(.35em); }
.patterns__cta-link:focus-visible { outline:2px solid var(--violet-300); outline-offset:4px; }

/* Below 768: no chasing the fold. The line, then the cards full width.
   The one-line headline is small here, so the labels and lines step down
   to stay under it. --------------------------------------------------- */
@media (max-width: 767px) {
  .patterns__cards { grid-template-columns: minmax(0,1fr); gap:1rem; margin-top:2rem; }
  .patterns__card { height:auto; min-height:180px; }
  .patterns__photo { --pat-r:160px; }
  .patterns__label { font-size: min(1.875rem, 6.4cqi); }
  .patterns__lines { font-size: min(1.25rem, 5.2cqi); }
  .patterns__cta { margin-top:2rem; padding-top:1rem; }
}

/* Reduced motion: no roll, no pointer light, no pulse; the stills rest a
   little brighter and cross-fade linearly; the lines fade only. ------- */
@media (prefers-reduced-motion: reduce) {
  .patterns__glyphs, .patterns__arrow, .patterns__cta-link, .patterns__cta-link .arrow,
  .patterns .ctx, .patterns .ctx__bar { transition:none !important; }
  .patterns__glyphs { transform:none; }
  .patterns__lines > span, .patterns__lines > span.is-out { transform:none;
    transition: opacity .26s linear; }
  .patterns .ctx__bar, .patterns.is-cycling .ctx__bar { animation:none; transform: scaleX(1); opacity:1; }
  .patterns__card { --pat-lit:0; --pat-floor:0; transition:none; }
  .patterns__photo { opacity:.25; }
  .patterns__photo--lit { opacity:1; }
  .patterns__card.is-full { --pat-lit:1; --pat-floor:1; }
  .patterns__card.is-pulse { animation:none; }
  .patterns__photo img, .patterns__photo img.is-on { transition: opacity .2s linear; transition-delay:0s; }
}

/* --- Surface -> truth cards --- */
.truth { position:relative; color:var(--tx-inv); background:var(--ink); overflow:hidden; }
.truth .media { position:absolute; inset:0; z-index:0; }
.truth .media img { object-position:50% 28%; }
.truth .media::after { content:""; position:absolute; inset:0; background: rgba(12,7,20,0.66); }
.truth__inner { position:relative; z-index:2; width:var(--wrap); margin-inline:auto; padding-block: clamp(5rem,10vw,9rem); }
.truth__head { margin-bottom: clamp(2.5rem,5vw,4rem); }
.truth__head .eyebrow { margin-bottom:1.2rem; }
.truth__head h2 { font-size: var(--step-3); font-weight:340; letter-spacing:-0.025em;
  max-width: 16ch; text-wrap: balance; }
/* Three full-width rows. Each row is one sentence said out loud and the
   sentence underneath it; the strike draws through the first as the second
   rises. One IntersectionObserver trigger per row, one way; hover, focus and
   press re-run it. */
.trows { display:flex; flex-direction:column; }
.trow { position:relative; display:block; width:100%; text-align:left;
  padding: clamp(1.6rem,3.2vw,2.6rem) 0 clamp(1.7rem,3.4vw,2.8rem);
  border-top:1px solid var(--line-inv); cursor:pointer; }
.trows .trow:last-child { border-bottom:1px solid var(--line-inv); }
.trow:focus-visible { outline:2px solid var(--violet-300); outline-offset:-4px; }

.trow__surface { position:relative; display:inline-block;
  font-family: var(--f-display); font-style:italic; font-weight:320;
  font-size: var(--step-4); line-height:1.02; letter-spacing:-0.03em;
  color: var(--tx-inv-soft); }
.trow__strike { position:absolute; left:0; top:.54em; height:2px; width:100%;
  background: var(--violet-300); transform: scaleX(0); transform-origin:left center;
  transition: transform .7s var(--ease-out); }

.trow__under { display:block; margin-top: clamp(.6rem,1.2vw,1rem);
  font-family: var(--f-text); font-size: var(--step-2); font-weight:400;
  line-height:1.14; letter-spacing:-0.01em; color:#fff; max-width: 26ch;
  opacity:0; transform: translateY(14px); filter: blur(8px);
  transition: opacity .6s var(--ease-out) .25s, transform .6s var(--ease-out) .25s,
              filter .6s var(--ease-out) .25s; }

/* One state class, so hover / focus / press can replay the reveal from zero
   by dropping it and re-adding it. Without script both lines simply show. */
.trow.is-revealed .trow__strike { transform: scaleX(1); }
.trow.is-revealed .trow__under { opacity:1; transform:none; filter: blur(0); }
html.no-js .trow__strike { transform: scaleX(1); }
html.no-js .trow__under { opacity:1; transform:none; filter:none; }

@media (max-width: 720px) {
  .trow__surface { font-size: var(--step-3); }
  .trow__under { font-size: var(--step-1); max-width:none; }
}

/* --- Constellation on the operating-system bleed --- */
.bleed__canvas { position:absolute; inset:0; z-index:1; width:100%; height:100%; }
.bleed .media { z-index:0; }
.bleed.bleed--net .media::after { background: radial-gradient(130% 90% at 50% 45%, rgba(14,8,22,.55), rgba(14,8,22,.92)); }

/* --- Keynotes: image bleed on hover, description reveal --- */
.keynote { position:relative; overflow:hidden; }
.keynote__img { position:absolute; inset:0 0 0 auto; width:46%; z-index:0; opacity:0;
  transition: opacity .55s var(--ease-amb); }
.keynote__img img { width:100%; height:100%; object-fit:cover; filter: var(--img-filter); }
.keynote__img::after { content:""; position:absolute; inset:0;
  background: linear-gradient(90deg, var(--plum-2) 6%, rgba(18,10,28,0.80) 42%, rgba(18,10,28,0.34) 100%); }
.keynote__no, .keynote__main, .keynote__cta > * { position:relative; z-index:2; }
/* The row's link is its CTA (10.C): the panel takes no box here, so the
   CTA stays the row's third column, and its ::after stretches over the
   whole row (the CTA itself is not positioned; its text and arrow are, to
   sit over the row's image), so the row clicks through as one link. */
.keynote__panel { display:contents; }
.keynote__pic { display:none; }
.keynote__cta::after { content:""; position:absolute; inset:0; z-index:3; }
.keynote__cta:focus-visible { outline:none; }
.keynote__cta:focus-visible::after { outline:2px solid var(--violet-500); outline-offset:-2px; }
.keynote:hover .keynote__img, .keynote:focus-within .keynote__img { opacity:1; }
.keynote__sub { opacity:0; transform: translateY(6px); max-height:0; overflow:hidden;
  transition: opacity .45s var(--ease-out), transform .45s var(--ease-out), max-height .45s var(--ease-out); }
.keynote:hover .keynote__sub, .keynote:focus-within .keynote__sub { opacity:1; transform:none; max-height:6rem; }

/* The hover picture (js module 10.B, fine pointers only): one still per
   section that follows the cursor (translate is written per frame, so only
   opacity and scale transition; z-index 1 keeps it under the rows' type,
   which sits at 2). While it is on, the row's own image
   bleed stands down. */
.keynotes-sec { position:relative; }
.keynotes__float { position:absolute; left:0; top:0; z-index:1; width:320px; height:200px;
  object-fit:cover; border-radius: 10px; pointer-events:none; filter: var(--img-filter);
  box-shadow: 0 18px 50px rgba(8,4,14,.45);
  opacity:0; scale: .92; transform-origin: 0 100%;
  transition: opacity var(--float-fade, 220ms) var(--ease-out), scale var(--float-fade, 220ms) var(--ease-out); }
.keynotes-sec.is-floating .keynotes__float { opacity:1; scale:1; }
.keynotes-sec.is-still .keynotes__float { transition:none; }
.keynotes-sec.has-float .keynote__img { display:none; }
.keynotes__float[hidden] { display:none; }

/* Talks on coarse pointers (js module 10.C adds .is-disc): each row is a
   disclosure. The title is the button (its ::after covers the row; the
   open panel sits above it so the CTA stays a link), the panel opens under
   it from a measured max-height (360ms) with the picture easing in from
   1.06, and the row's accent marks the open row. */
.keynotes-sec.is-disc .keynote { grid-template-columns:auto 1fr; padding-left:0; }
.keynotes-sec.is-disc .keynote__main { position:static; }
.keynotes-sec.is-disc .keynote__title::after { content:""; position:absolute; inset:0; z-index:3; }
.keynotes-sec.is-disc .keynote__title:focus-visible { outline:none; }
.keynotes-sec.is-disc .keynote__title:focus-visible::after { outline:2px solid var(--violet-500); outline-offset:-2px; }
.keynotes-sec.is-disc .keynote__img { display:none; }
.keynotes-sec.is-disc .keynote__panel { display:block; grid-column:2; position:relative; z-index:4;
  overflow:hidden; max-height:0; visibility:hidden;
  transition: max-height 360ms var(--ease-out), visibility 0s linear 360ms; }
.keynotes-sec.is-disc .keynote.is-open .keynote__panel { visibility:visible;
  transition: max-height 360ms var(--ease-out), visibility 0s; }
.keynotes-sec.is-disc .keynote__pic { display:block; margin-top:1.1rem; aspect-ratio:16/10;
  border-radius:12px; overflow:hidden; }
.keynotes-sec.is-disc .keynote__pic img { display:block; width:100%; height:100%; object-fit:cover;
  filter: var(--img-filter); transform: scale(1.06); transition: transform 360ms var(--ease-out); }
.keynotes-sec.is-disc .keynote.is-open .keynote__pic img { transform:none; }
.keynotes-sec.is-disc .keynote__sub { display:block; opacity:1; transform:none; max-height:none; margin-top:1rem; }
.keynotes-sec.is-disc .keynote__cta { display:inline-flex; margin-top:1rem; padding-block:.4rem; }
.keynotes-sec.is-disc .keynote__cta::after { content:none; }
.keynotes-sec.is-disc .keynote:hover .keynote__accent { width:0; }
.keynotes-sec.is-disc .keynote.is-open .keynote__accent { width: clamp(2.5rem,5vw,5rem); }
.keynotes-sec.is-disc .keynote:hover .keynote__no { color:var(--tx-inv-faint); }
.keynotes-sec.is-disc .keynote.is-open .keynote__no, .keynotes-sec.is-disc .keynote.is-open .keynote__cta { color: var(--_acc, var(--violet));
  color: color-mix(in oklab, var(--_acc, var(--violet)) 55%, var(--tx-inv)); }
@media (prefers-reduced-motion: reduce) {
  .keynotes-sec.is-disc .keynote__panel, .keynotes-sec.is-disc .keynote.is-open .keynote__panel,
  .keynotes-sec.is-disc .keynote__pic img { transition:none; }
}

/* Reduced motion: both lines are simply there, the strike is drawn full
   width and still. */
@media (prefers-reduced-motion: reduce) {
  .ctx .swap > span { transition:none; }
  .trow__strike { transform: scaleX(1); transition:none; }
  .trow__under { opacity:1; transform:none; filter:none; transition:none; }
}
@media (max-width: 720px) {
  .keynote__img { display:none; }
  .keynote__sub { opacity:1; transform:none; max-height:none; }  /* no hover on mobile */
  /* the CTA (hidden here before 10.C) sits under the row's text */
  .keynote__panel { display:block; grid-column:2; }
  .keynote__cta { margin-top:.9rem; }
}

/* =====================================================================
   CRAFT PASS (impeccable craft-floor + Emil design-eng)
   ===================================================================== */

/* Browser surfaces - themed, not browser-default */
::selection { background: var(--violet); color: #fff; }
html { caret-color: var(--violet); scrollbar-color: color-mix(in oklab, var(--violet) 55%, var(--paper-3)) var(--paper-2); }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--paper-2); }
::-webkit-scrollbar-thumb { background: color-mix(in oklab, var(--violet) 50%, var(--paper-3));
  border-radius: 10px; border: 3px solid var(--paper-2); }
::-webkit-scrollbar-thumb:hover { background: var(--violet); }

/* Press feedback - pressable elements answer the press */
.btn, .nav-cta, .play__ring, .keynote { transition-property: transform, background, color, opacity, padding-left, box-shadow; }
.btn:active { transform: scale(0.97); }
.btn--lg:active { transform: scale(0.98); }
.nav-cta:active { transform: scale(0.96); }
.play:active .play__ring { transform: scale(0.93); }
.textlink:active { opacity: .7; }

/* Hover effects only where hover is real (no touch false-fire) */
@media (hover: none) {
  .keynote__sub { opacity: 1; transform: none; max-height: none; }
  .keynote__img { display: none; }
}

/* Editorial stat line (replaces the three-metric template) */
.stats { background: var(--plum-2); color: var(--tx-inv); border-top: 1px solid var(--line-inv); }
.stats__eyebrow { width: var(--wrap); margin: 0 auto clamp(1.6rem,3vw,2.4rem);
  padding-top: clamp(3.5rem,7vw,6.5rem); padding-bottom: .55rem;
  border-bottom: 1px solid rgba(227,169,60,.30); }
.stats__line { width: var(--wrap); margin-inline: auto; padding-bottom: clamp(3.5rem,7vw,6.5rem);
  font-family: var(--f-display); font-weight: 340; font-size: var(--step-3); line-height: 1.12;
  letter-spacing: -0.03em; color: var(--tx-inv-faint); max-width: 26ch; }
.stats__n { color: var(--tx-inv); font-variant-numeric: tabular-nums lining-nums; }

/* The odometer (built by the script when the count-up is armed): the
   plain figure stays in the markup, visually hidden; the columns are
   aria-hidden. Each column is one line tall and clips a 0-9 stack, which
   the script rolls with translateY(-10% per digit). */
.odo__sr { position:absolute !important; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space:nowrap; border:0; }
.odo { display:inline; white-space:nowrap; }
.odo__col { position:relative; display:inline-block; height:1.12em; line-height:1.12; overflow:hidden; vertical-align:bottom; }
.odo__w { visibility:hidden; }
.odo__d { position:absolute; left:50%; top:0; display:block; margin-left:-1em; width:2em; text-align:center;
  transform: translateY(0); will-change: transform; }
.odo__d > span { display:block; height:1.12em; }
@media (prefers-reduced-motion: reduce) { .odo__d { transition:none !important; } }

/* Numerals that should never wobble */
.keynote__no, [data-count] { font-variant-numeric: tabular-nums lining-nums; }

/* Clip-path image reveals - an authored entrance distinct from the block fades */
/* Default is fully visible; JS only arms (hides) images that start below the fold. */
[data-reveal-clip] { clip-path: inset(0 0 0 0); }
[data-reveal-clip].armed { clip-path: inset(0 0 100% 0); transition: clip-path 1.1s var(--ease-out); }
[data-reveal-clip].armed.in { clip-path: inset(0 0 0 0); }
@media (prefers-reduced-motion: reduce) { [data-reveal-clip] { clip-path: none !important; transition: none; } }

/* Blur-to-focus image reveals: same fail-safe contract as the clip wipe. */
[data-reveal-focus] { filter: var(--img-filter); }
[data-reveal-focus].armed { filter: var(--img-filter) blur(18px); transition: filter 1.3s var(--ease-out); }
[data-reveal-focus].armed.in { filter: var(--img-filter); }
@media (prefers-reduced-motion: reduce) { [data-reveal-focus] { filter: var(--img-filter) !important; transition: none; } }

/* Credentials without the decorative numbering */
.creds .cred { gap: 0; }

/* ---- What happens when you book: sticky step list ----
   Five steps, then a sixth stage in which the scene becomes the final
   call to action (the old section.final). Each stage is 70vh of scroll. */
.steps { position:relative; background: var(--plum-2); color: var(--tx-inv); }
.steps__track { height: calc(6 * 70vh); }
.steps__sticky { position:sticky; top:0; height:100vh; overflow:hidden; background: var(--plum-2); }
.steps__media { position:absolute; inset:0; }
.steps__still { position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:50% 40%;
  filter: var(--img-filter); opacity:0; transform: scale(1.04);
  transition: opacity .9s var(--ease-out), transform 1.6s var(--ease-out); }
.steps__still.is-on { opacity:1; transform:none; }
.steps__grade { position:absolute; inset:0; pointer-events:none;
  background:
    linear-gradient(95deg, rgba(14,8,22,.93) 0%, rgba(14,8,22,.78) 34%, rgba(14,8,22,.34) 58%, rgba(14,8,22,0) 78%),
    linear-gradient(0deg, rgba(14,8,22,.72), rgba(14,8,22,0) 52%); }
.steps__copy { position:absolute; left: var(--gutter); top:50%; transform: translateY(-50%); z-index:2;
  width: min(46rem, calc(100% - 2 * var(--gutter)));
  transition: opacity .6s var(--ease-out), translate .6s var(--ease-out); }
.steps__copy .eyebrow { display:block; margin-bottom: .9rem; }
.steps__copy h2 { font-size: var(--step-3); font-weight:320; line-height:1.0; letter-spacing:-0.035em;
  max-width: 16ch; margin-bottom: clamp(1.8rem, 3vw, 2.6rem); }
.steps__list { list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:.35rem;
  min-height: var(--steps-list-h, 0px); }
.steps__list li { display:grid; grid-template-columns: 2.6rem 1fr; grid-template-rows:auto auto;
  column-gap:.9rem; align-items:baseline; padding:.75rem 1rem .8rem .9rem;
  border:1px solid transparent; border-radius: var(--radius); color: var(--tx-inv-faint);
  transition: color .5s var(--ease-out), border-color .5s var(--ease-out), background .5s var(--ease-out); }
.steps__n { font-family: var(--f-display); font-size: var(--step--1); letter-spacing:.08em;
  font-variant-numeric: tabular-nums lining-nums; transition: color .5s var(--ease-out); }
.steps__t { font-family: var(--f-display); font-size: var(--step-1); font-weight:360; letter-spacing:-0.02em;
  line-height:1.15; }
.steps__d { grid-column:2; font-family: var(--f-text); font-size: var(--step-0); line-height:1.5; color:inherit;
  max-width:42ch; margin-top:.25rem; opacity:0; max-height:0; overflow:hidden;
  transition: opacity .5s var(--ease-out), max-height .5s var(--ease-out); }
.steps__list li.is-on { color: var(--tx-inv); border-color: var(--line-inv-strong); background: rgba(244,236,222,0.06); }
.steps__list li.is-on .steps__n { color: var(--violet-300); }
.steps__list li.is-on .steps__d { opacity:1; max-height:8rem; }
.steps__copy .textlink { margin-top: clamp(1.6rem, 3vw, 2.4rem); display:inline-flex; }
.textlink--inv { color: var(--tx-inv); }

/* Stage 6. The final call to action is a second sticky layer laid over the
   pinned scene (same track, pulled up by its own height). It keeps every
   .final rule, so once in it looks exactly like the old section.final:
   the plum ground crossfades in on the stills' .9s, the content rises
   .25rem over .6s, and the step copy lifts away. Without script it is
   a normal block after the steps. */
.js .steps__final { position:sticky; top:0; height:100vh; margin-top:-100vh; z-index:3;
  display:flex; align-items:center; justify-content:center; padding-top: 4.75rem;
  opacity:0; pointer-events:none; transition: opacity .9s var(--ease-out); }
.js .steps__final .final__inner { padding-block:0; opacity:0; transform: translateY(.25rem);
  transition: opacity .6s var(--ease-out) .15s, transform .6s var(--ease-out) .15s; }
.js .steps.is-final .steps__final { opacity:1; pointer-events:auto; }
.js .steps.is-final .steps__final .final__inner { opacity:1; transform:none; }
.js .steps.is-final .steps__copy { opacity:0; translate: 0 -.25rem; pointer-events:none; }
@media (max-width: 720px) { .js .steps__final { padding-top: 3.25rem; } }
/* A short screen cannot hold the full-size line inside one pinned stage,
   so there the headline steps down to fit; 900px and taller are unchanged. */
@media (max-height: 860px) { .js .steps__final h2 { font-size: min(var(--step-5), 17vh); } }

@media (max-width: 720px) {
  .steps__copy { top:auto; bottom: clamp(2rem, 6vh, 4rem); transform:none; }
  .steps__copy h2 { font-size: var(--step-2); margin-bottom: clamp(1.1rem, 3vh, 1.6rem); }
  .steps__still { object-position: 60% 40%; }
  .steps__grade { background:
    linear-gradient(95deg, rgba(14,8,22,.88) 0%, rgba(14,8,22,.62) 44%, rgba(14,8,22,.30) 74%),
    linear-gradient(0deg, rgba(14,8,22,.94) 12%, rgba(14,8,22,.70) 46%, rgba(14,8,22,0) 86%); }
  .steps__list { gap:.15rem; }
  .steps__list li { padding:.5rem .7rem .55rem .65rem; grid-template-columns: 2.1rem 1fr; column-gap:.6rem; }
  .steps__d { font-size: var(--step--1); max-width:36ch; }
  /* reserve three lines so the bottom-anchored block never shifts the headline */
  .steps__list li.is-on .steps__d { max-height: 5.2rem; min-height: 4.5em; }
}


/* Short viewports: the scene is pinned at 100vh, so the copy column has to
   fit the height it is given. Step the scale down rather than clip. */
@media (min-width: 721px) and (max-height: 980px) {
  .steps__copy { top: calc(50% + 2.2rem); }   /* clear the fixed nav */
  .steps__copy h2 { font-size: var(--step-2); max-width: 20ch; margin-bottom: clamp(1rem, 2vh, 1.6rem); }
  .steps__copy .eyebrow { margin-bottom: .6rem; }
  .steps__list { gap: .2rem; }
  .steps__list li { padding: .55rem .9rem .6rem .8rem; }
  .steps__copy .textlink { margin-top: clamp(1rem, 2vh, 1.6rem); }
}
@media (min-width: 721px) and (max-height: 660px) {
  .steps__copy h2 { max-width: 24ch; }
  .steps__t { font-size: var(--step-0); }
  .steps__list li { padding: .4rem .8rem .45rem .7rem; }
  .steps__list li.is-on .steps__d { max-height: 4.6rem; }
}
@media (prefers-reduced-motion: reduce) {
  .steps__track { height:auto; }
  .steps__sticky { position:relative; height:auto; min-height:80vh; padding-block:6rem; }
  .steps__still { transition:none; }
  .steps__still.is-on { opacity:1; }
  .steps__copy { position:relative; top:auto; bottom:auto; left:auto; transform:none;
    width:auto; padding-inline: var(--gutter); }
  .steps__list { min-height:0; }
  .steps__list li { color: var(--tx-inv); transition:none; }
  .steps__d { opacity:1; max-height:none; transition:none; }
  .steps__list li.is-on .steps__d { max-height:none; }
  /* no pin: the call to action is a normal block after step 05 */
  .js .steps__final { position:relative; height:auto; margin-top:0; padding-top:0; display:block;
    opacity:1; pointer-events:auto; transition:none; }
  .js .steps__final .final__inner { padding-block: clamp(6rem,12vw,12rem); opacity:1; transform:none; transition:none; }
  .js .steps__final h2 { font-size: var(--step-5); }
}
/* ---- Credibility ribbon: label above the lane, timed spotlight ---- */
.orgband { background: var(--plum); color: var(--tx-inv);
  padding-block: clamp(3.2rem,6vw,5.5rem); overflow:hidden; }
.cred__lane { display:block; }
.cred__lane + .cred__lane { margin-top: clamp(2rem,4vw,3.4rem); }

/* Inverted eyebrow over its own lane, on the text measure, with the one
   piece of gold this section is allowed: a hairline under the label. */
.cred__label { display:block; width: var(--wrap); margin: 0 auto clamp(.9rem,1.6vw,1.3rem);
  padding-bottom: .55rem; border-bottom: 1px solid rgba(227,169,60,.30);
  font-family: var(--f-text); font-size: var(--step--1); font-weight:500;
  letter-spacing:.22em; text-transform:uppercase; color: var(--tx-inv-soft); line-height:1.3; }

/* Room for a logo to grow: the viewport is padded so a lit logo at 2.15x
   is never clipped, and the track gap holds grown neighbours apart. */
.cred__viewport { position:relative; overflow:hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
/* The track is transformed, so it is its own stacking context and nothing
   inside it can blend with anything outside. The knockouts screen against
   plum, so the plum has to be painted here, and the vertical padding lives
   here too so a logo grown to 2.15x is still inside the painted box. */
.cred__track { display:flex; align-items:center; gap: clamp(4.2rem,5vw,5.5rem);
  width:max-content; padding-block: 2.2rem; background: var(--plum);
  will-change:transform; }
.cred__track img { height: clamp(26px,3vw,42px); width:auto; object-fit:contain; flex:0 0 auto;
  user-select:none; position:relative; z-index:1;
  filter: grayscale(1) brightness(1.6) opacity(.42) brightness(calc(0.8 + 0.4 * var(--near, 1)));
  transition: filter 1100ms cubic-bezier(.4,0,.2,1), transform 1100ms cubic-bezier(.4,0,.2,1); }
.cred__lane--sm .cred__track img { height: clamp(20px,2.4vw,32px); }
/* the glow toward the lane's centre: --near (0..1) is written per logo by
   the drift loop; without it (no script, reduced motion) every logo is at
   1. The brightness rides on the end of each filter chain below; a lit
   logo is fully on. */
.cred__track img { opacity: calc(0.45 + 0.55 * var(--near, 1)); }
.cred__track img.lit { opacity:1; }
/* only the lit logo and the one queued next carry the compositing hint */
.cred__track img.lit, .cred__track img.next { will-change: transform, filter; }

.cred__track img.lit { filter:none; z-index:2;
  transform-origin: 50% 60%; transform: translateY(-8px) scale(1.9);
  transition: filter 900ms cubic-bezier(.22,1,.36,1), transform 900ms cubic-bezier(.22,1,.36,1); }
.cred__lane--sm .cred__track img.lit { transform: translateY(-8px) scale(2.15); }

/* Logos delivered as ink on an opaque white plate: inverted and screened so
   the plate drops out against the plum instead of flashing a white box. */
.cred__track img[data-knockout] {
  filter: grayscale(1) invert(1) brightness(1.5) opacity(.45) brightness(calc(0.8 + 0.4 * var(--near, 1))); mix-blend-mode: screen; }
.cred__track img[data-knockout].lit {
  filter: grayscale(1) invert(1) brightness(1.9) opacity(1); }

/* Logos that ARE a solid coloured box (the brand mark is the plate): they
   cannot be knocked out without inverting the brand. At rest they are
   desaturated and dimmed so the box recedes into the plum; lit, they come
   back in true brand colour. No inversion, no white plate. */
.cred__track img[data-plate] {
  filter: grayscale(1) brightness(.8) opacity(.38) brightness(calc(0.8 + 0.4 * var(--near, 1))); mix-blend-mode: normal; }
.cred__track img[data-plate].lit { filter: none; }

@media (max-width: 700px) {
  .cred__track img.lit,
  .cred__lane--sm .cred__track img.lit { transform: translateY(-8px) scale(1.5); }
}
@media (prefers-reduced-motion: reduce) {
  .cred__track { transform:none !important; }
  .cred__track img { filter: grayscale(0) opacity(.75); transition:none; transform:none !important; }
  /* the knockout still has to hold, or a white plate lands on the plum */
  .cred__track img[data-knockout],
  .cred__track img[data-knockout].lit {
    filter: grayscale(1) invert(1) brightness(1.6) opacity(.75); }
  /* the plate logos sit calm and legible, no inversion */
  .cred__track img[data-plate],
  .cred__track img[data-plate].lit {
    filter: grayscale(0) opacity(.6); }
}

/* CTA card riding the end of the ribbon */
.orgband__cta { width: var(--wrap); margin-inline: auto; margin-top: clamp(2.4rem, 4vw, 3.6rem);
  padding: clamp(1.4rem, 2.5vw, 2rem) clamp(1.6rem, 3vw, 2.6rem);
  background: var(--plum-2); border: 1px solid var(--line-inv);
  border-top-color: rgba(227,169,60,.30); border-radius: var(--radius);
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem; }
.orgband__cta p { margin: 0; font-family: var(--f-display); font-size: var(--step-1); font-weight: 360;
  letter-spacing: -0.02em; line-height: 1.15; max-width: 22ch; color: var(--tx-inv); }
@media (max-width: 700px) {
  .orgband__cta { flex-direction: column; align-items: stretch; text-align: left; }
  .orgband__cta .btn { width: 100%; justify-content: center; }
}

/* =====================================================================
   SPEAKING PAGE (/speaking/) — everything below is scoped to .spk-*
   Build spec: 05_Website/Design/SPEAKING-PAGE-DESIGN-SPEC.md
   Ground sequence, one tone step between neighbours:
   hero plum-2 · proof plum-2 · keynotes plum · turn plum-2 · formats plum
   · bio ink · ribbon plum · footer plum-2.
   Round 6: exactly one position:sticky on the page: .spk-chap__stage.
   ===================================================================== */

/* Visually-hidden utility for this page's live regions and connectives */
.spk-sr { position:absolute !important; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space:nowrap; border:0; }

/* ---- 0. The ground ---- */
.spk-ground { position:fixed; inset:0; z-index:0; overflow:hidden; pointer-events:none;
  background: var(--plum-2); }
.spk-ground__img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  object-position: 50% 42%; transform: scale(var(--spk-ground-zoom, 1)); transform-origin: 50% 40%;
  will-change: transform; }
.spk-ground__veil { position:absolute; inset:0;
  background: rgb(var(--spk-ground, 26 16 38)); opacity: .78; }
html.no-js .spk-ground__img { display:none; }
.spk-hero, .spk-proof, .spk-said, .spk-keys, .spk-chap, .spk-out, .spk-formats, .spk-plan, .spk-bio { position:relative; z-index:1; }

/* ---------------------------------------------------------------------
   0. Lights up — ONE shared treatment for every photo on this page:
   the keynote grounds, the walk-out still and the bio portrait. The
   house is dark until the moment the content lands, then the lights come
   up on the image. Written as `.media .spk-lights` because `.media img`
   already sets `filter: var(--img-filter)`, so the class has to carry the
   whole filter chain to win. Duration is per host through --lights-dur.
   --------------------------------------------------------------------- */
.media .spk-lights { filter: brightness(.30) saturate(.55) contrast(1.04); opacity:.55;
  transition: filter var(--lights-dur, 1.25s) var(--ease-out),
              opacity var(--lights-dur, 1.25s) var(--ease-out); }
.media .spk-lights.is-lit { filter: brightness(1) saturate(.92) contrast(1.06); opacity:1; }
/* Nothing brings the lights up without the script, so with no script the
   house is simply lit: every photo sits at the site's normal grade. */
html.no-js .media .spk-lights { filter: var(--img-filter); opacity:1; transition:none; }
@media (prefers-reduced-motion: reduce) {
  .media .spk-lights { transition:none; }
}

/* ---------------------------------------------------------------------
   1. Hero — full-screen reel with sound. No visible hero text: the reel
   carries its own on-screen titles, so the frame stays clear and the only
   thing over it is the control row at the bottom. The h1 is in the DOM as
   .spk-sr for the heading order and for search.
   Reuses .hero, .media.media--plum, .hero__actions and the
   .hero__poster / .hero__video positioning rules (selector lists above).
   --------------------------------------------------------------------- */
.spk-hero .media img, .spk-hero .media video { object-position: 50% 28%; }
/* Parallax: the picture leaves at half the scroll speed (module 9 writes
   --spk-hero-par). The hero clips what slides below its floor. */
.spk-hero { overflow:hidden; }
.spk-hero .media { transform: translateY(var(--spk-hero-par, 0px)); will-change: transform; }
@media (prefers-reduced-motion: reduce) { .spk-hero .media { transform:none; will-change:auto; } }

/* No text needs the left-to-right grade, so it goes. What stays is a soft
   bottom grade under the controls and a light top wash under the nav.
   With the big control now standing on the floor too, the bottom grade
   reaches a little further up so the ring and its label keep their contrast
   without the radial scrim that used to sit behind them. */
.spk-hero .media::after {
  background:
    linear-gradient(0deg, rgba(14,8,22,0.80) 0%, rgba(14,8,22,0.52) 14%, rgba(14,8,22,0.26) 30%, rgba(14,8,22,0) 52%),
    linear-gradient(180deg, rgba(14,8,22,0.48) 0%, rgba(14,8,22,0) 26%); }

/* The floor of the hero, as one measurement: the control row sits on it and
   everything above it (the voice line) is anchored off the same number, so
   the stack stays together at every viewport height. */
.spk-hero { --spk-floor: clamp(2rem, 6vh, 4rem); --spk-ctrl-h: 3rem; }

/* The primary control: one large ring on the floor of the hero, directly above
   the three small controls, because the thing being offered on a speaking page
   is the sound. It fades out on the click and comes back only when the reel
   ends. It is bottom-anchored off the same --spk-floor as the control row and
   sits in the slot the voice line uses once sound is on — the two are never
   on screen together, so they share it. The middle of the frame is left to the
   reel: its own burned-in title card runs there for the first few seconds. */
.spk-hero__cta { position:absolute; left:50%; transform: translateX(-50%);
  bottom: calc(var(--spk-floor) + var(--spk-ctrl-h) + 1.25rem);
  z-index:3; display:flex; flex-direction:column; align-items:center; gap:1.1rem;
  padding:0; border:0; background:none; color: var(--tx-inv);
  transition: opacity .42s var(--ease-out), transform .42s var(--ease-out); }
/* the one control that has to be unmissable, so the ring is drawn at full
   strength rather than the hairline the small controls use */
.spk-hero__cta .play__ring { width:6rem; height:6rem;
  border:1.5px solid rgba(244,236,222,.72);
  background: rgba(14,8,22,.34); backdrop-filter: blur(2px); }
.spk-hero__cta .play__ring svg { width:1.7rem; height:1.7rem; margin-left:0; }
.spk-hero__cta .spk-ic--play { margin-left:5px; }
.spk-hero__cta .play__ring::before { border-color: var(--violet-400, var(--violet-300)); }
@media (hover: hover) and (pointer: fine) {
  .spk-hero__cta:hover .play__ring { transform: scale(1.06); }
  .spk-hero__cta:hover .play__ring::before { clip-path: inset(0 0 0 0); }
}
.spk-hero__cta:active .play__ring { transform: scale(.95); }
.spk-hero__cta:focus-visible { outline:2px solid var(--gold); outline-offset:8px; }
.spk-hero__cta-label { font-family: var(--f-display); font-weight:380; font-size: var(--step-1);
  line-height:1.1; letter-spacing:-0.015em; white-space:nowrap;
  text-shadow: 0 2px 18px rgba(8,4,14,.55); }
.spk-hero__cta[data-state="start"]  .spk-ic--play   { display:block; }
.spk-hero__cta[data-state="replay"] .spk-ic--replay { display:block; }
/* gone once the reel is running: no transform on the way out, so the ring
   does not appear to fly off the frame */
.spk-hero__cta.is-gone { opacity:0; pointer-events:none; visibility:hidden;
  transition: opacity .42s var(--ease-out), visibility 0s linear .42s; }
html.no-js .spk-hero__cta { display:none; }
@media (max-width: 767px) {
  .spk-hero__cta .play__ring { width:4.75rem; height:4.75rem; }
  .spk-hero__cta .play__ring svg { width:1.4rem; height:1.4rem; }
  .spk-hero__cta-label { font-size: var(--step-0); }
  .spk-hero__cta { bottom: calc(var(--spk-floor) + var(--spk-ctrl-h) + .9rem); gap:.8rem; }
}

/* Controls: three real buttons, the .play__ring vocabulary at 3rem, as one
   centred row on the floor of the hero. */
.spk-hero__controls { position:absolute; left:0; right:0; bottom: var(--spk-floor);
  z-index:2; width: var(--wrap); margin: 0 auto; max-width:none;
  justify-content:center; gap: 1rem clamp(1.4rem, 2.6vw, 2.2rem); }
.spk-ctrl { display:inline-flex; align-items:center; gap:.75rem; color: var(--tx-inv);
  padding:0; border:0; background:none; }
.spk-ctrl[hidden] { display:none; }
.spk-ctrl .play__ring { width:3rem; height:3rem; flex:0 0 auto; }
.spk-ctrl .play__ring svg { width:1.05rem; height:1.05rem; margin-left:0; }
.spk-ctrl .spk-ic--play { margin-left:3px; }
@media (hover: hover) and (pointer: fine) {
  .spk-ctrl:hover .play__ring { transform: scale(1.07); }
  .spk-ctrl:hover .play__ring::before { clip-path: inset(0 0 0 0); }
}
.spk-ctrl:active .play__ring { transform: scale(.93); }
.spk-ctrl__label { font-family: var(--f-text); font-weight:600; font-size: var(--step--1);
  letter-spacing:.02em; white-space:nowrap; }
.spk-ctrl:focus-visible { outline:2px solid var(--gold); outline-offset:3px; }
/* the ring answers the pressed state without a fill or a box */
.spk-ctrl[aria-pressed="true"] .play__ring { border-color: var(--violet-300); }

/* One icon per state; the button's data-state decides which is painted. */
.spk-ic { display:none; fill: currentColor; }
.spk-ic--sound, .spk-ic--mute, .spk-ic--cc, .spk-ic--cc-off, .spk-ic--replay { fill:none; }
.spk-ctrl[data-state="play"]   .spk-ic--play   { display:block; }
.spk-ctrl[data-state="pause"]  .spk-ic--pause  { display:block; }
.spk-ctrl[data-state="replay"] .spk-ic--replay { display:block; }
.spk-ctrl[data-state="on"]     .spk-ic--sound  { display:block; }
.spk-ctrl[data-state="mute"]   .spk-ic--mute   { display:block; }
.spk-ctrl[data-state="off"]    .spk-ic--cc-off { display:block; }
.spk-ctrl[data-state="cc"]     .spk-ic--cc     { display:block; }

/* Native cue layer only — no custom caption box */
.spk-hero__video::cue { background: rgba(8,4,14,.72); color:#fff; }

html.no-js .spk-hero__controls { display:none; }

/* The voice line: one open line, compact and centred, sitting directly on top
   of the control row — bottom-anchored off the same --spk-floor, so it can
   never drift into the middle of the frame at any viewport height.
   It is INVISIBLE while the reel is muted, paused or finished: there is no
   idle line. The script adds .is-on only while sound is actually playing.
   Decorative, never interactive, so the controls keep the pointer.
   Absent with no script; a single static render under reduced motion. */
.spk-voice { position:absolute; left:50%; transform: translateX(-50%); z-index:1;
  pointer-events:none; display:block;
  width: min(560px, 60vw); height: 64px;
  bottom: calc(var(--spk-floor) + var(--spk-ctrl-h) + 1.25rem);
  opacity:0; transition: opacity .45s var(--ease-out); }
.spk-voice.is-on { opacity:1; }
@media (max-width: 767px) { .spk-voice { height: 52px; bottom: calc(var(--spk-floor) + var(--spk-ctrl-h) + .9rem); } }
html.no-js .spk-voice { display:none; }
@media (prefers-reduced-motion: reduce) { .spk-voice { transition:none; } }

@media (max-width: 767px) {
  .spk-ctrl__label { position:absolute !important; width:1px; height:1px; margin:-1px; padding:0;
    overflow:hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space:nowrap; border:0; }
  .spk-ctrl { gap:0; }
  .spk-hero__controls { gap: 1.25rem; }
}
@media (max-width: 720px) {
  .spk-hero .media img, .spk-hero .media video { object-position: 52% 26%; }
}

/* ---------------------------------------------------------------------
   2. Proof line — the reused .stats count-up, centred, no eyebrow
   --------------------------------------------------------------------- */
.spk-proof .stats__line { padding-top: clamp(3.5rem, 7vw, 6.5rem);
  margin-inline: auto; text-align: center; max-width: 30ch; }

/* ---------------------------------------------------------------------
   3. Keynotes — a pinned stage. The track is 480svh; the stage is sticky
   inside it for 380svh of scroll. Module 2 registers one spine entry and
   writes the phases as custom properties (the scroll is the clock, so
   none of them has a transition):
     --rise, --g  on the ground: both held at 1 (written once), so the
                  ground is exactly the viewport; the card rules stay
     --reveal     on the ground: held at 1 (the wheel's velvet fades
                  out over it instead, --spk-keys-reveal, first 60svh)
     --head       on the heading: in over 63-81svh (once the wheel's
                  candles have faded, --spk-keys-gone, u 40-70), out over the first
                  40svh of talk 01
     --wi         on panels 2 and 3: the wipe in from the right
     --cap        on each panel: its caption, the ring inside it
   The section rises UNDER the last 60svh of the candle wheel's stage
   (its margin-top, over the wheel only; the wheel is z 3): the velvet
   fades, the talks show in the gap between the candles, which stay in
   front and scroll away. The room section
   (.spk-chap) rises over this stage in the last 50svh (see its
   margin-top).
   --------------------------------------------------------------------- */
.spk-keys { position:relative; background: transparent; color: var(--tx-inv); }
/* under the candle wheel's held stage (a pinned wheel is z 3, see A.) */
.spk-keys { margin-top: -160svh; z-index: 2; }
/* only over a pinned wheel: no script, reduced motion, Save-Data and
   phones (where this section is not pinned) have none */
html.no-js .spk-keys, .spk-keys.is-stacked, .spk-said.is-stacked + .spk-keys { margin-top:0; }
@media (max-width: 768px) { .spk-keys { margin-top:0; } }
/* head + N talks + a 50svh hold, plus the stage's own screen: 480svh for
   three talks (--panels, --head-svh, --panel-svh: the section's inline
   style, from the block's settings) */
.spk-keys__track { height: calc((var(--head-svh, 90) + var(--panel-svh, 80) * var(--panels, 3) + 50) * 1svh + 100svh); }
.spk-keys__stage { position:sticky; top:0; height:100svh; overflow:hidden; }

/* The ground: a centred card that grows to full-bleed. At --g 1 it is
   exactly the viewport. */
.spk-keys__ground { position:absolute; left:50%; top:50%; z-index:1; overflow:hidden;
  width: calc(40vw + 60vw * var(--g, 0));
  height: calc(25vw + (100svh - 25vw) * var(--g, 0));
  transform: translate(-50%, calc(-50% + (1 - var(--rise, 0)) * 30svh));
  border-radius: calc(4px * (1 - var(--g, 0)));
  background: var(--plum-2); }
.spk-keys__ground { opacity: var(--reveal, 1); }
.spk-keys__rest, .spk-keys__still { position:absolute; inset:0; display:block;
  width:100%; height:100%; object-fit:cover; object-position: 50% 40%; }

/* The three talks exist only inside the grown picture. */
.spk-keys__panels { position:absolute; inset:0; opacity:0; visibility:hidden;
  transition: opacity .42s var(--ease-out), visibility 0s linear .42s; }
.spk-keys__panels.is-on { opacity:1; visibility:visible;
  transition: opacity .42s var(--ease-out), visibility 0s linear 0s; }
.spk-keys__panel { position:absolute; inset:0; overflow:hidden; }
.spk-keys__panel:focus-visible { outline:2px solid var(--violet-300); outline-offset:-4px; }
/* the panels that are not live take no pointer; the script also makes
   them inert */
.spk-keys__panel.is-off { pointer-events:none; }
.spk-keys__panel + .spk-keys__panel {
  -webkit-mask-image: linear-gradient(to left, #000 calc(var(--wi, 0) * 112% - 12%), transparent calc(var(--wi, 0) * 112%));
          mask-image: linear-gradient(to left, #000 calc(var(--wi, 0) * 112% - 12%), transparent calc(var(--wi, 0) * 112%)); }

/* On each picture: its title, its one line and "Watch Stephen speak",
   centred on the picture, over a soft dark pool drawn on the panel (not on
   the text) that follows the caption's --cap. */
.spk-keys__panel::after { content:""; position:absolute; inset:0; z-index:1; pointer-events:none;
  background: radial-gradient(60% 55% at 50% 50%, rgba(20,10,28,.62), rgba(20,10,28,.28) 60%, transparent 100%);
  opacity: var(--cap, 0); }
.spk-keys__caption { position:absolute; left:50%; top:50%; z-index:2;
  transform: translate(-50%, -50%); text-align:center;
  width: min(34ch, calc(100% - 2 * var(--gutter)));
  opacity: var(--cap, 0); }
.spk-keys__ptitle { font-family: var(--f-display); font-style:normal; font-weight:360;
  font-size: var(--step-2); line-height:1.08; letter-spacing:-0.02em; color: var(--tx-inv);
  text-shadow: 0 2px 24px rgba(0,0,0,.55); }
.spk-keys__ptitle .tm { font-size:.38em; vertical-align:super; color: var(--tx-inv-faint); }
.spk-keys__sub { margin-top:.45rem; font-family: var(--f-display); font-style:italic; font-weight:360;
  font-size: var(--step-0); line-height:1.3; letter-spacing:-0.01em; color: var(--violet-100);
  text-shadow: 0 2px 24px rgba(0,0,0,.55); }

/* The automatic start: a thin lilac ring drawn around the play button over
   4s (--load 0 -> 1, written by module 2); the talk plays when it closes. */
.spk-keys .spk-keys__hear .play__ring svg.spk-keys__load { position:absolute; inset:-6px; width:calc(100% + 12px); height:calc(100% + 12px);
  margin:0; fill:none; transform: rotate(-90deg); pointer-events:none; overflow:visible; }
.spk-keys__load circle { fill:none; stroke: #D6C6FF; stroke-width:2.6; stroke-linecap:round;
  stroke-dasharray: 1; stroke-dashoffset: calc(1 - var(--load, 0));
  opacity: calc(min(1, var(--load, 0) * 20)); filter: drop-shadow(0 0 5px rgba(214,198,255,.75)); }
/* the heading, alone over the full-bleed ground. */
.spk-keys__head { position:absolute; inset:0; z-index:4; display:grid; place-items:center;
  text-align:center; pointer-events:none; padding-inline: var(--gutter);
  opacity: var(--head, 0);
  transform: translateY(calc((1 - var(--head, 0)) * 12px));
  filter: blur(calc((1 - var(--head, 0)) * 6px)); }
.spk-keys__head h2 { font-size: var(--step-2); font-weight:360; color: var(--tx-inv);
  max-width: 30ch; text-wrap: balance; text-shadow: 0 2px 24px rgba(0,0,0,.55); }

/* The small index: one line, top-centre, shown with the panels. */
.spk-keys__index { position:absolute; left:0; right:0; top: clamp(5rem, 12vh, 8rem); z-index:5;
  display:flex; justify-content:center; gap: clamp(1.2rem, 3vw, 2.4rem);
  opacity:0; visibility:hidden;
  transition: opacity .42s var(--ease-out), visibility 0s linear .42s; }
.spk-keys__index.is-on { opacity:1; visibility:visible;
  transition: opacity .42s var(--ease-out), visibility 0s linear 0s; }
.spk-keys__tab { display:inline-flex; align-items:baseline; gap:.55em; padding:.35rem .2rem;
  font-family: var(--f-text); font-size: var(--step--1); font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; line-height:1.2; white-space:nowrap;
  /* .62 is the floor: small text over a picture */
  color: rgba(244,236,222,.62);
  transition: color var(--dur-fast) var(--ease-out); }
.spk-keys__no { font-variant-numeric: tabular-nums lining-nums;
  color: rgba(244,236,222,.62); transition: color var(--dur-fast) var(--ease-out); }
.spk-keys__name .tm { font-size:.6em; vertical-align:super; letter-spacing:0; color: var(--tx-inv-faint); }
/* Each talk carries its own accent, on the tab and on its panel. */
.spk-keys [data-accent="violet"] { --acc: var(--violet-300); }
.spk-keys [data-accent="coral"]  { --acc: var(--coral); }
.spk-keys [data-accent="gold"]   { --acc: var(--gold); }
@media (hover: hover) {
  .spk-keys__tab:hover, .spk-keys__tab:hover .spk-keys__no { color: rgba(244,236,222,.80); }
}
.spk-keys__tab:focus-visible { outline:2px solid var(--violet-300); outline-offset:4px; }
.spk-keys__tab[aria-selected="true"] { color: var(--tx-inv); }
.spk-keys__tab[aria-selected="true"] .spk-keys__no { color: var(--acc, var(--violet-300)); }

/* "Watch Stephen speak" — one button in the caption block, under the line:
   the ring (64px, 56px on phones) centred, its label under it; ring and
   label are the hit area. Being inside the caption, it fades with --cap. */
.spk-keys__hear { position:static; transform:none; display:inline-flex; flex-direction:column;
  align-items:center; gap:.7rem; margin-top: clamp(1.1rem, 2.6vh, 1.6rem);
  padding:0; border:0; background:none; color: var(--tx-inv); }
.spk-keys__hear .play__ring { width:4rem; height:4rem; border-color: var(--line-inv-strong);
  background: rgba(14,8,22,.26); }
.spk-keys__hear .play__ring svg { width:1rem; height:1rem; margin-left:0; fill: currentColor; }
.spk-keys__hear .spk-ic--play { margin-left:2px; }
@media (hover: hover) and (pointer: fine) {
  .spk-keys__hear:hover .play__ring { transform: scale(1.06); }
  .spk-keys__hear:hover .play__ring::before { clip-path: inset(0 0 0 0); }
}
.spk-keys__hear:active .play__ring { transform: scale(.94); }
.spk-keys__hear:focus-visible { outline:2px solid var(--violet-300); outline-offset:6px; }
/* the ring's hover sweep takes the talk's accent (the base .play__ring::before
   names --violet-400, which tokens.css does not define) */
.spk-keys__hear .play__ring::before { border-color: var(--acc, var(--violet-400)); }
.spk-keys__hear[aria-pressed="true"] .play__ring { border-color: var(--acc, var(--violet-300)); }
.spk-keys__hearlabel { font-family: var(--f-text); font-weight:600; font-size: var(--step--1);
  letter-spacing:.08em; text-transform:uppercase; white-space:nowrap;
  text-shadow: 0 1px 12px rgba(0,0,0,.55); }
.spk-keys__hear[data-state="play"]  .spk-ic--play  { display:block; }
.spk-keys__hear[data-state="pause"] .spk-ic--pause { display:block; }

/* The clip: one shared <video> above the pictures, seen only while a talk
   plays. With no script it never gets a src. */
.spk-keys__video { position:absolute; inset:0; z-index:3; width:100%; height:100%;
  object-fit:cover; object-position: 50% 38%; pointer-events:none;
  opacity:0; transition: opacity .42s var(--ease-out); }
.spk-keys__video.is-on { opacity:1; }
html.no-js .spk-keys__video { display:none; }

/* Play state. The type leaves the frame: the index, the heading and every
   caption (with its ring) fade out over 420ms, then go hidden. */
.spk-keys.is-playing .spk-keys__index,
.spk-keys.is-playing .spk-keys__head,
.spk-keys.is-playing .spk-keys__caption { opacity:0; visibility:hidden;
  transition: opacity .42s var(--ease-out), visibility 0s linear .42s; }

/* The only things on the frame while a clip plays: the reel's own caption
   as one line near the bottom (only when captions are on in the hero), and
   one small pause ring bottom-centre. */
.spk-keys__play { position:absolute; left:0; right:0; bottom: clamp(6.5rem, 14vh, 9rem);
  z-index:4; pointer-events:none; text-align:center; }
.spk-keys__cap { margin-inline:auto; max-width:46ch; padding-inline: var(--gutter);
  font-family: var(--f-text); font-size: var(--step-0); line-height:1.5;
  letter-spacing:.01em; color: var(--tx-inv); text-wrap:balance;
  opacity:0; transition: opacity .3s var(--ease-out); }
/* the leading hairline, in the playing talk's accent (the script sets
   data-accent on .spk-keys__play) */
.spk-keys__cap::before { content:""; display:block; width:2.5rem; height:1px;
  margin: 0 auto .7rem; background: var(--acc, var(--violet-300)); }
.spk-keys__cap.is-on { opacity:1; }
html[data-spk-cc="off"] .spk-keys__cap { display:none; }

.spk-keys__pause { position:absolute; left:50%; bottom: clamp(2.5rem, 6vh, 4rem);
  transform: translateX(-50%); z-index:6; padding:0; border:0; background:none;
  color: var(--tx-inv); opacity:0; transition: opacity .42s var(--ease-out); }
.spk-keys__pause[hidden] { display:none; }
.spk-keys.is-playing .spk-keys__pause { opacity:1; }
.spk-keys.is-playing .spk-keys__pause.is-idle { opacity:.35; }
.spk-keys__pause .play__ring { width:3rem; height:3rem; border-color: var(--line-inv-strong); }
.spk-keys__pause .play__ring svg { width:1rem; height:1rem; margin:0; fill:currentColor; display:block; }
@media (hover: hover) and (pointer: fine) {
  .spk-keys__pause:hover .play__ring { transform: scale(1.07); }
  .spk-keys__pause:hover .play__ring::before { clip-path: inset(0 0 0 0);
    border-color: var(--acc, var(--violet-300)); }
}
.spk-keys__pause:focus-visible .play__ring { transform: scale(1.07); }
.spk-keys__pause:focus-visible { outline:2px solid var(--violet-300); outline-offset:4px; opacity:1; }

/* Phones: no pin, no grow. The heading, then the index as a centred row,
   then the three talks as a horizontal snap strip. The script does not
   register with the spine here. */
@media (max-width: 768px) {
  .spk-keys { padding-block: clamp(3.5rem, 12vw, 5rem); }
  .spk-keys__track { height:auto; }
  .spk-keys__stage { position:static; height:auto; overflow:visible;
    display:flex; flex-direction:column; }
  .spk-keys__head { order:1; position:static; inset:auto; display:block;
    opacity:1; transform:none; filter:none; }
  .spk-keys__head h2 { margin-inline:auto; }
  .spk-keys__index { order:2; position:static; flex-wrap:wrap; row-gap:.2rem;
    margin: 1.1rem 0 1.4rem; padding-inline: var(--gutter);
    opacity:1; visibility:visible; transition:none; }
  .spk-keys__tab { min-height:44px; align-items:center; }
  .spk-keys__ground { order:3; position:static; left:auto; top:auto;
    width:auto; height:auto; transform:none; border-radius:0; overflow:visible;
    background:none; }
  .spk-keys__rest { display:none; }
  .spk-keys__panels { position:static; opacity:1; visibility:visible; transition:none;
    display:flex; overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory;
    gap: 1rem; padding-inline: 8vw; scrollbar-width:none; -ms-overflow-style:none;
    -webkit-overflow-scrolling: touch; }
  .spk-keys__panels::-webkit-scrollbar { display:none; }
  .spk-keys__panel { flex: 0 0 84vw; position:relative; inset:auto; aspect-ratio: 4 / 5;
    scroll-snap-align:center; }
  .spk-keys__panel + .spk-keys__panel { -webkit-mask-image:none; mask-image:none; }
  .spk-keys__caption, .spk-keys__panel::after { opacity:1; }
  .spk-keys__hear .play__ring { width:3.5rem; height:3.5rem; }
  /* with no stage to fill, a playing talk fills the viewport */
  .spk-keys__video, .spk-keys__play, .spk-keys__pause { position:fixed; }
}

/* Phones with motion (.is-reel, js module 2): the reel. N + 1 cards of a
   full screen each in the page's own flow: card 0 the rest picture with
   the heading centred on it (the scroll-fill), then one card per talk, its
   caption centred exactly as on the pin. The ground and the panel box let
   go of their boxes (display: contents) so the stage's grid holds the
   cards. No scroll snapping: a mandatory snap on the root made iOS Safari
   yank the page to the first card while the candle wheel's held stage
   was still playing its ending over it (the script still marks
   html.spk-snap while the cards are in view; nothing reads it). A card's
   caption rises in on arrival (--cap 0 → 1, written by the script over
   --cap-ms); the dots (1 + N, bottom right, vertical) replace the index. */
@media (max-width: 768px) {
  .spk-keys.is-reel { padding-block:0; }
  .spk-keys.is-reel .spk-keys__stage { display:grid; grid-template-columns: 100%; }
  .spk-keys.is-reel .spk-keys__ground,
  .spk-keys.is-reel .spk-keys__panels { display:contents; }
  .spk-keys.is-reel .spk-keys__rest { grid-area: 1 / 1; display:block; position:relative; inset:auto;
    width:100%; height:100svh; scroll-snap-align:start; }
  .spk-keys.is-reel .spk-keys__head { grid-area: 1 / 1; position:relative; z-index:2; display:grid;
    place-items:center; height:100svh; padding-inline: var(--gutter);
    background: radial-gradient(70% 45% at 50% 50%, rgba(20,10,28,.5), transparent 100%); }
  .spk-keys.is-reel .spk-keys__panel { position:relative; inset:auto; width:100%; height:100svh;
    aspect-ratio:auto; scroll-snap-align:start; }
  .spk-keys.is-reel .spk-keys__caption { opacity: var(--cap, 0);
    transform: translate(-50%, calc(-50% + (1 - var(--cap, 0)) * 16px)); }
  .spk-keys.is-reel .spk-keys__panel::after { opacity: var(--cap, 0); }
  .spk-keys.is-reel .spk-keys__panel.is-off { pointer-events:auto; }
  .spk-keys.is-reel .spk-keys__index[hidden] { display:none; }
}
.spk-keys__dots { position:fixed; right: 12px; bottom: max(1.2rem, env(safe-area-inset-bottom)); z-index:6;
  display:flex; flex-direction:column; align-items:center;
  opacity:0; visibility:hidden; transition: opacity .32s var(--ease-out), visibility 0s linear .32s; }
.spk-keys__dots.is-in { opacity:1; visibility:visible; transition: opacity .32s var(--ease-out), visibility 0s; }
.spk-keys.is-playing .spk-keys__dots { opacity:0; visibility:hidden; }
.spk-keys__dotlist { display:flex; flex-direction:column; align-items:center; }
.spk-keys__dot { position:relative; width:44px; height:32px; padding:0; border:0; background:none; cursor:pointer; }
.spk-keys__dot::before { content:""; position:absolute; left:50%; top:50%; width:8px; height:8px;
  border-radius:4px; transform: translate(-50%, -50%); background: rgba(244,236,222,.45);
  box-shadow: 0 0 10px rgba(0,0,0,.35);
  transition: height .32s var(--ease-out), background-color .32s var(--ease-out); }
.spk-keys__dot.is-cur::before { height:22px; background: var(--acc, var(--tx-inv)); }
.spk-keys__dot:focus-visible { outline:2px solid var(--violet-300); outline-offset:-4px; border-radius:16px; }

/* No script, or the stacked mode reduced motion switches on: no pin, no
   grow, no index. The heading, then the three talks stacked, each a 16:9
   picture with its caption and its ring. */
html.no-js .spk-keys, .spk-keys.is-stacked { padding-block: clamp(4rem, 8vw, 7rem); }
html.no-js .spk-keys__track, .spk-keys.is-stacked .spk-keys__track { height:auto; }
html.no-js .spk-keys__stage, .spk-keys.is-stacked .spk-keys__stage { position:static; height:auto;
  overflow:visible; display:flex; flex-direction:column; }
html.no-js .spk-keys__head, .spk-keys.is-stacked .spk-keys__head { order:1; position:static;
  inset:auto; display:block; opacity:1; transform:none; filter:none; }
html.no-js .spk-keys__head h2, .spk-keys.is-stacked .spk-keys__head h2 { margin-inline:auto; }
html.no-js .spk-keys__index, .spk-keys.is-stacked .spk-keys__index { display:none; }
html.no-js .spk-keys__ground, .spk-keys.is-stacked .spk-keys__ground { order:2; position:static;
  left:auto; top:auto; width: var(--wrap); max-width: 1200px; height:auto; margin-inline:auto;
  transform:none; border-radius:0; overflow:visible; background:none; }
html.no-js .spk-keys__rest, .spk-keys.is-stacked .spk-keys__rest { display:none; }
html.no-js .spk-keys__panels, .spk-keys.is-stacked .spk-keys__panels { position:static;
  display:block; opacity:1; visibility:visible; transition:none; overflow:visible; padding:0; }
html.no-js .spk-keys__panel, .spk-keys.is-stacked .spk-keys__panel { position:relative; inset:auto;
  aspect-ratio: 16 / 9; margin-top: clamp(2rem, 4vw, 3rem); }
html.no-js .spk-keys__panel + .spk-keys__panel,
.spk-keys.is-stacked .spk-keys__panel + .spk-keys__panel { -webkit-mask-image:none; mask-image:none; }
html.no-js .spk-keys__caption, .spk-keys.is-stacked .spk-keys__caption,
html.no-js .spk-keys__panel::after, .spk-keys.is-stacked .spk-keys__panel::after { opacity:1; }
/* No script means no clip and no captions, so neither control is offered. */
html.no-js .spk-keys__hear, html.no-js .spk-keys__cap { display:none; }
/* with no stage to fill, a playing talk fills the viewport */
.spk-keys.is-stacked .spk-keys__video, .spk-keys.is-stacked .spk-keys__play,
.spk-keys.is-stacked .spk-keys__pause { position:fixed; }
@media (max-width: 768px) {
  html.no-js .spk-keys__panel, .spk-keys.is-stacked .spk-keys__panel { aspect-ratio: 4 / 5; }
}

@media (prefers-reduced-motion: reduce) {
  .spk-keys__pause, .spk-keys__cap, .spk-keys__video,
  .spk-keys__index, .spk-keys__panels, .spk-keys__tab, .spk-keys__no { transition:none; }
  .spk-keys.is-stacked.is-playing .spk-keys__head,
  .spk-keys.is-stacked.is-playing .spk-keys__caption { opacity:0; visibility:hidden; transition:none; }
}

/* ---------------------------------------------------------------------
   4. What the room walks out with — no pin. A dark room and five words
   placed across the frame like seats, not a list: three on a front row,
   two on a back row. Each arrives once as a light: the word rises out of
   blur with a soft pool behind it, 380ms after the one before; when the
   fifth has landed the house lights come up on the still (.spk-lights).
   Nothing loops and nothing replays on scroll-back.
   --------------------------------------------------------------------- */
.spk-out { position:relative; overflow:hidden; background: var(--plum); color: var(--tx-inv);
  min-height: 100svh; }
.spk-out__media { position:absolute; inset:0; z-index:0; }
.spk-out__media .spk-lights { --lights-dur: 1.4s; object-position: 50% 45%; }
/* the grade the words sit on: the room is lit, the type still has ground */
.spk-out__media.media--plum::after {
  background: radial-gradient(120% 100% at 50% 55%,
    rgba(14,8,22,.42), rgba(14,8,22,.82) 78%); }

.spk-out__inner { position:relative; z-index:2; height:100svh; width:100%; }
.spk-out__h { position:absolute; z-index:3; left:50%; transform: translateX(-50%);
  top: clamp(5rem, 15vh, 9rem); width: var(--wrap); text-align:center;
  font-size: var(--step-2); font-weight:360; letter-spacing:-0.02em;
  color: var(--tx-inv-soft); text-wrap: balance; }

.spk-out__list { position:absolute; inset:0; margin:0; padding:0; list-style:none; }
/* each word is centred on its seat (--x / --y are set inline per word) */
.spk-out__word { position:absolute; left: var(--x, 50%); top: var(--y, 50%);
  transform: translate(-50%, -50%); white-space:nowrap;
  font-family: var(--f-display); font-weight:340; line-height:1; letter-spacing:-0.025em;
  color: var(--tx-inv); }
.spk-out__word--front { font-size: var(--step-3); }
.spk-out__word--back  { font-size: var(--step-2); }
/* the pool of light behind the word */
.spk-out__word::before { content:""; position:absolute; left:50%; top:50%; z-index:0;
  width:22rem; height:22rem; transform: translate(-50%, -50%); border-radius:50%;
  pointer-events:none;
  background: radial-gradient(closest-side, rgba(169,133,230,.22), transparent 60%);
  opacity:0; transition: opacity .9s var(--ease-out); }
.spk-out__word.is-on::before { opacity:1; }
/* the word itself rises out of blur */
.spk-out__t { position:relative; z-index:1; display:inline-block;
  opacity:0; transform: translateY(14px); filter: blur(8px);
  transition: opacity .6s var(--ease-out), transform .6s var(--ease-out),
              filter .6s var(--ease-out); }
.spk-out__word.is-on .spk-out__t { opacity:1; transform:none; filter: blur(0); }

@media (max-width: 1199px) {
  .spk-out__word--front { font-size: var(--step-2); }
  .spk-out__word--back  { font-size: var(--step-1); }
}
/* Phones: a centred stack, one word per line, same sequence. */
@media (max-width: 640px) {
  .spk-out { min-height:0; }
  .spk-out__inner { height:auto; padding: clamp(4rem,10vw,6rem) 0; }
  .spk-out__h { position:static; transform:none; width: var(--wrap); margin:0 auto;
    text-align:left; }
  .spk-out__list { position:relative; inset:auto; width: var(--wrap);
    margin: clamp(2rem,6vw,3rem) auto 0; }
  .spk-out__word, .spk-out__word--front, .spk-out__word--back { position:relative;
    left:auto; top:auto; transform:none; display:block; white-space:normal;
    padding-block: .35em; font-size: var(--step-2); text-align:left; }
  .spk-out__word::before { left:0; width:16rem; height:16rem; }
}
/* size "xl": the word at 1.6x its layer's size (the pool stays as is) */
.spk-out__word--xl .spk-out__t { font-size: 1.6em; }
/* No heading (the section is a statement, named by its aria-label):
   phones stack the words centred, one per line. */
@media (max-width: 640px) {
  .spk-out[aria-label] .spk-out__list { margin-top:0; }
  .spk-out[aria-label] .spk-out__word { text-align:center; }
  .spk-out[aria-label] .spk-out__word::before { left:50%; }
  .spk-out[aria-label] .spk-out__inner { min-height: 100svh; display:flex; align-items:center; }
}
/* Reduced motion: the five stand there, lit; no sequence, no pools. */
@media (prefers-reduced-motion: reduce) {
  .spk-out__t { opacity:1; transform:none; filter:none; transition:none; }
  .spk-out__word::before { display:none; }
  .spk-out__media .spk-lights { filter: brightness(1) saturate(.92) contrast(1.06); opacity:1; }
}
html.no-js .spk-out__t { opacity:1; transform:none; filter:none; }
html.no-js .spk-out__word::before { display:none; }
/* The hand-off: the section rises 40svh early, over the room's stage while
   Act is still leaving. Its top 40svh is transparent (the heading sits
   there, over the leaving picture); the still and the five words start
   40svh down, so the words' --y percentages keep meaning inside the
   picture. z-index 3 beats the room's 2. */
/* Only when the section follows a room directly (.spk-chap + .spk-out). */
.spk-chap + .spk-out { margin-top: -40svh; background: transparent; z-index:3; pointer-events:none; }  /* nothing here is interactive; the transparent band must not catch clicks meant for the room's tabs beneath it */
.spk-chap + .spk-out .spk-out__media { top: 40svh; }
.spk-chap + .spk-out .spk-out__inner { height: calc(100svh + 40svh); }
.spk-chap + .spk-out .spk-out__list { top: 40svh; height: 100svh; inset: auto 0 0 0; }
/* only over a pinned room: phones, reduced motion and no script stack */
@media (max-width: 640px) {
  .spk-chap + .spk-out { margin-top:0; }
  .spk-chap + .spk-out .spk-out__media { top:0; }
  .spk-chap + .spk-out .spk-out__inner { height:auto; }
  .spk-chap + .spk-out .spk-out__list { top:auto; height:auto; inset:auto; }
}
/* A room in its phone stage (.is-phone, up to 768px) has no pinned last
   frame to rise over: between 641 and 768 the section would still pull up
   40svh with a transparent top, so its picture began 40svh down and the
   room's stage showed through above it. There it sits in the flow and the
   picture covers it edge to edge (641-768 keep the scattered words). */
@media (min-width: 641px) {
  .spk-chap.is-phone + .spk-out { margin-top:0; }
  .spk-chap.is-phone + .spk-out .spk-out__media { top:0; }
  .spk-chap.is-phone + .spk-out .spk-out__inner { height:100svh; }
  .spk-chap.is-phone + .spk-out .spk-out__list { top:0; height:auto; inset:0; }
}
html.no-js .spk-out, html.no-js .spk-chap + .spk-out, .spk-chap.is-static ~ .spk-out { margin-top:0; }
html.no-js .spk-out__media, html.no-js .spk-chap + .spk-out .spk-out__media, .spk-chap.is-static ~ .spk-out .spk-out__media { top:0; }
html.no-js .spk-out__inner, html.no-js .spk-chap + .spk-out .spk-out__inner, .spk-chap.is-static ~ .spk-out .spk-out__inner { height:100svh; }
html.no-js .spk-out__list, html.no-js .spk-chap + .spk-out .spk-out__list, .spk-chap.is-static ~ .spk-out .spk-out__list { inset:0; height:auto; }
@media (max-width: 640px) {
  html.no-js .spk-out__inner, html.no-js .spk-chap + .spk-out .spk-out__inner, .spk-chap.is-static ~ .spk-out .spk-out__inner { height:auto; }
  html.no-js .spk-out__list, html.no-js .spk-chap + .spk-out .spk-out__list, .spk-chap.is-static ~ .spk-out .spk-out__list { inset:auto; }
}

/* ---------------------------------------------------------------------
   5. Formats — the sentence, the heading, then six real rooms in a strip
   the scroll moves sideways. The track is one screen plus the strip's own
   travel (--spk-strip, set by module 9); the stage is sticky inside it and
   the strip slides by --spk-x. Phones, reduced motion and no script: no
   pin, the strip scrolls natively with snap.
   --------------------------------------------------------------------- */
.spk-formats { position:relative; background:transparent; color: var(--tx-inv);
  padding:0; overflow:visible; }
/* + a 30svh hold on the last room, centred, before the pin lets go (also
   absorbs a phone's toolbar changing the viewport height) */
.spk-formats__track { height: calc(130svh + var(--spk-strip, 0px)); }
.spk-formats__stage { position:sticky; top:0; height:100svh; overflow:hidden;
  display:flex; flex-direction:column; justify-content:center; }
.spk-formats__line { width: var(--wrap); margin: 0 auto; text-align:center;
  font-family: var(--f-display); font-weight:340; font-size: var(--step-2);
  line-height:1.12; letter-spacing:-0.02em; max-width:46ch; text-wrap: balance; }
.spk-formats__line em { color: var(--violet-300); }
.spk-formats__h { width: var(--wrap);
  margin: clamp(1rem,2vh,1.6rem) auto clamp(1.6rem, 4vh, 2.6rem);
  text-align:center; font-size: var(--step-2); text-wrap: balance; }
.spk-formats__strip { display:flex; gap: 2vw; padding-inline: 15vw; margin:0;
  list-style:none; width:max-content;
  transform: translateX(calc(-1 * var(--spk-x, 0px))); will-change: transform; }
.spk-formats__room { position:relative; flex: 0 0 70vw; aspect-ratio: 16 / 9;
  max-height: 56svh; overflow:hidden; border-radius: 2px; }
.spk-formats__room img { width:100%; height:100%; object-fit:cover; display:block; }
.spk-formats__room span { position:absolute; left: clamp(1rem, 2.5vw, 2rem); right: clamp(1rem, 2.5vw, 2rem);
  bottom: clamp(1rem, 2.5vw, 2rem); text-wrap: balance; text-shadow: 0 2px 18px rgba(0,0,0,.6); font-family: var(--f-display); font-weight:360;
  font-size: var(--step-1); letter-spacing:-0.02em; color: var(--tx-inv); }
@media (max-width: 640px) {
  .spk-formats__line { font-size: var(--step-1); max-width:24ch; }
}
/* phones: pinned and slid by the scroll as on desktop, with taller cards */
@media (max-width: 768px) {
  .spk-formats__strip { padding-inline: 10vw; gap: 1rem; }
  .spk-formats__room { flex: 0 0 80vw; aspect-ratio: 4 / 5; max-height: 56svh; }
}
@media (prefers-reduced-motion: reduce) {
  .spk-formats__track { height:auto; }
  .spk-formats__stage { position:static; height:auto; overflow:visible;
    padding-block: clamp(4rem,10vw,6rem); }
  .spk-formats__strip { transform:none; overflow-x:auto; scroll-snap-type:x mandatory;
    width:auto; padding-inline: 8vw; gap: 1rem; scrollbar-width:none; }
  .spk-formats__room { flex: 0 0 84vw; scroll-snap-align:center; max-height:none; }
}
/* The formats sentence on its own: a solid plum section, the line large
   and centred */
.spk-avail { position:relative; z-index:1; background: var(--plum); color: var(--tx-inv);
  min-height: 70svh; display:grid; place-items:center; padding: clamp(5rem, 12vh, 9rem) var(--gutter); }
.spk-avail__line { margin:0; text-align:center; font-family: var(--f-display); font-weight:340;
  font-size: var(--step-4); line-height:1.08; letter-spacing:-0.025em; max-width: 22ch; text-wrap: balance; }
.spk-avail__line em { color: var(--violet-300); }
@media (max-width: 768px) { .spk-avail { min-height: 60svh; } .spk-avail__line { font-size: var(--step-3); } }

/* The home talks as a strip (.tstrip, keynotes layout "strip"): the rooms
   strip's pin and slide (module 9.B), one card per talk. The card is its
   picture under a dark foot, and over it the number and tag, the title,
   its line and the CTA; the accent colours the number and a hairline. */
.tstrip { position:relative; background: var(--plum-2); color: var(--tx-inv); }
.tstrip__track { height: calc(130svh + var(--spk-strip, 0px)); }
.tstrip__stage { position:sticky; top:0; height:100svh; overflow:hidden;
  display:flex; flex-direction:column; justify-content:center; }
.tstrip__h { width: var(--wrap); margin: 0 auto clamp(1.6rem, 4vh, 2.6rem);
  text-align:center; font-size: var(--step-3); text-wrap: balance; }
.tstrip__strip { display:flex; gap: 2vw; padding-inline: 15vw; margin:0; list-style:none;
  width:max-content; transform: translateX(calc(-1 * var(--spk-x, 0px))); will-change: transform; }
.tstrip__card { position:relative; flex: 0 0 70vw; aspect-ratio: 16 / 9; max-height: 60svh;
  overflow:hidden; border-radius: 2px; }
.tstrip__link { position:absolute; inset:0; display:block; color:inherit; text-decoration:none; }
.tstrip__link img { width:100%; height:100%; object-fit:cover; display:block;
  transition: transform .9s var(--ease-out); }
.tstrip__link::after { content:""; position:absolute; inset:0; pointer-events:none;
  background: linear-gradient(to top, rgba(14,8,22,.88) 0%, rgba(14,8,22,.45) 38%, rgba(14,8,22,0) 65%); }
.tstrip__link:hover img, .tstrip__link:focus-visible img { transform: scale(1.04); }
.tstrip__link:focus-visible { outline:2px solid var(--violet-300); outline-offset:-4px; }
.tstrip__cap { position:absolute; left: clamp(1.2rem, 3vw, 2.6rem); right: clamp(1.2rem, 3vw, 2.6rem);
  bottom: clamp(1.2rem, 3vw, 2.4rem); z-index:1; display:flex; flex-direction:column; gap:.55rem;
  max-width: 44ch; }
.tstrip__no { display:flex; align-items:center; gap:.9rem; font-family: var(--f-body, inherit);
  font-size: .78rem; letter-spacing:.18em; text-transform:uppercase; color: var(--_acc, var(--violet-300)); }
.tstrip__tag { padding-left:.9rem; border-left:1px solid currentColor; color: var(--tx-inv-soft); }
.tstrip__title { font-family: var(--f-display); font-weight:360; font-size: var(--step-3);
  line-height:1.02; letter-spacing:-0.025em; }
.tstrip__title .tm { font-size:.38em; vertical-align:super; color: var(--tx-inv-faint); }
.tstrip__sub { font-size: var(--step-0); line-height:1.45; color: var(--tx-inv-soft); }
.tstrip__sub strong, .tstrip__sub b { color: var(--tx-inv); font-weight:500; }
.tstrip__cta { display:inline-flex; align-items:center; gap:.5rem; margin-top:.3rem;
  font-size:.82rem; letter-spacing:.14em; text-transform:uppercase; color: var(--tx-inv); }
.tstrip__cta .arrow { width:18px; height:18px; transition: transform .3s var(--ease-out); }
.tstrip__link:hover .tstrip__cta .arrow { transform: translateX(4px); }
@media (max-width: 768px) {
  .tstrip__h { font-size: var(--step-2); }
  .tstrip__strip { padding-inline: 9vw; gap: 1rem; }
  .tstrip__card { flex: 0 0 82vw; aspect-ratio: 4 / 5; max-height: 64svh; }
  .tstrip__title { font-size: var(--step-2); }
  .tstrip__sub { font-size: .92rem; }
}
/* reduced motion and no script: a native snap strip, no pin */
@media (prefers-reduced-motion: reduce) {
  .tstrip__track { height:auto; }
  .tstrip__stage { position:static; height:auto; overflow:visible; padding-block: clamp(4rem,10vw,6rem); }
  .tstrip__strip { transform:none; overflow-x:auto; scroll-snap-type:x mandatory; width:auto;
    padding-inline: 8vw; gap: 1rem; scrollbar-width:none; }
  .tstrip__card { scroll-snap-align:center; }
}
html.no-js .tstrip__track { height:auto; }
html.no-js .tstrip__stage { position:static; height:auto; overflow:visible; padding-block: clamp(4rem,10vw,6rem); }
html.no-js .tstrip__strip { transform:none; overflow-x:auto; scroll-snap-type:x mandatory; width:auto;
  padding-inline: 8vw; gap: 1rem; scrollbar-width:none; }
html.no-js .tstrip__card { scroll-snap-align:center; }
.tstrip__strip::-webkit-scrollbar { display:none; }

/* no script, no scrub: the same native strip */
html.no-js .spk-formats__track { height:auto; }
html.no-js .spk-formats__stage { position:static; height:auto; overflow:visible;
  padding-block: clamp(4rem,10vw,6rem); }
html.no-js .spk-formats__strip { transform:none; overflow-x:auto; scroll-snap-type:x mandatory;
  width:auto; padding-inline: 8vw; gap: 1rem; scrollbar-width:none; }
html.no-js .spk-formats__room { flex: 0 0 84vw; scroll-snap-align:center; max-height:none; }
.spk-formats__strip::-webkit-scrollbar { display:none; }


/* =====================================================================
   SPEAKING PAGE — ROUND 5 SECTIONS
   Spec: 05_Website/Design/SPEAKING-R5-SECTIONS-SPEC.md
   Page order: hero · numbers · A · keynotes · B · turn · C · D · E · footer
   Ground, one tone step between neighbours:
   plum-2 · plum · plum-2 · plum · plum-2 · plum · plum-2 · plum · plum-2.
   Round 6: the turn's pin is gone; see the note at the top of this block.
   ===================================================================== */

/* The two tone swaps the new order needs, and the proof line's own ground.
   Nothing else about those sections changes. */
.spk-proof   { background: transparent; border-top:0; }
.spk-formats { background: transparent; }

/* ---------------------------------------------------------------------
   A. .spk-said — "What he talks about." The candle wheel. The six lines
   ship in the markup, stacked on the velvet, so the section reads with no
   script, under reduced motion and on Save-Data (the script then puts one
   lit candle over each line). With the script and motion the section
   becomes a pinned stage (.is-wheel): a 720svh track, the velvet under a
   plum veil, the wheel on a canvas above them, and the six lines in one
   grid cell, each carrying --on (0..1) from the scroll. The scroll is the
   clock: nothing here has a transition. The ending (three candles rise
   out of the ring, the camera pushes between the left and the middle
   one) is drawn on the canvas; the script also writes --push (0..1) on
   the section, which scales the velvet slightly about --push-ox/-oy.
   --------------------------------------------------------------------- */
.spk-said { position:relative; background: var(--plum-2); color: var(--tx-inv); }
.spk-said__stage { position:relative; overflow:hidden;
  padding-block: clamp(4rem, 9vw, 7rem); }
.spk-said__velvet { position:absolute; inset:0; z-index:0; display:block;
  width:100%; height:100%; object-fit:cover; object-position: 50% 50%; }
.spk-said__veil { position:absolute; inset:0; z-index:1; pointer-events:none;
  background: rgba(26,16,38,.42); }
.spk-said__wheel,
.spk-said__nextA, .spk-said__nextB, .spk-said__glowimg, .spk-said__lineimgs { display:none; }
.spk-said__inner { position:relative; z-index:5; width: var(--wrap); margin-inline:auto;
  text-align:center; }
.spk-said__h { margin:0; font-family: var(--f-display); font-style:italic; font-weight:360;
  font-size: var(--step-0); line-height:1.3; letter-spacing:0;
  color: var(--tx-inv-soft); }

/* Stacked (no script, reduced motion, Save-Data): every line is there. */
.spk-said__lines { display:grid; justify-items:center; row-gap: clamp(2.2rem, 6vh, 3.6rem);
  margin: clamp(1.8rem, 5vh, 3rem) auto 0; }
.spk-said__line { max-width:22ch; margin:0;
  font-family: var(--f-display); font-weight:340; font-size: var(--step-2);
  line-height:1.12; letter-spacing:-0.02em; color: var(--tx-inv); text-wrap: balance; }
.spk-said__no { display:block; margin-bottom:.75rem;
  font-family: var(--f-text); font-size: var(--step--1); font-weight:500; font-style:normal;
  line-height:1; letter-spacing:.12em; font-variant-numeric: tabular-nums lining-nums;
  color: rgba(244,236,222,.62); }
/* the quiet close: not the audience's own experience but what it has
   already cost the organization by the time anyone names it */
.spk-said__bridge { max-width:34ch; font-family: var(--f-text); font-weight:400;
  font-size: var(--step-0); line-height:1.55; letter-spacing:0;
  color: var(--tx-inv-soft); }
/* one lit candle over each line, inserted by the script (never with no-js) */
.spk-said__candle { display:block; width:auto; height:140px; margin: 0 auto 1rem; }
html.no-js .spk-said__candle { display:none; }

/* The wheel: a pinned stage, a 60svh intro, N + 1 beats of 80svh (N
   lines: --beats), a 100svh ending and 60svh over the talks section as it
   rises: 780svh for six lines (--intro, --beats, --beat, --grow: the
   section's inline style). */
.spk-said.is-wheel .spk-said__track { height: calc((var(--intro, 60) + (var(--beats, 6) - 0.5) * var(--beat, 80) + var(--grow, 160) + 160) * 1svh); }
.spk-said.is-wheel .spk-said__stage { position:sticky; top:0; height:100svh; padding:0; }
.spk-said.is-wheel .spk-said__wheel { display:block; position:absolute; inset:0; z-index:2;
  width:100%; height:100%; pointer-events:none; }
/* the push: the velvet follows the camera a little (x1.12 at the end),
   about the point between the left and the middle candle */
.spk-said.is-wheel .spk-said__velvet { transform: scale(calc(1 + 0.12 * var(--push, 0)));
  transform-origin: var(--push-ox, 39%) var(--push-oy, 55%); }
/* the hand-off: the pinned wheel sits over the talks section (z 3 over its
   z 2) with no ground of its own; its velvet and veil fade out as the
   talks rise under it (--spk-keys-reveal, from module 2), so the talks show
   in the gap while the candles stay in front; then the whole stage fades
   out as it slides (--spk-keys-gone, talks u 40-70), before the talks'
   heading rises. No pointer events, so the talks' buttons under it stay
   live. */
.spk-said.is-wheel { z-index:3; background: transparent; pointer-events:none; }
.spk-said.is-wheel .spk-said__stage { pointer-events:none; }
.spk-said.is-wheel .spk-said__velvet,
.spk-said.is-wheel .spk-said__veil { opacity: calc(1 - var(--spk-keys-reveal, 0)); }
/* the candles fade (--spk-keys-gone) well before the velvet has gone
   (--spk-keys-reveal), so the talks' picture comes up slowly through it */
.spk-said.is-wheel .spk-said__wheel { opacity: calc(1 - var(--spk-keys-gone, 0)); }
/* phones: no pinned talks take the wheel over, so it hands off by itself
   (module 7): the candle's bottom always fades into the velvet (in the
   canvas, no CSS mask, a still band); the grow is over 250svh before
   the track ends and the talks reel's first card (plain plum and its
   heading, stacked ABOVE the stage: keys z 4 over said z 3) scrolls up
   over the still candle; the stage is held for the track's last 100svh,
   then scrolls away under the reel. The track has no hold beat, a long
   grow (--grow-phone) and the hold's 100svh: 1072svh for six lines. */
@media (max-width: 768px) {
  .spk-said.is-wheel .spk-said__track { height: calc((var(--intro, 60) + (var(--beats, 6) - 0.6) * var(--beat, 80) + var(--grow-phone, 480) + 100) * 1svh); }
  .spk-keys.is-reel { z-index:4; }
  /* the reel pulled up 150svh: its first card enters as the grow ends
     (U - 250) and scrolls up over the still candle */
  .spk-said.is-wheel + .spk-keys.is-reel { margin-top: -150svh; }
  .spk-keys.is-reel .spk-keys__ground > .pic,
  .spk-keys.is-reel .spk-keys__rest { display:none; }
  /* card 0: plain plum, its top fading in (clear -> plum-2 over its first
     18%) so it rises over the candle's faded bottom with no edge; the
     heading at 30% of the card, on screen when the card is ~70% up */
  /* card 0 is short (48svh) and solid near-black, its top edge fading in
     over the first 22% so it rises over the candle's faded bottom with no
     edge; the heading sits in the solid part */
  .spk-keys.is-reel .spk-keys__head { height: 48svh; place-items: center; padding-top: 10svh;
    background: linear-gradient(to bottom, rgba(6,4,9,0) 0%, #060409 22%); }
}
/* The ending's two lines (visual only; the real heading is in the talks
   section), one roll through one window. Two windows with identical
   geometry sit at the same spot (centred, top 30%, two rows of the big
   type tall, overflow hidden): one under the canvas (z 1) holding A,
   "Three talks.", one over the canvas (z 4)
   holding B, "for people, teams / and organizations.". A comes up on the
   window's lower row over g 0-0.2 while the candle rests (--na: opacity
   and a 16px rise); then over g 0.2-0.5 (--roll), as the three candles
   start to rise, A rolls up and out
   through the window's top while B rolls up into it from below: one
   roll, no fade, no size change. The windows only hold text; they never
   clip the candle. Both leave with the talks section's reveal. */
.spk-said__win { display:none; }
.spk-said.is-wheel .spk-said__win { display:block; position:absolute; left:50%; top:30%;
  transform: translateX(-50%); width: calc(100% - 2 * var(--gutter));
  font-size: clamp(3.4rem, 6.6vw, 7.4rem); height: 2.08em;
  overflow:hidden; clip-path: inset(0); pointer-events:none; }
/* A alone, high: one row from 6% down, above the resting candle's flame,
   so the lifting row of three covers it */
.spk-said.is-wheel .spk-said__win--a { z-index:1; }
/* the key word of each ending line in the italic face */
.spk-said__cur { font-style: italic; font-weight: 400; letter-spacing: -0.02em; }
.spk-said.is-wheel .spk-said__win--b { z-index:4; }
.spk-said.is-wheel .spk-said__nextA,
.spk-said.is-wheel .spk-said__nextB {
  display:block; margin:0 auto; pointer-events:none;
  font-family: var(--f-display); font-optical-sizing: auto; color: var(--tx-inv);
  font-size: 1em; font-weight:340; line-height: 1.0; letter-spacing: -0.035em;
  text-align:center; text-wrap: balance; }
/* A sits on the window's lower row (a one-line padding above it) */
.spk-said.is-wheel .spk-said__nextA { padding-top: 0.1em;
  transform: translateY(calc((1 - var(--na, 0)) * 16px + var(--roll, 0) * -100%));
  opacity: calc(var(--na, 0) * (1 - min(1, var(--spk-keys-reveal, 0) * 2.5))); }
.spk-said.is-wheel .spk-said__nextA { max-width: 15ch; }
.spk-said.is-wheel .spk-said__nextB { text-shadow: 0 2px 28px rgba(0,0,0,.7), 0 0 60px rgba(20,10,28,.6); }
.spk-said.is-wheel .spk-said__nextB { max-width: 15ch; min-height: 2.08em;
  transform: translateY(calc((1 - var(--roll, 0)) * 100%));
  opacity: calc(1 - min(1, var(--spk-keys-reveal, 0) * 2.5)); }
/* desktop: both windows high (11%) and two rows tall at a size that fits
   ("You don't need / more resilience."), above the row's flames (31%) */
@media (min-width: 769px) {
  .spk-said.is-wheel .spk-said__win { top:11%; font-size: clamp(2.6rem, 4.4vw, 5rem); height: auto;
    overflow:visible; clip-path:none; }
  .spk-said.is-wheel .spk-said__nextA { padding-top: 0;
    transform: translateY(calc((1 - var(--na, 0)) * 16px - var(--nao, 0) * 16px));
    opacity: calc(var(--na, 0) * (1 - var(--nao, 0))); }
  .spk-said.is-wheel .spk-said__win--b { top:40%; }
  .spk-said.is-wheel .spk-said__nextB { min-height:0;
    transform: translateY(calc((1 - var(--nb, 0)) * 16px));
    opacity: calc(var(--nb, 0) * (1 - min(1, var(--spk-keys-reveal, 0) * 2.5))); }
}

/* Phones: smaller type in the same two-row window, high on the screen
   (top 9%): the one candle grows under it until its wax fills the frame,
   so B carries a shadow over the wax. B is two rows at 13ch (at 11ch
   "and organizations." breaks to a third row the window cuts off); it is as tall as
   the window, so before the roll it waits wholly below it; A keeps its
   one-row padding. */
@media (max-width: 768px) {
  .spk-said.is-wheel .spk-said__win { top:9%; font-size: clamp(2.1rem, 9vw, 3.2rem); line-height: 1.0; height: 3.2em; }
  .spk-said.is-wheel .spk-said__nextB { max-width: 12ch; min-height: 3.2em;
    text-shadow: 0 2px 20px rgba(0,0,0,.6); }
  /* A (top 33%, behind the canvas: the growing candle rises up behind
     it) and B low (its two-row window from 66% down, in front, pinned to
     the end: it leaves with the stage): no shared window, so no roll. A
     comes up (--na, g 0-0.06), stays to g 0.38, and leaves rising 16px
     (--nao, g 0.38-0.48); B comes in rising 16px (--nb, g 0.44-0.56) and leaves over U - 250 -> U - 215
     (--spk-said-bout) */
  .spk-said.is-wheel .spk-said__win--a { top:10%; font-size: clamp(2.2rem, 9.4vw, 3.4rem); height: 3.2em; }
  .spk-said.is-wheel .spk-said__nextA { padding-top: 0; max-width: 12ch; }
  /* one lit picture per line: between the line (which ends near 30%) and
     the flame (46% at rest), behind the canvas, feathered on every edge;
     each follows its line's --on (written by the script on the image) */
  .spk-said.is-wheel .spk-said__lineimgs { display:block; position:absolute; inset:0; z-index:1; pointer-events:none; }
  .spk-said.is-wheel .spk-said__lineimg { position:absolute; left:50%; top:27%; width: 94vw; height: 26svh;
    transform: translateX(-50%) translateY(calc((1 - var(--on, 0)) * 10px)); object-fit: cover;
    -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.85) 35%, transparent 72%);
            mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.85) 35%, transparent 72%);
    filter: brightness(1.05) saturate(1.05); opacity: calc(var(--on, 0) * .95); }
  /* the picture the candle lights: sits between "Three talks." and the
     flame, behind the canvas, its edges feathered to nothing so only the
     middle reads, lit; it comes and goes with line A (--na / --nao) */
  .spk-said.is-wheel .spk-said__glowimg { display:block; position:absolute; left:50%; top:25%; z-index:1;
    width: 94vw; height: 26svh; transform: translateX(-50%); object-fit: cover; pointer-events:none;
    -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.85) 35%, transparent 72%);
            mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.85) 35%, transparent 72%);
    filter: brightness(1.05) saturate(1.05);
    opacity: calc(var(--glow-na, 0) * (1 - var(--glow-nao, 0)) * .95); }
  .spk-said.is-wheel .spk-said__win--b { top:66%; }
  .spk-said.is-wheel .spk-said__nextA {
    transform: translateY(calc((1 - var(--na, 0)) * 16px - var(--nao, 0) * 16px));
    opacity: calc(var(--na, 0) * (1 - var(--nao, 0))); }
  .spk-said.is-wheel .spk-said__nextB {
    transform: translateY(calc((1 - var(--nb, 0)) * 16px));
    opacity: calc(var(--nb, 0) * (1 - var(--spk-said-bout, 0))); }
  /* the layering as on desktop: A behind the canvas (z 1; the growing
     candle passes over it), B pinned in front of it (z 4) */
  .spk-said.is-wheel .spk-said__nextA { text-shadow: 0 2px 20px rgba(0,0,0,.6); }
}
/* Desktop: each line's picture, lit by the flame: a wide window from
   behind the line (on one row at 11%) down behind the candle, its edges
   feathered into the velvet; behind the canvas, following its line (--on).
   The line itself stays on one row over it, with a soft shadow. */
@media (min-width: 769px) {
  .spk-said.is-wheel .spk-said__lineimgs { display:block; position:absolute; inset:0; z-index:1; pointer-events:none; }
  .spk-said.is-wheel .spk-said__lineimg { position:absolute; left:50%; top:4%; width: 100vw; height: 76svh;
    transform: translateX(-50%) translateY(calc((1 - var(--on, 0)) * 10px)); object-fit: cover; object-position: 50% 42%;
    -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 52%, #000 0%, rgba(0,0,0,.85) 40%, transparent 76%);
            mask-image: radial-gradient(ellipse 50% 50% at 50% 52%, #000 0%, rgba(0,0,0,.85) 40%, transparent 76%);
    filter: brightness(1.05) saturate(1.05) sepia(.12); opacity: calc(var(--on, 0) * .95); }
  .spk-said.is-wheel .spk-said__lines .spk-said__line:not(.spk-said__bridge) { max-width:none; white-space:nowrap;
    font-size: min(var(--step-2), 2.3vw); }
  .spk-said.is-wheel .spk-said__lines .spk-said__bridge { max-width:none; white-space:nowrap; font-size: min(var(--step-0), 1.55vw); }
  .spk-said.is-wheel .spk-said__line { text-shadow: 0 1px 18px rgba(18,8,26,.85), 0 0 4px rgba(18,8,26,.6); }
  .spk-said.is-wheel .spk-said__lines { grid-template-columns: 100%; }
  .spk-said.is-wheel .spk-said__line { justify-self:center; width:max-content; }
}
.spk-said.is-wheel .spk-said__inner { position:absolute; inset:0; width:auto; margin:0; }
.spk-said.is-wheel .spk-said__h { position:absolute; left:50%; top:12%;
  transform: translateX(-50%); white-space:nowrap; opacity: var(--on, 1); }
/* The lines: centred above the top candle's flame on every beat, the
   bridge included (it keeps its own typography). */
.spk-said.is-wheel .spk-said__lines { position:absolute; left:50%; top:11%; margin:0;
  width: calc(100% - 32px); transform: translate(-50%, 0);
  justify-items:center; text-align:center; row-gap:0; }
.spk-said.is-wheel .spk-said__line { grid-area: 1 / 1; opacity: var(--on, 0);
  transform: translateY(calc((1 - var(--on, 0)) * 12px));
  filter: blur(calc((1 - var(--on, 0)) * 6px)); }
.spk-said.is-wheel .spk-said__line:not(.spk-said__bridge) { max-width:30ch; }
/* Phones: the same wheel and the same rule; the flame sits higher. */
@media (max-width: 768px) {
  .spk-said.is-wheel .spk-said__lines { top:16%; }
  .spk-said.is-wheel .spk-said__h { white-space:normal; width: calc(100% - 32px); text-align:center; }
}

/* ---------------------------------------------------------------------
   B. .spk-chap — "What it's like in the room." The page's one pin, seven
   beats: the heading alone, then for each chapter (Think · Feel · Act)
   its word, then its line. One thing is on screen at a time; each beat
   arrives and leaves on the same time-based fade (the script swaps
   classes when the scroll crosses a beat, the transitions are the clock).
   Each chapter has its own still, shown at full brightness: no grade, no
   dimming. The stills crossfade at each change of chapter and push in
   slowly (--dolly) across that chapter's two beats. The rail on the left
   spans most of the stage and carries the homepage dot between three
   stops. Phones (.is-phone), reduced motion and Save-Data (.is-static)
   and no script get no pin: three stacked blocks.
   --------------------------------------------------------------------- */
.spk-chap { position:relative; background: var(--plum-2); color: var(--tx-inv); }
/* the curtain: the room rises over the pinned talks stage for its last
   50svh (the spine gave every section z-index 1, so 2 wins) */
.spk-chap { z-index:2; }
.spk-keys + .spk-chap { margin-top: -50svh; }
/* only over a pinned stage: phones, reduced motion and no script have none */
html.no-js .spk-chap, .spk-keys.is-stacked ~ .spk-chap { margin-top:0; }
@media (max-width: 768px) { .spk-chap, .spk-keys + .spk-chap { margin-top:0; } }
/* the turn's geometry: 1 + 2N beats (N chapters: --chapters) of 70vh
   (--beat) plus a tail; the script writes nothing to it */
.spk-chap__track { height: calc((1 + 2 * var(--chapters, 3)) * var(--beat, 70) * 1vh + 60vh); }
.spk-chap__stage { position:sticky; top:0; height:100svh; overflow:hidden; }

.spk-chap__media { position:absolute; inset:0; z-index:0; background: var(--plum-2); }
/* The dolly: --dolly (1 → 1.06) is written per frame on the current
   chapter's still, so there is no transition on the transform; the still
   that is leaving keeps its last value. */
.spk-chap__still { position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; object-position: 50% 40%; opacity:0;
  transform: scale(var(--dolly, 1)); transform-origin: 50% 40%;
  transition: opacity .9s var(--ease-amb); will-change: opacity, transform; }
.spk-chap__still.is-on { opacity:1; }
/* the block's optional veil (settings.veil, 0–0.8 → --chap-veil): one
   overlay over the stills, under the glow, the words and the rail */
.spk-chap__media::after { content:""; position:absolute; inset:0; z-index:3; pointer-events:none;
  background: rgba(26,16,38, var(--chap-veil, 0)); }
/* Light that belongs to the dot, carried on --px / --py (the homepage
   .thread__glow, slightly smaller) */
.spk-chap__glow { position:absolute; inset:0; z-index:1; pointer-events:none;
  background: radial-gradient(26rem circle at var(--px, 0px) var(--py, 50%),
    rgba(169,133,230,.20), rgba(169,133,230,.05) 40%, transparent 68%); }

.spk-chap__inner { position:absolute; inset:0; z-index:2; width: var(--wrap); margin-inline:auto; }
/* the heading is the first beat: it leaves on the same fade as the rest */
.spk-chap__h { position:absolute; left:0; right:0; top: clamp(5rem, 15vh, 9rem);
  text-align:center; font-size: var(--step-2); font-weight:360; letter-spacing:-0.02em;
  color: var(--tx-inv-soft); text-wrap: balance;
  opacity: 1; transition: opacity .32s var(--ease-amb), transform .32s var(--ease-amb),
    filter .32s var(--ease-amb); }
.spk-chap__h.is-gone { opacity:0; transform: translateY(-10px); filter: blur(6px); }

/* The rail: a guide line, a violet fill down to the dot, the dot, and the
   three chapter words each on its own stop (top, middle, bottom). --dot
   (0 → 1) is written by the script on the rail. */
.spk-chap__rail { position:absolute; left:0; top:18svh; bottom:10svh; height:auto;
  transform:none; z-index:1; width:1px; }
.spk-chap__line { position:absolute; left:0; top:0; bottom:0; width:1px;
  background: rgba(245,240,231,.14); }
.spk-chap__fill { position:absolute; left:0; top:0; width:1px;
  height: calc(var(--dot, 0) * 100%); background: var(--violet-300); }
/* the homepage .thread .pulse, reused */
.spk-chap__dot { position:absolute; left:0; top: calc(var(--dot, 0) * 100%); z-index:1;
  width:12px; height:12px; border-radius:50%; transform: translate(-50%, -50%);
  background: var(--violet-300);
  box-shadow: 0 0 18px 6px rgba(169,133,230,.55), 0 0 48px 16px rgba(169,133,230,.18); }
/* the .spk-keys__tab typography; .62 is the contrast floor, keep it */
.spk-chap__tab { position:absolute; left:0; top: calc(var(--i) / max(1, var(--chapters, 3) - 1) * 100%); transform: translateY(-50%);
  display:flex; align-items:center; gap:.9rem; padding:.3rem .5rem .3rem 0; white-space:nowrap;
  font-family: var(--f-display); font-size: var(--step-1); font-weight:360;
  letter-spacing:-0.02em; line-height:1.06;
  color: rgba(244,236,222,.62);
  transition: color var(--dur-fast) var(--ease-out); cursor:pointer; }
.spk-chap__tab.is-on { color: var(--tx-inv); }
.spk-chap__tab.is-on[data-tone="violet"] { color: var(--violet-300); }
.spk-chap__tab.is-on[data-tone="bone"] { color: var(--tx-inv); }
.spk-chap__tab:focus-visible { outline:2px solid var(--violet-300); outline-offset:4px; }
/* the stop sits centred on the line (hence the -6px); it is lit once the
   dot has reached it */
.spk-chap__stop { display:block; width:12px; height:12px; border-radius:50%; margin-left:-6px;
  border:1.5px solid rgba(169,133,230,.35); background: var(--plum-2);
  transition: border-color .5s var(--ease-out); }
.spk-chap__tab.is-lit .spk-chap__stop { border-color: var(--violet-300); }

/* The chapters are placed blocks, each on the quiet part of its still:
   upper-left (Think, Act: Act's still is bright at the bottom) or
   lower-right (Feel). The block itself never fades; its word and its line
   share one grid cell and take turns. The block is set at the line's size
   so 26ch measures the line. */
.spk-chap__chapters { position:absolute; inset:0; }
.spk-chap__chapter { position:absolute; max-width: 26ch; padding:0; font-size: var(--step-2);
  opacity:1; visibility:visible; transform:none; filter:none;
  display:grid; min-height:1em; }
.spk-chap__chapter[data-spot="ul"] { left: clamp(4rem, 8vw, 7rem); top: 27svh; text-align:left; }
.spk-chap__chapter[data-spot="lr"] { right: clamp(1rem, 4vw, 3rem); bottom: 14svh; text-align:right; }
/* centred on the still (spot "c"): the word, then its line, in the same
   place, over a soft shadow */
html:not(.no-js) .spk-chap:not(.is-static):not(.is-phone) .spk-chap__chapter[data-spot="c"] {
  left:50%; top:50%; transform: translate(-50%, -50%); width: min(26ch, 100%); text-align:center; }
.spk-chap__chapter[data-spot="c"] .spk-chap__word,
.spk-chap__chapter[data-spot="c"] .spk-chap__text { align-self:center; text-wrap: balance;
  text-shadow: 0 2px 28px rgba(0,0,0,.6), 0 0 60px rgba(20,10,28,.45); }
.spk-chap__chapter:focus-visible { outline:2px solid var(--violet-300); outline-offset:6px; }
/* phones only */
.spk-chap__frame { display:none; }

/* Turn mode (.spk-chap--turn, set by the script when a chapter has a
   second line and picture): the word is the chapter's title, in its own
   row on top, and stays across both beats; the first line and the turn
   line share the row under it and take turns, while the picture under
   them crossfades from the first still to the turn still. Everything
   centred. Stacked modes (reduced motion, no script) show both lines. */
html:not(.no-js) .spk-chap--turn:not(.is-static):not(.is-phone) .spk-chap__chapter {
  justify-items:center; row-gap: clamp(1rem, 3.2vh, 2.2rem); }
html:not(.no-js) .spk-chap--turn:not(.is-static):not(.is-phone) .spk-chap__word { grid-area:1/1; }
html:not(.no-js) .spk-chap--turn:not(.is-static):not(.is-phone) .spk-chap__text { grid-area:2/1; }
.spk-chap--turn .spk-chap__word { letter-spacing: .01em; }

/* One fade recipe for every beat element: hidden at rest, in, leaving. */
.spk-chap__word, .spk-chap__text { grid-area:1/1; opacity:0; transform: translateY(12px);
  filter: blur(8px); visibility:hidden;
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out),
    filter .7s var(--ease-out), visibility 0s linear .7s; }
.spk-chap__word.is-in, .spk-chap__text.is-in { opacity:1; transform:none; filter:none;
  visibility:visible;
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out),
    filter .7s var(--ease-out), visibility 0s; }
.spk-chap__word.is-leaving, .spk-chap__text.is-leaving { opacity:0; transform: translateY(-10px);
  filter: blur(6px); visibility:visible;
  transition: opacity .32s var(--ease-amb), transform .32s var(--ease-amb),
    filter .32s var(--ease-amb); }
.spk-chap__chapter[data-spot="ul"] .spk-chap__word,
.spk-chap__chapter[data-spot="ul"] .spk-chap__text { align-self:start; }
.spk-chap__chapter[data-spot="lr"] .spk-chap__word,
.spk-chap__chapter[data-spot="lr"] .spk-chap__text { align-self:end; }

.spk-chap__word { font-family: var(--f-display); font-style: italic; font-weight: 400;
  font-size: var(--step-4); line-height: .95; letter-spacing: -0.02em; margin:0; }
.spk-chap__chapter[data-tone="violet"] .spk-chap__word { color: var(--violet-300); }
.spk-chap__chapter[data-tone="bone"] .spk-chap__word { color: var(--tx-inv); }
.spk-chap__text { margin:0; font-family: var(--f-display); font-style: normal; font-weight: 340;
  font-size: var(--step-2); line-height: 1.22; letter-spacing: -0.015em;
  color: var(--tx-inv); text-wrap: balance; }
.spk-chap__key { font-style: italic; font-weight: 400; color: var(--violet-300); }

@media (max-width: 1199px) {
  .spk-chap__chapter { font-size: var(--step-1); }
  .spk-chap__word { font-size: var(--step-3); }
  .spk-chap__text { font-size: var(--step-1); }
}

/* Stacked, no pin: reduced motion and Save-Data (.is-static) and no
   script. (Phones, .is-phone, have their own pinned stage: see below.) */
.spk-chap.is-static .spk-chap__track,
html.no-js .spk-chap__track { height:auto; }
.spk-chap.is-static .spk-chap__stage,
html.no-js .spk-chap__stage { position:static; height:auto; overflow:visible; }
.spk-chap.is-static .spk-chap__glow,
html.no-js .spk-chap__glow { display:none; }
.spk-chap.is-static .spk-chap__inner,
html.no-js .spk-chap__inner { position:static; width: var(--wrap); margin-inline:auto;
  padding: clamp(3.5rem, 9vw, 5rem) 0; }
.spk-chap.is-static .spk-chap__h,
html.no-js .spk-chap__h { position:static; text-align:left; }
.spk-chap.is-static .spk-chap__chapters,
html.no-js .spk-chap__chapters { position:static; display:block; text-align:left;
  margin-top: clamp(1.6rem, 4vh, 2.6rem); padding-left:3rem; }
.spk-chap.is-static .spk-chap__chapter,
html.no-js .spk-chap__chapter { position:relative; display:block; left:auto; right:auto; top:auto;
  bottom:auto; text-align:left; max-width:none; min-height:0; padding:0; font-size:inherit;
  opacity:1; visibility:visible; transform:none; filter:none; }
.spk-chap.is-static .spk-chap__chapter + .spk-chap__chapter,
html.no-js .spk-chap__chapter + .spk-chap__chapter { margin-top: clamp(2.2rem, 7vw, 3.2rem); }
.spk-chap.is-static .spk-chap__word,
html.no-js .spk-chap__word { font-size: var(--step-2); }
.spk-chap.is-static .spk-chap__word, .spk-chap.is-static .spk-chap__text,
html.no-js .spk-chap__word, html.no-js .spk-chap__text { opacity:1; transform:none; filter:none;
  visibility:visible; transition:none; }
.spk-chap.is-static .spk-chap__text,
html.no-js .spk-chap__text { position:static; margin-top: clamp(.9rem, 2vh, 1.4rem); }

/* Phones (.is-phone, <= 768px, js module 8): a pinned full-screen stage,
   one beat of --beat-phone svh (100) per chapter. The still fills the
   screen (the portrait crop from the <picture>), under the block's veil;
   the word and its line are centred and large. The scroll is the clock:
   the script writes --o on each still (the crossfade), --in / --out on
   each word and line (the desktop's arrive and leave looks, scrubbed:
   opacity, a 12px rise, an 8px blur in; a 10px lift, a 6px blur out) and
   --hout on the heading. The rail is hidden; the dots at the bottom are
   the tablist, the current one long. */
.spk-chap.is-phone .spk-chap__track { height: calc(var(--chapters, 3) * var(--beat-phone, 100) * 1svh + 100svh); }
.spk-chap.is-phone .spk-chap__still { opacity: var(--o, 0); transition:none; }
.spk-chap.is-phone .spk-chap__glow { display:none; }
.spk-chap.is-phone .spk-chap__h { opacity: calc(1 - var(--hout, 0));
  transform: translateY(calc(var(--hout, 0) * -10px)); filter: blur(calc(var(--hout, 0) * 6px));
  transition:none; padding-inline: var(--gutter); text-shadow: 0 2px 24px rgba(0,0,0,.55); }
.spk-chap.is-phone .spk-chap__inner { width:auto; }
.spk-chap.is-phone .spk-chap__chapter { position:absolute; inset:0; max-width:none; min-height:0;
  padding: 0 var(--gutter) 4.5rem; display:flex; flex-direction:column; align-items:center;
  justify-content:center; text-align:center; visibility:hidden; }
.spk-chap.is-phone .spk-chap__chapter.is-live { visibility:visible; }
.spk-chap.is-phone .spk-chap__word,
.spk-chap.is-phone .spk-chap__text { visibility:inherit; align-self:auto;
  opacity: calc(var(--in, 0) * (1 - var(--out, 0)));
  translate: 0 calc((1 - var(--in, 0)) * 12px - var(--out, 0) * 10px);
  filter: blur(calc((1 - var(--in, 0)) * 8px + var(--out, 0) * 6px));
  transform:none; transition:none; text-shadow: 0 2px 24px rgba(0,0,0,.55); }
.spk-chap.is-phone .spk-chap__word { font-size: var(--step-5); }
.spk-chap.is-phone .spk-chap__text { margin-top: clamp(.9rem, 2.4vh, 1.4rem); max-width: 22ch;
  font-size: var(--step-1); }
.spk-chap.is-phone .spk-chap__chapter:focus-visible { outline-offset:-6px; }
/* turn mode on phones: the title on top, the two lines in one cell under it */
.spk-chap--turn.is-phone .spk-chap__chapter { display:grid; align-content:center; justify-items:center; }
.spk-chap--turn.is-phone .spk-chap__word { grid-area:1/1; }
.spk-chap--turn.is-phone .spk-chap__text { grid-area:2/1; }
/* the dots: one per chapter, the current one long; each is a 44px target */
.spk-chap__dots { position:absolute; left:0; right:0; bottom: max(1.2rem, env(safe-area-inset-bottom)); z-index:4;
  display:flex; justify-content:center; gap:0; }
.spk-chap__pdot { position:relative; width:44px; height:44px; padding:0; border:0; background:none; cursor:pointer; }
.spk-chap__pdot::before { content:""; position:absolute; left:50%; top:50%; width:8px; height:8px;
  border-radius:4px; transform: translate(-50%, -50%); background: rgba(244,236,222,.45);
  transition: width .32s var(--ease-out), background-color .32s var(--ease-out); }
.spk-chap__pdot[aria-selected="true"]::before { width:26px; background: var(--tx-inv); }
.spk-chap__pdot:focus-visible { outline:2px solid var(--violet-300); outline-offset:-8px; border-radius:22px; }

/* Reduced motion, Save-Data and no script: the Think still is shown once,
   at the top, as a lit 16:9 band; no rail, no frames, every chapter open. */
.spk-chap.is-static .spk-chap__media,
html.no-js .spk-chap .spk-chap__media { display:block; position:relative; inset:auto;
  aspect-ratio: 16 / 9; width: var(--wrap); margin-inline:auto; }
.spk-chap.is-static .spk-chap__still,
html.no-js .spk-chap .spk-chap__still { position:absolute; transform:none; transition:none; }
.spk-chap.is-static .spk-chap__still.is-on,
html.no-js .spk-chap .spk-chap__still.is-on { opacity:1; }
.spk-chap.is-static .spk-chap__rail, html.no-js .spk-chap__rail,
.spk-chap.is-static .spk-chap__frame, html.no-js .spk-chap__frame { display:none; }
.spk-chap.is-static .spk-chap__chapters,
html.no-js .spk-chap__chapters { padding-left:0; }

/* Strike mode (.spk-chap--strike, said-vs-meant pairs). Pinned: the word
   and its line get a row each; when the line arrives the word stays, rises
   0.6em and shrinks to 0.72 (from its outer bottom corner), dims so the
   violet strike reads over violet type, and a line draws through it from
   the left (--strike-ms, 420ms). The line pulls up into the room the word
   left. Stacked modes (phones, reduced motion, no script): the strike is
   simply drawn. */
.spk-chap--strike .spk-chap__word { position:relative; justify-self:start; }
.spk-chap--strike .spk-chap__chapter[data-spot="lr"] .spk-chap__word { justify-self:end; }
.spk-chap--strike .spk-chap__word::after { content:""; position:absolute; left:-.04em; right:-.04em;
  top:54%; height: max(2px, .05em); background: var(--violet-300); border-radius:1px;
  transform: scaleX(0); transform-origin: 0 50%; pointer-events:none; }
html.js .spk-chap--strike:not(.is-phone):not(.is-static) .spk-chap__word { grid-area:1/1;
  transform-origin: 0 100%; }
html.js .spk-chap--strike:not(.is-phone):not(.is-static) .spk-chap__chapter[data-spot="lr"] .spk-chap__word { transform-origin: 100% 100%; }
html.js .spk-chap--strike:not(.is-phone):not(.is-static) .spk-chap__text { grid-area:2/1;
  margin-top: calc(-.6 * var(--step-4) + .35em); }
.spk-chap--strike .spk-chap__word.is-in.is-struck,
.spk-chap--strike .spk-chap__word.is-leaving.is-struck { transform: translateY(-.6em) scale(.72);
  color: rgba(244,236,222,.62); }
.spk-chap--strike .spk-chap__word.is-in.is-struck {
  transition: opacity .7s var(--ease-out), transform var(--strike-ms, 420ms) var(--ease-out),
    color var(--strike-ms, 420ms) var(--ease-out), filter .7s var(--ease-out), visibility 0s; }
.spk-chap--strike .spk-chap__word.is-leaving.is-struck { transform: translateY(calc(-.6em - 10px)) scale(.72); }
.spk-chap--strike .spk-chap__word.is-struck::after { transform: scaleX(1);
  transition: transform var(--strike-ms, 420ms) var(--ease-out); }
.spk-chap--strike.is-static .spk-chap__word::after,
html.no-js .spk-chap--strike .spk-chap__word::after { transform: scaleX(1); }
.spk-chap--strike.is-static .spk-chap__word,
html.no-js .spk-chap--strike .spk-chap__word { display:inline-block; color: rgba(244,236,222,.62); }
/* Phones' stage: the quote large and centred; at 55% of its beat the line
   draws through it (--strike-ms) as it dims and rises from its bottom
   centre, and the real line arrives beneath it. */
.spk-chap--strike.is-phone .spk-chap__word { display:inline-block; font-size: var(--step-4); max-width: 9ch; line-height:1.05;
  transform-origin: 50% 100%;
  transition: transform var(--strike-ms, 420ms) var(--ease-out), color var(--strike-ms, 420ms) var(--ease-out); }
.spk-chap--strike.is-phone .spk-chap__word.is-struck { transform: translateY(-.6em) scale(.72);
  color: rgba(244,236,222,.62); }
.spk-chap--strike.is-phone .spk-chap__word::after { transition: transform var(--strike-ms, 420ms) var(--ease-out); }
.spk-chap--strike.is-phone .spk-chap__word.is-struck::after { transform: scaleX(1); }
.spk-chap--strike.is-phone .spk-chap__text { margin-top: calc(-.2 * var(--step-3)); }
@media (max-width: 1199px) {
  html.js .spk-chap--strike:not(.is-phone):not(.is-static) .spk-chap__text {
    margin-top: calc(-.6 * var(--step-3) + .35em); }
}

/* ---------------------------------------------------------------------
   C. .spk-formats — now the rooms strip; its rules live in block 5.
   --------------------------------------------------------------------- */

/* ---------------------------------------------------------------------
   D. .spk-bio — the diptych. The suit portrait, sticky on the left, and
   on the right the smallest true bio (one sentence, one link) followed
   by "For planners." and its blocks, left-aligned. The portrait stays on
   screen while the right column scrolls past it and drifts slightly
   upward across the section (module 6 scrubs --spk-bio-drift off the spine).
   --------------------------------------------------------------------- */
.spk-bio { background:transparent; color: var(--tx-inv);
  padding-block: clamp(5rem, 9vw, 9rem); min-height:auto; display:block; }
.spk-bio__grid { width: var(--wrap); margin-inline:auto; display:grid;
  grid-template-columns: 5fr 7fr; column-gap: clamp(2.5rem, 6vw, 6rem);
  align-items:start; }
.spk-bio__left { position:sticky; top: 10svh; align-self:start; }
/* soft-edged, so the portrait sits in the ground instead of on it */
.spk-bio__portrait { width:100%; max-width: 38vw; aspect-ratio: 4 / 5; height:auto;
  transform: translateY(var(--spk-bio-drift, 0px)); will-change: transform;
  -webkit-mask-image: radial-gradient(closest-side, #000 54%, rgba(0,0,0,.55) 82%, rgba(0,0,0,0) 100%);
          mask-image: radial-gradient(closest-side, #000 54%, rgba(0,0,0,.55) 82%, rgba(0,0,0,0) 100%); }
.spk-bio__portrait img { width:100%; height:100%; object-fit:cover; object-position: 50% 18%; }
/* the photo as it is: no grade, no lights, no soft-edge mask, no plum
   overlay; a plain photo with slightly rounded corners */
.spk-bio .media .spk-bio__img { filter:none; object-position: 55% 30%; }
.spk-bio .spk-bio__portrait { -webkit-mask-image:none; mask-image:none; border-radius: 4px; overflow:hidden; }
.spk-bio .spk-bio__portrait.media--plum::after { display:none; }
.spk-bio .media .spk-lights { --lights-dur: 1.3s;
  filter: brightness(.26) saturate(.45) contrast(1.04); }
.spk-bio .media .spk-lights.is-lit { filter: brightness(.74) saturate(.78) contrast(1.06); }
.spk-bio__right { max-width: 62ch; }
.spk-bio__line { font-family: var(--f-display); font-weight:360; font-size: var(--step-1);
  line-height:1.3; letter-spacing:-0.015em; color: var(--tx-inv); text-wrap: balance; }
.spk-bio__link { margin-top: 1.4rem; color: var(--tx-inv); }
.spk-plan__h { margin-top: clamp(3.5rem, 8vh, 6rem); font-size: var(--step-2); text-wrap: balance; }
.spk-plan__block { margin-top: clamp(2.6rem, 5vw, 4rem); text-align:left; }
.spk-plan__label { font-family: var(--f-display); font-style:italic; font-weight:360;
  font-size: var(--step-0); line-height:1.3; letter-spacing:-0.01em;
  color: var(--violet-300); text-align:left; }
.spk-plan__copy { margin-top: .9rem; font-size: var(--step-0); line-height:1.6;
  color: var(--tx-inv-soft); text-align:left; }
.spk-plan__list { list-style:none; margin: 1.1rem 0 0; padding:0; text-align:left; }
.spk-plan__list li { padding-block: clamp(.85rem, 1.8vh, 1.15rem);
  font-size: var(--step--1); line-height:1.6; color: var(--tx-inv); text-wrap: pretty; }
.spk-plan__list li + li { border-top: 1px solid rgba(169,133,230,.30); }
/* what each talk leaves behind: the three talks as a definition list,
   set like the AV list */
.spk-plan__outs { margin: 1.1rem 0 0; text-align:left; }
.spk-plan__outs dt { font-family: var(--f-display); font-weight:360; font-size: var(--step-0);
  color: var(--tx-inv); padding-top: clamp(.85rem, 1.8vh, 1.15rem); }
.spk-plan__outs dt .tm { font-size:.5em; vertical-align:super; color: var(--tx-inv-faint); }
.spk-plan__outs dd { margin: .35rem 0 0; padding-bottom: clamp(.85rem, 1.8vh, 1.15rem);
  font-size: var(--step--1); line-height:1.6; color: var(--tx-inv-soft); }
.spk-plan__outs dd + dt { border-top: 1px solid rgba(169,133,230,.30); }
/* For planners: every point a dropdown (native <details>). A hairline
   between rows, the title in the display face, a plus that turns into a
   minus; the body opens with a height transition where the browser can
   animate to auto (elsewhere it opens at once). */
.spk-plan__acc { margin-top: 1rem; border-top: 1px solid rgba(169,133,230,.30); }
.spk-plan__item { border-bottom: 1px solid rgba(169,133,230,.30); interpolate-size: allow-keywords; }
.spk-plan__item summary { list-style:none; cursor:pointer; display:flex; align-items:center;
  justify-content:space-between; gap:1rem; padding-block: clamp(1rem, 2vh, 1.3rem);
  font-family: var(--f-display); font-weight:360; font-size: var(--step-1); line-height:1.2;
  letter-spacing:-0.015em; color: var(--tx-inv); }
.spk-plan__item summary::-webkit-details-marker { display:none; }
.spk-plan__item summary:hover .spk-plan__sum { color: var(--violet-300); }
.spk-plan__item summary:focus-visible { outline:2px solid var(--violet-300); outline-offset:4px; border-radius:2px; }
.spk-plan__sum { transition: color .25s var(--ease-out); }
.spk-plan__sum .tm { font-size:.45em; vertical-align:super; color: var(--tx-inv-faint); }
.spk-plan__pm { position:relative; flex:0 0 auto; width:14px; height:14px; }
.spk-plan__pm::before, .spk-plan__pm::after { content:""; position:absolute; left:0; right:0; top:50%;
  height:1.5px; margin-top:-.75px; background: var(--violet-300); transition: transform .3s var(--ease-out); }
.spk-plan__pm::after { transform: rotate(90deg); }
.spk-plan__item[open] .spk-plan__pm::after { transform: rotate(0deg); }
.spk-plan__item::details-content { block-size:0; overflow:hidden;
  transition: block-size .4s var(--ease-out), content-visibility .4s allow-discrete; }
.spk-plan__item[open]::details-content { block-size:auto; }
.spk-plan__body { padding-bottom: clamp(1rem, 2vh, 1.3rem); }
.spk-plan__body p { margin:0; font-size: var(--step-0); line-height:1.6; color: var(--tx-inv-soft); }
.spk-plan__body .spk-plan__list { margin-top:0; }
@media (prefers-reduced-motion: reduce) { .spk-plan__item::details-content { transition:none; } }
@media (max-width: 900px) {
  .spk-bio__grid { grid-template-columns: 1fr; }
  .spk-bio__left { position:static; display:flex; justify-content:center;
    margin-bottom: clamp(2rem, 6vw, 3rem); }
  .spk-bio__portrait { width:240px; max-width:none; aspect-ratio:1; }
  .spk-bio__right { max-width:none; }
}

/* ---------------------------------------------------------------------
   F. The close — the page lifts off a fixed final panel. main carries a
   bottom margin the height of the footer and sits above it, so the last
   scroll uncovers the footer standing still beneath. Module 9 writes
   --spk-foot-h. Without :has, or under reduced motion, a normal footer.
   --------------------------------------------------------------------- */
@supports selector(:has(a)) {
  main:has(.spk-hero) { margin-bottom: var(--spk-foot-h, 0px); position:relative; z-index:1; }
  /* the ground is position:fixed inside main, so it would cover the footer
     standing beneath; clip-path holds it (and everything in main) to
     main's own box */
  main:has(.spk-hero) { clip-path: inset(0); }
  .spk-foot { position:fixed; left:0; right:0; bottom:0; z-index:0; }
  /* where the footer grid leaves the panel under 40% of the screen,
     module 9 sets .is-flow: a normal footer */
  .spk-foot.is-flow { position:relative; z-index:1; }
  /* no script, nothing measures the footer: a normal footer */
  html.no-js .spk-foot { position:relative; z-index:1; }
}
@media (prefers-reduced-motion: reduce) {
  .spk-foot { position:static; }
  main:has(.spk-hero) { margin-bottom:0; }
}
/* the panel is the top of the footer: the footer's own top padding moves
   below it, above the grid */
.spk-foot { padding-top:0; }
/* --spk-close-h: module 9 shortens the panel so the whole lifted footer
   fits the screen; 70svh wherever it is not set */
.spk-close { position:relative; min-height: var(--spk-close-h, 70svh); display:grid; place-items:center start;
  text-align:left; overflow:hidden; margin-bottom: 3.5rem; }
.spk-close__img { position:absolute; inset:0; width:100%; height:100%; object-fit:cover;
  object-position: 72% 0%; }
.spk-close__veil { position:absolute; inset:0;
  background:
    radial-gradient(60% 50% at 50% 60%, rgba(169,133,230,.22), rgba(169,133,230,0) 70%),
    linear-gradient(180deg, rgba(18,10,28,.55), rgba(18,10,28,.25) 40%, rgba(18,10,28,.7) 100%); }
/* 30ch is measured in the heading's own size (on the wrapper it resolved
   to the body size and broke the line in three) */
.spk-close__inner { position:relative; z-index:1; width: var(--wrap); margin-inline:auto; }
.spk-close__h { max-width: 16ch; margin-inline:0;
  font-size: var(--step-3); font-weight:340; letter-spacing:-0.025em;
  color: var(--tx-inv); text-wrap:balance; }
.spk-close__cta { margin-top: clamp(1.4rem, 3vh, 2.2rem); display:inline-block; }

/* =====================================================================
   Section tones: a block's background setting, written as data-tone on
   its section. Each maps onto an existing colour token; the defaults the
   templates write are each section's own ground above, so nothing
   changes until an editor picks another tone. Colour only (no image).
   ===================================================================== */
section[data-tone="plum"]        { background-color: var(--plum); }
section[data-tone="plum-2"]      { background-color: var(--plum-2); }
section[data-tone="ink"]         { background-color: var(--ink); }
section[data-tone="paper"]       { background-color: var(--paper); color: var(--tx); }
section[data-tone="transparent"] { background-color: transparent; }

/* =====================================================================
   Placement (CMS step 2b): text over a picture, placed by the editor.
   A block's optional `placement` { x, y, align, maxWidth, mobile } is
   written by src/_includes/place.njk as inline custom properties on a
   .place wrapper; with no placement the template writes no wrapper and
   everything above applies unchanged.
     .place         the safe area: the picture less --inset on every side
                    (absolute, so it measures the block's positioned frame)
     .place__inner  the text box: its own (x%, y%) point is pinned to the
                    area's (x%, y%) point, so 50/50 centres it and 0/100
                    puts its bottom-left corner in the bottom-left corner
   The motion a module runs stays on the original elements, which now sit
   inside .place__inner: placement owns the box, motion owns what is in it.
   --pdx/--pdy/--pda/--pdj (and -m) are each block's defaults: today's
   position expressed in the model, used for any key the JSON leaves out.
   ===================================================================== */
.place {
  --px: initial; --py: initial; --place-align: initial; --place-justify: initial; --place-max: initial;
  --px-m: initial; --py-m: initial; --place-align-m: initial; --place-justify-m: initial; --place-max-m: initial;
  --inset: clamp(1.25rem, 4vw, 3.5rem);
  position:absolute; inset: var(--inset); pointer-events:none; }
.place__inner {
  --place-x: var(--px, var(--pdx, 50%)); --place-y: var(--py, var(--pdy, 50%));
  --place-a: var(--place-align, var(--pda, left)); --place-j: var(--place-justify, var(--pdj, start));
  position:absolute; left: var(--place-x); top: var(--place-y);
  transform: translate(calc(-1 * var(--place-x)), calc(-1 * var(--place-y)));
  width: max-content; max-width: 100%;
  display:grid; justify-items: var(--place-j); text-align: var(--place-a);
  pointer-events:auto; }
/* maxWidth: the measure of the text elements in the box, in their own size */
.place[style*="--place-max:"] > .place__inner :is(h1, h2, h3, h4, h5, h6, p, li, .spk-out__t) {
  max-width: var(--place-max); }
@media (max-width: 768px) {
  .place__inner {
    --place-x: var(--px-m, var(--px, var(--pdx-m, var(--pdx, 50%))));
    --place-y: var(--py-m, var(--py, var(--pdy-m, var(--pdy, 50%))));
    --place-a: var(--place-align-m, var(--place-align, var(--pda-m, var(--pda, left))));
    --place-j: var(--place-justify-m, var(--place-justify, var(--pdj-m, var(--pdj, start)))); }
  .place[style*="--place-max"] > .place__inner :is(h1, h2, h3, h4, h5, h6, p, li, .spk-out__t) {
    max-width: var(--place-max-m, var(--place-max)); }
}

/* --- Home ------------------------------------------------------------ */
/* hero: h1, play and meta as one group; today bottom-left */
.hero:not(.spk-hero) > .place { --pdx:0%; --pdy:100%; z-index:2; }
.hero:not(.spk-hero) > .place .hero__inner { width:auto; margin:0; padding:0; }
.hero:not(.spk-hero) > .place .hero__actions { max-width:none; justify-content: var(--place-j); }
.hero:not(.spk-hero) > .place .hero__meta { position:static; width:auto; max-width:none;
  margin: clamp(1.4rem, 3vh, 2.2rem) 0 0; text-align:inherit;
  align-items: var(--place-j); justify-content: var(--place-j); }
/* bleed: the statement; today centred */
.bleed > .place { --pdx:50%; --pdy:50%; --pda:center; --pdj:center; z-index:2; }
.bleed > .place .bleed__inner { width:auto; max-width: min(94vw, 1100px); padding-block:0; }
/* truth: the heading, in the block's content frame; today top-left */
.truth__inner > .place { --pdx:0%; --pdy:0%; z-index:2; }
.truth__inner > .place .truth__head { margin-bottom:0; }
/* why / care: the text group in the block's frame (the frame keeps its
   height when the group leaves the flow) */
.why__grid > .place { --pdx:100%; --pdy:50%; }
.why__grid:has(> .place) { min-height: 100svh; }
.why__grid > .place .why__body { grid-column:auto; }
.care__inner > .place { --pdx:0%; --pdy:50%; }
.care__inner:has(> .place) { min-height: 92svh; }
/* steps: the copy column (today left, middle; bottom on phones) and the
   final call to action (centred); only while the scene is pinned */
@media (prefers-reduced-motion: no-preference) {
  .steps__sticky > .place { --pdx:0%; --pdy:50%; --pdy-m:100%; z-index:2; }
  .steps__sticky > .place .steps__copy { position:relative; left:auto; top:auto; bottom:auto;
    transform:none; width: min(46rem, calc(100vw - 2 * var(--gutter) - 2 * var(--inset))); }
  .js .steps__final > .place { --pdx:50%; --pdy:50%; --pda:center; --pdj:center; }
  .js .steps__final > .place .final__inner { width:auto; max-width: min(94vw, 1000px); margin:0; }
  .js .steps__final > .place :is(.final__actions, .final__contact) { justify-content: var(--place-j); }
}
@media (prefers-reduced-motion: reduce) {
  .steps .place, .steps .place__inner { display:contents; }
}
html.no-js .steps .place, html.no-js .steps .place__inner { display:contents; }
/* patterns: the title, its hint and its controls; today top, centred */
.patterns__inner .place { --pdx:50%; --pdy:0%; --pda:center; --pdj:center; }
.patterns__inner .place .patterns__title { text-align:inherit; }
.patterns__inner .place .patterns__ctrl { justify-content: var(--place-j); }

/* --- Speaking -------------------------------------------------------- */
/* reel hero: the sound button; today bottom-centre */
.spk-hero > .place { --pdx:50%; --pdy:100%; --pda:center; --pdj:center; z-index:3; }
.spk-hero > .place .spk-hero__cta { position:relative; left:auto; bottom:auto; transform:none;
  align-items: var(--place-j); }
/* said: heading, lines, and the two grow windows (one shared placement);
   only on the pinned wheel, the stacked fallback keeps its flow */
.spk-said:not(.is-wheel) .place, .spk-said:not(.is-wheel) .place__inner { display:contents; }
.spk-said.is-wheel .place--h { --pdx:50%; --pdy:12%; --pda:center; --pdj:center; }
.spk-said.is-wheel .place--h .spk-said__h { position:relative; left:auto; top:auto; width:auto;
  transform:none; text-align:inherit; }
.spk-said.is-wheel .place--lines { --pdx:50%; --pdy:11%; --pdy-m:16%; --pda:center; --pdj:center; }
.spk-said.is-wheel .place--lines .spk-said__lines { position:relative; left:auto; top:auto; width:auto;
  transform:none; text-align:inherit; justify-items: var(--place-j); }
.spk-said.is-wheel :is(.place--win-a, .place--win-b) { --pdx:50%; --pdy:30%; --pdy-m:9%; --pda:center; --pdj:center; }
.spk-said.is-wheel .place--win-a { --pdy-m:33%; }   /* phones: A where the flame rises behind it */
.spk-said.is-wheel .place--win-b { --pdy-m:66%; }   /* phones: B low */
.spk-said.is-wheel .place--win-a { z-index:1; }
.spk-said.is-wheel .place--win-b { z-index:4; }
.spk-said.is-wheel :is(.place--win-a, .place--win-b) .spk-said__win { position:relative; left:auto; top:auto;
  width:auto; transform:none; }
.spk-said.is-wheel :is(.place--win-a, .place--win-b) :is(.spk-said__nextA, .spk-said__nextB) { text-align:inherit; }
/* keys: the heading (only over the pinned ground) and each talk's caption
   (over its picture in every mode); captions today centred */
.spk-keys__head .place { --pdx:50%; --pdy:50%; --pda:center; --pdj:center; }
.spk-keys__head .place__inner { pointer-events:none; }
html.no-js .spk-keys__head .place, html.no-js .spk-keys__head .place__inner,
.spk-keys.is-stacked .spk-keys__head .place, .spk-keys.is-stacked .spk-keys__head .place__inner { display:contents; }
@media (max-width: 768px) { .spk-keys__head .place, .spk-keys__head .place__inner { display:contents; } }
.spk-keys__panel > .place { --pdx:50%; --pdy:50%; --pda:center; --pdj:center; z-index:2; }
.spk-keys__panel > .place .spk-keys__caption { position:relative; left:auto; top:auto; transform:none;
  width:34ch; max-width:100%; text-align:inherit; }
/* chap: each chapter's word and its line over its still (one placement,
   two boxes on the same anchor: they take turns on the stage), and the
   rail. The placed chapter fills the stage's frame; its data-spot preset
   stays the default (ul: upper-left, lr: lower-right). Phones: the word
   sits over the chapter's own still (its 16:10 frame), the line follows
   under it as today. Static and no script: flow. */
.spk-chap__chapter.is-placed { left:0; right:0; top:0; bottom:0; max-width:none; }
.spk-chap__chapter.is-placed > .place { --pdx:0%; --pdy:27%; }
.spk-chap__chapter.is-placed[data-spot="lr"] > .place { --pdx:100%; --pdy:100%; --pda:right; --pdj:end; }
.spk-chap__chapter.is-placed > .place > .place__inner { max-width: min(100%, 26ch); }
.spk-chap__chapter.is-placed .place__inner > :is(.spk-chap__word, .spk-chap__text) { text-align:inherit; }
.spk-chap .place--rail { --pdx:0%; --pdy:50%; z-index:1; }
/* the stop labels hang to the right of the line: the box keeps room for them */
.spk-chap .place--rail > .place__inner { padding-right: 7rem; }
.spk-chap .place--rail .spk-chap__rail { position:relative; left:auto; top:auto; bottom:auto; height:72svh; }
.spk-chap.is-static .place, .spk-chap.is-static .place__inner,
html.no-js .spk-chap .place, html.no-js .spk-chap .place__inner { display:contents; }
/* phones' stage: the rail is hidden and every placement is let go (the
   chapter centres its word and line) */
.spk-chap.is-phone .place, .spk-chap.is-phone .place__inner { display:contents; }
/* out: the heading (over the band and the picture; today top, centred) and
   each word: a placed word's <li> is its own area, the picture less the
   inset, and its pool of light moves onto the box. Phones stack. */
.spk-out .place__inner { pointer-events:none; }
@media (min-width: 641px) {
  .spk-out__inner > .place { --pdx:50%; --pdy:8%; --pda:center; --pdj:center; z-index:3; }
  .spk-out__inner > .place .spk-out__h { position:relative; left:auto; top:auto; width:auto;
    max-width: var(--wrap); transform:none; text-align:inherit; }
  .spk-out__word.place { --pdx: var(--x, 50%); --pdy: var(--y, 50%); --pda:center; --pdj:center;
    transform:none; }
  .spk-out__word.place::before { display:none; }
  .spk-out__word.place > .place__inner::before { content:""; position:absolute; left:50%; top:50%; z-index:0;
    width:22rem; height:22rem; transform: translate(-50%, -50%); border-radius:50%; pointer-events:none;
    background: radial-gradient(closest-side, rgba(169,133,230,.22), transparent 60%);
    opacity:0; transition: opacity .9s var(--ease-out); }
  .spk-out__word.place.is-on > .place__inner::before { opacity:1; }
}
@media (min-width: 641px) and (prefers-reduced-motion: reduce) {
  .spk-out__word.place > .place__inner::before { display:none; }
}
html.no-js .spk-out__word.place > .place__inner::before { display:none; }
@media (max-width: 640px) {
  .spk-out__inner > .place, .spk-out__inner > .place > .place__inner,
  .spk-out__word.place > .place__inner { display:contents; }
  .spk-out__word.place { position:relative; inset:auto; }
}
/* formats: the sentence, only while the stage is pinned; today upper-middle */
.spk-formats__stage > .place { --pdx:50%; --pdy:30%; --pda:center; --pdj:center; z-index:1; }
.spk-formats__stage > .place .spk-formats__line { width:auto; margin:0; text-align:inherit; }
html.no-js .spk-formats__stage > .place, html.no-js .spk-formats__stage > .place > .place__inner { display:contents; }
@media (max-width: 768px), (prefers-reduced-motion: reduce) {
  .spk-formats__stage > .place, .spk-formats__stage > .place > .place__inner { display:contents; }
}
/* close: heading and button as one group; today left, middle */
.spk-close > .place { --pdx:0%; --pdy:50%; z-index:1; }
.spk-close > .place .spk-close__inner { width:auto; margin:0; }

/* =====================================================================
   Phone pass, part 1 (brief 24)
   ===================================================================== */
/* Scroll-fill headings (js module 12). A .fill heading's words are split
   at build time (.fill__w, --i of --n). The module writes --fp (0..1) on
   the heading from its place in the viewport and adds .is-filling where
   the fill applies (data-fill on <body>: phone | all | off; never under
   reduced motion, never on a heading its own module is animating). Each
   word fills from the dim cream to its own colour with a --fill-stagger
   offset; an <em> or <b> inside a word keeps its own colour. */
body { --fill-stagger: 0.12; }
.fill.is-filling .fill__w, .fill.is-filling .fill__w * {
  --fw: clamp(0, calc(var(--fp, 0) * (1 + var(--fill-stagger) * (var(--n, 1) - 1)) - var(--fill-stagger) * var(--i, 0)), 1);
  -webkit-text-fill-color: color-mix(in srgb, currentColor calc(var(--fw) * 100%), rgba(244,236,222,.28)); }

/* The name into the header (js module 13, phones): the brand, large, under
   the nav at the hero's top-left; over the first 40% of the hero it moves
   and scales into the nav's brand slot, then the real .brand takes over. */
.hero__name { display:none; }
@media (max-width: 768px) {
  html.js .hero__name.is-armed { display:block; position:fixed; left:var(--gutter); top:5rem; z-index:91;
    margin:0; font-family:var(--f-display); font-size:2.4rem; font-weight:500; letter-spacing:-0.01em;
    line-height: var(--lh-text); white-space:nowrap; color: var(--tx-inv); pointer-events:none;
    text-shadow: 0 1px 10px rgba(0,0,0,.32); transform-origin: 0 0; will-change: transform; }
  html.js .hero__name.is-armed.is-done { visibility:hidden; }
  .nav.is-name-morph .brand { opacity:0; }

  /* The hero card-slide (js module 13): the hero holds still for its own
     height while the next section slides up over it as a card; the hero's
     picture dims as it is covered (--hero-dim); once covered it is hidden
     so the sections below never show it through. */
  html.js .hero { position:sticky; top:0; z-index:0; }
  html.js .hero.is-covered { visibility:hidden; }
  html.js .hero + section { position:relative; z-index:2; border-radius:20px 20px 0 0;
    box-shadow: 0 -18px 40px rgba(8,4,14,.45); }
  html.js .spk-hero + section { background: rgb(var(--spk-ground, 26 16 38)); }
  html.js .spk-hero .media::after {
    background:
      linear-gradient(rgba(14,8,22,var(--hero-dim, 0)), rgba(14,8,22,var(--hero-dim, 0))),
      linear-gradient(0deg, rgba(14,8,22,0.80) 0%, rgba(14,8,22,0.52) 14%, rgba(14,8,22,0.26) 30%, rgba(14,8,22,0) 52%),
      linear-gradient(180deg, rgba(14,8,22,0.48) 0%, rgba(14,8,22,0) 26%); }
}

/* =====================================================================
   Skip (js module 14): a thin arrow bottom right while a long pinned
   section holds the screen; "Skip now" slides out beside it only while
   the visitor shows they want out (.is-intent).
   ===================================================================== */
.pinskip { position:fixed; right: max(16px, env(safe-area-inset-right)); bottom: max(12px, env(safe-area-inset-bottom));
  z-index:80; display:flex; flex-direction:column; align-items:center; justify-content:flex-end; gap:0;
  min-width:44px; min-height:44px; padding:6px 10px; border:0; border-radius:12px; background: transparent;
  color: var(--violet-300, #A985E6); cursor:pointer;
  opacity:0; transform: translateY(6px); pointer-events:none;
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out), background-color .3s var(--ease-out); }
.pinskip.is-on { opacity:.55; transform:none; pointer-events:auto; }
.pinskip.is-on:hover, .pinskip.is-on:focus-visible, .pinskip.is-on.is-intent { opacity:1; }
.pinskip:focus-visible { outline:2px solid var(--violet-300); outline-offset:2px; }
.pinskip__arrow { width:110px; height:24px; filter: drop-shadow(0 0 6px rgba(10,5,16,.7)); flex:0 0 auto; fill:none; stroke: currentColor; stroke-width:1.2;
  stroke-linecap:round; stroke-linejoin:round; }
/* phones: a shorter arrow */
.pinskip__arrow--short { display:none; width:64px; }
@media (max-width: 768px) {
  .pinskip__arrow--long { display:none; }
  .pinskip__arrow--short { display:block; }
}
/* "Skip": sitting on the arrow's line, centred on it, no card behind;
   only on intent */
.pinskip__label { display:block; max-height:0; overflow:hidden; white-space:nowrap; opacity:0;
  font-size:.78rem; line-height:1.2; letter-spacing:.18em; text-transform:uppercase; color: var(--tx-inv);
  text-shadow: 0 1px 8px rgba(10,5,16,.9), 0 0 2px rgba(10,5,16,.8);
  transition: max-height .3s var(--ease-out), opacity .3s var(--ease-out), margin .3s var(--ease-out); }
.pinskip.is-intent .pinskip__label { max-height:1.4em; opacity:1; margin-bottom:-.3rem; }
@media (prefers-reduced-motion: reduce) { .pinskip { display:none; } }
