/* 2D autoplay story (opt-in .sx-play): no pinning; 海水寶寶 walks the three stops in one 6-second run. */
.sx-enabled .sx-story.sx-play { height: auto; }
.sx-enabled .sx-play .sx-pin { position: static; height: auto; min-height: 0; padding: 80px 0; display: block; overflow: visible; }
body.expo-theme .sx-play .sx-scene { height: auto; perspective: none; display: flex; flex-direction: column; gap: 18px; --sx-x: 48px; --sx-fill: 0; --sx-move: .75s; --sb-w: 96px; --sb-h: 64px; --sb-aqua: #5cc8e2; --sb-eye: #0c1e1c; --sx-ease: cubic-bezier(.45,0,.25,1); }
.sx-play .sx-visual-label { position: static; }
.sx-play .sx-step { transition: background-color 250ms; }
.sx-play .sx-step.is-current { background: var(--ex-bg); }
.sx-play .sx-step.is-current h3 { text-decoration: underline; text-underline-offset: 6px; text-decoration-thickness: 1px; }

/* Stops */
.sx-stops { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.sx-stop { position: relative; display: flex; flex-direction: column; gap: 14px; padding: 14px; background: var(--ex-bg); border: 1px solid var(--ex-border); transition: border-color .4s, box-shadow .4s, opacity .4s; }
.sx-stop-tag { font-size: 9px; letter-spacing: .06em; color: var(--ex-text-2); }
body.expo-theme .sx-stop strong { font-size: 17px; line-height: 1.3; letter-spacing: -.02em; color: var(--ex-text); }
.sx-art { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; overflow: visible; fill: none; stroke: var(--ex-text-2); stroke-width: 1.5; stroke-linejoin: round; }
.sx-art .fill { fill: var(--ex-text-2); stroke: none; }
.sx-art .hl { stroke: var(--ex-link); transition: stroke .4s, fill .4s; }
.sx-art .hl.fill { fill: var(--ex-link); stroke: none; }
.sx-art .a-ping { opacity: 0; }
.sx-play-ready .sx-stop:not(.is-on) { opacity: .55; }
.sx-play-ready .sx-stop:not(.is-on) .hl { stroke: var(--ex-text-2); }
.sx-play-ready .sx-stop:not(.is-on) .hl.fill { fill: var(--ex-text-2); stroke: none; }
.sx-stop.is-current { border-color: var(--ex-text-2); box-shadow: var(--ex-shadow-2); }
/* Pixel confetti on arrival, connectors light up in the finale. */
.sx-stop::after { content: ''; position: absolute; top: 10px; right: 10px; width: 4px; height: 4px; background: var(--sb-aqua); opacity: 0; pointer-events: none; box-shadow: -12px -10px 0 var(--sb-aqua), 10px -12px 0 var(--ex-link), -16px 6px 0 var(--ex-link), 8px 10px 0 var(--sb-aqua), -4px -18px 0 var(--sb-aqua); }
.sx-stop.is-current::after { animation: sx-spark .7s steps(4, jump-none) both; }
.sx-stop:not(:last-child)::before { content: ''; position: absolute; top: 50%; right: -13px; width: 12px; height: 2px; background: var(--ex-link); transform: scaleX(0); transform-origin: left; }
.sx-scene.is-finale .sx-stop:not(:last-child)::before { animation: sx-link .35s ease both; }
.sx-scene.is-finale .sx-stop:nth-child(2)::before { animation-delay: .15s; }

/* Art motion: every primitive runs once, inside the ~1s a stop is in focus. */
.sx-art .a-pop, .sx-art .a-grow, .sx-art .a-growx, .sx-art .a-spin, .sx-art .a-ping, .sx-art .a-swing, .sx-art .a-bounce { transform-box: fill-box; transform-origin: center; }
.sx-art .a-grow { transform-origin: bottom; }
.sx-art .a-growx { transform-origin: left; }
.sx-art .a-swing { transform-origin: top; }
.sx-stop.is-on .a-pop { animation: sx-pop .45s cubic-bezier(.34,1.56,.64,1) var(--d, 0s) both; }
.sx-stop.is-on .a-draw { stroke-dasharray: 1; animation: sx-draw .6s ease var(--d, 0s) both; }
.sx-stop.is-on .a-fly { animation: sx-fly .6s cubic-bezier(.16,1,.3,1) var(--d, 0s) both; }
.sx-stop.is-on .a-grow { animation: sx-grow .5s cubic-bezier(.16,1,.3,1) var(--d, 0s) both; }
.sx-stop.is-on .a-growx { animation: sx-growx .5s cubic-bezier(.16,1,.3,1) var(--d, 0s) both; }
.sx-stop.is-on .a-flow { animation: sx-flow .6s linear var(--d, 0s) 2 both; }
.sx-stop.is-on .a-scan { animation: sx-scan .5s ease-in-out var(--d, 0s) 2 alternate both; }
.sx-stop.is-on .a-ping { animation: sx-ping .7s ease-out var(--d, 0s) both; }
.sx-stop.is-on .a-blink { animation: sx-blink .6s steps(2, jump-none) var(--d, 0s) both; }
.sx-stop.is-on .a-spin { animation: sx-spin .9s ease-in-out var(--d, 0s) both; }
.sx-stop.is-on .a-swing { animation: sx-swing .8s ease-out var(--d, 0s) both; }
.sx-stop.is-on .a-bounce { animation: sx-bounce .3s ease-in-out var(--d, 0s) 3 alternate both; }

/* Rail + 海水寶寶 */
.sx-rail { position: relative; height: 84px; }
.sx-rail::before, .sx-rail-fill { content: ''; position: absolute; left: 0; right: 0; bottom: 9px; height: 1px; background: var(--ex-border-strong); }
.sx-rail-fill { height: 2px; bottom: 8px; background: var(--ex-link); transform-origin: left; transform: scaleX(var(--sx-fill)); transition: transform var(--sx-move) var(--sx-ease); }
.sx-rail-pins { position: absolute; left: 0; right: 0; bottom: 5px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }
.sx-rail-pins i { justify-self: center; width: 9px; height: 9px; background: var(--ex-surface); border: 1px solid var(--ex-border-strong); transition: background-color .3s, border-color .3s; }
.sx-rail-pins i.is-on { background: var(--ex-link); border-color: var(--ex-link); animation: sx-pop .4s cubic-bezier(.34,1.56,.64,1); }
.sx-buddy { position: absolute; left: 0; bottom: 12px; width: var(--sb-w); height: var(--sb-h); transform: translateX(calc(var(--sx-x) - var(--sb-w) / 2)); transition: transform var(--sx-move) var(--sx-ease), opacity .3s; }
.sx-buddy-sprite { width: 100%; height: 100%; animation: sx-bob 3.2s ease-in-out infinite; }
.sx-buddy svg { display: block; width: 100%; height: 100%; overflow: visible; fill: var(--sb-aqua); }
.sx-buddy-eyes { fill: var(--sb-eye); transform-origin: 60px 21px; animation: sx-eye 4.8s infinite; }
.sx-buddy > i { position: absolute; left: 50%; top: -8px; width: 6px; height: 6px; border: 1px solid var(--ex-text-2); border-radius: 50%; opacity: 0; animation: sx-rise 3.6s ease-in infinite; }
.sx-buddy > i:nth-of-type(2) { left: 64%; width: 4px; height: 4px; animation-delay: 1.2s; }
.sx-buddy > i:nth-of-type(3) { left: 40%; animation-delay: 2.4s; }
/* Dust puffs trail the buddy while walking. */
.sx-buddy::before { content: ''; position: absolute; left: 4px; bottom: 0; width: 5px; height: 5px; background: var(--ex-text-2); opacity: 0; box-shadow: -8px -4px 0 var(--ex-border-strong), -14px 1px 0 var(--ex-border-strong); }
.sx-scene.is-walking .sx-buddy::before { animation: sx-dust .38s steps(3, jump-none) infinite; }
.sx-scene.is-walking .sx-buddy-sprite { animation: sx-lean var(--sx-move) ease-in-out both; }
.sx-scene.is-walking .sx-buddy-legs rect:nth-child(odd) { animation: sx-step .19s steps(2, jump-none) infinite; }
.sx-scene.is-walking .sx-buddy-legs rect:nth-child(even) { animation: sx-step .19s steps(2, jump-none) infinite reverse; }
.sx-scene.is-talking .sx-buddy svg { animation: sx-hop .5s cubic-bezier(.34,1.56,.64,1); }
.sx-scene.is-talking .sx-buddy-arm-r { animation: sx-wave .25s steps(2, jump-none) 2; }
.sx-scene.is-finale .sx-buddy-arm-r, .sx-scene.is-finale .sx-buddy-arm-l { animation: sx-wave .25s steps(2, jump-none) 4; }
.sx-scene.is-finale .sx-buddy svg { animation: sx-hop .5s cubic-bezier(.34,1.56,.64,1) 2; }
.sx-scene.is-done .sx-buddy-sprite { animation-play-state: paused; }
.sx-scene.no-move .sx-buddy, .sx-scene.no-move .sx-rail-fill, .sx-scene.no-move .sx-say::before { transition: none; }

/* Speech bubble points up at the buddy. */
.sx-say { position: relative; min-height: 76px; padding: 12px 16px; background: var(--ex-bg); border: 1px solid var(--ex-border-strong); }
.sx-say::before { content: ''; position: absolute; top: -7px; left: clamp(12px, calc(var(--sx-x) - 7px), calc(100% - 26px)); width: 12px; height: 12px; background: var(--ex-bg); border-left: 1px solid var(--ex-border-strong); border-top: 1px solid var(--ex-border-strong); transform: rotate(45deg); transition: left var(--sx-move) var(--sx-ease); }
.sx-say-name { display: block; font-size: 10px; font-weight: 600; letter-spacing: .12em; color: var(--ex-text-2); margin-bottom: 6px; }
body.expo-theme .sx-say-text { margin: 0; font-size: 13px; line-height: 1.75; color: var(--ex-text); }
.sx-scene.is-talking .sx-say-text { animation: sx-say .3s ease both; }
.sx-play .sx-track { position: relative; inset: auto; }
.sx-play .sx-track span { transform: scaleX(var(--sx-progress, 1)); transition: transform .5s var(--sx-ease); }

@keyframes sx-pop { from { transform: scale(0); opacity: 0; } }
@keyframes sx-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes sx-fly { from { transform: translate(var(--fx, 0px), var(--fy, 0px)); opacity: 0; } }
@keyframes sx-grow { from { transform: scaleY(0); } }
@keyframes sx-growx { from { transform: scaleX(0); } }
@keyframes sx-flow { 0% { transform: translate(0, 0); opacity: 0; } 20%, 75% { opacity: 1; } 100% { transform: translate(var(--fx, 78px), var(--fy, 0px)); opacity: 0; } }
@keyframes sx-scan { to { transform: translate(var(--fx, 58px), var(--fy, 0px)); } }
@keyframes sx-ping { from { transform: scale(.6); opacity: .9; } to { transform: scale(2); opacity: 0; } }
@keyframes sx-blink { 0% { opacity: .2; } 50% { opacity: 1; } 75% { opacity: .3; } 100% { opacity: 1; } }
@keyframes sx-spin { from { transform: rotate(-180deg); } }
@keyframes sx-swing { 20% { transform: rotate(18deg); } 45% { transform: rotate(-14deg); } 70% { transform: rotate(8deg); } 100% { transform: rotate(0); } }
@keyframes sx-bounce { to { transform: translateY(-4px); } }
@keyframes sx-spark { 0% { opacity: 1; transform: scale(.4); } 100% { opacity: 0; transform: scale(1.6) translateY(-6px); } }
@keyframes sx-link { to { transform: scaleX(1); } }
@keyframes sx-bob { 50% { transform: translateY(-6px); } }
@keyframes sx-lean { 30%, 70% { transform: rotate(4deg) translateY(-2px); } }
@keyframes sx-eye { 0%, 94%, 100% { transform: scaleY(1); } 97% { transform: scaleY(.1); } }
@keyframes sx-step { to { transform: translateY(-5px); } }
@keyframes sx-wave { to { transform: translateY(-10px); } }
@keyframes sx-dust { 0% { opacity: .8; transform: translate(0, 0); } 100% { opacity: 0; transform: translate(-10px, -6px); } }
@keyframes sx-rise { 0% { transform: translateY(0); opacity: 0; } 15% { opacity: .8; } 100% { transform: translateY(-46px); opacity: 0; } }
@keyframes sx-hop { 40% { transform: translateY(-12px); } }
@keyframes sx-say { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }

@media (max-width: 900px) {
 .sx-enabled .sx-play .sx-pin { padding: 64px 0; }
 body.expo-theme .sx-play .sx-scene { gap: 14px; --sb-w: 72px; --sb-h: 48px; }
 .sx-stops, .sx-rail-pins { gap: 8px; }
 .sx-stop:not(:last-child)::before { right: -9px; width: 8px; }
 .sx-stop { padding: 10px; gap: 10px; }
 body.expo-theme .sx-stop strong { font-size: 14px; }
 .sx-rail { height: 70px; }
}
@media (max-width: 600px) {
 .sx-stop-tag { display: none; }
 body.expo-theme .sx-stop strong { font-size: 12px; }
 .sx-stop { padding: 8px; }
}
@media (prefers-reduced-motion: reduce) {
 .sx-scene *, .sx-scene *::before, .sx-scene *::after { animation: none !important; transition: none !important; }
 .sx-scene.is-finale .sx-stop:not(:last-child)::before { transform: scaleX(1); }
}
