/* ========================================
   The Classlings look for the pupils' pages
   The reviewed design (design-directions/MIX.md: the mix, playful on the pupils' pages) as pupils see
   it on their login, their home and My Classling. Every colour, size, space and shape is a token on
   .cla-pupil, the page's root; the pages' own stylesheets lay out their parts with these tokens.
   Each class stands on plain white or on Pixel Quest's sky and grass: .cla-pupil[data-world="sky"].
   Nothing moves on its own except the Classlings; the only springy motion is a press.
   ======================================== */

/* Atkinson Hyperlegible, which the reading room already serves from ClassSlate, for the words. */
@font-face {
    font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 400; font-display: swap;
    src: url('../fonts/atkinson-hyperlegible/atkinson-hyperlegible-400-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 400; font-display: swap;
    src: url('../fonts/atkinson-hyperlegible/atkinson-hyperlegible-400-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 700; font-display: swap;
    src: url('../fonts/atkinson-hyperlegible/atkinson-hyperlegible-700-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Atkinson Hyperlegible'; font-style: normal; font-weight: 700; font-display: swap;
    src: url('../fonts/atkinson-hyperlegible/atkinson-hyperlegible-700-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

.cla-pupil {
    /* Colour. Text is always ink, on white or on a light-bright shape. */
    --page: #ffffff;
    --ink: #1e1b3a;
    --ink-2: #4a4766;
    --wash: #f3f2f9;
    --wash-2: #e4e1f1;
    --paper: #fbf9f4;
    --line-soft: rgba(30, 27, 58, 0.3);
    --sky: #3aa0ff;       --sky-deep: #1b6fcf;       --sky-tint: #e1efff;
    --grape: #a07cff;     --grape-deep: #6a45dc;     --grape-tint: #eee8ff;
    --lime: #7ed957;      --lime-deep: #3e9a2a;      --lime-tint: #e5f8da;
    --tangerine: #ff8a3d; --tangerine-deep: #cf5a12; --tangerine-tint: #ffeddf;
    --bubblegum: #ff5fa2; --bubblegum-deep: #cf3177; --bubblegum-tint: #ffe5f0;
    --vermilion: #f0532f; --vermilion-deep: #b8341a; --vermilion-tint: #ffe3dc;
    --teal: #2ec4b6;      --teal-deep: #12867b;      --teal-tint: #d8f5f1;
    --gold: #f7c230;      --gold-deep: #c98a12;      --gold-light: #ffe08a;  --gold-tint: #fff3c4;
    /* Each app wears one colour. */
    --app: var(--sky); --app-deep: var(--sky-deep); --app-tint: var(--sky-tint);

    /* Pixel Quest's world, drawn in the sky world and in each little scene. */
    --world: #7cc6f2;
    --cloud: #ffffff;
    --cloud-shade: #d4ecfb;
    --grass: #5fbf5a;
    --grass-dark: #3f9a44;
    --soil: #7a4a26;
    --hill: #8fd384;
    --art-cloud: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 9' width='32' height='9' shape-rendering='crispEdges'%3E%3Cpath fill='%23ffffff' d='M11 0h5v1h-5zM9 1h9v1h-9zM5 2h14v1h-14zM20 2h5v1h-5zM3 3h25v1h-25zM2 4h28v1h-28zM1 5h30v1h-30zM0 6h32v1h-32z'/%3E%3Cpath fill='%23d4ecfb' d='M0 7h32v1h-32zM1 8h30v1h-30z'/%3E%3C/svg%3E");
    --art-puff: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 5' width='20' height='5' shape-rendering='crispEdges'%3E%3Cpath fill='%23ffffff' d='M6 0h4v1h-4zM4 1h8v1h-8zM13 1h3v1h-3zM2 2h16v1h-16zM0 3h20v1h-20z'/%3E%3Cpath fill='%23d4ecfb' d='M1 4h18v1h-18z'/%3E%3C/svg%3E");
    --art-tufts: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 3' width='16' height='3' shape-rendering='crispEdges'%3E%3Cpath fill='%235fbf5a' d='M2 0h1v1h-1zM12 0h1v1h-1zM1 1h3v1h-3zM6 1h1v1h-1zM11 1h3v1h-3zM15 1h1v1h-1zM0 2h16v1h-16z'/%3E%3C/svg%3E");
    --art-edge: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 2' width='16' height='2' shape-rendering='crispEdges'%3E%3Cpath fill='%233f9a44' d='M0 0h2v1h-2zM5 0h4v1h-4zM11 0h3v1h-3zM0 1h16v1h-16z'/%3E%3C/svg%3E");
    /* The playful layer's art: a sparkle, a twinkle, speech-bubble tails, a tree and the far hills. */
    --art-sparkle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 7 7' width='7' height='7' shape-rendering='crispEdges'%3E%3Cpath fill='%231e1b3a' d='M3 0h1v1h-1zM2 1h1v1h-1zM4 1h1v1h-1zM1 2h2v1h-2zM4 2h2v1h-2zM0 3h1v1h-1zM6 3h1v1h-1zM1 4h2v1h-2zM4 4h2v1h-2zM2 5h1v1h-1zM4 5h1v1h-1zM3 6h1v1h-1z'/%3E%3Cpath fill='%23f7c230' d='M3 1h1v1h-1zM1 3h1v1h-1zM5 3h1v1h-1zM3 5h1v1h-1z'/%3E%3Cpath fill='%23ffe08a' d='M3 2h1v1h-1zM2 3h1v1h-1zM4 3h1v1h-1zM3 4h1v1h-1z'/%3E%3Cpath fill='%23ffffff' d='M3 3h1v1h-1z'/%3E%3C/svg%3E");
    --art-twinkle: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 5' width='5' height='5' shape-rendering='crispEdges'%3E%3Cpath fill='%231e1b3a' d='M2 0h1v1h-1zM1 1h1v1h-1zM3 1h1v1h-1zM0 2h1v1h-1zM4 2h1v1h-1zM1 3h1v1h-1zM3 3h1v1h-1zM2 4h1v1h-1z'/%3E%3Cpath fill='%23f7c230' d='M2 1h1v1h-1zM1 2h1v1h-1zM3 2h1v1h-1zM2 3h1v1h-1z'/%3E%3Cpath fill='%23ffffff' d='M2 2h1v1h-1z'/%3E%3C/svg%3E");
    --art-tail: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 5' width='5' height='5' shape-rendering='crispEdges'%3E%3Cpath fill='%231e1b3a' d='M0 0h1v1h-1zM4 0h1v1h-1zM0 1h1v1h-1zM3 1h1v1h-1zM0 2h1v1h-1zM2 2h1v1h-1zM0 3h2v1h-2zM0 4h1v1h-1z'/%3E%3Cpath fill='%23ffffff' d='M1 0h3v1h-3zM1 1h2v1h-2zM1 2h1v1h-1z'/%3E%3C/svg%3E");
    --art-tail-left: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 5 5' width='5' height='5' shape-rendering='crispEdges'%3E%3Cpath fill='%231e1b3a' d='M3 0h2v1h-2zM2 1h1v1h-1zM1 2h1v1h-1zM0 3h1v1h-1zM0 4h5v1h-5z'/%3E%3Cpath fill='%23ffffff' d='M3 1h2v1h-2zM2 2h3v1h-3zM1 3h4v1h-4z'/%3E%3C/svg%3E");
    --art-tree: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 14' width='12' height='14' shape-rendering='crispEdges'%3E%3Cpath fill='%231e1b3a' d='M4 0h4v1h-4zM2 1h2v1h-2zM8 1h2v1h-2zM1 2h1v1h-1zM10 2h1v1h-1zM0 3h1v1h-1zM11 3h1v1h-1zM0 4h1v1h-1zM11 4h1v1h-1zM0 5h1v1h-1zM11 5h1v1h-1zM0 6h1v1h-1zM11 6h1v1h-1zM1 7h1v1h-1zM10 7h1v1h-1zM2 8h1v1h-1zM9 8h1v1h-1zM3 9h2v1h-2zM7 9h2v1h-2zM4 10h1v1h-1zM7 10h1v1h-1zM4 11h1v1h-1zM7 11h1v1h-1zM3 12h1v1h-1zM8 12h1v1h-1zM4 13h4v1h-4z'/%3E%3Cpath fill='%235fbf5a' d='M4 1h4v1h-4zM2 2h8v1h-8zM1 3h2v1h-2zM4 3h5v1h-5zM10 3h1v1h-1zM1 4h5v1h-5zM7 4h4v1h-4zM1 5h1v1h-1zM3 5h8v1h-8zM1 6h6v1h-6zM8 6h3v1h-3zM2 7h2v1h-2zM5 7h5v1h-5zM3 8h6v1h-6z'/%3E%3Cpath fill='%233f9a44' d='M3 3h1v1h-1zM9 3h1v1h-1zM6 4h1v1h-1zM2 5h1v1h-1zM7 6h1v1h-1zM4 7h1v1h-1z'/%3E%3Cpath fill='%237a4a26' d='M5 9h2v1h-2zM5 10h2v1h-2zM5 11h2v1h-2zM4 12h4v1h-4z'/%3E%3C/svg%3E");
    --art-hills: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 96 14' width='96' height='14' shape-rendering='crispEdges'%3E%3Cpath fill='%238fd384' d='M69 0h12v1h-12zM66 1h18v1h-18zM64 2h22v1h-22zM61 3h27v1h-27zM59 4h31v1h-31zM57 5h35v1h-35zM54 6h40v1h-40zM50 7h46v1h-46zM0 8h3v1h-3zM27 8h69v1h-69zM0 9h6v1h-6zM20 9h76v1h-76zM0 10h96v1h-96zM0 11h96v1h-96zM0 12h96v1h-96zM0 13h96v1h-96z'/%3E%3C/svg%3E");
    /* How much ground a page stands on, and where its clouds float (the sky world only). */
    --ground: 48px;
    --soil-h: 16px;
    --cloud-a: left 600px top 22px;
    --cloud-b: left 880px top 58px;
    --cloud-c: left -400px top 0;

    /* Type. Titles are drawn in Classlings' own lettering at a whole number of screen pixels per
       art pixel (--title-scale); headings are Fredoka; words are Atkinson Hyperlegible. */
    --display: 'Fredoka', 'Atkinson Hyperlegible', 'Trebuchet MS', system-ui, sans-serif;
    --body: 'Atkinson Hyperlegible', 'Segoe UI', system-ui, sans-serif;
    --title-scale: 4;
    --t-huge: 88px;
    --t-xl: 64px;
    --t-l: 48px;
    --t-m: 36px;
    --t-s: 28px;
    --t-label: 24px;
    --t-ui: 20px;
    --t-body: 18px;
    --t-ui-s: 18px;
    --t-small: 16px;
    --t-tag: 14px;

    /* Space */
    --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px; --s-8: 64px;
    --gutter: 32px;

    /* Shape */
    /* The shared button sizes come from shared/css/classlings-controls.css (the fallbacks are the same numbers). */
    --r-s: var(--ctl-small-r, 14px);
    --r-m: var(--ctl-r, 20px);
    --r-l: var(--ctl-big-r, 28px);
    --r-xl: 44px;
    --edge: var(--ctl-edge, 3px);
    --lift: var(--ctl-lift, 6px);
    --float: 0 8px 0 rgba(30, 27, 58, 0.13);
    /* Pixel parts (speech bubbles, the code boxes) sit on a 4 px grid with Pixel Quest's stepped
       outline: four one-pixel shadows that leave each corner pixel out. */
    --px: 4px;
    --ring: 0 calc(var(--px) * -1) 0 var(--ink), 0 var(--px) 0 var(--ink),
        calc(var(--px) * -1) 0 0 var(--ink), var(--px) 0 0 var(--ink);
    /* The logo: 2 CSS pixels per art pixel. */
    --logo-s: 2px;
    --logo-ink: #2d3436;

    /* Sizes of things pupils press. */
    --tap: var(--ctl-h, 56px);
    --tap-l: var(--ctl-big-h, 72px);
    --tap-xl: var(--ctl-huge-h, 88px);

    /* Motion: a quick press down, a spring back up. */
    --press: 70ms;
    --settle: 460ms;
    --spring: cubic-bezier(0.28, 1.9, 0.5, 1);

    position: relative;
    box-sizing: border-box;
    min-height: 100vh;
    min-height: 100dvh;
    margin: 0;
    color: var(--ink);
    font: 400 var(--t-body) / 1.5 var(--body);
    letter-spacing: 0.02em;
    background: var(--page);
    -webkit-font-smoothing: antialiased;
}

.cla-pupil *, .cla-pupil *::before, .cla-pupil *::after { box-sizing: border-box; }
.cla-pupil :is(h1, h2, h3, h4, p, ul, ol, figure) { margin: 0; }
.cla-pupil :is(ul, ol) { padding: 0; list-style: none; }
/* Controls take the page's type unless their own rule sets it (:where keeps this from outranking it). */
.cla-pupil :where(button, input) { font: inherit; color: inherit; letter-spacing: inherit; }
.cla-pupil a { color: inherit; }
.cla-pupil canvas { display: block; image-rendering: pixelated; }
.cla-pupil [hidden] { display: none !important; }
.cla-pupil :focus-visible { outline: 4px solid var(--ink); outline-offset: 4px; }
/* The page moved the keyboard on by itself (pupil/app.js quietFocus): no ring until the pupil moves it. */
.cla-pupil [data-quiet-focus]:focus-visible { outline: none; }
.cla-pupil [data-quiet-focus]:focus-visible::after { content: none; }
.cla-pupil .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.cla-pupil .quiet { color: var(--ink-2); }
.cla-pupil .num { font-variant-numeric: tabular-nums; }

/* Apps and their colours: the Cup purple, Maths green, Reading pink, Try new things orange (as Cub,
   who peeks over it), and blue for the pupil's own progress. A page root can wear one too (My
   Classling is the Cup's). */
.cla-pupil.app-cup, .cla-pupil .app-cup { --app: var(--grape); --app-deep: var(--grape-deep); --app-tint: var(--grape-tint); }
.cla-pupil.app-maths, .cla-pupil .app-maths { --app: var(--lime); --app-deep: var(--lime-deep); --app-tint: var(--lime-tint); }
.cla-pupil.app-reading, .cla-pupil .app-reading { --app: var(--bubblegum); --app-deep: var(--bubblegum-deep); --app-tint: var(--bubblegum-tint); }
.cla-pupil.app-try, .cla-pupil .app-try { --app: var(--tangerine); --app-deep: var(--tangerine-deep); --app-tint: var(--tangerine-tint); }
.cla-pupil.app-me, .cla-pupil .app-me { --app: var(--sky); --app-deep: var(--sky-deep); --app-tint: var(--sky-tint); }
/* Teal is for their badges. */
.cla-pupil.app-badges, .cla-pupil .app-badges { --app: var(--teal); --app-deep: var(--teal-deep); --app-tint: var(--teal-tint); }

/* ------------------------------------------------------------------ the logo and titles */

/* The brand kit's logo at scale 2: the word's 77 x 22 art-pixel grid (an empty one-pixel ring round
   the letters) with 8 rows of headroom for the Classling peeking over it, as the teacher's page draws
   it. Its letters line up with the gutter. */
.cla-pupil .logo {
    flex: none;
    width: calc(var(--logo-s) * 77);
    height: calc(var(--logo-s) * 30);
}
/* Still pictures written into the page (scripts/pupil-login-inline.mjs): the logo, and Kit over "Type your code",
   there from the first frame (the teacher, 10 October). Each fills its box at a whole-number scale. */
.cla-pupil [data-still] { display: block; }
.cla-pupil [data-still] > svg { display: block; width: 100%; height: 100%; }

/* A title in the lettering, dressed as the logo is: white letters on the two-pixel dark edge. The art
   is 20 art pixels tall; the bottom 4 are room for tails, handed back so the capitals line up. */
.cla-pupil .pt { line-height: 0; margin-bottom: calc(var(--title-scale) * -4px); }
.cla-pupil .pt .title-art { display: block; width: calc(var(--title-scale) * var(--w) * 1px); height: calc(var(--title-scale) * var(--h) * 1px); }
.cla-pupil .pt .title-edge { fill: var(--logo-ink); }
.cla-pupil .pt .title-fill { fill: #ffffff; }
/* A name the lettering can't draw: plain words instead. */
.cla-pupil .pt.is-text { margin-bottom: 0; font: 700 var(--t-l) / 1.1 var(--display); line-height: 1.1; }

/* ------------------------------------------------------------------ icons: the kit's pixel icons, in the text's colour

   brand/icons.js draws them (barIcons.js, as on the teacher's pages), each at a whole number of screen
   pixels to an art pixel: a 12 x 12 icon at 24 px, an 8 x 8 one at 24 px, the padlock's 8 x 10 at
   16 x 20, Close's 8 x 7 at 24 x 21 and the star's 7 x 7 at 21 px. Places that want a smaller one set
   12 px (a 12 x 12 at one to one) or 16 px (an 8 x 8 at two to one). */

.cla-pupil .cla-ic { display: inline-block; flex: none; width: 1.15em; height: 1.15em; vertical-align: -0.2em; }
.cla-pupil .cla-ic.is-px { width: 24px; height: 24px; vertical-align: middle; }
.cla-pupil .cla-ic.is-8x10 { width: 16px; height: 20px; }
.cla-pupil .cla-ic.is-8x7 { height: 21px; }
.cla-pupil .cla-ic.is-7x7 { width: 21px; height: 21px; }

/* The pixel icons (shared/js/classlings/brand/barIcons.js): an 8-wide icon at 3 screen pixels to an art pixel. */
.cla-pupil .pi { display: inline-block; flex: none; width: 24px; height: 24px; vertical-align: middle; }

/* ------------------------------------------------------------------ the toy button
   A flat cap on a base of its own deeper colour. Press: it sinks onto the base, then springs back. */

.cla-pupil .btn {
    --c: var(--page);
    --c-deep: var(--ink);
    --c-line: var(--ink);
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    min-height: var(--tap);
    margin: 0 0 var(--lift);
    padding: 0 var(--s-5);
    font: 600 var(--t-ui) / 1.1 var(--display);
    letter-spacing: 0.01em;
    color: var(--ink);
    text-decoration: none;
    white-space: nowrap;
    background: var(--c);
    border: var(--edge) solid var(--c-line);
    border-radius: var(--r-m);
    box-shadow: 0 var(--lift) 0 var(--c-deep);
    --ring-lift: var(--lift); --ring-edge: var(--edge);
    cursor: pointer;
    transition: transform var(--settle) var(--spring), box-shadow var(--settle) var(--spring);
    -webkit-tap-highlight-color: transparent;
}
.cla-pupil .btn:active:not(:disabled) {
    transform: translateY(var(--lift));
    box-shadow: 0 0 0 var(--c-deep);
    transition-duration: var(--press);
    transition-timing-function: ease-out;
}
/* A button that can't be pressed right now is flat and quiet, but its words stay easy to read (ink on a pale wash is
   about 8:1; the old half-faded button was 2.3:1). One that has done its job is a state of its own: green, with a tick. */
.cla-pupil .btn:disabled {
    color: var(--ink-2);
    background: var(--wash);
    border-color: var(--wash-2);
    box-shadow: 0 var(--lift) 0 var(--wash-2);
    cursor: default;
}
.cla-pupil .btn.is-done:disabled { color: var(--ink); background: var(--lime-tint); border-color: var(--lime-deep); box-shadow: 0 var(--lift) 0 var(--lime-deep); }
.cla-pupil .btn.is-done .cla-ic { box-sizing: content-box; width: 22px; height: 22px; padding: 4px; color: var(--ink); background: var(--lime); border-radius: 50%; }
.cla-pupil .btn .cla-ic { font-size: 1.15em; }
/* The main action: gold, with ink words. */
.cla-pupil .btn.is-go { --c: var(--gold); --c-deep: var(--gold-deep); --c-line: var(--gold-deep); }
.cla-pupil .btn.is-app { --c: var(--app); --c-deep: var(--app-deep); --c-line: var(--app-deep); }
.cla-pupil .btn.is-big { min-height: var(--tap-l); padding: 0 var(--s-6); font-size: var(--t-s); border-radius: var(--r-l); --lift: var(--ctl-big-lift, 7px); }
.cla-pupil .btn.is-huge { min-height: var(--tap-xl); padding: 0 var(--s-7); font-size: var(--t-m); font-weight: 700; border-radius: var(--r-l); --lift: var(--ctl-huge-lift, 8px); }
.cla-pupil .btn.is-wide { width: 100%; }
.cla-pupil .btn.is-small { min-height: var(--ctl-small-h, 48px); padding: 0 var(--s-4); font-size: var(--t-ui-s); border-radius: var(--r-s); --lift: var(--ctl-small-lift, 4px); }

/* A switch between views: one shape, and the chosen view wears the app's colour. */
.cla-pupil .seg { display: flex; gap: var(--s-1); padding: var(--s-1); background: var(--wash); border-radius: calc(var(--r-m) + var(--s-1)); }
.cla-pupil .tool {
    appearance: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    min-height: var(--ctl-tab-h, 48px);
    padding: 0 var(--s-4);
    font: 600 var(--t-ui) / 1 var(--display);
    color: var(--ink);
    text-decoration: none;
    white-space: nowrap;
    background: transparent;
    border: var(--edge) solid transparent;
    border-radius: var(--r-m);
    cursor: pointer;
    transition: transform var(--settle) var(--spring);
}
.cla-pupil .tool:hover { background: var(--page); }
.cla-pupil .tool:active { transform: scale(0.93); transition-duration: var(--press); }
.cla-pupil .seg .tool.is-on, .cla-pupil .seg .tool[aria-selected="true"], .cla-pupil .seg .tool[aria-pressed="true"] { background: var(--app); border-color: var(--app-deep); }

/* ------------------------------------------------------------------ shapes */

/* Pale panels: a quiet fill on white (a wash, or the app's tint). In the sky they turn white with a
   soft ink line, so they still read. */
.cla-pupil .panel { background: var(--wash); border-radius: var(--r-xl); }
.cla-pupil .panel.is-tint { background: var(--app-tint); }

/* A scalloped badge for levels: an ink edge round a white middle. */
.cla-pupil .cookie {
    --cookie: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 2.0L52.5 2.5L54.9 3.9L57 5.8L59 7.7L60.9 9.4L62.9 10.4L65.1 10.8L67.6 10.5L70.3 10.1L73.2 9.8L75.9 10.1L78.2 11.2L79.9 13.0L81 15.5L81.7 18.3L82.1 21.1L82.7 23.6L83.7 25.5L85.2 27.1L87.4 28.4L89.9 29.7L92.4 31.1L94.4 33.0L95.7 35.2L96 37.7L95.4 40.4L94.2 43.0L93 45.5L92 47.8L91.6 50.0L92 52.2L93 54.5L94.2 57.0L95.4 59.6L96 62.3L95.7 64.8L94.4 67.0L92.4 68.9L89.9 70.3L87.4 71.6L85.2 72.9L83.7 74.5L82.7 76.4L82.1 78.9L81.7 81.7L81 84.5L79.9 87.0L78.2 88.8L75.9 89.9L73.2 90.2L70.3 89.9L67.6 89.5L65.1 89.2L62.9 89.6L60.9 90.6L59 92.3L57 94.2L54.9 96.1L52.5 97.5L50 98.0L47.5 97.5L45.1 96.1L43 94.2L41 92.3L39.1 90.6L37.1 89.6L34.9 89.2L32.4 89.5L29.7 89.9L26.8 90.2L24.1 89.9L21.8 88.8L20.1 87.0L19 84.5L18.3 81.7L17.9 78.9L17.3 76.4L16.3 74.5L14.8 72.9L12.6 71.6L10.1 70.3L7.6 68.9L5.6 67.0L4.3 64.8L4 62.3L4.6 59.6L5.8 57.0L7 54.5L8 52.2L8.4 50.0L8 47.8L7 45.5L5.8 43.0L4.6 40.4L4 37.7L4.3 35.2L5.6 33.0L7.6 31.1L10.1 29.7L12.6 28.4L14.8 27.1L16.3 25.5L17.3 23.6L17.9 21.1L18.3 18.3L19 15.5L20.1 13.0L21.8 11.2L24.1 10.1L26.8 9.8L29.7 10.1L32.4 10.5L34.9 10.8L37.1 10.4L39.1 9.4L41 7.7L43 5.8L45.1 3.9L47.5 2.5Z'/%3E%3C/svg%3E");
    --c: var(--page);
    display: grid;
    place-items: center;
    flex: none;
    width: 104px;
    height: 104px;
    background: var(--ink);
    -webkit-mask: var(--cookie) center / 100% 100% no-repeat;
    mask: var(--cookie) center / 100% 100% no-repeat;
}
.cla-pupil .cookie::before {
    content: '';
    grid-area: 1 / 1;
    width: calc(100% - 9px);
    height: calc(100% - 9px);
    background: var(--c);
    -webkit-mask: var(--cookie) center / 100% 100% no-repeat;
    mask: var(--cookie) center / 100% 100% no-repeat;
}
.cla-pupil .cookie > span { grid-area: 1 / 1; position: relative; display: grid; justify-items: center; line-height: 1; }
.cla-pupil .cookie small { font: 600 var(--t-small) / 1 var(--display); }
.cla-pupil .cookie b { font: 700 var(--t-l) / 1 var(--display); font-variant-numeric: tabular-nums; }

/* App tiles: big pressable toys in the app's colour. */
.cla-pupil .tile {
    --ring-lift: 8px; --ring-edge: var(--edge); /* what takes a press reaches over its lift (classlings-controls.css) */
    position: relative;
    display: grid;
    color: var(--ink);
    text-decoration: none;
    background: var(--app);
    border: var(--edge) solid var(--app-deep);
    border-radius: var(--r-xl);
    box-shadow: 0 8px 0 var(--app-deep);
    margin-bottom: 8px;
    cursor: pointer;
    transition: transform var(--settle) var(--spring), box-shadow var(--settle) var(--spring);
}
.cla-pupil .tile:active { transform: translateY(8px); box-shadow: 0 0 0 var(--app-deep); transition-duration: var(--press); }

/* Things to pick in a grid: a light card with a chunky edge when chosen; greyed and dashed when locked. */
.cla-pupil .pick {
    appearance: none;
    position: relative;
    display: grid;
    justify-items: center;
    align-content: start;
    gap: var(--s-1);
    min-width: 0;
    padding: var(--s-2);
    color: var(--ink);
    font: 600 var(--t-small) / 1.2 var(--display);
    text-align: center;
    background: var(--page);
    border: var(--edge) solid var(--wash-2);
    border-radius: var(--r-l);
    cursor: pointer;
    transition: transform var(--settle) var(--spring);
}
.cla-pupil .pick:active { transform: scale(0.94); transition-duration: var(--press); }
.cla-pupil .pick.is-on { background: var(--app-tint); border-color: var(--app-deep); box-shadow: inset 0 0 0 var(--edge) var(--app-deep); }
.cla-pupil .pick .on {
    position: absolute;
    top: -10px;
    right: -8px;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px 10px 3px 6px;
    font: 600 var(--t-small) / 1 var(--display);
    background: var(--lime);
    border: 2px solid var(--lime-deep);
    border-radius: var(--r-s);
}
.cla-pupil .pick .on .cla-ic.is-px { width: 12px; height: 12px; }
.cla-pupil .pick.locked { cursor: default; color: var(--ink-2); background: var(--wash); border-style: dashed; }
.cla-pupil .pick.locked:active { transform: none; }
.cla-pupil .pick.locked canvas { filter: grayscale(1); opacity: 0.45; }
.cla-pupil .pick .lvl {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px 2px 6px;
    font: 600 var(--t-small) / 1.2 var(--display);
    color: var(--ink);
    white-space: nowrap;
    background: var(--page);
    border: 2px solid var(--wash-2);
    border-radius: var(--r-s);
}
/* The kit's padlock ("in use, or locked"), 8 x 10 at 16 x 20. */
.cla-pupil .pick .lvl .cla-ic.is-px { width: 16px; height: 20px; }

/* A little marker: a word on a light shape. */
.cla-pupil .tag {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 30px;
    padding: 2px 12px;
    font: 600 var(--t-small) / 1.1 var(--display);
    color: var(--ink);
    background: var(--app-tint);
    border: 2px solid var(--app-deep);
    border-radius: var(--r-s);
    white-space: nowrap;
}

/* A quiet notice when something's wrong, and a problem a pupil must read. */
.cla-pupil .notice {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    min-height: 44px;
    padding: var(--s-2) var(--s-4);
    font: 600 var(--t-ui-s) / 1.3 var(--display);
    color: var(--ink);
    background: var(--tangerine-tint);
    border: 2px solid var(--tangerine-deep);
    border-radius: var(--r-s);
}
.cla-pupil .notice.is-bad { background: var(--vermilion-tint); border-color: var(--vermilion-deep); }

/* ------------------------------------------------------------------ a little pixel scene
   Pixel Quest's world in a box: sky, still clouds, and grass the Classling stands on. The grass is
   drawn in front, so the tufts brush the Classling's feet. */

.cla-pupil .scene {
    --scene-ground: 44px;
    position: relative;
    overflow: hidden;
    background:
        var(--art-cloud) var(--scene-cloud, left 28px top 30px) / calc(var(--px) * 32) calc(var(--px) * 9) no-repeat,
        var(--art-puff) var(--scene-puff, right 32px top 92px) / calc(var(--px) * 20) calc(var(--px) * 5) no-repeat,
        var(--world);
    border: var(--edge) solid var(--ink);
}
.cla-pupil .scene::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: calc(var(--scene-ground) + var(--px) * 3);
    background:
        var(--art-tufts) left 0 top 0 / calc(var(--px) * 16) calc(var(--px) * 3) repeat-x,
        var(--art-edge) left 0 bottom calc(var(--px) * 3) / calc(var(--px) * 16) calc(var(--px) * 2) repeat-x,
        linear-gradient(var(--soil), var(--soil)) left 0 bottom 0 / 100% calc(var(--px) * 3) no-repeat,
        linear-gradient(var(--grass), var(--grass)) left 0 bottom 0 / 100% var(--scene-ground) no-repeat;
    pointer-events: none;
}
.cla-pupil .scene > canvas { position: absolute; left: 0; right: 0; bottom: calc(var(--scene-ground) - var(--px)); width: 100%; }

/* ------------------------------------------------------------------ the playful layer
   Classlings with a line to say, a few pixel sparkles, Classlings peeking over panels, and in the sky
   far hills and trees along the grass. Nothing here moves and nothing covers content. The pieces of
   class "play" show only in the playful tone; those marked "in-sky" only in the sky world. */

.cla-pupil:not([data-tone="play"]) .play,
.cla-pupil:not([data-world="sky"]) .in-sky { display: none !important; }

/* A Classling's line, in a pixel speech bubble: white, the stepped ink outline, a pixel tail. */
.cla-pupil .bubble {
    position: absolute;
    z-index: 4;
    margin: 0;
    padding: 6px 14px 8px;
    color: var(--ink);
    font: 600 var(--t-ui) / 1.2 var(--display);
    letter-spacing: 0.01em;
    white-space: nowrap;
    background: var(--page);
    box-shadow: var(--ring), 0 calc(var(--px) * 3) 0 var(--line-soft);
    pointer-events: none;
}
/* The tail points at the Classling speaking: below and to the left (the default), below and to the
   right, or straight out to the left or right. Its first row lies over the outline and opens it. */
.cla-pupil .bubble::after {
    content: '';
    position: absolute;
    left: var(--tail-at, 20px);
    top: 100%;
    width: calc(var(--px) * 5);
    height: calc(var(--px) * 5);
    background: var(--art-tail) 0 0 / 100% 100%;
}
.cla-pupil .bubble.below-right::after { left: auto; right: var(--tail-at, 20px); transform: scaleX(-1); }
.cla-pupil .bubble.left::after { left: auto; right: 100%; top: var(--tail-at, 12px); background-image: var(--art-tail-left); }
.cla-pupil .bubble.right::after { left: 100%; top: var(--tail-at, 12px); background-image: var(--art-tail-left); transform: scaleX(-1); }

/* Pixel sparkle, used sparingly: a star, and a smaller twinkle. They never move. */
.cla-pupil .sparkle {
    position: absolute;
    z-index: 3;
    width: calc(var(--px) * 7);
    height: calc(var(--px) * 7);
    background: var(--art-sparkle) 0 0 / 100% 100%;
    pointer-events: none;
}
.cla-pupil .sparkle.is-small { width: calc(var(--px) * 5); height: calc(var(--px) * 5); background-image: var(--art-twinkle); }
.cla-pupil .sparkle.inline { position: static; display: inline-block; vertical-align: middle; margin-left: var(--s-2); }

/* Classlings peeking over a panel's top edge: placed inside the panel, drawn behind it. */
.cla-pupil[data-tone="play"] { isolation: isolate; }
.cla-pupil .peeker { position: absolute; z-index: -1; top: -48px; width: 56px; height: 56px; pointer-events: none; }

/* A tree standing on the grass (the sky world, on screens that don't scroll). */
.cla-pupil .tree {
    position: absolute;
    bottom: calc(var(--ground) - var(--px));
    width: calc(var(--px) * 12);
    height: calc(var(--px) * 14);
    background: var(--art-tree) 0 0 / 100% 100%;
    pointer-events: none;
}

/* ------------------------------------------------------------------ the sky world
   The same pages in Pixel Quest's world: a flat sky with still pixel clouds, far hills, and grass
   with tufts and a soil band along the foot. Nothing moves position. Text straight on the sky stays
   ink. Panels that were only a pale fill turn white with a soft ink line. The page scrolls on a
   phone, so the world scrolls with it and the ground ends the page. */

.cla-pupil[data-world="sky"] {
    padding-bottom: var(--ground);
    background:
        var(--art-cloud) var(--cloud-a) / calc(var(--px) * 32) calc(var(--px) * 9) no-repeat,
        var(--art-puff) var(--cloud-b) / calc(var(--px) * 20) calc(var(--px) * 5) no-repeat,
        var(--art-puff) var(--cloud-c) / calc(var(--px) * 20) calc(var(--px) * 5) no-repeat,
        var(--art-edge) left 0 bottom var(--soil-h) / calc(var(--px) * 16) calc(var(--px) * 2) repeat-x,
        linear-gradient(var(--soil), var(--soil)) left 0 bottom 0 / 100% var(--soil-h) no-repeat,
        var(--art-tufts) left 0 bottom var(--ground) / calc(var(--px) * 16) calc(var(--px) * 3) repeat-x,
        linear-gradient(var(--grass), var(--grass)) left 0 bottom 0 / 100% var(--ground) no-repeat,
        var(--art-hills) left var(--hills-x, 0px) bottom var(--ground) / calc(var(--px) * 96) calc(var(--px) * 14) repeat-x,
        var(--world);
}
.cla-pupil[data-world="sky"] .panel,
.cla-pupil[data-world="sky"] .seg {
    background: var(--page);
    box-shadow: inset 0 0 0 var(--edge) var(--line-soft);
}
.cla-pupil[data-world="sky"] .pick.is-on { box-shadow: inset 0 0 0 var(--edge) var(--app-deep); }
/* Pointing at a view that's already chosen leaves it in the app's colour. */
.cla-pupil[data-world="sky"] .tool:hover:not(.is-on, [aria-selected="true"], [aria-pressed="true"]) { background: var(--wash); }

/* ------------------------------------------------------------------ phones */

@media (max-width: 600px) {
    .cla-pupil {
        --gutter: 16px;
        --t-huge: 52px;
        --t-xl: 40px;
        --t-l: 34px;
        --title-scale: 3;
        --t-m: 28px;
        --t-s: 24px;
        --t-label: 20px;
        --r-xl: 36px;
        --ground: 56px;
        --cloud-a: left -400px top 0;
        --cloud-b: left -400px top 0;
        --cloud-c: left -400px top 0;
    }
    .cla-pupil .bubble { font-size: var(--t-ui-s); padding: 4px 10px 6px; }
    .cla-pupil .tree { display: none; }
    .cla-pupil .cookie { width: 84px; height: 84px; }
    .cla-pupil .cookie b { font-size: var(--t-m); }
}

/* ------------------------------------------------------------------ calm */

@media (prefers-reduced-motion: reduce) {
    .cla-pupil *, .cla-pupil *::before, .cla-pupil *::after { transition: none !important; animation: none !important; }
    .cla-pupil .tool:active, .cla-pupil .pick:active, .cla-pupil .btn:active, .cla-pupil .tile:active { transform: none; }
}
