/* Order processing page: the three animations (hero note, results sort, converge).
   Markup: app/home/templates/order_processing/_hero_note.html, _results_sort.html, _motion_converge.html.
   Start/stop: assets/js/order-processing-motion.js adds .is-playing to each [data-motion] root while it is
   on screen. Without that class (no JavaScript, reduced motion, off screen) every piece rests on its
   finished frame, so all "resting" styles below ARE the finished picture.

   Each piece has two fixed-size layouts drawn at their design size and scaled to fit:
   - a large one (from the mockup) for wide containers,
   - a compact one for phones, where every text is at least 13px at design size (12px+ on screen).
   The scale is worked out in CSS (container width / design width); the JS only steps in for browsers
   that can't do that maths.
   Note: things that move along a path (offset-path) grow and turn with `transform`, never with the
   separate `scale` / `rotate` properties: those are applied on top of the path movement and would
   push the element away from its path. */

/* ---------- shared ---------- */
.op-motion {
  position: relative;
  display: block;
  width: 100%;
  container-type: inline-size;
  color: #0C1A2E;
  font-family: 'Geist', system-ui, -apple-system, 'Segoe UI', sans-serif;
  text-align: left;
}
.op-motion,
.op-motion *,
.op-motion *::before,
.op-motion *::after { box-sizing: border-box; }

.op-frame { position: relative; width: 100%; margin-inline: auto; }
.op-stage {
  position: absolute;
  left: 0;
  top: 0;
  transform-origin: 0 0;
  line-height: normal;
  letter-spacing: normal;
}
.op-stage svg { display: block; overflow: visible; }
.op-stage i { display: block; font-style: normal; }

.op-vh {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Scale = min(container width, frame max width) / design width, as a plain number. */
.hn-frame-l { display: none; max-width: 620px; aspect-ratio: 620 / 560; }
.hn-frame-l > .op-stage { width: 620px; height: 560px; transform: scale(tan(atan2(min(100cqw, 620px), 620px))); }
.hn-frame-s { max-width: 360px; aspect-ratio: 300 / 492; }
.hn-frame-s > .op-stage { width: 300px; height: 492px; transform: scale(tan(atan2(min(100cqw, 360px), 300px))); }

.sn-frame-l { display: none; max-width: 1200px; aspect-ratio: 1200 / 640; }
.sn-frame-l > .op-stage { width: 1200px; height: 640px; transform: scale(tan(atan2(min(100cqw, 1200px), 1200px))); }
.sn-frame-s { max-width: 360px; aspect-ratio: 300 / 336; }
.sn-frame-s > .op-stage { width: 300px; height: 336px; transform: scale(tan(atan2(min(100cqw, 360px), 300px))); }

.cv-frame-l { display: none; max-width: 1200px; aspect-ratio: 1200 / 640; }
.cv-frame-l > .op-stage { width: 1200px; height: 640px; transform: scale(tan(atan2(min(100cqw, 1200px), 1200px))); }
.cv-frame-s { max-width: 360px; aspect-ratio: 300 / 620; }
.cv-frame-s > .op-stage { width: 300px; height: 620px; transform: scale(tan(atan2(min(100cqw, 360px), 300px))); }

/* Large layouts: hero from 560px of container on screens 720px+; the other two from 960px of container. */
@media (min-width: 720px) {
  @container (min-width: 560px) {
    .hn-frame-l { display: block; }
    .hn-frame-s { display: none; }
  }
}
@container (min-width: 960px) {
  .sn-frame-l, .cv-frame-l { display: block; }
  .sn-frame-s, .cv-frame-s { display: none; }
}

/* ---------- hero note (from HeroScribble, green) ---------- */
.hn-paper {
  position: absolute;
  border-radius: 4px;
  background: #FFFDF6;
  border: 1px solid #E8E1CC;
  box-shadow: 0 24px 48px -16px rgba(12, 26, 46, 0.28);
  transform: rotate(-3deg);
}
.hn-stain { position: absolute; border-radius: 50%; border: 4px solid rgba(150, 105, 60, 0.13); }
.hn-s .hn-stain { border-width: 3px; }
.hn-paper svg { position: absolute; left: 0; top: 0; }
.hn-ink {
  position: absolute;
  z-index: 3;
  white-space: nowrap;
  font-family: 'Caveat', 'Segoe Print', 'Bradley Hand', cursive;
  font-weight: 500;
  line-height: normal;
  color: #2B3A5C;
  transform-origin: 0 50%;
}
.hn-ink s { text-decoration-thickness: 2px; color: #7A859A; }
.hn-beam {
  position: absolute;
  z-index: 7;
  width: 5px;
  border-radius: 3px;
  background: linear-gradient(180deg, rgba(8, 122, 78, 0), #087A4E 30%, #00C2FF 70%, rgba(0, 194, 255, 0));
  opacity: 0;
}
.hn-card {
  position: absolute;
  z-index: 4;
  border-radius: 12px;
  background: #FFFFFF;
  border: 1px solid #DDE3EA;
  box-shadow: 0 50px 100px -20px rgba(12, 26, 46, 0.25), 0 30px 60px -30px rgba(0, 0, 0, 0.30);
}
.hn-head {
  display: flex;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid #E8EDF2;
  font-size: 14px;
}
.hn-title { font-weight: 600; white-space: nowrap; }
.hn-status { position: relative; min-width: 96px; text-align: right; }
.hn-reading { position: absolute; right: 0; top: 0; color: #8A96A8; font-weight: 500; white-space: nowrap; }
.hn-done { color: #087A4E; font-weight: 600; white-space: nowrap; }
.hn-cols {
  position: relative;
  height: 30px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #5B6B82;
}
.hn-cols span { position: absolute; top: 12px; }
.hn-foot {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  justify-content: flex-end;
  padding: 14px 18px;
  background: #F7F9FB;
  border-top: 1px solid #E8EDF2;
  border-radius: 0 0 12px 12px;
}
/* A quiet status pill, not a button: the page's real call to action must stay the only strong button (Nik, 2026-10-15) */
.hn-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 28px;
  padding: 0 11px;
  border-radius: 999px;
  background: #E3F4EC;
  color: #05603C;
  font-size: 12.5px;
  font-weight: 600;
}
.hn-btn__tick { font-size: 12px; }
.hn-skel { opacity: 0; }
.hn-bars { position: absolute; z-index: 5; display: flex; }
.hn-bars span { display: block; height: 8px; border-radius: 4px; background: #EDF1F6; }
.hn-type { position: absolute; z-index: 5; white-space: nowrap; font-size: 12.5px; line-height: 16px; }
.hn-mono { font-family: 'Geist Mono', ui-monospace, monospace; color: #5B6B82; }
.hn-code { font-family: 'Geist Mono', ui-monospace, monospace; color: #087A4E; }
.hn-tick {
  position: absolute;
  z-index: 5;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #E3F4EC;
  color: #087A4E;
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hn-parts { position: absolute; inset: 0; pointer-events: none; }
.hn-d, .hn-n {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 6;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  opacity: 0;
  offset-rotate: 0deg;
  offset-anchor: 50% 50%;
}
.hn-n { background: #B08A7C; }
.hn-d.g { color: #9AA6B8; }
.hn-d.a { color: #087A4E; }
.hn-d.k { color: #0C1A2E; }

/* compact hero: bigger small print */
.hn-s .hn-head { padding: 12px 14px; font-size: 13px; }
.hn-s .hn-status { min-width: 0; }
.hn-s .hn-cols { height: 28px; font-size: 13px; letter-spacing: 0.04em; }
.hn-s .hn-cols span { top: 9px; }
.hn-s .hn-type { font-size: 13px; }
.hn-s .hn-tick { width: 20px; height: 20px; font-size: 13px; }
.hn-s .hn-foot { padding: 10px 14px; }
.hn-s .hn-btn { min-height: 26px; font-size: 12.5px; }

@keyframes hnInk { 0%, 12% { opacity: 1; clip-path: inset(-20px -20px -20px 0); } 28%, 88% { opacity: 1; clip-path: inset(-20px -20px -20px calc(100% + 20px)); } 89% { opacity: 0; clip-path: inset(-20px -20px -20px 0); } 100% { opacity: 1; clip-path: inset(-20px -20px -20px 0); } }
@keyframes hnDot { 0%, 11.9% { offset-distance: 0%; transform: scale(1); background: #2B3A5C; opacity: 0; } 12.5% { offset-distance: 0%; transform: scale(1.3); background: #2B3A5C; opacity: .9; } 14% { offset-distance: 2%; transform: scale(1); background: #2B3A5C; opacity: .9; } 30% { background: currentColor; } 42% { offset-distance: 100%; transform: scale(1); background: currentColor; opacity: .9; } 50%, 100% { offset-distance: 100%; transform: scale(.4); background: currentColor; opacity: 0; } }
@keyframes hnNoise { 0%, 11.9% { offset-distance: 0%; transform: scale(1); opacity: 0; } 12.5% { offset-distance: 0%; transform: scale(1.3); opacity: .8; } 14% { offset-distance: 4%; transform: scale(1); opacity: .7; } 30%, 100% { offset-distance: 100%; transform: scale(.4); opacity: 0; } }
@keyframes hnType { 0%, 48% { opacity: 0; filter: blur(5px); letter-spacing: .3em; } 60%, 90% { opacity: 1; filter: blur(0); letter-spacing: 0; } 97%, 100% { opacity: 0; filter: blur(0); letter-spacing: 0; } }
@keyframes hnBeam { 0%, 10% { transform: translateX(0); opacity: 0; } 12% { opacity: 1; } 28% { transform: translateX(390px); opacity: 1; } 31%, 100% { transform: translateX(390px); opacity: 0; } }
@keyframes hnBeamS { 0%, 10% { transform: translateX(0); opacity: 0; } 12% { opacity: 1; } 28% { transform: translateX(284px); opacity: 1; } 31%, 100% { transform: translateX(284px); opacity: 0; } }
@keyframes hnSkel { 0%, 46% { opacity: 1; } 56%, 90% { opacity: 0; } 98%, 100% { opacity: 1; } }
@keyframes hnDone { 0%, 54% { opacity: 0; } 60%, 90% { opacity: 1; } 97%, 100% { opacity: 0; } }
@keyframes hnBtn { 0%, 54% { opacity: .35; } 62%, 90% { opacity: 1; } 97%, 100% { opacity: .35; } }
@keyframes hnTick { 0%, 60% { opacity: 0; transform: scale(.4); } 64%, 90% { opacity: 1; transform: scale(1); } 97%, 100% { opacity: 0; } }

.is-playing .hn-ink { animation: hnInk 10s linear infinite both; }
.is-playing .hn-d { animation: hnDot 10s cubic-bezier(.33, .1, .3, 1) infinite both; }
.is-playing .hn-n { animation: hnNoise 10s cubic-bezier(.3, .2, .3, 1) infinite both; }
.is-playing .hn-type { animation: hnType 10s cubic-bezier(.3, 0, .2, 1) infinite both; }
.is-playing .hn-beam { animation: hnBeam 10s cubic-bezier(.45, 0, .55, 1) infinite both; }
.is-playing .hn-s .hn-beam { animation-name: hnBeamS; }
.is-playing .hn-skel { animation: hnSkel 10s ease-in-out infinite both; }
.is-playing .hn-done { animation: hnDone 10s ease-out infinite both; }
.is-playing .hn-btn { animation: hnBtn 10s ease-out infinite both; }
.is-playing .hn-tick { animation: hnTick 10s ease-out infinite both; }

/* ---------- results sort (from MotionSort, bare + results) ---------- */
.sn-inner { position: relative; }
.sn-results { margin: 0 0 28px; }
.sn-lead { margin: 0 0 6px; font-size: 14px; font-weight: 600; line-height: 1.45; color: #1E3FCC; }
.sn-list { list-style: none; margin: 0; padding: 0; }
.sn-list li {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0;
  padding: 16px 0;
  border-top: 1px solid #E3E8EF;
}
.sn-num { font-size: 44px; font-weight: 700; letter-spacing: -0.045em; line-height: 1; color: #2F5BFF; white-space: nowrap; }
.sn-txt { font-size: 16px; line-height: 1.45; color: #42526B; }
.sn-frame-s { margin-inline: auto; }

@container (min-width: 420px) {
  .sn-list li { flex-direction: row; align-items: baseline; gap: 18px; }
  .sn-num { flex: 0 0 132px; }
}
/* tablet: results on the left, compact table on the right */
@container (min-width: 600px) {
  .sn-inner { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 360px); gap: 40px; align-items: center; }
  .sn-results { margin: 0; }
  .sn-frame-s { margin: 0; }
  .sn-list li { flex-direction: column; gap: 6px; }
  .sn-num { flex: none; }
}
/* desktop: the mockup layout, results drawn over the left side of the animation at its scale */
@container (min-width: 960px) {
  .sn-inner { display: block; }
  .sn-results {
    position: absolute;
    left: 0;
    top: 0;
    z-index: 2;
    width: 500px;
    margin: 0;
    transform-origin: 0 0;
    transform: scale(tan(atan2(min(100cqw, 1200px), 1200px))) translate(40px, 110px);
  }
  .sn-lead { margin-bottom: 8px; }
  .sn-list li { flex-direction: row; gap: 18px; padding: 18px 0; }
  .sn-num { flex: 0 0 150px; font-size: 52px; }
  .sn-txt { font-size: 17px; }
}

.sn-card {
  position: absolute;
  border-radius: 14px;
  background: #FFFFFF;
  border: 1px solid #E3E8EF;
  box-shadow: 0 40px 80px -24px rgba(12, 26, 46, 0.22);
}
.sn-cols {
  position: relative;
  height: 40px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #5B6B82;
}
.sn-cols span { position: absolute; top: 20px; }
.sn-flag { position: absolute; background: #FFF1EB; box-shadow: inset 3px 0 0 #FF6A3D; }
.sn-w { position: absolute; white-space: nowrap; transform-origin: 0 50%; font-size: 13px; line-height: 16px; }
.sn-word, .sn-noise {
  left: 0;
  top: 0;
  font-family: 'Geist Mono', ui-monospace, monospace;
  offset-rotate: 0deg;
  offset-anchor: 0% 50%;
  offset-distance: 100%;
}
.sn-buyer { color: #5B6B82; }
.sn-qty { color: #0C1A2E; }
.sn-noise { color: #B08A7C; opacity: 0; }
.sn-code { font-family: 'Geist Mono', ui-monospace, monospace; color: #2F5BFF; }
.sn-flagged, .sn-flagged .sn-code { color: #A8380F; }

.sn-s .sn-cols { height: 44px; font-size: 13px; letter-spacing: 0.04em; }
.sn-s .sn-cols span { top: 17px; }
.sn-s .sn-w { font-size: 13px; }

@keyframes snSnapA { 0% { offset-distance: 0%; transform: rotate(-16deg) scale(1.35); opacity: 0; } 6% { opacity: 1; } 30% { offset-distance: 10%; transform: rotate(-9deg) scale(1.35); } 52%, 88% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 1; } 96%, 100% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 0; } }
@keyframes snSnapB { 0% { offset-distance: 0%; transform: rotate(14deg) scale(.9); opacity: 0; } 6% { opacity: 1; } 30% { offset-distance: 10%; transform: rotate(7deg) scale(.9); } 52%, 88% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 1; } 96%, 100% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 0; } }
@keyframes snSnapC { 0% { offset-distance: 0%; transform: rotate(-5deg) scale(1.6); opacity: 0; } 6% { opacity: 1; } 30% { offset-distance: 10%; transform: rotate(4deg) scale(1.6); } 52%, 88% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 1; } 96%, 100% { offset-distance: 100%; transform: rotate(0deg) scale(1); opacity: 0; } }
@keyframes snNoise { 0% { offset-distance: 0%; transform: rotate(-12deg) scale(1.2); opacity: 0; } 6% { opacity: .9; } 30% { offset-distance: 45%; opacity: .9; } 46%, 100% { offset-distance: 100%; transform: rotate(0deg) scale(.6); opacity: 0; } }
@keyframes snMatch { 0%, 54% { opacity: 0; transform: translateX(-10px); } 60%, 88% { opacity: 1; transform: none; } 96%, 100% { opacity: 0; transform: none; } }
@keyframes snCard { 0%, 40% { opacity: 0; transform: translateY(8px); } 52%, 88% { opacity: 1; transform: translateY(0); } 96%, 100% { opacity: 0; } }
@keyframes snFlag { 0%, 58% { opacity: 0; } 64%, 88% { opacity: 1; } 96%, 100% { opacity: 0; } }

.is-playing .sn-w { animation-duration: 7s; animation-iteration-count: infinite; animation-fill-mode: both; }
.is-playing .sn-word { animation-timing-function: cubic-bezier(.7, 0, .2, 1); }
.is-playing .sn-ka { animation-name: snSnapA; }
.is-playing .sn-kb { animation-name: snSnapB; }
.is-playing .sn-kc { animation-name: snSnapC; }
.is-playing .sn-noise { animation-name: snNoise; animation-timing-function: ease-in-out; }
.is-playing .sn-match { animation-name: snMatch; animation-timing-function: ease-out; }
.is-playing .sn-card { animation: snCard 7s ease-out infinite both; }
.is-playing .sn-flag { animation: snFlag 7s ease-out infinite both; }
/* Desktop layout: the results numbers share space with the flying words, so they appear only after the
   words have moved into the table. The piece plays once (data-motion-once) and then holds the finished
   frame, so the numbers never disappear again (Nik, 2026-10-15). */
@keyframes snRes { 0%, 50% { opacity: 0; transform: translateY(14px); } 60%, 100% { opacity: 1; transform: none; } }
@container (min-width: 960px) {
  .is-playing .sn-res { animation: snRes 7s cubic-bezier(.2, .7, .2, 1) infinite both; }
  .is-playing .sn-res-1 { animation-delay: .1s; }
  .is-playing .sn-res-2 { animation-delay: .35s; }
  .is-playing .sn-res-3 { animation-delay: .6s; }
}

/* ---------- converge (from MotionConverge, bare: no background glows) ---------- */
.cv-lines { position: absolute; left: 0; top: 0; fill: none; }
.cv-dot, .cv-lane {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 0;
  offset-anchor: 50% 50%;
}
.cv-dot { border-radius: 50%; offset-rotate: 0deg; }
.cv-lane { width: 18px; height: 4px; border-radius: 3px; offset-rotate: auto; }
.cv-chip {
  position: absolute;
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.92);
  border: 1px solid #F1D9CF;
  box-shadow: 0 6px 16px -8px rgba(12, 26, 46, 0.3);
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 12px;
  color: #8A3A1A;
  white-space: nowrap;
}
.cv-hub {
  position: absolute;
  background: #0C1A2E;
  box-shadow: 0 20px 40px -12px rgba(12, 26, 46, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
}
.cv-ring {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  border: 2px solid #2F5BFF;
  opacity: 0;
}
.cv-out {
  position: absolute;
  padding: 5px 10px;
  border-radius: 8px;
  background: #FFFFFF;
  border: 1px solid #D9E2F2;
  box-shadow: 0 6px 16px -10px rgba(12, 26, 46, 0.35);
  font-family: 'Geist Mono', ui-monospace, monospace;
  font-size: 12px;
  color: #1E3FCC;
  white-space: nowrap;
}
.cv-logo { position: relative; display: block; }
.cv-label {
  position: absolute;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.cv-label-in { color: #A8380F; }
.cv-label-out { color: #1E3FCC; }
.cv-s .cv-chip, .cv-s .cv-out { font-size: 13px; }
.cv-s .cv-label { letter-spacing: 0.04em; }

@keyframes cvTravel { 0% { offset-distance: 0%; opacity: 0; } 12% { opacity: 1; } 88% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
@keyframes cvPulse { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes cvBob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }

.is-playing .cv-dot { animation-name: cvTravel; animation-iteration-count: infinite; animation-timing-function: cubic-bezier(.45, 0, .25, 1); }
.is-playing .cv-lane { animation: cvTravel 3s linear infinite; }
.is-playing .cv-ring { animation: cvPulse 2.4s cubic-bezier(.2, .6, .3, 1) infinite; }
.is-playing .cv-ring-2 { animation-delay: 1.2s; }
.is-playing .cv-chip { animation: cvBob 4s ease-in-out infinite; }

/* ---------- motion off: always the finished frame ---------- */
@media (prefers-reduced-motion: reduce) {
  .op-motion *, .op-motion *::before, .op-motion *::after { animation: none !important; }
}

/* Waiting to play: every animation is applied but held at its first frame (see order-processing-motion.js). */
.op-motion.is-waiting, .op-motion.is-waiting * { animation-play-state: paused !important; }
