/* ============================================================================
   THE NURSE BRIDGE — FAST-TRAVEL GRAMMAR  (shared visual language of movement)
   travel.css  ·  pair with /js/travel.js  ·  budget: <= 8 KB gzip
   ----------------------------------------------------------------------------
   ONE sequence, every place. A place-to-place navigation reads like a cut in a
   film: the leaving page pushes back a hair, a gold light-streak wipes the
   frame, the destination blooms in its own accent with a "-> <Place>" chip.
   450-650 ms of PERCEIVED motion, but the part that ever blocks a real request
   is <= 220 ms (see travel.js). Transform + opacity only. No layout, no paint
   storms, one full-viewport layer at a time.

   Two engines, mutually exclusive (travel.js picks one):
     A. NATIVE cross-document View Transitions  -> ::view-transition-*(root)
        A seamless snapshot cross-cut. Browser drives it; JS never delays nav.
     B. JS FALLBACK overlay  -> .travel-veil (streak + chip + glow)
        For browsers without cross-document VT (older WebViews, Firefox, etc).
   Both share the SAME accent tokens + arrival bloom, so identity is constant.
   ============================================================================ */

/* ---- per-place accent + push direction ---------------------------------- *
 * Set html[data-place="<slug>"] on every page. Arrival reads its OWN accent
 * here (pure CSS, no JS needed); departure reads the DESTINATION accent from
 * the JS twin of this table. --tv-dir (-1|0|+1) biases the directional push.  */
:root{
  --tv-accent:#e0b877;            /* default = brand gold */
  --tv-dir:0;
  --tv-ink:#05060a;
  --tv-exit-ms:210;               /* request-blocking budget ceiling          */
  --tv-arrive-ms:340;             /* free — destination is already loading    */
}
:root[data-place="home"]        { --tv-accent:#e0b877; --tv-dir:0;  }
:root[data-place="hall"]        { --tv-accent:#efc76a; --tv-dir:1;  }
:root[data-place="universities"]{ --tv-accent:#63cdbd; --tv-dir:-1; }
:root[data-place="standings"]   { --tv-accent:#e6a55c; --tv-dir:1;  }
:root[data-place="communities"] { --tv-accent:#82c79b; --tv-dir:-1; }
:root[data-place="forums"]      { --tv-accent:#79bfe6; --tv-dir:1;  }
:root[data-place="journal"]     { --tv-accent:#a99be6; --tv-dir:-1; }
:root[data-place="pathway"]     { --tv-accent:#f2d38a; --tv-dir:0;  }
:root[data-place="placement"]   { --tv-accent:#6fcfe0; --tv-dir:1;  }
:root[data-place="chapters"]    { --tv-accent:#e6a07e; --tv-dir:-1; }
:root[data-place="partners"]    { --tv-accent:#8aa6e6; --tv-dir:1;  }
:root[data-place="provinces"]   { --tv-accent:#e39177; --tv-dir:-1; }

/* ==========================================================================
   ENGINE A — NATIVE cross-document View Transitions
   Opt both documents in. The browser snapshots old + new <html> and tweens
   them. We keep it to a short, well-matched directional cut (a 250 ms matched
   cut beats a 900 ms delay). Accent identity arrives via the veil bloom that
   travel.js triggers on pagereveal, so this stays snapshot-safe.
   ========================================================================== */
/* @view-transition navigation:auto REMOVED (Carlos 2026-07-11): the native
   browser transition is too subtle; travel.js now drives the dramatic overlay
   on every tier instead. Kept the ::view-transition rules below inert (they
   only fire under an opt-in that no longer exists) for reference. */
/* @view-transition { navigation: auto; }  -- intentionally disabled */

::view-transition-group(root){ animation-duration:320ms; }
::view-transition-old(root){
  animation:tv-root-out 210ms cubic-bezier(.4,0,.9,.3) both;
}
::view-transition-new(root){
  animation:tv-root-in 320ms cubic-bezier(.15,.75,.2,1) both;
}
@keyframes tv-root-out{
  to{ opacity:0; transform:scale(1.022) translateX(calc(var(--tv-dir) * -1.2%)); }
}
@keyframes tv-root-in{
  from{ opacity:0; transform:scale(.988) translateX(calc(var(--tv-dir) * 1.6%)); }
}

/* ==========================================================================
   ENGINE B — JS FALLBACK overlay
   travel.js injects exactly this (<= 5 nodes) once, then reuses it:
     .travel-veil > .travel-streak , .travel-chip(> arrow + name) , .travel-glow
   Idle state = invisible + pointer-events:none. States are class-driven so a
   stuck veil can never survive a pageshow (travel.js hard-resets on restore).
   ========================================================================== */
.travel-veil{
  position:fixed; inset:0; z-index:9700; pointer-events:none;
  opacity:0; visibility:hidden;
  contain:layout paint;                   /* isolate from page layout/paint   */
}
.travel-veil::before{                     /* the ink dip behind the streak    */
  content:""; position:absolute; inset:0;
  background:radial-gradient(120% 90% at 50% 50%,
             rgba(5,6,10,.30) 0%, rgba(5,6,10,.78) 70%, var(--tv-ink) 100%);
  opacity:0; transition:opacity 160ms linear;
}

/* the gold light-streak — a canted bar that wipes across on translateX only  */
.travel-streak{
  position:absolute; top:-20%; bottom:-20%; left:-40%; width:36%;
  transform:translate3d(-180%,0,0) rotate(9deg);
  background:linear-gradient(90deg,
     rgba(255,255,255,0) 0%,
     color-mix(in srgb, var(--tv-accent) 30%, transparent) 30%,
     var(--tv-accent) 50%,
     #fff6e2 54%,
     color-mix(in srgb, var(--tv-accent) 30%, transparent) 72%,
     rgba(255,255,255,0) 100%);
  filter:blur(2px);
  opacity:.9;
}

/* destination name chip — "-> The Conference Hall" */
.travel-chip{
  position:absolute; left:26px; bottom:30px;
  display:inline-flex; align-items:center; gap:10px;
  padding:10px 16px 10px 14px; border-radius:100px;
  font-family:var(--font-mono,"Cascadia Code",Consolas,monospace);
  font-size:.72rem; letter-spacing:.14em; text-transform:uppercase;
  color:#f4ecda; white-space:nowrap;
  background:rgba(8,11,16,.72);
  border:1px solid color-mix(in srgb, var(--tv-accent) 55%, transparent);
  box-shadow:0 10px 34px -14px color-mix(in srgb, var(--tv-accent) 70%, transparent);
  transform:translate3d(0,14px,0); opacity:0;
}
.travel-chip .tv-arrow{ color:var(--tv-accent); font-size:.9rem; line-height:1; }
.travel-chip .tv-name{ color:#f7efdd; }

/* accent bloom — radial glow in the destination's colour */
.travel-glow{
  position:absolute; left:50%; top:46%; width:64vmax; height:64vmax;
  transform:translate3d(-50%,-50%,0) scale(.6); transform-origin:center;
  background:radial-gradient(circle,
     color-mix(in srgb, var(--tv-accent) 26%, transparent) 0%,
     color-mix(in srgb, var(--tv-accent) 8%, transparent) 34%,
     transparent 62%);
  opacity:0; pointer-events:none;
}

/* ---- DEPARTURE (leaving page, fallback engine only) --------------------- */
.travel-veil.is-exiting{ visibility:visible; opacity:1; pointer-events:auto; }
.travel-veil.is-exiting::before{ opacity:1; }
.travel-veil.is-exiting .travel-streak{ animation:tv-streak 260ms cubic-bezier(.5,0,.2,1) both; }
.travel-veil.is-exiting .travel-chip{ animation:tv-chip-in 220ms cubic-bezier(.2,.8,.2,1) both; }
.travel-veil.is-exiting .travel-glow{ animation:tv-glow 300ms ease-out both; }

/* the leaving page itself pushes back a hair — transform only, on <main>     */
html.travel-exiting main{
  transform:scale(.992) translateX(calc(var(--tv-dir) * -0.5%));
  transform-origin:center 42%;
  transition:transform 220ms cubic-bezier(.4,0,.9,.3);
  will-change:transform;
}

/* ---- ARRIVAL (destination, both engines) -------------------------------- *
 * Veil starts covering, then lifts as the accent blooms and the chip settles.
 * Never touches the page's own .reveal / .stop entrance — that plays beneath. */
.travel-veil.is-arriving{ visibility:visible; opacity:1; }
/* Native View-Transitions tier = glow-only on arrival (the browser drives the
   cut). The ink veil, gold streak and destination chip are the JS-FALLBACK
   grammar only, so scope them to :root.travel-fallback; native keeps just the
   accent bloom below. */
:root.travel-fallback .travel-veil.is-arriving::before{ opacity:1; animation:tv-veil-lift 360ms ease-out both; }
:root.travel-fallback .travel-veil.is-arriving .travel-streak{ animation:tv-streak-rev 300ms cubic-bezier(.5,0,.2,1) both; }
.travel-veil.is-arriving .travel-glow{ animation:tv-glow 420ms ease-out both; }
:root.travel-fallback .travel-veil.is-arriving .travel-chip{ animation:tv-chip-arrive 520ms cubic-bezier(.2,.8,.2,1) both; }

@keyframes tv-streak{
  0%{ transform:translate3d(-180%,0,0) rotate(9deg); opacity:0; }
  30%{ opacity:.95; }
  100%{ transform:translate3d(360%,0,0) rotate(9deg); opacity:0; }
}
@keyframes tv-streak-rev{         /* reverse sweep on arrival */
  0%{ transform:translate3d(360%,0,0) rotate(9deg); opacity:0; }
  40%{ opacity:.8; }
  100%{ transform:translate3d(-180%,0,0) rotate(9deg); opacity:0; }
}
@keyframes tv-chip-in{
  0%{ transform:translate3d(0,14px,0); opacity:0; }
  100%{ transform:translate3d(0,0,0); opacity:1; }
}
@keyframes tv-chip-arrive{
  0%{ transform:translate3d(0,14px,0); opacity:0; }
  22%{ transform:translate3d(0,0,0); opacity:1; }
  72%{ opacity:1; }
  100%{ transform:translate3d(0,-4px,0); opacity:0; }
}
@keyframes tv-glow{
  0%{ transform:translate3d(-50%,-50%,0) scale(.6); opacity:0; }
  35%{ opacity:1; }
  100%{ transform:translate3d(-50%,-50%,0) scale(1.12); opacity:0; }
}
@keyframes tv-veil-lift{
  0%{ opacity:1; } 60%{ opacity:.55; } 100%{ opacity:0; }
}

/* ==========================================================================
   TIER B — reduced motion  (also honoured for Save-Data in travel.js)
   No zoom, no streak, no bloom, no snapshot tween. Navigation is instant.
   ========================================================================== */
@media (prefers-reduced-motion: reduce){
  ::view-transition-group(root),
  ::view-transition-old(root),
  ::view-transition-new(root){ animation:none !important; }
  .travel-veil{ display:none !important; }
  html.travel-exiting main{ transform:none !important; transition:none !important; }
}
