/* ============================================================
   MOTION TOKENS — the single source of truth for every app
   (apps/web, apps/admin, apps/portal all load this file).

   Rules of the system (2026 standards, see docs/design/motion.md):
   - Enter decelerates (ease-emphasized / ease-standard), exit accelerates
     (ease-exit), and an EXIT is always one duration tier shorter than its
     enter: popover 180 in / 100 out, modal 280 in / 180 out.
   - Animate transform + opacity only. Never height/width/top/left
     (use grid-template-rows 0fr→1fr, FLIP, or View Transitions).
   - Overshoot (ease-spring) is for celebration/confirmation moments only:
     badge pops, success checks, switch thumbs. Never on a leave, never on
     utility chrome (modals, popovers, toasts, tabs).
   - Hover feedback ≤ 200ms; press feedback ≤ 100ms and synchronous.
   - Stagger: --anim-stagger-step per item, cap at 8 items.
   - Reduced motion: movement collapses (move tokens → 0, press scale → 1,
     stagger → 0) but the state change still registers. The app-wide
     duration kill switch lives in apps/web/assets/css/animations.css.

   Legacy aliases (--transition-*, --motion-*, --ease-*,
   --anim-duration-instant/base/content/emphasis, --anim-ease-decelerate/
   accelerate) are kept so older CSS keeps resolving, but new code uses
   the --anim-* names below.
   ============================================================ */

:root {
  /* ── Durations: 5 tiers ──
     micro      hover, focus, press, popover EXIT, toggles
     fast       dropdowns, tooltips, tab indicator, modal EXIT, toast exit
     standard   modals, drawers, collapse, list mutations, empty state
     expressive sheets, page pushes (mobile), choreographed enters
     dramatic   skeleton reveals, chart draw-in, KPI count-ups only */
  --anim-duration-micro: 0.1s;
  --anim-duration-fast: 0.18s;
  --anim-duration-standard: 0.28s;
  --anim-duration-expressive: 0.4s;
  --anim-duration-dramatic: 0.6s;
  /* Tooltip enter only — the standards doc calls this out as its own
     timing (125ms), between micro and fast rather than on either tier.
     Tooltip exit reuses --anim-duration-micro (100ms), which already
     matches. Hover-only / no touch, so no phone override needed. */
  --anim-duration-tooltip: 125ms;

  /* ── Outside the 5-tier system: continuous/looping indicators and holds ──
     Not enter/exit transitions, so the tier ladder above doesn't apply
     (same reasoning as .animate-spin's own fixed 1s speed). */
  /* Indeterminate progress-bar sweep loop (PullToRefreshIndicator's strip). */
  --anim-duration-sweep: 1.2s;
  /* How long an ERROR state holds visible before dismissing — deliberately
     longer than the success hold (--anim-duration-dramatic, 0.6s) so there
     is time to read what went wrong. usePullToRefresh.ts's error-hold
     setTimeout is pinned to this same 1400ms; change both together. */
  --anim-duration-error-hold: 1.4s;

  /* ── Easings ──
     standard    MD3 standard: everyday state changes, FLIP moves
     emphasized  MD3 emphasized-decelerate: entering surfaces (modal, popover)
     exit        MD3 accelerate: anything leaving
     drawer      iOS/Vaul signature curve: sheets, drawers, page push/pop
     snappy      barely-there overshoot: switch thumb, tab indicator settle
     spring      visible overshoot: badge pop, success check, celebration
     hover       plain `ease`: colour/background hover changes only */
  --anim-ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --anim-ease-emphasized: cubic-bezier(0.05, 0.7, 0.1, 1);
  --anim-ease-exit: cubic-bezier(0.4, 0, 1, 1);
  --anim-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --anim-ease-snappy: cubic-bezier(0.34, 1.1, 0.64, 1);
  --anim-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --anim-ease-ios: cubic-bezier(0.23, 1, 0.32, 1);
  --anim-ease-hover: ease;

  /* ── Movement distances (enter-from offsets) ── */
  --anim-move-sm: 4px;
  --anim-move-md: 8px;
  --anim-move-lg: 14px;

  /* ── Scale start points for entering surfaces ── */
  --anim-scale-popover: 0.96;
  --anim-scale-tooltip: 0.93;
  --anim-scale-modal: 0.95;
  /* Modal LEAVE only: a smaller shrink than --anim-scale-modal's entrance --
     the panel is still fully visible when the exit starts, so it settles
     rather than retreating as far as it arrived from. */
  --anim-scale-modal-exit: 0.98;

  /* Phone collapsing header: how far the large title shrinks into the
     compact bar title as the list scrolls (ListMobileHead + AppNav mobile
     top bar). Not a movement/scale-entrance token — kept separate so
     reduced motion doesn't zero it (the collapse stays under reduced
     motion: it tracks scroll position, it does not autoplay). */
  --anim-scale-title-collapse: 0.78;

  /* ── Press feedback ── */
  --anim-press-scale: 0.97;
  --anim-press-scale-sm: 0.94;
  /* Barely-there press for large, full-width surfaces (a whole list card, a
     KPI tile) -- a visible 3-6% squish on something that wide reads as the
     layout glitching, not a button. Used by EntityListCard and
     MobileKpiTile. */
  --anim-press-scale-lg: 0.99;
  --anim-press-duration: 80ms;

  /* ── Hover lift for cards/rows ── */
  --anim-hover-lift: -1px;

  /* ── Stagger ── */
  --anim-stagger-step: 30ms;

  /* ── Legacy aliases (do not use in new code) ── */
  --anim-duration-instant: var(--anim-duration-micro);
  --anim-duration-base: var(--anim-duration-fast);
  --anim-duration-content: var(--anim-duration-standard);
  --anim-duration-emphasis: var(--anim-duration-expressive);
  --anim-ease-decelerate: var(--anim-ease-emphasized);
  --anim-ease-accelerate: var(--anim-ease-exit);
  --transition-fast: var(--anim-duration-micro) ease-out;
  --transition-base: var(--anim-duration-fast) ease-out;
  --transition-slow: var(--anim-duration-standard) ease-out;
  --motion-instant: var(--anim-duration-micro);
  --motion-fast: var(--anim-duration-fast);
  --motion-base: var(--anim-duration-standard);
  --motion-slow: var(--anim-duration-expressive);
  --ease-emphasized: var(--anim-ease-drawer);
  --ease-accel: var(--anim-ease-exit);
  --ease-standard: var(--anim-ease-standard);
}

/* ============================================================
   PHONE OVERRIDES (layout-bound: the phone chrome lives ≤ 640px)
   Longer travel and the iOS deceleration curve so surfaces feel
   native rather than web. Page pushes and sheets use --anim-ease-drawer
   at the expressive tier.
   ============================================================ */
@media (max-width: 640px) {
  :root {
    --anim-duration-fast: 0.22s;
    --anim-duration-standard: 0.32s;
    --anim-duration-expressive: 0.45s;
    --anim-duration-dramatic: 0.7s;

    --anim-ease-standard: cubic-bezier(0.23, 1, 0.32, 1);
    --anim-ease-emphasized: cubic-bezier(0.23, 1, 0.32, 1);

    --anim-move-sm: 10px;
    --anim-move-md: 14px;
    --anim-move-lg: 20px;

    --anim-stagger-step: 40ms;
  }
}

/* ============================================================
   TOUCH OVERRIDES (input-bound: any coarse pointer, whatever the width)
   Press feedback is the only affordance a finger gets, so it is a touch
   larger than the mouse version. Hover lift is meaningless on touch.
   ============================================================ */
@media (hover: none) and (pointer: coarse) {
  :root {
    --anim-press-scale: 0.96;
    --anim-hover-lift: 0px;
  }
}

/* ============================================================
   REDUCED MOTION — collapse MOVEMENT, keep the state change.
   Durations are zeroed app-wide in apps/web/assets/css/animations.css;
   this block makes sure the enter-from/leave-to OFFSETS collapse too, so a
   reduced-motion user sees an in-place appearance, not an instant jump
   from 14px away.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --anim-move-sm: 0px;
    --anim-move-md: 0px;
    --anim-move-lg: 0px;
    --anim-scale-popover: 1;
    --anim-scale-tooltip: 1;
    --anim-scale-modal: 1;
    --anim-scale-modal-exit: 1;
    --anim-duration-tooltip: 0ms;
    --anim-press-scale: 1;
    --anim-press-scale-sm: 1;
    --anim-press-scale-lg: 1;
    --anim-hover-lift: 0px;
    --anim-stagger-step: 0ms;
    --motion-instant: 0ms;
    --motion-fast: 0ms;
    --motion-base: 0ms;
    --motion-slow: 0ms;
  }
}
