/* ============================================================
   Throughline — Motion System
   Token-driven. Loaded after app.css / styles.css so it wins.
   Every animation here is transform/opacity only (GPU-safe).
   ============================================================ */

:root{
  /* Duration scale — 5 values, one per distinct use case */
  --dur-instant: 60ms;   /* toggles, checks */
  --dur-fast:    120ms;  /* chips, pills, small hovers */
  --dur-normal:  200ms;  /* default: buttons, cards, focus */
  --dur-moderate:300ms;  /* drawer, modal, panels */
  --dur-slow:    460ms;  /* entrances, reveals */

  /* Easing vocabulary — semantic, not decorative */
  --ease-standard:   cubic-bezier(.2,0,0,1);        /* on-screen movement */
  --ease-decelerate: cubic-bezier(.15,.85,.25,1);   /* entering  (ease-out) */
  --ease-accelerate: cubic-bezier(.3,0,1,.3);       /* exiting   (ease-in)  */
  --ease-spring:     cubic-bezier(.34,1.4,.64,1);   /* tactile, playful     */
  --ease-out-quint:  cubic-bezier(.23,1,.32,1);     /* long, luxurious      */

  --lift-1: 0 2px 6px rgba(11,31,22,.06), 0 8px 24px rgba(11,31,22,.07);
  --lift-2: 0 6px 14px rgba(11,31,22,.09), 0 18px 44px rgba(11,31,22,.11);
  --ring: 0 0 0 3px var(--accent-soft, #E8F5EE), 0 0 0 4px var(--accent, #1A9457);
}

/* ---------- Global: reduced motion handled at the system level ---------- */
@media (prefers-reduced-motion: reduce){
  :root{
    --dur-instant:1ms; --dur-fast:1ms; --dur-normal:1ms;
    --dur-moderate:1ms; --dur-slow:1ms;
  }
  *, *::before, *::after{
    animation-duration:1ms !important;
    animation-iteration-count:1 !important;
    transition-duration:1ms !important;
    scroll-behavior:auto !important;
  }
  /* Preserve opacity fades; kill movement. */
  .m-rise, .m-reveal, .tl-item, .kcard, .stat, .scorepill{ transform:none !important; }
}

html{ scroll-behavior:smooth; }

/* ---------- Focus: visible, on-brand, keyboard-only ---------- */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:none;
  box-shadow:var(--ring);
  border-radius:6px;
  transition:box-shadow var(--dur-fast) var(--ease-decelerate);
}

/* ---------- Buttons: responsive press, subtle sheen on primary ---------- */
.btn{
  transition:
    transform var(--dur-fast) var(--ease-spring),
    box-shadow var(--dur-normal) var(--ease-standard),
    background-color var(--dur-normal) ease,
    border-color var(--dur-normal) ease;
  will-change:transform;
}
.btn:hover{ transform:translateY(-1px); box-shadow:var(--lift-1); }
.btn:active{ transform:translateY(0) scale(.975); transition-duration:var(--dur-instant); }

.btn.primary{ position:relative; overflow:hidden; }
.btn.primary::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(115deg,transparent 20%,rgba(255,255,255,.28) 48%,transparent 72%);
  transform:translateX(-140%);
  transition:transform var(--dur-slow) var(--ease-out-quint);
  pointer-events:none;
}
.btn.primary:hover::after{ transform:translateX(140%); }

/* ---------- Cards: quiet lift, never bouncy ---------- */
.card{
  transition:
    transform var(--dur-normal) var(--ease-standard),
    box-shadow var(--dur-normal) var(--ease-standard),
    border-color var(--dur-normal) ease;
}
.card:hover{ transform:translateY(-2px); box-shadow:var(--lift-2); }
/* Stat cards read as data, not buttons — lift less. */
.card.stat:hover{ transform:translateY(-1px); }

/* ---------- Kanban: pick-up / drop physics ---------- */
.kcard{
  transition:
    transform var(--dur-normal) var(--ease-spring),
    box-shadow var(--dur-normal) var(--ease-standard);
  will-change:transform;
}
.kcard:hover{ transform:translateY(-2px) scale(1.008); box-shadow:var(--lift-2); }
.kcard:active{ transform:scale(.99); transition-duration:var(--dur-instant); cursor:grabbing; }
.kcard.dragging{ transform:rotate(1.4deg) scale(1.03); box-shadow:var(--lift-2); opacity:.92; }
.kcol.dragover{
  background:var(--accent-soft,#E8F5EE);
  transition:background var(--dur-fast) var(--ease-decelerate);
}

/* ---------- Table rows: hairline sweep on hover ---------- */
tbody tr{ transition:background-color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-standard); }
tbody tr:hover{ background:var(--accent-soft,#E8F5EE); }

/* ---------- Chips, pills, tags ---------- */
.chip,.tlchip,.scorepill,.emeng{
  transition:transform var(--dur-fast) var(--ease-spring), background-color var(--dur-fast) ease, color var(--dur-fast) ease;
}
.chip:hover,.tlchip:hover{ transform:translateY(-1px); }
.scorepill:hover{ transform:scale(1.08); }
.scorepill:active{ transform:scale(.94); transition-duration:var(--dur-instant); }

/* ---------- Drawer: slide + backdrop, exit faster than entry ---------- */
#drawer{
  transition:transform var(--dur-moderate) var(--ease-accelerate),
             opacity var(--dur-fast) ease;
  will-change:transform;
}
#drawer.on{
  transition:transform var(--dur-moderate) var(--ease-decelerate),
             opacity var(--dur-fast) ease;
}

/* ---------- Toast: springs up, settles ---------- */
#toast{ transition:transform var(--dur-moderate) var(--ease-spring), opacity var(--dur-fast) ease !important; }

/* ---------- Entrances ---------- */
@keyframes m-rise{
  from{ opacity:0; transform:translateY(10px); }
  to  { opacity:1; transform:none; }
}
@keyframes m-fade{ from{opacity:0} to{opacity:1} }
@keyframes m-scale-in{
  from{ opacity:0; transform:scale(.97); }
  to  { opacity:1; transform:none; }
}

/* View content animates on every render (innerHTML swap replays it). */
#main > *{ animation:m-rise var(--dur-slow) var(--ease-decelerate) both; }

/* Staggered children — lead with the most important, cap the sequence.
   Delays stop at 6 so a long list never feels sluggish. */
.kpis .stat{
  animation:m-rise var(--dur-slow) var(--ease-decelerate) both;
}
.kpis .stat:nth-child(1){ animation-delay:0ms }
.kpis .stat:nth-child(2){ animation-delay:40ms }
.kpis .stat:nth-child(3){ animation-delay:80ms }
.kpis .stat:nth-child(4){ animation-delay:120ms }
.kpis .stat:nth-child(n+5){ animation-delay:160ms }

.tl-item{ animation:m-rise var(--dur-moderate) var(--ease-decelerate) both; }
.tl-item:nth-child(1){animation-delay:0ms}
.tl-item:nth-child(2){animation-delay:30ms}
.tl-item:nth-child(3){animation-delay:60ms}
.tl-item:nth-child(4){animation-delay:90ms}
.tl-item:nth-child(5){animation-delay:120ms}
.tl-item:nth-child(n+6){animation-delay:150ms}

/* Modals / sheets */
.modal, .dupwrap, #dup-root > *{ animation:m-scale-in var(--dur-moderate) var(--ease-decelerate) both; }

/* ---------- Scroll reveal (marketing) ---------- */
.m-reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity var(--dur-slow) var(--ease-decelerate),
             transform var(--dur-slow) var(--ease-out-quint);
  will-change:transform,opacity;
}
.m-reveal.in{ opacity:1; transform:none; }
.m-reveal.in{ transition-delay:var(--m-delay,0ms); }

/* ---------- Skeleton shimmer (loading) ---------- */
@keyframes m-shimmer{ from{background-position:-200% 0} to{background-position:200% 0} }
.m-skel{
  background:linear-gradient(90deg,#eef1f4 25%,#f7f9fa 50%,#eef1f4 75%);
  background-size:200% 100%;
  animation:m-shimmer 1.4s linear infinite;
  border-radius:8px; color:transparent !important;
}

/* ---------- Nav / sidebar affordance ---------- */
.side a, .side .navitem, .nav a{
  transition:color var(--dur-fast) ease, background-color var(--dur-fast) ease, transform var(--dur-fast) var(--ease-standard);
}
.side a:hover, .nav a:hover{ transform:translateX(2px); }

/* ---------- Links: underline grows from the left ---------- */
.m-link{ position:relative; text-decoration:none; }
.m-link::after{
  content:""; position:absolute; left:0; bottom:-2px; height:1.5px; width:100%;
  background:currentColor; transform:scaleX(0); transform-origin:left;
  transition:transform var(--dur-normal) var(--ease-out-quint);
}
.m-link:hover::after{ transform:scaleX(1); }

/* ============================================================
   Extensions: view crossfade · hero parallax · KPI count-up
   ============================================================ */

/* ---------- View crossfade (app) ----------
   #main children already rise on render; this crossfades the whole
   pane so switching views reads as one motion, not N staggered ones. */
@keyframes m-viewin{
  from{ opacity:0; transform:translateY(6px) scale(.996); }
  to  { opacity:1; transform:none; }
}
#main.m-viewin{
  animation:m-viewin var(--dur-moderate) var(--ease-decelerate) both;
}
/* When the pane itself crossfades, children shouldn't also stagger in —
   that double-animates. Children fade only. */
#main.m-viewin > *{ animation:m-fade var(--dur-normal) var(--ease-decelerate) both; }

/* ---------- Hero parallax (marketing) ---------- */
.hero{ position:relative; }
.m-par{
  will-change:transform;
  transform:translate3d(0, var(--m-par-y, 0px), 0);
}
/* Depth cue: the hero's own copy drifts slower than the decoration. */
@media (prefers-reduced-motion: reduce){
  .m-par{ transform:none !important; }
}

/* ---------- Count-up (app KPIs) ----------
   Numerals shouldn't reflow while ticking. */
.stat .v{ font-variant-numeric:tabular-nums; }
.m-count{ transition:none; }
