.motion-scene {
  --cycle: 10s;
  --m-io: cubic-bezier(.45, 0, .25, 1);
}
/* --- scroll reveal: sections rise between cases, one-shot, staggered --- */
@media (prefers-reduced-motion: no-preference) {
  html.js [data-reveal-item] {
    opacity: 0;
    transform: translateY(18px);
    transition:
      opacity .65s var(--ease-out),
      transform .65s var(--ease-out);
    transition-delay: calc(min(var(--reveal-i, 0), 9) * 60ms);
  }
  html.js [data-reveal].is-inview [data-reveal-item] {
    opacity: 1;
    transform: none;
  }
  /* The section's top rule draws itself as the section arrives. */
  html.js [data-rule] { position: relative; }
  html.js [data-rule]::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 1px;
    background: var(--line);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 1.1s var(--ease-out) .05s;
  }
  html.js [data-rule].is-inview::before { transform: scaleX(1); }
}
/* --- plan figure: document -> bus -> claim nodes --- */
html.js .plan-document { animation: doc-in var(--cycle) var(--m-io) infinite; }
html.js .doc-highlight { transform-box: fill-box; transform-origin: left center; animation: doc-sweep var(--cycle) var(--m-io) infinite; }
html.js .bus-tap { stroke-dasharray: 30; animation: bus-tap-draw var(--cycle) linear infinite; }
html.js .bus-rail { stroke-dasharray: 240; animation: rail-draw var(--cycle) linear infinite; }
html.js .bus-dot { transform-box: fill-box; transform-origin: center; animation: bus-pop var(--cycle) var(--m-io) infinite; }
html.js .bus-dot.d1 { animation-delay: -.4s; }
html.js .bus-dot.d3 { animation-delay: .5s; }
html.js .bus-dot.d4 { animation-delay: 1s; }
html.js .stub { stroke-dasharray: 36; animation: stub-draw var(--cycle) linear infinite; }
html.js .stub.st2 { animation-delay: .6s; }
html.js .stub.st3 { animation-delay: 1.2s; }
html.js .claim { animation: claim-in var(--cycle) var(--m-io) infinite; }
html.js .claim-question { animation-delay: .8s; }
html.js .claim-settled { animation-delay: 1.6s; }
html.js .claim-risk .claim-dot { transform-box: fill-box; transform-origin: center; animation: risk-pulse var(--cycle) var(--m-io) 1s infinite; }
/* --- review figure: gutter rail -> changed line -> anchored answer --- */
html.js .review-wire { stroke-dasharray: 455; animation: wire-draw var(--cycle) linear infinite; }
html.js .station { transform-box: fill-box; transform-origin: center; animation: station-pop var(--cycle) var(--m-io) infinite; }
html.js .station-1 { animation-delay: -5.8s; }
html.js .station-2 { animation-delay: -3.6s; }
html.js .station-3 { animation-delay: -.4s; }
html.js .review-file { animation: focus-in var(--cycle) var(--m-io) infinite; }
html.js .first-file { animation-delay: -6s; }
html.js .second-file { animation-delay: -4.5s; }
html.js .third-file { animation-delay: -1s; }
html.js .change-band { transform-box: fill-box; transform-origin: left center; animation: band-sweep var(--cycle) var(--m-io) infinite; }
html.js .q-chip { transform-box: fill-box; transform-origin: center; animation: chip-pop var(--cycle) var(--m-io) infinite; }
html.js .agent-answer { animation: answer-in var(--cycle) var(--m-io) infinite; }
html.js .answer-leader { stroke-dasharray: 63; animation: leader-draw var(--cycle) linear infinite; }
html.js .mini-check { stroke-dasharray: 18; animation: mini-draw var(--cycle) linear infinite; }
html.js .s3-check { animation-delay: 4.6s; }
@keyframes doc-in {
  0%, 6%, 97%, 100% { transform: translateY(8px); opacity: .35; }
  16%, 90% { transform: translateY(0); opacity: 1; }
}
@keyframes doc-sweep {
  0%, 16% { transform: scaleX(0); opacity: 1; }
  27%, 88.5% { transform: scaleX(1); opacity: 1; }
  92% { transform: scaleX(1); opacity: 0; }
  93%, 100% { transform: scaleX(0); opacity: 0; }
}
@keyframes bus-tap-draw {
  0%, 12% { stroke-dashoffset: 30; opacity: 0; }
  24%, 90% { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: -30; opacity: 0; }
}
@keyframes rail-draw {
  0%, 16% { stroke-dashoffset: 240; opacity: 0; }
  34%, 90% { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: -240; opacity: 0; }
}
@keyframes bus-pop {
  0%, 18%, 94%, 100% { transform: scale(.85); opacity: 0; }
  25%, 88.5% { transform: scale(1); opacity: 1; }
}
@keyframes stub-draw {
  0%, 34% { stroke-dashoffset: 36; opacity: 0; }
  40%, 90% { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: -36; opacity: 0; }
}
@keyframes claim-in {
  0%, 40%, 94%, 100% { transform: translateY(8px); opacity: .3; }
  50%, 88.5% { transform: translateY(0); opacity: 1; }
}
@keyframes risk-pulse {
  0%, 44%, 60%, 100% { transform: scale(1); opacity: 1; }
  52% { transform: scale(1.2); opacity: .75; }
}
@keyframes wire-draw {
  0%, 6% { stroke-dashoffset: 455; opacity: 0; }
  30%, 90% { stroke-dashoffset: 0; opacity: 1; }
  97%, 100% { stroke-dashoffset: -455; opacity: 0; }
}
@keyframes station-pop {
  0%, 66%, 94%, 100% { transform: scale(.9); opacity: 0; }
  74%, 88% { transform: scale(1); opacity: 1; }
}
@keyframes focus-in {
  0%, 64%, 92%, 100% { opacity: .55; transform: translateY(4px); }
  70%, 84% { opacity: 1; transform: translateY(0); }
}
@keyframes band-sweep {
  0%, 36% { transform: scaleX(0); opacity: 1; }
  45%, 88.5% { transform: scaleX(1); opacity: 1; }
  92.5% { transform: scaleX(1); opacity: 0; }
  93.5%, 100% { transform: scaleX(0); opacity: 0; }
}
@keyframes chip-pop {
  0%, 44%, 90%, 100% { transform: scale(.9); opacity: 0; }
  53%, 84% { transform: scale(1); opacity: 1; }
}
@keyframes leader-draw {
  0%, 46% { stroke-dashoffset: 63; opacity: 0; }
  54%, 88% { stroke-dashoffset: 0; opacity: 1; }
  95%, 100% { stroke-dashoffset: -63; opacity: 0; }
}
@keyframes answer-in {
  0%, 46%, 91%, 100% { transform: translateY(8px); opacity: 0; }
  56%, 84% { transform: translateY(0); opacity: 1; }
}
@keyframes mini-draw {
  0%, 22%, 95%, 100% { stroke-dashoffset: 18; opacity: 0; }
  30%, 88% { stroke-dashoffset: 0; opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .bus-tap, .bus-rail, .stub, .review-wire, .mini-check, .answer-leader { stroke-dasharray: none !important; }
}
