/* app.css - Where The Work Is
 *
 * One surface, one ink scale, three data hues. The data hues are the project's
 * matplotlib palette re-stepped for a dark surface (blue #3987e5, orange
 * #d95926, aqua #199e70, plus red #e66767 for the negative half of a diverging
 * pair). Every one of them clears 3:1 against the surface. Nothing else on the
 * page is allowed to use a data hue as a fill.
 *
 * Depth comes from three cheap layers and no filters: a fixed ambient wash, a
 * fixed grain tile, and a hairline of light along the top edge of every raised
 * surface. All three are painted once and composited; none of them repaint on
 * scroll, which matters because this page animates eighteen circles at once.
 */

:root {
  color-scheme: dark;

  /* three tiers: canvas, elevated section, card. A fourth, lighter step is
     only for hover and recessed tiles INSIDE a card. */
  --surface: #0a0c10;
  --surface-1: #11151c;
  --card: #181d27;
  --card-line: rgba(255, 255, 255, 0.07);
  --surface-2: #1f2531;
  --line: rgba(255, 255, 255, 0.07);
  --line-2: rgba(255, 255, 255, 0.14);

  --ink: #f4f5f7;
  --ink-2: #a7aeba;
  --muted: #6e7783;

  --blue: #3987e5;
  --orange: #d95926;
  --aqua: #199e70;
  --red: #e66767;
  --amber: #dfa54e;          /* caveats only: a warning, not a data series */

  /* Windows 11 and macOS both ship a proper display cut of their UI face; the
     stack falls back through the old static ones, so nothing is downloaded. */
  --ff-display: "Segoe UI Variable Display", "SF Pro Display", -apple-system,
                BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue",
                Arial, sans-serif;
  --ff: "Segoe UI Variable Text", "SF Pro Text", -apple-system,
        BlinkMacSystemFont, "Segoe UI", Inter, Roboto, "Helvetica Neue",
        Arial, sans-serif;
  --fm: ui-monospace, SFMono-Regular, "SF Mono", "Cascadia Mono", Menlo,
        Consolas, monospace;

  --gut: clamp(16px, 5vw, 72px);
  --maxw: 1280px;

  --r-sm: 10px;
  --r: 18px;
  --r-lg: 24px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --t-fast: 0.18s;
  --t: 0.32s;

  /* chrome that floats over content: translucent, never a data hue */
  --glass: rgba(12, 15, 20, 0.62);
  --glass-line: rgba(255, 255, 255, 0.09);
  --chip: rgba(255, 255, 255, 0.045);
  --chip-hi: rgba(255, 255, 255, 0.09);

  /* one raised-surface recipe, used everywhere */
  --raise: linear-gradient(180deg, rgba(255, 255, 255, 0.045),
                                   rgba(255, 255, 255, 0.012));
  --lift: inset 0 1px 0 rgba(255, 255, 255, 0.07),
          0 1px 2px rgba(0, 0, 0, 0.4),
          0 14px 34px rgba(0, 0, 0, 0.3);
  --lift-hi: inset 0 1px 0 rgba(255, 255, 255, 0.11),
             0 2px 4px rgba(0, 0, 0, 0.4),
             0 22px 48px rgba(0, 0, 0, 0.42);
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  background: var(--surface);
}

body {
  margin: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--ff);
  font-size: 17px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Ambient wash and grain. Both are fixed and sit at z-index -1, so they paint
   above the root background and below every block of content, and neither is
   touched again while the page scrolls. */
body::before,
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

body::before {
  background:
    radial-gradient(1100px 620px at 18% -8%, rgba(57, 135, 229, 0.11), transparent 62%),
    radial-gradient(900px 560px at 92% 8%, rgba(217, 89, 38, 0.06), transparent 64%),
    radial-gradient(1000px 700px at 50% 108%, rgba(25, 158, 112, 0.05), transparent 60%);
}

/* A 140px tile of fractal noise, rasterised once and repeated. This is the
   texture that stops a large flat dark area looking like a dead screen. */
body::after {
  opacity: 0.035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

::selection { background: rgba(57, 135, 229, 0.35); color: #fff; }

:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
  border-radius: 4px;
}

* { scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, 0.16) transparent; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16);
  border-radius: 8px;
  border: 3px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.26); background-clip: content-box; }
body.locked { overflow: hidden; }
a { color: inherit; }
h1, h2, h3 {
  font-family: var(--ff-display);
  line-height: 1.06;
  margin: 0;
  letter-spacing: -0.03em;
  font-weight: 700;
  text-wrap: balance;
}

/* Figures line up in columns wherever they are compared. */
.stat .v, .kpi .v, .hc-row .v, .exp-row .val, .mono, .hero-count, .aud-row .ch {
  font-variant-numeric: tabular-nums;
}
.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gut); }
.mono {
  font-family: var(--fm);
  font-size: 0.7em;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}

/* ------------------------------------------------------------------ nav */
/* A hairline of progress across the top, and a quiet bar that only appears once
   the opening screen is behind you. */
/* Glass here and nowhere else: the bar only exists once most of the hero is
   behind you, so at worst it blurs a 60px strip of the slow 16s drift. The
   hero card and chips sit ON the field and stay solid for that reason. */
.nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 18px;
  height: 60px;
  padding: 0 var(--gut);
  background: rgba(10, 12, 15, 0.94);
  border-bottom: 1px solid var(--glass-line);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04), 0 18px 40px -24px rgba(0, 0, 0, 0.9);
  transform: translateY(-100%);
  transition: transform 0.5s var(--ease);
}

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .nav {
    background: var(--glass);
    -webkit-backdrop-filter: saturate(170%) blur(18px);
    backdrop-filter: saturate(170%) blur(18px);
  }
}

.nav.on { transform: none; }

.nav-brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: 15.5px;
  letter-spacing: -0.02em;
  text-decoration: none;
  white-space: nowrap;
}

/* the favicon's rising line, as a mark */
.nav-brand::before {
  content: "";
  width: 22px; height: 22px;
  flex: none;
  border-radius: 7px;
  border: 1px solid var(--glass-line);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M18 74 L40 52 L58 62 L82 26' stroke='%233987e5' stroke-width='11' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/15px no-repeat,
    var(--surface-1);
}

.nav-links { margin-left: auto; display: flex; gap: 2px; }

.nav-links a {
  text-decoration: none;
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 500;
  padding: 7px 14px;
  border-radius: 999px;
  transition: color var(--t-fast), background var(--t-fast);
}

.nav-links a:hover { color: var(--ink); background: var(--chip-hi); }

.nav-sfx {
  margin-left: 4px; display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 999px;
  border: 1px solid var(--glass-line);
  background: var(--chip);
  color: var(--ink-2); cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast),
              border-color var(--t-fast), transform var(--t-fast) var(--ease);
}
.nav-sfx:hover { color: var(--ink); background: var(--chip-hi); border-color: var(--line-2); }
.nav-sfx:active { transform: scale(0.92); }
.nav-sfx svg path, .nav-sfx svg line {
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
/* hover: the sound waves reach a little further out */
.nav-sfx[aria-pressed="true"]:hover .w1 { transform: translateX(1px); }
.nav-sfx[aria-pressed="true"]:hover .w2 { transform: translateX(2px); }
.nav-sfx .x { opacity: 0; }
.nav-sfx[aria-pressed="false"] { color: var(--muted); }
.nav-sfx[aria-pressed="false"] .w1,
.nav-sfx[aria-pressed="false"] .w2 { opacity: 0; }
.nav-sfx[aria-pressed="false"] .x { opacity: 1; }

.nav-prog {
  position: absolute;
  left: 0; bottom: -1px;
  height: 2px;
  width: var(--p, 0%);
  background: linear-gradient(90deg, var(--blue), #6da7ec);
  box-shadow: 0 0 10px rgba(57, 135, 229, 0.55);
}

@media (max-width: 620px) {
  .nav-links a:not(.keep) { display: none; }
}

/* on a phone the mark, not the sound button, is what gives way */
@media (max-width: 480px) {
  .nav { gap: 8px; }
  .nav-brand { font-size: 14.5px; }
  .nav-brand::before { display: none; }
  .nav-links a { padding: 7px 10px; }
}
@media (max-width: 360px) {
  .nav-links a { padding: 7px 7px; font-size: 13px; }
}

/* ------------------------------------------------------------------ hero */
/* Exactly one screen: head, field and foot share it, and the field takes
   whatever the other two leave. */
.hero {
  position: relative;
  height: 100vh;
  height: 100dvh;
  min-height: 540px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: clamp(26px, 4vh, 44px) 0 44px;
}

.hero-head { flex: none; }

/* Massive, but ONE line: every pixel of height the headline takes comes out of
   the bubble field under it, so it grows sideways and tracks tight instead. */
.hero h1 {
  font-size: clamp(32px, 4.9vw, 78px);
  font-weight: 800;
  letter-spacing: -0.048em;
  line-height: 0.98;
  max-width: none;
  margin: 14px 0 0;
}

.hero h1 em {
  font-style: normal;
  color: var(--orange);
  background: linear-gradient(100deg, #f0875a 10%, var(--orange) 70%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

.hero-sub {
  margin: 12px 0 0;
  max-width: 90ch;
  color: var(--ink-2);
  font-size: clamp(13.5px, 1.2vw, 15.5px);
}

.hero-sub b { color: var(--ink); font-weight: 600; }

/* A pill, not a line of small caps: it reads as a dataset stamp. */
.hero-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 6px 13px 6px 11px;
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: var(--chip);
  color: var(--ink-2);
  font-size: 11px;
  letter-spacing: 0.14em;
}
.hero-eyebrow::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--aqua);
  box-shadow: 0 0 0 3px rgba(25, 158, 112, 0.18);
}

/* full bleed: the field is not inside .wrap, so it uses the whole window */
.hero-stage {
  position: relative;
  flex: 1 1 0;
  min-height: 0;
  margin: 6px 0 0;
}

.hero-svg { display: block; width: 100%; height: 100%; overflow: visible; }

.bub { cursor: pointer; outline: none; transition: opacity 0.35s; }
.bub.dim { opacity: 0.22; }

.bub-halo { pointer-events: none; }

/* Hover and selection work on fill-opacity, not on a filter: a filter would
   re-render the circle on every frame it drifts. */
.bub-c { transition: fill-opacity 0.25s, stroke-width 0.2s; }
.bub:hover .bub-c { fill-opacity: 1; }
.bub.sel .bub-c { fill-opacity: 1; stroke: #ffffff; stroke-width: 2.5; stroke-opacity: 1; }
.bub:focus-visible .bub-c { stroke: var(--ink); stroke-width: 3; stroke-opacity: 1; }

/* Drift and entrance sit on separate groups so the two transforms compose.
   will-change hands both to the compositor. */
.bub-float {
  animation: bubDrift 16s ease-in-out infinite alternate;
  will-change: transform;
}

@keyframes bubDrift {
  from { transform: translate(0, 0); }
  to { transform: translate(var(--fx, 0px), var(--fy, 0px)); }
}

/* 🚨 Only circles live in here. Scaling a group that contains an emoji forces a
   glyph re-raster on every frame, which is what made the entrance stutter. */
.bub-pop {
  transform-box: fill-box;
  transform-origin: center;
  animation: bubPop 0.5s cubic-bezier(0.22, 1, 0.36, 1) backwards;
  will-change: transform;
}

@keyframes bubPop {
  from { transform: scale(0.55); opacity: 0; }
  to { transform: scale(1); opacity: 1; }
}

/* Labels never scale. They only fade, which the compositor does for free. */
.bub-lab {
  animation: bubFade 0.45s ease-out backwards;
  pointer-events: none;
}

@keyframes bubFade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.bub-i {
  dominant-baseline: middle;
  font-family: "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
}

.bub-t {
  fill: #ffffff;
  font-weight: 700;
  letter-spacing: -0.01em;
  paint-order: stroke;
  stroke: rgba(0, 0, 0, 0.5);
  stroke-width: 3.5px;
}

.hero-foot {
  flex: none;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  align-items: center;
  justify-content: space-between;
  margin-top: 8px;
}

/* Legend and count are dashboard chips. No blur on either: they sit under the
   field, where a backdrop filter would re-sample drifting circles every frame. */
.hero-legend,
.hero-count {
  border: 1px solid var(--glass-line);
  border-radius: 999px;
  background: rgba(16, 19, 25, 0.78);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05), 0 8px 24px -12px rgba(0, 0, 0, 0.8);
}

.hero-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  padding: 8px 16px;
  color: var(--ink-2);
  font-size: 12.5px;
}

/* hairline between the size key and the colour key */
.hero-legend > span:nth-child(2)::after {
  content: "";
  display: inline-block;
  width: 1px; height: 14px;
  margin-left: 14px;
  vertical-align: -2px;
  background: var(--line-2);
}

.hero-count {
  padding: 9px 16px;
  color: var(--ink-2);
  font-size: 11px;
}
.hero-count span { color: var(--ink); font-weight: 700; }

/* On a phone every pixel of chrome comes out of the field, which has to share
   one screen with it, so the chrome gets tight. */
@media (max-width: 620px) {
  .hero-legend, .hero-count { border-radius: 14px; }
  .hero-legend > span:nth-child(2)::after { display: none; }
  .hero-eyebrow { font-size: 9px; letter-spacing: 0.08em; padding: 5px 10px 5px 9px; gap: 7px; white-space: nowrap; }
  .hero h1 { margin-top: 10px; }
  .hero-sub { margin-top: 8px; }
  .hero-foot { gap: 6px; margin-top: 4px; }
  .hero-legend { padding: 6px 12px; gap: 4px 10px; font-size: 11.5px; }
  .hero-count { padding: 6px 12px; font-size: 10px; }
  .lg-ramp i { width: 10px; }
}

.lg-size { display: inline-flex; align-items: flex-end; gap: 4px; }
.lg-size i {
  display: block;
  border-radius: 50%;
  background: transparent;
  border: 1.5px solid var(--line-2);
}
.lg-size i:nth-child(1) { width: 7px; height: 7px; }
.lg-size i:nth-child(2) { width: 12px; height: 12px; }
.lg-size i:nth-child(3) { width: 18px; height: 18px; }

.lg-ramp { position: relative; display: inline-flex; }
.lg-ramp i { display: block; width: 13px; height: 8px; }
.lg-ramp i:first-child { border-radius: 999px 0 0 999px; }
.lg-ramp i:last-child { border-radius: 0 999px 999px 0; }
.lg-ramp::after {
  content: "";
  position: absolute;
  left: 50%; top: -4px; bottom: -4px;
  width: 1.5px;
  margin-left: -0.75px;
  border-radius: 1px;
  background: var(--ink);
}

/* the card that opens when a circle is tapped */
.hero-card {
  position: absolute;
  right: var(--gut);
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: min(360px, calc(100% - var(--gut) * 2));
  max-height: calc(100% - 32px);
  overflow-y: auto;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: var(--r);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.05), transparent 40%), rgba(20, 24, 33, 0.95);
  padding: 22px 24px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 24px 70px rgba(0, 0, 0, 0.7);
  animation: cardIn 0.32s var(--ease);
}

.hero-card[hidden] { display: none; }

@supports ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hero-card, .hero-photos {
    -webkit-backdrop-filter: saturate(160%) blur(18px);
    backdrop-filter: saturate(160%) blur(18px);
  }
  .hero-card { background: linear-gradient(180deg, rgba(255, 255, 255, 0.06), transparent 40%), rgba(20, 24, 33, 0.72); }
}
.hero:has(.hero-card:not([hidden])) .bub-float { animation-play-state: paused; }

/* Three photographs of the industry, stacked in a column to the LEFT of the
   hero card. Same vertical centring so the two blocks are one unit visually.
   Hidden on narrow screens where the card already fills the space. */
.hero-photos {
  position: absolute;
  right: calc(var(--gut) + min(360px, calc(100% - var(--gut) * 2)) + 12px);
  top: 50%; transform: translateY(-50%);
  z-index: 3;
  display: flex; flex-direction: column; gap: 10px;
  padding: 10px;
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: calc(var(--r) + 2px);
  background: rgba(20, 24, 33, 0.55);
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
  animation: cardIn 0.32s var(--ease);
}
.hero-photos[hidden] { display: none; }
.hero-photos figure {
  position: relative;
  width: clamp(140px, 18vw, 220px);
  margin: 0;
}
.hero-photos img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover; object-position: center 40%;
  border-radius: 12px;
  border: 1px solid var(--line-2);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.5);
}
.hero-photos figcaption {
  position: absolute;
  left: 8px; bottom: 8px;
  background: rgba(10, 12, 15, 0.78);
  color: #fff;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
  padding: 4px 8px;
  border-radius: 6px;
  max-width: calc(100% - 16px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  backdrop-filter: blur(4px);
}
@media (max-width: 900px) { .hero-photos { display: none; } }


@keyframes cardIn {
  from { opacity: 0; transform: translate(14px, -50%); }
  to { opacity: 1; transform: translate(0, -50%); }
}

.hero-card .hc-top { display: flex; align-items: center; gap: 10px; }
.hero-card .hc-ic {
  font-size: 26px;
  line-height: 1;
  font-family: "Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", sans-serif;
}
.hero-card h3 { font-size: 19px; flex: 1; min-width: 0; }
.hero-card .hc-x {
  flex: none;
  width: 30px; height: 30px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--chip);
  color: var(--ink-2);
  cursor: pointer;
  line-height: 1;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.hero-card .hc-x:hover { color: var(--ink); border-color: var(--line-2); background: var(--chip-hi); transform: rotate(90deg); }
.hero-card .hc-blurb { margin: 10px 0 0; font-size: 13.5px; color: var(--ink-2); }

.hc-rows { margin-top: 14px; display: flex; flex-direction: column; gap: 10px; }

.hc-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 12px;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.hc-row:first-child { border-top: 0; padding-top: 0; }
.hc-row .l {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.hc-row .v { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.15; }
.hc-row .v.pos { color: var(--aqua); }
.hc-row .v.neg { color: var(--red); }
.hc-row .m { font-size: 12.5px; color: var(--ink-2); align-self: center; }

.hc-rank {
  display: inline-block;
  font-size: 11px;
  font-weight: 700;
  color: var(--ink);
  background: var(--surface-2);
  border: 1px solid var(--line-2);
  border-radius: 5px;
  padding: 1px 6px;
  margin-right: 6px;
}

.hc-go {
  margin-top: 18px;
  width: 100%;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--ink);
  color: var(--surface);
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  padding: 11px 14px;
  cursor: pointer;
  transition: background var(--t-fast), transform var(--t-fast) var(--ease), box-shadow var(--t-fast);
}
.hc-go:hover { background: #fff; transform: translateY(-1px); box-shadow: 0 10px 24px -10px rgba(255, 255, 255, 0.35); }
.hc-go:active { transform: none; }

.scroll-hint {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  color: var(--muted);
  animation: bob 2.4s ease-in-out infinite;
  pointer-events: none;
}

@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); }
  50% { transform: translate(-50%, 7px); }
}

.scroll-hint span { font-size: 10px; letter-spacing: 0.16em; text-transform: uppercase; }

@media (max-width: 760px) {
  .hero { padding-top: 18px; padding-bottom: 14px; }   /* the scroll hint is hidden here */
  .hero-card {
    left: 0; right: 0; top: auto; bottom: 0;
    width: auto; transform: none; max-height: 72%;
    border-radius: 22px 22px 0 0;
    border-bottom: 0;
    padding-top: 26px;
    box-shadow: 0 -18px 50px rgba(0, 0, 0, 0.6);
  }
  .hero-card::before {
    content: "";
    position: absolute;
    top: 9px; left: 50%;
    width: 38px; height: 4px;
    margin-left: -19px;
    border-radius: 2px;
    background: rgba(255, 255, 255, 0.25);
  }
  @keyframes cardIn {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
  }
  .scroll-hint { display: none; }
}

/* ------------------------------------------------------------------ section */
.sec { padding: clamp(80px, 12vw, 160px) 0; }

/* Alternate canvas and elevated tiers so each section reads as its own room.
   #explore is always elevated; the others alternate around it. */
#who, #explore, .foot {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.012), transparent 240px), var(--surface-1);
}

.sec-head { max-width: 62ch; margin-bottom: clamp(36px, 5vw, 56px); }

/* eyebrow: a short rule, then the label */
.sec-head .mono { display: inline-flex; align-items: center; gap: 12px; }
.sec-head .mono::before {
  content: "";
  width: 26px; height: 1px;
  background: linear-gradient(90deg, var(--blue), transparent);
}

.sec-head h2 {
  font-size: clamp(30px, 4.6vw, 56px);
  letter-spacing: -0.038em;
  margin-top: 16px;
}

.sec-head p {
  color: var(--ink-2);
  margin: 18px 0 0;
  font-size: clamp(15px, 1.7vw, 18px);
}

.rule {
  height: 1px;
  border: 0;
  margin: 0;
  background: linear-gradient(90deg, transparent, var(--line-2) 22%,
                                     var(--line-2) 78%, transparent);
}

/* ------------------------------------------------------------------ audience */
/* Four cards, still one line each. Anyone skimming should find their own card
   and its chapter numbers in about two seconds. */
.aud {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}
/* a 2x2 bento: four rooms, same size, one glance */
@media (min-width: 720px) { .aud { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; } }

.aud-row {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 168px;
  padding: 26px 26px 22px;
  border: 1px solid var(--card-line);
  border-radius: var(--r);
  background: var(--raise), var(--card);
  box-shadow: var(--lift);
  overflow: hidden;
}

/* a line of light along the top edge, only while hovered */
.aud-row::before,
.limit::after {
  content: "";
  position: absolute;
  left: 18px; right: 18px; top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent);
  opacity: 0;
  transition: opacity var(--t);
}

.aud-row:hover { transform: translateY(-4px); border-color: var(--line-2); box-shadow: var(--lift-hi); }
.aud-row:hover::before { opacity: 1; }

.aud-row b { font: 700 17px/1.25 var(--ff-display); letter-spacing: -0.02em; }
.aud-row span { color: var(--ink-2); font-size: 14.5px; line-height: 1.5; }
.aud-row .ch {
  align-self: flex-end;        /* the pill sits bottom right, on the card floor */
  margin-top: auto;
  font-family: var(--fm);
  font-size: 11.5px;
  color: var(--ink-2);
  letter-spacing: 0.08em;
  white-space: nowrap;
  padding: 5px 11px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--chip);
}
/* the chip sits on the card floor; a spacer keeps it off the sentence */
.aud-row span:not(.ch) { margin-bottom: 8px; }

/* ------------------------------------------------------------------ chapter cards */
.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

/* Nine chapters divide by three, so the columns are fixed rather than left to
   auto-fill, which at some widths dropped a single card onto a row of its own. */
/* Eleven chapters, and never an empty cell:
     3 columns  01-09 fill a 3x3, then the closing pair is 10 | 11 11, so the
                whole thing is a complete 3x4 with chapter 11 as the capstone
     2 columns  01 spans both (a featured opener), 02-09 fill four rows, then
                10 | 11
     1 column   everything stacks  */
.finale { display: grid; grid-template-columns: 1fr; gap: 16px; }

@media (min-width: 680px) {
  .cards, .finale { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards > .card:first-child { grid-column: span 2; }
}

@media (min-width: 1040px) {
  .cards, .finale { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .cards > .card:first-child { grid-column: auto; }
  .finale > .card:last-child { grid-column: span 2; }
}

.card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 26px 24px 22px;
  border: 1px solid var(--card-line);
  border-radius: var(--r);
  background: var(--raise), var(--card);
  box-shadow: var(--lift);
  cursor: pointer;
  text-align: left;
  color: inherit;
  font: inherit;
  overflow: hidden;
}

.card::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--r);
  background: radial-gradient(420px 220px at var(--mx, 50%) var(--my, 0%),
              rgba(57, 135, 229, 0.14), transparent 70%);
  opacity: 0;
  transition: opacity 0.3s;
  pointer-events: none;
}

.card:hover, .card:focus-visible {
  border-color: var(--line-2);
  transform: translateY(-4px);
  box-shadow: var(--lift-hi);
  outline: none;
}

.card:hover::after, .card:focus-visible::after { opacity: 1; }

.card .num {
  position: absolute;
  top: 10px; right: 18px;
  font-family: var(--ff-display);
  font-size: 52px;
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 1;
  color: rgba(255, 255, 255, 0.05);
  transition: color 0.3s var(--ease);
  pointer-events: none;
}

.card:hover .num { color: rgba(255, 255, 255, 0.1); }

.card h3 { font-size: 20px; letter-spacing: -0.022em; padding-right: 38px; }

.card .teaser { color: var(--ink-2); font-size: 14px; margin: 0; }

.card .who {
  margin-top: auto;
  padding-top: 14px;
  color: var(--muted);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.card .who::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--blue);
  flex: none;
}

.card .go {
  position: absolute;
  bottom: 18px; right: 20px;
  color: var(--muted);
  transition: transform 0.3s var(--ease), color 0.3s var(--ease);
}

.card:hover .go { transform: translateX(5px); color: var(--blue); }

/* ------------------------------------------------------------------ player */
/* A screening room: the page falls away, a cool light from the top left, and
   the frame settles in from a hair larger than its final size. */
.player {
  position: fixed;
  inset: 0;
  z-index: 60;
  background:
    radial-gradient(1200px 640px at 22% -12%, rgba(57, 135, 229, 0.09), transparent 62%),
    radial-gradient(900px 500px at 100% 110%, rgba(217, 89, 38, 0.045), transparent 60%),
    var(--surface);
  display: flex;
  flex-direction: column;
  opacity: 0;
  visibility: hidden;
  transform: scale(1.012);
  transition: opacity 0.4s var(--ease), transform 0.55s var(--ease), visibility 0s 0.4s;
}

.player.on {
  opacity: 1; visibility: visible; transform: none;
  transition: opacity 0.4s var(--ease), transform 0.55s var(--ease), visibility 0s;
}

.p-top {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px var(--gut);
  border-bottom: 1px solid var(--line);
  flex: none;
}

.p-top .num {
  font-family: var(--fm);
  font-size: 11.5px;
  letter-spacing: 0.1em;
  color: var(--ink-2);
  padding: 5px 11px;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  background: var(--chip);
  font-variant-numeric: tabular-nums;
}

.p-top h2 {
  font-size: clamp(15px, 2.2vw, 20px);
  letter-spacing: -0.02em;
  margin-left: 4px;
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.icon-btn {
  flex: none;
  width: 40px; height: 40px;
  display: grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--chip);
  color: var(--ink-2);
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast),
              transform var(--t-fast) var(--ease), box-shadow var(--t-fast);
}

.icon-btn:hover:not(:disabled) { border-color: var(--line-2); color: var(--ink); background: var(--chip-hi); transform: translateY(-1px); }
.icon-btn:active:not(:disabled) { transform: scale(0.94); }
.icon-btn:disabled { opacity: 0.28; cursor: not-allowed; box-shadow: none; }
.icon-btn[hidden] { display: none; }

/* Forward is the one action that matters most, so it is the one filled button. */
.icon-btn.p-next { background: var(--ink); color: var(--surface); border-color: transparent; }
.icon-btn.p-next:hover:not(:disabled) { background: #fff; color: var(--surface); box-shadow: 0 10px 26px -10px rgba(255, 255, 255, 0.4); }
.icon-btn.p-close:hover:not(:disabled) { transform: rotate(90deg); }

/* The read-aloud toggle carries its own word, because the page no longer has a
   sentence anywhere explaining that the chapters can read themselves. */
.p-voice { width: auto; gap: 8px; padding: 0 14px; grid-auto-flow: column; }
.p-voice-l { font-size: 13px; font-weight: 500; letter-spacing: 0.01em; }
/* pressed: a tinted, lit chip. Read at a glance as ON without reading the word */
.p-voice[aria-pressed="true"],
.p-auto[aria-pressed="true"] {
  color: #9cc3f2;
  border-color: color-mix(in srgb, var(--blue) 55%, transparent);
  background: color-mix(in srgb, var(--blue) 16%, transparent);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06), 0 0 0 3px rgba(57, 135, 229, 0.12);
}

/* Only shown when the browser offers more than one English voice. */
#credits { font-size: 11px; line-height: 1.55; }

/* Inside one industry: a heading, then one card per job type, ranked by pay.
   Each card is photo on top (a real <img>, locked to 16:9 so it can never be
   stretched into a portrait slit), then the figures. */
.bd-head {
  grid-column: 1 / -1;
  font: 600 clamp(17px, 1.7vw, 21px)/1.25 var(--ff-display);
  color: var(--ink); letter-spacing: -0.02em;
  padding-top: 6px;
}
.bd-head .sub { display: block; margin-top: 6px; font-size: 13px; color: var(--muted); font-weight: 400; letter-spacing: 0; }

.bdc {
  display: flex;
  flex-direction: column;
  align-self: start;               /* never stretched to a taller neighbour */
  min-width: 0;
  border: 1px solid var(--card-line);
  border-radius: 14px;
  background: var(--card);
  box-shadow: var(--lift);
  overflow: hidden;
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
.bdc:hover { border-color: var(--line-2); box-shadow: var(--lift-hi); }
.bdc.me { border-color: color-mix(in srgb, var(--blue) 45%, transparent); background: color-mix(in srgb, var(--blue) 8%, var(--card)); }

.bdc-ph {
  position: relative;
  margin: 0;
  width: 100%;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--surface-2);
  flex: none;
}
.bdc-ph img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 0.3s ease;
}
/* a soft dark fade at the foot of the photo, so it sits on the card */
.bdc-ph::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 45%;
  background: linear-gradient(180deg, transparent, rgba(12, 15, 21, 0.55));
  pointer-events: none;
}
.bdc:hover .bdc-ph img { transform: scale(1.04); }

.bdc-body { padding: 14px 16px 14px; }
.bdc-h { display: flex; gap: 12px; align-items: baseline; justify-content: space-between; }
.bdc-n { font: 600 15px/1.3 var(--ff-display); color: var(--ink); min-width: 0; }
.bdc-n b { font-size: 10.5px; letter-spacing: 0.07em; text-transform: uppercase; color: var(--blue); font-weight: 700; }
.bdc-w { font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.bdc-blurb { margin: 6px 0 10px; font-size: 12.5px; color: var(--muted); line-height: 1.45; }
.bdc-bar { height: 5px; margin: 9px 0 12px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.bdc-bar i { display: block; height: 100%; background: var(--blue); border-radius: 3px; }
.bdc-k { margin-bottom: 10px; }
.bdc-k .kpi { padding: 8px 10px; }
.bdc-k .kpi .v { font-size: 15px; }
.bdc-s { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.bdc-s .spark-box { margin: 0; }
@media (prefers-reduced-motion: reduce) { .bdc:hover .bdc-ph img { transform: none; } }

/* The industry portrait: a real photograph per industry named in the beat.
   Several industries means several images, all the same size, in one row. */
/* 🚨 The photographs live in the SIDE PANEL, one per row, and the panel
   scrolls. Four earlier placements and what each got wrong:
     side panel, side by side  ->  100px wide each: a thumbnail of a thumbnail
     side panel, stacked, tall ->  legible, but it pushed the prose off screen
                                   because the panel did not really scroll
     strip under the player    ->  `height: 14vh` + `width: 100%` gave a 4:1
                                   letterbox slit: you could not see the person
     strip, sized by height    ->  legible, but beside the story rather than
                                   with it, and it cost the chart 190px
   This is the fifth and it is what was asked for: keep them beside the text,
   full width of the column, and let the column scroll. `.p-side` already has
   `overflow-y: auto` and `justify-content: safe center`, so as soon as the
   content is taller than the panel it aligns to the top and every part of it
   is reachable. */
.p-art { display: grid; gap: 12px; }
.p-art[hidden] { display: none; }
.p-art figure {
  margin: 0; min-width: 0; position: relative;
  animation: artIn 0.6s cubic-bezier(0.2, 0.8, 0.25, 1) backwards;
}
.p-art img {
  display: block; width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 38%;   /* people are in the upper half of a frame */
  border-radius: 12px; border: 1px solid var(--line);
  background: var(--surface-2);
}
.p-art figcaption {
  position: absolute; left: 10px; bottom: 10px;
  background: rgba(10, 12, 15, 0.78);
  color: #fff;
  font-size: 12px; font-weight: 600; letter-spacing: 0.02em;
  padding: 4px 10px;
  border-radius: 6px;
  max-width: calc(100% - 20px);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  backdrop-filter: blur(4px);
}
.p-art figcaption .p-art-sub {
  font-weight: 500; color: rgba(255, 255, 255, 0.82);
  margin-left: 6px;
  padding-left: 6px;
  border-left: 1px solid rgba(255, 255, 255, 0.3);
}
@keyframes artIn { from { opacity: 0; transform: translateY(12px) scale(0.96); } }
@media (prefers-reduced-motion: reduce) { .p-art figure { animation: none; } }

/* The panel now scrolls on purpose, so say so: a thicker rail than the page's
   hairline one, and a hint that there is more under the fold. */
.p-side::-webkit-scrollbar { width: 10px; }
.p-side::-webkit-scrollbar-thumb {
  background: rgba(255, 255, 255, 0.16); border-radius: 6px;
  border: 3px solid transparent; background-clip: content-box;
}
.p-side::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.28); background-clip: content-box; }

/* Auto: the story plays itself, each step waiting for the narration to end. */
.p-auto { width: auto; gap: 8px; padding: 0 14px; grid-auto-flow: column; }
.p-auto-l { font-size: 13px; font-weight: 500; letter-spacing: 0.01em; }
.p-auto .i-pause { display: none; }
.p-auto[aria-pressed="true"] .i-play { display: none; }
.p-auto[aria-pressed="true"] .i-pause { display: inline; }
@media (max-width: 620px) { .p-auto-l { display: none; } }

/* The closing chapter is one wide card under the grid of nine, and it is meant
   to be the thing you notice on the page. */
.finale { margin-top: 16px; }
/* The capstone: the chapter that turns the evidence into what to do. It is the
   one high-contrast card on the page. */
.finale > .card:last-child {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 22px;
  align-items: center;
  padding: 30px 28px;
  border-color: color-mix(in srgb, var(--blue) 55%, transparent);
  background:
    radial-gradient(120% 180% at 0% 0%, color-mix(in srgb, var(--blue) 24%, transparent), transparent 62%),
    radial-gradient(90% 120% at 100% 100%, color-mix(in srgb, var(--aqua) 10%, transparent), transparent 60%),
    #152035;
  box-shadow: var(--lift), 0 0 0 1px color-mix(in srgb, var(--blue) 18%, transparent),
              0 20px 60px -20px rgba(57, 135, 229, 0.45);
}
.finale > .card:last-child::after { display: none; }
.finale > .card:last-child .num {
  position: static;
  font: 700 clamp(44px, 6vw, 76px)/1 var(--ff-display);
  color: color-mix(in srgb, var(--blue) 75%, white);
  grid-row: 1 / span 3;
  letter-spacing: -0.04em;
}
.finale > .card:last-child h3 { font-size: clamp(21px, 2.4vw, 30px); padding-right: 46px; margin: 0; }
.finale > .card:last-child .teaser { margin: 6px 0 0; max-width: 62ch; color: #c3cad6; }
.finale > .card:last-child .who { margin-top: 12px; }
.finale > .card:last-child .go { color: #8fbaf0; }
@media (max-width: 560px) {
  .finale > .card:last-child { grid-template-columns: 1fr; gap: 2px; padding: 24px 20px; }
  .finale > .card:last-child .num { grid-row: auto; }
}
.p-voice .wave1, .p-voice .wave2 { opacity: 0.35; }
.p-voice[aria-pressed="true"] .wave1, .p-voice[aria-pressed="true"] .wave2 { opacity: 1; }
.p-voice.speaking .wave1 { animation: wv 1.3s ease-in-out infinite; }
.p-voice.speaking .wave2 { animation: wv 1.3s ease-in-out 0.18s infinite; }

@keyframes wv {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}

.p-body {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 68fr) minmax(280px, 32fr);
  min-height: 0;
}

.p-chart {
  position: relative;
  min-width: 0;
  min-height: 0;
  overflow: hidden;          /* a stale scene must never spill into the prose */
  padding: 18px 10px 18px var(--gut);
}

.scene-host { position: absolute; inset: 18px 10px 18px var(--gut); }

/* A chapter whose chart is taller than the pane scrolls inside it. The host
   stops being absolutely positioned so its explicit height drives the scroll
   height; everything else about the Scene is unchanged. */
.p-chart.scrolly { overflow-y: auto; overflow-x: hidden; cursor: grab; }
.p-chart.scrolly.grabbing { cursor: grabbing; }
.p-chart.scrolly .scene-host { position: relative; inset: auto; width: 100%; }

.scene { display: block; overflow: visible; }

.scene .tx {
  font-family: var(--ff);
  pointer-events: none;
  paint-order: stroke;
}

.scene .halo {
  paint-order: stroke;
  stroke: var(--surface);
  stroke-width: 3.5px;
  stroke-linejoin: round;
}

.scene .w6 { font-weight: 600; }
.scene .w7 { font-weight: 700; }
.scene .quad { letter-spacing: 0.1em; text-transform: uppercase; font-size: 10px; }

.scene rect, .scene circle { transition: none; }

/* With one short line per beat instead of a paragraph, the panel had far more
   room than content, so the block is centred against the chart rather than
   stranded at the top of an empty column. */
.p-side {
  border-left: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.018), transparent 60%);
  padding: clamp(16px, 3vh, 26px) var(--gut) clamp(16px, 3vh, 26px) 28px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  /* 🚨 `safe` matters. A centred flex column that overflows is clipped at BOTH
     ends and the top is unreachable even with overflow:auto, which is how a
     content-heavy beat came out as "Three rules. Job type," and nothing else.
     `safe center` falls back to flex-start the moment it does not fit. */
  justify-content: center;
  justify-content: safe center;
  gap: clamp(10px, 2.2vh, 18px);
}

.p-side .beat-n { font-family: var(--fm); font-size: 11px; color: var(--muted); letter-spacing: 0.14em; }

/* One short line per beat, so it is set like a headline rather than a
   paragraph. The detail is in the voice, not here. */
.p-text {
  font-family: var(--ff-display);
  font-size: clamp(18px, min(2vw, 3.2vh), 27px);
  line-height: 1.26;
  letter-spacing: -0.02em;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
  text-wrap: balance;
}

.p-stats { display: flex; flex-direction: column; gap: 10px; }

/* On a short screen the two stat cards sit side by side instead of stacked:
   it is the cheapest 100px on the panel, and two figures read fine in a row. */
@media (max-height: 820px) and (min-width: 760px) {
  .p-stats { display: grid; grid-template-columns: 1fr 1fr; align-items: start; }
  .p-stats .stat:only-child { grid-column: 1 / -1; }
}

.stat {
  border-left: 3px solid var(--blue);
  padding: clamp(6px, 1.4vh, 10px) 0 clamp(6px, 1.4vh, 10px) 14px;
  background: linear-gradient(90deg, rgba(255, 255, 255, 0.035), transparent 70%);
}

.stat.orange { border-color: var(--orange); }
.stat.aqua { border-color: var(--aqua); }
.stat.red { border-color: var(--red); }

.stat .l { font-size: 12px; color: var(--muted); letter-spacing: 0.02em; }
/* ⚠️ Sized off height as well as width. Two stat cards at the old size were
   203px of a 590px panel on a 720px laptop. */
.stat .v { font-size: clamp(20px, min(3vw, 3.4vh), 30px); font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.stat .n { font-size: 12.5px; color: var(--ink-2); }

.p-answer {
  position: relative;
  margin-top: 6px;
  border: 1px solid color-mix(in srgb, var(--blue) 50%, transparent);
  border-radius: 14px;
  padding: clamp(10px, 1.8vh, 18px);
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--blue) 20%, transparent), color-mix(in srgb, var(--aqua) 7%, transparent) 70%),
    var(--card);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08),
              0 0 0 3px rgba(57, 135, 229, 0.1),
              0 12px 36px -12px rgba(57, 135, 229, 0.5);
  overflow: hidden;
}
.p-answer::before {
  content: "";
  position: absolute;
  left: 0; top: 0; right: 0;
  height: 2px;
  background: linear-gradient(90deg, var(--blue), transparent 80%);
}

.p-answer .l { color: #8fbaf0; font-size: 11px; letter-spacing: 0.14em; text-transform: uppercase; }
/* ⚠️ Height-aware, like the stat cards: the pivot beats carry the answer AND
   the stats, and on a 720px laptop the pair was the last thing still
   overflowing the side panel. */
.p-answer p { margin: 6px 0 0; font-size: clamp(13px, 1.95vh, 16px); line-height: 1.4; }

.p-bot {
  flex: none;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 12px var(--gut);
  border-top: 1px solid var(--line);
}

.segs { display: flex; gap: 6px; flex: 1; }

.seg {
  position: relative;
  flex: 1;
  height: 4px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.09);
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: background var(--t), height var(--t-fast) var(--ease), box-shadow var(--t);
}
/* a 4px bar is a hard target; the hit area is 20px tall */
.seg::before { content: ""; position: absolute; inset: -8px 0; }
.segs:hover .seg { height: 6px; }

.seg.done { background: rgba(255, 255, 255, 0.3); }
.seg.now { background: var(--blue); box-shadow: 0 0 12px rgba(57, 135, 229, 0.6); }
.seg:hover:not(.now) { background: rgba(255, 255, 255, 0.45); }

.p-hint { color: var(--muted); font-size: 12px; white-space: nowrap; }

/* tooltip shared by every chart */
.tip {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  background: rgba(22, 26, 33, 0.97);
  border: 1px solid var(--line-2);
  border-radius: 12px;
  padding: 10px 13px;
  font-size: 13px;
  line-height: 1.5;
  max-width: 250px;
  overflow: hidden;
  opacity: 0;
  left: 0;
  top: 0;
  transition: opacity 0.14s;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.55);
}

.tip.on { opacity: 1; }
.tip b { display: block; font-size: 14px; margin-bottom: 4px; }
.tip .row { display: flex; justify-content: space-between; gap: 16px; color: var(--ink-2); }
.tip .row b { display: inline; font-size: 13px; color: var(--ink); margin: 0; }

/* ------------------------------------------------------------------ explorer */
.exp-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: center;
  margin-bottom: 26px;
}

/* Desktop dashboard: the controls stay under the nav while you work, and the
   list scrolls on its own beside a detail column that scrolls with the page. */
@media (min-width: 901px) {
  #explore { --stick: 60px; }
  .exp-controls {
    position: sticky;
    top: var(--stick);
    z-index: 20;
    padding: 12px 0;
    background: rgba(17, 21, 28, 0.94);
    /* the bar's background runs edge to edge, the controls stay in the column */
    box-shadow: 0 0 0 100vmax rgba(17, 21, 28, 0.94), 0 14px 22px -14px rgba(0, 0, 0, 0.8);
    clip-path: inset(0 -100vmax -30px);
  }
}

/* An app-style segmented control: a recessed track, the active option a raised
   chip inside it. Neutral on purpose: a data hue here would read as data. */
.seg-ctl {
  display: inline-flex;
  gap: 2px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.28);
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.45);
  max-width: 100%;
}

.seg-ctl button {
  border: 1px solid transparent;
  border-radius: 999px;
  background: transparent;
  color: var(--ink-2);
  padding: 8px 16px;
  font: inherit;
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-fast), color var(--t-fast), box-shadow var(--t-fast), border-color var(--t-fast);
}

.seg-ctl button:hover { color: var(--ink); background: rgba(255, 255, 255, 0.04); }
.seg-ctl button[aria-pressed="true"] {
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.17), rgba(255, 255, 255, 0.1));
  border-color: rgba(255, 255, 255, 0.1);
  color: var(--ink);
  font-weight: 600;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 2px 8px rgba(0, 0, 0, 0.45);
}

.search {
  flex: 1;
  min-width: 200px;
  height: 46px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236e7783' stroke-width='2.2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='M20 20l-3.5-3.5'/%3E%3C/svg%3E") 16px center/17px no-repeat,
    var(--card);
  color: var(--ink);
  font: inherit;
  font-size: 14.5px;
  padding: 0 18px 0 44px;
  box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.3);
  transition: border-color var(--t-fast), box-shadow var(--t-fast), background-color var(--t-fast);
}

.search:hover { border-color: var(--line-2); }
.search::placeholder { color: var(--muted); }
.search:focus {
  outline: none;
  border-color: rgba(57, 135, 229, 0.65);
  box-shadow: 0 0 0 4px rgba(57, 135, 229, 0.16);
}

.exp-grid {
  display: grid;
  grid-template-columns: minmax(0, 35fr) minmax(0, 65fr);
  gap: 20px;
  align-items: start;
}

.exp-list {
  grid-column: 1;
  grid-row: 1 / span 2;
  position: sticky;
  top: calc(60px + 70px + 16px);
  border: 1px solid var(--card-line);
  border-radius: var(--r);
  background: var(--raise), var(--card);
  box-shadow: var(--lift);
  max-height: min(75vh, calc(100dvh - 170px));
  overflow-y: auto;
  overscroll-behavior: contain;
}

.exp-detail { grid-column: 2; grid-row: 1; }

/* The breakdown stacks under the detail in the right-hand column, as a bento
   of cards: as many columns as fit at 300px or more, so two in the desktop
   column and one on a phone. 300, not 260: each card carries five figures,
   two sparklines and a paragraph of advice, which a 260px card turns into a
   tall ribbon of text. */
#exp-breakdown {
  grid-column: 2;
  grid-row: 2;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  gap: 1.25rem;
  align-items: start;
}
#exp-breakdown:empty { display: none; }

.exp-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 14px;
  align-items: center;
  width: 100%;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: transparent;
  color: inherit;
  font: inherit;
  padding: 12px 18px;
  cursor: pointer;
  text-align: left;
  transition: background 0.16s;
}

.exp-row:last-child { border-bottom: 0; }
.exp-row:hover { background: var(--surface-2); }
.exp-row[aria-selected="true"] { background: var(--surface-2); box-shadow: inset 3px 0 0 var(--blue); }
@media (max-width: 620px) {
  .exp-row { grid-template-columns: 1fr auto; }
  .exp-row .val:last-child { display: none; }
}

.exp-row .nm { font-size: 15px; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.exp-row .sub { font-size: 12px; color: var(--muted); }
.exp-row .val { font-family: var(--fm); font-size: 13px; color: var(--ink-2); text-align: right; }
.exp-row .val.pos { color: var(--aqua); }
.exp-row .val.neg { color: var(--red); }

.exp-detail {
  border: 1px solid var(--card-line);
  border-radius: var(--r);
  background: var(--raise), var(--card);
  box-shadow: var(--lift);
  padding: 28px;
}

.exp-detail h3 { font-size: 25px; margin-bottom: 4px; }
.exp-detail .kind { color: var(--muted); font-size: 13px; }
.exp-detail .blurb { color: var(--ink-2); font-size: 15px; margin: 16px 0 0; }

/* Flex, not grid: five tiles in a three-wide grid leave a hole in the last row,
   and the hole shows as an empty box. Flexing lets the last row stretch. */
.kpis {
  display: flex;
  flex-wrap: wrap;
  gap: 1px;
  margin: 22px 0 0;
  background: var(--line);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  overflow: hidden;
}

.kpi { flex: 1 1 108px; background: var(--surface-2); padding: 14px 16px; }
.kpi .l { font-size: 11.5px; color: var(--muted); letter-spacing: 0.04em; }
.kpi .v { font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }
.kpi .v.pos { color: var(--aqua); }
.kpi .v.neg { color: var(--red); }
/* the comparison line under each figure: the average, and which side of it this sits */
.kpi .c { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--ink-2); font-variant-numeric: tabular-nums; line-height: 1.3; }
.kpi .c span { font-size: 9px; margin-right: 2px; }
.kpi .c.up span { color: var(--aqua); }
.kpi .c.down span { color: var(--red); }
.kpi .c.eq span { color: var(--muted); font-size: 11px; }
.bdc-k .kpi .c { font-size: 10.5px; margin-top: 4px; padding-top: 4px; }

.spark-box { margin-top: 22px; }
.spark-box .cap { display: flex; justify-content: space-between; font-size: 12px; color: var(--muted); margin-bottom: 6px; }
.spark-box svg { display: block; width: 100%; height: 92px; }

/* Highlighted advice card. Sits between the KPI grid and the sparklines so
   the reader gets the interpretation before the trend lines, and is coloured
   by the recommendation: aqua for a target worth aiming at, blue for a
   qualifier-heavy target, orange for a stepping stone, red for one to think
   twice about. */
.verdict {
  margin: 18px 0 4px;
  padding: 14px 16px;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--advice) 45%, transparent);
  background: color-mix(in srgb, var(--advice) 12%, var(--surface-1));
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink);
}
.verdict::before {
  content: attr(data-verdict-label);
  display: block;
  font: 700 10.5px/1 var(--fm);
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--advice);
  margin-bottom: 6px;
}
.verdict b { color: var(--ink); }
.verdict.v-aqua   { --advice: var(--aqua);   }
.verdict.v-blue   { --advice: var(--blue);   }
.verdict.v-orange { --advice: var(--orange); }
.verdict.v-red    { --advice: var(--red);    }
.bdc .verdict { margin: 12px 0 12px; padding: 12px 14px; font-size: 13px; }

.tag {
  display: inline-block;
  font-size: 11.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  border: 1px solid var(--line-2);
  border-radius: 999px;
  padding: 3px 11px;
  color: var(--ink-2);
  margin: 12px 8px 0 0;
}

/* ------------------------------------------------------------------ limits */
.limits {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  gap: 16px;
  counter-reset: lim;
}

.limit {
  position: relative;
  border: 1px solid var(--card-line);
  border-radius: var(--r);
  padding: 26px 24px 24px 28px;
  background:
    radial-gradient(120% 90% at 0% 0%, color-mix(in srgb, var(--amber) 7%, transparent), transparent 55%),
    var(--card);
  box-shadow: var(--lift);
  overflow: hidden;
}

.limit::before {
  content: "";
  position: absolute;
  left: 0; top: 0; bottom: 0;
  width: 3px;
  background: linear-gradient(180deg, var(--amber), color-mix(in srgb, var(--amber) 15%, transparent));
}

.limit:hover {
  transform: translateY(-4px);
  border-color: color-mix(in srgb, var(--amber) 40%, transparent);
  box-shadow: var(--lift-hi);
}
.limit:hover::after { opacity: 1; }

.limit h3 { font-size: 18px; letter-spacing: -0.02em; margin-bottom: 10px; }
.limit h3::before {
  counter-increment: lim;
  content: "\26A0\FE0E  Caveat " counter(lim, decimal-leading-zero);
  display: block;
  margin-bottom: 12px;
  font: 500 10.5px/1 var(--fm);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--amber);
}
.limit p { margin: 0; color: var(--ink-2); font-size: 15px; }

/* ------------------------------------------------------------------ footer */
.foot {
  border-top: 1px solid var(--line);
  padding: 56px 0 72px;
  color: var(--muted);
  font-size: 14px;
}

.foot .cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); gap: 26px; }
.foot b { color: var(--ink-2); font-weight: 600; display: block; margin-bottom: 6px; }

/* ------------------------------------------------------------------ reveal */
/* 🚨 The entrance rides on `translate`, hover lifts ride on `transform`. They
   are separate properties, so a card can slide in slowly (0.8s) and still lift
   quickly (0.32s) on hover. With both on `transform`, this rule's single
   transition list overrode every card's hover timing. */
.rv {
  opacity: 0;
  translate: 0 24px;
  transition: opacity 0.8s var(--ease), translate 0.8s var(--ease),
              transform var(--t) var(--ease), border-color var(--t) var(--ease),
              box-shadow var(--t) var(--ease), background-color var(--t);
}
.rv.in { opacity: 1; translate: none; }

/* ------------------------------------------------------------------ narrow */
@media (max-width: 620px) {
  .p-voice-l { display: none; }
  .p-voice, .p-auto { width: 40px; padding: 0; }
  .seg-ctl button { padding: 8px 12px; font-size: 13.5px; }
}

@media (max-width: 900px) {
  .exp-grid { grid-template-columns: 1fr; }
  .exp-list { max-height: 330px; grid-column: 1; grid-row: auto; position: static; }
  .exp-detail { grid-column: 1; grid-row: auto; }
  #exp-breakdown { grid-column: 1; grid-row: auto; }
  .p-hint { display: none; }
}

/* Phone: chart on top at 45% of the screen, the text below it scrolls, the
   controls stay pinned to the bottom edge (the player is a flex column). */
@media (max-width: 767px) {
  .p-body { grid-template-columns: 1fr; grid-template-rows: 45vh minmax(0, 1fr); grid-template-rows: 45dvh minmax(0, 1fr); }
  .p-side { border-left: 0; border-top: 1px solid var(--line); padding: 20px var(--gut) 20px; }
  .p-chart { padding: 10px 6px 10px 6px; }
  .scene-host { inset: 10px 6px 10px 6px; }
  .p-answer { margin-top: 6px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  html { scroll-behavior: auto; }
  .rv { opacity: 1; translate: none; }
  .card:hover, .aud-row:hover, .limit:hover, .icon-btn:hover:not(:disabled) { transform: none; }
}

/* ================================================================== the 5-minute story
   A short film with characters (Mia, Alex) for Assignment 5. Same surfaces,
   same chart engine; its own frame: photo setting, headline, picture,
   subtitles, controls. Character colours: Mia blue, Alex orange, as in the
   Journal 3 empathy map. */

/* the film and the presentation sit side by side in the hero's corner */
.story-btns {
  position: absolute;
  top: clamp(14px, 3vh, 26px);
  right: var(--gut);
  z-index: 4;
  display: flex; gap: 10px; flex-wrap: wrap; justify-content: flex-end;
}
.film-btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 7px 16px 7px 7px;
  border: 1px solid color-mix(in srgb, var(--blue) 45%, transparent);
  border-radius: 999px;
  background: rgba(16, 20, 28, 0.82);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  box-shadow: 0 10px 30px -12px rgba(57, 135, 229, 0.55), inset 0 1px 0 rgba(255, 255, 255, 0.06);
  transition: transform var(--t-fast) var(--ease), border-color var(--t-fast), background var(--t-fast);
}
.film-btn:hover { transform: translateY(-1px); border-color: var(--blue); background: rgba(22, 28, 40, 0.92); }
.film-btn-ic {
  display: grid; place-items: center;
  width: 34px; height: 34px; border-radius: 50%;
  background: var(--blue); color: #fff;
  box-shadow: 0 0 0 0 rgba(57, 135, 229, 0.5);
  animation: filmPulse 2.6s ease-out infinite;
}
@keyframes filmPulse { 0% { box-shadow: 0 0 0 0 rgba(57, 135, 229, 0.5); } 70%, 100% { box-shadow: 0 0 0 12px rgba(57, 135, 229, 0); } }
.film-btn-tx { display: flex; flex-direction: column; line-height: 1.2; }
.film-btn-tx b { font: 700 14px/1.2 var(--ff-display); letter-spacing: -0.01em; }
.film-btn-tx > span { font-size: 11.5px; color: var(--ink-2); }
.film-len { font-family: var(--fm); color: var(--muted); margin-left: 4px; }
/* the presentation button: the same pill, quieter, so the film stays the first choice */
.pres-btn { border-color: var(--line-2); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06); }
.pres-btn .film-btn-ic { background: var(--surface-2); color: var(--ink); animation: none; border: 1px solid var(--line-2); }
.pres-btn:hover { border-color: var(--ink-2); }
/* two pills need room: shed their sub-lines first, then the centred dataset
   pill (the source is still in the footer), before they could touch either */
@media (max-width: 1200px) { .story-btns .film-btn-tx > span { display: none; } }
@media (max-width: 1040px) { .hero-eyebrow { display: none; } }
@media (min-width: 621px) and (max-width: 1040px) { .hero-head { padding-top: 60px; } }   /* the pills take the pill's row */
/* On a phone the head is one column wide, so the button takes the dataset
   pill's corner instead of landing on the headline; the source is still in the
   footer. */
@media (max-width: 620px) {
  .hero-eyebrow { display: none; }
  .hero-head { padding-top: 46px; }
  .story-btns { left: var(--gut); right: auto; top: 16px; justify-content: flex-start; gap: 8px; }
  .film-btn { padding: 5px 12px 5px 5px; gap: 8px; }
  .film-btn-ic { width: 28px; height: 28px; }
  .film-btn-tx b { font-size: 12.5px; }
  .film-btn-tx > span { display: none; }
}

.nav-film {
  display: inline-flex; align-items: center; gap: 7px;
  margin-left: 6px; padding: 7px 13px;
  border: 1px solid color-mix(in srgb, var(--blue) 45%, transparent);
  border-radius: 999px; background: color-mix(in srgb, var(--blue) 14%, transparent);
  color: var(--ink); font: 600 13px/1 var(--ff); cursor: pointer; white-space: nowrap;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.nav-film:hover { background: color-mix(in srgb, var(--blue) 24%, transparent); border-color: var(--blue); }
@media (max-width: 620px) { .nav-film span { display: none; } .nav-film { padding: 9px; } }
@media (max-width: 360px) { .nav-film { display: none; } }   /* the hero button is still there */
.nav-pres { margin-left: 4px; border-color: var(--line-2); background: var(--chip, rgba(255, 255, 255, 0.05)); }
.nav-pres:hover { border-color: var(--ink-2); background: rgba(255, 255, 255, 0.09); }

/* ---- presentation mode: the film's frame, no voice, a click per step ---- */
.film.present { cursor: pointer; }
.film.present button, .film.present a, .film.present .film-bot, .film.present .film-top { cursor: auto; }
.film.present button { cursor: pointer; }
.film.present .film-play { display: none; }
.film.present .film-cap { visibility: hidden; }
.film.present.notes .film-cap {
  visibility: visible; text-align: left; font-size: clamp(13px, 1.25vw, 15px); color: var(--ink-2);
  max-width: min(110ch, calc(100% - 2 * var(--gut))); max-height: 7.2em; overflow-y: auto;
  padding: 8px 14px; border-left: 3px solid var(--amber, #e0a33a); background: rgba(8, 10, 14, 0.7); border-radius: 6px;
}
.film.present .f-col:hover, .film.present .f-jc:hover, .film.present .f-rule:hover, .film.present .f-castcard:hover {
  border-color: rgba(255, 255, 255, 0.35);
}
.film.present .f-jc:hover, .film.present .f-col:hover { translate: 0 -4px; }
.present-hint { font: 500 11.5px/1 var(--fm); color: var(--muted); letter-spacing: 0.04em; }
.film:not(.present) .present-hint { display: none; }
@media (max-width: 620px) { .present-hint { display: none; } }

.film {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: grid;
  grid-template-rows: auto auto minmax(0, 1fr) auto auto;
  background: var(--surface);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0s 0.5s;
  overflow: hidden;
}
.film.on { opacity: 1; visibility: visible; transition: opacity 0.5s var(--ease), visibility 0s; }

/* the setting: a photograph behind everything, slowly drifting (Ken Burns) */
.film-bg { position: absolute; inset: 0; opacity: 0; transition: opacity 0.9s var(--ease); pointer-events: none; }
.film-bg.on { opacity: 1; }
.film-bg img { width: 100%; height: 100%; object-fit: cover; object-position: center 45%; opacity: 0.85; }
.film-bg.kb img { animation: kenBurns 26s ease-out both; }
@keyframes kenBurns { from { transform: scale(1); } to { transform: scale(1.06) translate(-1%, -0.6%); } }
.film-bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(10, 12, 16, 0.82) 0%, rgba(10, 12, 16, 0.12) 34%, rgba(10, 12, 16, 0.18) 64%, rgba(10, 12, 16, 0.9) 100%);
}

.film-top, .film-head, .film-visual, .film-cap, .film-bot { position: relative; z-index: 2; }

/* Footage, documentary style: each roll is a layer wiped across the frame,
   with a slow push-in for its whole voice-over and a lower-third label. The
   narration subtitles keep running on top. Leaving footage for a slide zooms
   through a fade, so the slide's own entrance is what you see. */
.film-cut {
  position: absolute; inset: 0; z-index: 1;
  opacity: 0; transform: scale(1.05); pointer-events: none;
  transition: opacity 0.7s var(--ease), transform 0.9s var(--ease);
  background: #000;
}
.film-cut.on { opacity: 1; transform: none; transition: opacity 0.15s linear, transform 0.9s var(--ease); }
.fc-layer {
  position: absolute; inset: 0; display: grid; grid-template-columns: 1fr; background: #000;
  clip-path: inset(0 0 0 100%);
  transition: clip-path 0.85s cubic-bezier(0.77, 0, 0.18, 1);
}
.fc-layer.in { clip-path: inset(0 0 0 0); }
.fc-layer.two { grid-template-columns: 1fr 1fr; gap: 3px; }
.fc-pane { position: relative; margin: 0; overflow: hidden; min-width: 0; }
.fc-pane video, .fc-pane img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* photos drift in slowly; video is never scaled, an upscaled frame is a soft frame */
.fc-layer.in .fc-pane img { animation: pushIn var(--dur, 6s) linear both; }
@keyframes pushIn { from { transform: scale(1.06); } to { transform: scale(1); } }
/* shade only the top (headline bar) and the bottom (subtitles, controls) */
.fc-pane::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(10, 12, 16, 0.6) 0%, rgba(10, 12, 16, 0) 24%, rgba(10, 12, 16, 0) 62%, rgba(10, 12, 16, 0.82) 100%);
}
/* lower third: a label bar that slides in after the wipe */
.fc-pane figcaption {
  position: absolute; left: var(--gut); top: clamp(64px, 11vh, 96px); z-index: 1;
  display: inline-flex; align-items: center; gap: 10px;
  max-width: calc(100% - 2 * var(--gut));
  padding: 9px 16px 9px 14px; border-radius: 4px;
  background: rgba(8, 10, 14, 0.78); border-left: 3px solid var(--blue);
  font: 700 clamp(14px, min(1.6vw, 2.6vh), 21px)/1.25 var(--ff-display); letter-spacing: -0.005em; color: #fff;
  animation: lowerIn 0.6s var(--ease) 0.75s both;
}
@keyframes lowerIn { from { opacity: 0; translate: -18px 0; } to { opacity: 1; translate: none; } }
.fc-layer.two .fc-pane figcaption { font-size: clamp(13px, min(1.3vw, 2.2vh), 17px); }
/* portrait screens stack a pair of clips, so neither is cropped to a sliver */
@media (max-aspect-ratio: 1/1) {
  .fc-layer.two { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .fc-layer.two .fc-pane:last-child figcaption { top: 12px; }
}
.film-head, .film-visual { transition: opacity 0.45s var(--ease); }
.film.cutting .film-head, .film.cutting .film-visual { opacity: 0; }
/* over footage the subtitle sits on a soft bar, like a broadcast caption */
.film.cutting .film-cap { color: #fff; }
.film.cutting .film-cap:not(:empty) {
  width: max-content; max-width: min(68ch, calc(100% - 2 * var(--gut)));
  padding: 8px 16px; border-radius: 8px; background: rgba(8, 10, 14, 0.66);
}

/* act title card: a dip to near black, the act numeral, a rule that draws */
.film-sting {
  position: absolute; inset: 0; z-index: 3; pointer-events: none;
  display: grid; place-items: center;
  background: radial-gradient(ellipse at center, rgba(14, 18, 26, 0.94), rgba(6, 8, 11, 0.98));
  opacity: 0; transition: opacity 0.45s var(--ease);
}
.film-sting.on { opacity: 1; transition-duration: 0.3s; }
.fs-in { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.fs-num { font: 800 clamp(56px, 9vw, 120px)/1 var(--ff-display); letter-spacing: -0.04em; color: rgba(255, 255, 255, 0.9); }
.fs-rule { width: clamp(80px, 12vw, 160px); height: 2px; background: var(--blue); transform-origin: center; }
.fs-t { font: 600 clamp(13px, 1.4vw, 17px)/1 var(--fm); letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-2); }
.film-sting.on .fs-num { animation: stingNum 1.6s var(--ease) both; }
.film-sting.on .fs-rule { animation: stingRule 0.9s var(--ease) 0.2s both; }
.film-sting.on .fs-t { animation: filmIn 0.7s var(--ease) 0.35s both; }
@keyframes stingNum { from { opacity: 0; transform: scale(1.18); } 35% { opacity: 1; } to { transform: scale(1); } }
@keyframes stingRule { from { transform: scaleX(0); } }
.film-top, .film-bot { z-index: 4; }

.film-top { display: flex; align-items: center; gap: 14px; padding: 14px var(--gut) 0; }
.film-act {
  font: 600 11px/1 var(--fm); letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--ink-2); padding: 7px 12px; border: 1px solid var(--line-2); border-radius: 999px;
  background: rgba(10, 12, 16, 0.5);
}
.film-time { margin-left: auto; font-size: 12px; color: var(--ink-2); }
.film-fs .fs-out, .film.fs .film-fs .fs-in { display: none; }
.film.fs .film-fs .fs-out { display: inline; }

.film-head { padding: clamp(10px, 2.4vh, 26px) var(--gut) 0; }
.film-head h2 {
  font-size: clamp(24px, min(3.3vw, 5vh), 46px);
  letter-spacing: -0.035em; line-height: 1.08; max-width: 28ch;
}
.film-head h2.in { animation: filmIn 0.7s var(--ease) both; }
@keyframes filmIn { from { opacity: 0; translate: 0 14px; } to { opacity: 1; translate: none; } }

.film-visual { min-height: 0; margin: clamp(8px, 2vh, 18px) 0 0; }
.film-chart { position: absolute; inset: 0 var(--gut) 0 var(--gut); }
.film-chart[hidden] { display: none; }
.film-card {
  position: absolute; inset: 0 var(--gut);
  display: flex; align-items: center; justify-content: center;
  pointer-events: none;
}
.film-card > * { pointer-events: auto; }
.film-card.in > * { animation: filmIn 0.8s var(--ease) 0.1s both; }

.film-cap {
  margin: 10px auto 0; padding: 0 var(--gut);
  max-width: 68ch; min-height: 4.7em;          /* three lines: a longer subtitle never resizes the chart mid-beat */
  text-align: center; color: var(--ink);
  font-size: clamp(14px, min(1.5vw, 2.3vh), 18px); line-height: 1.55;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
}

.film-bot { display: flex; align-items: center; gap: 12px; padding: 12px var(--gut) clamp(12px, 2.4vh, 22px); }
.film-play .i-play { display: none; }
.film.paused .film-play .i-play { display: block; }
.film.paused .film-play .i-pause { display: none; }
.icon-btn.film-play { background: var(--ink); color: var(--surface); border-color: transparent; }
.icon-btn.film-play:hover:not(:disabled) { background: #fff; color: var(--surface); }
.film-segs { flex: 1; display: flex; gap: 4px; }
.fseg { position: relative; height: 4px; padding: 0; border: 0; border-radius: 2px; background: rgba(255, 255, 255, 0.12); cursor: pointer; overflow: visible; }
.fseg::before { content: ""; position: absolute; inset: -8px 0; }
.fseg i { display: block; height: 100%; width: 0; border-radius: 2px; background: var(--who, var(--blue)); }
.fseg.now { box-shadow: 0 0 10px color-mix(in srgb, var(--who, var(--blue)) 55%, transparent); }

/* ---- the compositions ---- */

.f-hook { text-align: center; }
.f-big {
  font: 800 clamp(84px, min(16vw, 24vh), 220px)/0.95 var(--ff-display); letter-spacing: -0.05em;
  background: linear-gradient(180deg, #fff, #9fb6d6); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
}
.f-sub { margin-top: 10px; font: 500 13px/1 var(--fm); letter-spacing: 0.16em; text-transform: uppercase; color: var(--ink-2); }

.f-cast { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(14px, 2.4vw, 32px); width: min(1040px, 100%); }
.film-card.in > .f-cast { animation: none; }
.f-castcard {
  display: flex; align-items: flex-start; gap: clamp(14px, 2vw, 24px);
  padding: clamp(16px, 2.6vh, 28px) clamp(16px, 2.2vw, 28px);
  border: 1px solid color-mix(in srgb, var(--c) 40%, transparent); border-top: 3px solid var(--c);
  border-radius: var(--r-lg); background: rgba(12, 15, 21, 0.8);
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.9);
  animation: filmIn 0.8s var(--ease) var(--d) both;
}
.f-castcard .fa { flex: none; width: clamp(56px, 9vh, 92px); height: auto; }
/* the cast: a face on video first, the facts underneath */
.f-castcard.f-person2 { flex-direction: column; align-items: stretch; gap: 0; padding: 0; overflow: hidden; transition: box-shadow 0.3s var(--ease), translate 0.3s var(--ease); }
.f-castv { margin: 0; aspect-ratio: 16 / 9; max-height: 30vh; overflow: hidden; background: #000; }
.f-castv video { width: 100%; height: 100%; object-fit: cover; display: block; }
.f-castmeta { padding: clamp(10px, 1.8vh, 18px) clamp(14px, 1.8vw, 22px) clamp(12px, 2vh, 20px); }
.f-castmeta .f-name { font-size: clamp(22px, 2.6vw, 36px); }
.f-castcard.f-person2.on { translate: 0 -4px; box-shadow: 0 24px 60px -24px color-mix(in srgb, var(--c) 75%, transparent); }
.f-face { border-radius: 50%; object-fit: cover; border: 3px solid var(--c); }
/* the persona dock in the control bar: a face lights while the voice talks about that person */
.film-dock { display: flex; gap: 8px; align-items: center; }
.film.nodock .film-dock { visibility: hidden; }
.fd { position: relative; display: block; width: 40px; height: 40px; border-radius: 50%; opacity: 0.4; filter: none; transition: opacity 0.25s var(--ease), transform 0.25s var(--ease), box-shadow 0.25s var(--ease); }
.fd img { width: 100%; height: 100%; border-radius: 50%; object-fit: cover; border: 2px solid rgba(255, 255, 255, 0.25); display: block; }
.fd b { position: absolute; left: 50%; bottom: calc(100% + 6px); translate: -50% 0; padding: 3px 8px; border-radius: 999px; background: var(--c); color: #fff; font: 700 11px/1 var(--ff); white-space: nowrap; opacity: 0; transition: opacity 0.25s var(--ease); }
.fd.on { opacity: 1; transform: scale(1.18); box-shadow: 0 0 0 3px var(--c), 0 0 22px color-mix(in srgb, var(--c) 70%, transparent); }
.fd.on img { border-color: transparent; }
.fd.on b { opacity: 1; }
.f-name { font: 800 clamp(26px, 3.2vw, 44px)/1 var(--ff-display); letter-spacing: -0.04em; color: var(--c, var(--ink)); }
.f-role { margin-top: 8px; font-size: clamp(13px, 1.3vw, 16px); color: var(--ink-2); }
.f-need {
  display: inline-block; margin-top: 12px; padding: 6px 12px; border-radius: 999px;
  background: color-mix(in srgb, var(--c) 22%, transparent); color: color-mix(in srgb, var(--c) 55%, white);
  font: 700 clamp(13px, 1.3vw, 16px)/1 var(--ff-display); letter-spacing: -0.01em;
}
.f-traits { list-style: none; padding: 0; margin: 12px 0 0; display: flex; flex-wrap: wrap; gap: 6px; }
.f-traits li { padding: 5px 10px; border-radius: 999px; background: rgba(255, 255, 255, 0.07); border: 1px solid var(--line); font-size: 12.5px; color: var(--ink); }
.f-job { margin-top: 12px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }
.f-job b { font: 700 clamp(15px, 1.5vw, 19px)/1.2 var(--ff-display); }
.f-job span { font-size: 13px; color: var(--aqua); font-variant-numeric: tabular-nums; }
.f-dec { margin: 12px 0 0; max-width: 36ch; font: 600 clamp(15px, 1.6vw, 21px)/1.35 var(--ff-display); letter-spacing: -0.02em; color: var(--ink); }




.f-rules { list-style: none; margin: 0; padding: 0; width: min(900px, 100%); display: grid; gap: clamp(10px, 2vh, 18px); }
.f-rule {
  display: flex; align-items: flex-start; gap: clamp(14px, 2vw, 22px);
  padding: clamp(12px, 2.2vh, 20px) clamp(14px, 2vw, 24px);
  border: 1px solid var(--line); border-radius: var(--r); background: rgba(12, 15, 21, 0.7);
  opacity: 0.38; transition: opacity 0.25s var(--ease), border-color 0.25s var(--ease), translate 0.25s var(--ease);
}
.f-rule.on { opacity: 1; border-color: color-mix(in srgb, var(--blue) 60%, transparent); translate: 6px 0; }
.f-rule > b {
  flex: none; display: grid; place-items: center; width: 2em; height: 2em; border-radius: 50%;
  background: var(--blue); color: #fff; font: 800 clamp(15px, 1.6vw, 20px)/1 var(--ff-display);
}
.f-rule strong { display: block; font: 700 clamp(17px, 2vw, 26px)/1.2 var(--ff-display); letter-spacing: -0.02em; }
.f-rule span { display: block; margin-top: 5px; font-size: clamp(13px, 1.3vw, 16px); color: var(--ink-2); }

/* three needs, three top threes: a column lights as the voice names it */
.f-cols { width: min(1100px, 100%); display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(10px, 1.6vw, 20px); }
.f-col {
  border: 1px solid var(--line); border-radius: var(--r-lg); overflow: hidden; background: rgba(12, 15, 21, 0.85);
  opacity: 0.38; transition: opacity 0.25s var(--ease), border-color 0.25s var(--ease), translate 0.25s var(--ease);
}
.f-col.on { opacity: 1; border-color: color-mix(in srgb, var(--blue) 70%, transparent); translate: 0 -4px; box-shadow: 0 20px 50px -24px rgba(57, 135, 229, 0.55); }
.f-colph { position: relative; margin: 0; aspect-ratio: 16 / 8; overflow: hidden; }
.f-colph img { width: 100%; height: 100%; object-fit: cover; display: block; }
.f-colph::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(10, 12, 16, 0) 40%, rgba(10, 12, 16, 0.9)); }
.f-colph span { position: absolute; left: 14px; bottom: 10px; z-index: 1; font: 700 clamp(15px, 1.6vw, 21px)/1.1 var(--ff-display); color: #fff; letter-spacing: -0.01em; }
.f-col ol { list-style: none; margin: 0; padding: 10px 14px 4px; display: grid; gap: 8px; }
.f-col li { display: grid; grid-template-columns: 1.5em minmax(0, 1fr) auto; grid-template-areas: "i n v" "i b b"; align-items: center; gap: 2px 8px; }
.f-ci { grid-area: i; font-size: 18px; text-align: center; }
.f-cn { grid-area: n; font: 600 clamp(13px, 1.2vw, 15px)/1.2 var(--ff); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.f-col li b { grid-area: v; font: 700 clamp(12.5px, 1.15vw, 14.5px)/1 var(--ff-display); font-variant-numeric: tabular-nums; }
.f-cb { grid-area: b; height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.f-cb i { display: block; height: 100%; border-radius: 3px; background: var(--blue); }
.f-col li:first-child .f-cn, .f-col li:first-child b { color: #fff; }
.f-col li:first-child .f-cb i { background: var(--aqua); }
.f-col p { margin: 4px 14px 12px; font-size: 12px; color: var(--ink-2); }

/* the corner's strongest job types as photo cards; each measure's winner is bolded in aqua */
.f-jcards { width: min(1180px, 100%); display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(8px, 1.2vw, 14px); }
.f-jc {
  border: 1px solid var(--line); border-radius: var(--r); overflow: hidden; background: rgba(12, 15, 21, 0.88);
  transition: opacity 0.3s var(--ease), border-color 0.3s var(--ease), translate 0.3s var(--ease), box-shadow 0.3s var(--ease);
}
.f-jc figure { position: relative; margin: 0; aspect-ratio: 16 / 10; overflow: hidden; }
.f-jc img { width: 100%; height: 100%; object-fit: cover; display: block; }
.f-jtags { position: absolute; left: 8px; top: 8px; display: flex; flex-wrap: wrap; gap: 4px; }
.f-jt { padding: 4px 8px; border-radius: 999px; background: var(--aqua); color: #04150f; font: 800 11px/1 var(--ff); }
.f-jc .f-forwho { position: absolute; right: 8px; bottom: 8px; display: none; padding: 4px 10px; border-radius: 999px; background: var(--c); color: #fff; font: 800 12px/1 var(--ff); }
.f-jn { padding: 10px 12px 6px; font: 700 clamp(13.5px, 1.25vw, 16px)/1.2 var(--ff-display); min-height: 2.6em; }
.f-jm { display: grid; grid-template-columns: 3.6em minmax(0, 1fr) auto; align-items: center; gap: 6px; padding: 3px 12px; font-size: 12px; color: var(--ink-2); }
.f-jm b { font: 600 12.5px/1 var(--ff-display); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.f-jb { height: 6px; border-radius: 3px; background: rgba(255, 255, 255, 0.07); overflow: hidden; }
.f-jb i { display: block; height: 100%; border-radius: 3px; background: #5f6877; }
.f-jm.best { color: var(--ink); }
.f-jm.best b { font-weight: 800; font-size: 14px; color: var(--aqua); }
.f-jm.best .f-jb i { background: var(--aqua); }
.f-jc > :last-child { padding-bottom: 12px; }
.f-jc.on { border-color: var(--c); translate: 0 -6px; box-shadow: 0 22px 50px -22px color-mix(in srgb, var(--c) 70%, transparent); }
.f-jc.on .f-forwho { display: inline-block; }
.f-jc.off { opacity: 0.32; }

/* footage behind a card slide, or two clips side by side */
.film-bgv { position: absolute; inset: 0; display: grid; }
.film-bgv.two { grid-template-columns: 1fr 1fr; gap: 3px; }
.film-bgv video { width: 100%; height: 100%; object-fit: cover; display: block; opacity: 0.6; }
.film-bg.vid img { display: none; }
@media (max-aspect-ratio: 1/1) { .film-bgv.two { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; } }

.f-end { text-align: center; max-width: 760px; }
.f-actions { margin-top: 22px; display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.f-go, .f-go2 { padding: 11px 18px; border-radius: 999px; font: 600 14px/1 var(--ff); cursor: pointer; transition: transform var(--t-fast), background var(--t-fast); }
.f-go { border: 0; background: var(--ink); color: var(--surface); }
.f-go:hover { background: #fff; transform: translateY(-1px); }
.f-go2 { border: 1px solid var(--line-2); background: var(--chip); color: var(--ink); }
.f-go2:hover { background: var(--chip-hi); }
.f-credits { margin: 20px auto 0; font-size: 11px; line-height: 1.5; color: var(--muted); max-width: 70ch; }

@media (max-width: 760px) {
  .f-cast { grid-template-columns: 1fr; gap: 10px; }
  .f-castv { max-height: 15vh; }
  .fd { width: 30px; height: 30px; }
  .film-dock { gap: 5px; }
  .f-castcard { padding: 12px 14px; }
  .f-traits { display: none; }
  .f-rules { gap: 8px; }
  .f-rule { padding: 10px 12px; gap: 10px; }
  .f-rule > b { width: 1.7em; height: 1.7em; font-size: 14px; }
  .f-rule strong { font-size: 15.5px; }
  .f-rule span { font-size: 12.5px; line-height: 1.4; margin-top: 3px; }
  .f-cols { grid-template-columns: 1fr; gap: 8px; }
  .f-colph { aspect-ratio: auto; height: 34px; }
  .f-colph span { bottom: 8px; font-size: 14px; }
  .f-col ol { padding: 6px 12px 2px; gap: 4px; }
  .f-col li { grid-template-areas: "i n v"; }
  .f-cb { display: none; }
  .f-col p { display: none; }
  .f-jcards { grid-template-columns: 1fr; gap: 6px; }
  .f-jc { display: grid; grid-template-columns: 1fr auto auto auto; align-items: center; }
  .f-jc figure { display: none; }
  .f-jn { padding: 8px 10px; min-height: 0; font-size: 13px; }
  .f-jm { display: block; padding: 0 8px 0 0; }
  .f-jm > span:first-child, .f-jb { display: none; }
  .f-jc > :last-child { padding-bottom: 0; }
  .film[data-kind="chart"] .film-card { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .film-bg.kb img, .film-btn-ic, .fc-pane video, .fc-pane img { animation: none !important; }
  .fc-layer { transition: none; }
}
