/* Theme 13 — motion.css
   Polish layer loaded AFTER common.css so these rules win the cascade.
   Owns: (1) the single big hero portrait, (2) the gaganthapa.com-style hero text
   stagger (blur-fade word entrance, driven by motion.js), (3) refined scroll
   reveals for the lower bands, (4) the "read more" band links.
   Every animated surface degrades to its final state under prefers-reduced-motion. */

:root {
  /* Easing curves lifted verbatim from the gaganthapa.com motion audit. */
  --t13-mo-quart: cubic-bezier(0.165, 0.84, 0.44, 1);   /* easeOutQuart */
  --t13-mo-quint: cubic-bezier(0.22, 1, 0.36, 1);       /* easeOutQuint */
  --t13-mo-back:  cubic-bezier(0.34, 1.56, 0.64, 1);    /* easeOutBack  */
}

/* =====================================================================
   1. HERO — one big, confident portrait (the accent "flag" image is gone)
   ===================================================================== */

/* Give the visual a touch more room than the text column now that it stands
   alone, and centre it in that column. */
.t13-hero__grid { grid-template-columns: 1fr 1.05fr; }

.t13-hero__figure--solo { justify-self: center; width: 100%; }

/* Bigger, self-assured portrait. drop-shadow (not box-shadow) traces the PNG
   cut-out's alpha silhouette instead of boxing the transparent canvas. */
.t13-hero__portrait {
  width: clamp(320px, 42vw, 560px);
  max-width: 100%;
  /* Rounded so a rectangular portrait PHOTO (seeder now feeds a 900x1200 portrait,
     not a cut-out PNG) reads as a framed figure; on a transparent cut-out the
     rounded corners fall on empty pixels, so this is a no-op there. The drop-shadow
     then traces the rounded frame / the cut-out silhouette respectively. */
  border-radius: 20px;
  filter: drop-shadow(0 26px 46px color-mix(in srgb, var(--t13-primary) 22%, transparent));
}
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .t13-hero__portrait { filter: drop-shadow(0 26px 46px rgba(31, 58, 95, .22)); }
}

/* Tame the ambient glow so it frames the larger portrait instead of fighting it. */
.t13-hero__figure--solo::before {
  inset: 6% -4% -2% -4%;
  background: radial-gradient(circle at 50% 42%, var(--t13-p-100), transparent 72%);
  opacity: .85;
}

/* ---------- Landscape hero photo ----------
   The treatment above (silhouette drop-shadow + ambient glow) assumes a TALL alpha-cutout
   PNG of a standing figure. A wide scene photo (hero_image whose intrinsic width > height,
   flagged as .t13-hero__figure--landscape by hero.blade.php) needs a framed rectangle
   instead: object-fit cover into a set aspect, rounded corners, a real box-shadow. Gated
   by ASPECT RATIO — not tenant or colour — so cutout portraits (theme13 demo, netapolish)
   are untouched; the shadow tint derives from --t13-primary, so it stays primary-agnostic. */
.t13-hero__figure--landscape { width: 100%; }
.t13-hero__figure--landscape::before { display: none; }
.t13-hero__figure--landscape .t13-hero__portrait {
  width: 100%;
  max-width: 620px;
  aspect-ratio: 16 / 10;
  object-fit: cover;
  border-radius: 16px;
  filter: none;
  box-shadow: 0 26px 46px color-mix(in srgb, var(--t13-primary) 22%, transparent);
}
@supports not (color: color-mix(in srgb, red 50%, blue)) {
  .t13-hero__figure--landscape .t13-hero__portrait { box-shadow: 0 26px 46px rgba(31, 58, 95, .22); }
}

/* No portrait entrance — measured on gaganthapa.com: the hero image has ZERO
   animation (getAnimations().length === 0, no parallax, no scale). The client
   chose "match reference: text only", so the portrait is static; do not add
   scale/opacity motion or resize it here. */

/* Retire the block-level slide-in — motion.js now animates each line/word so the
   two must not stack. display:block still comes from the common.css rule.
   Gated behind `.t13-motion` (set by the <head> script only when JS runs) so
   that with JS off — or if motion.js fails to load — common.css's t13-slide-in
   still plays and the hero text is never stuck hidden. */
.t13-motion .t13-hero__slide.is-active { animation: none; }

/* Parked start state for the staggered hero text (title + lead only — the
   eyebrow has no parked state here, so motion.js parks the whole incoming
   slide with visibility:hidden during the exit; see swap()).
   motion.js reveals these; the reduced-motion fallback below (opacity:1
   !important) and the no-JS path (no `.t13-motion` class) both restore them.
   Progressive enhancement: visible by default, parked only when motion is
   actually active. */
.t13-motion .t13-hero__slide .t13-hero__title,
.t13-motion .t13-hero__slide .t13-lead { opacity: 0; }

/* Individual words (wrapped by motion.js, title AND lead). `display: inline`
   — not inline-block — so wrapping stays natural, per the gaganthapa.com
   measurement: opacity + blur only, no transform. */
.t13-motion .t13-hero__title .t13-word,
.t13-motion .t13-lead .t13-word {
  display: inline;
  opacity: 0;
  filter: blur(10px);
  will-change: opacity, filter;
}

/* Word stagger (consumed by motion.js — title: 500ms/200ms-per-word stagger;
   lead: 1000ms/20ms-per-word stagger; both eased with the measured ease-out
   curve, cubic-bezier(0, 0, 0.58, 1)). */
@keyframes t13mo-word {
  from { opacity: 0; filter: blur(10px); }
  to   { opacity: 1; filter: blur(0); }
}

/* Whole-slide crossfade wrapper — the AnimatePresence mode="wait" equivalent
   for the 6s milestone rotation. motion.js forces the outgoing slide to stay
   display:block for exactly this exit's duration (script.js's carousel would
   otherwise snap it to display:none the instant it loses .is-active); the
   incoming slide only starts t13mo-hero-enter once that exit has fully
   finished — never both slides moving at once. */
@keyframes t13mo-hero-exit {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(-15px); }
}
@keyframes t13mo-hero-enter {
  from { opacity: 0; transform: translateY(15px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Anti-CLS: reserve room for the tallest realistic title/lead so swapping
   between milestones of different text length never jolts the buttons/portrait
   below. Title mirrors t13-h1's own fluid clamp doubled (line-height:1, so one
   line's height == the font-size — doubling reserves 2 lines at every
   viewport). Lead is a fixed 1rem/1.75 line-height (28px/line) column that
   actually wraps MORE on the full-width single-column mobile layout (narrow
   phone viewport) than on the >1024px two-column layout's narrower-but-wider
   text column, hence the taller mobile default. */
.t13-hero__slide .t13-hero__title { min-height: clamp(4.5rem, 10.4vw, 7.5rem); }
.t13-hero__slide .t13-lead { min-height: 7.5rem; }
@media (min-width: 1025px) {
  .t13-hero__slide .t13-lead { min-height: 6.25rem; }
}

/* =====================================================================
   2. SCROLL REVEALS — refine the built-in [data-reveal] feel
   Enhances (does not replace) the common.css observer-driven reveals with
   a gaganthapa-style unblur and easeOutQuart timing.
   ===================================================================== */
/* Only up/pop get the gaganthapa unblur — left/right stay pure slides (their
   filter isn't transitioned in common.css, so blurring them would snap). */
[data-reveal="up"] {
  filter: blur(6px);
  transition: opacity .7s var(--t13-mo-quart), transform .7s var(--t13-mo-quart), filter .7s var(--t13-mo-quart);
}
[data-reveal="pop"] {
  filter: blur(6px);
  transition: opacity .6s var(--t13-mo-back), transform .6s var(--t13-mo-back), filter .6s var(--t13-mo-quart);
}
[data-reveal="up"].is-in,
[data-reveal="pop"].is-in { filter: blur(0); }

/* Grouped children reveal one-after-another (≤3 per the spec) via transition-delay. */
.t13-impact__grid [data-reveal]:nth-child(2) { transition-delay: .08s; }
.t13-impact__grid [data-reveal]:nth-child(3) { transition-delay: .16s; }
.t13-impact__grid [data-reveal]:nth-child(4) { transition-delay: .24s; }
.t13-speeches__grid [data-reveal]:nth-child(2) { transition-delay: .08s; }
.t13-speeches__grid [data-reveal]:nth-child(3) { transition-delay: .16s; }

/* =====================================================================
   3. "READ MORE" band links
   ===================================================================== */
.t13-readmore {
  display: inline-flex; align-items: center; gap: .4rem;
  margin-top: 1.5rem;
  font-weight: 700; font-size: 1rem; line-height: 1.4;
  color: var(--t13-accent-ink);
  transition: gap .25s var(--t13-ease-ctrl), color .2s var(--t13-ease-ctrl);
}
.t13-readmore svg { transition: transform .25s var(--t13-ease-ctrl); }
.t13-readmore:hover { gap: .7rem; color: var(--t13-p-700); }
.t13-readmore:hover svg { transform: translateX(3px); }
.t13-readmore-row { margin-top: 2rem; }

/* =====================================================================
   4. RESPONSIVE — hero's own mobile behaviour, plus a lighter reveal blur
   ===================================================================== */
@media (max-width: 1024px) {
  .t13-hero__grid { grid-template-columns: 1fr; }
  .t13-hero__figure--solo { order: -1; max-width: 480px; margin-inline: auto; }
  .t13-hero__portrait { width: clamp(260px, 66vw, 440px); }
}

/* Trim the §2 reveal's pre-animation blur radius on phones — 6px is a
   noticeably heavier rasterize/composite cost than 3px on low-end hardware,
   so [data-reveal="up"] / [data-reveal="pop"] resolve to their .is-in state
   a touch snappier there. Only the blur RADIUS shrinks (same .7s/.6s
   duration and easing as §2, untouched) — desktop (>768px) keeps the full
   6px. */
@media (max-width: 768px) {
  [data-reveal="up"],
  [data-reveal="pop"] {
    filter: blur(3px);
  }
}

/* =====================================================================
   5. A11Y — reduced motion shows every final state, nothing parked
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  .t13-hero__slide,
  .t13-hero__slide .t13-eyebrow,
  .t13-hero__slide .t13-hero__title,
  .t13-hero__slide .t13-lead,
  .t13-hero__title .t13-word,
  .t13-lead .t13-word {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
    animation: none !important;
  }
  [data-reveal] { filter: none; }
}
