/* ==================================================================
   Cairo FACE World Summit 2027 — scroll-driven WebGL brand film
   Architecture per BUILD_SPEC: fixed canvas (z-0), DOM overlays
   (z-10), header (z-20), rail + CTA pill stack (z-30).
   Identity unchanged: steel blue #A83020 + white, circular shapes,
   Graphik.
   ================================================================== */

:root {
  --accent: #A83020;
  --accent-strong: #7A2010;
  --ink: #0C1828;
  --paper: #FFFFFF;
  --paper-2: #F5EBE0;
  --wash: rgba(168, 48, 32, 0.08);
  --muted-light: rgba(10, 26, 40, 0.6);
  --muted-dark: rgba(255, 255, 255, 0.64);
  --hairline-light: rgba(168, 48, 32, 0.35);
  --hairline-dark: rgba(255, 255, 255, 0.22);
  --panel-dark: rgba(30, 26, 50, 0.45);
  --grad-footer: linear-gradient(180deg, #1E1A32 0%, #1E1A32 55%, #141828 100%);

  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-ui: cubic-bezier(0.4, 0, 0.2, 1);
  /* 200px page margins on desktop, scaling down below 1600px */
  --pad: clamp(28px, 12.5vw, 200px);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }
/* the floating nav sits from y=28 to y=92, so every anchor jump must clear it
   or the section's own headline lands underneath the pill */
html { scroll-padding-top: 108px; }
/* decorative faces bleed past the right edge by design — clip, never scroll
   (overflow-x: clip keeps position: sticky working, unlike hidden) */
html, body { overflow-x: clip; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: "Outfit", Arial, sans-serif;
  font-size: 16px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

a { color: inherit; text-decoration: none; cursor: pointer; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
summary { cursor: pointer; }
img { max-width: 100%; display: block; }

::selection { background: var(--accent); color: #fff; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }

.container {
  width: 100%;
  max-width: 1920px;
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}

/* ---------------- type ---------------- */
.display-xl { font-size: clamp(44px, 6.6vw, 88px); font-weight: 400; line-height: 0.98; letter-spacing: -0.03em; }
.display-l  { font-size: clamp(34px, 5vw, 64px); font-weight: 400; line-height: 1.06; letter-spacing: -0.02em; }
.display-m  { font-size: clamp(26px, 3.2vw, 42px); font-weight: 400; line-height: 1.2; letter-spacing: -0.01em; }
.heading    { font-size: clamp(21px, 2.3vw, 30px); font-weight: 500; line-height: 1.16; letter-spacing: -0.01em; }
.body-l     { font-size: 19px; font-weight: 500; line-height: 1.4; }
.body       { font-size: 16px; font-weight: 400; line-height: 1.5; }
.label {
  font-family: "Outfit", Arial, sans-serif;
  font-size: 13px; font-weight: 500; line-height: 1.4;
  letter-spacing: 0.08em;
}
.label--dim { opacity: 0.62; }
/* section eyebrows are headlines now (client mandate) */
.label--head {
  font-size: clamp(24px, 3vw, 44px);
  font-weight: 500; line-height: 1.15; letter-spacing: -0.01em;
}
.label--head.label--dim { opacity: 0.95; }
.line-2 { opacity: 0.55; }

/* ---------------- circular primitives ---------------- */
.circle-arrow {
  display: inline-flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: 9999px; flex: none;
  background: var(--accent); color: #fff; font-size: 18px;
  transition: transform 0.32s var(--ease-ui);
}
.circle-arrow--sm { width: 30px; height: 30px; font-size: 15px; }

.pill-sm {
  display: inline-flex; align-items: center; gap: 10px;
  height: 38px; padding-block: 0; padding-inline: 18px 4px; border-radius: 9999px;
  border: 1px solid var(--hairline-light);
  font-family: "Outfit", Arial, sans-serif;
  font-size: 13px; font-weight: 600; letter-spacing: 0.08em;
  transition: border-color 0.3s var(--ease-ui);
  white-space: nowrap;
}
.pill-sm:hover { border-color: var(--accent); }
.footer .pill-sm { border-color: var(--hairline-dark); color: #fff; }

.tick {
  position: absolute; width: 10px; height: 10px; border-radius: 9999px;
  background: var(--accent); display: block;
}
.tick--corner { top: -5px; left: -5px; z-index: 2; }

/* ---------------- z-0 · canvas ---------------- */
#film {
  position: fixed; inset: 0; z-index: 0;
  width: 100%; height: 100svh;
  display: block;
  pointer-events: none;
}
body:not(.film-gl) #film { display: none; }

/* ---------------- z-20 · header — floating-pill nav ----------------
   Transparent bar at rest; past 5px of scroll the pill materialises:
   frosted glass, hairline ring, layered soft shadow, and the logo/burger
   nudge 12px inward to re-centre inside the pill padding. One class
   ("scrolling"), one threshold, no hide-on-scroll. */
.header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 20;
  padding: 12px 0;
  background: transparent;
  transition: color 0.5s var(--ease-ui);
}
@media (min-width: 991px) { .header { top: 16px; } }
.nav-container { width: 90%; max-width: 1180px; margin-inline: auto; }
.menu-pill {
  position: relative; z-index: 5;
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; width: 100%;
  padding: 10px 12px; border-radius: 16px;
}
/* desktop: symmetric grid so the tabs sit EXACTLY centered in the pill
   (flex space-between drifts them toward the narrower side) */
/* the tabs ride beside the logo; the buttons hold the right edge */
.header__nav { margin-right: auto; margin-left: 10px; }
.menu-pill {
  background: rgba(255, 255, 255, 0);
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  box-shadow: none;
  transition: all 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.header[data-theme="dark"] .menu-pill.scrolling {
  background: rgba(7, 30, 50, 0.5);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  box-shadow:
    rgba(255, 255, 255, 0.14) 0 0 0 1px,
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    rgba(2, 12, 20, 0.2) 0 2px 2px -1px,
    rgba(2, 12, 20, 0.2) 0 4px 4px -2px,
    rgba(2, 12, 20, 0.2) 0 8px 8px -4px;
}
.header[data-theme="light"] .menu-pill.scrolling {
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(22px) saturate(1.6);
  -webkit-backdrop-filter: blur(22px) saturate(1.6);
  box-shadow:
    rgba(17, 24, 39, 0.1) 0 0 0 1px,
    rgba(17, 24, 39, 0.05) 0 2px 2px -1px,
    rgba(17, 24, 39, 0.05) 0 4px 4px -2px,
    rgba(17, 24, 39, 0.05) 0 8px 8px -4px;
}
.header__brand {
  position: relative; z-index: 11;
  display: inline-flex; align-items: center;
  transition: transform 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
.menu-pill.scrolling .header__brand { transform: translateX(12px); }
.menu-pill .menu-btn { transition: transform 0.15s cubic-bezier(0.25, 0.46, 0.45, 0.94), background 0.3s var(--ease-ui); }
.menu-pill.scrolling .menu-btn { transform: translateX(-12px); }
.header__logo { height: 44px; width: auto; display: block; }
/* the two official logo states: blue on light headers, white on dark —
   full artwork, no filters, no cropping */
.header__logo--mark { display: none; height: 44px; width: auto; }
.header[data-theme="dark"] .header__logo--full { display: none; }
.header[data-theme="dark"] .header__logo--mark { display: block; }
.header__nav { display: flex; align-items: center; gap: 2px; }
/* nav links: quiet by default, a soft tint on hover — no pills, no borders */
.navpill {
  display: inline-flex; align-items: center; height: 40px; padding: 0 12px;
  border-radius: 12px;
  background: transparent;
  font-family: "Outfit", Arial, sans-serif;
  font-size: 13px; font-weight: 500; letter-spacing: 0.06em;
  transition: background 0.2s var(--ease-ui);
}
.header[data-theme="light"] .navpill:hover { background: rgba(17, 24, 39, 0.04); }
.header[data-theme="dark"] .navpill:hover { background: rgba(255, 255, 255, 0.08); }
.navpill__flip { display: block; height: 1.4em; overflow: hidden; }
.navpill__flip span { display: block; white-space: nowrap; transition: transform 0.32s var(--ease-ui); }
.navpill:hover .navpill__flip span { transform: translateY(-100%); }
/* right-side CTAs: one quiet, one loud */
.nav-ctas { display: flex; align-items: center; gap: 8px; }
.nav-cta {
  display: inline-flex; align-items: center; height: 40px; padding: 0 16px;
  border-radius: 12px;
  font-family: "Outfit", Arial, sans-serif;
  font-size: 13px; font-weight: 600; letter-spacing: 0.06em;
  white-space: nowrap;
  transition: background 0.35s cubic-bezier(0.6, 0.6, 0, 1), color 0.35s cubic-bezier(0.6, 0.6, 0, 1);
}
.nav-cta--primary { background: var(--accent); color: #fff; }
.nav-cta--primary:hover { background: var(--accent-strong); }
.header[data-theme="dark"] .nav-cta--secondary { color: #fff; background: rgba(255, 255, 255, 0.1); }
.header[data-theme="dark"] .nav-cta--secondary:hover { background: rgba(255, 255, 255, 0.18); }
.header[data-theme="light"] .nav-cta--secondary { color: var(--ink); background: rgba(17, 24, 39, 0.05); }
.header[data-theme="light"] .nav-cta--secondary:hover { background: rgba(17, 24, 39, 0.1); }

.header[data-theme="dark"] { color: #fff; }
.header[data-theme="dark"] .navpill { color: #fff; }
.header[data-theme="light"] { color: var(--ink); }
.header[data-theme="light"] .navpill { color: var(--ink); }

/* ---------------- mobile menu button (shown ≤768px) ---------------- */
.menu-btn {
  display: none;
  position: relative; flex: none;
  width: 40px; height: 40px; border-radius: 9999px;
  background: var(--panel-dark);
  backdrop-filter: blur(12px);
}
.header[data-theme="light"] .menu-btn { background: rgba(168, 48, 32, 0.12); }
.menu-btn__bar {
  position: absolute; left: 12px; right: 12px; height: 2px;
  border-radius: 2px; background: currentColor;
  transition: transform 0.32s var(--ease-ui);
}
.menu-btn__bar:nth-child(1) { top: 16px; }
.menu-btn__bar:nth-child(2) { top: 22px; }
body.menu-open .menu-btn__bar:nth-child(1) { transform: translateY(3px) rotate(45deg); }
body.menu-open .menu-btn__bar:nth-child(2) { transform: translateY(-3px) rotate(-45deg); }

/* ---------------- z-60 · slide-in side menu ---------------- */
.sidemenu {
  position: fixed; inset: 0; z-index: 60;
  visibility: hidden; pointer-events: none;
  transition: visibility 0s 0.4s;
}
.sidemenu__scrim {
  position: absolute; inset: 0;
  background: rgba(4, 14, 22, 0.55);
  opacity: 0;
  transition: opacity 0.35s var(--ease-ui);
}
.sidemenu__panel {
  position: absolute; top: 0; inset-inline-end: 0; bottom: 0;
  width: min(320px, 86vw);
  display: flex; flex-direction: column;
  padding: 20px 24px calc(28px + env(safe-area-inset-bottom));
  background: rgba(7, 30, 50, 0.94);
  backdrop-filter: blur(22px);
  -webkit-backdrop-filter: blur(22px);
  border-inline-start: 1px solid rgba(255, 255, 255, 0.08);
  color: #fff;
  transform: translateX(102%);
  transition: transform 0.42s var(--ease-out);
  overflow-y: auto;
}
body.menu-open { overflow: hidden; }
body.menu-open .sidemenu { visibility: visible; pointer-events: auto; transition-delay: 0s; }
body.menu-open .sidemenu__scrim { opacity: 1; }
body.menu-open .sidemenu__panel { transform: translateX(0); }
.sidemenu__head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 20px;
}
.sidemenu__logo {
  height: 34px; width: auto;
}
.sidemenu__close {
  position: relative; width: 40px; height: 40px; border-radius: 9999px;
  border: 1px solid var(--hairline-dark);
}
.sidemenu__close span {
  position: absolute; left: 12px; right: 12px; top: 19px; height: 2px;
  border-radius: 2px; background: currentColor;
}
.sidemenu__close span:nth-child(1) { transform: rotate(45deg); }
.sidemenu__close span:nth-child(2) { transform: rotate(-45deg); }
.sidemenu__links { display: flex; flex-direction: column; margin-bottom: 24px; }
.sidemenu__links a {
  display: flex; justify-content: space-between; align-items: center;
  padding: 14px 4px;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.14);
  font-family: "Outfit", Arial, sans-serif;
  font-size: 15px; font-weight: 500; letter-spacing: 0.08em;
}
.sidemenu__links a::after { content: "→"; font-family: "Outfit", sans-serif; opacity: 0.45; }
.sidemenu__cta { margin-top: auto; justify-content: space-between; }
.sidemenu__meta { margin-top: 16px; }

/* ---------------- z-30 · scene-dot rail ---------------- */
.rail {
  position: fixed; right: 30px; top: 50%; transform: translateY(-50%);
  z-index: 30;
  display: flex; flex-direction: column; gap: 12px;
}
.rail__dot {
  position: relative; width: 26px; height: 26px; border-radius: 9999px;
  display: flex; align-items: center; justify-content: center;
}
.rail__dot::before {
  content: ""; width: 4px; height: 4px; border-radius: 9999px;
  background: var(--rail-dot, rgba(255, 255, 255, 0.55));
  transition: background 0.3s var(--ease-ui);
}
.rail__dot::after {
  content: ""; position: absolute; inset: 0; border-radius: 9999px;
  border: 1px solid var(--rail-dot, rgba(255, 255, 255, 0.55));
  opacity: 0; transform: scale(0.6);
  transition: opacity 0.3s var(--ease-ui), transform 0.3s var(--ease-ui);
}
.rail__dot[aria-current="true"]::after { opacity: 1; transform: scale(1); }
body[data-scene-theme="light"] .rail { --rail-dot: rgba(10, 26, 40, 0.5); }

/* ---------------- z-30 · CTA pill stack ---------------- */
/* sticky contact dock — bottom-left, clear of the centred CTA pill and the
   right-hand scene rail */
.contactdock {
  position: fixed; inset-inline-start: 24px; bottom: 24px; z-index: 31;
  display: flex; flex-direction: column; gap: 12px;
}
.contactdock__btn {
  display: flex; align-items: center; justify-content: center;
  width: 48px; height: 48px; border-radius: 9999px;
  color: #fff;
  box-shadow: 0 8px 24px rgba(10, 26, 40, 0.28);
  transition: transform 0.3s var(--ease-out), filter 0.3s var(--ease-ui);
}
.contactdock__btn svg { width: 24px; height: 24px; display: block; }
.contactdock__btn--wa  { background: #25D366; }
.contactdock__btn--tel { background: var(--accent); }
.contactdock__btn:hover { transform: translateY(-2px); filter: brightness(1.06); }

.pillstack {
  position: fixed; left: 50%; bottom: 24px; z-index: 30;
  width: 200px; height: 44px;
  transform: translateX(-50%);
}
.pill-cta {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  /* symmetric padding so justify-content:center leaves equal slack either
     side; the 28px badge in a 44px pill gives an even 8px top and bottom */
  padding: 0 14px;
  border-radius: 9999px;
  background: var(--accent); color: #fff;
  font-family: "Outfit", Arial, sans-serif;
  font-size: 14px; font-weight: 600; letter-spacing: 0.04em;
  box-shadow: 0 10px 30px rgba(10, 26, 40, 0.25);
  transition: opacity 0.45s var(--ease-ui), transform 0.45s var(--ease-ui);
}
.pill-cta__arrow {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 0 0 auto;
  width: 28px; height: 28px; border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.5);
  font-family: "Outfit", sans-serif; font-size: 13px; line-height: 1;
  transition: transform 0.3s var(--ease-ui);
}
.pill-cta:hover .pill-cta__arrow { transform: translateX(3px); }
.pillstack { transition: opacity 0.45s var(--ease-ui), transform 0.45s var(--ease-ui); }
.pillstack--hidden { opacity: 0; transform: translateX(-50%) translateY(16px); pointer-events: none; }
.pill-cta--back { opacity: 0; transform: scale(0.95); pointer-events: none; }
.pill-cta--front { opacity: 1; transform: scale(1); }
.pill-cta--gone { opacity: 0; transform: scale(1.04); pointer-events: none; }

/* ---------------- scenes ---------------- */
.scene { position: relative; z-index: 10; }
.scene--dark { color: #fff; }
.scene--white, .scene--pale { color: var(--ink); }

/* 190vh meant 0.9 of a screen where the reader scrolls and nothing moves on
   to the next section. Measured across the page that was 5.8 screens of held
   scrub out of 22.7 — a quarter of the scroll. The scrub still has to be long
   enough to read as a scrub, so these come down rather than away. */
.beat { height: 150vh; position: relative; }
/* the client found Why Cairo FACE slow to scroll through — shorter beats */
#about .beat { height: 130vh; }
#about .beat:has(.cardgrid) { height: 200vh; }
.beat--tall { height: 168vh; }
/* a short punctuation beat (single CTA) — no long empty scroll stretch */
.beat--brief { height: 110vh; }
.beat__inner {
  position: sticky; top: 0;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  gap: 22px;
  align-items: center; text-align: center;
  /* The stage centres its content in exactly one screen with nothing held
     back at the edges, so on any window where the content nearly fills it
     the last element — always a CTA — ends up flush against the section
     boundary and reads as sitting on the join. Reserve the band. */
  padding-block: clamp(20px, 4vh, 48px);
  box-sizing: border-box;
}
.beat__inner > * { max-width: 720px; }
.beat__inner--left { align-items: flex-start; text-align: left; }
.beat__inner--left > * { max-width: 680px; }
.beat__inner .body { max-width: 62ch; }

/* a film-styled section with its own solid ground (no canvas behind) */
.scene--solid { background: #0C1828; }

/* per-scene fallback + flat-mode backgrounds (canvas paints these live) */
/* the hero ground is the artwork's ground exactly, and stays opaque even in
   GL mode — so the scroll transition can never lighten behind the artwork
   and reveal its rectangle */
[data-scene="hero"]                         { background: #051C29; }
body:not(.film-gl) [data-scene="manifesto"] { background: linear-gradient(180deg, #0C1828 0%, #1E1A32 62%, #1E1A32 100%); }
body:not(.film-gl) [data-scene="numbers"]   { background: #F5EBE0; }
body:not(.film-gl) [data-scene="plan"]      { background: linear-gradient(180deg, #2C2440 0%, #1E1A32 100%); }
body:not(.film-gl) [data-scene="days"]      { background: #141828; }
body:not(.film-gl) [data-scene="voices"]    { background: #F5EBE0; }
body:not(.film-gl) [data-scene="abstract"]  { background: linear-gradient(180deg, #A83020 0%, #2C2440 100%); }
body:not(.film-gl) .beat, body:not(.film-gl) .beat--tall { height: auto; }
body:not(.film-gl) .beat__inner { position: static; min-height: 0; padding-block: 96px; }

/* the extracted contour face, reused as quiet set-dressing in dark sections */
.section-face {
  position: absolute; right: -5vw; top: 50%;
  transform: translateY(calc(-50% + var(--par, 0px)));
  width: min(64vw, 1040px); max-width: none;
  opacity: 0.45; pointer-events: none; user-select: none;
}
.beat__inner--withface > *:not(.section-face) { position: relative; z-index: 1; }
.section-face--footer {
  top: 2%; bottom: auto; right: -4vw; transform: none;
  width: min(46vw, 720px); opacity: 0.28;
}
.footer > .container, .footer .wordmark { position: relative; z-index: 1; }

/* ---------------- the opening: the face alone, then the page ---------------- */
.header, .rail, .pillstack { transition: opacity 1s var(--ease-ui); }
body.intro .header, body.intro .rail, body.intro .pillstack {
  opacity: 0; pointer-events: none;
}
.hero__act--1 > * {
  transition: opacity 1s var(--ease-ui), transform 1.1s var(--ease-out);
}
body.intro .hero__act--1 > * {
  opacity: 0; transform: translateY(14px); pointer-events: none;
}
/* staggered arrival once the intro releases */
body:not(.intro) .hero__act--1 > *:nth-child(2) { transition-delay: 0.14s; }
body:not(.intro) .hero__act--1 > *:nth-child(3) { transition-delay: 0.28s; }
body:not(.intro) .hero__act--1 > *:nth-child(4) { transition-delay: 0.4s; }
body:not(.intro) .hero__act--1 > *:nth-child(5) { transition-delay: 0.52s; }

/* hero: the three education pillars as chips — each its own color, and on
   hover its ground becomes a blurred scene of the thing itself */
.hero__tags { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; }
.hero__tag {
  position: relative; overflow: hidden;
  border-radius: 12px;
  border: 1px dashed rgba(var(--tagc), 0.55);
  color: rgb(var(--tagc));
  font-family: "Outfit", Arial, sans-serif;
  font-size: 13px; font-weight: 500; letter-spacing: 0.08em;
  backdrop-filter: blur(6px);
}
.hero__tag > span { position: relative; z-index: 1; display: inline-block; padding: 12px 22px; }
.hero__tag::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-color: rgba(var(--tagc), 0.12);
}
.hero__tag::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: linear-gradient(rgba(12, 24, 40, 0.42), rgba(12, 24, 40, 0.52)), var(--tagimg);
  background-size: cover; background-position: center;
  opacity: 0; transform: scale(1.14);
  transition: opacity 0.5s var(--ease-ui), transform 3.5s var(--ease-out);
}
.hero__tag:hover::after { opacity: 1; transform: scale(1); }
.hero__tag:hover { color: #fff; border-color: rgba(var(--tagc), 0.8); }
.hero__tag--surgery  { --tagc: 132, 214, 202; --tagimg: url("../img/chip-surgery.jpg?v=b4"); }
.hero__tag--training { --tagc: 168, 48, 32; --tagimg: url("../img/chip-training.jpg?v=b4"); }
.hero__tag--network  { --tagc: 148, 194, 232; --tagimg: url("../img/chip-network.jpg?v=b4"); }

/* …and the whole hero atmosphere follows the hovered chip: a full-stage
   blurred scene + color wash fades in beneath the face */
.hero__bg {
  --veil: 0; /* scrim strength; raised at narrow widths below */
  position: absolute; inset: 0; z-index: 2; /* over the face, under the copy */
  max-width: none !important;
  pointer-events: none;
  overflow: hidden;
}
.hero__bg-layer {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  transform: scale(1.08);
  filter: blur(26px) saturate(1.35) brightness(1.6);
  opacity: 0;
  transition: opacity 0.9s var(--ease-ui);
}
/* the surgery layer carries a real OR photograph — lighter blur and no
   brightness push, so the scene itself reads */
.hero__bg--surgery  {
  background-image: linear-gradient(rgba(8, 40, 52, 0.3), rgba(12, 24, 40, 0.58)), url("../img/chip-surgery.jpg?v=b4");
  filter: blur(9px) saturate(1.1);
}
/* the training layer is also a real photograph — same photographic recipe */
.hero__bg--training {
  background-image: linear-gradient(rgba(10, 44, 42, 0.3), rgba(12, 24, 40, 0.58)), url("../img/chip-training.jpg?v=b4");
  filter: blur(9px) saturate(1.1);
}
/* the networking layer is a real photograph too — photographic recipe */
.hero__bg--network  {
  background-image: linear-gradient(rgba(14, 36, 70, 0.3), rgba(12, 24, 40, 0.58)), url("../img/chip-network.jpg?v=b4");
  filter: blur(9px) saturate(1.1);
}
#hero:has(.hero__tag--surgery:hover)  .hero__bg--surgery,
#hero:has(.hero__tag--training:hover) .hero__bg--training,
#hero:has(.hero__tag--network:hover)  .hero__bg--network { opacity: 0.62; }

/* hero extras */
.beat__inner--hero { justify-content: center; }
/* the hero plays in two acts on one stage: the title holds the opening,
   then hands the frame to the details as you scroll — all scrubbed,
   all reversible */
.hero__copy {
  position: relative; z-index: 3;
  display: grid; width: 100%;
}
.hero__act {
  grid-area: 1 / 1;
  display: flex; flex-direction: column; align-items: center;
  gap: 22px; width: 100%;
}
.hero__act > * { max-width: min(760px, 92%); }
/* act 1 — present at rest, rises away as the story turns */
.hero__act--1 {
  opacity: calc(1 - clamp(0, (var(--bp, 0) - 0.14) * 5, 1));
  transform: translateY(calc(var(--bp, 0) * -130px));
}
/* act 2 — arrives from below, then hands off to the next scene */
.hero__act--2 {
  margin-top: 9vh; /* sits lower — the frame reads composed, not empty */
  opacity: calc(clamp(0, (var(--bp, 0) - 0.24) * 5, 1) - clamp(0, (var(--bp, 0) - 0.8) * 6, 1));
  transform: translateY(calc(52px - clamp(0, (var(--bp, 0) - 0.24) * 5, 1) * 52px - clamp(0, (var(--bp, 0) - 0.8) * 6, 1) * 90px));
  pointer-events: none;
}
.hero--p2 .hero__act--1 { pointer-events: none; }
.hero--p2 .hero__act--2 { pointer-events: auto; }
/* flat mode / no scrub: both acts read as one composition */
body:not(.film-gl) .hero__act { position: static; opacity: 1; transform: none; pointer-events: auto; }
body:not(.film-gl) .hero__copy { display: flex; flex-direction: column; align-items: center; gap: 22px; }

/* the headline: the edition chip crowns the summit name */
.hero__title {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px;
  font-size: clamp(24px, 4.7vw, 72px);
  font-weight: 500; line-height: 1.08; letter-spacing: -0.02em;
}
.chip-edition {
  align-self: center; white-space: nowrap;
  padding: 10px 18px; border-radius: 9999px;
  background: rgba(168, 48, 32, 0.14);
  border: 1px solid rgba(168, 48, 32, 0.55);
  color: #F0D8C4;
  font-size: clamp(11px, 0.85vw, 14px); font-weight: 600;
  letter-spacing: 0.14em;
}
/* one moving-gradient treatment, shared by every hero headline that uses it */
.hero__tagline, .hero__lead {
  background: linear-gradient(100deg, #F5EBE0 0%, #D4907A 30%, #D4907A 50%, #F5EBE0 70%, #F0D8C4 100%);
  background-size: 300% 100%;
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
  animation: tagline-sheen 8s linear infinite;
}
@keyframes tagline-sheen { to { background-position: -300% 0; } }
.hero__tagline {
  font-size: clamp(17px, 2.2vw, 34px);
  font-weight: 500; line-height: 1.3;
}
/* act two opens on its own headline, not a body line */
.hero__lead {
  font-size: clamp(24px, 3.2vw, 44px);
  font-weight: 500; line-height: 1.18; letter-spacing: -0.01em;
  max-width: 22ch; margin-inline: auto;
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .hero__tagline, .hero__lead { animation: none; background-position: 0 0; }
}

/* the date as a calendar tile beside the place */
.hero__cal {
  display: flex; align-items: stretch;
  border: 1px solid var(--hairline-dark); border-radius: 16px;
  overflow: hidden;
  background: rgba(7, 30, 50, 0.42);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}
.hero__cal-date {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  flex: none; white-space: nowrap;
  gap: 2px; padding: 14px 22px;
  background: rgba(168, 48, 32, 0.2);
  border-inline-end: 1px solid var(--hairline-dark);
}
.hero__cal-month {
  font-family: "Outfit", Arial, sans-serif;
  font-size: 11px; font-weight: 600; letter-spacing: 0.14em;
  color: #F0D8C4;
}
.hero__cal-days { font-size: 30px; font-weight: 600; letter-spacing: -0.01em; line-height: 1; }
.hero__cal-place {
  display: flex; flex-direction: column; justify-content: center; align-items: flex-start;
  gap: 5px; padding: 14px 24px; text-align: left;
}
.hero__cal-place .heading { font-size: 20px; }

/* the hero woman — the reference artwork itself, blended into the ground.
   The page's hero background is the artwork's exact ground (#071E32), so
   there is no rectangle to hide; the left edge is masked to dissolve the
   artwork into the copy zone. */
.hero__face {
  position: absolute; inset: 0; z-index: 1;
  max-width: none !important; /* exempt from the copy column's width cap */
  display: flex; align-items: center; justify-content: flex-end;
  pointer-events: none;
  overflow: hidden;
}
.hero__face-canvas {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}
/* a quiet navy wash over the seam so the copy always wins */
.hero__face::after {
  content: "";
  position: absolute; inset: 0;
  background: radial-gradient(ellipse 60% 66% at 50% 46%, rgba(12, 24, 40, 0.68) 0%, rgba(12, 24, 40, 0.34) 55%, rgba(12, 24, 40, 0) 78%);
}
@media (max-width: 600px) {
  /* the supporting sizes step down so the summit name clearly leads */
  .hero__title { font-size: clamp(22px, 6.4vw, 72px); }
  .chip-edition { padding: 8px 14px; font-size: 10px; }
  .hero__tagline { font-size: 16px; }
  .hero__lead { font-size: 22px; max-width: 18ch; }
  .hero__copy .hero__welcome { font-size: 15px; }
  .hero__tag { font-size: 11px; }
  .hero__tag > span { padding: 10px 16px; }
  .hero__cal-days { font-size: 24px; }
  .hero__cal-place .heading { font-size: 16px; }
  .hero__cal-place .label { font-size: 10px; }
  .hero__copy .btn-pill, .hero__copy .btn-ghost { font-size: 13px; }
}
/* regular weight so the bold "3 days of" actually leads the sentence */
.hero__welcome { color: inherit; opacity: 0.85; max-width: 52ch; font-weight: 400; }
.hero__welcome strong { font-weight: 700; }

/* hero CTAs */
.hero__ctas { display: flex; align-items: center; justify-content: center; gap: 12px; margin-top: 4px; }
.btn-pill {
  display: inline-flex; align-items: center; gap: 10px;
  height: 48px; padding-block: 0; padding-inline: 24px 8px; border-radius: 9999px;
  background: var(--accent); color: #fff;
  font-family: "Outfit", Arial, sans-serif;
  font-size: 14px; font-weight: 600; letter-spacing: 0.08em;
  transition: background 0.3s var(--ease-ui);
}
.btn-pill:hover { background: var(--accent-strong); }
.btn-pill .circle-arrow--sm { background: rgba(255, 255, 255, 0.18); transition: transform 0.32s var(--ease-ui); }
.btn-pill:hover .circle-arrow--sm { transform: translateX(3px); }
.btn-ghost {
  display: inline-flex; align-items: center;
  height: 48px; padding: 0 24px; border-radius: 9999px;
  border: 1px solid var(--hairline-dark);
  font-family: "Outfit", Arial, sans-serif;
  font-size: 14px; font-weight: 600; letter-spacing: 0.08em;
  transition: border-color 0.3s var(--ease-ui), background 0.3s var(--ease-ui);
}
.btn-ghost:hover { border-color: #fff; background: rgba(255, 255, 255, 0.08); }

/* manifesto */
.manifesto { max-width: 24ch; }
.manifesto__vision { color: var(--muted-light); font-weight: 500; }

/* why — core benefits */
.benefits {
  list-style: none;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 32px; margin-top: 8px; width: 100%; max-width: 680px;
}
.benefits li {
  position: relative; display: flex; align-items: baseline; gap: 12px;
  padding: 14px 4px 14px 22px;
  border-bottom: 1px dashed var(--hairline-light);
}
.benefits .tick { position: absolute; left: 0; top: 22px; }
.benefits .body-l { font-weight: 400; }
.benefits--rich { max-width: 100%; }
.benefits--rich li { align-items: flex-start; padding: 20px 4px 20px 22px; }
.benefits--rich li div { display: flex; flex-direction: column; gap: 6px; }
.benefits--rich .body { color: var(--muted-light); max-width: 42ch; }

/* who should attend */
.audience {
  list-style: none;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 12px; margin-top: 8px; max-width: 760px;
}
.audience li {
  padding: 14px 28px; border-radius: 9999px;
  border: 1px dashed var(--hairline-dark);
  font-weight: 400;
}
.audience--rich {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px; max-width: 880px; width: 100%;
}
.audience--rich li {
  border-radius: 20px; padding: 24px 28px;
  display: flex; flex-direction: column; gap: 8px;
  text-align: left; align-items: flex-start;
}
.audience--rich .heading { font-size: clamp(19px, 1.8vw, 24px); }
.audience--rich .body { opacity: 0.75; }

/* per-character reveal */
/* typography choreography: each character rises, sharpens and lights as the
   scrub reaches it — a traveling settle across the headline */
[data-split] .ch, [data-split-progress] .ch {
  display: inline-block;
  color: var(--ch-dim);
  opacity: 0.7;
  transform: translateY(0.16em);
  filter: blur(2px);
  transition:
    color 0.32s ease-out,
    opacity 0.55s ease-out,
    transform 0.75s var(--ease-out),
    filter 0.5s ease-out;
}
[data-split] .ch.on, [data-split-progress] .ch.on {
  color: var(--ch-lit);
  opacity: 1;
  transform: none;
  filter: blur(0);
}
.scene--white [data-split-progress], .scene--pale [data-split-progress],
.tail [data-split] { --ch-dim: rgba(10, 26, 40, 0.2); --ch-lit: var(--ink); }
.scene--dark [data-split-progress] { --ch-dim: rgba(255, 255, 255, 0.28); --ch-lit: #fff; }

/* late body reveal, driven by the beat's --bp progress */
/* was 0.34: a third of every pinned scrub was a stage with the headline and
   nothing under it, which is the "empty section" the client sees */
.lateshow { opacity: clamp(0, calc((var(--bp, 1) - 0.08) * 3.4), 1); }
body:not(.film-gl) .lateshow { opacity: 1; }

strong { font-weight: 600; }

/* ---------------- info cards (doc items → cards) ---------------- */
.cardgrid {
  display: grid; gap: 16px; width: 100%; max-width: 1240px;
}
.cardgrid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cardgrid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cardgrid--5 { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.cardgrid--5 > * { grid-column: span 2; }
/* the last two share the second row edge-to-edge — no leftover gap */
.cardgrid--5 > *:nth-child(n+4) { grid-column: span 3; }
.infocard {
  position: relative;
  display: flex; flex-direction: column; gap: 10px;
  align-items: flex-start; text-align: left;
  padding: 24px; border-radius: 20px;
  border: 1px dashed var(--hairline-light);
}
.infocard .body { color: var(--muted-light); }
.infocard--dark { border-color: var(--hairline-dark); color: #fff; }
.infocard--dark .body { color: rgba(255, 255, 255, 0.72); }
.infocard__icon { width: 32px; height: 32px; color: var(--accent); }
.infocard--dark .infocard__icon { color: #F0D8C4; }
.infocard__icon svg { width: 100%; height: 100%; }

/* ---------------- rail arrows ---------------- */
.railside { display: flex; align-items: center; gap: 16px; }
.railnav { display: flex; gap: 8px; }
.railnav[hidden] { display: none; }
.railnav__btn { transition: background 0.3s var(--ease-ui); }
.railnav__btn:hover { background: var(--accent-strong); }

/* ---------------- testimonials rail + event photos ---------------- */
.cardrail--quotes { scroll-snap-type: x mandatory; }
.quotecard {
  flex: none; width: min(720px, 86vw);
  scroll-snap-align: start;
  display: flex; flex-direction: column; justify-content: center; gap: 20px;
  padding: 40px; border-radius: 20px;
  border: 1px dashed var(--hairline-light);
}
.photos { margin-top: 48px; display: flex; flex-direction: column; gap: 20px; }
.photo-feature {
  position: relative; margin: 0;
  width: min(420px, 100%);
  aspect-ratio: 3 / 4;
  /* How far the deck deals out.

     This used to be a percentage, and a percentage resolves against the
     figure — which is a fixed 420px on any desktop. So one number produced
     the SAME absolute spread at 1280 as at 1440, and the band had to be set
     narrow enough for the smallest screen in it: measured at 1440 the open
     deck covered 456px, 29% of the window, with 510px of empty page either
     side. Tuning per breakpoint just moved the compromise around — at 66%
     the prints then hung 42px off the edge at 1280.

     So the distance is measured against the VIEWPORT instead, and one
     expression serves every width: half the window, less the room the
     outermost print needs for its own width and its 10deg tilt. The near
     pair keeps the original 0.52 ratio to the far pair. */
  --spread2: clamp(120px, calc(50vw - 260px), 680px);
  --spread: calc(var(--spread2) * 0.52);
  --deck: 1;        /* how much the whole composition pulls back */
  --lift: 0px;      /* and how far it rises as it opens */
}
.photo-feature img {
  position: relative; z-index: 1;
  width: 100%; height: 100%; object-fit: cover; display: block;
  border-radius: 20px;
  box-shadow: 0 18px 44px rgba(10, 26, 40, 0.16);
}
/* the gallery behind: printed photos fanning open as you scroll (--fan
   is scrubbed 0..1 by main.js) */
.photo-fan {
  position: absolute; inset: 0; z-index: 0;
  border-radius: 18px;
  border: 6px solid #fff;
  background: #141828 center/cover no-repeat;
  background-image: url("../img/ev-artwork.jpg?v=b4");
  box-shadow: 0 14px 34px rgba(10, 26, 40, 0.2);
  transform-origin: 50% 88%;
  pointer-events: none;
}
/* the deck: four real prints deal out from behind the hero photo — the
   near pair first, the far pair a beat later (--fan2 lags --fan), each on
   its own slight arc and tilt, spreading wide enough to be seen whole. */
.photo-fan--l {
  background-image: url("../img/ev-artwork.jpg?v=b4");
  transform:
    translateY(var(--lift, 0px)) scale(var(--deck, 1))
    rotate(calc(var(--fan, 0) * -5deg))
    translate(calc(var(--fan, 0) * var(--spread) * -1), calc(var(--fan, 0) * -12px + var(--fan, 0) * var(--fan, 0) * 26px))
    scale(calc(0.94 - var(--fan, 0) * 0.02));
}
.photo-fan--r {
  background-image: url("../img/ev-dates.jpg?v=b4");
  transform:
    translateY(var(--lift, 0px)) scale(var(--deck, 1))
    rotate(calc(var(--fan, 0) * 5deg))
    translate(calc(var(--fan, 0) * var(--spread)), calc(var(--fan, 0) * -8px + var(--fan, 0) * var(--fan, 0) * 30px))
    scale(calc(0.94 - var(--fan, 0) * 0.02));
}
.photo-fan--l2 {
  background-image: url("../img/ev-abstract.jpg?v=b4");
  transform:
    translateY(var(--lift, 0px)) scale(var(--deck, 1))
    rotate(calc(var(--fan2, 0) * -10deg))
    translate(calc(var(--fan2, 0) * var(--spread2) * -1), calc(var(--fan2, 0) * -6px + var(--fan2, 0) * var(--fan2, 0) * 44px))
    scale(calc(0.9 - var(--fan2, 0) * 0.04));
}
.photo-fan--r2 {
  background-image: url("../img/ev-artwork.jpg?v=b4");
  transform:
    translateY(var(--lift, 0px)) scale(var(--deck, 1))
    rotate(calc(var(--fan2, 0) * 10deg))
    translate(calc(var(--fan2, 0) * var(--spread2)), calc(var(--fan2, 0) * -2px + var(--fan2, 0) * var(--fan2, 0) * 48px))
    scale(calc(0.9 - var(--fan2, 0) * 0.04));
}
/* the hero print answers with a breath of counter-tilt */

/* The pill is a sibling of the hero print, not a child, so a plain
   `bottom: 16px` pins it to the figure box while the print shrinks by --deck
   and rises by --lift away from it — at full fan it was left 112px adrift,
   sitting on the fanned prints behind. Walk it back by the height the print
   loses and the distance it rose. */
.photo-feature__cta {
  position: absolute; left: 50%;
  bottom: calc(16px + 50% * (1 - var(--deck, 1)) - var(--lift, 0px));
  transform: translateX(-50%);
  border: 0; background: rgba(255, 255, 255, 0.92); color: #0C1828;
  backdrop-filter: blur(6px); white-space: nowrap;
}
.photo-feature__cta:hover { background: #fff; }

/* ---------------- video testimonial cards + lightbox ---------------- */
.qvcard {
  flex: none; width: min(480px, 86vw);
  scroll-snap-align: start;
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 16px 16px 24px; border-radius: 20px;
  border: 1px solid rgba(168, 48, 32, 0.24);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.4));
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 8px 24px rgba(10, 26, 40, 0.05);
  text-align: center; cursor: pointer;
}
.qvcard__poster {
  position: relative; width: 100%; aspect-ratio: 16 / 9;
  border-radius: 12px; overflow: hidden;
  background: #141828 center/cover no-repeat;
  display: flex; align-items: center; justify-content: center;
}
.qvcard__poster::before {
  content: ""; position: absolute; inset: 0;
  background: rgba(12, 24, 40, 0.22);
  transition: background 0.35s var(--ease-ui);
}
.qvcard__play {
  position: relative; z-index: 1;
  display: flex; align-items: center; justify-content: center;
  width: 64px; height: 64px; border-radius: 9999px;
  background: rgba(255, 255, 255, 0.92); color: var(--accent-strong);
  font-size: 20px; padding-left: 5px;
  box-shadow: 0 10px 28px rgba(2, 12, 20, 0.35);
  transition: transform 0.35s var(--ease-out);
}
.qvcard:hover .qvcard__poster::before { background: rgba(12, 24, 40, 0.05); }
.qvcard:hover .qvcard__play { transform: scale(1.1); }
.qvcard__title { font-size: clamp(18px, 1.8vw, 24px); }
.qvcard__quote { color: var(--muted-light); max-width: 44ch; }

.vlb { position: fixed; inset: 0; z-index: 80; opacity: 0; transition: opacity 0.35s var(--ease-ui); }
.vlb--in { opacity: 1; }
.vlb__scrim { position: absolute; inset: 0; background: rgba(3, 14, 22, 0.86); backdrop-filter: blur(8px); }
.vlb__frame {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: min(1080px, 92vw); aspect-ratio: 16 / 9;
  border-radius: 16px; overflow: hidden;
  box-shadow: 0 40px 120px rgba(0, 0, 0, 0.6);
  background: #000;
}
.vlb__frame iframe { width: 100%; height: 100%; border: 0; display: block; }
.vlb__close {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 42px; height: 42px; border-radius: 9999px;
  background: rgba(255, 255, 255, 0.92); color: #0C1828; font-size: 22px; line-height: 1;
}
body.vlb-open { overflow: hidden; }

/* ---------------- pricing toggle (the visitor chooses) ---------------- */
/* wrap: two nowrap tabs will not sit side by side on a phone, so the second
   takes its own row rather than squeezing the pair into two lines of text
   each — same pill, same padding, just stacked */
.pricing__toggle { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 24px; }
.ptab {
  padding: 12px 28px; border-radius: 9999px;
  /* every other pill in the system is nowrap; these two were not, so
     "Video testimonials" and "Written testimonials" broke across two lines
     inside a 67px-tall pill */
  white-space: nowrap;
  border: 1px solid var(--hairline-light);
  font-family: "Outfit", Arial, sans-serif;
  font-size: 14px; letter-spacing: 0.08em;
  transition: background 0.3s var(--ease-ui), color 0.3s var(--ease-ui), border-color 0.3s var(--ease-ui);
}
.ptab.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.price-panel { max-width: 900px; }
.price-line {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px;
  padding: 20px 0; border-bottom: 1px dashed var(--hairline-light);
}
.price-line:last-child { border-bottom: none; }
.pricing__cta { margin-top: 24px; }

.endorse__card--logo { align-items: center; text-align: center; gap: 10px; padding: 48px 32px; }
/* "Endorsed by" — the acronym leads, the CTA is pinned so both cards align */
.endorse__card--org {
  gap: 12px; padding: 40px 40px 32px;
  border: 1px solid var(--hairline-light);
  /* solid white for the same reason as .logoplate: the ISAPS and EAFPS files
     ship on opaque white, so any tint on the card frames each mark in a
     visible rectangle */
  background: #fff;
}
.endorse__mark {
  font-size: clamp(32px, 3.4vw, 44px); font-weight: 600; letter-spacing: -0.01em;
  line-height: 1; color: var(--accent-strong);
}
.endorse__name { font-size: 20px; font-weight: 500; line-height: 1.3; }
.endorse__card--org .body { color: var(--muted-light); }
.endorse__cta { margin-top: auto; padding-top: 4px; }

/* cards arrive ONE PER SCROLL STEP — each owns a stretch of the beat */
.cardgrid.lateshow, .audience.lateshow { opacity: 1; }
.cardgrid > *, .audience--rich > li {
  opacity: clamp(0, calc((var(--bp, 1) - var(--d, 0.12)) * 5), 1);
  transform: translateY(calc((1 - clamp(0, calc((var(--bp, 1) - var(--d, 0.12)) * 5), 1)) * 22px));
}
.cardgrid > *:nth-child(1), .audience--rich > li:nth-child(1) { --d: 0.06; }
.cardgrid > *:nth-child(2), .audience--rich > li:nth-child(2) { --d: 0.24; }
.cardgrid > *:nth-child(3), .audience--rich > li:nth-child(3) { --d: 0.42; }
.cardgrid > *:nth-child(4), .audience--rich > li:nth-child(4) { --d: 0.6; }
.cardgrid > *:nth-child(5) { --d: 0.78; }
/* the card beats run longer, giving each card its own scroll dwell */
.beat:has(.cardgrid), .beat:has(.audience--rich), .beat:has(.whoscene), .beat:has(.gainscene) { height: 300vh; }
body:not(.film-gl) .cardgrid > *, body:not(.film-gl) .audience--rich > li { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .cardgrid > *, .audience--rich > li { opacity: 1; transform: none; }
}

/* the Cairo FACE contour motif — a cheek-line curve, the recurring signature */
.motif { width: 108px; height: 46px; color: var(--accent); opacity: 0.55; flex: none; }
.scene--dark .motif, .footer .motif { color: #D4907A; opacity: 0.4; }

/* speakers: portrait reveal — dim → clear, a contour light passes, name arrives */
.scard__media::after {
  content: ""; position: absolute; left: -20%; right: -20%; top: -30%; height: 26%;
  background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(214,229,238,0.16) 50%, rgba(255,255,255,0) 100%);
  transform: rotate(-8deg);
  opacity: 0;
}
.scard img { filter: saturate(0.35) brightness(0.82); transition: filter 1.3s var(--ease-ui); }
.scard .scard__name, .scard .scard__sub, .scard .scard__more {
  opacity: 0; transform: translateY(8px);
  transition: opacity 0.8s var(--ease-ui) 0.35s, transform 0.9s var(--ease-out) 0.35s;
}
.scard .scard__sub { transition-delay: 0.45s; }
.scard .scard__more { transition-delay: 0.55s; }
.scard.seen img { filter: none; }
.scard.seen .scard__name, .scard.seen .scard__sub, .scard.seen .scard__more { opacity: 1; transform: none; }
.scard.seen .scard__media::after { animation: portrait-sweep 1.1s var(--ease-ui) 0.15s 1 both; }
@keyframes portrait-sweep {
  from { opacity: 1; top: -30%; }
  to { opacity: 0; top: 110%; }
}

/* stats: editorial arrival — each figure settles in turn */
.stat { opacity: 0; transform: translateY(12px); transition: opacity 0.9s var(--ease-ui), transform 1s var(--ease-out); }
.stat.seen { opacity: 1; transform: none; }

/* stats — numbers lead, labels follow, rows stay centered */
.stats {
  display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start;
  gap: 48px 72px; margin-top: 16px; width: 100%;
}
.stat { display: flex; flex-direction: column; gap: 10px; align-items: center; min-width: 150px; }
.stat dd {
  font-size: clamp(48px, 6vw, 92px); font-weight: 300; line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums;
}
.stat dt { order: 2; max-width: 18ch; text-align: center; }
.stat dd small { font-size: 0.28em; font-weight: 500; letter-spacing: 0.08em; margin-left: 8px; }
.beat__inner .stats { max-width: 1280px; }

/* day marker */
.opp__day {
  display: flex; flex-direction: column; gap: 2px;
  width: 110px; height: 110px; border-radius: 9999px;
  border: 1px dashed currentColor;
  align-items: center; justify-content: center;
  opacity: 0.9;
}
.opp__day b { font-size: 28px; font-weight: 300; letter-spacing: -0.01em; }

/* ---------------- DOM tail ---------------- */
.tail { position: relative; z-index: 10; background: var(--paper); padding: 128px 0; }
.tail.committee { background: var(--paper-2); }

.speakers__head {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 20px;
  margin-bottom: 48px;
}
/* heading first, controls beneath it — one centered column */
.speakers__head--stacked {
  flex-direction: column; align-items: center; justify-content: flex-start;
  gap: 24px; text-align: center;
}
.speakers__head--stacked .railside { justify-content: center; }
/* controls sit centered beneath the speaker cards */
.railside--under {
  display: flex; align-items: center; justify-content: center; gap: 16px;
  margin-top: 24px;
}
.speakers__head h2 { margin-top: 10px; }

/* the card rail — horizontal, scroll-snap, continues past the edge */
.cardrail {
  display: flex; gap: 28px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--pad);
  padding: 6px var(--pad) 24px;
  -webkit-overflow-scrolling: touch;
}
.cardrail { scrollbar-width: thin; scrollbar-color: rgba(168, 48, 32, 0.3) transparent; }
.cardrail::-webkit-scrollbar { height: 4px; }
.cardrail::-webkit-scrollbar-track { background: transparent; }
.cardrail::-webkit-scrollbar-thumb { background: rgba(168, 48, 32, 0.3); border-radius: 9999px; }
/* the speaker card: a full-bleed portrait with a frosted panel resting on a
   progressive blur — name, role, and one clear action on the photo itself */
.scard {
  position: relative;
  flex: none; width: min(408px, 80vw);
  aspect-ratio: 9 / 14;
  border-radius: 24px; overflow: hidden;
  background: #141828;
  scroll-snap-align: start;
  display: block;
}
.scard__media { position: absolute; inset: 0; overflow: hidden; }
.scard__media img {
  width: 100%; height: 100%; object-fit: cover; object-position: top;
  display: block;
}
.scard__badge {
  position: absolute; top: 14px; right: 14px; z-index: 2;
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 9999px;
  background: rgba(255, 255, 255, 0.14);
  border: 1px solid rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  color: #fff; font-size: 16px;
  transform: rotate(-45deg);
  transition: background 0.3s var(--ease-ui);
}
.scard:hover .scard__badge { background: rgba(255, 255, 255, 0.28); }
.scard__panel {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-start; text-align: left;
  gap: 4px; padding: 64px 18px 18px;
  color: #fff;
}
.scard__panel::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(6, 20, 31, 0) 0%, rgba(6, 20, 31, 0.42) 45%, rgba(6, 20, 31, 0.62) 100%);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  mask-image: linear-gradient(180deg, transparent 0%, #000 62%);
  -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 62%);
}
.scard__name { font-size: 28px; font-weight: 600; letter-spacing: -0.01em; color: #fff; }
.scard__sub { font-size: 15px; color: rgba(255, 255, 255, 0.62); }
.scard__more {
  width: 100%; margin-top: 24px;
  display: flex; align-items: center; justify-content: center;
  height: 48px; border-radius: 9999px;
  background: rgba(255, 255, 255, 0.92); color: #0C1828;
  font-size: 14px; font-weight: 600; letter-spacing: 0.04em;
  transition: background 0.3s var(--ease-ui);
}
.scard:hover .scard__more { background: #fff; }
.scard--more {
  display: flex; flex-direction: column;
  justify-content: center; align-items: center; text-align: center; gap: 16px;
  background: linear-gradient(180deg, #1E1A32 0%, #141828 100%);
  color: #fff; padding: 24px;
}
.scard--more .label--dim { color: rgba(255, 255, 255, 0.6); max-width: 22ch; }
.scard--more .circle-arrow { background: rgba(255, 255, 255, 0.14); border: 1px solid rgba(255, 255, 255, 0.25); color: #fff; }
.scard:hover .circle-arrow { transform: translateX(3px); }

.spindex { margin-top: 48px; display: flex; flex-direction: column; gap: 16px; }
.spindex__names {
  columns: 3; column-gap: 28px;
  font-size: 17px; line-height: 1.9; color: var(--muted-light);
}

/* committee */
.committee__grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0 28px;
  margin-top: 48px;
}
.member {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 14px 4px; border-bottom: 1px dashed var(--hairline-light);
}
.member .body-l { font-weight: 400; }

/* pricing */
.pricing__head {
  display: flex; justify-content: space-between; align-items: flex-end; gap: 20px;
  margin-bottom: 48px;
}
.pricing__head h2 { margin-top: 10px; }
.pricing__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.price-card {
  position: relative; padding: 40px; border-radius: 20px;
  border: 1px dashed var(--hairline-light);
  display: flex; flex-direction: column; gap: 8px; align-items: stretch;
}
.price-card > .label { margin-bottom: 12px; }
.price-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: 16px;
  padding: 16px 0; border-bottom: 1px dashed var(--hairline-light);
}
.price-row:last-child { border-bottom: none; }
.price-row .body-l { font-weight: 400; }
.price {
  font-size: clamp(28px, 3vw, 40px); font-weight: 300; line-height: 1;
  letter-spacing: -0.02em; font-variant-numeric: tabular-nums; white-space: nowrap;
}
.price small { font-size: 0.5em; font-weight: 400; letter-spacing: 0.04em; }
.price-card__inc { margin-top: 16px; color: var(--muted-light); max-width: 46ch; }
.pricing__note { margin-top: 32px; color: var(--muted-light); }
.u { text-decoration: underline; text-underline-offset: 3px; }

/* faq */
.faq__list { margin-top: 48px; max-width: 880px; }
.faq__item { border-bottom: 1px dashed var(--hairline-light); }
.faq__item summary {
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
  padding: 22px 4px; cursor: pointer; list-style: none;
  text-align: left;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary .body-l { font-weight: 400; }
.faq__item summary .circle-arrow--sm {
  background: var(--wash); color: var(--accent);
  transition: transform 0.32s var(--ease-ui), background 0.3s var(--ease-ui);
}
.faq__item[open] summary .circle-arrow--sm {
  transform: rotate(45deg); background: var(--accent); color: #fff;
}
.faq__item .body { padding: 0 4px 24px; max-width: 62ch; color: var(--muted-light); }

/* endorse */
.endorse__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; margin-top: 32px; }
.endorse__card {
  position: relative; padding: 40px; border-radius: 20px;
  border: 1px dashed var(--hairline-light);
  display: flex; flex-direction: column; gap: 16px; align-items: flex-start;
}
.endorse__card .body { color: var(--muted-light); max-width: 48ch; }

/* footer */
.footer { position: relative; z-index: 10; background: var(--grad-footer); color: #fff; padding: 96px 0 0; overflow: hidden; }
.footer__grid {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 48px 28px;
  padding-bottom: 72px; border-bottom: 1px dashed var(--hairline-dark);
}
.footer__col { display: flex; flex-direction: column; gap: 16px; align-items: flex-start; }
.footer__col--nav     { grid-column: 1 / span 2; }
.footer__col--about   { grid-column: 3 / span 2; }
.footer__col--contact { grid-column: 5 / span 3; }
.footer__col--social  { grid-column: 8 / span 2; }
.footer__col--brand   { grid-column: 11 / span 2; align-items: flex-end; text-align: right; gap: 24px; }
.footer__logo { width: 148px; height: auto; }
.footer__note { margin-top: 8px; }
.footer__links { display: grid; gap: 10px; }
.footer__links a { opacity: 0.85; transition: opacity 0.2s; font-size: 17px; }
.footer__links a:hover { opacity: 1; }
.footer__legal { display: flex; justify-content: space-between; gap: 16px; padding: 20px var(--pad); }
.wordmark {
  font-size: clamp(120px, 21vw, 400px); font-weight: 500; letter-spacing: -0.02em;
  line-height: 0.72; text-align: center; white-space: nowrap;
  margin-top: 24px; margin-bottom: -0.16em;
  background: linear-gradient(180deg, rgba(255,255,255,0.5) 0%, rgba(255,255,255,0.06) 80%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  user-select: none;
}


/* ==================================================================
   Centered alignment site-wide (the hero keeps the reference layout)
   ================================================================== */
.beat__inner--left:not(.beat__inner--hero) { align-items: center; text-align: center; }
.beat__inner--left:not(.beat__inner--hero) > * { max-width: 760px; }
.pricing__head, .speakers__head {
  flex-direction: column; align-items: center; text-align: center; gap: 20px;
}
.railside { justify-content: center; flex-wrap: wrap; }
.pricing .container { display: flex; flex-direction: column; align-items: center; text-align: center; }
.pricing__toggle { justify-content: center; }
.price-panel { width: 100%; }
.price-line { justify-content: center; }
.voices .photos { align-items: center; text-align: center; }
.endorse > .container { text-align: center; }
.endorse__grid { max-width: 1100px; margin-left: auto; margin-right: auto; }
.faq > .container { display: flex; flex-direction: column; align-items: center; text-align: center; }
/* every item spans the list — dividers align, questions read space-between */
.faq__list { width: 100%; }
.faq__list .faq__item { width: 100%; }
.infocard, .audience--rich li { align-items: center; text-align: center; }
.infocard { align-items: center; }
.quotecard { align-items: center; text-align: center; }
.footer { text-align: center; }
.footer__col { align-items: center; }
.footer__col--brand { align-items: center; text-align: center; }
.footer__legal { justify-content: center; }

/* ---------------- responsive ---------------- */
@media (max-width: 1400px) {
  .navpill { padding: 0 11px; }
}
@media (max-width: 1320px) {
  .nav-cta--secondary { display: none; }
}
@media (max-width: 1100px) {
  :root { --pad: 32px; } /* tablet gutters */
}
/* the full pill nav needs ~830px — below that the side menu takes over
   (the arrow CTA goes too: the drawer and hero both carry Register) */
@media (max-width: 920px) {
  .header__nav, .nav-ctas { display: none; }
  .menu-btn { display: block; }
}
/* narrow screens: the brand aligns to the pill edge, nudge cancelled */
@media (max-width: 767px) {
  .menu-pill.scrolling .header__brand { transform: none; }
  .menu-pill.scrolling .menu-btn { transform: none; }
  .menu-pill { padding: 8px 10px; }
}
@media (max-width: 1200px) {
  .cardgrid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spindex__names { columns: 2; }
  .committee__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer__grid { grid-template-columns: repeat(6, minmax(0, 1fr)); }
  .footer__col--nav     { grid-column: 1 / span 2; }
  .footer__col--about   { grid-column: 3 / span 2; }
  .footer__col--contact { grid-column: 5 / span 2; }
  .footer__col--social  { grid-column: 1 / span 3; }
  .footer__col--brand   { grid-column: 4 / span 3; align-items: center; }
}
@media (max-width: 768px) {
  :root { --pad: 16px; }
  .header__logo { height: 36px; }
  /* the scene rail crowds a small screen — the menu covers navigation */
  .rail { display: none; }
  /* decorative section faces add clutter at this size */
  .section-face { display: none; }
  .beat { height: 135vh; }
  .beat--tall { height: 200vh; }
  /* the film beats keep their cinematic pins, but shorter — enough for the
     scrub to play without long empty dwells on a small screen */
  .beat { height: 112vh; }
  .beat--tall { height: 145vh; }
  #hero .beat--tall { height: 165vh; }
  /* a pinned viewport-height stage cannot show a full one-column stack of
     cards — those beats flow naturally; the film beats keep their pins */
  .beat:has(.cardgrid), .beat:has(.audience--rich), .beat:has(.whoscene), .beat:has(.gainscene) { height: auto; overflow: hidden; }
  .beat:has(.cardgrid) > .beat__inner, .beat:has(.audience--rich) > .beat__inner,
  .beat:has(.whoscene) > .beat__inner, .beat:has(.gainscene) > .beat__inner {
    position: static; min-height: 0; padding-block: 72px;
  }
  /* one card at a time: each item reveals as IT enters the viewport */
  .cardgrid > *, .audience--rich li, .whoitem, .gitem {
    opacity: 0 !important;
    transform: translateY(30px);
    transition: opacity 0.8s var(--ease-ui), transform 0.9s var(--ease-out);
  }
  .cardgrid > *.seen, .audience--rich li.seen, .whoitem.seen, .gitem.seen {
    opacity: 1 !important;
    transform: none;
  }
  .whoitem.seen, .gitem.seen { transform: none; }
  .whoscene__stage, .gainscene__stage {
    transform:
      translateY(calc((1 - clamp(0, calc((var(--bp, 1) - var(--d, 0.04)) * 4), 1)) * 34px + var(--pary, 0px)))
      scale(calc(0.965 + clamp(0, calc((var(--bp, 1) - var(--d, 0.04)) * 4), 1) * 0.035));
  }
  /* depth: tagged layers drift at their own speeds through the viewport
     (JS writes --pary from each element's distance to viewport centre) */
  [data-par]:not(.whoscene__stage) { transform: translateY(var(--pary, 0px)); }
  /* lighter atmosphere on phones: same look, cheaper compositing */
  .ga-haze { filter: blur(26px); }
  .ga-haze--2 { display: none; }
  .vlb__scrim { backdrop-filter: none; background: rgba(3, 14, 22, 0.94); }
  /* pinned headings drift up as they settle */
  .beat__inner > .label, .beat__inner > h2, .beat__inner > .body-l {
    transform: translateY(calc((1 - clamp(0, calc(var(--bp, 1) * 3), 1)) * 22px));
  }
  .photo-feature img { transition-duration: 0.7s; }
  .stats { gap: 28px 24px; }
  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px 20px; }
  .footer__col--nav     { grid-column: 1 / span 1; }
  .footer__col--about   { grid-column: 2 / span 1; }
  .footer__col--contact { grid-column: 1 / span 2; }
  .footer__col--social  { grid-column: 1 / span 2; }
  .footer__col--brand   { grid-column: 1 / span 2; }
  .faq__item summary { padding: 18px 4px; }
  .hero__copy > * { max-width: 100%; }
  .audience--rich { grid-template-columns: 1fr; }
  .cardgrid--3, .cardgrid--4, .cardgrid--5 { grid-template-columns: 1fr; }
  .cardgrid--5 > *, .cardgrid--5 > *:nth-child(n+4) { grid-column: auto; }
  .quotecard .display-m { font-size: 22px; }
  .pillstack { width: 188px; height: 42px; bottom: 16px; }
  .pill-cta { padding: 0 12px; }
  .pill-cta__arrow { width: 28px; height: 28px; }
  html { scroll-padding-top: 92px; }
  /* centered copy needs a centered scrim, and clearance under the header */
  .hero__face::after {
    background: radial-gradient(ellipse 120% 62% at 50% 44%, rgba(12, 24, 40, 0.72) 0%, rgba(12, 24, 40, 0.4) 58%, rgba(12, 24, 40, 0.05) 82%);
  }
  .beat__inner--hero { padding-top: 76px; padding-bottom: 16px; }
  .hero__act { gap: 16px; }
  body:not(.film-gl) .hero__copy { gap: 16px; }
  .hero__ctas { flex-direction: column; align-items: stretch; }
  .btn-pill { justify-content: space-between; }
  .btn-ghost { justify-content: center; }
  .benefits { grid-template-columns: 1fr; gap: 0; }
  .audience { flex-direction: column; align-items: stretch; }
  .pricing__head { flex-direction: column; align-items: center; }
  .pricing__grid { grid-template-columns: 1fr; }
  .price-card { padding: 24px; }
  .speakers__head { flex-direction: column; align-items: center; }
  .spindex__names { columns: 1; }
  .committee__grid { grid-template-columns: 1fr; }
  .endorse__grid { grid-template-columns: 1fr; }
  .tail { padding: 72px 0; }
  .footer__legal { flex-direction: column; gap: 8px; }
}

/* ---------------- motion language ----------------
   One vocabulary across the site: the contour line draws itself, content
   settles upward into place, surfaces lift softly under the cursor, and
   CTAs lean toward the hand. Everything easing, nothing bouncing. */

/* the Cairo FACE motif writes itself in when it enters the frame
   (main.js normalizes every path to pathLength 100) */
.motif path {
  stroke-dasharray: 101;
  stroke-dashoffset: 101;
  transition: stroke-dashoffset 1.6s var(--ease-out) 0.15s;
}
.motif.seen path { stroke-dashoffset: 0; }

/* editorial arrival for the composed tail sections */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 0.9s var(--ease-ui), transform 1.05s var(--ease-out);
}
[data-reveal].seen { opacity: 1; transform: none; }

/* the featured photo settles out of a slow zoom as it reveals */
.photo-feature img {
  transform: scale(1.07);
  transition: transform 2.4s var(--ease-out);
}
/* the hero print rides the same --lift and --deck as the prints behind it;
   scoping that to phones left the 769-1799px band lifting the deck but not
   the print it fans out from */
.photo-feature.seen img {
  transform: translateY(var(--lift, 0px)) scale(var(--deck, 1)) rotate(calc(var(--fan, 0) * -1.4deg));
}

/* CTAs lean toward the cursor (transform driven by main.js) */
.mag { transition: transform 0.45s var(--ease-out); will-change: transform; }



/* surfaces lift softly; portraits breathe closer */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .infocard, .quotecard, .price-card, .endorse__card {
    transition: transform 0.5s var(--ease-out), box-shadow 0.5s var(--ease-ui), border-color 0.4s var(--ease-ui);
  }
  .infocard:hover, .quotecard:hover, .price-card:hover, .endorse__card:hover {
    transform: translateY(-5px);
  }
  .tail .quotecard:hover, .tail .price-card:hover, .tail .endorse__card:hover,
  .tail .infocard:hover {
    box-shadow: 0 24px 48px rgba(10, 26, 40, 0.09);
  }
  .infocard--dark:hover, .scene--dark .audience--rich li:hover {
    border-color: rgba(240, 216, 196, 0.5);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.12), 0 18px 44px rgba(2, 12, 20, 0.35);
  }
  .scard img { transition: filter 1.3s var(--ease-ui), transform 1.8s var(--ease-out); }
  .scard:hover img { transform: scale(1.045); }
  .scard__badge { transition: background 0.3s var(--ease-ui), transform 0.55s var(--ease-out); }
  .scard:hover .scard__badge { transform: rotate(0deg); }
  .faq__item summary .body-l { transition: color 0.3s var(--ease-ui); }
  .faq__item summary:hover .body-l { color: var(--accent-strong); }
}

/* small screens skip the per-character blur (GPU cost, invisible payoff) */
@media (max-width: 768px) {
  /* On a phone the headline lights as one quick wave rather than a long
     scrub, so the unlit state is only ever seen for a moment — but it is
     seen, and at 14% ink on a shifted baseline a half-finished line reads
     as broken, overlapping text rather than as an effect in flight. So the
     floor comes up: still clearly unlit, still clearly travelling, but
     legible at every frame of the wave and at rest if it ever stalls. */
  [data-split] .ch, [data-split-progress] .ch {
    filter: none;
    opacity: 1;
    transform: none;
  }
  .scene--white [data-split-progress], .scene--pale [data-split-progress],
  .tail [data-split] { --ch-dim: rgba(10, 26, 40, 0.34); }
  .scene--dark [data-split-progress] { --ch-dim: rgba(255, 255, 255, 0.44); }
  /* A phone cannot take five prints side by side, so the camera pulls back
     as the deck opens: --deck shrinks the whole composition in step with
     --fan and --lift raises it, both consumed by the shared transforms. */
  .photo-feature { --spread: 18%; --spread2: 34%;
    --deck: calc(1 - var(--fan, 0) * 0.42);
    --lift: calc(var(--fan, 0) * -52px); }
}


/* ---------------- content hierarchy ----------------
   One ladder everywhere: eyebrow (.label, 13px) → section headline
   (.display-l) → sub-headline (.body-l, 19/500) → body (.body, 16/400).
   Card titles sit between sub-headline and body — one spec for ALL cards. */
.infocard h3 {
  font-family: "Outfit", Arial, sans-serif;
  font-size: clamp(17px, 1.35vw, 20px);
  font-weight: 500; line-height: 1.25; letter-spacing: -0.01em;
}
/* testimonial pull-quotes read as sub-headline emphasis, not headlines */
.quotecard .display-m { font-size: clamp(19px, 1.9vw, 26px); line-height: 1.35; }

/* ---------------- glass cards ----------------
   The info and audience cards are filled frosted surfaces: a soft glass
   gradient, a hairline ring, a halo behind the icon, and on hover a light
   sweep passes across the card as it lifts. */
.infocard, .audience--rich li {
  overflow: hidden;
  border-style: solid;
}
.infocard {
  border-color: rgba(168, 48, 32, 0.24);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.72), rgba(255, 255, 255, 0.4));
  backdrop-filter: blur(14px) saturate(1.2);
  -webkit-backdrop-filter: blur(14px) saturate(1.2);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.6), 0 8px 24px rgba(10, 26, 40, 0.05);
}
.infocard--dark, .scene--dark .audience--rich li {
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.03));
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.09), 0 10px 30px rgba(2, 12, 20, 0.22);
}
/* the artistic accent: a soft halo pooling from the top of the card */
.infocard::before, .audience--rich li::before {
  content: ""; position: absolute; z-index: 0;
  top: -34%; left: 50%; transform: translateX(-50%);
  width: 78%; aspect-ratio: 1; border-radius: 9999px;
  background: radial-gradient(circle, rgba(168, 48, 32, 0.16), rgba(168, 48, 32, 0) 70%);
  pointer-events: none;
  opacity: 0.75;
  transition: opacity 0.5s var(--ease-ui);
}
.infocard--dark::before, .scene--dark .audience--rich li::before {
  background: radial-gradient(circle, rgba(212, 144, 122, 0.14), rgba(212, 144, 122, 0) 70%);
}
/* the hover sweep: one band of light crosses the glass */
.infocard::after, .audience--rich li::after {
  content: ""; position: absolute; z-index: 0;
  top: -20%; bottom: -20%; left: -80%; width: 46%;
  background: linear-gradient(105deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0));
  transform: skewX(-14deg);
  pointer-events: none;
}
.infocard > *, .audience--rich li > * { position: relative; z-index: 1; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .infocard:hover::after, .audience--rich li:hover::after {
    transition: left 0.85s var(--ease-out);
    left: 135%;
  }
  .infocard:hover::before, .audience--rich li:hover::before { opacity: 1; }
  .infocard:hover {
    border-color: rgba(168, 48, 32, 0.45);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.7), 0 22px 48px rgba(10, 26, 40, 0.12);
  }
}


/* ---------------- whoscene: the audience as a cinematic scene ----------
   One face emerging from darkness holds the center; the four audiences
   stand beside it as editorial type. Hovering an audience shifts what the
   face reveals — anatomy, skin, mapping, or the learning network. */
.beat__inner .whoscene { max-width: min(1280px, 100%); }
.whoscene {
  display: grid; grid-template-columns: 1fr minmax(300px, 440px) 1fr;
  gap: clamp(24px, 4vw, 56px); align-items: center;
  width: 100%; margin-top: 8px;
}
.whoscene__col { list-style: none; display: flex; flex-direction: column; gap: clamp(32px, 5vh, 56px); }
.whoscene__col--l { text-align: right; align-items: flex-end; }
.whoscene__col--r { text-align: left; align-items: flex-start; }
.whoitem {
  max-width: 300px;
  display: flex; flex-direction: column; gap: 6px;
  opacity: clamp(0, calc((var(--bp, 1) - var(--d, 0)) * 5), 1);
  filter: opacity(0.92);
  transition: filter 0.5s var(--ease-ui);
  cursor: default; outline-offset: 6px;
}
.whoscene__col--l .whoitem { align-items: flex-end; }
.whoitem__num { font-size: 11px; color: #D4907A; }
.whoitem .heading { font-size: clamp(19px, 1.5vw, 25px); transition: color 0.4s var(--ease-ui); }
.whoitem .body { color: rgba(255, 255, 255, 0.66); font-size: 15px; }
.whoitem::after {
  content: ""; width: 34px; height: 1px; margin-top: 8px;
  background: rgba(240, 216, 196, 0.45);
  transition: width 0.5s var(--ease-out), background 0.5s var(--ease-ui);
}
.whoscene[data-focus] .whoitem { filter: opacity(0.42); }
.whoscene[data-focus] .whoitem.is-focus { filter: opacity(1); }
.whoitem.is-focus .heading { color: #CFE4F2; }
.whoitem.is-focus::after { width: 72px; background: #D4907A; }

/* the stage */
.whoscene__stage {
  position: relative; aspect-ratio: 3 / 4; width: 100%;
  opacity: clamp(0, calc((var(--bp, 1) - var(--d, 0)) * 5), 1);
  transform: translateY(calc((1 - var(--bp, 1)) * 46px));
}
.whoscene__stage::before {
  content: ""; position: absolute; inset: -14%;
  background: radial-gradient(circle at 50% 42%, rgba(168, 48, 32, 0.16), rgba(168, 48, 32, 0) 64%);
  pointer-events: none;
}
/* film grain, barely there */
.whoscene__stage::after {
  content: ""; position: absolute; inset: 0; z-index: 6; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
  opacity: 0.045; mix-blend-mode: overlay;
  -webkit-mask-image: radial-gradient(ellipse 60% 62% at 48% 44%, #000 30%, transparent 74%);
  mask-image: radial-gradient(ellipse 60% 62% at 48% 44%, #000 30%, transparent 74%);
}
.wv {
  position: absolute; inset: 0; width: 100%; height: 100%;
  transition: opacity 0.8s var(--ease-ui), filter 0.9s var(--ease-ui);
}
.wv-base {
  object-fit: cover;
  /* the fade must reach full transparency INSIDE the image rect —
     0.72 × 58% = 41.8% of width from center, left edge sits at 48% */
  -webkit-mask-image: radial-gradient(ellipse 58% 60% at 48% 44%, #000 30%, rgba(0, 0, 0, 0.42) 55%, transparent 72%);
  mask-image: radial-gradient(ellipse 58% 60% at 48% 44%, #000 30%, rgba(0, 0, 0, 0.42) 55%, transparent 72%);
  filter: grayscale(0.25) brightness(0.9) contrast(1.04);
  animation: who-breathe 10s ease-in-out infinite;
}
@keyframes who-breathe { 50% { transform: scale(1.02); } }
.wv-anatomy polyline {
  stroke: #EADDD0; stroke-width: 1;
  stroke-dasharray: 5 7; stroke-linecap: round; stroke-linejoin: round;
  animation: who-dashdrift 36s linear infinite;
}
.wv-anatomy .wv-anatomy__dashed { stroke-dasharray: 2 9; }
@keyframes who-dashdrift { to { stroke-dashoffset: -240; } }
.wv-anatomy { opacity: 0.3; }
.wv-scan { opacity: 0; overflow: hidden; pointer-events: none; }
.wv-scan::before {
  content: ""; position: absolute; left: 6%; right: 6%; height: 16%; top: -20%;
  background: linear-gradient(180deg, rgba(212, 144, 122, 0), rgba(212, 144, 122, 0.28), rgba(212, 144, 122, 0));
  animation: who-scan 5.5s linear infinite;
}
@keyframes who-scan { to { top: 108%; } }
.wv-marks { opacity: 0.32; }
.wv-marks circle { fill: none; stroke: #F0D8C4; stroke-width: 1.2; animation: who-pulse 4s ease-in-out infinite; }
.wv-marks circle:nth-child(2n) { animation-delay: 1.3s; }
.wv-marks circle:nth-child(3n) { animation-delay: 2.4s; }
@keyframes who-pulse { 50% { r: 4.5; stroke-opacity: 0.55; } }
.wv-marks line { stroke: rgba(240, 216, 196, 0.4); stroke-width: 0.7; stroke-dasharray: 3 6; }
.wv-net { opacity: 0.2; }
.wv-net line { stroke: rgba(212, 144, 122, 0.4); stroke-width: 0.6; }
.wv-net circle { fill: #F0D8C4; animation: who-tw 4s ease-in-out infinite; }
@keyframes who-tw { 50% { fill-opacity: 0.25; } }
.wv-dust {
  position: absolute; width: 3px; height: 3px; border-radius: 9999px;
  background: rgba(214, 229, 238, 0.5); pointer-events: none;
  animation: who-dust 9s ease-in-out infinite;
}
@keyframes who-dust {
  0%, 100% { transform: translate(0, 0); opacity: 0.15; }
  50% { transform: translate(9px, -26px); opacity: 0.6; }
}

/* the four gazes of the same face */
.whoscene[data-focus="surgeons"] .wv-base { filter: grayscale(0.6) brightness(0.68) contrast(1.1); }
.whoscene[data-focus="surgeons"] .wv-anatomy { opacity: 1; }
.whoscene[data-focus="surgeons"] .wv-marks { opacity: 0.14; }
.whoscene[data-focus="surgeons"] .wv-net { opacity: 0.06; }
.whoscene[data-focus="derm"] .wv-base { filter: grayscale(0) brightness(1.06) saturate(1.12) contrast(1.02); }
.whoscene[data-focus="derm"] .wv-scan { opacity: 1; }
.whoscene[data-focus="derm"] .wv-anatomy { opacity: 0.06; }
.whoscene[data-focus="derm"] .wv-marks { opacity: 0.1; }
.whoscene[data-focus="derm"] .wv-net { opacity: 0.04; }
.whoscene[data-focus="aesthetic"] .wv-base { filter: grayscale(0.3) brightness(0.84) contrast(1.06); }
.whoscene[data-focus="aesthetic"] .wv-marks { opacity: 1; }
.whoscene[data-focus="aesthetic"] .wv-anatomy { opacity: 0.14; }
.whoscene[data-focus="aesthetic"] .wv-net { opacity: 0.08; }
.whoscene[data-focus="residents"] .wv-base { filter: grayscale(0.55) brightness(0.7) contrast(1.08); }
.whoscene[data-focus="residents"] .wv-net { opacity: 1; }
.whoscene[data-focus="residents"] .wv-anatomy { opacity: 0.1; }
.whoscene[data-focus="residents"] .wv-marks { opacity: 0.16; }

.whoscene__cta { margin-top: 8px; }

@media (max-width: 980px) {
  .whoscene { grid-template-columns: 1fr; gap: 32px; justify-items: center; }
  .whoscene__stage { order: -1; max-width: 340px; }
  .whoscene__col, .whoscene__col--l, .whoscene__col--r { text-align: center; align-items: center; gap: 28px; }
  .whoscene__col--l .whoitem, .whoitem { align-items: center; }
}
@media (prefers-reduced-motion: reduce) {
  .wv-base, .wv-scan::before, .wv-marks circle, .wv-net circle, .wv-dust, .wv-anatomy polyline { animation: none; }
  .whoitem, .whoscene__stage { opacity: 1; transform: none; }
}


/* ---------------- gainscene v2: a still frame from the theatre ----------
   No geometry, no strokes — only photographed light: an off-frame surgical
   lamp, its volumetric fall through haze, dust hanging in the beam, and
   darkness holding everything else. The five experiences appear inside the
   frame as staggered film chapters. */
.beat:has(.gainscene) .beat__inner::before {
  content: ""; position: absolute; inset: -2% -50vw;
  background:
    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.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.05'/%3E%3C/svg%3E"),
    radial-gradient(ellipse 70% 60% at 46% 30%, rgba(9, 30, 41, 0.88), rgba(2, 10, 17, 0.985) 70%);
  opacity: clamp(0, calc(var(--bp, 1) * 2.6), 1);
  pointer-events: none;
}
.beat:has(.gainscene) .beat__inner > * { position: relative; }
.beat__inner .gainscene { max-width: min(1080px, 100%); }
.gainscene { position: relative; width: 100%; margin-top: 4px; }

/* the atmosphere fills the whole frame behind the chapters */
.gainscene__atmo {
  position: absolute; inset: 0 -40vw -24vh;
  overflow: hidden;
  pointer-events: none;
  opacity: clamp(0, calc((var(--bp, 1) - 0.04) * 4), 1);
}
/* the lamp head: a dark mass barely separating from the darkness */
.ga-head {
  position: absolute; left: 38%; top: -26%;
  width: 30%; aspect-ratio: 5 / 2; transform: translateX(-50%);
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(2, 8, 13, 0.9), rgba(2, 8, 13, 0) 72%);
}
/* the source: a hot core with real falloff — three stacked radials */
.ga-source {
  position: absolute; left: 38%; top: -21%;
  width: 46%; aspect-ratio: 2 / 1; transform: translateX(-50%);
  background:
    radial-gradient(ellipse 7% 11% at 50% 42%, rgba(244, 250, 253, 0.95), rgba(244, 250, 253, 0) 100%),
    radial-gradient(ellipse 16% 26% at 50% 44%, rgba(214, 236, 245, 0.5), rgba(214, 236, 245, 0) 100%),
    radial-gradient(ellipse 46% 74% at 50% 48%, rgba(212, 144, 122, 0.17), rgba(212, 144, 122, 0) 100%);
  animation: ga-breathe 11s ease-in-out infinite;
  transition: opacity 1s var(--ease-ui), transform 1s var(--ease-ui);
}
@keyframes ga-breathe { 50% { opacity: 0.82; } }
/* the volumetric fall — soft, blurred, no edges */
.ga-beam {
  position: absolute; left: 38%; top: -4%;
  width: 34%; height: 74%; transform: translateX(-50%);
  clip-path: polygon(43% 0, 57% 0, 96% 100%, 4% 100%);
  background: linear-gradient(180deg, rgba(206, 228, 238, 0.13), rgba(206, 228, 238, 0.045) 55%, rgba(206, 228, 238, 0) 92%);
  filter: blur(22px);
  animation: ga-breathe 11s ease-in-out infinite;
  transition: opacity 1s var(--ease-ui);
}
/* hanging haze — two huge soft masses drifting imperceptibly */
.ga-haze {
  position: absolute; border-radius: 9999px; filter: blur(46px);
  background: radial-gradient(circle, rgba(212, 144, 122, 0.075), rgba(212, 144, 122, 0) 70%);
}
.ga-haze--1 { left: 16%; top: 30%; width: 54%; aspect-ratio: 1.6; animation: ga-drift1 46s ease-in-out infinite; }
.ga-haze--2 { left: 40%; top: 52%; width: 44%; aspect-ratio: 1.3; animation: ga-drift2 58s ease-in-out infinite; }
@keyframes ga-drift1 { 50% { transform: translate(5%, -4%); } }
@keyframes ga-drift2 { 50% { transform: translate(-6%, 3%); } }
/* the lit pool low in frame */
.ga-pool {
  position: absolute; left: 38%; bottom: 4%;
  width: 52%; height: 16%; transform: translateX(-50%);
  background: radial-gradient(ellipse 50% 50% at 50% 50%, rgba(240, 216, 196, 0.11), rgba(240, 216, 196, 0) 70%);
  filter: blur(10px);
}
.ga-dust {
  position: absolute; width: 2px; height: 2px; border-radius: 9999px;
  background: rgba(224, 238, 246, 0.55); filter: blur(0.5px);
  animation: ga-dustf 13s ease-in-out infinite;
}
@keyframes ga-dustf {
  0%, 100% { transform: translate(0, 0); opacity: 0; }
  30% { opacity: 0.55; }
  60% { opacity: 0.2; }
  100% { transform: translate(12px, 34px); }
}

/* the chapters: staggered editorial type inside the frame */
.gchapters {
  list-style: none; position: relative;
  display: flex; flex-direction: column; gap: clamp(16px, 2.2vh, 28px);
  width: min(760px, 100%); margin-inline: auto;
  /* headroom for the beam — but the sticky stage is capped at 100svh and the
     CTA is its last child, so this must never push the CTA past the fold */
  padding-top: clamp(64px, 11vh, 180px);
  text-align: left;
}
.gitem {
  position: relative;
  margin-left: var(--ox, 0%);
  max-width: 480px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 4px;
  /* entry is owned by .gchapters > .gitem above (per-card --ip), not by the
     section-wide --bp, which would hold every card to the same schedule */
  filter: opacity(0.88);
  transition: filter 0.6s var(--ease-ui);
  cursor: default; outline-offset: 4px;
}
/* a soft local light answers the cursor — no borders, no boxes */
.gitem::before {
  content: ""; position: absolute; inset: -22% -14%;
  background: radial-gradient(ellipse 60% 80% at 30% 50%, rgba(232, 190, 170, 0.09), rgba(232, 190, 170, 0) 70%);
  opacity: 0; transition: opacity 0.7s var(--ease-ui);
  pointer-events: none;
}
.gitem__row {
  display: flex; align-items: baseline; gap: 16px;
  transition: transform 0.6s var(--ease-out);
}
.gitem__num {
  font-size: clamp(20px, 1.8vw, 27px); font-weight: 300;
  color: rgba(212, 144, 122, 0.75);
  font-variant-numeric: tabular-nums; letter-spacing: 0.02em;
}
.gitem h3 {
  font-family: "Outfit", Arial, sans-serif;
  font-size: clamp(20px, 1.9vw, 27px);
  font-weight: 500; line-height: 1.2; letter-spacing: -0.01em;
  color: #F5EBE0;
}
.gitem .body {
  color: rgba(233, 242, 247, 0.52); font-size: 15px; max-width: 44ch;
  padding-left: calc(clamp(20px, 1.8vw, 27px) + 16px + 8px);
  transition: color 0.6s var(--ease-ui);
}
.gitem::after {
  content: ""; height: 1px; width: 100%; margin-top: 14px;
  background: linear-gradient(90deg, rgba(206, 228, 238, 0.16), rgba(206, 228, 238, 0));
  transition: background 0.6s var(--ease-ui);
}
.gitem:last-child::after { display: none; }
/* `opacity(0.4)` flattened the inactive cards into grey text. They now step
   BACK instead: dimmer, a touch soft, and very slightly smaller, so the live
   one reads as nearer rather than just brighter. */
.gainscene[data-glow] .gitem {
  filter: opacity(0.34) blur(0.6px);
  transition: filter 0.55s var(--ease-ui);
}
.gainscene[data-glow] .gitem.is-focus { filter: opacity(1) blur(0); }
.gainscene[data-glow] .gitem .gitem__row,
.gainscene[data-glow] .gitem .body { transition: transform 0.6s var(--ease-out); }
.gainscene[data-glow] .gitem:not(.is-focus) .gitem__row { transform: scale(0.975); transform-origin: left center; }
.gitem.is-focus::before { opacity: 1; }
.gitem.is-focus .gitem__row { transform: translateX(8px); }
.gitem.is-focus .body { color: rgba(233, 242, 247, 0.78); }
.gitem.is-focus::after { background: linear-gradient(90deg, rgba(212, 144, 122, 0.4), rgba(212, 144, 122, 0)); }
/* the theatre answers, faintly */
.gainscene[data-glow] .ga-source { opacity: 1; transform: translateX(-50%) scale(1.06); }
.gainscene[data-glow] .ga-beam { opacity: 1.25; }

.gain__cta { margin-top: 12px; }

/* short desktop windows (a 1440x900 laptop leaves ~760px) cannot afford the
   beam headroom: the stage is sticky at top:0, so anything over 100svh puts
   the CTA permanently under the fold */
@media (min-width: 769px) and (max-height: 780px) {
  .gchapters { padding-top: 32px; gap: 12px; }
}

@media (max-width: 768px) {
  .gchapters { padding-top: 110px; gap: 22px; }
  .gitem { margin-left: 0; max-width: 100%; }
  .gainscene__atmo { inset: -20vh -20vw -16vh; }
  .ga-source, .ga-beam, .ga-head, .ga-pool { left: 50%; }
}
@media (prefers-reduced-motion: reduce) {
  .ga-source, .ga-beam, .ga-haze, .ga-dust { animation: none; }
  .gitem { opacity: 1; }
  .gainscene__atmo { opacity: 1; }
}

/* ---------------- reduced motion ---------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  [data-split] .ch, [data-split-progress] .ch {
    color: var(--ch-lit); transition: none;
    opacity: 1; transform: none; filter: none;
  }
  .lateshow { opacity: 1; }
  .navpill:hover .navpill__flip span { transform: none; }
  .pill-cta { transition: none; }
  [data-reveal] { opacity: 1; transform: none; transition: none; }
  .cardgrid > *, .audience--rich li, .whoitem, .gitem,
  .whoscene__stage, .gainscene__stage,
  .beat__inner > .label, .beat__inner > h2, .beat__inner > .body-l,
  [data-par] { transform: none; }
  .hero__act { opacity: 1; transform: none; pointer-events: auto; }
  .hero__copy { display: flex; flex-direction: column; align-items: center; gap: 22px; }
  .motif path { stroke-dashoffset: 0; transition: none; }
  .photo-feature img { transform: none; transition: none; }
  .photo-fan { display: none; }
  .section-face { transform: translateY(-50%); }
}


/* ================= client feedback · sliders ================= */

/* --- faculty carousel: runs itself, stops on the doctor you point at --- */
.docrail { overflow: hidden; position: relative; }
.docrail__track {
  --gap: 20px;
  display: flex; gap: var(--gap); width: max-content;
  animation: docmarquee 72s linear infinite;
}
@keyframes docmarquee { to { transform: translateX(calc(-50% - var(--gap) / 2)); } }
.docrail__track:hover, .docrail__track:focus-within,
.docrail.is-held .docrail__track { animation-play-state: paused; }
.docrail .scard { flex: 0 0 auto; }

/* --- sponsor / partner logo rails: slower, same mechanism --- */
.logos { padding-block: 96px; }
.logos__head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; }
.logos__head .body-l { color: var(--muted-light); max-width: 56ch; text-wrap: balance; }
.logos__foot { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 40px; }
.logorail { overflow: hidden; margin-top: 40px; }
.logorail__track {
  --gap: 20px;
  display: flex; gap: var(--gap); width: max-content;
  animation: docmarquee var(--dur, 64s) linear infinite;
}
.logorail__track:hover, .logorail.is-held .logorail__track { animation-play-state: paused; }
.logoplate {
  flex: 0 0 auto; width: 250px; height: 136px; padding: 20px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  border: 1px solid var(--hairline-light); border-radius: 16px; overflow: hidden;
  /* Solid white, not a translucent grey wash. Most of these logo files carry
     their own white background baked in (they were supplied as JPEGs and
     flattened PNGs), so any tint on the plate made each one show as a white
     rectangle floating inside a grey card. */
  background: #fff;
}
.logoplate__mark {
  font-size: 20px; font-weight: 600; letter-spacing: 0.02em;
  color: var(--accent-strong);
}
.logoplate__name { font-size: 13px; color: var(--muted-light); }
.logoplate img {
  max-width: 100%; max-height: 76px; width: auto; height: auto; object-fit: contain;
  /* no grayscale/opacity at rest: on a logo with a baked-in white background
     it tints that background too, which is what made the inner rectangle
     visible against the plate */
  transition: opacity 0.35s var(--ease-ui);
}
.logoplate:hover img { opacity: 1; }


/* --- event photos: an arched print rail --- */
.photos__head { display: flex; align-items: center; justify-content: space-between; gap: 20px; }
.photos__foot { display: flex; justify-content: center; margin-top: 32px; }
.archrail {
  display: flex; gap: 24px; overflow-x: auto; margin-top: 32px;
  padding-inline: var(--pad); padding-bottom: 8px;
  scroll-snap-type: x mandatory; scroll-padding-left: var(--pad);
  scrollbar-width: none;
}
.archrail::-webkit-scrollbar { display: none; }
.archcard {
  flex: 0 0 auto; width: min(320px, 74vw); margin: 0;
  scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 12px;
}
.archcard img {
  width: 100%; height: 420px; object-fit: cover; display: block;
  /* the arch: a dome on top, quiet corners below */
  border-radius: 160px 160px 16px 16px;
  box-shadow: 0 18px 44px rgba(10, 26, 40, 0.16);
}
.archcard figcaption { text-align: center; }

@media (max-width: 768px) {
  .docrail__track { --gap: 14px; animation-duration: 56s; }
  .logorail__track { --gap: 14px; }
  .logoplate { width: 180px; height: 112px; padding: 14px; }
  .logoplate img { max-height: 58px; }
  .logos { padding-block: 72px; }
  .archcard img { height: 320px; border-radius: 130px 130px 16px 16px; }
  .photos__head { flex-direction: column; align-items: flex-start; }
  /* photos live in the slider now — the gallery button is desktop-only */
  .photos__cta { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .docrail__track, .logorail__track { animation: none; }
  .docrail, .logorail { overflow-x: auto; }
}


/* ================= faculty profile page (doctor.html) ================= */
.doc-page { background: var(--bg-light, #F5EBE0); color: var(--ink); }
.docmain { padding-top: 148px; padding-bottom: 96px; }
.doc-back { display: inline-block; margin-bottom: 32px; color: var(--muted-light); }
.doc-back:hover { color: var(--accent-strong); }
.dochero__grid {
  display: grid; grid-template-columns: minmax(0, 380px) minmax(0, 1fr);
  gap: 48px; align-items: start;
}
.dochero__photo { margin: 0; border-radius: 24px; overflow: hidden; background: #EADDD0; }
.dochero__photo img { width: 100%; height: 100%; object-fit: cover; display: block; aspect-ratio: 4 / 5; }
.dochero__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 16px; }
.dochero__copy .body-l { color: var(--muted-light); max-width: 56ch; }
.docmeta { display: flex; flex-wrap: wrap; gap: 8px; }
.docchip {
  font-size: 13px; padding: 8px 14px; border-radius: 9999px;
  border: 1px solid var(--hairline-light); color: var(--muted-light);
}
.docsection { margin-top: 64px; }
.docsection > .label--head { display: block; margin-bottom: 20px; }
.doclist { list-style: none; display: grid; gap: 12px; }
.docitem {
  display: grid; grid-template-columns: 160px minmax(0, 1fr) auto;
  gap: 16px; align-items: baseline;
  padding: 20px 24px; border-radius: 16px;
  border: 1px solid var(--hairline-light);
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.9), rgba(240, 245, 249, 0.5));
}
.docitem__where { color: var(--muted-light); }
.doclist--past .docitem { background: none; border-style: dashed; }
.docitem--empty { grid-template-columns: 1fr; color: var(--muted-light); }
.doc-page .footer { padding: 48px 0; }
.doc-page .footer__legal { border-top: 0; }

@media (max-width: 900px) {
  .dochero__grid { grid-template-columns: 1fr; gap: 32px; }
  .dochero__photo { max-width: 320px; }
}
@media (max-width: 768px) {
  .docmain { padding-top: 120px; padding-bottom: 72px; }
  .docsection { margin-top: 48px; }
  .docitem { grid-template-columns: 1fr; gap: 8px; padding: 16px 20px; }
}


/* ---- 2. hero seam ----
   There used to be a 180px dark-to-transparent band on #sponsors, because
   "Our partners" sat directly under the hero and the blend belonged there.
   That section has moved down the page, and the band moved with it: a dark
   smear across white, in the middle of the page, exactly the failure its own
   comment described when the band lived on #summit.

   Nothing needs to blend now. The hero ends on #0C1828 and the section below
   it starts on #0C1828, so the seam is already invisible. */
#sponsors { position: relative; }
#sponsors > * { position: relative; z-index: 1; }

/* ---- 7. event experience: a static designed ground, no drifting dots ---- */
#events {
  background:
    radial-gradient(120% 74% at 50% 0%, rgba(168, 48, 32, 0.30) 0%, rgba(11, 34, 51, 0) 62%),
    radial-gradient(80% 52% at 82% 88%, rgba(122, 32, 16, 0.24) 0%, rgba(11, 34, 51, 0) 70%),
    linear-gradient(180deg, #1E1A32 0%, #141828 46%, #081B29 100%);
}
/* one quiet diagonal sheen — fixed to the section, so it never animates */
#events::before {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: linear-gradient(104deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0) 38%);
}
#events > * { position: relative; z-index: 1; }


/* ---- 1 + 6. the CairoFACE model replaces the generated artwork ----
   The client read the wireframe/mapping overlay as an "AI vibe", so the
   photograph now carries both scenes on its own. face.js keeps running
   (it still releases the intro gate) but is no longer drawn. */
.hero__face-canvas { opacity: 0; }
.hero__bg--model {
  position: absolute; inset: 0; z-index: 0;
  background-image: url("../img/model-hero.jpg?v=b4");
  /* the source is a 1131x1600 portrait. `cover` on a wide hero scales it to
     the WIDTH, so only ~44% of the frame survives — a close-up cropped through
     the mouth. Size to the HEIGHT instead and anchor right, which keeps the
     whole head and restores the original composition: portrait right, copy left. */
  background-size: auto 118%;
  background-position: 100% 30%;
  background-repeat: no-repeat;
  opacity: 1;
  filter: brightness(1.02) saturate(1.08);

  transform: none;
}
/* keep the copy legible over the portrait */
.hero__bg::after {
  content: ""; position: absolute; inset: 0; z-index: 2; pointer-events: none;
  background:
    /* the centre wash the old .hero__face::after used to provide — the copy
       crosses the lit side of the profile, so it has to win there */
    radial-gradient(ellipse 80% 74% at 48% 46%, rgba(5, 28, 41, 0.82) 0%, rgba(5, 28, 41, 0.58) 48%, rgba(5, 28, 41, 0.24) 74%, rgba(5, 28, 41, 0) 96%),
    linear-gradient(90deg, rgba(5, 28, 41, 0.92) 0%, rgba(5, 28, 41, 0.64) 36%, rgba(5, 28, 41, 0.28) 62%, rgba(5, 28, 41, 0.05) 84%, rgba(5, 28, 41, 0.08) 100%),
    linear-gradient(180deg, rgba(5, 28, 41, 0.58) 0%, rgba(5, 28, 41, 0) 28%, rgba(5, 28, 41, 0.55) 100%),
    linear-gradient(rgba(5, 28, 41, var(--veil)), rgba(5, 28, 41, var(--veil)));
}
/* the anatomical wireframe went with it */
.wv-anatomy, .wv-marks, .wv-net, .wv-scan { display: none; }
.wv-base { filter: grayscale(0.1) brightness(0.96) contrast(1.04); }

@media (max-width: 768px) {
  .hero__bg--model { background-size: auto 96%; background-position: 72% 22%; }
  .hero__bg { --veil: 0.34; }
  .pageout__logo { width: min(300px, 78vw); }
}

/* veil steps up as the copy column claims more of the portrait.
   MUST stay after the base .hero__bg--model rule: same specificity, so
   source order is what makes these win. */
/* narrower desktops put the whole copy column on top of the portrait, so the
   veil scales with width. Declared on the base .hero__bg rule far above, so
   these overrides win on source order. */
@media (max-width: 1360px) { .hero__bg { --veil: 0.16; } }
@media (max-width: 1180px) { .hero__bg { --veil: 0.34; } }


/* doc comment [a]/[d]/[g] (reopened): "video men el event nafso or motion
   baset" — the motion half, a very slow drift so the hero is never static.
   A real event video can replace the layer without touching anything else. */
@media (prefers-reduced-motion: no-preference) {
  .hero__bg--model { animation: hero-drift 32s ease-in-out infinite alternate; }
}
@keyframes hero-drift {
  from { transform: scale(1) translate3d(0, 0, 0); }
  to   { transform: scale(1.055) translate3d(-1.2%, -0.8%, 0); }
}


/* ================= doc comments [k] and "Our Leadership" ================= */

/* [k] "Slider" — the numbers band scrolls when it cannot fit */
.statrail {
  /* .stats sets flex-wrap:wrap; without resetting it here the band wraps to as
     many as six rows instead of scrolling, which pushes the CTA off the pinned
     100svh stage on anything narrower than a desktop. */
  display: flex; flex-wrap: nowrap; gap: 40px; overflow-x: auto;
  /* .stats centres its children. Once the band overflows, a centred flex
     row spills off BOTH edges and the left spill cannot be scrolled to, so
     the first number is unreachable. `safe` falls back to start on overflow. */
  justify-content: flex-start; justify-content: safe center;
  scroll-snap-type: x proximity; scrollbar-width: none;
  padding-bottom: 4px;
}
.statrail::-webkit-scrollbar { display: none; }
.statrail .stat { flex: 0 0 auto; min-width: 168px; scroll-snap-align: start; }

/* the leadership section the doc asks for and the build was missing */
.leadership { padding-block: 96px; }
.leadership__head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 12px; }
.leadership__lede { margin-top: 48px; display: flex; justify-content: center; }
.leadfeature {
  margin: 0; display: grid; grid-template-columns: 148px minmax(0, 1fr);
  gap: 32px; align-items: center; max-width: 760px;
  padding: 32px; border-radius: 24px;
  border: 1px solid var(--hairline-light);
  background: linear-gradient(160deg, rgba(255, 255, 255, 0.9), rgba(240, 245, 249, 0.5));
}
.leadfeature figcaption { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; }
.leadfeature .body { color: var(--muted-light); margin: 4px 0 8px; }
.leadfeature__avatar, .leadcard__avatar {
  display: flex; align-items: center; justify-content: center;
  border-radius: 9999px; background: linear-gradient(160deg, #A83020, #2C2440);
  color: #fff; font-weight: 600; letter-spacing: 0.02em;
}
.leadfeature__avatar { width: 148px; height: 148px; font-size: 40px; }
.leadcard__avatar { width: 72px; height: 72px; font-size: 22px; }
.leadgrid {
  margin-top: 48px;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px;
}
.leadcard {
  display: flex; flex-direction: column; align-items: flex-start; gap: 10px;
  padding: 24px; border-radius: 20px;
  border: 1px solid var(--hairline-light);
  transition: border-color 0.3s var(--ease-ui), transform 0.5s var(--ease-out);
}
.leadcard:hover { border-color: var(--accent); transform: translateY(-3px); }
.leadcard__name { font-size: 18px; }
.leadcard__more { font-size: 13px; color: var(--accent-strong); margin-top: 4px; }

@media (max-width: 900px) { .leadgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 768px) {
  .leadership { padding-block: 72px; }
  .leadgrid { grid-template-columns: 1fr; margin-top: 32px; }
  .leadfeature { grid-template-columns: 1fr; gap: 20px; padding: 24px; justify-items: start; }
  .leadfeature__avatar { width: 96px; height: 96px; font-size: 28px; }
  .statrail { gap: 24px; }
}


/* ============ hero: event video, endorsement logos ============ */
/* The supplied reel is itself a portrait on Cairo FACE blue, at almost the
   same aspect as the model photo — so it takes the SAME right-hand column and
   simply brings that column to life. The photo stays underneath as the poster
   and the reduced-motion fallback. Left edge is feathered so it dissolves into
   the hero ground instead of ending in a rectangle. */
.hero__reel {
  position: absolute; top: 50%; right: 0; z-index: 1;
  height: 118%; width: auto; max-width: none;
  transform: translateY(-50%);
  object-fit: cover; pointer-events: none;
  opacity: 0; transition: opacity 1.2s var(--ease-ui);
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 18%, #000 44%),
                      linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 18%, #000 44%),
              linear-gradient(180deg, transparent 0%, #000 12%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in; mask-composite: intersect;
}
.hero__reel.is-playing { opacity: 0.88; }
/* the 5s clip ramps dark -> bright, so dip it across the loop seam */
.hero__reel.is-looping { opacity: 0.12; transition: opacity 0.36s linear; }

.hero__orgs { display: flex; align-items: center; justify-content: center; gap: 28px; margin-top: 4px; }
.hero__orgs img {
  height: 40px; width: auto; display: block;
  filter: brightness(0) invert(1); opacity: 0.72;
  transition: opacity 0.3s var(--ease-ui);
}
.hero__orgs a:hover img { opacity: 1; }

/* ============ what you'll gain, on one screen ============ */


/* ============ leadership rail ============ */
.leadrail { overflow: hidden; margin-top: 40px; }
.leadrail__track { --gap: 20px; display: flex; gap: var(--gap); width: max-content; animation: docmarquee var(--dur, 72s) linear infinite; }
.leadrail__track:hover, .leadrail__track:focus-within, .leadrail.is-held .leadrail__track { animation-play-state: paused; }
.leadcard {
  flex: 0 0 auto; width: 248px;
  display: flex; flex-direction: column; gap: 0; padding: 0; overflow: hidden;
  border-radius: 20px; border: 1px solid var(--hairline-light); background: #fff;
  transition: transform 0.5s var(--ease-out), border-color 0.3s var(--ease-ui), box-shadow 0.4s var(--ease-ui);
}
.leadcard:hover { transform: translateY(-4px); border-color: var(--accent); box-shadow: 0 18px 40px rgba(10,26,40,0.12); }
.leadcard__media {
  position: relative; aspect-ratio: 4 / 5; overflow: hidden;
  background: linear-gradient(160deg, #A83020, #2C2440);
  display: flex; align-items: center; justify-content: center;
}
.leadcard__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%; display: block; transition: transform 1.2s var(--ease-out); }
.leadcard:hover .leadcard__media img { transform: scale(1.05); }
.leadcard__ini { color: #fff; font-size: 44px; font-weight: 600; letter-spacing: 0.02em; }
.leadcard__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(12, 24, 40,0) 52%, rgba(12, 24, 40,0.55) 100%);
}
.leadcard__body { display: flex; flex-direction: column; gap: 4px; padding: 16px 18px 18px; align-items: flex-start; }
.leadcard__name { font-size: 17px; }
.leadcard__more { font-size: 13px; color: var(--accent-strong); margin-top: 6px; }


/* Two of the supplied files carry a DARK ground baked in — Skinfill on
   near-black, Univa on aubergine — so the white plate framed each one as a
   dark rectangle: the same bug as the grey plate, inverted. Paint the plate
   in the mark's own ground and it sits flush like every other logo. */
.logoplate--ink { background: var(--plate); border-color: rgba(255, 255, 255, 0.16); }
.logoplate--ink .logoplate__name { color: rgba(255, 255, 255, 0.72); }
.logoplate--skinfill { --plate: #252022; }
.logoplate--univa { --plate: #421D50; }
/* these two are tight crops with no baked-in margin, so cap them against the
   plate or they read a size larger than every logo beside them */
.logoplate--ink img { max-width: 68%; max-height: 46%; }

/* ============ the sponsor board: one row per tier ============
   The client's sponsor sheet grades partners Strategic / Platinum / Gold /
   Silver plus an official carrier and a media partner. A single flat rail
   rendered a Strategic partner exactly like a Silver one, which is the thing
   sponsors actually pay for. Each tier is now its own labelled row, and plate
   size carries the rank — same .logoplate component, four sizes. */
.tierboard { display: flex; flex-direction: column; gap: 40px; margin-top: 32px; }
.tiergroup { display: flex; flex-direction: column; gap: 16px; }
.tiergroup__head {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding-bottom: 12px; border-bottom: 1px dashed var(--hairline-light);
}
.tiergroup__label {
  font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--accent-strong); margin: 0;
}
.tiergroup__nav { display: flex; gap: 8px; }
.tiergroup__nav[hidden] { display: none; }
.tierrow {
  display: flex; gap: 16px; overflow-x: auto; scroll-behavior: smooth;
  padding-block: 4px; scrollbar-width: none; scroll-snap-type: x proximity;
}
.tierrow::-webkit-scrollbar { display: none; }
.tierrow > .logoplate { scroll-snap-align: start; }

/* rank by size — every other plate property stays identical */
.logoplate--xl { width: 288px; height: 156px; }
.logoplate--md { width: 216px; height: 120px; }
.logoplate--sm { width: 184px; height: 104px; }
.logoplate--xl img { max-height: 84px; }
.logoplate--md img { max-height: 60px; }
.logoplate--sm img { max-height: 48px; }

/* a sponsor whose logo file the client has not supplied yet */
.logoplate--mark { justify-content: center; }
.logoplate__mark {
  font-size: 20px; font-weight: 600; letter-spacing: -0.01em; line-height: 1.1;
  color: var(--accent-strong); text-align: center;
}
.logoplate--xl .logoplate__mark { font-size: 24px; }
.logoplate--sm .logoplate__mark { font-size: 17px; }
.logoplate--mark .logoplate__name { display: none; }

/* the product brands that sit under one sponsor, and the booth number */
.logoplate__brands {
  font-size: 11px; line-height: 1.3; color: var(--muted-light);
  text-align: center; max-width: 92%;
}
.logoplate__booth {
  font-size: 11px; font-weight: 500; letter-spacing: 0.04em;
  color: var(--accent-strong); opacity: 0.75;
}
.logoplate--ink .logoplate__brands { color: rgba(255, 255, 255, 0.6); }
.logoplate--ink .logoplate__booth { color: rgba(255, 255, 255, 0.72); opacity: 1; }
.logoplate--ink .logoplate__mark { color: #fff; }

@media (max-width: 768px) {
  .tierboard { gap: 32px; }
  .tierrow { gap: 12px; margin-inline: -16px; padding-inline: 16px; }
  .tiergroup__nav { display: none; }          /* swipe the row on a phone */
  .logoplate--xl { width: 208px; height: 124px; }
  .logoplate--md { width: 172px; height: 104px; }
  .logoplate--sm { width: 156px; height: 96px; }
  .logoplate--xl img { max-height: 62px; }
  .logoplate--md img { max-height: 48px; }
  .logoplate--sm img { max-height: 40px; }
  .logoplate__brands { display: none; }
}

/* ============ page transition: the Cairo FACE mark, big ============ */
.pageout {
  position: fixed; inset: 0; z-index: 200;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 36px;
  background: radial-gradient(120% 90% at 50% 45%, #1E1A32 0%, #0C1828 62%, #03141E 100%);
  opacity: 0; pointer-events: none;
  transition: opacity 0.4s var(--ease-ui);
}
.pageout.is-on { opacity: 1; pointer-events: all; }
.pageout__logo { position: relative; width: min(460px, 72vw); overflow: hidden; }
.pageout__logo img {
  display: block; width: 100%; height: auto;
  opacity: 0; transform: scale(0.94);
}
.pageout.is-on .pageout__logo img { animation: mark-in 0.9s var(--ease-out) forwards; }
/* a light sweeps across the mark once it has landed */
.pageout__sheen {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, rgba(255,255,255,0) 38%, rgba(212, 144, 122,0.55) 50%, rgba(255,255,255,0) 62%);
  transform: translateX(-120%);
}
.pageout.is-on .pageout__sheen { animation: mark-sheen 1.6s 0.5s var(--ease-ui) infinite; }
.pageout__bar {
  display: block; width: min(200px, 44vw); height: 2px; border-radius: 2px;
  background: rgba(255, 255, 255, 0.14); overflow: hidden;
}
.pageout__bar > span {
  display: block; width: 40%; height: 100%; border-radius: 2px;
  background: linear-gradient(90deg, transparent, #D4907A, transparent);
  transform: translateX(-100%);
}
.pageout.is-on .pageout__bar > span { animation: mark-bar 1.1s 0.2s var(--ease-ui) infinite; }
@keyframes mark-in { to { opacity: 1; transform: scale(1); } }
@keyframes mark-sheen { 0% { transform: translateX(-120%); } 100% { transform: translateX(120%); } }
@keyframes mark-bar { 0% { transform: translateX(-100%); } 100% { transform: translateX(350%); } }

@media (max-width: 768px) {
  .hero__orgs { gap: 20px; }
  .hero__orgs img { height: 30px; }
  .gainscene--one .gchapters { grid-template-columns: 1fr; gap: 14px; padding-top: 56px; }
  .leadcard { width: 196px; }
  .leadrail__track { --gap: 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .leadrail__track { animation: none; }
  .leadrail { overflow-x: auto; }
  .pageout { display: none; }
}




/* mobile reel overrides — MUST live after the base .hero__reel rules above,
   which are appended later in this file and would otherwise win on order */
@media (max-width: 768px) {
  .hero__reel {
    height: 100%; width: 100%; right: 0; left: 0;
    object-fit: cover; object-position: 50% 20%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 76%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0%, #000 14%, #000 76%, transparent 100%);
    /* The base rule intersects TWO mask layers. This one declares a single
       layer, and leaving `source-in` / `intersect` in place asks WebKit to
       composite that layer against a second that does not exist - which iOS
       Safari resolves as empty, so the reel renders fully transparent and the
       hero shows no face at all. Desktop Chrome does not, which is why it only
       failed on a phone. One layer needs no compositing. */
    -webkit-mask-composite: source-over;
    mask-composite: add;
  }
  /* it sits over a near-black ground behind the headline: at 0.6 the face was
     barely legible on a phone in daylight */
  .hero__reel.is-playing { opacity: 0.78; }
  .pageout__logo { width: min(300px, 78vw); }
}


/* ---- fixes from client review ---- */



/* these two marks ship on opaque white, so inverting them produced solid
   rectangles. Sit them on a light chip instead. */
.hero__orgs { flex-wrap: wrap; gap: 12px; }
.hero__orgs-label { width: 100%; text-align: center; opacity: 0.5; margin-bottom: 2px; }
.orgchip {
  display: inline-flex; align-items: center; justify-content: center;
  height: 52px; padding: 0 16px; border-radius: 12px;
  background: rgba(255, 255, 255, 0.92);
  box-shadow: 0 6px 18px rgba(3, 16, 26, 0.28);
  transition: transform 0.3s var(--ease-out), background 0.3s var(--ease-ui);
}
.orgchip:hover { transform: translateY(-2px); background: #fff; }
.orgchip img { height: 34px; width: auto; display: block; filter: none; opacity: 1; }

/* social becomes icons */
.socrow { display: flex; gap: 12px; }
.socicon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 9999px;
  border: 1px solid rgba(255, 255, 255, 0.22); color: #fff;
  transition: background 0.3s var(--ease-ui), border-color 0.3s var(--ease-ui), transform 0.3s var(--ease-out);
}
.socicon svg { width: 18px; height: 18px; display: block; }
.socicon:hover { background: rgba(255, 255, 255, 0.14); border-color: rgba(255, 255, 255, 0.5); transform: translateY(-2px); }

@media (max-width: 768px) {
  .orgchip { height: 44px; padding: 0 12px; }
  .orgchip img { height: 28px; }
  .socrow { justify-content: center; }
}


/* event photos: a plain slider, per the client's call — the fanned deck and
   its cross-fade are retired (their CSS above is now unused). */
.photorail {
  display: flex; gap: 20px; overflow-x: auto; margin-top: 28px;
  padding-inline: var(--pad); padding-bottom: 8px;
  scroll-snap-type: x mandatory; scroll-padding-left: var(--pad);
  scrollbar-width: none; scroll-behavior: smooth;
}
.photorail::-webkit-scrollbar { display: none; }
.pslide {
  flex: 0 0 auto; width: min(420px, 82vw); margin: 0;
  scroll-snap-align: start;
  display: flex; flex-direction: column; gap: 10px;
}
.pslide img {
  width: 100%; height: 300px; object-fit: cover; display: block;
  border-radius: 18px; box-shadow: 0 16px 40px rgba(10, 26, 40, 0.16);
}
@media (max-width: 768px) {
  .photorail { gap: 14px; }
  .pslide img { height: 230px; }
}


/* ---- second review pass ---- */

/* 3. the lift on hover was being sliced off by the rail's overflow */
.leadrail { padding-block: 14px; }
.logorail { padding-block: 10px; }

/* 1. the hero marks: one consistent white plate, logo trimmed so there is no
   box-inside-a-box, and both sized off their own height */
.orgchip { height: 56px; padding: 0 18px; background: #fff; border-radius: 14px; }
.orgchip img { height: auto; max-height: 34px; max-width: 124px; }

/* 7. the endorsement cards carry the real marks */
.endorse__logo { display: flex; align-items: center; min-height: 56px; }
.endorse__logo img { max-height: 52px; max-width: 190px; width: auto; height: auto; }

@media (max-width: 768px) {
  .orgchip { height: 46px; padding: 0 14px; }
  .orgchip img { max-height: 26px; max-width: 96px; }
  .endorse__logo img { max-height: 42px; }
}


/* ---- gain: intro copy now shares the pinned stage with the chapters ----
   The stage is sticky at 100svh, so the headline's height comes straight out
   of the chapters' beam headroom or the CTA drops under the fold. */
.gainhead { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.gainhead__lede { color: var(--muted-dark); max-width: 64ch; font-size: 16px; }
/* This headline must read at the SAME size as every other section heading —
   it was running at half (33px vs 64px), the one outlier on the page. It is
   held to two lines by widening its measure instead of shrinking the type;
   the space that buys back is taken from the sub-line and gaps below. */
#gain .gainhead { max-width: min(1080px, 94%); }
#gain .gainhead h2 { max-width: none; text-wrap: balance; }
/* ---- #gain stops fighting for one screen ----
   It was a pinned 100svh stage carrying a headline, five chapters and a CTA,
   and the budget never balanced: the sub-headline was set to `display: none`
   on any window under 960px tall (which is most laptops — that is why it
   "disappeared"), and the headline stepped down through three breakpoints.
   With a face to show as well there is no version of that which fits. So the
   section flows like the rest of the page: the type stays at full size, the
   sub-headline always shows, and the scroll moves straight on to the next
   section instead of holding still for a screen. */
#gain .beat { height: auto; }
#gain .beat__inner { position: static; min-height: 0; padding-block: clamp(72px, 9vh, 120px); }
#gain .gainhead__lede { display: block; }
@media (max-width: 768px) {
  #gain .gchapters { padding-top: 24px; }
}


/* ---- Who should attend: the scroll-scrubbed reel ----
   Same mask and grade as the still it sits on, so it reads as the same shot
   coming alive. The still stays underneath as the poster and the
   reduced-motion fallback. */
.wv-reel {
  object-fit: cover;
  opacity: 0;
  transition: opacity 1s var(--ease-ui);
  -webkit-mask-image: radial-gradient(ellipse 58% 60% at 48% 44%, #000 30%, rgba(0, 0, 0, 0.42) 55%, transparent 72%);
  mask-image: radial-gradient(ellipse 58% 60% at 48% 44%, #000 30%, rgba(0, 0, 0, 0.42) 55%, transparent 72%);
  filter: grayscale(0.1) brightness(0.96) contrast(1.04);
}
.wv-reel.is-ready { opacity: 1; }
/* with the reel showing, the still is only there to cover the seams */
.whoscene__stage:has(.wv-reel.is-ready) .wv-base { opacity: 0.25; }
@media (prefers-reduced-motion: reduce) {
  .wv-reel { display: none; }
}


/* the feature card now carries a portrait rather than initials */



/* ================= leadership feature card ================= */
/* The portrait hangs off the card like a pinned flag: its own rounded panel,
   overhanging top and bottom, gradient-scrimmed, with the card lighting up
   around it on hover. */
.leadfeature {
  position: relative;
  /* NOT a grid: the flag is positioned, so its overhang is fixed rather than
     being absorbed by the card's padding. The left padding reserves its lane. */
  display: block;
  max-width: 840px;
  min-height: 296px;
  padding: 40px 44px 40px 288px;
  border-radius: 28px;
  border: 1px solid rgba(168, 48, 32, 0.22);
  background:
    radial-gradient(120% 150% at 0% 0%, rgba(168, 48, 32, 0.14), rgba(255, 255, 255, 0) 55%),
    linear-gradient(150deg, #ffffff 0%, #FBF6F0 58%, #F5EBE0 100%);
  box-shadow: 0 18px 46px rgba(10, 26, 40, 0.09);
  transition:
    transform 0.6s var(--ease-out),
    box-shadow 0.6s var(--ease-ui),
    border-color 0.5s var(--ease-ui);
}
.leadfeature:hover {
  transform: translateY(-4px);
  border-color: rgba(168, 48, 32, 0.5);
  box-shadow: 0 30px 66px rgba(10, 26, 40, 0.16);
}

/* a light sweeps the card — background-position, so nothing escapes the radius */
.leadfeature::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  border-radius: inherit; pointer-events: none;
  background: linear-gradient(104deg, rgba(255,255,255,0) 38%, rgba(255,255,255,0.85) 50%, rgba(255,255,255,0) 62%);
  background-size: 260% 100%;
  background-position: 190% 0;
  opacity: 0;
  transition: background-position 1.15s var(--ease-out), opacity 0.4s var(--ease-ui);
}
.leadfeature:hover::before { background-position: -90% 0; opacity: 1; }

.leadfeature__flag {
  /* pinned to the card and overhanging it top and bottom, whatever the copy
     length — the image's own aspect no longer drives the layout */
  position: absolute; z-index: 1;
  left: 36px; top: -24px; bottom: -24px; width: 208px;
  border-radius: 22px;
  overflow: hidden;
  background: linear-gradient(160deg, #A83020, #2C2440);
  box-shadow: 0 18px 40px rgba(10, 26, 40, 0.3);
  transition: transform 0.6s var(--ease-out), box-shadow 0.6s var(--ease-ui);
}
.leadfeature__flag img {
  width: 100%; height: 100%; object-fit: cover; object-position: 50% 18%;
  display: block; border-radius: 0;
  transition: transform 1.2s var(--ease-out);
}
/* depth at the foot of the flag so the badge always has something to sit on */
.leadfeature__flag::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(12, 24, 40, 0.22) 0%, rgba(12, 24, 40, 0) 32%, rgba(12, 24, 40, 0.62) 100%);
}
.leadfeature:hover .leadfeature__flag {
  transform: translateY(-5px);
  box-shadow: 0 28px 56px rgba(10, 26, 40, 0.38);
}
.leadfeature:hover .leadfeature__flag img { transform: scale(1.06); }

.leadfeature__badge {
  position: absolute; left: 14px; bottom: 14px; z-index: 2;
  padding: 6px 12px; border-radius: 9999px;
  font-size: 11px; font-weight: 600; letter-spacing: 0.12em; text-transform: uppercase;
  color: #fff;
  background: rgba(255, 255, 255, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.34);
  backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px);
}

.leadfeature figcaption { position: relative; z-index: 1; }
.leadfeature figcaption .heading { font-size: clamp(22px, 2.2vw, 30px); line-height: 1.15; }
.leadfeature .pill-sm { transition: background 0.35s var(--ease-ui), border-color 0.35s var(--ease-ui); }
.leadfeature:hover .pill-sm { border-color: var(--accent); background: rgba(168, 48, 32, 0.08); }

@media (max-width: 768px) {
  .leadfeature {
    display: flex; flex-direction: column; gap: 18px;
    min-height: 0; padding: 24px; border-radius: 22px;
  }
  .leadfeature__flag {
    position: relative; left: auto; top: auto; bottom: auto;
    width: 100%; height: 252px; margin: 0 0 4px;
  }
  /* The mobile banner is landscape and the source a tall portrait, so only
     ~46% of the photo's height is in frame. At 74% that band started below
     his hairline and cut the top of his head off. 46% puts the band at
     26%-72% of the photo: the whole head, with air above it. */
  .leadfeature__flag img { object-position: 50% 46%; }
}
@media (prefers-reduced-motion: reduce) {
  .leadfeature, .leadfeature__flag, .leadfeature__flag img { transition: none; }
  .leadfeature:hover { transform: none; }
  .leadfeature:hover .leadfeature__flag { transform: none; }
  .leadfeature:hover .leadfeature__flag img { transform: none; }
  .leadfeature::before { display: none; }
}


/* ---- the lamp now lights the whole section ----
   The atmosphere used to live inside .gainscene, so it began below the
   headline and threw a narrow 34%-wide cone. It is a direct child of the
   pinned stage now, and the beam spans the full width. */
/* MUST stay sticky. This was `position: relative` — added so the lifted-out
   `.gainscene__atmo` (absolute, inset:0) would anchor to the stage — but its ID
   specificity silently beat `.beat__inner { position: sticky }`, so this was the
   only beat on the page that never pinned. Its stage scrolled away and left the
   rest of the beat as bare background: the empty blue frame the client kept
   screenshotting. `sticky` establishes a containing block just as `relative`
   does, so the lamp still anchors correctly. */
/* Was `sticky` to stop the stage scrolling away and leaving bare background.
   The section flows now, so there is no leftover beat to expose — but the
   lamp is positioned against this box, so it still needs to establish a
   containing block. */
#gain .beat__inner { position: relative; }
#gain .gainscene__atmo {
  position: absolute; inset: 0; max-width: none; width: 100%;
  z-index: 0; pointer-events: none;
}
#gain .beat__inner > *:not(.gainscene__atmo) { position: relative; z-index: 1; }

#gain .ga-head   { left: 50%; top: -12%; width: 26%; }
#gain .ga-source { left: 50%; top: -9%;  width: 42%; opacity: 0.8; }
#gain .ga-beam {
  left: 50%; top: 0; width: 92%; height: 100%;
  clip-path: polygon(41% 0, 59% 0, 106% 100%, -6% 100%);
  filter: blur(30px);
}
#gain .ga-haze--1 { left: 50%; top: 12%; width: 78%; }
#gain .ga-haze--2 { left: 50%; top: 42%; width: 92%; }
#gain .ga-pool { left: 50%; bottom: 2%; width: 88%; height: 22%; }

/* ---- event photos: the set change is choreographed, not a hard cut ---- */
.photo-feature .photo-fan {
  transition: opacity 0.5s var(--ease-ui), filter 0.5s var(--ease-ui);
}
.photo-feature.is-swapping .photo-fan { opacity: 0; filter: blur(7px); }
/* out in fan order, back in reversed, so the deck re-deals rather than blinks */
.photo-feature.is-swapping .photo-fan--l  { transition-delay: 0s; }
.photo-feature.is-swapping .photo-fan--r  { transition-delay: 0.06s; }
.photo-feature.is-swapping .photo-fan--l2 { transition-delay: 0.12s; }
.photo-feature.is-swapping .photo-fan--r2 { transition-delay: 0.18s; }
.photo-feature .photo-fan--r2 { transition-delay: 0s; }
.photo-feature .photo-fan--l2 { transition-delay: 0.06s; }
.photo-feature .photo-fan--r  { transition-delay: 0.12s; }
.photo-feature .photo-fan--l  { transition-delay: 0.18s; }
.photo-feature > img { transition: opacity 0.5s var(--ease-ui), filter 0.5s var(--ease-ui); }
.photo-feature.is-swapping > img { opacity: 0.55; filter: blur(3px); }


/* ---- pacing: scroll length should follow how much there is to read ----
   `.beat:has(.cardgrid)` grants 300vh, which is right for the who- and
   gain-scenes (staged reveals that use every pixel) but absurd for a row of
   three cards: #events was spending 4.9 screens of scroll on one headline and
   three small cards, so most of the section scrolled past as empty stage.
   Desktop only — at <=768px these beats already drop their pins entirely. */
@media (min-width: 769px) {
  #events .beat { height: 110vh; }                 /* 155px of headline */
  #events .beat:has(.cardgrid) { height: 145vh; }  /* 229px of cards + CTA */
  #summit .beat--tall { height: 150vh; }           /* 236px: rail + one CTA */
}

/* the event-photo arrows now sit under the deck; .photos centres its
   children and its own 20px gap does the spacing. */
.photos__nav { margin-top: 4px; }
/* On a phone the deck rises as it opens (--lift), so the arrows sit close
   underneath. On a desktop it does not rise — the far pair deals downward as
   well as outward, 146px past the figure at full fan — so the arrows need
   that room or the prints land on top of them. */
@media (min-width: 769px) { .photos__nav { margin-top: 0; } }


/* ---- all six numbers on screen at once ----
   The band used to be a scroller, so only four fitted and the last two were
   hidden behind a horizontal scroll. It is now a grid with a fixed column
   count per breakpoint: the row count is deterministic, so the pinned 100svh
   stage can be sized for it, and nothing is ever off-screen. */
.statrail {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 28px 16px;
  overflow: visible;
  padding-bottom: 0;
}
/* the flex-era sizing would blow the tracks out */
.statrail .stat { flex: initial; min-width: 0; }
.statrail .stat dd { font-size: clamp(28px, 3.5vw, 54px); }
.statrail .stat dt { max-width: 18ch; }  /* 15ch broke the longest label onto three lines */
.statrail .stat dd small { font-size: 0.3em; margin-left: 6px; }

/* six across stops being readable before it stops fitting */
@media (max-width: 1120px) {
  .statrail { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px 20px; }
  .statrail .stat dd { font-size: clamp(34px, 5vw, 56px); }
}
@media (max-width: 600px) {
  .statrail { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 24px 12px; }
  .statrail .stat dd { font-size: clamp(30px, 8.5vw, 44px); }
  .statrail .stat dt { max-width: 14ch; }
}


/* ---- the five programme cards arrive one per scroll step ----
   The staged-reveal rule (see "cards arrive ONE PER SCROLL STEP") only ever
   matched `.cardgrid > *` and `.audience--rich > li`. `.gitem` lives in
   `.gchapters`, so it matched neither: the --d values authored on every card
   in the HTML were read by nothing and all five were fully lit the moment the
   section appeared. Same formula, now actually applied. */
/* The cards used to fade in on the SECTION's progress (--bp), which meant
   five cards sharing one number: they arrived together, near enough, and the
   column moved as a single slab. Each card now has its own --ip (its entry,
   against its own position on screen) and its own --pary (a parallax offset
   at a rate unique to that card), both written by gainScroll. So they appear
   one at a time, and keep travelling at different speeds afterwards. */
.gchapters > .gitem {
  opacity: clamp(0, calc(var(--ip, 1) * 1.45), 1);
  transform:
    translateY(calc((1 - var(--ip, 1)) * 46px + var(--pary, 0px)))
    translateX(calc((1 - var(--ip, 1)) * var(--slide, 18px)));
  transition: none;
}
/* alternate which side they slide in from, so the column reads as dealt */
.gchapters > .gitem:nth-child(2n) { --slide: -22px; }
.gchapters > .gitem:nth-child(3n) { --slide: 26px; }

/* The lamp wants headroom, but centring an 785px block in a 987px stage left
   ~100px of dead space above the headline (and the same below). Anchor the
   stage to the top so the headline sits up under the lamp and the cards have
   somewhere to deal out into. Fluid, so short windows give the space back. */
/* The stage pins at top:0 and the nav pill occupies 28-92px, so the headline
   was sitting underneath it. Reserve that band, then centre as every other
   section does. */
#gain .beat__inner { justify-content: center; }
/* a 1440x760 window left only 4px under the CTA with 5vh of headroom — the
   stage is capped at 100svh, so short windows get the top space back */


/* re-assert after the rules above, which would otherwise re-animate them */
@media (prefers-reduced-motion: reduce) {
  .gchapters > .gitem { opacity: 1; transform: none; --pary: 0px; }
}


/* ---- a pinned stage must never render completely empty ----
   #about's and #events' second beats contain nothing but a card grid and a
   `.lateshow` CTA — no heading of their own, because the heading lives in the
   preceding beat and has already scrolled away. With the first card's
   threshold at 0.06 and `.lateshow` holding the CTA until 0.34, the opening
   stretch of each pin showed a full-screen view of nothing but the background
   canvas: rings, dust and no content at all.
   The first card now starts already on screen and the CTA follows sooner; the
   one-per-scroll-step cadence of cards 2..n is unchanged. */
.cardgrid > *:nth-child(1), .audience--rich > li:nth-child(1) { --d: -0.12; }
.beat:has(.cardgrid) .lateshow { opacity: clamp(0, calc((var(--bp, 1) - 0.05) * 3.4), 1); }
.beat:has(.cardgrid) .cardgrid.lateshow { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .beat:has(.cardgrid) .lateshow { opacity: 1; }
}


/* The centre print is `position: relative; z-index: 1`, so it paints in the
   positive-z layer — above every positioned sibling left on `z-index: auto`,
   including this button, which sits later in the DOM. The opaque photo covered
   it completely. */
.photo-feature__cta { z-index: 2; }


/* ---- scroll length follows content, continued ----
   Client: the page spends whole screens of scrolling on sections whose content
   fits in one. These keep every staged reveal (the thresholds are fractions of
   the beat, so the cadence is unchanged — just less scroll between steps).
   Desktop only: at <=768px `.beat:has(.whoscene)` / `:has(.cardgrid)` already
   drop their pins and flow, and an ID rule here would override that. */
@media (min-width: 769px) {
  #who .beat { height: 170vh; }                     /* was 240vh — 1.4 screens of it was held */
  #about .beat:has(.cardgrid) { height: 170vh; }    /* was 200vh */
}


/* ---- #who: same two faults the gain stage had ----
   On laptop heights its headline sat at y=60 with the nav pill occupying
   28-92px (covered by 30px), and the stage ran 890px tall in a 768px window so
   the CTA was permanently under the fold. The height is almost entirely the
   portrait: `.whoscene__stage` is `aspect-ratio: 3/4`, so a 440px centre column
   is 587px tall. Narrowing that column is the lever. */
#who .beat__inner { padding-top: 96px; }

@media (min-width: 769px) and (max-height: 900px) {
  #who .whoscene { grid-template-columns: 1fr minmax(220px, 320px) 1fr; }
  #who .whoitem .body { font-size: 14px; }
  #who .whoscene__col { gap: clamp(18px, 2.6vh, 30px); }
}
/* The eyebrows are display-sized now (client asked for bigger), which is the
   right call on a normal window but costs a pinned stage ~20px it does not
   have on a short one. They step down here rather than push a CTA out. */
@media (min-width: 769px) and (max-height: 820px) {
  .label--head { font-size: clamp(20px, 2.1vw, 30px); }
  #who .beat__inner { padding-top: 76px; padding-bottom: 20px; gap: 12px; }
  #who .whoscene__stage { max-height: 46vh; }
  #who .whoscene { grid-template-columns: 1fr minmax(200px, 268px) 1fr; }
  #who .whoitem .body { font-size: 13px; line-height: 1.4; }
}


/* ================= person pop-up ================= */
body.pmodal-open { overflow: hidden; }
.pmodal { position: fixed; inset: 0; z-index: 200; display: flex; align-items: center; justify-content: center; padding: 24px; }
.pmodal[hidden] { display: none; }
.pmodal__scrim { position: absolute; inset: 0; background: rgba(6, 20, 32, 0.62); backdrop-filter: blur(3px); }
.pmodal__panel {
  position: relative; z-index: 1; background: #fff; color: var(--ink, #0C1828);
  width: min(620px, 100%); max-height: min(84vh, 760px); overflow-y: auto;
  border-radius: 20px; padding: 28px; box-shadow: 0 32px 80px rgba(6, 20, 32, 0.38);
  animation: pmIn 0.26s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes pmIn { from { opacity: 0; transform: translateY(12px) scale(0.985); } to { opacity: 1; transform: none; } }
.pmodal__x {
  position: absolute; top: 14px; inset-inline-end: 14px; width: 34px; height: 34px; border-radius: 50%;
  border: 1px solid rgba(10, 26, 40, 0.14); background: #fff; cursor: pointer;
  font-size: 20px; line-height: 1; color: #0C1828; font-family: inherit;
}
.pmodal__x:hover { background: #F5EBE0; }
.pmodal__head { display: flex; gap: 18px; align-items: center; padding-inline-end: 36px; }
.pmodal__media {
  width: 96px; height: 96px; flex: 0 0 96px; border-radius: 50%; overflow: hidden;
  background: #EADDD0; box-shadow: 0 8px 20px rgba(10, 26, 40, 0.14);
}
.pmodal__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pmodal__id h2 { font-size: 25px; font-weight: 700; line-height: 1.15; }
.pmodal__role { font-size: 14px; font-weight: 500; color: #7A2010; margin-top: 4px; }
.pmodal__chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.pmodal__chip {
  font-size: 12px; font-weight: 500; padding: 4px 10px; border-radius: 9999px;
  background: rgba(122, 32, 16, 0.09); color: #7A2010;
}
.pmodal__bio { font-size: 15px; font-weight: 400; line-height: 1.6; color: #6B6470; margin-top: 20px; }
.pmodal__note { font-size: 14px; color: #6B6470; margin-top: 20px; }
.pmodal__sessions { margin-top: 24px; }
.pmodal__sessions h3 {
  font-size: 12px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: #7A2010;
}
.pmodal__sessions ol { list-style: none; margin: 12px 0 0; padding: 0; }
.pmodal__sessions li {
  display: grid; grid-template-columns: 104px 1fr; gap: 14px;
  padding: 12px 0; border-top: 1px solid rgba(10, 26, 40, 0.1);
}
.pmodal__when { font-size: 13px; font-weight: 600; color: #7A2010; white-space: nowrap; }
.pmodal__what { display: flex; flex-direction: column; gap: 3px; }
.pmodal__what b { font-size: 15px; font-weight: 500; line-height: 1.4; }
.pmodal__what span { font-size: 13px; color: #6B6470; }
@media (max-width: 560px) {
  .pmodal { padding: 14px; }
  .pmodal__panel { padding: 22px 18px; }
  .pmodal__head { flex-direction: column; align-items: flex-start; gap: 14px; padding-inline-end: 30px; }
  .pmodal__media { width: 78px; height: 78px; flex-basis: 78px; }
  .pmodal__sessions li { grid-template-columns: 1fr; gap: 4px; }
}
@media (prefers-reduced-motion: reduce) { .pmodal__panel { animation: none; } }


/* ================= mobile: beats that must flow, flow =================
   The 768px block above deliberately unpins the card/scene beats: a pinned
   100svh stage cannot hold a one-column stack, so those beats get
   `height: auto` and a static inner. Two rules added later for the desktop
   fix were written without a media query —

     #about .beat:has(.cardgrid) { height: 200vh }
     #gain  .beat                { height: 200vh }
     #gain  .beat__inner         { position: sticky }

   — and ID specificity carried all three past the mobile block. The result
   on a phone: the inner flows at its natural height while the beat stays two
   screens tall, so each ends with a screen of bare background (measured at
   375x812: 615px under #about, 567px under #gain). #gain was worse still —
   its inner stayed `sticky` inside an `overflow: hidden` beat, where sticky
   does nothing at all. Re-assert the flowing layout at matching specificity. */
@media (max-width: 768px) {
  #about .beat:has(.cardgrid) { height: auto; }
  #gain .beat { height: auto; }
  /* relative rather than static: .gainscene__atmo is absolutely positioned
     against this box and would otherwise escape to the nearest positioned
     ancestor */
  #gain .beat__inner { position: relative; top: auto; min-height: 0; }
}


/* ================= responsive audit fixes =================
   Found by measuring every page at 320 / 375 / 600 / 768 / 1024 / 1440. */

/* 1. Type floor. The global standard sets 12px as the smallest caption, but
   several labels are sized in em against a number that shrinks on small
   screens — `.statrail .stat dd small` resolved to 9px at 320px ("3 days"),
   and a handful of tracked uppercase labels sat at 10–11px. */
.stat dd small { font-size: max(12px, 0.28em); }
.statrail .stat dd small { font-size: max(12px, 0.3em); }
.price small { font-size: max(12px, 0.5em); }
.hero__cal-month { font-size: 12px; }
.whoitem__num { font-size: 12px; }
.leadfeature__badge { font-size: 12px; }
@media (max-width: 600px) {
  .chip-edition { font-size: 12px; }
  .hero__tag { font-size: 12px; }
  .hero__cal-place .label { font-size: 12px; }
}

/* 2. Tap targets. Footer links were 24px tall — under half the 44px a thumb
   needs, and they sit in tight stacks where a mis-tap opens the wrong page.
   Only on touch pointers, so the desktop footer keeps its current rhythm. */
@media (pointer: coarse), (max-width: 900px) {
  .footer__links { gap: 0; }
  .footer__links a { padding-block: 10px; }
  .doc-back { padding-block: 8px; }
  .footer__legal { padding-block: 24px; }
}

/* 3. The floating contact dock sits in the page gutter on a wide screen, but
   below 1100px the gutter shrinks to 32px and on a phone to 16px, so the dock
   starts overlapping the left edge of the content column. Measured at 320px:
   22px of the home page's "Register now" and "Explore the programme" buttons
   were under the WhatsApp button. Tucking the dock into the corner and taking
   the buttons to 44px (still a full thumb target) cuts that to 8px and clears
   it entirely at tablet widths. */
@media (max-width: 1100px) {
  .contactdock { inset-inline-start: 14px; bottom: 14px; gap: 10px; }
  .contactdock__btn { width: 44px; height: 44px; }
  .contactdock__btn svg { width: 22px; height: 22px; }
}


/* ================= short viewports (landscape phone) =================
   KNOWN LIMITATION, deliberately not patched. At 844x390 the hero copy is
   440px inside a 390px pinned stage, so it centres and spills off both ends
   and the summit title sits ~31px behind the nav pill.

   Neither obvious fix works. Aligning the stage to the top clears the nav but
   pushes the CTAs below a pinned stage, where they cannot be scrolled to.
   Unpinning the beat so it flows collapses the choreography instead: the
   hero is a multi-act scrubbed sequence, and with `height: auto` the beat's
   own progress reads --bp = 1 at scroll 0, so every act is already at its end
   position and the copy lands above the fold.

   A landscape phone needs its own hero composition (fewer acts, tighter type),
   which is a design decision rather than a stylesheet fix. Leaving the pinned
   behaviour intact until that is agreed.
   ==================================================================== */

/* ---- the dock collapses to one button (js/contactdock.js) ----
   Two permanently visible buttons covered the bottom-left corner of every
   page; hiding them on scroll instead made them flicker. One trigger that
   opens on demand is a third of the footprint and never moves on its own. */
.contactdock { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
.contactdock__list {
  display: flex; flex-direction: column; gap: 12px;
  transform-origin: bottom center;
  transition: opacity 0.22s var(--ease-ui), transform 0.26s var(--ease-out);
}
.contactdock:not(.is-open) .contactdock__list {
  opacity: 0; transform: translateY(12px) scale(0.9); pointer-events: none;
}
.contactdock__toggle {
  display: flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 9999px;
  background: var(--accent); color: #fff;
  box-shadow: 0 10px 28px rgba(10, 26, 40, 0.34);
  transition: background 0.3s var(--ease-ui), transform 0.3s var(--ease-out);
}
.contactdock__toggle:hover { background: var(--accent-strong); }
.contactdock__toggle:active { transform: scale(0.94); }
.contactdock__ico { width: 24px; height: 24px; display: block; transition: opacity 0.2s var(--ease-ui); }
.contactdock__ico--close { position: absolute; opacity: 0; }
.contactdock.is-open .contactdock__ico--menu { opacity: 0; }
.contactdock.is-open .contactdock__ico--close { opacity: 1; }
.contactdock__toggle { position: relative; }
@media (max-width: 1100px) {
  .contactdock__toggle { width: 48px; height: 48px; }
  .contactdock__ico { width: 22px; height: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .contactdock__list, .contactdock__toggle, .contactdock__ico { transition: none; }
}


/* ================= buttons: one line, hugging =================
   A button never wraps and is never wider than its label plus its icon.
   These primitives carry a fixed height (48px / 44px / 38px), so a wrapped
   label did not grow the pill — it spilled out of it. */
.btn-pill,
.btn-ghost,
.pill-sm,
.nav-cta,
.pill-cta,
.sidemenu__cta,
.fchip,
.docchip,
.price-cta {
  white-space: nowrap;
  width: auto;
  flex: 0 0 auto;
}
/* the day tab stacks three labels by design; each stays on its own line */
.agdaytab__day, .agdaytab__date, .agdaytab__kind { white-space: nowrap; }

/* the floating pill is a two-layer crossfade: the front layer goes back into
   flow so the stack takes its width, the back layer still sits over it */
.pillstack { width: max-content; height: auto; }
.pill-cta { height: 44px; }
.pill-cta--front { position: relative; inset: auto; }

/* containers that were stretching their buttons to full width */
@media (max-width: 768px) {
  .hero__ctas { align-items: center; }
}
/* the drawer is a column flex, so its default stretch made the CTA span the
   whole panel; `margin-top: auto` still pins it to the bottom */
.sidemenu__cta { align-self: flex-start; justify-content: flex-start; }

/* Below 400px the longest labels — "Enter the Rising Star Competition",
   "Become a Cairo FACE partner" — need ~334px against 288px of column. Rather
   than let them wrap or truncate, the button steps down a size: tighter
   tracking carries most of it, since 33 characters at 0.08em spend 37px on
   letter-spacing alone. */
@media (max-width: 400px) {
  .btn-pill, .btn-ghost {
    font-size: 13px; letter-spacing: 0.02em;
    height: 44px; padding-inline-start: 16px;
  }
  .btn-ghost { padding-inline-end: 16px; }
  .pill-sm { font-size: 12px; letter-spacing: 0.02em; padding-inline-start: 14px; }
}


/* ================= event photo deck: keep the spread on screen =================
   The wide fan throws the outer prints ±158% of their own width, which only
   fits once the viewport is about 1800px. Below that the two far cards ran off
   both edges — visible at 1440 and every size down to tablet, and previously
   only corrected under 768px. The compact geometry that mobile already used is
   simply given the whole range below 1800px: scale() leads the transform, so
   each translate happens in the shrunken space and the deck stays in frame.
   Same prints, same motion, same timing — only the spread distance changes. */
/* (the fan geometry lives with .photo-feature — one set of transforms,
   four spread distances; see --spread / --spread2 there) */


/* ---- event photo deck: the arrows page the deck across ----
   `translate` is its own property, so this slide composes with the fan's
   scroll-scrubbed `transform` rather than replacing it. */
.photo-feature .photo-fan,
.photo-feature > img {
  translate: var(--swipe, 0px) 0;
  transition: opacity 0.42s var(--ease-ui), filter 0.42s var(--ease-ui),
              translate 0.42s var(--ease-out);
}
.photo-feature.is-out-next { --swipe: -22%; }
.photo-feature.is-out-prev { --swipe: 22%; }
.photo-feature.is-in-next  { --swipe: 22%; }
.photo-feature.is-in-prev  { --swipe: -22%; }
/* the hop to the far side must not animate, or it slides the wrong way first */
.photo-feature.is-jump .photo-fan,
.photo-feature.is-jump > img { transition: none; }
@media (prefers-reduced-motion: reduce) {
  .photo-feature .photo-fan,
  .photo-feature > img { translate: none; transition: opacity 0.3s linear; }
}


/* ---- social links as icons ----
   The label is gone from the page, so it lives in aria-label and title
   instead: a screen reader still hears "Cairo FACE on Instagram", and a
   mouse user gets the tooltip. 44px keeps them a thumb's width apart. */
.sociconrow { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; }
.socicon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 9999px;
  color: #fff;
  background: rgba(255, 255, 255, 0.08);
  border: 1px solid var(--hairline-dark);
  transition: background 0.3s var(--ease-ui), border-color 0.3s var(--ease-ui),
              color 0.3s var(--ease-ui), transform 0.3s var(--ease-out);
}
.socicon svg { width: 20px; height: 20px; display: block; }
.socicon:hover { background: var(--accent); border-color: var(--accent); color: #fff; }
.socicon--wa:hover { background: #25D366; border-color: #25D366; }
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .socicon:hover { transform: translateY(-2px); }
}
/* on a light surface — the contact card */
.socicon--ink {
  color: var(--accent-strong);
  background: rgba(168, 48, 32, 0.10);
  border-color: rgba(168, 48, 32, 0.24);
}
.socicon--ink:hover { color: #fff; }

/* ---------------- event photo gallery ----------------
   Rides the existing .vlb lightbox shell (scrim, close, body lock) and adds
   only what a picture needs that a video frame does not: a size that follows
   the image, paging, and a caption. */
.pgal__frame {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: flex; flex-direction: column; align-items: center; gap: 16px;
  width: min(92vw, 720px); max-height: 92vh;
}
.pgal__img {
  display: block; max-width: 100%; max-height: 68vh;
  width: auto; height: auto; object-fit: contain;
  border-radius: 16px; background: #141828;
  box-shadow: 0 24px 60px rgba(3, 14, 22, 0.5);
}
.pgal__bar { display: flex; align-items: center; gap: 16px; }
.pgal__nav {
  background: rgba(255, 255, 255, 0.14); color: #fff; border: 0; cursor: pointer;
  transition: background 0.3s var(--ease-ui);
}
.pgal__nav:hover { background: rgba(255, 255, 255, 0.28); }
.pgal__nav:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }
.pgal__count {
  font-size: 13px; font-weight: 500; letter-spacing: 0.08em;
  color: rgba(255, 255, 255, 0.72); font-variant-numeric: tabular-nums;
  min-width: 56px; text-align: center;
}
.pgal__cap {
  margin: 0; max-width: 560px; text-align: center;
  font-size: 14px; line-height: 1.5; color: rgba(255, 255, 255, 0.72);
}
.pgal .vlb__close { top: -44px; right: 0; }
@media (max-width: 768px) {
  .pgal__frame { width: 92vw; gap: 12px; }
  .pgal__img { max-height: 58vh; }
  .pgal__cap { font-size: 13px; }
  .pgal .vlb__close { top: -40px; }
}

/* ================= gain: the face, and what happens on it =================
   The section carried a lamp and a list; the face it is all about was
   missing. Each chapter now marks a point on it — hovering, focusing or (on
   a phone) the scene's own cycle lights the matching one. The list keeps its
   own reading order; the face is the index, not a second navigation. */
.gainscene {
  position: relative;
  display: grid; grid-template-columns: minmax(240px, 380px) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 64px); align-items: center; width: 100%;
}
.gainscene__stage { position: relative; aspect-ratio: 630 / 840; width: 100%; }
.gv { position: absolute; inset: 0; width: 100%; height: 100%; }
.gv-base {
  object-fit: cover; display: block;
  /* A radial vignette still read as a rectangle — its solid core reached the
     box edges before it had faded, and it dimmed the face's own profile on
     the way. Two crossed linear fades instead: each edge dissolves on its own
     axis and the middle, where the face is, stays fully opaque. No radius —
     a rounded rectangle is still a rectangle. */
  -webkit-mask-image:
    linear-gradient(to right, transparent 0%, #000 20%, #000 80%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 16%, #000 78%, transparent 100%);
  mask-image:
    linear-gradient(to right, transparent 0%, #000 20%, #000 80%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 16%, #000 78%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  /* the face leans toward whichever chapter is live (set by main.js) */
  transform: scale(var(--face-zoom, 1));
  transform-origin: var(--face-x, 46%) var(--face-y, 44%);
  transition: transform 1.1s var(--ease-out), transform-origin 1.1s var(--ease-out);
}
/* the push-in tracks the chapter's own progress, so the face is always
   moving with the reader rather than snapping to one zoom and holding */
.gainscene[data-glow] .gv-base { --face-zoom: calc(1.02 + var(--gp, 0) * 0.07); }
@media (prefers-reduced-motion: reduce) {
  .gv-base { transition: none; --face-zoom: 1 !important; }
}
.gv-map { overflow: visible; }

.gpt { transition: opacity 0.55s var(--ease-ui); opacity: 0.55; }
.gpt__halo { fill: rgba(212, 144, 122, 0.10); }
.gpt__ring { fill: none; stroke: rgba(240, 216, 196, 0.55); stroke-width: 1.2; }
.gpt__core { fill: #F0D8C4; }
.gpt__halo, .gpt__ring, .gpt__core { transition: fill 0.5s var(--ease-ui), stroke 0.5s var(--ease-ui), opacity 0.5s var(--ease-ui); }

/* with a chapter in focus the rest of the face steps back */
.gainscene[data-glow] .gpt { opacity: 0.22; }
.gainscene[data-glow="live"]  .gpt[data-pt="live"],
.gainscene[data-glow="class"] .gpt[data-pt="class"],
.gainscene[data-glow="hands"] .gpt[data-pt="hands"],
.gainscene[data-glow="panel"] .gpt[data-pt="panel"],
.gainscene[data-glow="globe"] .gpt[data-pt="globe"] { opacity: 1; }
.gainscene[data-glow] .gpt[data-pt] { transform-box: fill-box; transform-origin: center; }
.gainscene[data-glow="live"]  .gpt[data-pt="live"]  .gpt__halo,
.gainscene[data-glow="class"] .gpt[data-pt="class"] .gpt__halo,
.gainscene[data-glow="hands"] .gpt[data-pt="hands"] .gpt__halo,
.gainscene[data-glow="panel"] .gpt[data-pt="panel"] .gpt__halo,
.gainscene[data-glow="globe"] .gpt[data-pt="globe"] .gpt__halo { fill: rgba(212, 144, 122, 0.26); }

@media (prefers-reduced-motion: reduce) {
  .gpt, .gpt__halo, .gpt__ring, .gpt__core { transition: none; }
}
@media (max-width: 900px) {
  /* stacked: the face becomes a band above the list rather than a column */
  .gainscene { grid-template-columns: 1fr; gap: 20px; }
  .gainscene__stage { aspect-ratio: 16 / 10; max-height: 280px; margin-inline: auto; width: min(100%, 460px); }
  .gv-base { object-position: 50% 32%; }
}

/* rails that auto-scroll can now be stepped by hand as well — the arrows
   drive the marquee's animation-delay, the same mechanism the faculty rail
   already used, so no rail needs its own scroll model */
.leadrail__nav, .logorail__nav { margin-top: 24px; justify-content: center; }

/* ---- the gain face: a layer per chapter, drawn by the scroll ----
   Same idea as the who-scene's four gazes, but nothing here runs on a timer.
   Each layer's animation is a function of --gp, the chapter's own progress
   through its share of the scroll (written by gainScroll in main.js), so the
   contour draws, the scan travels and the orbit turns exactly as far as the
   reader has come — scroll back and it runs backwards. */
.gv-lines, .gv-scan, .gv-pts, .gv-net, .gv-orbit {
  opacity: 0.1;
  transition: opacity 0.7s var(--ease-ui);
}
.gv-base { transition: transform 1.1s var(--ease-out), transform-origin 1.1s var(--ease-out), filter 0.9s var(--ease-ui); }

/* 01 · the contour draws itself along the face as you scroll.
   pathLength="1" on every path means one formula fits them all. */
.gv-lines path {
  stroke: #EADDD0; stroke-width: 1.1; stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: calc(1 - var(--gp, 0));
}
.gv-lines .gv-lines__dash { stroke: rgba(240, 216, 196, 0.7); }

/* 02 · the read travels down the face with the scroll */
.gv-scan { overflow: hidden; }
.gv-scan::before {
  content: ""; position: absolute; left: 4%; right: 4%; height: 15%;
  top: calc(var(--gp, 0) * 116% - 15%);
  background: linear-gradient(180deg, rgba(212, 144, 122, 0), rgba(212, 144, 122, 0.34), rgba(212, 144, 122, 0));
}

/* 03 · the treatment points arrive one after another */
.gv-pts circle {
  fill: none; stroke: #F0D8C4; stroke-width: 1.3;
  transform-box: fill-box; transform-origin: center;
  opacity: clamp(0, calc((var(--gp, 0) - var(--i, 0) * 0.13) * 7), 1);
  transform: scale(calc(0.4 + clamp(0, calc((var(--gp, 0) - var(--i, 0) * 0.13) * 7), 1) * 1.1));
}

/* 04 · the mesh draws between them, then the nodes light */
.gv-net line {
  stroke: rgba(212, 144, 122, 0.55); stroke-width: 0.8;
  stroke-dasharray: 1; stroke-dashoffset: calc(1 - clamp(0, calc(var(--gp, 0) * 1.5), 1));
}
.gv-net circle {
  fill: #F0D8C4;
  opacity: clamp(0, calc((var(--gp, 0) - 0.35 - var(--i, 0) * 0.07) * 8), 1);
}

/* 05 · the rings open out and the dots travel round */
.gv-orbit { overflow: visible; }
.gv-orbit ellipse {
  stroke: rgba(212, 144, 122, 0.38); stroke-width: 0.9;
  stroke-dasharray: 1; stroke-dashoffset: calc(1 - clamp(0, calc(var(--gp, 0) * 1.25), 1));
  transform-box: fill-box; transform-origin: center;
  transform: scale(calc(0.86 + var(--gp, 0) * 0.14));
}
.gv-orbit__dot {
  fill: #F0D8C4;
  transform-box: view-box; transform-origin: 290px 420px;
  transform: rotate(calc(var(--gp, 0) * 300deg));
}
.gv-orbit__dot--b { transform: rotate(calc(90deg + var(--gp, 0) * 300deg)); }
.gv-orbit__dot--c { transform: rotate(calc(200deg + var(--gp, 0) * 300deg)); }

/* ---- which layer each chapter brings forward, and how the photo reads ---- */
.gainscene[data-glow="live"]  .gv-lines { opacity: 1; }
.gainscene[data-glow="live"]  .gv-base  { filter: grayscale(0.45) contrast(1.12) brightness(0.9); }
.gainscene[data-glow="class"] .gv-scan  { opacity: 1; }
.gainscene[data-glow="class"] .gv-base  { filter: grayscale(0) brightness(1.08) saturate(1.1); }
.gainscene[data-glow="hands"] .gv-pts   { opacity: 1; }
.gainscene[data-glow="hands"] .gv-base  { filter: grayscale(0.2) contrast(1.06) brightness(0.96); }
.gainscene[data-glow="panel"] .gv-net   { opacity: 1; }
.gainscene[data-glow="panel"] .gv-base  { filter: grayscale(0.5) brightness(0.86) contrast(1.05); }
.gainscene[data-glow="globe"] .gv-orbit { opacity: 1; }
.gainscene[data-glow="globe"] .gv-base  { filter: grayscale(0.6) brightness(0.8); }

@media (prefers-reduced-motion: reduce) {
  /* nothing to stop — there are no timers — so just show each layer whole */
  .gv-lines path, .gv-net line, .gv-orbit ellipse { stroke-dashoffset: 0; }
  .gv-pts circle, .gv-net circle { opacity: 1; transform: none; }
  .gv-scan::before { top: 42%; }
}

/* ---- and the breath underneath the scroll ----
   Everything above is a function of --gp, which means a page nobody is
   scrolling is a page where nothing moves. So each layer also breathes on
   its own — slowly, slightly, and crucially on properties the scroll is NOT
   already using (stroke-opacity, fill-opacity, and the independent `rotate`
   property, which composes with `transform` rather than replacing it). The
   scroll still owns the story; this just keeps the face alive between
   gestures. */
@keyframes gain-breathe { 50% { stroke-opacity: 0.4; } }
@keyframes gain-twinkle { 50% { fill-opacity: 0.28; } }
@keyframes gain-drift   { to { rotate: 360deg; } }
@keyframes gain-glow    { 50% { opacity: 0.6; } }

.gv-lines path { animation: gain-breathe 7.5s ease-in-out infinite; }
.gv-lines path:nth-child(2n) { animation-delay: -2.6s; }
.gv-lines path:nth-child(3n) { animation-delay: -4.9s; }

.gv-scan::before { animation: gain-glow 4.6s ease-in-out infinite; }

.gv-pts circle { animation: gain-breathe 3.9s ease-in-out infinite; }
.gv-pts circle:nth-child(2n) { animation-delay: -1.3s; }
.gv-pts circle:nth-child(3n) { animation-delay: -2.5s; }

.gv-net line { animation: gain-breathe 6.2s ease-in-out infinite; }
.gv-net line:nth-child(2n) { animation-delay: -2.1s; }
.gv-net circle { animation: gain-twinkle 4.2s ease-in-out infinite; }
.gv-net circle:nth-child(2n) { animation-delay: -1.7s; }

/* the rings turn slowly for ever; the scroll adds its own 300deg on top */
.gv-orbit ellipse { animation: gain-breathe 9s ease-in-out infinite, gain-drift 150s linear infinite; }
.gv-orbit__dot { animation: gain-drift 46s linear infinite; }
.gv-orbit__dot--b { animation-duration: 62s; animation-delay: -18s; }
.gv-orbit__dot--c { animation-duration: 78s; animation-delay: -35s; }

@media (prefers-reduced-motion: reduce) {
  .gv-lines path, .gv-scan::before, .gv-pts circle,
  .gv-net line, .gv-net circle, .gv-orbit ellipse, .gv-orbit__dot { animation: none; }
}

/* ---- the leader line, card to face ---- */
.gconnect {
  position: absolute; inset: 0; width: 100%; height: 100%;
  pointer-events: none; z-index: 2; overflow: visible;
  transition: opacity 0.5s var(--ease-ui);
}
.gconnect__line {
  fill: none; stroke: rgba(212, 144, 122, 0.5); stroke-width: 1;
  stroke-dasharray: 1;
  /* drawn by the chapter's own progress, like every other layer here */
  stroke-dashoffset: calc(1 - clamp(0, calc(var(--gp, 0) * 2.4), 1));
}
.gconnect__end {
  fill: #F0D8C4;
  opacity: clamp(0, calc((var(--gp, 0) - 0.35) * 4), 1);
}
@media (max-width: 900px) { .gconnect { display: none; } }

/* ---- the live marker sends out a ring ---- */
.gpt__wave {
  fill: none; stroke: rgba(240, 216, 196, 0.5); stroke-width: 1.4;
  transform-box: fill-box; transform-origin: center;
  opacity: 0; r: 12;
}
.gainscene[data-glow="live"]  .gpt[data-pt="live"]  .gpt__wave,
.gainscene[data-glow="class"] .gpt[data-pt="class"] .gpt__wave,
.gainscene[data-glow="hands"] .gpt[data-pt="hands"] .gpt__wave,
.gainscene[data-glow="panel"] .gpt[data-pt="panel"] .gpt__wave,
.gainscene[data-glow="globe"] .gpt[data-pt="globe"] .gpt__wave {
  animation: gpt-wave 2.8s ease-out infinite;
}
@keyframes gpt-wave {
  0%   { transform: scale(0.55); opacity: 0.65; }
  70%  { opacity: 0; }
  100% { transform: scale(2.4); opacity: 0; }
}

/* ---- the layer that arrives comes forward, the one leaving steps back ---- */
.gv-lines, .gv-scan, .gv-pts, .gv-net, .gv-orbit {
  transform: scale(0.985);
  transition: opacity 0.7s var(--ease-ui), transform 0.9s var(--ease-out);
  transform-origin: 46% 44%;
}
.gainscene[data-glow="live"]  .gv-lines,
.gainscene[data-glow="class"] .gv-scan,
.gainscene[data-glow="hands"] .gv-pts,
.gainscene[data-glow="panel"] .gv-net,
.gainscene[data-glow="globe"] .gv-orbit { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .gpt__wave { animation: none; }
  .gv-lines, .gv-scan, .gv-pts, .gv-net, .gv-orbit { transform: none; transition: none; }
  .gconnect__line { stroke-dashoffset: 0; }
}

/* ---- gala night (homepage tail) --------------------------------------
   Same .tail rhythm and .infocard as its neighbours; only the head and the
   button row need positioning, and both follow the .endorse pattern above. */
.gala > .container { text-align: center; }
.gala .cardgrid { margin-top: 32px; }
.gala__foot { display: flex; justify-content: center; margin-top: 32px; }

/* ---- founders page ---------------------------------------------------
   .leadcard is declared twice: the later rule fixes it at 248px for the
   homepage marquee, which inside a grid leaves each card stranded at the
   left of its column. On this page the grid owns the width. */
.leadgrid .leadcard { width: auto; }
.founders__feature { padding-bottom: 0; }
@media (max-width: 900px) { .leadgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 620px) { .leadgrid { grid-template-columns: 1fr; } }
.leadership__more { display: flex; justify-content: center; margin-top: 24px; }

/* ---- gala page: the editions list ------------------------------------
   A year rail rather than cards: each entry is one line of fact, and the
   year is the thing the eye lands on. */
.galayears { list-style: none; margin: 0; padding: 0; max-width: 72ch; margin-inline: auto; }
.galayear {
  display: grid; grid-template-columns: 96px 1fr; gap: 20px; align-items: baseline;
  padding: 24px 0; border-top: 1px solid var(--hairline-light);
}
.galayear:last-child { border-bottom: 1px solid var(--hairline-light); }
.galayear__y { font-size: 28px; font-weight: 700; color: var(--accent-strong); line-height: 1; }
.galayear__name { font-size: 20px; font-weight: 700; line-height: 1.25; }
.galayear__meta { font-size: 15px; line-height: 1.55; color: var(--muted-light); margin-top: 4px; }
/* an edition with no record reads as an open slot, not as a styled fact */
.galayear--open .galayear__y,
.galayear--open .galayear__name { color: var(--muted-light); font-weight: 500; }
@media (max-width: 620px) {
  .galayear { grid-template-columns: 1fr; gap: 6px; padding: 20px 0; }
  .galayear__y { font-size: 22px; }
}

/* The homepage ends on seven .tail sections in a row, all on white paper —
   one undifferentiated stretch from the gala to the FAQ. Alternating the
   ground the way about.html alternates --atmo/--tint gives the eye a seam.
   Same token .tail.committee already uses. */
.tail--tint { background: var(--paper-2); }


/* ---- experts: one landing, not a loop ---------------------------------
   The cards arrive once when the section lands (js/expertsnap.js adds
   .is-landed), then rest. The rail is an ordinary scroller from there. */
.docrail { overflow-x: auto; scroll-snap-type: x proximity; scrollbar-width: none; }
.docrail::-webkit-scrollbar { display: none; }
.docrail__track { animation: none; padding-inline: 32px; }
.docrail .scard {
  opacity: 0; transform: translateX(56px);
  transition: opacity 0.7s var(--ease-ui), transform 0.9s var(--ease-out);
  transition-delay: calc(var(--i, 0) * 80ms);
}
.docrail.is-landed .scard { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .docrail .scard { opacity: 1; transform: none; transition: none; }
}


/* ---- pause ambient motion in sections far from the viewport ------------
   js/pauseoffscreen.js sets .is-offscreen. Paused, not removed: the animation
   resumes from where it stopped when the section comes back. */
main > section.is-offscreen *,
main > section.is-offscreen *::before,
main > section.is-offscreen *::after { animation-play-state: paused !important; }

/* the experts rail snaps to its padded edge, so the left gutter survives */
.docrail { scroll-padding-inline: 32px; }



/* ---- event photos: the shuffling deck (js/photodeck.js) --------------------
   Prints are stacked in one cell and posed by the script (transform + opacity
   only). No transitions here on purpose: the script eases everything itself. */
.photos__controls { display: flex; align-items: center; justify-content: center; gap: 20px; flex-wrap: wrap; margin-top: 8px; }
.pdeck { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 16px; outline: none; }
.pdeck__stage {
  position: relative; width: 100%;
  height: clamp(300px, 54vw, 500px);
  display: grid; place-items: center;
  user-select: none; -webkit-user-select: none;
}
.pdeck__card {
  grid-area: 1 / 1; display: block; overflow: hidden;
  width: clamp(200px, 56vw, 340px); aspect-ratio: 4 / 5;
  border-radius: 20px;
  box-shadow: 0 18px 44px rgba(10, 26, 40, 0.18);
  will-change: transform, opacity;
  backface-visibility: hidden;
  pointer-events: none;
  opacity: 0;
}
/* every print is pre-cropped 4:5 around its subject's face (face on the card's
   vertical axis, about 40% down), so the card just shows the picture as is */
.pdeck__card img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pdeck__cap { min-height: 2.6em; text-align: center; max-width: 46ch; }
.pdeck:focus-visible .pdeck__stage { outline: 2px solid var(--accent); outline-offset: 8px; border-radius: 24px; }
@media (prefers-reduced-motion: reduce) { .pdeck__card { transition: none; } }

/* ---- centring: pictures and their captions sit on the axis of their block --
   The endorsement cards left-aligned their logos and copy inside each card. */
.endorse__card { align-items: center; text-align: center; }
.endorse__logo { justify-content: center; }
.endorse__card .body { margin-inline: auto; }

/* ---- founder feature: one centred portrait card at every width ------------
   It used to be a wide card with the photo hanging off its left edge, so the
   picture sat off the page axis on desktop. Now the card is centred and the
   photo is its full-bleed top, exactly like the founder cards in the rail. */
.leadfeature {
  display: block; padding: 0; min-height: 0; overflow: hidden;
  width: min(360px, 100%); max-width: 360px; margin-inline: auto;
  border-radius: 20px; box-shadow: 0 18px 46px rgba(10, 26, 40, 0.09);
  border: 1px solid var(--hairline-light); background: #fff;
}
.leadfeature::before { display: none; }
.leadfeature__flag {
  display: block;   /* it is a <span>: aspect-ratio is ignored on an inline box */
  position: relative; inset: auto; left: auto; top: auto; bottom: auto;
  width: 100%; height: auto; aspect-ratio: 4 / 5; margin: 0;
  border-radius: 0; box-shadow: none;
}
.leadfeature__flag img { object-position: 50% 18%; }
.leadfeature:hover .leadfeature__flag { transform: none; }
.leadfeature figcaption { padding: 16px 18px 20px; gap: 4px; }
.leadfeature figcaption .heading { font-size: 17px; }
.leadfeature .body { margin: 4px 0 12px; font-size: 14px; }

/* ---- experts: the photo carries the Cairo FACE mark, the text sits BELOW it ---
   The portraits now include the mark (top centre, like the leadership photos) and
   the name / role / "Learn more" no longer overlay the face: same card anatomy as
   the founders rail — a 4:5 photo on top, a white panel underneath. */
.docrail .scard:not(.scard--more) {
  display: flex; flex-direction: column; aspect-ratio: auto;
  background: #fff; border: 1px solid var(--hairline-light);
}
.docrail .scard:not(.scard--more) .scard__media {
  position: relative; inset: auto; flex: none; aspect-ratio: 7 / 10;   /* tall enough for the tightest portrait's chin */
  background: linear-gradient(160deg, #A83020, #2C2440);
}
.docrail .scard:not(.scard--more) .scard__media img { object-position: 50% 0; }
.docrail .scard:not(.scard--more) .scard__panel {
  position: static; padding: 16px 18px 18px; gap: 4px; color: var(--ink);
}
.docrail .scard:not(.scard--more) .scard__panel::before { display: none; }
.docrail .scard:not(.scard--more) .scard__name { font-size: 18px; color: var(--ink); }
.docrail .scard:not(.scard--more) .scard__sub { font-size: 13px; color: var(--muted-light); }
.docrail .scard:not(.scard--more) .scard__more {
  width: auto; height: auto; margin-top: 8px; padding: 0; background: none;
  justify-content: flex-start; color: var(--accent-strong);
  font-size: 13px; font-weight: 500; letter-spacing: 0;
}
.docrail .scard:not(.scard--more):hover .scard__more { background: none; text-decoration: underline; }


/* attribution on the written testimonials: each quote links to its original public post */
.quotecard__src { display: block; margin-top: 8px; font-size: 12px; letter-spacing: 0.02em; color: var(--accent-strong); text-decoration: underline; text-underline-offset: 3px; }
.quotecard__src:hover { color: var(--ink); }

/* ---- shorter scroll (client: "too slow, need too much scrolling") ----
   Pin distance (height - 100vh) cut by ~40% on every pinned beat, desktop. */
@media (min-width: 769px) {
  .beat { height: 130vh; }
  .beat--tall { height: 141vh; }
  #hero .beat--tall { height: 139vh; }
  #about .beat { height: 118vh; }
  #about .beat:has(.cardgrid) { height: 142vh; }
  .beat:has(.cardgrid), .beat:has(.audience--rich), .beat:has(.whoscene) { height: 220vh; }
  #who .beat { height: 142vh; }
  #events .beat { height: 106vh; }
  #events .beat:has(.cardgrid) { height: 127vh; }
  #summit .beat--tall { height: 130vh; }
}

/* client: remove the blue corner point on cards */
.tick, .tick--corner { display: none !important; }
