/* motion.css — the shared motion of plan §2.2.7 (R9 G1.D · D5).
 *
 * Opt-in classes and keyframes; nothing here selects an existing component, so loading it changes no screen by itself.
 * RULES THIS FILE KEEPS (and test/tools/designlint.mjs enforces over public/):
 *   - transform and opacity only: no transition or keyframe touches left/top/width/height or any other layout property
 *     (the window manager's own .w2-window.is-animating in shell.css is the one exception, and it lives there);
 *   - --ease-spring is never used (the token stays defined in tokens.css);
 *   - no side stripes, no glass over text.
 *
 * LOAD ORDER. Link it after shell.css (a core request to public/index.html, owned by G1.S/S2):
 *   <link rel="stylesheet" href="/css/motion.css">
 * Durations are local --mo-* knobs (the frozen token names are untouched); every easing is an existing token.
 *
 * REDUCED MOTION (plan §2.2.7): `:root[data-motion="reduced"]` (the shell's own switch, base.css) and, before the shell has set
 * data-motion, `prefers-reduced-motion: reduce` unless data-motion="full" — every duration becomes 1 ms, every delay 0, every
 * slide offset 0 and the seal's peak 1: crossfades only, and the seal appears without scaling. The keyframes read these knobs,
 * so no animation-name override is needed.
 *
 * CLASS INDEX
 *   Place switch      .w2-mo-place-in  .w2-mo-place-out         on the place window (other places' windows never move)
 *   Rail pill         .w2-mo-pill                               --mo-pill-y: <length> moves it; transform transition only
 *   Window open/close .w2-mo-open  .w2-mo-close                 as shell.css's w2-win-open / w2-win-close
 *   Inspector         .w2-mo-inspector-in / -out  + .w2-mo-inspector-body (its content, fading in 60 ms later)
 *   Filing tray       .w2-mo-tray-in  .w2-mo-tray-out          --mo-tray-dx / --mo-tray-dy: the offset of the taskbar badge
 *   The Seal          .w2-mo-seal-row  + .is-unfiled | .is-filing | .is-filed   (the outline)
 *                     .w2-mo-seal      + .is-stamping                           (the 16 px glyph, stamped once)
 *   Tool-call pulse   .w2-mo-pulse                              a 1 px pulse on a run row, once per class add
 *   Crossfade         .w2-mo-fade-in  .w2-mo-fade-out          the reduced-motion form of every slide, usable alone
 */

:root {
  --mo-place-fade: 120ms;        /* place switch: opacity */
  --mo-place-rise: 160ms;        /* place switch: the rise */
  --mo-rise-y: 4px;              /* place switch: how far it rises */
  --mo-pill: 200ms;              /* rail pill slide */
  --mo-open-scale: .96;          /* window open / close */
  --mo-open-y: 6px;
  --mo-inspector: 200ms;         /* Inspector slide */
  --mo-inspector-x: 16px;
  --mo-inspector-content-delay: 60ms;
  --mo-tray: 200ms;              /* Filing tray rise */
  --mo-tray-dx: 0px;
  --mo-tray-dy: 12px;
  --mo-seal-draw: 300ms;         /* the dashed outline draws solid */
  --mo-seal-stamp: 180ms;        /* the 16 px seal stamps once */
  --mo-seal-peak: 1.08;
  --mo-pulse: 900ms;
}

/* ── place switch: the incoming place crossfades 120 ms and rises 4 px over 160 ms ──────────────────────────────── */
@keyframes w2-mo-place-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes w2-mo-place-rise { from { transform: translateY(var(--mo-rise-y)); } to { transform: none; } }
@keyframes w2-mo-place-gone { from { opacity: 1; } to { opacity: 0; } }

.w2-mo-place-in {
  animation: w2-mo-place-fade var(--mo-place-fade) var(--ease-out) both, w2-mo-place-rise var(--mo-place-rise) var(--ease-out) both;
}
/* the outgoing place only fades, in place: it does not move */
.w2-mo-place-out { animation: w2-mo-place-gone var(--mo-place-fade) var(--ease-out) both; pointer-events: none; }

/* ── the rail pill slides 200 ms on --ease-out (the host sets --mo-pill-y to the active item's offset) ────────────── */
.w2-mo-pill {
  transform: translateY(var(--mo-pill-y, 0px));
  transition: transform var(--mo-pill) var(--ease-out);
}

/* ── window open / close: as today (scale(.96) translateY(6px) → none, --dur-base, --ease-out) ───────────────────── */
@keyframes w2-mo-open { from { opacity: 0; transform: scale(var(--mo-open-scale)) translateY(var(--mo-open-y)); } to { opacity: 1; transform: none; } }
@keyframes w2-mo-close { to { opacity: 0; transform: scale(var(--mo-open-scale)); } }
.w2-mo-open { animation: w2-mo-open var(--dur-base) var(--ease-out) both; }
.w2-mo-close { animation: w2-mo-close var(--dur-fast) var(--ease-in) both; pointer-events: none; }

/* ── Inspector: translateX(16px) + opacity over 200 ms; its content fades in after 60 ms ───────────────────────── */
@keyframes w2-mo-inspector-in { from { opacity: 0; transform: translateX(var(--mo-inspector-x)); } to { opacity: 1; transform: none; } }
@keyframes w2-mo-inspector-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(var(--mo-inspector-x)); } }
@keyframes w2-mo-content-fade { from { opacity: 0; } to { opacity: 1; } }
.w2-mo-inspector-in { animation: w2-mo-inspector-in var(--mo-inspector) var(--ease-out) both; }
.w2-mo-inspector-out { animation: w2-mo-inspector-out var(--mo-inspector) var(--ease-in) both; pointer-events: none; }
.w2-mo-inspector-in .w2-mo-inspector-body {
  animation: w2-mo-content-fade var(--mo-inspector) var(--ease-out) var(--mo-inspector-content-delay) both;
}

/* ── Filing tray: rises 200 ms from the taskbar badge (--mo-tray-dx / --mo-tray-dy place the starting point) ───────── */
@keyframes w2-mo-tray-in { from { opacity: 0; transform: translate(var(--mo-tray-dx), var(--mo-tray-dy)); } to { opacity: 1; transform: none; } }
@keyframes w2-mo-tray-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translate(var(--mo-tray-dx), var(--mo-tray-dy)); } }
.w2-mo-tray-in { animation: w2-mo-tray-in var(--mo-tray) var(--ease-out) both; }
.w2-mo-tray-out { animation: w2-mo-tray-out var(--mo-tray) var(--ease-in) both; pointer-events: none; }

/* ── the Seal: a filing files ──────────────────────────────────────────────────────────────────────────────────────
 * Row outline: two overlay layers (the dashed "Not filed yet" outline and the solid one) cross over 300 ms by opacity — the
 * outline "draws solid" without a border-style transition. The 16 px seal stamps once after that: scale 1 → peak → 1 in
 * 180 ms with an ink spread (a ring that scales out and fades). No toast: the live region speaks "Filed 14:02".
 *   <div class="w2-mo-seal-row is-unfiled"> … <span class="w2-mo-seal" role="img" aria-label="Filed seal">…svg…</span></div>
 * Add .is-filing to start; add .is-filed (and .is-stamping on the seal) when the commit lands. */
.w2-mo-seal-row { position: relative; }
.w2-mo-seal-row::before,
.w2-mo-seal-row::after {
  content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
}
.w2-mo-seal-row::before { border: 1px dashed var(--accent); opacity: 1; }
.w2-mo-seal-row::after { border: 1px solid var(--accent); opacity: 0; }

@keyframes w2-mo-seal-dash-out { from { opacity: 1; } to { opacity: 0; } }
@keyframes w2-mo-seal-solid-in { from { opacity: 0; } to { opacity: 1; } }
.w2-mo-seal-row.is-filing::before { animation: w2-mo-seal-dash-out var(--mo-seal-draw) var(--ease-out) both; }
.w2-mo-seal-row.is-filing::after { animation: w2-mo-seal-solid-in var(--mo-seal-draw) var(--ease-out) both; }
/* filed: the outline rests solid, in the quiet line colour */
.w2-mo-seal-row.is-filed::before { opacity: 0; }
.w2-mo-seal-row.is-filed::after { opacity: 1; border-color: var(--line-2); }

/* the glyph: hidden until the outline has drawn, then stamped once */
.w2-mo-seal { position: relative; display: block; width: 16px; height: 16px; flex: none; }
@keyframes w2-mo-seal-stamp {
  0% { opacity: 0; transform: scale(1); }
  1% { opacity: 1; transform: scale(1); }
  50% { opacity: 1; transform: scale(var(--mo-seal-peak)); }
  100% { opacity: 1; transform: scale(1); }
}
@keyframes w2-mo-seal-ink {
  0% { opacity: 0; transform: scale(.6); }
  1% { opacity: .9; transform: scale(.6); }
  100% { opacity: 0; transform: scale(1.5); }
}
.w2-mo-seal.is-stamping { animation: w2-mo-seal-stamp var(--mo-seal-stamp) var(--ease-out) var(--mo-seal-draw) both; }
.w2-mo-seal.is-stamping::before {
  content: ""; position: absolute; inset: -9px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, var(--accent-weak) 0 50%, transparent 72%);
  animation: w2-mo-seal-ink var(--mo-seal-stamp) var(--ease-out) var(--mo-seal-draw) both;
}

/* ── a run's tool call: a 1 px pulse on the run row, once; never a spinner over content ───────────────────────────── */
@keyframes w2-mo-pulse { 0%, 100% { opacity: 0; } 35% { opacity: .85; } }
.w2-mo-pulse { position: relative; }
.w2-mo-pulse::after {
  content: ""; position: absolute; inset: 0; border: 1px solid var(--accent); border-radius: inherit; pointer-events: none;
  opacity: 0; animation: w2-mo-pulse var(--mo-pulse) var(--ease-inout) 1 both;
}

/* ── crossfade only: what a slide becomes under reduced motion, and usable on its own ─────────────────────────────── */
@keyframes w2-mo-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes w2-mo-fade-out { from { opacity: 1; } to { opacity: 0; } }
.w2-mo-fade-in { animation: w2-mo-fade-in var(--dur-base) var(--ease-out) both; }
.w2-mo-fade-out { animation: w2-mo-fade-out var(--dur-base) var(--ease-out) both; pointer-events: none; }

/* ── reduced motion: every duration 1 ms, no slides, the seal appears without scaling ─────────────────────────────── */
:root[data-motion="reduced"] {
  --mo-place-fade: 1ms; --mo-place-rise: 1ms; --mo-rise-y: 0px; --mo-pill: 1ms;
  --mo-open-scale: 1; --mo-open-y: 0px;
  --mo-inspector: 1ms; --mo-inspector-x: 0px; --mo-inspector-content-delay: 0ms;
  --mo-tray: 1ms; --mo-tray-dx: 0px; --mo-tray-dy: 0px;
  --mo-seal-draw: 1ms; --mo-seal-stamp: 1ms; --mo-seal-peak: 1; --mo-pulse: 1ms;
}
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]):not([data-motion="reduced"]) {
    --mo-place-fade: 1ms; --mo-place-rise: 1ms; --mo-rise-y: 0px; --mo-pill: 1ms;
    --mo-open-scale: 1; --mo-open-y: 0px;
    --mo-inspector: 1ms; --mo-inspector-x: 0px; --mo-inspector-content-delay: 0ms;
    --mo-tray: 1ms; --mo-tray-dx: 0px; --mo-tray-dy: 0px;
    --mo-seal-draw: 1ms; --mo-seal-stamp: 1ms; --mo-seal-peak: 1; --mo-pulse: 1ms;
  }
}
