/**
 * Traverse CSS
 * @version 1.6.0
 */

:root {
  --tv-slide-speed: 300ms;
  --tv-slide-x-speed: 300ms;
  --tv-slide-mini-speed: 260ms;
  /* Throw distance for the -mini slide variants: how far a panel travels
     (as a % of its own size) before it's fully faded. Small by design — a
     restrained nudge for nested Traverses. Tune here; JS reads the speed
     var, the keyframes read this one. */
  --tv-slide-mini-dist: 25%;
  --tv-fade-speed:  220ms;
  --tv-scale-speed: 250ms;
  --tv-easing:      ease;
}

/* ─── PANEL BASE ─────────────────────────────────────────────────────────── */

.tv-panel {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  /* Library-level default: pages commonly add their own overflow-y:auto
     to a .tv-panel (or a wrapper sharing its box), and without this the
     content shifts sideways whenever a scrollbar appears/disappears on
     panel switch. Only takes effect on panels that actually scroll —
     harmless no-op otherwise. */
  scrollbar-gutter: stable;
}

.tv-panel.tv-active {
  z-index: 1;
  display: block;
  visibility: visible;
  opacity: 1;
  pointer-events: auto;
}

.tv-panel.tv-hidden {
  display: none;
  pointer-events: none;
}

.tv-panel.tv-anim-in,
.tv-panel.tv-anim-out {
  display: block;
  visibility: visible;
  pointer-events: none;
  user-select: none;
}

.tv-panel.tv-anim-in  { z-index: 2; }
.tv-panel.tv-anim-out { z-index: 1; }


/* ─── SLIDE (vertical) ───────────────────────────────────────────────────── */

.tv-panel.tv-anim-in.tv-slide-up    { animation: tv-slide-up-in    var(--tv-slide-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-up   { animation: tv-slide-up-out   var(--tv-slide-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-in.tv-slide-down  { animation: tv-slide-down-in  var(--tv-slide-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-down { animation: tv-slide-down-out var(--tv-slide-speed) var(--tv-easing) forwards; }

@keyframes tv-slide-up-in    { from { transform: translate3d(0,  100%, 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-up-out   { from { transform: translate3d(0,    0,  0); opacity: 1; } to { transform: translate3d(0, -100%, 0); opacity: 0; } }
@keyframes tv-slide-down-in  { from { transform: translate3d(0, -100%, 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-down-out { from { transform: translate3d(0,    0,  0); opacity: 1; } to { transform: translate3d(0,  100%, 0); opacity: 0; } }


/* ─── SLIDE-X (horizontal) ───────────────────────────────────────────────── */

.tv-panel.tv-anim-in.tv-slide-left   { animation: tv-slide-left-in   var(--tv-slide-x-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-left  { animation: tv-slide-left-out  var(--tv-slide-x-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-in.tv-slide-right  { animation: tv-slide-right-in  var(--tv-slide-x-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-right { animation: tv-slide-right-out var(--tv-slide-x-speed) var(--tv-easing) forwards; }

@keyframes tv-slide-left-in    { from { transform: translate3d( 100%, 0, 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-left-out   { from { transform: translate3d(   0,  0, 0); opacity: 1; } to { transform: translate3d(-100%, 0, 0); opacity: 0; } }
@keyframes tv-slide-right-in   { from { transform: translate3d(-100%, 0, 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-right-out  { from { transform: translate3d(   0,  0, 0); opacity: 1; } to { transform: translate3d( 100%, 0, 0); opacity: 0; } }


/* ─── SLIDE-MINI (vertical, short throw) ─────────────────────────── */
/* Same direction + easing as the full vertical slide, but the panel travels
   only --tv-slide-mini-dist and fades fully over that short distance. The
   incoming panel enters opaque-ish and settles; the outgoing panel drifts a
   little and fades out — a restrained nudge for nested Traverses. */

.tv-panel.tv-anim-in.tv-slide-up-mini    { animation: tv-slide-up-mini-in    var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-up-mini   { animation: tv-slide-up-mini-out   var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-in.tv-slide-down-mini  { animation: tv-slide-down-mini-in  var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-down-mini { animation: tv-slide-down-mini-out var(--tv-slide-mini-speed) var(--tv-easing) forwards; }

@keyframes tv-slide-up-mini-in    { from { transform: translate3d(0, var(--tv-slide-mini-dist), 0);              opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-up-mini-out   { from { transform: translate3d(0, 0, 0); opacity: 1; } to { transform: translate3d(0, calc(-1 * var(--tv-slide-mini-dist)), 0); opacity: 0; } }
@keyframes tv-slide-down-mini-in  { from { transform: translate3d(0, calc(-1 * var(--tv-slide-mini-dist)), 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-down-mini-out { from { transform: translate3d(0, 0, 0); opacity: 1; } to { transform: translate3d(0, var(--tv-slide-mini-dist), 0);              opacity: 0; } }


/* ─── SLIDE-X-MINI (horizontal, short throw) ─────────────────────── */

.tv-panel.tv-anim-in.tv-slide-left-mini   { animation: tv-slide-left-mini-in   var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-left-mini  { animation: tv-slide-left-mini-out  var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-in.tv-slide-right-mini  { animation: tv-slide-right-mini-in  var(--tv-slide-mini-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-slide-right-mini { animation: tv-slide-right-mini-out var(--tv-slide-mini-speed) var(--tv-easing) forwards; }

@keyframes tv-slide-left-mini-in    { from { transform: translate3d(var(--tv-slide-mini-dist), 0, 0);              opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-left-mini-out   { from { transform: translate3d(0, 0, 0); opacity: 1; } to { transform: translate3d(calc(-1 * var(--tv-slide-mini-dist)), 0, 0); opacity: 0; } }
@keyframes tv-slide-right-mini-in   { from { transform: translate3d(calc(-1 * var(--tv-slide-mini-dist)), 0, 0); opacity: 0; } to { transform: translate3d(0, 0, 0); opacity: 1; } }
@keyframes tv-slide-right-mini-out  { from { transform: translate3d(0, 0, 0); opacity: 1; } to { transform: translate3d(var(--tv-slide-mini-dist), 0, 0);              opacity: 0; } }


/* ─── FADE ───────────────────────────────────────────────────────────────── */

.tv-panel.tv-anim-in.tv-fade  { animation: tv-fade-in  var(--tv-fade-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-fade { animation: tv-fade-out var(--tv-fade-speed) var(--tv-easing) forwards; }

@keyframes tv-fade-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes tv-fade-out { from { opacity: 1; } to { opacity: 0; } }


/* ─── SCALE ──────────────────────────────────────────────────────────────── */

.tv-panel.tv-anim-in.tv-scale  { animation: tv-scale-in  var(--tv-scale-speed) var(--tv-easing) forwards; }
.tv-panel.tv-anim-out.tv-scale { animation: tv-scale-out var(--tv-scale-speed) var(--tv-easing) forwards; }

@keyframes tv-scale-in  { from { transform: scale(0.95); opacity: 0; } to { transform: scale(1);    opacity: 1; } }
@keyframes tv-scale-out { from { transform: scale(1);    opacity: 1; } to { transform: scale(0.95); opacity: 0; } }


/* ─── CONTAINER ──────────────────────────────────────────────────────────── */

.tv-container {
  position: relative;
  overflow: hidden;
  touch-action: manipulation; /* eliminates 300ms tap delay on touch devices
    without blocking scroll or zoom — tap latency killer for tab bars */
}


/* Reduced-motion handling lives in JS now (traverse.js's _isReducedMotion()
   / show(), driven by each instance's reduceMotion config and
   Traverse.setGlobalReduceMotion() — see js/motion.js). A blanket CSS
   @media (prefers-reduced-motion: reduce) rule used to live here, but it
   collapsed animation-duration unconditionally at the browser level,
   which fought the JS-level "explicitly override reduced motion" choice
   in the Motion popover — picking Slide or Fade would still render as an
   instant snap because the CSS never knew about the override. Removed
   so JS is the single source of truth for whether reduced motion applies. */
