/* Earlyman motion pass (2026-10-24). Motion that explains the product, on top of finish.css.
   Ideas: M1 the receipt prints, M2 the limit runway, M3 rules switch on, M4 facts arrive, M5 hover lines redraw,
   M6 the privacy lock clicks shut. Plus: loops pause off screen and when the tab is hidden.
   Rules: only transform, opacity, clip-path and stroke-dashoffset move. Every hidden start state hangs off a class that
   motion.js adds (.mx-pend, .mx-play), so without JS the page is the finished frame. Reduced motion (OS or html.rm)
   shows the final state at once. Colours come only from the lantern.css tokens. */
:root { --mx-ease: cubic-bezier(.22, 1, .36, 1); --mx-snap: cubic-bezier(.23, 1, .32, 1); }

/* ---------- M1 receipt print: rows wipe in top to bottom under a moving print line, costs count up ---------- */
.seeit .frame-body { position: relative; overflow: hidden; }
.seeit .frame-body::after {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 100%; pointer-events: none;
  border-bottom: 1px solid var(--fg-1); opacity: 0; transform: translate3d(0, -100%, 0);
}
.seeit.mx-play .frame-body::after { animation: mx-head 1100ms var(--mx-ease) 160ms both; }
@keyframes mx-head { 0% { opacity: 1; transform: translate3d(0, -100%, 0); } 80% { opacity: 1; transform: none; } 100% { opacity: 0; transform: none; } }
.seeit.mx-play .rows .r { animation: mx-print 760ms var(--mx-ease) both; animation-delay: calc(var(--i, 0) * 180ms + 220ms); }
@keyframes mx-print { from { clip-path: inset(0 0 100% 0); opacity: .2; } to { clip-path: inset(0 0 0 0); opacity: 1; } }
.seeit .rows .v { display: inline-block; min-width: 6ch; }
.seeit .rows .r.sel .nm { transition: box-shadow 0s; }

/* ---------- M2 limit runway: after the gauge fills, the pace line runs on to the wall; the heads-up mark pulses ---------- */
.mx-run.rows .bar::after, .mx-run .rows .bar::after {
  content: ""; position: absolute; top: 1px; bottom: 1px; left: var(--mx-at); right: 0; pointer-events: none;
  background: repeating-linear-gradient(90deg, var(--fg-3) 0 4px, transparent 4px 8px);
}
.mx-pend.mx-run .rows .bar::after { clip-path: inset(0 100% 0 0); }
.mx-play.mx-run .rows .bar::after { animation: mx-wipe 1400ms var(--mx-ease) 1300ms both; }
@keyframes mx-wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
.rows .bar s::after {
  content: ""; position: absolute; left: -3px; top: 50%; width: 7px; height: 7px; margin-top: -4px;
  border: 1px solid var(--fg-1); opacity: 0; pointer-events: none;
}
.mx-live .rows .bar s::after { animation: mx-ping 2000ms ease-out 2400ms infinite; }
@keyframes mx-ping { 0% { opacity: .8; transform: scale(1); } 70%, 100% { opacity: 0; transform: scale(3.2); } }

/* ---------- M3 rules switch on, one after another ---------- */
.rules-list .sw.on::after { left: 2px; transform: translate3d(12px, 0, 0); }
.rules-list.mx-pend .sw.on::after { transform: none; opacity: .35; }
.rules-list.mx-play .sw.on::after { animation: mx-flip 420ms var(--mx-snap) both; }
.rules-list li:nth-child(1) .sw::after { animation-delay: 500ms; }
.rules-list li:nth-child(2) .sw::after { animation-delay: 760ms; }
.rules-list li:nth-child(3) .sw::after { animation-delay: 1020ms; }
@keyframes mx-flip { from { transform: none; opacity: .35; } to { transform: translate3d(12px, 0, 0); opacity: 1; } }
.rules-list.mx-play .rl li { animation: mx-up 320ms var(--mx-snap) both; }
.rules-list.mx-play .rl li:nth-child(2) { animation-delay: 60ms; } .rules-list.mx-play .rl li:nth-child(3) { animation-delay: 120ms; }

/* ---------- M4 facts arrive: the hairline draws, then the four facts rise, stagger capped ---------- */
.facts { position: relative; }
.facts.mx-pend, .facts.mx-play { border-top-color: transparent; }
.facts.mx-pend::before, .facts.mx-play::before {
  content: ""; position: absolute; left: 0; right: 0; top: -1px; height: 1px; background: var(--line-1);
  transform: scaleX(0); transform-origin: left;
}
.facts.mx-play::before { animation: mx-line 900ms var(--mx-ease) both; }
@keyframes mx-line { to { transform: scaleX(1); } }
.facts.mx-pend li { opacity: 0; }
.facts.mx-play li { animation: mx-up 420ms var(--mx-snap) both; animation-delay: calc(var(--mx-k, 0) * 70ms + 180ms); }
@keyframes mx-up { from { opacity: 0; transform: translate3d(0, 12px, 0); } to { opacity: 1; transform: none; } }

/* ---------- M5 hover: link icons redraw their line, button arrows nudge ---------- */
.morerow a svg [pathLength] { stroke-dasharray: 1; stroke-dashoffset: 0; }
.morerow a:hover svg [pathLength], .morerow a:focus-visible svg [pathLength] { animation: mx-redraw 640ms var(--mx-ease) both; }
@keyframes mx-redraw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.btn:hover .arr { transform: translate3d(3px, 0, 0); }

/* ---------- M6 privacy lock: drawn, then the shackle drops shut ---------- */
.final .lock path { transform-box: fill-box; transform-origin: 50% 100%; }
.final .lock.in path { animation: lock-draw 1.2s var(--ease) both, mx-shut 360ms var(--mx-snap) 1200ms both; }
@keyframes mx-shut { 0% { transform: translate3d(0, -4px, 0); } 70% { transform: translate3d(0, .6px, 0); } 100% { transform: none; } }

/* ---------- other pages (10-25): the landing's motion carried to the inner pages ----------
   M9  the "three things" bands (feature pages, agent infrastructure): each item's top hairline draws a short mark as it
       reveals, the same mark the landing's steps use; the four-part loop draws one mark after another.
   M10 card icons (privacy promises) draw their line as the card arrives, and redraw on hover.
   All 150-400 ms ease-out. Start states hang off .js + a class the scripts add (.reveal without .in, .mx-pend). */
.fp-three li { position: relative; }
.fp-three li::before {
  content: ""; position: absolute; top: -1px; left: 0; width: 100%; height: 1px; background: var(--fg-0); pointer-events: none;
  transform: scaleX(.18); transform-origin: left; transition: transform 400ms var(--mx-ease); transition-delay: calc(var(--i, 0) * 80ms + 240ms);
}
.js .fp-three li.reveal:not(.in)::before { transform: scaleX(0); }
.ai-parts li::before { transition-delay: calc(var(--i, 0) * 160ms + 240ms); }
.mx-ic [pathLength] { stroke-dasharray: 1; }
.mx-ic.mx-pend [pathLength] { stroke-dashoffset: 1; }
.mx-ic.mx-play [pathLength] { animation: mx-redraw 400ms var(--mx-ease) 160ms both; }
.promises li:hover .mx-ic [pathLength] { animation: mx-redraw 400ms var(--mx-ease) both; }

/* ---------- no JS: product rows and gauges were hidden until showcase.js marked the frame (.in); show them ---------- */
html:not(.js) .rows .r { opacity: 1; transform: none; }
html:not(.js) .rows .bar i, html:not(.js) .ftr-r .bar i { transform: none; }

/* ---------- pause: off screen (.mx-live missing) and when the tab is hidden ---------- */
html.mx-hidden *, html.mx-hidden *::before, html.mx-hidden *::after { animation-play-state: paused !important; }
/* while the demo video plays, the ambient loops hold still; the video element itself is never transformed */
html.mx-quiet .rows .bar s::after, html.mx-quiet .flow { animation-play-state: paused; }

/* ---------- reduced motion (OS or html.rm): the finished frame, nothing moves ---------- */
@media (prefers-reduced-motion: reduce) {
  .seeit .frame-body::after, .rows .bar s::after { animation: none !important; opacity: 0; }
  .seeit .rows .r, .rules-list .sw.on::after, .rules-list .rl li, .facts li, .facts::before, .rows .bar::after,
  .morerow a svg [pathLength], .final .lock path { animation: none !important; opacity: 1; clip-path: none; }
  .rules-list .sw.on::after { transform: translate3d(12px, 0, 0) !important; }
  .facts::before { transform: scaleX(1) !important; }
  .facts li, .final .lock path { transform: none !important; }
  .btn:hover .arr { transform: none; }
  .fp-three li::before, .js .fp-three li.reveal:not(.in)::before { transition: none; transform: scaleX(.18); }
  .mx-ic [pathLength], .mx-ic.mx-pend [pathLength], .promises li:hover .mx-ic [pathLength] { animation: none !important; stroke-dashoffset: 0; }
}
html.rm .seeit .frame-body::after, html.rm .rows .bar s::after { animation: none !important; opacity: 0; }
html.rm .seeit .rows .r, html.rm .rules-list .sw.on::after, html.rm .rules-list .rl li, html.rm .facts li, html.rm .facts::before,
html.rm .rows .bar::after, html.rm .morerow a svg [pathLength], html.rm .final .lock path { animation: none !important; opacity: 1; clip-path: none; }
html.rm .rules-list .sw.on::after { transform: translate3d(12px, 0, 0) !important; }
html.rm .facts::before { transform: scaleX(1) !important; }
html.rm .facts li, html.rm .final .lock path { transform: none !important; }
html.rm .btn:hover .arr { transform: none; }
html.rm .fp-three li::before, html.rm .fp-three li.reveal:not(.in)::before { transition: none; transform: scaleX(.18); }
html.rm .mx-ic [pathLength], html.rm .mx-ic.mx-pend [pathLength], html.rm .promises li:hover .mx-ic [pathLength] { animation: none !important; stroke-dashoffset: 0; }
