/* Quizari "alive" layer: scroll-linked motion, journey preview, trap game.
   Everything that moves is transform/opacity only and is switched off for prefers-reduced-motion. */

/* ---- word-by-word headings ---- */
.js .words .w { display: inline-block; overflow: hidden; vertical-align: bottom; padding-bottom: .08em; margin-bottom: -.08em; }
.js .words .w > span { display: inline-block; transform: translateY(112%) rotate(4deg); transition: transform .8s var(--spring); transition-delay: calc(var(--i) * 60ms + 80ms); }
.js .in .words .w > span, .js .words.in .w > span { transform: none; }

/* ---- spine rider (a little cube that travels the story line) ---- */
.rider { position: absolute; left: calc(var(--gutter) / 2 - 13px); top: 0; width: 26px; height: 26px; display: block; pointer-events: none; will-change: transform; z-index: 3; }
.rider svg { width: 100%; height: 100%; transition: transform .6s var(--spring); }
@media (max-width: 999px) { .rider { width: 18px; height: 18px; left: calc(var(--gutter) / 2 - 9px); } }

/* ---- scroll-linked parallax uses the individual `translate` property so it composes with reveals ---- */
[data-speed] { will-change: translate; }

/* ---- tracks: art draws itself, nodes pop ---- */
.js .track .art [pathLength] { stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset 1.2s cubic-bezier(.5,0,.2,1) .35s; }
.js .track.in .art [pathLength] { stroke-dashoffset: 0; }
.js .track .art :is(circle, rect) { transform-box: fill-box; transform-origin: center; transform: scale(0); transition: transform .6s var(--spring); transition-delay: calc(.45s + var(--k, 0) * 80ms); }
.js .track.in .art :is(circle, rect) { transform: none; }
.js .track .art text { opacity: 0; transition: opacity .4s ease 1.1s; } .js .track.in .art text { opacity: 1; }
.js .track .topic-list li { opacity: 0; transform: translateY(10px); transition: opacity .4s, transform .5s var(--spring); transition-delay: calc(.3s + var(--k, 0) * 45ms); }
.js .track.in .topic-list li { opacity: 1; transform: none; }

/* ---- tiers & companions ---- */
.js .tier .lvl { opacity: 0; transform: translateX(-36px); transition: opacity .6s, transform .8s var(--spring); }
.js .tier.in .lvl { opacity: 1; transform: none; }
.js .tier ul li { opacity: 0; transform: translateX(14px); transition: opacity .4s, transform .5s var(--spring); transition-delay: calc(.25s + var(--k, 0) * 80ms); }
.js .tier.in ul li { opacity: 1; transform: none; }
.pets[data-reveal] { opacity: 1 !important; transform: none !important; }
.js .pets .pet { opacity: 0; transform: translateY(46px) scale(.78) rotate(-4deg); }
.js .pets.in .pet { opacity: 1; transform: none; transition: opacity .5s, transform .9s var(--spring); transition-delay: calc(var(--k, 0) * 130ms); }
/* calm mode */
html[data-motion="calm"] .js .track .art [pathLength], html[data-motion="calm"] .js .track .art :is(circle, html[data-motion="calm"] rect), html[data-motion="calm"] .js .track .art text, html[data-motion="calm"] .js .track .topic-list li, html[data-motion="calm"] .js .tier .lvl, html[data-motion="calm"] .js .tier ul li, html[data-motion="calm"] .js .pets .pet, html[data-motion="calm"] .js .words .w > span { opacity: 1; transform: none; stroke-dashoffset: 0; transition: none; }

/* ---- click zap: an angular diamond, never a circle ---- */
.zap { position: fixed; width: 26px; height: 26px; margin: -13px 0 0 -13px; border: 3px solid var(--zc, var(--green)); pointer-events: none; z-index: 200; transform: rotate(45deg) scale(.3); opacity: 1; animation: zap .5s cubic-bezier(.2,.7,.2,1) forwards; border-radius: 4px; }
@keyframes zap { to { transform: rotate(135deg) scale(2.2); opacity: 0; } }

/* ---- hero buddy ---- */
.buddy-row { display: flex; align-items: flex-end; gap: var(--s3); max-width: 28em; }
#buddy { width: 64px; flex: none; transition: transform .2s; }
#buddy svg { width: 100%; height: auto; overflow: visible; }
#buddy.hop { animation: hop .55s var(--spring); }
@keyframes hop { 30% { transform: translateY(-16px) rotate(-6deg); } 60% { transform: translateY(0) rotate(3deg); } }
#buddy[data-mood="oops"] { filter: saturate(.8); }
.bubble-say { position: relative; background: var(--surface); padding: 10px 14px; border-radius: 14px 14px 14px 4px; font-size: .92rem; line-height: 1.4; color: var(--ink-2); min-height: 3.2em; box-shadow: 0 6px 18px -12px var(--shadow); }
.bubble-say.pop { animation: say .4s var(--spring); }
@keyframes say { from { transform: scale(.94); opacity: .4; } }
.stage-ui { align-items: flex-end; }
/* calm mode */
html[data-motion="calm"] #buddy.hop, html[data-motion="calm"] .bubble-say.pop, html[data-motion="calm"] .zap { animation: none; }

/* ---- journey preview ---- */
.jtabs { display: flex; flex-wrap: wrap; gap: var(--s3) var(--s5); margin-bottom: var(--s5); align-items: center; }
.jseg { display: inline-flex; background: var(--surface-2); border-radius: var(--r-pill); padding: 4px; gap: 4px; }
.jseg button { border: 0; background: transparent; padding: 9px 18px; border-radius: var(--r-pill); font-weight: 600; color: var(--ink-2); cursor: pointer; }
.jseg button[aria-pressed="true"] { background: var(--ink); color: var(--bg); }
.jmap { position: relative; margin-inline: calc(-1 * var(--s4)); }
.jmap svg { width: 100%; height: auto; overflow: visible; }
.jtrack { fill: none; stroke: var(--line); stroke-width: 14; stroke-linecap: round; }
.jtrack-on { fill: none; stroke: var(--green); stroke-width: 14; stroke-linecap: round; }
.jnode .hex { fill: var(--surface-2); stroke: var(--ink-3); stroke-width: 3; transform-box: fill-box; transform-origin: center; transition: fill .4s, stroke .4s, transform .6s var(--spring); }
.jnode.lit .hex { fill: var(--zc); stroke: var(--ink); transform: scale(1.12); }
.jnode .num { font: 700 20px var(--f-display); fill: var(--ink-3); text-anchor: middle; dominant-baseline: central; transition: fill .3s; } .jnode.lit .num { fill: #1E2230; }
.jnode .lbl { font: 600 15px var(--f-ui); fill: var(--ink-2); text-anchor: middle; }
.jnode .stars { opacity: 0; transform: translateY(6px); transition: opacity .4s .2s, transform .6s var(--spring) .2s; } .jnode.lit .stars { opacity: 1; transform: none; }
.jrider { transition: none; }
.jrider svg { overflow: visible; }
.jfacts { margin-top: var(--s5); font: 500 .95rem/1.7 var(--f-mono); color: var(--ink-2); }
.jfacts b { color: var(--ink); }
@media (max-width: 700px) { .jnode .lbl { font-size: 19px; } }

/* ---- trap game ---- */
.traps { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--s6); align-items: start; }
.trap-tabs { display: grid; gap: 6px; }
.trap-tabs button { text-align: left; border: 0; background: transparent; padding: 14px 16px; border-radius: var(--r-m); cursor: pointer; font: 600 1rem/1.3 var(--f-ui); color: var(--ink-2); display: grid; gap: 4px; transition: background .2s, transform .2s var(--spring); }
.trap-tabs button small { font: 500 .78rem/1.3 var(--f-mono); color: var(--ink-3); }
.trap-tabs button:hover { background: var(--surface-2); transform: translateX(4px); }
.trap-tabs button[aria-selected="true"] { background: var(--ink); color: var(--bg); } .trap-tabs button[aria-selected="true"] small { color: var(--bg); opacity: .75; }
.trap-tabs button.done::after { content: "answered"; font: 600 .68rem/1 var(--f-mono); letter-spacing: .08em; text-transform: uppercase; color: var(--green-ink); }
.trap-tabs button[aria-selected="true"].done::after { color: var(--green); }
.trap-panel { background: var(--surface); border-radius: var(--r-l); overflow: hidden; box-shadow: 0 18px 40px -26px var(--shadow); }
.trap-panel .q { padding: var(--s5) var(--s5) var(--s3); font: 600 1.15rem/1.3 var(--f-display); }
.trap-panel pre { margin: 0; background: #151823; color: #E9E7DD; font: 400 .95rem/1.7 var(--f-mono); padding: var(--s4) var(--s5); overflow-x: auto; }
.trap-panel pre .kw { color: #B9A1F5; } .trap-panel pre .fn { color: #74C9F3; } .trap-panel pre .st { color: #8EDB72; } .trap-panel pre .nm { color: #FFD56E; }
.trap-opts { display: grid; gap: var(--s2); padding: var(--s4) var(--s5); }
.trap-opts button { text-align: left; border: 2px solid var(--line); background: transparent; border-radius: var(--r-m); padding: 12px 16px; font: 500 1rem/1.4 var(--f-mono); cursor: pointer; transition: transform .2s var(--spring), border-color .2s, background .2s; }
.trap-opts button:hover:not([disabled]) { transform: translateY(-2px); border-color: var(--ink-3); }
.trap-opts button.right { border-color: var(--green-ink); background: color-mix(in srgb, var(--green) 28%, var(--surface)); }
.trap-opts button.wrong { border-color: var(--coral-ink); background: color-mix(in srgb, var(--coral) 24%, var(--surface)); }
.trap-fb { padding: 0 var(--s5) var(--s5); min-height: 4.5em; color: var(--ink-2); }
.trap-fb b { color: var(--ink); } .trap-fb .where { display: block; margin-top: var(--s3); font: 600 .78rem/1.3 var(--f-mono); letter-spacing: .06em; text-transform: uppercase; color: var(--ink-3); }
@media (max-width: 900px) { .traps { grid-template-columns: 1fr; } .trap-tabs { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); } }

/* phones: keep the journey map at a readable size and let it scroll sideways */
@media (max-width: 700px) { .jmap { overflow-x: auto; margin-inline: 0; padding-bottom: var(--s3); } .jmap svg { min-width: 700px; } }

/* ---- scroll progress bar ---- */
#progress { position: fixed; left: 0; top: 0; height: 4px; width: 100%; z-index: 120; transform-origin: 0 50%; transform: scaleX(0); background: linear-gradient(90deg, var(--green), var(--blue), var(--lilac), var(--coral), var(--yellow)); pointer-events: none; }

/* ---- motion switch + notice ---- */
.motion-btn[aria-pressed="false"] { opacity: .55; }
.motion-note { position: fixed; left: 50%; bottom: 20px; transform: translateX(-50%); z-index: 150; width: min(560px, calc(100% - 32px)); background: var(--ink); color: var(--bg); border-radius: var(--r-l); padding: 16px 18px; display: grid; gap: 12px; box-shadow: 0 18px 40px -16px var(--shadow); font-size: .95rem; }
.motion-note .row { display: flex; flex-wrap: wrap; gap: 8px; }
.motion-note button { border: 0; border-radius: 999px; padding: 10px 16px; font: 600 .9rem var(--f-ui); cursor: pointer; background: var(--green); color: #1E2230; }
.motion-note button.alt { background: transparent; color: var(--bg); box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--bg) 40%, transparent); }
@media (max-width: 520px) { .jseg { max-width: 100%; } .jseg button { padding: 9px 12px; font-size: .9rem; flex: 1 1 auto; } }
