/*
 * MathSheets "modern playful" look: chunky 3D buttons, pop cards, a soft
 * dotted page background and floating shapes. Plain CSS (no Tailwind
 * directives) so it works with both the Tailwind CDN (local) and the compiled
 * public/css/app.css (production). Colours match resources/tailwind-theme.json.
 */

:root {
    --brand: #5B3FE0;
    --brand-deep: #3F28B5;
    --brand-dark: #241A5C;
    --brand-tint: #F2EEFF;
    --accent: #E31890;
    --accent-deep: #9D0F5E;
    --sun: #FFC53D;
    --sun-deep: #D99A00;
    --mint: #22C997;
    --mint-deep: #0E8F69;
    --sky: #36AEF5;
    --sky-deep: #0B78B8;
    --coral: #FF7B54;
    --coral-deep: #D24A22;
    --ink: #1D1740;
}

/* Page background: soft lilac with a faint dot grid. */
.app-bg {
    background-color: #FBF9FF;
    background-image: radial-gradient(#E6E0FF 1.2px, transparent 1.2px);
    background-size: 24px 24px;
}

h1, h2, h3, .font-display, .font-playful {
    letter-spacing: -0.01em;
}

/* Page titles in the header band: bold, in the brand's dark purple. */
header h1, header h2 {
    font-weight: 700;
    color: var(--brand-dark);
}

/* ---- Chunky 3D buttons ------------------------------------------------ */

.btn-pop {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    font-family: Fredoka, sans-serif;
    font-weight: 600;
    border-radius: 1rem;
    padding: .8rem 1.5rem;
    color: #fff;
    background: var(--brand);
    box-shadow: 0 5px 0 var(--brand-deep);
    transition: transform .1s ease, box-shadow .1s ease, filter .15s ease;
    text-decoration: none;
    border: 0;
    cursor: pointer;
}
.btn-pop:hover { filter: brightness(1.06); transform: translateY(-1px); box-shadow: 0 6px 0 var(--brand-deep); }
.btn-pop:active { transform: translateY(4px); box-shadow: 0 1px 0 var(--brand-deep); }
.btn-pop.is-accent { background: var(--accent); box-shadow: 0 5px 0 var(--accent-deep); }
.btn-pop.is-accent:hover { box-shadow: 0 6px 0 var(--accent-deep); }
.btn-pop.is-accent:active { box-shadow: 0 1px 0 var(--accent-deep); }
.btn-pop.is-sun { background: var(--sun); color: var(--ink); box-shadow: 0 5px 0 var(--sun-deep); }
.btn-pop.is-sun:hover { box-shadow: 0 6px 0 var(--sun-deep); }
.btn-pop.is-sun:active { box-shadow: 0 1px 0 var(--sun-deep); }
.btn-pop.is-white { background: #fff; color: var(--brand-dark); box-shadow: 0 5px 0 #D9D2F7; border: 2px solid #E9E4FB; }
.btn-pop.is-white:hover { box-shadow: 0 6px 0 #D9D2F7; }
.btn-pop.is-white:active { box-shadow: 0 1px 0 #D9D2F7; }
.btn-pop.is-lg { font-size: 1.15rem; padding: 1rem 1.9rem; border-radius: 1.15rem; }

/* Every existing gradient / pink action button on the site gets the same press effect. */
a.from-brand.to-grad, button.from-brand.to-grad {
    box-shadow: 0 4px 0 var(--brand-deep);
    transition: transform .1s ease, box-shadow .1s ease, filter .15s ease;
}
a.from-brand.to-grad:hover, button.from-brand.to-grad:hover:not(:disabled) { filter: brightness(1.06); }
a.from-brand.to-grad:active, button.from-brand.to-grad:active:not(:disabled) { transform: translateY(3px); box-shadow: 0 1px 0 var(--brand-deep); }
a.bg-accent, button.bg-accent {
    box-shadow: 0 4px 0 var(--accent-deep);
    transition: transform .1s ease, box-shadow .1s ease;
}
a.bg-accent:active, button.bg-accent:active { transform: translateY(3px); box-shadow: 0 1px 0 var(--accent-deep); }

/* ---- Pop cards ----------------------------------------------------------- */

.card-pop {
    background: #fff;
    border: 2px solid #ECE7FD;
    border-radius: 1.5rem;
    box-shadow: 0 4px 0 #E4DDFB;
    transition: transform .15s ease, box-shadow .15s ease, border-color .15s ease;
}
a.card-pop:hover, .card-pop.is-hover:hover {
    transform: translateY(-3px);
    border-color: #D4CAFA;
    box-shadow: 0 7px 0 #D4CAFA;
}

/* A coloured "sticker" tile: set --tile and --tile-deep inline. */
.tile-pop {
    border-radius: 1.5rem;
    background: var(--tile, var(--brand));
    box-shadow: 0 6px 0 var(--tile-deep, var(--brand-deep));
    transition: transform .15s ease, box-shadow .15s ease;
    color: #fff;
}
a.tile-pop:hover { transform: translateY(-4px) rotate(-1deg); box-shadow: 0 10px 0 var(--tile-deep, var(--brand-deep)); }
a.tile-pop:active { transform: translateY(3px); box-shadow: 0 2px 0 var(--tile-deep, var(--brand-deep)); }

/* Hand-drawn underline under a highlighted word. */
.squiggle {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 120 12'%3E%3Cpath d='M2 8 Q 15 2 30 7 T 60 7 T 90 7 T 118 6' fill='none' stroke='%23FFC53D' stroke-width='5' stroke-linecap='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: 0 100%;
    background-size: 100% .38em;
    padding-bottom: .12em;
}

/* ---- 3D look ------------------------------------------------------------- */

/* Deeper, glossy buttons: a light top edge and a thick coloured base. */
.btn-pop {
    background-image: linear-gradient(180deg, rgba(255,255,255,.22) 0%, rgba(255,255,255,0) 55%);
    box-shadow: 0 6px 0 var(--brand-deep), 0 10px 18px -6px rgba(63,40,181,.45), inset 0 2px 0 rgba(255,255,255,.35);
}
.btn-pop:hover { box-shadow: 0 7px 0 var(--brand-deep), 0 14px 22px -8px rgba(63,40,181,.5), inset 0 2px 0 rgba(255,255,255,.35); }
.btn-pop:active { transform: translateY(5px); box-shadow: 0 1px 0 var(--brand-deep), 0 4px 8px -4px rgba(63,40,181,.4), inset 0 2px 0 rgba(255,255,255,.25); }
.btn-pop.is-accent { box-shadow: 0 6px 0 var(--accent-deep), 0 10px 18px -6px rgba(157,15,94,.45), inset 0 2px 0 rgba(255,255,255,.35); }
.btn-pop.is-accent:hover { box-shadow: 0 7px 0 var(--accent-deep), 0 14px 22px -8px rgba(157,15,94,.5), inset 0 2px 0 rgba(255,255,255,.35); }
.btn-pop.is-accent:active { box-shadow: 0 1px 0 var(--accent-deep), inset 0 2px 0 rgba(255,255,255,.25); }
.btn-pop.is-sun { box-shadow: 0 6px 0 var(--sun-deep), 0 10px 18px -6px rgba(217,154,0,.5), inset 0 2px 0 rgba(255,255,255,.5); }
.btn-pop.is-sun:hover { box-shadow: 0 7px 0 var(--sun-deep), 0 14px 22px -8px rgba(217,154,0,.55), inset 0 2px 0 rgba(255,255,255,.5); }
.btn-pop.is-sun:active { box-shadow: 0 1px 0 var(--sun-deep), inset 0 2px 0 rgba(255,255,255,.4); }
.btn-pop.is-white { background-image: linear-gradient(180deg, #fff 0%, #F7F5FF 100%); box-shadow: 0 6px 0 #D9D2F7, 0 10px 18px -8px rgba(63,40,181,.25); }
.btn-pop.is-white:hover { box-shadow: 0 7px 0 #D9D2F7, 0 14px 22px -8px rgba(63,40,181,.3); }
.btn-pop.is-white:active { box-shadow: 0 1px 0 #D9D2F7; }

/* Clay cards: soft raised surfaces with a light top edge and a long soft shadow. */
.card-pop {
    box-shadow: 0 5px 0 #E4DDFB, 0 18px 30px -18px rgba(63,40,181,.35), inset 0 2px 0 #fff;
    background-image: linear-gradient(180deg, #fff 0%, #FCFBFF 100%);
}
a.card-pop:hover, .card-pop.is-hover:hover {
    box-shadow: 0 8px 0 #D4CAFA, 0 26px 36px -18px rgba(63,40,181,.45), inset 0 2px 0 #fff;
}

/* Extruded tiles: a thick block edge, a gloss highlight and a deep soft shadow. */
.tile-pop {
    position: relative;
    background-image: linear-gradient(160deg, rgba(255,255,255,.28) 0%, rgba(255,255,255,0) 45%);
    box-shadow:
        0 3px 0 var(--tile-deep, var(--brand-deep)),
        0 6px 0 var(--tile-deep, var(--brand-deep)),
        0 9px 0 var(--tile-deep, var(--brand-deep)),
        0 22px 28px -10px rgba(29,23,64,.35),
        inset 0 3px 0 rgba(255,255,255,.35);
}
a.tile-pop:hover {
    box-shadow:
        0 3px 0 var(--tile-deep, var(--brand-deep)),
        0 7px 0 var(--tile-deep, var(--brand-deep)),
        0 12px 0 var(--tile-deep, var(--brand-deep)),
        0 30px 34px -12px rgba(29,23,64,.4),
        inset 0 3px 0 rgba(255,255,255,.35);
}
a.tile-pop:active { transform: translateY(6px); box-shadow: 0 3px 0 var(--tile-deep, var(--brand-deep)), 0 8px 14px -6px rgba(29,23,64,.3); }

/* Pointer-follow 3D tilt (public/js/tilt.js sets --rx/--ry on [data-tilt]). */
[data-tilt] {
    transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift, 0px));
    transform-style: preserve-3d;
    transition: transform .25s ease, box-shadow .25s ease;
    will-change: transform;
}
[data-tilt].is-tilting { transition: transform .06s linear, box-shadow .25s ease; }
/* The tilt replaces the plain hover lift on tilting tiles and cards. */
a[data-tilt]:hover, a[data-tilt]:active {
    transform: perspective(900px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) translateY(var(--lift, -3px));
}
/* Children marked data-depth float above the surface while tilting. */
/* (`translate` combines with any rotate/animation transform instead of replacing it.) */
[data-tilt] [data-depth] { translate: 0 0 var(--depth, 30px); }

/* Real 3D icon images (Fluent Emoji, public/img/3d). */
.icon-3d {
    display: inline-block;
    filter: drop-shadow(0 8px 10px rgba(29,23,64,.25));
    user-select: none;
    -webkit-user-drag: none;
}

/* Glossy 3D spheres, rings and a spinning cube for decoration. */
.sphere {
    border-radius: 9999px;
    background: radial-gradient(circle at 32% 28%, #fff 0%, var(--c, var(--sun)) 26%, var(--c-deep, var(--sun-deep)) 78%, color-mix(in srgb, var(--c-deep, var(--sun-deep)) 70%, #000) 100%);
    box-shadow: 0 14px 22px -8px rgba(29,23,64,.35);
}
.ring-3d {
    border-radius: 9999px;
    border: 9px solid var(--c, var(--sky));
    box-shadow: inset 0 -4px 0 var(--c-deep, var(--sky-deep)), 0 4px 0 var(--c-deep, var(--sky-deep)), 0 14px 20px -8px rgba(29,23,64,.3);
}
.cube-3d {
    --s: 46px;
    width: var(--s);
    height: var(--s);
    position: relative;
    transform-style: preserve-3d;
    animation: ms-cube 14s linear infinite;
}
.cube-3d > span {
    position: absolute;
    inset: 0;
    border-radius: 10px;
    background: var(--c, var(--mint));
    border: 2px solid rgba(255,255,255,.45);
}
.cube-3d > span:nth-child(1) { transform: translateZ(calc(var(--s) / 2)); }
.cube-3d > span:nth-child(2) { transform: rotateY(180deg) translateZ(calc(var(--s) / 2)); filter: brightness(.8); }
.cube-3d > span:nth-child(3) { transform: rotateY(90deg) translateZ(calc(var(--s) / 2)); filter: brightness(.9); }
.cube-3d > span:nth-child(4) { transform: rotateY(-90deg) translateZ(calc(var(--s) / 2)); filter: brightness(.85); }
.cube-3d > span:nth-child(5) { transform: rotateX(90deg) translateZ(calc(var(--s) / 2)); filter: brightness(1.12); }
.cube-3d > span:nth-child(6) { transform: rotateX(-90deg) translateZ(calc(var(--s) / 2)); filter: brightness(.7); }
@keyframes ms-cube { from { transform: rotateX(-24deg) rotateY(0deg); } to { transform: rotateX(-24deg) rotateY(360deg); } }

/* ---- Floating decorative shapes ----------------------------------------- */

.float-a { animation: ms-float 6s ease-in-out infinite; }
.float-b { animation: ms-float 7.5s ease-in-out -2s infinite; }
.float-c { animation: ms-float 9s ease-in-out -4s infinite; }
.spin-slow { animation: ms-spin 18s linear infinite; }
.wobble { animation: ms-wobble 3.2s ease-in-out infinite; }

/* Decorations that circle the hero card on a tilted 3D orbit: in front of it
   along the bottom, behind it along the top. Must be a direct child of the
   [data-tilt] card wrapper. --a start angle, --t lap time, --tx/--tz tilt of
   the orbit plane, --k radius multiplier. The trailing rotations undo the
   plane's tilt so the object itself always faces the viewer. */
.orbit {
    --r: min(300px, 46vw);
    --a: 0deg;
    --tx: 64deg;
    --tz: 0deg;
    --k: 1;
    position: absolute;
    left: 50%;
    top: 50%;
    translate: -50% -50%;
    transform: rotateZ(var(--tz)) rotateX(var(--tx)) rotateZ(var(--a)) translateX(calc(var(--r) * var(--k))) rotateZ(calc(-1 * var(--a))) rotateX(calc(-1 * var(--tx))) rotateZ(calc(-1 * var(--tz)));
    animation: ms-orbit var(--t, 18s) linear infinite;
}
/* Phones have no room to circle the card: orbiting objects are hidden there
   and their .orbit-fallback stand-ins show instead. (Set here, not with
   Tailwind classes, which .icon-3d's display would override.) */
@media (max-width: 639.98px) { .orbit { display: none; } }
@media (min-width: 640px) { .orbit-fallback { display: none; } }
/* Beside the headline the orbit must stay clear of the text column. */
@media (min-width: 1024px) { .orbit { --r: min(275px, 25vw); } }
@keyframes ms-orbit {
    from { transform: rotateZ(var(--tz)) rotateX(var(--tx)) rotateZ(var(--a)) translateX(calc(var(--r) * var(--k))) rotateZ(calc(-1 * var(--a))) rotateX(calc(-1 * var(--tx))) rotateZ(calc(-1 * var(--tz))); }
    to { transform: rotateZ(var(--tz)) rotateX(var(--tx)) rotateZ(calc(var(--a) + 360deg)) translateX(calc(var(--r) * var(--k))) rotateZ(calc(-1 * var(--a) - 360deg)) rotateX(calc(-1 * var(--tx))) rotateZ(calc(-1 * var(--tz))); }
}

/* Mascot (components/mascot.blade.php): blinks, waves and its star twinkles. */
.mascot { height: auto; overflow: visible; }
.mascot-climber .mascot { display: block; }

/* Mascot walk (public/js/mascot-walk.js): on wide screens the walker climbs
   down the page from one [data-mascot-perch] to the next as it scrolls; the
   script sets its transform one step at a time and the transition here makes
   each step a little hop. Narrower screens show .mascot-static instead.
   (Display is set here, not with Tailwind classes, because this file loads
   after app.css and would override them.) */
.mascot-walker {
    display: none;
    visibility: hidden;
    position: absolute;
    left: 0;
    top: 0;
    width: 128px;
    z-index: 30;
    pointer-events: none;
    transform-origin: 50% 100%;
    will-change: transform;
}
.mascot-walker.is-ready { visibility: visible; transition: transform .22s cubic-bezier(.34, 1.4, .64, 1); }
@media (min-width: 1024px) {
    .mascot-walker { display: block; }
    .mascot-static { display: none; }
}
.mascot-eye { transform-box: fill-box; transform-origin: center; animation: ms-blink 5s infinite; }
.mascot-arm { transform-origin: 164px 128px; animation: ms-wave 1.6s ease-in-out infinite; }
.mascot-star { transform-box: fill-box; transform-origin: center; animation: ms-twinkle 3s ease-in-out infinite; }
@keyframes ms-blink {
    0%, 92%, 100% { transform: scaleY(1); }
    96% { transform: scaleY(.1); }
}
@keyframes ms-wave {
    0%, 100% { transform: rotate(-8deg); }
    50% { transform: rotate(14deg); }
}
@keyframes ms-twinkle {
    0%, 100% { transform: scale(1) rotate(0deg); }
    50% { transform: scale(1.2) rotate(14deg); }
}

/* Mascot moods: .is-happy / .is-sad on the mascot or any ancestor swap its arms and face. */
.mascot-if-happy, .mascot-if-sad, .mascot-if-eating, .mascot-if-laughing { display: none; }
.is-happy .mascot-if-happy, .is-sad .mascot-if-sad, .is-eating .mascot-if-eating, .is-laughing .mascot-if-laughing { display: inline; }
.is-happy .mascot-unless-happy, .is-sad .mascot-unless-sad, .is-eating .mascot-smile { display: none; }
.is-laughing .mascot-eye, .is-laughing .mascot-smile { display: none; }
.mascot.is-laughing, .is-laughing .mascot { transform-origin: 50% 100%; animation: ms-laugh .32s ease-in-out infinite; }
@keyframes ms-laugh {
    0%, 100% { transform: translateY(0) rotate(-2deg); }
    50% { transform: translateY(-6px) rotate(2deg); }
}
/* Turned around to climb: no face or belly, both hands up, reaching in turn. */
.mascot-if-back { display: none; }
.is-back .mascot-if-back, .is-back .mascot-if-happy { display: inline; }
.is-back .mascot-front, .is-back .mascot-unless-happy { display: none; }
/* (--grip flips between 1 and -1 with every step, so the hands swap.) */
.is-back .mascot-arm, .is-back .mascot-arm-l { animation: none; transition: transform .18s ease-out; }
.is-back .mascot-arm { transform: translateY(calc(var(--grip, 1) * 9px)); }
.is-back .mascot-arm-l { transform: translateY(calc(var(--grip, 1) * -9px)); }
.mascot-arm-l { transform-origin: 36px 128px; animation: ms-wave-l .5s ease-in-out infinite; }
.is-happy .mascot-arm { animation-duration: .5s; }
.is-sad .mascot-pupil { transform: translateY(5px); }
.is-sad .mascot-star { animation: none; }
.mascot-tear { animation: ms-tear 2.2s ease-in infinite; }
@keyframes ms-wave-l {
    0%, 100% { transform: rotate(8deg); }
    50% { transform: rotate(-14deg); }
}
@keyframes ms-tear {
    0% { transform: translateY(0); opacity: 0; }
    15% { opacity: 1; }
    100% { transform: translateY(30px); opacity: 0; }
}

/* Moving parts of the shop's outfit items (App\Support\Wardrobe). */
.wd-spin, .wd-flame, .wd-flutter { transform-box: fill-box; }
.wd-spin { transform-origin: center; animation: wd-spin .16s linear infinite alternate; } /* a propeller, edge-on */
.wd-bob { animation: wd-bob 2.6s ease-in-out infinite; } /* a floating friend */
.wd-flap { transform-origin: 58px 108px; animation: wd-flap .7s ease-in-out infinite alternate; } /* a wing, hinged at the body */
.wd-flame { transform-origin: 50% 0; animation: wd-flame .14s ease-in-out infinite alternate; }
.wd-flutter { transform-origin: 50% 100%; animation: wd-flutter .09s linear infinite alternate; } /* a bee's wing */
.wd-twinkle { animation: wd-twinkle 1.5s ease-in-out infinite; }
.wd-pulse { animation: wd-pulse 1.1s ease-in-out infinite alternate; } /* a glow */
.wd-float { animation: wd-float 2.4s ease-in infinite; } /* a rising soap bubble */
.wd-googly { animation: wd-googly 1.2s ease-in-out infinite; } /* a pupil rolling around its eye */
.wd-rotate { transform-box: fill-box; transform-origin: center; animation: wd-rotate 2.5s linear infinite; }
.wd-gum { transform-box: fill-box; transform-origin: 50% 15%; animation: wd-gum 3s ease-in-out infinite; } /* a bubble blown up, then popped */
.wd-wiggle { transform-origin: 186px 84px; animation: wd-wiggle .22s ease-in-out infinite alternate; } /* flopping in the hand */
.wd-buzz { animation: wd-buzz 1.4s linear infinite; } /* a fly doing laps */
.wd-rain { animation: wd-rain .9s linear infinite; }
@keyframes wd-googly {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(9px, -9px); }
    50% { transform: translate(-8px, -12px); }
    75% { transform: translate(-9px, -1px); }
}
@keyframes wd-rotate { to { transform: rotate(360deg); } }
@keyframes wd-gum {
    0% { transform: scale(.3); }
    80% { transform: scale(1.15); }
    86%, 100% { transform: scale(.3); }
}
@keyframes wd-wiggle { from { transform: rotate(-9deg); } to { transform: rotate(9deg); } }
@keyframes wd-buzz {
    0%, 100% { transform: translate(0, 0); }
    25% { transform: translate(14px, -9px); }
    50% { transform: translate(27px, 2px); }
    75% { transform: translate(12px, 11px); }
}
@keyframes wd-rain { from { transform: translateY(0); opacity: 1; } to { transform: translateY(9px); opacity: 0; } }
@keyframes wd-spin { from { transform: scaleX(1); } to { transform: scaleX(-1); } }
@keyframes wd-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-7px); } }
@keyframes wd-flap { from { transform: scaleX(1); } to { transform: scaleX(.74); } }
@keyframes wd-flame { from { transform: scaleY(1); } to { transform: scaleY(.6); } }
@keyframes wd-flutter { from { transform: scaleY(1); } to { transform: scaleY(.35); } }
@keyframes wd-twinkle { 0%, 100% { opacity: 1; } 50% { opacity: .15; } }
@keyframes wd-pulse { from { opacity: .3; } to { opacity: .6; } }
@keyframes wd-float {
    0% { transform: translateY(8px); opacity: 0; }
    25% { opacity: 1; }
    100% { transform: translateY(-16px); opacity: 0; }
}

/* "Read it to me" (public/js/mascot-reader.js): the bar that asks for it, and the
   mascot that pops up in the corner with a speech bubble and reads aloud. */
.read-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    width: 100%;
    padding: .5rem 1rem;
    border-radius: 9999px;
    border: 2px solid var(--sky);
    background: #E4F4FE;
    color: var(--sky-deep);
    font-family: Fredoka, sans-serif;
    font-weight: 600;
    font-size: .95rem;
    cursor: pointer;
    transition: background .15s ease, transform .1s ease;
}
.read-bar:hover { background: #CDEBFD; }
.read-bar:active { transform: translateY(1px); }
.read-bar.is-small { width: auto; padding: .25rem .6rem; font-size: .8rem; display: inline-flex; }
.sumi-reader {
    position: fixed;
    right: 12px;
    bottom: 12px;
    z-index: 50;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    max-width: min(26rem, calc(100vw - 24px));
    pointer-events: none;
}
.sumi-reader[hidden] { display: none; }
.sumi-reader > * { pointer-events: auto; }
.sumi-reader.is-entering { animation: ms-reader-in .45s cubic-bezier(.34, 1.4, .64, 1); }
.sumi-reader-bubble {
    margin-bottom: 3.2rem;
    padding: .75rem 1rem;
    border-radius: 1.25rem 1.25rem .35rem 1.25rem;
    background: #fff;
    border: 2px solid var(--brand-tint);
    box-shadow: 0 5px 0 #E4DDFB, 0 16px 24px -10px rgba(29,23,64,.35);
    max-height: 45vh;
    overflow-y: auto;
}
.sumi-reader-mascot { flex-shrink: 0; background: none; border: 0; padding: 0; cursor: pointer; }
/* Its mouth moves while it reads. */
.sumi-reader.is-talking .mascot-smile { transform-box: fill-box; transform-origin: 50% 0; animation: ms-talk .22s ease-in-out infinite alternate; }
@keyframes ms-reader-in { from { transform: translateY(110%); } to { transform: translateY(0); } }
@keyframes ms-talk { from { transform: scaleY(.35); } to { transform: scaleY(1.5); } }

/* Mascot stage (components/mascot-stage.blade.php): the mascot hops up a
   staircase after a finished worksheet or quiz. is-happy climbs to the top and
   cheers, is-ok stops on the middle step, is-sad stays on the ground. The
   resting transform is where each climb ends, so it also holds without motion. */
.mascot-stage { position: relative; width: 244px; height: 200px; margin-inline: auto; }
.mascot-step {
    position: absolute;
    bottom: 0;
    left: calc(64px + (var(--i) - 1) * 60px);
    width: 60px;
    height: calc(var(--i) * 28px);
    border-radius: 12px 12px 4px 4px;
    background: var(--c);
    box-shadow: inset 0 4px 0 rgba(255,255,255,.4), inset 0 -5px 0 var(--c-deep);
}
.mascot-climber { position: absolute; left: 0; bottom: -3px; width: 64px; }
.mascot-stage.is-ok .mascot-climber { transform: translate(122px, -56px); animation: ms-climb-ok 1.7s both; }
.mascot-stage.is-happy .mascot-climber { transform: translate(182px, -84px); animation: ms-climb 2.4s both; }
.mascot-stage.is-happy .mascot { animation: ms-cheer .7s ease-in-out 2.4s infinite; }
.mascot-stage.is-sad .mascot { transform-origin: 50% 100%; filter: saturate(.8); animation: ms-sad 3s ease-in-out infinite; }
.mascot-stage-sparkle { display: none; position: absolute; left: 140px; bottom: 140px; width: 40px; height: 40px; }
.mascot-stage.is-happy .mascot-stage-sparkle { display: block; animation: ms-pop .5s ease-out 2.3s both; }
@keyframes ms-climb {
    0%, 10% { transform: translate(0, 0); animation-timing-function: ease-out; }
    20% { transform: translate(31px, -50px); animation-timing-function: ease-in; }
    30%, 35% { transform: translate(62px, -28px); animation-timing-function: ease-out; }
    45% { transform: translate(92px, -80px); animation-timing-function: ease-in; }
    55%, 60% { transform: translate(122px, -56px); animation-timing-function: ease-out; }
    70% { transform: translate(152px, -108px); animation-timing-function: ease-in; }
    80%, 100% { transform: translate(182px, -84px); }
}
@keyframes ms-climb-ok {
    0%, 14% { transform: translate(0, 0); animation-timing-function: ease-out; }
    28% { transform: translate(31px, -50px); animation-timing-function: ease-in; }
    42%, 50% { transform: translate(62px, -28px); animation-timing-function: ease-out; }
    66% { transform: translate(92px, -80px); animation-timing-function: ease-in; }
    80%, 100% { transform: translate(122px, -56px); }
}
@keyframes ms-cheer {
    0%, 100% { transform: translateY(0); }
    40% { transform: translateY(-14px); }
}
@keyframes ms-sad {
    0%, 100% { transform: rotate(-2deg); }
    50% { transform: rotate(2deg); }
}
@keyframes ms-pop {
    from { transform: scale(0) rotate(-30deg); }
    to { transform: scale(1) rotate(0deg); }
}

@keyframes ms-float {
    0%, 100% { transform: translateY(0) rotate(0deg); }
    50% { transform: translateY(-14px) rotate(6deg); }
}
@keyframes ms-spin { to { transform: rotate(360deg); } }
@keyframes ms-wobble {
    0%, 100% { transform: rotate(-3deg); }
    50% { transform: rotate(3deg); }
}

@media (prefers-reduced-motion: reduce) {
    .float-a, .float-b, .float-c, .spin-slow, .wobble, .cube-3d, .orbit, .mascot-eye, .mascot-arm, .mascot-star { animation: none; }
    .mascot, .mascot *, .mascot-stage, .mascot-stage * { animation: none !important; }
    .btn-pop, .card-pop, .tile-pop, [data-tilt] { transition: none; }
    [data-tilt] { transform: none !important; }
}

@media print {
    .app-bg { background: #fff; }
    .card-pop, .tile-pop { box-shadow: none; }
}

/*
 * Worksheet pictures (graphs, shapes...) are drawn at a fixed size, up to
 * ~510px wide. On a phone a question box is narrower, so shrink them to fit
 * instead of cutting off the right side (every picture has a viewBox, so it
 * scales cleanly). Wide HTML pictures that can't shrink scroll instead.
 */
.ws-visual {
    max-width: 100%;
    overflow-x: auto;
}

.ws-visual svg {
    max-width: 100%;
    height: auto;
}
