/*
 * Scenes B: Evidence Room, Getaway Bill, Code Lock, Rooftop Run, Split the Loot.
 * Markup: js/topics/_visuals.js (+ pythagoras.js triangle). Reactions are driven by
 * the state classes on #play-visual (is-correct / is-wrong / is-timeout, from
 * js/ext/scenes.js) plus .is-answer / .is-chosen / .sb-filled from js/visuals/scenes-b.js.
 * Animated elements never carry an SVG transform attribute, so CSS transforms are safe.
 */

.scene-b {
  display: block;
  width: 100%;
  max-width: 320px;
  height: auto;
  overflow: visible;
}
.scene-b .sb-sans {
  font-family: "Avenir Next", "Segoe UI", system-ui, -apple-system, sans-serif;
}
.scene-b .sb-mono {
  font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
}

/* Animated parts pivot around their own box. */
.scene-b .sb-file,
.scene-b .sb-drawer,
.scene-b .sb-cab-art,
.scene-b .sb-stamp-ink,
.scene-b .sb-exhibit-art,
.scene-b .sb-pack-art,
.scene-b .sb-coin-art,
.scene-b .sb-shackle,
.scene-b .sb-lock-body,
.scene-b .sb-runner,
.scene-b .sb-cap,
.scene-b .sb-cell,
.scene-b .sb-marker,
.scene-b .sb-unknown {
  transform-box: fill-box;
  transform-origin: center;
}

/* Hidden until a reaction shows them. */
.scene-b .sb-stamp,
.scene-b .sb-badge,
.scene-b .sb-ribbon,
.scene-b .sb-verdict,
.scene-b .sb-gap,
.scene-b .sb-coin-art {
  opacity: 0;
}
.scene-b .sb-route {
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
}
.scene-b .sb-lamp,
.scene-b .sb-cab-body,
.scene-b .sb-exhibit-card,
.scene-b .sb-pack-card,
.scene-b .sb-area,
.scene-b .sb-screen,
.scene-b .sb-readout,
.scene-b .sb-led,
.scene-b .sb-echo,
.scene-b .sb-hilite {
  transition: fill 0.25s ease, stroke 0.25s ease, opacity 0.25s ease, fill-opacity 0.25s ease;
}

/* ---------- shared reactions ---------- */

/* Unknown placeholders type in once the answer is printed into them. */
.scene-b .sb-unknown.sb-filled {
  animation: sb-type 0.45s steps(7, end) both;
}
.is-correct .scene-b .sb-coin-art {
  animation: sb-coin 0.38s cubic-bezier(0.3, 1.5, 0.5, 1) both;
  animation-delay: calc(0.12s + var(--i, 0) * 55ms);
}
.is-correct .scene-b .sb-cell {
  animation: sb-glow 0.5s ease-out both;
}

.is-wrong .scene-b .sb-hilite,
.is-timeout .scene-b .sb-hilite {
  fill: #ff5470;
  stroke: #ff5470;
}
.is-wrong .scene-b .sb-unknown,
.is-timeout .scene-b .sb-unknown {
  animation: sb-shake 0.4s ease-in-out both;
}

/* ---------- Evidence Room ---------- */

[data-scene="evidence"] { --dx: -74px; --dy: 122px; }
[data-scene="evidence"][data-answer-slot="1"] { --dx: 74px; }

.is-correct [data-scene="evidence"] .sb-file {
  animation: sb-file-drop 0.55s cubic-bezier(0.5, 0, 0.3, 1) both;
}
.is-correct [data-scene="evidence"] .sb-cab.is-answer .sb-drawer {
  animation: sb-drawer-close 0.18s 0.5s ease-out both;
}
.is-correct [data-scene="evidence"] .sb-cab.is-answer .sb-lamp {
  fill: #2ee66b;
}
.is-correct [data-scene="evidence"] .sb-cab.is-answer .sb-cab-body,
.is-correct [data-scene="evidence"] .sb-exhibit.is-answer .sb-exhibit-card {
  stroke: #2ee66b;
  stroke-width: 3;
}
.is-correct [data-scene="evidence"] .sb-exhibit.is-answer .sb-badge {
  opacity: 1;
}
.is-correct [data-scene="evidence"] .sb-exhibit.is-answer .sb-exhibit-art {
  animation: sb-lift 0.4s ease-out both;
}
.is-correct [data-scene="evidence"] .sb-exhibit:not(.is-answer) .sb-exhibit-art {
  opacity: 0.4;
}
.is-correct [data-scene="evidence"] .sb-area {
  fill: rgba(46, 230, 107, 0.22);
}
.is-correct [data-scene="evidence"] .sb-gap {
  opacity: 0.6;
}
.is-correct [data-scene="evidence"] .sb-marker {
  animation: sb-bounce 0.5s ease-out both;
}
.is-correct [data-scene="evidence"] .sb-echo {
  stroke: #ffd166;
  fill: rgba(255, 209, 102, 0.14);
}

.is-wrong [data-scene="evidence"] .sb-misfiled,
.is-timeout [data-scene="evidence"] .sb-misfiled {
  opacity: 1;
}
.is-wrong [data-scene="evidence"] .sb-misfiled .sb-stamp-ink,
.is-timeout [data-scene="evidence"] .sb-misfiled .sb-stamp-ink {
  animation: sb-stamp 0.32s cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
}
.is-wrong [data-scene="evidence"] .is-chosen .sb-cab-body,
.is-wrong [data-scene="evidence"] .is-chosen .sb-exhibit-card {
  stroke: #ff5470;
  stroke-width: 3;
}
.is-wrong [data-scene="evidence"] .is-chosen .sb-cab-art,
.is-wrong [data-scene="evidence"] .is-chosen .sb-exhibit-art {
  animation: sb-shake 0.4s ease-in-out both;
}

/* ---------- Getaway Bill ---------- */

.is-correct [data-scene="bill"] .sb-paid {
  opacity: 1;
}
.is-correct [data-scene="bill"] .sb-paid .sb-stamp-ink {
  animation: sb-stamp 0.32s 0.42s cubic-bezier(0.2, 0.9, 0.3, 1.2) both;
}
.is-correct [data-scene="bill"] .sb-hilite {
  fill: #2ee66b;
  stroke: #2ee66b;
}
.is-correct [data-scene="bill"] .sb-cap {
  animation: sb-grow 0.4s ease-out both;
  animation-delay: calc(var(--i, 0) * 70ms);
  transform-origin: center bottom;
}
.is-correct [data-scene="bill"] .sb-pack.is-answer .sb-ribbon {
  opacity: 1;
}
.is-correct [data-scene="bill"] .sb-pack.is-answer .sb-pack-art {
  animation: sb-lift 0.4s ease-out both;
}
.is-correct [data-scene="bill"] .sb-pack.is-answer .sb-pack-card {
  stroke: #2ee66b;
  stroke-width: 3;
}
.is-correct [data-scene="bill"] .sb-pack:not(.is-answer) .sb-pack-art {
  opacity: 0.45;
}
.is-wrong [data-scene="bill"] .sb-pack.is-chosen .sb-pack-card {
  stroke: #ff5470;
  stroke-width: 3;
}
.is-wrong [data-scene="bill"] .sb-pack.is-chosen .sb-pack-art {
  animation: sb-shake 0.4s ease-in-out both;
}

/* ---------- Code Lock ---------- */

.is-correct [data-scene="lock"] .sb-shackle {
  animation: sb-shackle-pop 0.45s 0.15s cubic-bezier(0.3, 1.6, 0.5, 1) both;
}
.is-correct [data-scene="lock"] .sb-screen {
  stroke: #2ee66b;
  fill: #0c2418;
}
.is-correct [data-scene="lock"] .sb-readout {
  fill: #2ee66b;
}
.is-correct [data-scene="lock"] .sb-led {
  fill: #2ee66b;
  transition-delay: calc(var(--i, 0) * 70ms);
}
.is-wrong [data-scene="lock"] .sb-lock-body,
.is-timeout [data-scene="lock"] .sb-lock-body {
  stroke: #ff5470;
  animation: sb-shake 0.4s ease-in-out both;
}
.is-wrong [data-scene="lock"] .sb-led,
.is-timeout [data-scene="lock"] .sb-led {
  animation: sb-blink 0.5s steps(2, jump-none) 2 both;
}

/* ---------- Rooftop Run ---------- */

.is-correct [data-scene="rooftop"] .sb-route {
  animation: sb-draw 0.6s ease-out both;
}
.is-correct [data-scene="rooftop"] .sb-runner {
  animation: sb-run 0.6s ease-in-out both;
}
.is-correct [data-scene="rooftop"] .sb-verdict.is-answer {
  opacity: 1;
}
.is-correct [data-scene="rooftop"] .sb-angle-q {
  opacity: 0;
}
.is-wrong [data-scene="rooftop"] .sb-runner,
.is-timeout [data-scene="rooftop"] .sb-runner {
  animation: sb-shake 0.4s ease-in-out both;
}

/* ---------- Split the Loot ---------- */

.is-correct [data-scene="loot"] .sb-corridor {
  fill-opacity: 0.8;
}

/* ---------- keyframes ---------- */

@keyframes sb-type {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}
@keyframes sb-coin {
  from { opacity: 0; transform: translateY(-18px) scale(0.4); }
  to { opacity: 1; transform: none; }
}
@keyframes sb-glow {
  0% { transform: scale(1); }
  45% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
@keyframes sb-shake {
  0%, 100% { transform: translateX(0); }
  20% { transform: translateX(-6px); }
  40% { transform: translateX(6px); }
  60% { transform: translateX(-4px); }
  80% { transform: translateX(4px); }
}
@keyframes sb-file-drop {
  0% { transform: none; opacity: 1; }
  55% { transform: translate(var(--dx), calc(var(--dy) - 34px)) scale(0.5); opacity: 1; }
  100% { transform: translate(var(--dx), var(--dy)) scale(0.32); opacity: 0; }
}
@keyframes sb-drawer-close {
  from { transform: none; }
  to { transform: translateY(-7px); }
}
@keyframes sb-lift {
  0% { transform: none; }
  50% { transform: translateY(-6px); }
  100% { transform: translateY(-3px); }
}
@keyframes sb-bounce {
  0%, 100% { transform: none; }
  40% { transform: translateY(-8px); }
  70% { transform: translateY(2px); }
}
@keyframes sb-stamp {
  from { opacity: 0; transform: scale(2.2); }
  to { opacity: 1; transform: none; }
}
@keyframes sb-grow {
  from { transform: scaleY(0); }
  to { transform: none; }
}
@keyframes sb-shackle-pop {
  from { transform: none; }
  to { transform: translateY(-13px); }
}
@keyframes sb-blink {
  0% { fill: #ff5470; }
  50% { fill: #3a1420; }
  100% { fill: #ff5470; }
}
@keyframes sb-draw {
  from { stroke-dashoffset: 100; }
  to { stroke-dashoffset: 0; }
}
@keyframes sb-run {
  from { transform: none; }
  to { transform: translate(var(--run-x), var(--run-y)); }
}

/* Reduced motion: no movement, jump straight to the final frame. */
@media (prefers-reduced-motion: reduce) {
  .scene-b *,
  .scene-b *::before,
  .scene-b *::after {
    animation-duration: 1ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition: none !important;
  }
  .is-wrong .scene-b .sb-unknown,
  .is-timeout .scene-b .sb-unknown,
  .is-wrong .scene-b .is-chosen .sb-cab-art,
  .is-wrong .scene-b .is-chosen .sb-exhibit-art,
  .is-wrong .scene-b .sb-pack.is-chosen .sb-pack-art,
  .is-wrong .scene-b .sb-lock-body,
  .is-timeout .scene-b .sb-lock-body,
  .is-wrong .scene-b .sb-runner,
  .is-timeout .scene-b .sb-runner {
    animation: none !important;
  }
}
