/* Toots's Pattern Train — game styles. GameKit tokens loaded first. */

:root {
    --pt-sky-top: #BFE3F7;
    --pt-sky-bot: #FBF3DC;
    --pt-ink: #2E4668;
    --pt-wood: #C98F5A;
    --pt-wood-dark: #8A5A32;
    --pt-cream: #FFF8F0;
}

html, body { overflow: hidden; }
body { background: var(--pt-sky-top); }

.screen {
    position: fixed;
    inset: 0;
    z-index: 10;
    display: flex;
    flex-direction: column;
}

/* ═══════════ Backdrop — Garden Street station ═══════════ */

#backdrop { position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none; }

.bk-sky { position: absolute; inset: 0; background: linear-gradient(to bottom, var(--pt-sky-top), #E4F0F7 50%, var(--pt-sky-bot)); }
.bk-cloud {
    position: absolute; width: 150px; height: 44px;
    background: #fff; border-radius: 44px; opacity: .9;
    animation: pt-drift linear infinite;
}
.bk-cloud::before, .bk-cloud::after { content: ''; position: absolute; background: #fff; border-radius: 50%; }
.bk-cloud::before { width: 62px; height: 62px; left: 22px; top: -30px; }
.bk-cloud::after  { width: 44px; height: 44px; right: 26px; top: -20px; }
.bc1 { top: 7%; animation-duration: 110s; animation-delay: -40s; }
.bc2 { top: 16%; transform: scale(1.2); animation-duration: 150s; animation-delay: -95s; opacity: .7; }
@keyframes pt-drift { from { left: -220px; } to { left: 105vw; } }

.bk-hills { position: absolute; left: 0; right: 0; bottom: 24%; height: 32%; }
.bk-hills svg { width: 100%; height: 100%; display: block; }
.bk-station { position: absolute; left: 4%; bottom: 34%; width: clamp(190px, 22vw, 300px); }
.bk-station svg { width: 100%; display: block; }
.bk-lamp { position: absolute; bottom: 35%; width: clamp(26px, 3vw, 40px); }
.bl1 { left: 30%; } .bl2 { right: 6%; }
.bk-lamp svg { width: 100%; display: block; }
.bk-bird { position: absolute; width: 44px; animation: pt-fly linear infinite; }
.bb1 { top: 12%; animation-duration: 55s; animation-delay: -20s; }
.bk-bird svg { width: 100%; }
.bird-wing { transform-box: fill-box; transform-origin: 60% 80%; animation: pt-flap 0.6s ease-in-out infinite alternate; }
@keyframes pt-fly { from { left: -60px; } to { left: 108vw; } }
@keyframes pt-flap { from { transform: rotate(0); } to { transform: rotate(-34deg); } }

@media (prefers-reduced-motion: reduce) {
    /* Nothing may MOVE while the child is idle. Verified by pixel-diffing five
       idle frames under reduce: this page changed on every one. Snap each
       animation to its final keyframe (iteration-count:1 + ~0 duration) rather
       than `animation:none`, because several entry animations fill `both`/
       `forwards` and their last frame is the state the art is supposed to hold —
       removing the animation outright would leave those elements mid-nothing.
       Every keyframe set on this page ends on its own rest pose, so this stops
       the motion without losing a single piece of art. */
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        /* and no stagger: these delays are set inline by the art code (up to 5s
           on lost-star's cover). An animation counts as running for the whole
           delay, so without this each one snapped to its end frame seconds
           after load, one at a time — the page kept twitching long after the
           child arrived. Zeroed, everything is settled by first paint. */
        animation-delay: 0s !important;
        transition-duration: 0.01ms !important;
    }
    .bk-cloud, .bk-bird { animation: none !important; }
}

/* ═══════════ Title ═══════════ */

#screen-title { align-items: center; justify-content: center; gap: 8px; padding: 16px; }

.game-title {
    font-size: clamp(2.3rem, 6.6vw, 4rem);
    line-height: 1.02;
    text-align: center;
    color: var(--pt-ink);
    text-shadow: 0 3px 0 #fff, 0 6px 14px rgba(46, 70, 104, .3);
    margin: 0;
}
.tagline {
    margin: 6px 0 0;
    font-size: clamp(1rem, 2.4vw, 1.3rem);
    color: #4E6488;
    font-weight: 700;
    text-align: center;
}
.t-row { display: flex; align-items: flex-end; gap: 4px; }
.t-toots { width: clamp(130px, 21vh, 200px); }
.toots-svg { width: 100%; display: block; overflow: visible; }
#title-toots .toots-svg { animation: pt-bob 3s ease-in-out infinite; }
@keyframes pt-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-9px); } }
.t-train { width: clamp(120px, 18vh, 180px); }
.t-train svg { width: 100%; display: block; }
.eng-puff { animation: pt-puffidle 2.4s ease-out infinite; transform-box: fill-box; transform-origin: 50% 100%; }
@keyframes pt-puffidle {
    0% { opacity: 0; transform: translateY(6px) scale(.5); }
    30% { opacity: .9; }
    100% { opacity: 0; transform: translateY(-26px) scale(1.5); }
}

.start-btn {
    font-family: inherit;
    font-size: clamp(1.5rem, 4vw, 2.1rem);
    font-weight: 900;
    padding: 18px 54px;
    border: none;
    border-radius: 60px;
    color: #fff;
    background: linear-gradient(180deg, #EF4560, #C9243E);
    box-shadow: 0 8px 0 #8E1A2E, 0 14px 26px rgba(142, 26, 46, .35);
    cursor: pointer;
    margin-top: 8px;
}
.start-btn:active { transform: translateY(6px); box-shadow: 0 2px 0 #8E1A2E; }
.btn-pulse { display: inline-block; animation: pt-pulse 1.6s ease-in-out infinite; }
@keyframes pt-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }

.title-row { display: flex; gap: 14px; align-items: center; margin-top: 12px; }
.star-pill, .album-btn {
    font-family: inherit;
    font-size: 1.15rem;
    font-weight: 800;
    color: var(--pt-ink);
    background: rgba(255, 255, 255, .88);
    border: 3px solid #3F5E8C;
    border-radius: 40px;
    padding: 10px 20px;
    min-height: 52px;
    display: flex;
    align-items: center;
    gap: 6px;
}
.album-btn { cursor: pointer; }
.album-btn:active { transform: scale(.95); }

#level-row { display: flex; gap: 16px; margin-top: 14px; }
.lvl-btn {
    position: relative;
    font-family: inherit;
    /* Cap at a third of the usable width: the 106px clamp floor x3 plus gaps came to
       350px, so on a 320px phone the centred row pushed levels 1 and 3 past both
       edges of a screen that cannot scroll (.screen is fixed/inset:0 over
       overflow:hidden), making them untappable. */
    width: min(clamp(106px, 13vw, 136px), calc((100vw - 56px) / 3));
    padding: 12px 8px 10px;
    border: none;
    border-radius: 22px;
    background: rgba(255, 255, 255, .92);
    box-shadow: 0 5px 0 rgba(46, 70, 104, .3), 0 10px 18px rgba(46, 70, 104, .16);
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}
.lvl-btn:active { transform: translateY(4px); box-shadow: 0 1px 0 rgba(46, 70, 104, .3); }
.lvl-num {
    font-size: 1.5rem; font-weight: 900; color: #fff;
    background: linear-gradient(180deg, #6F8FC9, #3F5E8C);
    width: 44px; height: 44px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
}
.lvl-name { font-size: .84rem; font-weight: 800; color: var(--pt-ink); }
.lvl-stars { font-size: .9rem; letter-spacing: 1px; }
.lvl-stars .dim { opacity: .25; filter: grayscale(1); }
.lvl-lock { display: none; position: absolute; top: -10px; right: -6px; font-size: 1.5rem; }
.lvl-btn.locked { opacity: .68; filter: saturate(.5); }
.lvl-btn.locked .lvl-lock { display: block; }
.lvl-btn.shake { animation: pt-shake .45s ease-in-out; }
.lvl-btn.just-unlocked { animation: pt-unlock 1s ease-in-out; }
@keyframes pt-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-7px); } 75% { transform: translateX(7px); } }
@keyframes pt-unlock { 40% { transform: scale(1.16) rotate(-3deg); } 70% { transform: scale(1.08) rotate(2deg); } }

.info-btn {
    position: absolute;
    bottom: 14px;
    left: 14px;
    width: 52px;
    height: 52px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, .85);
    font-size: 1.4rem;
    cursor: pointer;
    box-shadow: 0 3px 8px rgba(46, 70, 104, .25);
    z-index: 40;
}
.info-btn:active { transform: scale(.92); }

/* ═══════════ Play ═══════════ */

#play-top {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 12px 14px 0;
    min-height: 60px;
}
#tracker {
    display: flex;
    gap: 4px;
    background: rgba(255, 255, 255, .82);
    border: 3px solid rgba(63, 94, 140, .5);
    border-radius: 40px;
    padding: 6px 14px;
    font-size: clamp(1.2rem, 2.6vw, 1.7rem);
}
.trk-train { opacity: .3; filter: grayscale(1); }
.trk-train.done { opacity: 1; filter: none; animation: pt-jump .6s cubic-bezier(.5,1.6,.5,1); }
@keyframes pt-jump { 0% { transform: scale(.4); } 60% { transform: scale(1.4); } 100% { transform: scale(1); } }

/* track area */
#track-zone {
    position: relative;
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: flex-end;
    overflow: hidden;
}
#rails {
    position: absolute;
    left: 0; right: 0;
    bottom: clamp(20px, 5vh, 44px);
    height: 14px;
    background:
        linear-gradient(#8A5A32, #8A5A32) 0 0 / 100% 4px no-repeat,
        linear-gradient(#8A5A32, #8A5A32) 0 10px / 100% 4px no-repeat,
        repeating-linear-gradient(90deg, #B98146 0 12px, transparent 12px 42px) 0 -6px / 100% 26px no-repeat;
}
#train {
    position: relative;
    max-width: 100%;
    display: flex;
    align-items: flex-end;
    gap: 2px;
    padding-left: 3vw;
    margin-bottom: clamp(24px, 5.4vh, 50px);
    transform: translateX(-120%);
    cursor: pointer;
}
#train.arrived { transform: translateX(0); transition: transform 1.1s cubic-bezier(.2, .8, .3, 1); }
#train.depart { transform: translateX(120vw) !important; transition: transform 1.6s cubic-bezier(.6, 0, .8, .4); }

/* The train laid out at a fixed 512-515px whatever the screen: below about 700px
   wide the vw term is smaller than the 66px floor, so the cars stopped scaling and
   the train simply ran off the right edge — measured +192px at 320, +121px at 393,
   with document.scrollWidth equal to the viewport, so it was clipped and not
   scrollable. The engine and conductor vanished, and on the narrowest phones the
   .car-q gap card — the one thing the child has to look at to answer — was cut too.
   Level 3 runs 8 cars, so it overflowed harder still.

   Cars may now shrink to fit (min-width:0 + flex-shrink), floored at a size where a
   plum is still tellable from an orange rather than at the old desktop width. */
.train-car {
    position: relative;
    width: clamp(66px, 9.4vw, 120px);
    flex: 0 1 auto;
    min-width: 0;
}
.car-svg { width: 100%; display: block; }
.train-engine { width: clamp(92px, 12.6vw, 160px); margin-left: 2px; flex: 0 1 auto; min-width: 0; }
.engine-svg { width: 100%; display: block; overflow: visible; }
.train-car.bounce { animation: pt-carbounce .34s ease-out; transform-origin: 50% 100%; }
@keyframes pt-carbounce {
    35% { transform: translateY(-13px) scale(1.05, .95); }
    75% { transform: translateY(0) scale(.98, 1.04); }
}
.car-cargo {
    position: absolute;
    left: 18%; right: 18%;
    top: 6%;
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Letting the cars shrink stopped the train being clipped, but on the narrowest
   phones a level-3 train (8 cars) lands at ~31px per car, which put the cargo at
   20px — and the whole task is telling one fruit from another. The crate walls are
   the least useful pixels there, so the cargo claims more of the car as it gets
   smaller: 64% of the car normally, up to 84% on a narrow screen. */
@media (max-width: 430px) {
    .car-cargo { left: 8%; right: 8%; top: 4%; }
}
.car-cargo .item-svg { width: 100%; height: 100%; filter: drop-shadow(0 3px 3px rgba(60, 40, 20, .3)); }
.car-cargo.empty {
    border: 3.5px dashed rgba(63, 94, 140, .65);
    border-radius: 14px;
    background: rgba(255, 255, 255, .4);
}
.car-q {
    font-size: clamp(1.6rem, 3.4vw, 2.4rem);
    font-weight: 900;
    color: #3F5E8C;
    animation: pt-pulse 1.2s ease-in-out infinite;
}

/* Toots at the platform */
#toots-side {
    position: absolute;
    right: 2%;
    bottom: clamp(20px, 5vh, 44px);
    width: clamp(86px, 11vw, 150px);
    z-index: 3;
    pointer-events: none;
}
#toots-side .tt-trunk { transform-box: fill-box; transform-origin: 78% 8%; transition: transform .3s; }
#toots-side.toot .tt-trunk { transform: rotate(74deg); }
#toots-side.toot .tt-toot { opacity: 1; transition: opacity .2s .25s; }
#toots-side.happy .tt-all { animation: pt-carbounce .5s ease-in-out 2; transform-box: fill-box; transform-origin: 50% 100%; }
#toots-side.curious .tt-all { animation: pt-tilt 1.2s ease-in-out; transform-box: fill-box; transform-origin: 50% 90%; }
@keyframes pt-tilt { 30%, 70% { transform: rotate(5deg); } }
.tt-ear-l { transform-box: fill-box; transform-origin: 90% 50%; animation: pt-earflap 4s ease-in-out infinite; }
.tt-ear-r { transform-box: fill-box; transform-origin: 10% 50%; animation: pt-earflap 4s ease-in-out 2s infinite; }
@keyframes pt-earflap { 0%, 84%, 100% { transform: rotate(0); } 92% { transform: rotate(-7deg); } }

/* signal lever */
#lever {
    position: absolute;
    left: 2.5%;
    bottom: clamp(20px, 5vh, 44px);
    width: clamp(74px, 8.5vw, 110px);
    border: none;
    background: none;
    cursor: pointer;
    z-index: 5;
    -webkit-tap-highlight-color: transparent;
}
.lever-svg { width: 100%; display: block; overflow: visible; }
.lever-arm { transform-box: fill-box; transform-origin: 50% 96%; transition: transform .3s cubic-bezier(.3, 1.4, .5, 1); }
#lever.pulled .lever-arm { transform: rotate(58deg); }
#lever.glowing { animation: pt-leverglow 1s ease-in-out infinite; }
@keyframes pt-leverglow {
    0%, 100% { filter: drop-shadow(0 0 0 rgba(252, 191, 73, 0)); transform: scale(1); }
    50% { filter: drop-shadow(0 0 18px rgba(252, 191, 73, .95)); transform: scale(1.07); }
}

/* crate tray */
#crate-tray {
    padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
    background: linear-gradient(180deg, var(--pt-wood), var(--pt-wood-dark));
    border-top: 5px solid #6E4626;
    z-index: 20;
    min-height: clamp(104px, 16vh, 140px);
}
#crate-rack { display: flex; justify-content: center; gap: clamp(14px, 3.4vw, 30px); }
.crate-btn {
    width: clamp(92px, 13vw, 124px);
    height: clamp(84px, 13vh, 108px);
    border: none;
    border-radius: 16px;
    background:
        linear-gradient(rgba(255,255,255,.16), rgba(0,0,0,.06)),
        repeating-linear-gradient(0deg, #E2B27E 0 14px, #D9A870 14px 28px);
    box-shadow: inset 0 0 0 4px #8A5A32, 0 6px 0 #6E4626, 0 10px 16px rgba(60, 35, 10, .35);
    cursor: pointer;
    padding: 8px;
    transition: transform .12s;
}
.crate-btn:active:not(:disabled) { transform: translateY(5px); box-shadow: inset 0 0 0 4px #8A5A32, 0 1px 0 #6E4626; }
.crate-btn .item-svg { width: 78%; height: auto; margin: 0 auto; display: block; }
.crate-btn.shake { animation: pt-shake .45s ease-in-out; }
.crate-btn.glow { animation: pt-crateglow 1s ease-in-out infinite; }
@keyframes pt-crateglow {
    0%, 100% { box-shadow: inset 0 0 0 4px #8A5A32, 0 6px 0 #6E4626, 0 0 0 0 rgba(252, 191, 73, 0); }
    50% { box-shadow: inset 0 0 0 4px #8A5A32, 0 6px 0 #6E4626, 0 0 0 10px rgba(252, 191, 73, .55); transform: scale(1.05); }
}

.fly-crate { position: fixed; z-index: 70; width: 60px; height: 60px; pointer-events: none; }
.fly-crate .item-svg { width: 100%; height: 100%; }

.steam-puff {
    position: fixed;
    width: 26px; height: 26px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .95);
    pointer-events: none;
    z-index: 30;
    animation: pt-steam .85s ease-out forwards;
}
@keyframes pt-steam {
    from { transform: translate(0, 0) scale(.5); opacity: .95; }
    to   { transform: translate(-34px, -60px) scale(1.9); opacity: 0; }
}

/* ═══════════ Overlays ═══════════ */

.overlay {
    position: fixed;
    inset: 0;
    z-index: 90;
    background: rgba(30, 44, 70, .5);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 18px;
}
.overlay-card {
    position: relative;
    max-width: 560px;
    width: 100%;
    max-height: 86vh;
    overflow-y: auto;
    padding: 26px 26px 22px;
}
.overlay-card h3 { margin: 0 0 12px; font-size: 1.5rem; color: var(--pt-ink); }
.overlay-card p { line-height: 1.55; color: #46527A; margin: 0 0 12px; }
.close-btn {
    position: absolute;
    top: 10px; right: 10px;
    width: 48px; height: 48px;
    border: none;
    border-radius: 50%;
    background: #E2EAF5;
    font-size: 1.2rem;
    font-weight: 800;
    color: var(--pt-ink);
    cursor: pointer;
}
.close-btn:active { transform: scale(.92); }

#stamp-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.stamp-cell { background: #F2F6FB; border-radius: 16px; padding: 10px 6px 8px; text-align: center; }
.stamp-cell svg { width: 74%; max-width: 96px; }
.stamp-cell.dim svg { filter: grayscale(1) brightness(.8); opacity: .5; }
.stamp-name { font-size: .82rem; font-weight: 800; color: var(--pt-ink); margin-top: 4px; }

.tip-row { display: flex; gap: 12px; align-items: flex-start; background: #F2F6FB; border-radius: 14px; padding: 12px; }
.tip-icons { font-size: 1.6rem; }
.tip-row p { margin: 0; font-size: .95rem; }

@media (max-width: 880px) {
    .bk-station { display: none; }
    #toots-side { width: clamp(70px, 10vw, 110px); }
}
@media (max-height: 720px) {
    .t-toots { width: clamp(110px, 17vh, 160px); }
}

/* ── The progress trains must clear the HUD ────────────────────────────────
   #tracker is the only thing in #play-top and it is left-aligned, but with four
   🚂 markers the pill runs to 156px and a 320px phone only has 120px to the left
   of the HUD — so the fourth marker, the one that says "nearly there", sat behind
   the home button. Nothing here fits beside a 188px HUD in a 320px viewport, so
   the row drops below the HUD band. From 360px up the pill clears the HUD on its
   own. Clearance is the shared token — see gamekit.css, not a number. */
@media (max-width: 360px) {
    #play-top { padding-top: var(--gk-hud-clear-top); }
}
