/* ============================================================================
   AMRIT YATRA — page styles
   Extends css/base.css. Uses the existing CHYK tokens (--gold, --font-display,
   --ease, --radius-*) throughout; declares no new colour language of its own.
   ========================================================================== */

.ay {
  --ay-ink: #050505;
  --ay-line: rgba(255, 255, 255, .07);
  --ay-line-soft: rgba(255, 255, 255, .035);
  --ay-lift: cubic-bezier(.16, 1, .3, 1);
  --ay-gutter: clamp(1.25rem, 4vw, 4rem);
  background: var(--ay-ink);
}

/* Reveals are CSS transitions toggled by IntersectionObserver, not GSAP tweens.
   A tween animating opacity from 0 needs gsap.ticker; if the ticker stalls the
   content stays invisible. This degrades to "already visible" instead. */
.ay .gsap-reveal {
  opacity: 0; transform: translateY(26px);
  transition: opacity .8s var(--ay-lift), transform .8s var(--ay-lift);
}
.ay .gsap-reveal.is-in { opacity: 1; transform: none; }

/* Shared furniture ---------------------------------------------------------- */
.ay-section { position: relative; overflow: hidden; padding: clamp(5rem, 12vh, 9rem) var(--ay-gutter); }
.ay-shell { max-width: 1400px; margin: 0 auto; position: relative; z-index: 2; }

/* The oversized ghost word — the site's `core-bg-text` idiom. Clipped by the
   section: it is wider than the viewport and would scroll the page sideways. */
.ay-bgword {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(6rem, 22vw, 22rem); line-height: .8;
  letter-spacing: -.04em; text-transform: uppercase;
  color: rgba(255, 255, 255, .022);
  pointer-events: none; user-select: none; white-space: nowrap; z-index: 0;
}

.ay-eyebrow {
  display: inline-flex; align-items: center; gap: .6rem;
  font-size: .72rem; font-weight: 700; letter-spacing: 3.5px;
  text-transform: uppercase; color: var(--gold); margin-bottom: 1.4rem;
}
.ay-eyebrow::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); flex: none; }

.ay-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.75rem, 6vw, 5.2rem); line-height: .9;
  letter-spacing: -.035em; text-transform: uppercase;
  /* Shared mobile stylesheets set word-break on headings; at this size that
     splits "MOVEMENT," across two lines mid-word. */
  overflow-wrap: normal; word-break: normal; hyphens: none;
}
.ay-title .gold, .gold { color: var(--gold); }
.ay-lede {
  margin-top: 1.25rem; max-width: 54ch;
  font-size: clamp(.95rem, 1.1vw, 1.05rem); line-height: 1.8;
  color: rgba(255, 255, 255, .45);
}

/* ============================================================================
   01 — THE COUNTDOWN
   ========================================================================== */
.ay-hero {
  position: relative; min-height: 100svh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 7rem var(--ay-gutter) 5rem; text-align: center; overflow: hidden;
}
.ay-hero-dust { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.ay-hero-glow {
  position: absolute; left: 50%; top: 38%; width: min(140vw, 1500px); aspect-ratio: 1;
  transform: translate(-50%, -50%); pointer-events: none; z-index: 0;
  background: radial-gradient(circle, rgba(201, 162, 74, .16) 0%, rgba(201, 162, 74, .05) 32%, transparent 66%);
}
/* Only the content column is in flow; every atmosphere layer stays absolute. */
#ay-hero-inner { position: relative; z-index: 3; display: flex; flex-direction: column; align-items: center; }

/* --- the flip clock ------------------------------------------------------- */
.ay-clock {
  display: flex; align-items: flex-start; justify-content: center;
  gap: clamp(.5rem, 2.2vw, 2rem); margin-bottom: clamp(2.5rem, 6vh, 4rem);
  perspective: 1400px;
}
.ay-unit { display: flex; flex-direction: column; align-items: center; gap: .85rem; }
.ay-digits { display: flex; gap: clamp(3px, .5vw, 8px); }
.ay-unit-label {
  font-size: clamp(.58rem, .7vw, .7rem); font-weight: 700; letter-spacing: 4px;
  text-transform: uppercase; color: rgba(255, 255, 255, .34);
}
.ay-colon {
  align-self: flex-start; padding-top: clamp(1.4rem, 3.4vw, 3.2rem);
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.2rem, 2.6vw, 2.4rem); color: rgba(201, 162, 74, .35);
  animation: ayColon 2s steps(1) infinite;
}
@keyframes ayColon { 0%, 49% { opacity: 1 } 50%, 100% { opacity: .25 } }

.ay-flip {
  --ay-card-h: clamp(64px, 10.4vw, 152px);
  position: relative;
  width: clamp(45px, 7.2vw, 106px); height: var(--ay-card-h);
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2.3rem, 6.2vw, 6.2rem); line-height: 1;
  /* Syne's proportional figures differ by up to 60% in width — a "1" is half a
     "9" — so every flip visibly shifted the digit. Its tabular set is uniform. */
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1;
  border-radius: clamp(4px, .5vw, 9px);
  background: #0d0d0d;
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .06),
              0 18px 40px rgba(0, 0, 0, .65), 0 0 0 1px rgba(0, 0, 0, .8);
  transform-style: preserve-3d;
}
.ay-flip::after {
  content: ''; position: absolute; left: 0; right: 0; top: 50%;
  height: 2px; transform: translateY(-1px); z-index: 6;
  background: rgba(0, 0, 0, .9); box-shadow: 0 1px 0 rgba(255, 255, 255, .05);
}
.ay-leaf {
  position: absolute; left: 0; right: 0; height: 50%;
  overflow: hidden; backface-visibility: hidden;
  display: flex; justify-content: center;
  background: linear-gradient(180deg, #1a1a1a, #101010);
}
/* Full-height glyph box: the top leaf clips it from the top and the bottom leaf
   from the bottom, so the two halves line up exactly. */
.ay-leaf span {
  display: block; width: 100%; text-align: center;
  height: var(--ay-card-h); line-height: var(--ay-card-h);
  color: #f2ede2; font-variant-numeric: tabular-nums;
}
.ay-leaf.top { top: 0; border-radius: clamp(4px, .5vw, 9px) clamp(4px, .5vw, 9px) 0 0; align-items: flex-start; }
.ay-leaf.bottom { bottom: 0; border-radius: 0 0 clamp(4px, .5vw, 9px) clamp(4px, .5vw, 9px); align-items: flex-end;
                  background: linear-gradient(180deg, #0e0e0e, #171717); }
.ay-leaf.fold-top, .ay-leaf.fold-bottom { z-index: 5; transform-origin: bottom center; }
.ay-leaf.fold-bottom { transform-origin: top center; transform: rotateX(90deg); }
.ay-flip.is-flipping .fold-top    { animation: ayFoldTop .42s cubic-bezier(.4, 0, .7, .35) forwards }
.ay-flip.is-flipping .fold-bottom { animation: ayFoldBottom .42s cubic-bezier(.3, .7, .6, 1) .4s forwards }
@keyframes ayFoldTop { to { transform: rotateX(-90deg) } }
@keyframes ayFoldBottom { to { transform: rotateX(0deg) } }
.ay-flip.is-flipping .fold-top span    { animation: ayShadeOut .42s linear forwards }
.ay-flip.is-flipping .fold-bottom span { animation: ayShadeIn .42s linear .4s forwards }
@keyframes ayShadeOut { to { filter: brightness(.45) } }
@keyframes ayShadeIn { from { filter: brightness(.45) } to { filter: brightness(1) } }

.ay-hero-headline {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.6rem, 5vw, 4.4rem); line-height: .92;
  letter-spacing: -.04em; text-transform: uppercase; max-width: 18ch;
  overflow-wrap: normal; word-break: normal; hyphens: none;
}
.ay-hero-sub {
  margin-top: 1.4rem; max-width: 46ch;
  font-size: clamp(.88rem, 1vw, 1rem); line-height: 1.8; color: rgba(255, 255, 255, .42);
}
.ay-hero-ctas { margin-top: 2.5rem; display: flex; gap: .85rem; flex-wrap: wrap; justify-content: center; }

.ay-cta-glow { position: relative; isolation: isolate; }
.ay-cta-glow::before {
  content: ''; position: absolute; inset: -4px; border-radius: inherit; z-index: -1;
  background: var(--gold); filter: blur(18px); opacity: .3;
  animation: ayBreathe 3.6s var(--ease) infinite;
}
@keyframes ayBreathe { 0%, 100% { opacity: .22; transform: scale(.97) } 50% { opacity: .46; transform: scale(1.04) } }

.ay-scrollcue {
  position: absolute; bottom: 2rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: .6rem; z-index: 4;
  font-size: .62rem; font-weight: 700; letter-spacing: 3px;
  text-transform: uppercase; color: rgba(255, 255, 255, .28);
}
.ay-scrollcue i { display: block; width: 1px; height: 44px; background: linear-gradient(180deg, var(--gold), transparent); }

/* ============================================================================
   02 — THE MAP. The hero of the page: large, centred, minimal surrounding UI.
   ========================================================================== */
.ay-map-section {
  position: relative; overflow: hidden;
  min-height: 100svh;
  display: flex; flex-direction: column; align-items: center;
  /* Top padding clears the fixed site header, which floats at top:20px —
     no more than that, so the map gets the rest of the screen. */
  padding: clamp(4.25rem, 7.5vh, 5.5rem) var(--ay-gutter) clamp(.75rem, 2vh, 1.5rem);
}
/* A single shaft of light behind the landmass — museum plinth lighting. */
.ay-map-section::before {
  content: ''; position: absolute; left: 50%; top: 46%;
  width: min(120vw, 1200px); aspect-ratio: 1; transform: translate(-50%, -50%);
  background: radial-gradient(circle, rgba(201, 162, 74, .10) 0%, rgba(201, 162, 74, .03) 40%, transparent 68%);
  pointer-events: none; z-index: 0;
}
.ay-map-head { position: relative; z-index: 2; text-align: center; flex: none; }
.ay-map-head .ay-eyebrow { margin-bottom: .5rem; font-size: .64rem; letter-spacing: 3px; }
.ay-map-title {
  font-family: var(--font-display); font-weight: 800;
  /* Wall text, not a headline — the artefact on the plinth is the map. */
  font-size: clamp(1.05rem, 1.8vw, 1.7rem); line-height: 1;
  letter-spacing: -.02em; text-transform: uppercase;
  overflow-wrap: normal; word-break: normal; hyphens: none;
}
.ay-map-hint {
  margin-top: .45rem; font-size: clamp(.72rem, .82vw, .8rem);
  color: rgba(255, 255, 255, .42); max-width: 46ch; margin-inline: auto; line-height: 1.7;
}

.ay-map-wrap {
  position: relative; z-index: 1;
  /* Takes whatever the head and foot leave, rather than a fixed svh share —
     88svh of map plus a head and a foot does not fit in a 100svh section, and
     the legend ends up below the fold. */
  position: relative;
  flex: 1 1 auto; min-height: 0; width: 100%;
  margin-top: clamp(.25rem, 1vh, .75rem);
}
/* Absolute, so the SVG's intrinsic 1000x1080 ratio cannot drive the wrap's
   height — with preserveAspectRatio="xMidYMid meet" it scales to fill whatever
   box the flex row hands it, and the legend below always stays on screen. */
.ay-map-svg {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  overflow: visible; display: block;
}

/* -- state shapes ---------------------------------------------------------
   Two paths per state: `shape` is the fill, `edge` is a hairline that carries
   the hover treatment. No filters anywhere — an animated SVG filter forces the
   whole map to re-rasterise every frame. */
.ay-state-shape {
  fill: rgba(255, 255, 255, .035);
  stroke: rgba(255, 255, 255, .13);
  stroke-width: .9; stroke-linejoin: round;
  transition: fill .45s var(--ease), stroke .45s var(--ease);
}
.ay-state-edge { fill: none; stroke: transparent; stroke-width: 2.4; stroke-linejoin: round; transition: stroke .4s var(--ease); }

.ay-state.is-visited .ay-state-shape { fill: url(#ay-land); stroke: rgba(201, 162, 74, .5); stroke-width: 1.05; }
.ay-state.is-open { cursor: pointer; }

/* Hover: lift, brighten, and a warm rim. transform-box keeps the transform
   origin on the shape itself rather than the whole SVG. */
.ay-state {
  transform-box: fill-box; transform-origin: center;
  opacity: 0;
  transition: transform .5s var(--ay-lift), opacity .55s ease var(--ay-in, 0ms);
}
.ay-map-svg.is-in .ay-state { opacity: 1; }
.ay-state.is-open:hover, .ay-state.is-open:focus-visible { transform: translateY(-6px) scale(1.015); outline: none; }
.ay-state.is-open:hover .ay-state-shape,
.ay-state.is-open:focus-visible .ay-state-shape { fill: rgba(232, 190, 90, .34); stroke: var(--gold-bright); stroke-width: 1.5; }
.ay-state.is-open:hover .ay-state-edge,
.ay-state.is-open:focus-visible .ay-state-edge { stroke: rgba(232, 190, 90, .22); }

/* The invitation to explore next. Paint-only: fill and stroke-width. */
.ay-state.is-next .ay-state-shape { stroke: var(--gold-bright); animation: ayNextPulse 2.4s var(--ease) infinite; }
@keyframes ayNextPulse {
  0%, 100% { fill: rgba(201, 162, 74, .16); stroke-width: 1.1 }
  50%      { fill: rgba(232, 190, 90, .34); stroke-width: 2 }
}
.ay-state.is-seen .ay-state-shape { fill: rgba(201, 162, 74, .3); stroke: rgba(232, 190, 90, .72); }

.ay-state-label {
  font-family: var(--font-body); font-size: 11px; font-weight: 700;
  letter-spacing: 1.2px; text-transform: uppercase;
  fill: rgba(255, 255, 255, .22); pointer-events: none;
  transition: fill .35s var(--ease);
}
.ay-state-label.is-visited { fill: rgba(255, 255, 255, .58); font-size: 12px; }
.ay-state-label.is-hot { fill: var(--gold-bright); }

/* -- hover card ----------------------------------------------------------- */
.ay-tip {
  position: absolute; z-index: 6; pointer-events: none;
  transform: translate(-50%, calc(-100% - 16px));
  padding: .7rem .95rem; min-width: 170px;
  background: rgba(8, 8, 8, .95); backdrop-filter: blur(10px);
  border: 1px solid rgba(201, 162, 74, .3); border-radius: var(--radius);
  box-shadow: 0 20px 50px rgba(0, 0, 0, .7);
  opacity: 0; transition: opacity .25s var(--ease);
  display: flex; flex-direction: column; gap: .2rem; text-align: left;
}
.ay-tip.is-on { opacity: 1; }
.ay-tip.is-below { transform: translate(-50%, 16px); }
.ay-tip b { font-family: var(--font-display); font-size: .95rem; font-weight: 800; letter-spacing: -.01em; }
.ay-tip i { font-style: normal; font-size: .74rem; color: rgba(255, 255, 255, .4); line-height: 1.45; }
.ay-tip u {
  text-decoration: none; margin-top: .3rem;
  font-size: .62rem; font-weight: 700; letter-spacing: 2px;
  text-transform: uppercase; color: var(--gold);
}


/* -- the cartographic bed --------------------------------------------------
   Five-degree meridians and parallels. The map used to float in a void; this
   gives it a plate to sit on. A slow breath keeps it alive without ever
   pulling focus from the states. */
.ay-graticule line { stroke: rgba(201, 162, 74, .16); stroke-width: .7; }
.ay-graticule { animation: ayGratBreath 9s ease-in-out infinite; }
@keyframes ayGratBreath { 0%, 100% { opacity: .55 } 50% { opacity: 1 } }

/* Corner brackets: the map reads as a mounted exhibit rather than a stray SVG. */
.ay-map-wrap::before, .ay-map-wrap::after {
  content: ''; position: absolute; width: clamp(22px, 3vw, 40px); aspect-ratio: 1;
  border: 1px solid rgba(201, 162, 74, .28); pointer-events: none;
}
.ay-map-wrap::before { top: 0; left: clamp(.5rem, 4vw, 4rem); border-right: 0; border-bottom: 0; }
.ay-map-wrap::after { bottom: 0; right: clamp(.5rem, 4vw, 4rem); border-left: 0; border-top: 0; }

/* Legend and tally — the only fixed text around the map, and both are data. */
.ay-map-foot {
  position: relative; z-index: 3; flex: none;
  width: 100%; max-width: 1400px; margin: 0 auto;
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding-top: clamp(.5rem, 1.5vh, 1rem);
  font-size: .62rem; font-weight: 700; letter-spacing: 2.4px;
  text-transform: uppercase; color: rgba(255, 255, 255, .3);
}
.ay-legend { display: flex; gap: clamp(.85rem, 2vw, 1.6rem); flex-wrap: wrap; }
.ay-legend span { display: inline-flex; align-items: center; gap: .45rem; }
.ay-legend em { font-style: normal; }
.ay-legend i { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.ay-legend .lit { background: rgba(201, 162, 74, .55); box-shadow: 0 0 0 1px rgba(201, 162, 74, .8); }
.ay-legend .unlit { background: rgba(255, 255, 255, .05); box-shadow: 0 0 0 1px rgba(255, 255, 255, .18); }
.ay-map-tally b { color: var(--gold-bright); font-size: .8rem; }

/* ============================================================================
   THE RIBBON — every visited state as a moving index
   ========================================================================== */
.ay-ribbon-section {
  position: relative; overflow: hidden;
  padding: clamp(1.5rem, 4vh, 2.75rem) 0;
  border-top: 1px solid var(--ay-line-soft);
  border-bottom: 1px solid var(--ay-line-soft);
  background: linear-gradient(90deg, rgba(201, 162, 74, .05), transparent 30%, transparent 70%, rgba(201, 162, 74, .05));
}
/* Feathered ends so the loop dissolves instead of being cut off. */
.ay-ribbon-section::before, .ay-ribbon-section::after {
  content: ''; position: absolute; top: 0; bottom: 0; width: clamp(3rem, 12vw, 12rem);
  z-index: 3; pointer-events: none;
}
.ay-ribbon-section::before { left: 0; background: linear-gradient(90deg, var(--ay-ink), transparent); }
.ay-ribbon-section::after { right: 0; background: linear-gradient(270deg, var(--ay-ink), transparent); }

.ay-ribbon { position: relative; overflow: hidden; }
/* The track holds two identical copies; translating exactly -50% lands copy two
   where copy one began, so the seam is never visible. */
.ay-ribbon-track {
  display: flex; align-items: center; gap: clamp(1rem, 2.5vw, 2.25rem);
  width: max-content; will-change: transform;
  animation: ayMarquee 95s linear infinite;
}
.ay-ribbon:hover .ay-ribbon-track { animation-play-state: paused; }
@keyframes ayMarquee { from { transform: translateX(0) } to { transform: translateX(-50%) } }

.ay-ribbon-item {
  position: relative; background: none; border: 0; cursor: pointer;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.5rem, 3.6vw, 3.1rem); line-height: 1;
  letter-spacing: -.03em; text-transform: uppercase;
  color: rgba(255, 255, 255, .42);
  transition: color .35s var(--ease);
  white-space: nowrap; padding: .2rem 0;
}
.ay-ribbon-item i {
  font-style: normal; font-family: var(--font-body);
  font-size: .3em; font-weight: 700; letter-spacing: 1.5px;
  color: var(--gold); vertical-align: super; margin-left: .35em;
  opacity: .55; transition: opacity .35s var(--ease);
}
.ay-ribbon-item:hover, .ay-ribbon-item:focus-visible { color: var(--gold-bright); outline: none; }
.ay-ribbon-item:hover i { opacity: 1; }
.ay-ribbon-sep { color: rgba(201, 162, 74, .3); font-size: clamp(.5rem, 1vw, .7rem); flex: none; }

/* ============================================================================
   DISPATCHES — the photographs, on the page
   ========================================================================== */
.ay-dispatches { padding-bottom: clamp(4rem, 9vh, 7rem); }
.ay-marquee {
  position: relative; overflow: hidden;
  margin-top: clamp(1.25rem, 3vh, 2rem);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.ay-marquee-track {
  display: flex; gap: clamp(.75rem, 1.5vw, 1.25rem);
  width: max-content; will-change: transform;
  animation: ayMarquee 64s linear infinite;
}
.ay-marquee-track.is-reverse { animation-direction: reverse; animation-duration: 78s; }
.ay-marquee:hover .ay-marquee-track { animation-play-state: paused; }

.ay-dispatch {
  flex: 0 0 auto; width: clamp(220px, 24vw, 320px);
  background: none; border: 0; padding: 0; cursor: pointer; text-align: left;
  display: flex; flex-direction: column; gap: .7rem;
  transition: transform .45s var(--ay-lift);
}
.ay-dispatch:hover, .ay-dispatch:focus-visible { transform: translateY(-6px); outline: none; }
.ay-dispatch-shot {
  position: relative; display: block; aspect-ratio: 4 / 3; overflow: hidden;
  border-radius: var(--radius); background: #0d0d0d;
  border: 1px solid rgba(255, 255, 255, .06);
  transition: border-color .4s var(--ease);
}
.ay-dispatch:hover .ay-dispatch-shot { border-color: rgba(201, 162, 74, .45); }
.ay-dispatch-shot img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: grayscale(.25) brightness(.98);
  transition: transform .8s var(--ease), filter .5s var(--ease);
}
.ay-dispatch:hover .ay-dispatch-shot img { transform: scale(1.06); filter: none; }
.ay-dispatch-no {
  position: absolute; top: .55rem; left: .6rem; z-index: 2;
  padding: .18rem .45rem; border-radius: 3px;
  background: rgba(5, 5, 5, .6); backdrop-filter: blur(4px);
  font-size: .55rem; font-weight: 700; letter-spacing: 1.8px; color: rgba(255, 255, 255, .6);
}
.ay-dispatch-meta { display: flex; flex-direction: column; gap: .22rem; padding: 0 .15rem; }
.ay-dispatch-state { font-size: .58rem; font-weight: 700; letter-spacing: 2.4px; text-transform: uppercase; color: var(--gold); }
.ay-dispatch-ttl {
  font-family: var(--font-display); font-weight: 800; font-size: .95rem;
  letter-spacing: -.01em; line-height: 1.15; color: rgba(255, 255, 255, .9);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ay-dispatch-loc {
  font-size: .7rem; color: rgba(255, 255, 255, .34);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ============================================================================
   SCROLL READ-OUT
   ========================================================================== */
.ay-scrollbar {
  position: fixed; top: 0; left: 0; right: 0; height: 2px; z-index: 700;
  transform-origin: left center; transform: scaleX(0);
  background: linear-gradient(90deg, var(--gold), var(--gold-bright));
  pointer-events: none;
}
body.ay-story-open .ay-scrollbar { opacity: 0; }

/* ============================================================================
   03 — LIVE YATRA STATS (kinetic typography, not cards)
   ========================================================================== */
.ay-stats { border-top: 1px solid var(--ay-line-soft); }
.ay-stat-list { margin-top: clamp(2rem, 6vh, 4rem); }
.ay-stat {
  display: grid; grid-template-columns: 4.5rem 1fr auto; align-items: baseline;
  gap: clamp(1rem, 3vw, 3rem);
  padding: clamp(1.4rem, 3.5vh, 2.6rem) 0;
  border-bottom: 1px solid var(--ay-line-soft);
  position: relative; overflow: hidden;
}
.ay-stat::after {
  content: ''; position: absolute; left: 0; bottom: -1px; height: 1px; width: 0;
  background: linear-gradient(90deg, var(--gold), transparent); transition: width .8s var(--ease);
}
.ay-stat:hover::after { width: 100%; }
.ay-stat-idx { font-size: .68rem; font-weight: 700; letter-spacing: 2.5px; color: rgba(201, 162, 74, .55); font-variant-numeric: tabular-nums; }
.ay-stat-num {
  font-family: var(--font-display); font-weight: 800; line-height: .85;
  letter-spacing: -.045em; color: var(--white);
  font-size: clamp(2.6rem, 9vw, 8rem);
  font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1;
  transition: color .4s var(--ease), transform .6s var(--ay-lift); transform-origin: left center;
}
.ay-stat[data-weight="1"] .ay-stat-num { font-size: clamp(2rem, 6vw, 5.2rem); color: rgba(255, 255, 255, .72); }
.ay-stat:hover .ay-stat-num { color: var(--gold-bright); transform: translateX(10px); }
.ay-stat-meta { text-align: right; }
.ay-stat-label {
  display: block; font-family: var(--font-display); font-weight: 800;
  font-size: clamp(.85rem, 1.5vw, 1.35rem); letter-spacing: .5px;
  text-transform: uppercase; color: rgba(255, 255, 255, .82);
}
.ay-stat-note { display: block; margin-top: .35rem; font-size: .7rem; letter-spacing: 2px; text-transform: uppercase; color: rgba(255, 255, 255, .28); }

/* ============================================================================
   04 — THE STATE STORY EXPERIENCE
   A fullscreen exhibition built for twenty stops.
   ========================================================================== */
/* content-visibility keeps this subtree — and its backdrop-filter — out of the
   compositor entirely while closed. A live full-viewport blurred layer is on
   its own enough to stop the page ever finishing a frame. */
.ay-story {
  position: fixed; inset: 0; z-index: 950;
  display: flex; flex-direction: column;
  background: rgba(4, 4, 4, .96);
  opacity: 0; visibility: hidden; pointer-events: none;
  content-visibility: hidden;
  transition: opacity .5s var(--ease), visibility .5s;
}
.ay-story.is-open {
  opacity: 1; visibility: visible; pointer-events: auto;
  content-visibility: visible;
  backdrop-filter: blur(24px); -webkit-backdrop-filter: blur(24px);
}
.ay-story-grain {
  position: absolute; inset: 0; pointer-events: none; z-index: 4; opacity: .05; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
}
.ay-story.is-open .ay-story-grain { animation: grainShift .14s steps(1) infinite; }

/* The shared persistent logo sits at z-index 999999 with mix-blend-mode, right
   over the close button. It steps aside while the exhibition is open. */
body.ay-story-open .persistent-chyk-logo,
body.ay-story-open .site-header,
body.ay-story-open .ay-float { opacity: 0 !important; pointer-events: none !important; }

/* -- header: state name, progress, controls ------------------------------- */
.ay-story-top { position: relative; z-index: 6; flex: none; padding: clamp(.9rem, 2vh, 1.4rem) clamp(1rem, 3vw, 2.5rem) 0; }
.ay-story-bar-row { display: flex; align-items: center; gap: clamp(.75rem, 2vw, 1.5rem); }
.ay-story-id { display: flex; flex-direction: column; gap: .15rem; min-width: 0; }
.ay-story-state {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.05rem, 2.2vw, 1.75rem); line-height: 1;
  text-transform: uppercase; letter-spacing: -.02em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ay-story-tag { font-size: .66rem; letter-spacing: 2.4px; text-transform: uppercase; color: var(--gold); }
.ay-story-counter {
  margin-left: auto; flex: none;
  font-family: var(--font-display); font-weight: 800; font-size: clamp(1rem, 2vw, 1.5rem);
  letter-spacing: 1px; color: rgba(255, 255, 255, .35); font-variant-numeric: tabular-nums;
}
.ay-story-counter b { color: var(--gold-bright); }
.ay-story-counter span { margin: 0 .2em; color: rgba(255, 255, 255, .2); }

.ay-iconbtn {
  width: 38px; height: 38px; flex: none; border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .12); background: rgba(255, 255, 255, .04);
  display: grid; place-items: center; color: rgba(255, 255, 255, .75);
  transition: all .25s var(--ease);
}
.ay-iconbtn:hover { color: var(--white); border-color: var(--gold); background: rgba(201, 162, 74, .12); transform: scale(1.06); }
.ay-iconbtn svg { width: 15px; height: 15px; }
.ay-iconbtn.is-off { opacity: .45; }

/* One continuous progress bar, plus a tick per stop. At twenty stops a segment
   tray becomes hairline noise, so the ticks are a scrubbable index instead. */
.ay-story-bar { position: relative; height: 2px; margin-top: .9rem; background: rgba(255, 255, 255, .1); border-radius: 2px; overflow: hidden; }
.ay-story-bar-fill {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--gold), var(--gold-bright));
  will-change: width;   /* the script transitions this across each dwell */
}
.ay-story-dots {
  display: flex; gap: 3px; margin-top: .55rem; padding-bottom: .5rem;
  overflow-x: auto; scrollbar-width: none;
}
.ay-story-dots::-webkit-scrollbar { display: none; }
.ay-dot {
  flex: 1 1 0; min-width: 10px; height: 14px; padding: 5px 0;
  background: none; border: 0; cursor: pointer;
}
.ay-dot::before {
  content: ''; display: block; height: 3px; border-radius: 2px;
  background: rgba(255, 255, 255, .14); transition: background .3s var(--ease), transform .3s var(--ease);
}
.ay-dot:hover::before { background: rgba(255, 255, 255, .4); }
.ay-dot.is-done::before { background: rgba(201, 162, 74, .45); }
.ay-dot.is-on::before { background: var(--gold-bright); transform: scaleY(1.8); }

/* -- stage ---------------------------------------------------------------- */
.ay-story-stage {
  position: relative; z-index: 5; flex: 1; min-height: 0;
  display: grid; place-items: center;
  padding: clamp(.75rem, 2vh, 1.5rem) clamp(3.5rem, 7vw, 6rem) clamp(1rem, 3vh, 2rem);
}
.ay-slide {
  position: absolute;
  inset: clamp(.75rem, 2vh, 1.5rem) clamp(3.5rem, 7vw, 6rem) clamp(1rem, 3vh, 2rem);
  display: grid; place-items: center;
  opacity: 0; visibility: hidden; pointer-events: none;
}
.ay-slide.is-current { opacity: 1; visibility: visible; pointer-events: auto; }

.ay-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 7;
  width: clamp(38px, 4vw, 52px); height: clamp(38px, 4vw, 52px); border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .14); background: rgba(10, 10, 10, .6);
  backdrop-filter: blur(8px); display: grid; place-items: center;
  color: rgba(255, 255, 255, .8); transition: all .3s var(--ease);
}
.ay-nav:hover { border-color: var(--gold); color: var(--gold-bright); background: rgba(201, 162, 74, .14); }
.ay-nav.prev { left: clamp(.5rem, 1.5vw, 1.5rem) }
.ay-nav.next { right: clamp(.5rem, 1.5vw, 1.5rem) }
.ay-nav svg { width: 17px; height: 17px; }

/* -- the record ------------------------------------------------------------
   One composition, and the photograph is it. The frame is filled edge to edge;
   the only permanent text is the event, the place and three facts. Everything
   else — the account and the full dossier — waits behind Details, so the
   picture never competes with a page of copy. The data is disclosed, not
   discarded. */
.ay-card {
  position: relative; width: 100%; height: 100%;
  max-width: min(1500px, 100%); min-height: 0; min-width: 0;
  /* Photograph on top, caption beneath. The caption used to sit over the
     picture; with more than half the archive in portrait that meant text
     across somebody's face. Its own row cannot do that. */
  display: grid; grid-template-rows: minmax(0, 1fr) auto;
  gap: clamp(.75rem, 1.6vw, 1.15rem);
}
/* The photograph IS the frame.

   There is deliberately no plate behind it. A box with its own dimensions can
   only match the picture on one axis at a time — width binds on a phone, height
   binds on a desktop — so any plate eventually shows a mismatch on one of them.
   Letting the image size itself means what you see is exactly the photograph:
   whole, never cropped, never enlarged, at every viewport. */
.ay-shot { position: relative; min-height: 0; min-width: 0; overflow: hidden; }
/* The image fills its area and `contain` fits the picture inside it.

   It must have a definite size: sizing it from its own intrinsic dimensions
   (`width:auto`) computes to 0x0 before the file arrives, and a zero-sized
   `loading="lazy"` image never intersects the viewport, so it never loads at
   all — a deadlock where the photograph simply never appears.

   The element box may therefore be larger than the picture, but the box is
   transparent and unstyled, so what the eye sees is the photograph alone at its
   own ratio: whole, never cropped, never enlarged. */
/* Absolute, so the box is exactly the area the layout allocated.

   Two things go wrong otherwise. Sized from its own intrinsic dimensions
   (`width:auto`) it computes to 0x0 before the file arrives, and a zero-sized
   `loading="lazy"` image never intersects the viewport, so it never loads at
   all. Left in flow, its aspect-ratio grows the row past the space available
   and the picture spills over the caption beneath it. */
.ay-photo {
  position: absolute; inset: 0;
  display: block;
  width: 100%; height: 100%;
  object-fit: contain;
  object-position: center;
}

/* the caption row — three lines, no more */
.ay-caption {
  position: relative; z-index: 4;
  border-left: 2px solid var(--gold); padding-left: clamp(.85rem, 1.5vw, 1.2rem);
  padding-right: clamp(6.5rem, 12vw, 11rem);
  transition: opacity .4s var(--ease), transform .4s var(--ease);
}
.ay-loc {
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .68rem; font-weight: 700; letter-spacing: 2.5px;
  text-transform: uppercase; color: var(--gold);
}
.ay-loc::before { content: ''; width: 4px; height: 4px; border-radius: 50%; background: currentColor; flex: none; }
.ay-ttl {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  letter-spacing: -.03em; line-height: .96;
  font-size: clamp(1.15rem, 2.6vw, 2.3rem); margin-top: .35rem;
  overflow-wrap: normal; word-break: normal; hyphens: none;
}
.ay-facts {
  display: flex; flex-wrap: wrap; align-items: center; gap: .4rem clamp(.75rem, 1.6vw, 1.4rem);
  margin-top: .5rem;
  font-size: .66rem; font-weight: 700; letter-spacing: 2px;
  text-transform: uppercase; color: rgba(255, 255, 255, .5);
}
.ay-facts span { display: inline-flex; align-items: center; gap: clamp(.75rem, 1.6vw, 1.4rem); }
.ay-facts span + span::before {
  content: ''; width: 3px; height: 3px; border-radius: 50%;
  background: rgba(255, 255, 255, .3); flex: none;
}
.ay-empty { color: rgba(255, 255, 255, .28); font-weight: 400; }

/* A portrait frame in a wide stage would be squeezed into a short row and end
   up tiny. Giving it the full height and standing the caption beside it uses
   the space the photograph cannot, and the picture gets as large as the stage
   allows. Landscape keeps the caption underneath. */
@media (min-width: 760px) {
  .ay-card.is-portrait {
    grid-template-columns: minmax(0, 1fr) minmax(230px, 30%);
    grid-template-rows: minmax(0, 1fr);
    gap: clamp(1.25rem, 3vw, 2.5rem);
    /* NOT align-items:center — .ay-shot's children are all absolute, so it has
       no intrinsic height and would collapse to zero rather than stretch. The
       caption is centred on its own instead. */
  }
  .ay-card.is-portrait .ay-caption {
    padding-right: 0; padding-bottom: 3rem;
    align-self: center;
  }
  /* Long moment names get a narrow column here, so ease the display size. */
  .ay-card.is-portrait .ay-ttl { font-size: clamp(1.05rem, 1.8vw, 1.65rem); }
  /* The toggle already sits bottom-right of the card, which in this layout is
     the foot of the caption column. Nothing to move. */
}

/* the toggle — above the panel it opens, so it stays available to close it */
.ay-more {
  position: absolute; z-index: 7;
  right: 0; bottom: .1rem;
  display: inline-flex; align-items: center; gap: .5rem;
  padding: .6rem 1rem; border-radius: var(--radius-pill);
  background: rgba(10, 10, 10, .6); backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .16);
  font-size: .64rem; font-weight: 700; letter-spacing: 2.2px;
  text-transform: uppercase; color: rgba(255, 255, 255, .8);
  transition: all .3s var(--ease);
}
.ay-more:hover { color: var(--white); border-color: var(--gold); background: rgba(201, 162, 74, .16); }
.ay-more svg { width: 11px; height: 11px; transition: transform .35s var(--ease); }
.ay-card.is-detailed .ay-more svg { transform: rotate(180deg); }

/* the dossier — everything the caption leaves out */
.ay-details {
  position: absolute; z-index: 6; left: 0; right: 0; bottom: 0;
  border-radius: var(--radius-lg);
  padding: clamp(1.5rem, 3vw, 2.5rem) clamp(1.25rem, 3vw, 3rem) clamp(4.75rem, 8vw, 5.5rem);
  background: linear-gradient(0deg, rgba(4, 4, 4, .97) 60%, rgba(4, 4, 4, .82));
  backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
  border-top: 1px solid rgba(201, 162, 74, .22);
  transform: translateY(101%); transition: transform .55s var(--ay-lift);
  max-height: 78%; overflow-y: auto; scrollbar-width: none;
}
.ay-details::-webkit-scrollbar { display: none; }
.ay-card.is-detailed .ay-details { transform: none; }
.ay-card.is-detailed .ay-caption { opacity: 0; transform: translateY(12px); pointer-events: none; }

.ay-desc {
  max-width: 62ch;
  font-size: clamp(.86rem, 1.05vw, 1rem); line-height: 1.8; color: rgba(255, 255, 255, .68);
}
.ay-details-grid {
  margin-top: clamp(1.25rem, 2.5vw, 2rem);
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.25rem, 3vw, 3rem); align-items: start;
}
.ay-meta-row {
  display: grid; grid-template-columns: 1fr auto; gap: 1rem; align-items: baseline;
  padding: .42rem 0; border-bottom: 1px solid var(--ay-line-soft);
}
.ay-meta-row dt { font-size: .62rem; font-weight: 700; letter-spacing: 2.2px; text-transform: uppercase; color: rgba(255, 255, 255, .3); }
.ay-meta-row dd {
  font-family: var(--font-display); font-size: .88rem; font-weight: 800;
  letter-spacing: -.01em; color: rgba(255, 255, 255, .88); text-align: right;
}
.ay-hl-title {
  display: block; margin-bottom: .5rem;
  font-size: .62rem; font-weight: 700; letter-spacing: 2.2px;
  text-transform: uppercase; color: var(--gold);
}
.ay-highlights ul { display: flex; flex-direction: column; gap: .38rem; }
.ay-highlights li {
  position: relative; padding-left: .95rem;
  font-size: .78rem; line-height: 1.55; color: rgba(255, 255, 255, .5);
}
.ay-highlights li::before {
  content: ''; position: absolute; left: 0; top: .5em;
  width: 4px; height: 1px; background: var(--gold); opacity: .7;
}
.ay-highlights p { font-size: .78rem; }

/* entrance */
.ay-slide.is-current .ay-card { animation: ayEnter .7s var(--ay-lift) both; }
@keyframes ayEnter { from { opacity: 0; transform: scale(1.02) } to { opacity: 1; transform: none } }

/* end card — a pause, not a pitch: the state, the count, one way out */
.l-end { display: grid; place-items: center; }
.ay-endcard {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: .9rem; padding: clamp(1.5rem, 4vw, 3rem);
}
.ay-endcard-ttl {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.5rem, 4vw, 2.8rem); line-height: 1;
  letter-spacing: -.03em; color: rgba(255, 255, 255, .92);
}
.ay-endcard-btn {
  margin-top: .75rem;
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .8rem 1.5rem .8rem 1.2rem; border-radius: var(--radius-pill);
  border: 1px solid rgba(201, 162, 74, .45); background: rgba(201, 162, 74, .08);
  font-size: .72rem; font-weight: 700; letter-spacing: 2.2px;
  text-transform: uppercase; color: var(--gold-bright);
  transition: all .3s var(--ease);
}
.ay-endcard-btn:hover {
  background: var(--gold); border-color: var(--gold); color: #050505;
  transform: translateY(-2px); box-shadow: 0 12px 30px rgba(201, 162, 74, .3);
}
.ay-endcard-btn svg { width: 14px; height: 14px; transition: transform .3s var(--ease); }
.ay-endcard-btn:hover svg { transform: translateX(-3px); }

/* ============================================================================
   CELEBRATION · FLOATING CTA · FINALE
   ========================================================================== */
.ay-toast {
  position: fixed; left: 50%; bottom: 6rem; transform: translateX(-50%); z-index: 945;
  display: inline-flex; align-items: center; gap: .7rem;
  padding: .7rem 1.15rem; border-radius: var(--radius-pill);
  background: rgba(10, 10, 10, .94); backdrop-filter: blur(10px);
  border: 1px solid rgba(201, 162, 74, .32);
  font-size: .72rem; font-weight: 700; letter-spacing: 1.8px;
  text-transform: uppercase; color: rgba(255, 255, 255, .85);
}
.ay-toast i { width: 7px; height: 7px; border-radius: 50%; background: var(--gold-bright); flex: none; }

.ay-float {
  position: fixed; right: clamp(1rem, 2.5vw, 2rem); bottom: clamp(1rem, 2.5vw, 2rem);
  z-index: 600; opacity: 0; transform: translateY(20px) scale(.94);
  pointer-events: none; transition: all .5s var(--ay-lift);
}
.ay-float.is-visible { opacity: 1; transform: none; pointer-events: auto; }
.ay-float .btn { box-shadow: 0 14px 40px rgba(201, 162, 74, .4); }

.ay-finale { text-align: center; border-top: 1px solid var(--ay-line-soft); }
.ay-finale .ay-lede { margin-inline: auto; }
.ay-finale-ctas { margin-top: 2.5rem; display: flex; gap: .85rem; flex-wrap: wrap; justify-content: center; }
.ay-quote { margin-top: clamp(3rem, 8vh, 5rem); padding-top: clamp(2rem, 5vh, 3rem); border-top: 1px solid var(--ay-line-soft); }
.ay-quote p {
  font-family: var(--font-display); font-weight: 800; font-style: italic;
  font-size: clamp(1.1rem, 2.4vw, 2rem); line-height: 1.3; letter-spacing: -.02em;
  max-width: 22ch; margin: 0 auto; color: rgba(255, 255, 255, .8);
}
.ay-quote cite {
  display: block; margin-top: 1.1rem; font-style: normal;
  font-size: .7rem; font-weight: 700; letter-spacing: 3px;
  text-transform: uppercase; color: var(--gold);
}

/* ============================================================================
   RESPONSIVE
   ========================================================================== */
/* Short viewports: the caption keeps its three lines, the type just gets
   smaller. Nothing is dropped, because there is little left to drop. */
@media (max-height: 760px) {
  .ay-ttl { font-size: clamp(1.3rem, 3.4vw, 2.4rem); }
  .ay-facts { margin-top: .55rem; font-size: .62rem; }
  .ay-desc { font-size: .84rem; line-height: 1.7; }
  .ay-meta-row { padding: .32rem 0; }
  .ay-meta-row dd { font-size: .8rem; }
  .ay-highlights li { font-size: .72rem; line-height: 1.45; }
  .ay-highlights ul { gap: .28rem; }
}

@media (max-width: 767px) {
  /* All four units stay on a single row. The cards are shrunk enough that the
     nine digits (3 for days + 2 each for hours/minutes/seconds) fit across the
     narrowest phones without wrapping. */
  .ay-clock {
    flex-wrap: nowrap; justify-content: center; align-items: flex-start;
    gap: clamp(6px, 2.4vw, 14px);
    max-width: 100%; margin-inline: auto;
    margin-bottom: clamp(1.75rem, 4vh, 2.5rem);
  }
  .ay-colon { display: none; }
  .ay-clock > .ay-unit { flex: 0 0 auto; gap: .5rem; }
  .ay-flip {
    --ay-card-h: clamp(42px, 12vw, 66px);
    width: clamp(26px, 7.6vw, 42px);
    font-size: clamp(1.35rem, 5.4vw, 2.2rem);
    border-radius: 4px;
  }
  .ay-digits { gap: 2px; }
  .ay-unit-label {
    font-size: clamp(.5rem, 2.2vw, .62rem); letter-spacing: 1px; white-space: nowrap;
  }

  /* 34px is under the comfortable tap size; the story controls get 40. */
  .ay-iconbtn { width: 40px; height: 40px; }
  .ay-iconbtn svg { width: 14px; height: 14px; }
  /* The ribbon is a control, not just a banner — give it a real tap height. */
  .ay-ribbon-item { padding: .5rem 0; }

  .ay-map-section { min-height: auto; padding-bottom: clamp(2rem, 5vh, 3rem); }
  /* The section stops being height-constrained here, so `flex:1` would hand the
     wrap zero height and the absolutely-positioned SVG would have no box to
     fill. Give it an explicit box shaped like the country instead. */
  .ay-map-wrap { flex: none; width: 100%; aspect-ratio: 1 / 1.06; max-height: 66svh; }
  .ay-state-label { font-size: 15px; }
  /* Hover cards are meaningless on touch — the tap opens the state directly. */
  .ay-tip { display: none; }

  .ay-stat { grid-template-columns: 2.4rem 1fr; gap: .9rem 1rem; }
  .ay-stat-meta { grid-column: 2; text-align: left; }
  .ay-stat:hover .ay-stat-num { transform: none; }

  .ay-story-stage, .ay-slide { padding-inline: 0; }
  .ay-slide { inset: .5rem .75rem 1rem; }
  .ay-story-stage { padding: .5rem .75rem 1rem; }
  .ay-nav { display: none; }                       /* swipe instead */
  .ay-story-top { padding: .8rem 1rem 0; }
  /* Six items in 375px: drop the tagline and shrink the controls so the state
     name keeps its space instead of truncating to three letters. */
  /* "Madhya Pradesh" cannot share 375px with a counter and three controls, so
     the name drops to its own full-width row rather than truncating. */
  .ay-story-bar-row { gap: .55rem; flex-wrap: wrap; }
  .ay-story-id { order: 10; flex: 1 0 100%; margin-top: .45rem; }
  .ay-story-tag { display: none; }
  .ay-story-state { font-size: 1.2rem; }
  .ay-story-counter { font-size: 1.05rem; }
  .ay-details-grid { grid-template-columns: 1fr; gap: 1.25rem; }
  /* Moment names run long ("Adoni, Tirupati, Kadapa, Kurnool & Vizag"). Capped
     at three lines so the caption block stays a predictable height and the
     Details control never gets pushed off the bottom; the full name is in the
     Details panel's Moment row. */
  .ay-ttl {
    font-size: clamp(1.1rem, 5.2vw, 1.6rem);
    display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .ay-desc { font-size: .84rem; line-height: 1.72; }
  /* The toggle sits under the caption so neither has to shrink. */
  .ay-caption { padding-right: 0; padding-bottom: 2.6rem; }
  .ay-more { left: 0; right: auto; bottom: 0; }
  .ay-details { padding-bottom: clamp(4.25rem, 14vw, 5rem); max-height: 88%; }
  .ay-facts { gap: .4rem .8rem; font-size: .62rem; }
  /* Twenty ticks in a phone's width would be sub-pixel — let them scroll. */
  .ay-dot { flex: 0 0 auto; width: 16px; }
  .ay-bgword { font-size: 28vw; }
  .ay-dispatch { width: clamp(180px, 62vw, 240px); }
  .ay-ribbon-track { animation-duration: 34s; }
  .ay-marquee-track { animation-duration: 40s; }
  .ay-marquee-track.is-reverse { animation-duration: 48s; }
  /* The map heading above is centred, so the legend and tally centre too
     rather than sitting hard left under it. */
  .ay-map-foot {
    font-size: .58rem; letter-spacing: 2px;
    flex-direction: column; align-items: center; gap: .6rem; text-align: center;
  }
  .ay-legend { justify-content: center; }
  .ay-map-tally { max-width: 30ch; }
}

@media (prefers-reduced-motion: reduce) {
  .ay-flip.is-flipping .fold-top,
  .ay-flip.is-flipping .fold-bottom,
  .ay-flip.is-flipping .fold-top span,
  .ay-flip.is-flipping .fold-bottom span { animation: none !important; }
  .ay-leaf.fold-top { transform: rotateX(-90deg) }
  .ay-leaf.fold-bottom { transform: rotateX(0deg) }
  .ay-state, .ay-cta-glow::before, .ay-graticule, .ay-ribbon-track, .ay-marquee-track,
  .ay-colon, .ay-story-grain, .ay-state.is-next .ay-state-shape { animation: none !important; }
  .ay-slide.is-current .ay-card { animation: none !important; }
  .ay-state.is-open:hover { transform: none; }
  .ay .gsap-reveal { opacity: 1; transform: none; transition: none; }
  .ay-state { opacity: 1; transition: none; }
}
