/* Shivraj Singh — event loop. Tokens only; literals live in variables.css. */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background: var(--ev-navy-950);
  font-family: var(--ev-sans);
  cursor: default;
}
body.cursor-idle { cursor: none; }

#stage { position: absolute; inset: 0; display: grid; place-items: center; }

#frame {
  position: relative;
  width: 100vw;
  height: 56.25vw;
  max-height: 100vh;
  max-width: 177.78vh;
  overflow: hidden;
  background: var(--ev-navy-900);
}

/* ============================================================
   Slide plumbing — the engine drives transitions with JS-set
   styles; these classes only define resting states.
   ============================================================ */
.slide {
  position: absolute;
  inset: 0;
  display: none;
  opacity: 0;
  overflow: hidden;
}
.slide.active   { display: flex; opacity: 1; z-index: var(--ev-z-active); }
.slide.exiting  { display: flex; z-index: var(--ev-z-slide); }
.slide.entering { display: flex; z-index: var(--ev-z-incoming); }

/* ============================================================
   Entrance choreography — [data-animate] children start hidden,
   the slide's .choreo-in reveals them; stagger via --d.
   ============================================================ */
[data-animate] {
  opacity: 0;
  transform: translate3d(0, 2.2vw, 0);
  transition:
    opacity var(--ev-d-entrance) var(--ev-ease-expo),
    transform var(--ev-d-entrance) var(--ev-ease-expo);
  transition-delay: var(--d, 0ms);
  will-change: opacity, transform;
}
[data-animate="left"]  { transform: translate3d(-3vw, 0, 0); }
[data-animate="right"] { transform: translate3d(3vw, 0, 0); }
[data-animate="scale"] { transform: scale(0.92); }
[data-animate="rise"]  { transform: translate3d(0, 6vw, 0); }
.slide.choreo-in [data-animate] {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

/* Draw-in rules: scaleX from 0 */
[data-animate="draw"] {
  transform: scaleX(0);
  transform-origin: left center;
}
.slide.choreo-in [data-animate="draw"] { transform: scaleX(1); }

/* ============================================================
   Animated emphasis — key words get a slow gold shimmer sweep;
   .u-draw gets an underline that draws itself after entrance.
   ============================================================ */
.shimmer {
  background: linear-gradient(100deg,
    var(--ev-gold-400) 0%, var(--ev-gold-100) 46%,
    var(--ev-gold-400) 55%, var(--ev-gold-400) 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmerSweep 7s var(--ev-ease-smooth) infinite;
}
@keyframes shimmerSweep {
  0%, 55%  { background-position: 110% 0; }
  85%, 100% { background-position: -60% 0; }
}
/* Draw-on emphasis box: an SVG rect sketches itself around a key
   phrase after the text lands. Delay tiers via .bd-1/.bd-2/.bd-3. */
.box-draw {
  position: relative;
  display: inline-block;
}
.box-draw > svg {
  position: absolute;
  inset: -0.18em -0.35em;
  width: calc(100% + 0.7em);
  height: calc(100% + 0.36em);
  overflow: visible;
  pointer-events: none;
}
.box-draw rect {
  width: 100%;
  height: 100%;
  fill: none;
  stroke: var(--ev-gold-500);
  stroke-width: 0.09em;
  rx: 0.22em;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.box-draw.box-crimson rect { stroke: var(--ev-crimson-400); }
.slide.choreo-in .box-draw rect {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1200ms var(--ev-ease-smooth) var(--bd, 1200ms);
}
.box-draw.bd-1 { --bd: 1100ms; }
.box-draw.bd-2 { --bd: 1700ms; }
.box-draw.bd-3 { --bd: 3400ms; }

.u-draw {
  position: relative;
}
.u-draw::after {
  content: "";
  position: absolute;
  left: 0; right: 0;
  bottom: -0.35vw;
  height: var(--ev-r-med);
  background: var(--ev-gold-500);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1200ms var(--ev-ease-expo) 1100ms;
}
.slide.choreo-in .u-draw::after { transform: scaleX(1); }

/* ============================================================
   Ambient drift — every dark slide's glow layer slowly wanders,
   so no card ever sits perfectly still.
   ============================================================ */
.drift {
  animation: ambientDrift 18s var(--ev-ease-smooth) infinite alternate;
}
@keyframes ambientDrift {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-3vw, 2vw, 0) scale(1.06); }
}

/* ============================================================
   Ambient floaters — persistent slow-wandering shapes so no
   message slide is ever static. Gold on dark slides, navy on
   paper. Transform-only, cheap to composite.
   ============================================================ */
.amb {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.amb > i {
  position: absolute;
  left: var(--ax, 50%);
  top: var(--ay, 50%);
  display: block;
  animation: ambDrift var(--adur, 40s) var(--ev-ease-smooth) infinite;
  animation-delay: var(--adel, 0s);
  will-change: transform;
}
.amb .a-ring {
  width: var(--asz, 7vw);
  height: var(--asz, 7vw);
  border-radius: 50%;
  border: var(--ev-r-hair) solid var(--amb-c1, var(--ev-gold-500));
  opacity: 0.12;
}
.amb .a-diamond {
  width: var(--asz, 2.2vw);
  height: var(--asz, 2.2vw);
  background: var(--amb-c2, var(--ev-navy-500));
  border-radius: 0.2vw;
  rotate: 45deg;
  opacity: 0.1;
}
.amb .a-blob {
  width: var(--asz, 22vw);
  height: var(--asz, 22vw);
  border-radius: 50%;
  background: var(--amb-c1, var(--ev-gold-500));
  filter: blur(3.5vw);
  opacity: 0.07;
}
.amb .a-spark {
  width: var(--asz, 0.5vw);
  height: var(--asz, 0.5vw);
  border-radius: 50%;
  background: var(--amb-c1, var(--ev-gold-400));
  opacity: 0.28;
}
@keyframes ambDrift {
  0%   { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
  18%  { transform: translate3d(5vw, -3.5vw, 0) rotate(12deg) scale(1.06); }
  38%  { transform: translate3d(-3.5vw, 5vw, 0) rotate(-9deg) scale(0.95); }
  58%  { transform: translate3d(6.5vw, 2.2vw, 0) rotate(18deg) scale(1.05); }
  78%  { transform: translate3d(-4.5vw, -4.5vw, 0) rotate(-14deg) scale(0.96); }
  100% { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
}
/* content stacks above the ambient layer */
.hero-copy, .years-wrap, .biz-wrap, .pillars-wrap, .tag-wrap,
.close-wrap, .donate-copy, .donate-card, .copy-col, .cutout-col {
  position: relative;
}

/* ============================================================
   Poster-frame variant — the yard-sign/welcome-poster background
   (cream texture, flag corners, gold frame). Applied by JS only
   when assets/poster-frame.jpg exists. The art is exactly 16:9
   and #frame is a locked 16:9 box, so 100%/100% fill never
   distorts or crops the baked-in gold frame at any window size.
   ============================================================ */
.slide.on-poster {
  background-image: url("assets/poster-frame.jpg");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  /* keep content inside the printed gold frame */
  padding: 4.5vw 5vw;
}
.slide.on-poster .amb { --amb-c1: var(--ev-navy-500); --amb-c2: var(--ev-gold-600); }
.slide.on-poster .amb > i { opacity: 0.05; }
.s-neighbor.on-poster .line-a { color: var(--ev-ink); }
.s-neighbor.on-poster .line-b { color: var(--ev-crimson-600); }
.s-neighbor.on-poster .sub { color: var(--ev-ink-soft); }
.s-business.on-poster .biz-head { color: var(--ev-ink); }
.s-business.on-poster .biz-head em { color: var(--ev-gold-600); }
.s-business.on-poster .tl-rail { background: var(--ev-navy-100); }
.s-business.on-poster .tl-year { color: var(--ev-navy-800); }
.s-business.on-poster .tl-tag,
.s-business.on-poster .biz-sub { color: var(--ev-ink-soft); }

/* ============================================================
   Shared vocabulary
   ============================================================ */
.eyebrow {
  font-family: var(--ev-sans);
  font-weight: 600;
  font-size: var(--ev-t-micro);
  letter-spacing: var(--ev-track-caps);
  text-transform: uppercase;
  color: var(--ev-gold-500);
}
.gold-rule {
  height: var(--ev-r-hair);
  width: 9vw;
  background: linear-gradient(to right, var(--ev-gold-500), var(--ev-scrim-none));
}
.brand-seal {
  position: absolute;
  right: var(--ev-s-5);
  bottom: var(--ev-s-5);
  width: 5.5vw;
  height: auto;
  z-index: var(--ev-z-brand);
  filter: drop-shadow(0 0.3vw 1.2vw var(--ev-shadow-cast));
  opacity: 0.92;
}

/* ============================================================
   S1 — HERO
   ============================================================ */
.s-hero {
  background:
    radial-gradient(90% 120% at 72% 40%, var(--ev-glow-navy), var(--ev-scrim-none) 60%),
    linear-gradient(160deg, var(--ev-navy-900), var(--ev-navy-950) 70%);
  align-items: center;
  justify-content: flex-start;
  padding: 0 var(--ev-s-8);
}
.s-hero .glow-orb {
  position: absolute;
  right: -10vw; top: -14vw;
  width: 46vw; height: 46vw;
  border-radius: 50%;
  background: radial-gradient(circle, var(--ev-glow-gold), var(--ev-scrim-none) 68%);
  animation: orbBreathe 9s var(--ev-ease-smooth) infinite;
}
@keyframes orbBreathe {
  0%, 100% { opacity: 0.55; transform: scale(1) translate3d(0, 0, 0); }
  50%      { opacity: 0.95; transform: scale(1.08) translate3d(-2vw, 1.4vw, 0); }
}
.s-hero .hero-copy { display: grid; gap: var(--ev-s-4); max-width: 52vw; position: relative; z-index: 1; }
.s-hero .hero-cutout {
  position: absolute;
  right: var(--ev-s-6);
  bottom: 0;
  height: 88%;
  width: auto;
  object-fit: contain;
  object-position: bottom right;
  filter: drop-shadow(-1.4vw 1vw 2.6vw var(--ev-shadow-cast));
}
.s-hero .hero-seal {
  width: 11vw;
  height: auto;
  filter: drop-shadow(0 0.4vw 1.6vw var(--ev-shadow-cast));
}
.s-hero .hero-name {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-hero);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
}
.s-hero .hero-for {
  font-size: var(--ev-t-h2);
  font-family: var(--ev-serif);
  font-style: italic;
  font-weight: 600;
  color: var(--ev-gold-400);
}
.s-hero .hero-district {
  display: inline-flex;
  align-items: center;
  gap: var(--ev-s-3);
  font-size: var(--ev-t-caption);
  letter-spacing: var(--ev-track-caps);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ev-navy-100);
}
.s-hero .hero-district::before {
  content: "";
  width: 6vw;
  height: var(--ev-r-hair);
  background: var(--ev-gold-500);
}

/* ============================================================
   S2 — NEIGHBOR (dark, site hero cutout)
   ============================================================ */
.s-neighbor {
  background:
    radial-gradient(70% 100% at 22% 75%, var(--ev-glow-navy), var(--ev-scrim-none) 62%),
    linear-gradient(140deg, var(--ev-navy-800), var(--ev-navy-950) 78%);
  flex-direction: row;
  align-items: flex-end;
}
.s-neighbor .cutout-col {
  position: relative;
  width: 40%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  justify-content: center;
}
.s-neighbor .cutout-col::before {
  content: "";
  position: absolute;
  left: 50%; bottom: -14vw;
  width: 34vw; height: 34vw;
  transform: translateX(-50%);
  border-radius: 50%;
  background: radial-gradient(circle, var(--ev-gold-veil), var(--ev-scrim-none) 70%);
  animation: ambientDrift 16s var(--ev-ease-smooth) infinite alternate;
}
.s-neighbor .cutout {
  position: relative;
  max-height: 92%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: bottom center;
  filter: drop-shadow(-1.2vw 0.8vw 2.4vw var(--ev-shadow-cast));
}
.slide.choreo-in .s-neighbor-breathe {
  animation: cutoutBreathe 12s var(--ev-ease-smooth) 2s infinite alternate;
}
@keyframes cutoutBreathe {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(0, -0.5%, 0) scale(1.025); }
}
.s-neighbor .copy-col {
  width: 60%;
  align-self: center;
  display: grid;
  gap: var(--ev-s-4);
  padding: var(--ev-s-7) var(--ev-s-7) var(--ev-s-7) var(--ev-s-4);
}
.s-neighbor .line-a,
.s-neighbor .line-b {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
}
.s-neighbor .line-b { color: var(--ev-gold-400); }
.s-neighbor .sub {
  font-size: var(--ev-t-lead);
  color: var(--ev-on-dark-mut);
  max-width: 42vw;
  line-height: var(--ev-lh-body);
}

/* ============================================================
   S3 — 25 YEARS (counting numeral, drifting particles)
   ============================================================ */
.s-years {
  background:
    radial-gradient(70% 90% at 30% 70%, var(--ev-glow-navy), var(--ev-scrim-none) 65%),
    linear-gradient(200deg, var(--ev-navy-950), var(--ev-navy-800));
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-years .years-wrap { display: grid; gap: var(--ev-s-3); justify-items: center; }
.s-years .count {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-count);
  line-height: 0.85;
  color: var(--ev-gold-400);
  font-variant-numeric: tabular-nums;
}
.s-years .count-label {
  font-family: var(--ev-serif);
  font-size: var(--ev-t-h1);
  font-weight: 600;
  color: var(--ev-on-dark);
}
.s-years .count-sub {
  font-size: var(--ev-t-lead);
  color: var(--ev-on-dark-mut);
}
.particle {
  position: absolute;
  border-radius: 50%;
  background: var(--ev-gold-500);
  opacity: 0;
  animation: particleFloat var(--pf-dur, 11s) linear infinite;
  animation-delay: var(--pf-delay, 0s);
  left: var(--pf-x, 50%);
  width: var(--pf-size, 0.4vw);
  height: var(--pf-size, 0.4vw);
}
@keyframes particleFloat {
  0%   { transform: translate3d(0, 58vw, 0); opacity: 0; }
  12%  { opacity: 0.7; }
  85%  { opacity: 0.25; }
  100% { transform: translate3d(1.5vw, -6vw, 0); opacity: 0; }
}

/* ============================================================
   S4 — BUSINESS (dark; timeline draws point-to-point:
   line reaches a node → dot pops → labels rise → line continues)
   ============================================================ */
.s-business {
  background:
    radial-gradient(75% 100% at 80% 25%, var(--ev-glow-navy), var(--ev-scrim-none) 62%),
    linear-gradient(200deg, var(--ev-navy-900), var(--ev-navy-950) 76%);
  align-items: center;
  justify-content: center;
}
.s-business .biz-wrap {
  display: grid;
  gap: var(--ev-s-5);
  width: 76vw;
}
.s-business .biz-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  /* roomier than the display default: the emphasis box around the
     second line needs clearance from the line above */
  line-height: 1.14;
  color: var(--ev-white);
}
.s-business .biz-head em {
  font-style: italic;
  color: var(--ev-gold-400);
}
.s-business .timeline {
  position: relative;
  height: 9vw;
}
.s-business .tl-rail {
  position: absolute;
  top: 50%; left: 0; right: 0;
  height: var(--ev-r-hair);
  background: var(--ev-navy-700);
}
.s-business .tl-fill {
  position: absolute;
  top: 50%; left: 0;
  height: var(--ev-r-med);
  transform: translateY(-50%) scaleX(0);
  width: 100%;
  background: linear-gradient(to right, var(--ev-gold-500), var(--ev-crimson-500));
  transform-origin: left center;
  /* per-leg transition set by the engine; no all-at-once sweep */
  transition: transform 900ms var(--ev-ease-expo);
}
.s-business .tl-node {
  position: absolute;
  top: 50%;
  left: var(--tl-x, 0%);
  transform: translate(-50%, -50%) scale(0.3);
  opacity: 0;
  display: grid;
  justify-items: center;
  transition:
    opacity 420ms var(--ev-ease-smooth),
    transform 560ms var(--ev-ease-expo);
}
.s-business .tl-node.on {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.s-business .tl-dot {
  width: 1.2vw; height: 1.2vw;
  border-radius: 50%;
  background: var(--ev-gold-400);
  outline: var(--ev-r-hair) solid var(--ev-gold-600);
  outline-offset: 0.25vw;
}
.s-business .tl-node.on .tl-dot {
  animation: dotPulse 3.2s var(--ev-ease-smooth) infinite;
}
@keyframes dotPulse {
  0%, 100% { outline-offset: 0.25vw; }
  50%      { outline-offset: 0.6vw; }
}
.s-business .tl-year {
  position: absolute;
  top: 2.4vw;
  font-weight: 800;
  font-size: var(--ev-t-caption);
  color: var(--ev-white);
  white-space: nowrap;
}
.s-business .tl-tag {
  position: absolute;
  bottom: 2.4vw;
  font-size: var(--ev-t-micro);
  letter-spacing: var(--ev-track-wide);
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ev-on-dark-mut);
  white-space: nowrap;
}
.s-business .biz-sub {
  font-size: var(--ev-t-lead);
  color: var(--ev-on-dark-mut);
  line-height: var(--ev-lh-body);
  max-width: 56vw;
}

/* ============================================================
   S5 — PILLARS (six issue chips from his published platform)
   ============================================================ */
.s-pillars {
  background:
    radial-gradient(80% 100% at 80% 10%, var(--ev-glow-navy), var(--ev-scrim-none) 60%),
    linear-gradient(160deg, var(--ev-navy-900), var(--ev-navy-950));
  align-items: center;
  justify-content: center;
}
.s-pillars .pillars-wrap { display: grid; gap: var(--ev-s-5); width: 74vw; }
.s-pillars .pillars-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  color: var(--ev-on-dark);
}
.s-pillars .grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* every row identical height regardless of label wrapping */
  grid-auto-rows: 1fr;
  gap: var(--ev-s-3);
}
.s-pillars .chip {
  display: grid;
  gap: var(--ev-s-2);
  align-content: center;
  /* fixed card height: two-line labels wrap INSIDE the card, they
     never resize it — all six cards stay identical */
  min-height: 8.2vw;
  padding: var(--ev-s-3) var(--ev-s-4);
  border: var(--ev-r-hair) solid var(--ev-navy-500);
  border-left: var(--ev-r-med) solid var(--ev-gold-500);
  /* solid lift so cards read as cards against the slide ground */
  background: linear-gradient(160deg, var(--ev-navy-700), var(--ev-navy-800));
  box-shadow: 0 0.4vw 1.6vw var(--ev-scrim-mid);
}
.s-pillars .chip-num {
  font-family: var(--ev-serif);
  font-style: italic;
  font-size: var(--ev-t-h2);
  color: var(--ev-gold-400);
  line-height: 1;
}
.s-pillars .chip-name {
  font-weight: 600;
  font-size: var(--ev-t-body);
  color: var(--ev-on-dark);
  line-height: var(--ev-lh-snug);
  text-wrap: balance;
}
/* sequential spotlight — engine cycles .lit across the chips */
.s-pillars .chip {
  transition:
    transform 450ms var(--ev-ease-expo),
    border-color 450ms var(--ev-ease-smooth),
    box-shadow 450ms var(--ev-ease-smooth),
    background-color 450ms var(--ev-ease-smooth);
}
.s-pillars .chip.lit {
  transform: scale(1.045);
  border-color: var(--ev-gold-500);
  border-left-color: var(--ev-gold-300);
  background-color: var(--ev-navy-700);
  box-shadow: 0 0 2.6vw var(--ev-glow-gold);
}
.s-pillars .chip.lit .chip-num { color: var(--ev-gold-300); }

/* ============================================================
   S5a — TEAM (six equal cards, spotlight cycle; distinct from
   pillars: centered text, gold top rule instead of left border)
   ============================================================ */
.s-team {
  background:
    radial-gradient(90% 110% at 50% 110%, var(--ev-glow-navy), var(--ev-scrim-none) 58%),
    linear-gradient(190deg, var(--ev-navy-950), var(--ev-navy-800) 85%);
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-team .team-wrap { display: grid; gap: var(--ev-s-5); width: 76vw; justify-items: center; }
.s-team .team-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  color: var(--ev-on-dark);
}
.s-team .team-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
  gap: var(--ev-s-3);
  width: 100%;
}
.s-team .chip {
  display: grid;
  /* fixed row heights so avatar, name, and title sit at identical
     vertical positions in every card; the name row is sized from
     the name's own font metrics: exactly two lines, no spill */
  grid-template-rows: auto calc(var(--ev-t-lead) * var(--ev-lh-snug) * 2) auto;
  gap: var(--ev-s-2);
  align-content: start;
  justify-items: center;
  min-height: 7.6vw;
  padding: var(--ev-s-3);
  border: var(--ev-r-hair) solid var(--ev-navy-500);
  border-top: var(--ev-r-med) solid var(--ev-gold-500);
  background: linear-gradient(160deg, var(--ev-navy-700), var(--ev-navy-800));
  box-shadow: 0 0.4vw 1.6vw var(--ev-scrim-mid);
  transition:
    transform 450ms var(--ev-ease-expo),
    border-color 450ms var(--ev-ease-smooth),
    box-shadow 450ms var(--ev-ease-smooth),
    background-color 450ms var(--ev-ease-smooth);
}
.s-team .chip.lit {
  transform: scale(1.045);
  border-color: var(--ev-gold-500);
  border-top-color: var(--ev-gold-300);
  background-color: var(--ev-navy-700);
  box-shadow: 0 0 2.6vw var(--ev-glow-gold);
}
/* avatars hidden until the grid upgrades to photo mode */
.s-team .avatar { display: none; }
.s-team .team-grid.with-photos .avatar {
  display: grid;
  place-items: center;
  width: 4.6vw;
  height: 4.6vw;
  border-radius: 50%;
  border: var(--ev-r-hair) solid var(--ev-gold-500);
  overflow: hidden;
}
.s-team .team-grid.with-photos .avatar-img { object-fit: cover; }
.s-team .team-grid.with-photos .avatar-mono {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h2);
  color: var(--ev-gold-300);
  background: var(--ev-navy-900);
}
.s-team .team-grid.with-photos .chip { min-height: 13.5vw; }

.s-team .team-name {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-lead);
  line-height: var(--ev-lh-snug);
  color: var(--ev-white);
  align-self: center;
}
.s-team .team-role {
  font-size: var(--ev-t-micro);
  font-weight: 600;
  letter-spacing: var(--ev-track-wide);
  text-transform: uppercase;
  color: var(--ev-gold-400);
  text-wrap: balance;
}

/* ============================================================
   S5a2 — MEMBER announcements (equal structure, mirrored A/B)
   ============================================================ */
.s-member {
  background:
    radial-gradient(70% 100% at 78% 30%, var(--ev-glow-navy), var(--ev-scrim-none) 60%),
    linear-gradient(150deg, var(--ev-navy-900), var(--ev-navy-950) 78%);
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--ev-s-8);
  padding: 0 var(--ev-s-8);
}
.s-member.mirror {
  flex-direction: row-reverse;
  background:
    radial-gradient(70% 100% at 22% 70%, var(--ev-glow-navy), var(--ev-scrim-none) 60%),
    linear-gradient(210deg, var(--ev-navy-800), var(--ev-navy-950) 78%);
}
.s-member .mem-figure { position: relative; }
.s-member .mem-avatar {
  display: grid;
  place-items: center;
  width: 17vw;
  height: 17vw;
  border-radius: 50%;
  border: var(--ev-r-med) solid var(--ev-gold-500);
  background: linear-gradient(160deg, var(--ev-navy-700), var(--ev-navy-900));
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  color: var(--ev-gold-300);
  overflow: hidden;
  box-shadow: 0 0.8vw 2.6vw var(--ev-shadow-cast);
}
.s-member .mem-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}
.s-member .mem-copy {
  display: grid;
  gap: var(--ev-s-3);
  max-width: 48vw;
  justify-items: start;
  text-align: left;
}
.s-member.mirror .mem-copy { justify-items: end; text-align: right; }
.s-member .mem-name {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
}
.s-member .mem-role {
  font-size: var(--ev-t-h2);
  font-family: var(--ev-serif);
  font-style: italic;
  font-weight: 600;
  color: var(--ev-gold-400);
}
.s-member .mem-org {
  font-size: var(--ev-t-body);
  color: var(--ev-on-dark-mut);
}
.s-member .mem-blurb {
  font-size: var(--ev-t-body);
  line-height: var(--ev-lh-body);
  color: var(--ev-gold-100);
  max-width: 40vw;
  margin-top: var(--ev-s-2);
  border-top: var(--ev-r-hair) solid var(--ev-navy-500);
  padding-top: var(--ev-s-3);
}

/* ============================================================
   S5b — NUMBERS (district stats count up in sequence)
   ============================================================ */
.s-numbers {
  background:
    radial-gradient(85% 110% at 15% 15%, var(--ev-glow-navy), var(--ev-scrim-none) 58%),
    linear-gradient(170deg, var(--ev-navy-900), var(--ev-navy-950) 74%);
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-numbers .num-wrap { display: grid; gap: var(--ev-s-5); width: 78vw; justify-items: center; }
.s-numbers .num-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  color: var(--ev-on-dark);
}
.s-numbers .num-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--ev-s-6);
  width: 100%;
}
.s-numbers .num-cell { display: grid; gap: var(--ev-s-2); justify-items: center; }
.s-numbers .num-val {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  line-height: 1;
  color: var(--ev-gold-400);
  font-variant-numeric: tabular-nums;
}
.s-numbers .num-label {
  font-size: var(--ev-t-caption);
  font-weight: 600;
  letter-spacing: var(--ev-track-wide);
  text-transform: uppercase;
  color: var(--ev-on-dark-mut);
}
.s-numbers .num-punch {
  font-family: var(--ev-serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--ev-t-h2);
  color: var(--ev-white);
}
.s-numbers .num-punch em { font-style: italic; color: var(--ev-gold-300); }

/* ============================================================
   S5c — QUOTE (his own words, revealed word by word)
   ============================================================ */
.s-quote {
  background:
    radial-gradient(60% 90% at 50% 100%, var(--ev-glow-gold), var(--ev-scrim-none) 55%),
    linear-gradient(180deg, var(--ev-navy-950), var(--ev-navy-800));
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-quote .quote-wrap { display: grid; gap: var(--ev-s-4); width: 72vw; justify-items: center; }
.s-quote .quote-mark {
  font-family: var(--ev-serif);
  font-size: var(--ev-t-hero);
  line-height: 0.5;
  color: var(--ev-gold-500);
}
.s-quote .quote-text {
  font-family: var(--ev-serif);
  font-weight: 600;
  font-size: var(--ev-t-h1);
  line-height: var(--ev-lh-snug);
  color: var(--ev-white);
  text-wrap: balance;
}
.s-quote .qw { display: inline-block; }
.s-quote .quote-attr {
  font-size: var(--ev-t-caption);
  font-weight: 600;
  letter-spacing: var(--ev-track-caps);
  text-transform: uppercase;
  color: var(--ev-gold-400);
}

/* ============================================================
   S5d — ELECTION DAY (crimson family, the urgency beat)
   ============================================================ */
.s-election {
  background: linear-gradient(220deg,
    var(--ev-navy-950) 8%, var(--ev-crimson-700) 60%, var(--ev-crimson-600));
  background-size: 220% 220%;
  animation: taglineShift 16s var(--ev-ease-smooth) infinite;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-election .el-wrap { display: grid; gap: var(--ev-s-3); justify-items: center; }
.s-election .el-tues {
  font-family: var(--ev-serif);
  font-style: italic;
  font-weight: 600;
  font-size: var(--ev-t-h2);
  color: var(--ev-gold-100);
}
.s-election .el-day {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
}
.s-election .el-day em { font-style: italic; color: var(--ev-gold-300); }
.s-election .el-first {
  font-size: var(--ev-t-lead);
  color: var(--ev-gold-100);
  line-height: var(--ev-lh-body);
  max-width: 52vw;
}

/* ============================================================
   S6 — DEPTH (parallax bg/fg cutout pairs from the site)
   ============================================================ */
.s-depth { background: var(--ev-navy-950); }
.s-depth .depth-bg,
.s-depth .depth-fg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.slide.choreo-in .depth-bg { animation: depthBg var(--ev-d-kb) var(--ev-ease-smooth) both; }
.slide.choreo-in .depth-fg { animation: depthFg var(--ev-d-kb) var(--ev-ease-smooth) both; }
@keyframes depthBg {
  from { transform: scale(1.02); }
  to   { transform: scale(1.12); }
}
@keyframes depthFg {
  from { transform: scale(1.05) translate3d(0, 0.6%, 0); }
  to   { transform: scale(1.22) translate3d(0, 2%, 0); }
}
.s-depth .depth-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--ev-scrim-strong) 0%, var(--ev-scrim-soft) 30%, var(--ev-scrim-none) 55%);
}
.s-depth .depth-caption {
  position: absolute;
  left: var(--ev-s-7);
  bottom: var(--ev-s-6);
  display: grid;
  gap: var(--ev-s-2);
  z-index: var(--ev-z-active);
}
.s-depth .depth-line {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  color: var(--ev-white);
  text-shadow: 0 0.2vw 1.4vw var(--ev-shadow-text);
}

/* ============================================================
   S7 — TAGLINE (animated navy→crimson gradient, word stagger)
   ============================================================ */
.s-tagline {
  /* navy and gold family: crimson is reserved for the two ask
     slides (election, donate2) so red always signals "act" */
  background: linear-gradient(240deg,
    var(--ev-navy-950), var(--ev-navy-700) 45%,
    var(--ev-gold-700) 96%);
  background-size: 260% 260%;
  animation: taglineShift 14s var(--ev-ease-smooth) infinite;
  align-items: center;
  justify-content: center;
  text-align: center;
}
@keyframes taglineShift {
  0%, 100% { background-position: 0% 50%; }
  50%      { background-position: 100% 50%; }
}
.s-tagline .tag-wrap { display: grid; gap: var(--ev-s-4); justify-items: center; }
.s-tagline .tag-word {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
}
.s-tagline .tag-word em {
  font-style: italic;
  color: var(--ev-gold-300);
}

/* ============================================================
   S8 — CLOSE (seal, url)
   ============================================================ */
.s-close {
  background:
    radial-gradient(60% 80% at 50% 30%, var(--ev-glow-gold), var(--ev-scrim-none) 62%),
    linear-gradient(180deg, var(--ev-navy-900), var(--ev-navy-950) 75%);
  align-items: center;
  justify-content: center;
  text-align: center;
}
.s-close .close-wrap { display: grid; gap: var(--ev-s-4); justify-items: center; }
.s-close .close-seal {
  width: 15vw;
  height: auto;
  filter: drop-shadow(0 0.5vw 2vw var(--ev-shadow-cast));
  animation: sealBreathe 8s var(--ev-ease-smooth) infinite;
}
@keyframes sealBreathe {
  0%, 100% { transform: scale(1) rotate(0deg); }
  50%      { transform: scale(1.035) rotate(0.6deg); }
}
.s-close .close-name {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  color: var(--ev-white);
}
.s-close .close-url {
  font-weight: 800;
  font-size: var(--ev-t-h2);
  letter-spacing: var(--ev-track-wide);
  color: var(--ev-gold-400);
}

/* ============================================================
   DONATE — join-the-campaign message first, QR as a quiet detail.
   Composed so a photo of the candidate in front of it reads
   "Join the campaign", not "scan my QR code".
   ============================================================ */
.s-donate {
  background:
    radial-gradient(80% 110% at 20% 20%, var(--ev-glow-navy), var(--ev-scrim-none) 60%),
    linear-gradient(140deg, var(--ev-navy-900), var(--ev-navy-950) 72%);
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  padding: 0 var(--ev-s-8);
}
.s-donate .donate-copy {
  display: grid;
  gap: var(--ev-s-4);
  max-width: 54vw;
}
.s-donate .donate-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-display);
  line-height: var(--ev-lh-tight);
  color: var(--ev-on-dark);
}
.s-donate .donate-head em { font-style: italic; }
.s-donate .donate-sub {
  font-size: var(--ev-t-lead);
  color: var(--ev-on-dark-mut);
  line-height: var(--ev-lh-body);
  max-width: 44vw;
}
.s-donate .donate-card {
  display: grid;
  gap: var(--ev-s-2);
  justify-items: center;
  padding: var(--ev-s-4);
  background: var(--ev-white);
  border-top: var(--ev-r-thick) solid var(--ev-gold-500);
  box-shadow: 0 1vw 3vw var(--ev-shadow-cast);
}
.s-donate .donate-qr {
  width: 13vw;
  height: 13vw;
  display: block;
}
.s-donate .donate-scan {
  font-weight: 800;
  font-size: var(--ev-t-caption);
  letter-spacing: var(--ev-track-wide);
  text-transform: uppercase;
  color: var(--ev-navy-800);
}
.s-donate .donate-url {
  font-weight: 600;
  font-size: var(--ev-t-micro);
  color: var(--ev-ink-soft);
}

/* ============================================================
   DONATE 2 — mid-deck, flipped: QR left, crimson aesthetic.
   ============================================================ */
.s-donate2 {
  background:
    radial-gradient(70% 100% at 85% 80%, var(--ev-glow-crimson), var(--ev-scrim-none) 60%),
    linear-gradient(320deg, var(--ev-crimson-700) 0%, var(--ev-navy-950) 55%, var(--ev-navy-900));
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: var(--ev-s-8);
  padding: 0 var(--ev-s-7);
}
.s-donate2 .d2-card {
  display: grid;
  gap: var(--ev-s-2);
  justify-items: center;
  padding: var(--ev-s-4);
  background: var(--ev-white);
  border-bottom: var(--ev-r-thick) solid var(--ev-crimson-500);
  box-shadow: 0 1vw 3vw var(--ev-shadow-cast);
  rotate: -2deg;
}
.slide.choreo-in .d2-card { animation: cardSway 9s var(--ev-ease-smooth) 2s infinite alternate; }
@keyframes cardSway {
  from { rotate: -2deg; }
  to   { rotate: -0.6deg; }
}
.s-donate2 .d2-qr { width: 14vw; height: 14vw; display: block; }
.s-donate2 .d2-scan {
  font-weight: 800;
  font-size: var(--ev-t-caption);
  letter-spacing: var(--ev-track-wide);
  text-transform: uppercase;
  color: var(--ev-crimson-600);
}
.s-donate2 .d2-copy { display: grid; gap: var(--ev-s-4); max-width: 46vw; }
.s-donate2 .d2-head {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  line-height: var(--ev-lh-snug);
  color: var(--ev-white);
}
.s-donate2 .d2-list {
  display: grid;
  gap: var(--ev-s-3);
  list-style: none;
}
.s-donate2 .d2-list li {
  display: flex;
  align-items: center;
  gap: var(--ev-s-3);
  font-size: var(--ev-t-lead);
  color: var(--ev-gold-100);
}
.s-donate2 .d2-list li::before {
  content: "";
  width: 2.4vw;
  height: var(--ev-r-hair);
  background: var(--ev-gold-500);
  flex: none;
}

/* ============================================================
   PHOTO slides — focal-point Ken Burns.
   transform-origin comes from --focus-x/--focus-y (set per photo)
   so motion pushes toward faces, never past them.
   ============================================================ */
.s-photo { background: var(--ev-navy-950); }
.s-photo img.ph {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: var(--focus-x, 50%) var(--focus-y, 30%);
  transform-origin: var(--focus-x, 50%) var(--focus-y, 30%);
}
/* Landscape (cover) motion — capped at 1.07 so tight crops never
   push faces out of frame; origin stays on the focal point. */
.slide.choreo-in .ph-in  { animation: phIn  var(--ev-d-kb) linear both; }
.slide.choreo-in .ph-out { animation: phOut var(--ev-d-kb) linear both; }
.slide.choreo-in .ph-pan { animation: phPan var(--ev-d-kb) linear both; }
@keyframes phIn  { from { transform: scale(1.0);  } to { transform: scale(1.07); } }
@keyframes phOut { from { transform: scale(1.07); } to { transform: scale(1.0);  } }
@keyframes phPan {
  from { transform: scale(1.04) translate3d(-1.1%, 0, 0); }
  to   { transform: scale(1.04) translate3d(1.1%, 0, 0); }
}

/* Portrait & square photos — mode-contain: the WHOLE image floats
   over a blurred copy of itself. Nothing is ever cropped away. */
.s-photo .ph-backdrop {
  position: absolute;
  inset: -4%;
  width: 108%;
  height: 108%;
  object-fit: cover;
  filter: blur(28px) brightness(0.55) saturate(1.1);
}
.s-photo.mode-contain img.ph {
  object-fit: contain;
  object-position: center center;
}
.slide.choreo-in.mode-contain .ph-in,
.slide.choreo-in.mode-contain .ph-out,
.slide.choreo-in.mode-contain .ph-pan {
  animation: phDrift var(--ev-d-kb) var(--ev-ease-smooth) both;
}
@keyframes phDrift {
  from { transform: scale(1.0); }
  to   { transform: scale(1.035); }
}
.s-photo .ph-scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--ev-scrim-strong) 0%, var(--ev-scrim-soft) 32%, var(--ev-scrim-none) 58%);
}
.s-photo .ph-caption {
  position: absolute;
  left: var(--ev-s-7);
  right: var(--ev-s-7);
  bottom: var(--ev-s-6);
  display: grid;
  gap: var(--ev-s-2);
  justify-items: start;
}
.s-photo .ph-kicker {
  font-size: var(--ev-t-micro);
  font-weight: 600;
  letter-spacing: var(--ev-track-caps);
  text-transform: uppercase;
  color: var(--ev-gold-400);
}
.s-photo .ph-line {
  font-family: var(--ev-serif);
  font-weight: 700;
  font-size: var(--ev-t-h1);
  line-height: var(--ev-lh-tight);
  color: var(--ev-white);
  text-shadow: 0 0.2vw 1.4vw var(--ev-shadow-text);
  text-wrap: balance;
}

/* ============================================================
   Progress bar
   ============================================================ */
#progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 0.3vh;
  z-index: var(--ev-z-progress);
}
#progress .bar {
  height: 100%;
  width: 0%;
  background: var(--ev-gold-500);
}

/* ============================================================
   Control strip — appears bottom-right on cursor movement,
   fades away after the cursor goes idle.
   ============================================================ */
#controls {
  position: absolute;
  right: var(--ev-s-4);
  bottom: var(--ev-s-4);
  z-index: var(--ev-z-progress);
  display: flex;
  gap: var(--ev-s-2);
  opacity: 0;
  pointer-events: none;
  transform: translate3d(0, 0.8vw, 0);
  transition:
    opacity 300ms var(--ev-ease-smooth),
    transform 300ms var(--ev-ease-smooth);
}
#controls.visible {
  opacity: 1;
  pointer-events: auto;
  transform: translate3d(0, 0, 0);
}
#controls button {
  width: 2.6vw;
  height: 2.6vw;
  min-width: 34px;
  min-height: 34px;
  display: grid;
  place-items: center;
  border: var(--ev-r-hair) solid var(--ev-navy-700);
  border-radius: 50%;
  background: var(--ev-scrim-strong);
  color: var(--ev-on-dark);
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: border-color 200ms var(--ev-ease-smooth), color 200ms var(--ev-ease-smooth);
}
#controls button:hover,
#controls button:focus-visible {
  border-color: var(--ev-gold-500);
  color: var(--ev-gold-400);
  outline: none;
}
#controls svg {
  width: 44%;
  height: 44%;
  display: block;
}
#controls svg.hidden { display: none; }

/* ============================================================
   Reduced motion — decorative animation resolves to none via
   the cascade; durations zero out through the tokens.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ev-d-transition: 0ms;
    --ev-d-entrance: 0ms;
    --ev-d-kb: 0s;
  }
  .slide { transition: none; }
  [data-animate] { opacity: 1; transform: none; transition: none; }
  .slide.choreo-in .u-draw::after { transition: none; }
  .s-hero .glow-orb,
  .s-neighbor .cutout-col::before,
  .slide.choreo-in .s-neighbor-breathe,
  .s-tagline,
  .s-close .close-seal,
  .s-business .tl-dot,
  .particle,
  .drift,
  .shimmer,
  .slide.choreo-in .depth-bg,
  .slide.choreo-in .depth-fg,
  .slide.choreo-in .ph-in,
  .slide.choreo-in .ph-out,
  .slide.choreo-in .ph-pan,
  .amb > i { animation: none; }
}
