/* ============================================================
   Campfire — css/learn.css                   (LEARN-05, 06, 07)
   THE GAME'S LOOK: the round and its number pad, the trail, the
   rescue panels and the camp. The pair of js/learn-play.js.

   ⚠ ONE FILE, TWO SHELLS. index.html and dash/index.html both link
   it and both workers precache it: A CHANGE HERE IS A PAIRED BUMP.
   ⚠ EVERY var() RESOLVES AGAINST branding.css ALONE (L17) — the wall
   loads no app.css. No custom property is declared in this file, and
   there is no hex here: every colour is a --learn-* (or shared) token.
   ⚠ REDUCED MOTION: every animation has a tail at the foot of this
   file. Anything that exists only to move is display:none there. The
   JavaScript half (rAF loops) is in learn-play.js.
   ============================================================ */

/* ── The frame ─────────────────────────────────────────────── */
.lp {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    background: var(--bg);
    color: var(--text-primary);
    font-family: var(--font-medium);
    overflow: hidden;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}
.lp-view { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; }
.lp-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* :where() keeps these at zero specificity, so every component rule
   below (the pad's 30px keys included) wins over the reset. */
:where(.lp) button { font: inherit; color: inherit; cursor: pointer; }
:where(.lp) button:disabled { cursor: default; }
.lp-center {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 16px; padding: 24px 16px; text-align: center;
}
.lp-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.lp-pad { padding: 16px; }
.lp-spinner {
    width: 36px; height: 36px; border-radius: 50%;
    border: 4px solid var(--border); border-top-color: var(--primary);
    animation: lp-spin 0.9s linear infinite;
}

.lp-btn {
    border: 1px solid var(--border-strong);
    background: var(--surface);
    border-radius: var(--radius-md);
    padding: 10px 16px;
    font-family: var(--font-bold);
    font-size: 16px;
    min-height: 44px;
}
.lp-btn-primary { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }
.lp .lp-btn-primary { color: var(--on-primary); }
.lp-btn-big { min-height: 52px; padding: 12px 22px; font-size: 18px; border-radius: var(--radius-lg); }
.lp-btn:disabled { background: var(--surface-2); border-color: var(--border); color: var(--text-secondary); }
.lp .lp-btn:disabled { color: var(--text-secondary); }

.lp-x {
    width: 44px; height: 44px; border-radius: 50%;
    border: 0; background: var(--learn-hud-bg); color: var(--learn-hud-ink);
    font-size: 18px; box-shadow: var(--shadow-sm);
}
.lp .lp-x { color: var(--learn-hud-ink); }
.lp-x-corner { position: absolute; top: 12px; left: 12px; }

.lp-pill {
    display: inline-flex; align-items: center; gap: 6px;
    min-height: 40px; padding: 6px 12px;
    border: 0; border-radius: 999px;
    background: var(--learn-hud-bg); color: var(--learn-hud-ink);
    box-shadow: var(--shadow-sm);
    font-family: var(--font-bold); font-size: 15px; white-space: nowrap;
}
.lp .lp-pill { color: var(--learn-hud-ink); }
.lp-food-pill b { font-family: var(--font-heavy); }

.lp-toast {
    position: absolute; left: 50%; bottom: 24px; z-index: 60;
    transform: translate(-50%, 10px); opacity: 0; pointer-events: none;
    background: var(--inverse-surface); color: var(--on-inverse);
    border-radius: 999px; padding: 10px 16px; font-size: 15px;
    max-width: min(92vw, 420px); text-align: center;
    transition: opacity 0.2s, transform 0.2s;
}
.lp-toast.is-on { opacity: 1; transform: translate(-50%, 0); }
.lp-error p { font-size: 17px; max-width: 320px; }

/* ── Animals: THE ART SEAM moved to css/camp-scene.css (WILD-02). ── */

/* ── The level board (LEARN-10) ─────────────────────────────
   12 green boxes (one per fact: empty → light → dark) over 12 grey
   review boxes (light → dark; in levels 7–12 outline → light → dark).
   The only progress display in a round. */
.lp-board { display: flex; flex-direction: column; gap: 5px; width: 100%; max-width: 560px; margin: 0 auto; }
/* A box is always 1/12 of the board, so a 12-fact board fills the row
   and a shorter one (Counting's 8, Make 10's 6) sits in the middle:
   auto-fit collapses the empty tracks and justify-content centres the rest. */
.lp-board-row { display: grid; grid-template-columns: repeat(auto-fit, calc((100% - 44px) / 12)); justify-content: center; gap: 4px; }
.lp-box {
    height: 26px; border-radius: 6px; border: 2px solid transparent;
    display: flex; align-items: center; justify-content: center;
    font-family: var(--font-bold); font-size: 11px; line-height: 1; white-space: nowrap; overflow: hidden;
    transition: background 0.25s, border-color 0.25s, color 0.25s;
}
.lp-board-grey .lp-box { height: 16px; border-radius: 5px; }
.lp-g-0 { background: var(--surface); border-style: dashed; border-color: var(--border-strong); color: var(--text-tertiary); }
.lp-g-1 { background: var(--success-soft); border-color: var(--success); color: var(--success-ink); }
.lp-g-2 { background: var(--success); border-color: var(--success); color: var(--on-primary); }
.lp .lp-g-2 { color: var(--on-primary); }
.lp-r-0 { background: transparent; border-color: var(--border-strong); }
.lp-r-1 { background: var(--learn-grey-light); border-color: var(--learn-grey-light); }
.lp-r-2 { background: var(--learn-grey-dark); border-color: var(--learn-grey-dark); }
.lp-box.is-asked { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.lp-box.lp-pop { animation: lp-pop 0.5s ease-out; }
.lp-round-board .lp-box { height: 30px; font-size: 12px; }
.lp-round-board .lp-board-grey .lp-box { height: 18px; }

@media (max-width: 360px) { .lp-box { font-size: 9px; } }

/* An animal's first look: "?" (before its shape is found). */

/* ── The camp screen ───────────────────────────────────────── */

.lp-hud-gap { flex: 1; }

/* ── The scene: moved to css/camp-scene.css (WILD-02), unchanged. ── */

/* ── Overlays: map, field guide, story beat, rescue panels ─── */
.lp-overlay {
    position: absolute; inset: 0; z-index: 50;
    background: var(--overlay-scrim);
    display: flex; align-items: flex-end; justify-content: center;
}

.lp-landscape .lp-overlay { align-items: center; }

/* The field guide */

/* ── The trail (the map) ───────────────────────────────────── */

/* ── LEARN-11: the other themes. Same rules as Canyon's, each theme's
   own tokens. The painted backdrop hides the mesa, ground and pool
   fallbacks once a theme's art is in; the sky is always these.
   WILD-02: the scene's rules (sky, rocks, ground, pool, fire glow) are in
   css/camp-scene.css; the map's stay here. ── */

/* A stop's label and animal sit TOGETHER, outside the path (LEARN-10),
   so the pin — always on the path — never covers a label. */

/* The pin, in the kid's member colour (set inline). */

/* ── The round ─────────────────────────────────────────────── */
.lp-round {
    flex: 1; min-height: 0; display: flex; flex-direction: column;
    padding: max(10px, env(safe-area-inset-top)) 14px max(12px, env(safe-area-inset-bottom));
    gap: 10px;
}
.lp-round-top { display: flex; align-items: center; gap: 10px; }
.lp-round-top .lp-x { background: var(--surface-2); box-shadow: none; }
.lp .lp-round-top .lp-x { color: var(--text-primary); }
.lp-round-board { width: 100%; }
/* The round's goal (LEARN-10 v2.1): why the round ends, in words. */
.lp-goal { text-align: center; font-family: var(--font-heavy); font-size: 17px; line-height: 1.2; color: var(--text-primary); }
.lp .lp-goal { color: var(--text-primary); }
/* A fact missed twice is shown before it comes back. */
.lp-overlay-reteach { align-items: center; }
.lp-reteach {
    width: calc(100% - 32px); max-width: 420px; margin: 16px;
    background: var(--surface); color: var(--text-primary); box-shadow: var(--shadow-lg);
    border-radius: var(--radius-xl); padding: 28px 24px; cursor: pointer;
    display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center;
}

/* LEARN-35b: THE STAGE. The round is three bands — top (✕, Look, food,
   goal, board), the stage, the controls. Top and controls take their
   natural height; the stage gets exactly what's left and never spills
   onto the pad. Its one child, .lp-fit, holds the prompt at its natural
   size, scaled by --fit (LearnPrompts.fit → fitStage(), never below
   0.55). The question is max-content wide so it can be measured. */
.lp-q-area {
    flex: 1 1 0; min-height: 0; overflow: hidden; position: relative;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.lp-fit {
    flex: none; width: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 16px;
    transform: scale(var(--fit, 1)); transform-origin: 50% 50%;
}
.lp-question {
    font-family: var(--font-heavy); line-height: 1.1; text-align: center; white-space: nowrap;
    display: flex; align-items: center; justify-content: center; gap: 0.2em;
    width: max-content; max-width: none;
}
.lp-q-l { font-size: clamp(44px, 14vw, 76px); }
.lp-q-m { font-size: clamp(38px, 11vw, 64px); }
.lp-q-s { font-size: clamp(30px, 9vw, 52px); }
.lp-slot { display: inline-flex; gap: 0.08em; }
.lp-slot i {
    font-style: normal; display: inline-flex; align-items: center; justify-content: center;
    width: 0.8em; height: 1.1em; border-radius: 0.14em;
    border: 0.05em solid var(--border-strong); background: var(--surface);
}
.lp-slot i.is-filled { border-color: var(--primary); }
/* LEARN-64: the played answer (S1, a copy after a miss), faint in the box until the kid types over it. */
.lp-slot i.is-ghost { color: var(--text-tertiary); opacity: 0.55; border-style: dashed; }
/* Wrong (LEARN-10): the typed digits go red, then the right answer in PLAIN ink — never green. */
.lp-slot.is-wrong i { border-color: var(--danger); color: var(--danger); }
.lp-slot.is-shown i { border-color: var(--border-strong); background: var(--surface); color: var(--text-primary); }
.lp-slot.lp-shake { animation: lp-shake 0.45s ease-in-out; }
/* The `objects` prompt (LEARN-20): the theme's food to count, laid out
   by the server in cell units (positions are inline percentages). A
   tapped thing gets its number; the hint's numbers are quieter. */
.lp-objs-wrap { width: 100%; display: flex; justify-content: center; align-items: center; }
/* With things to count, the drawing takes the room the round leaves
   (fitObjects() sizes it) and the pad gives a little back. */
.lp-round.has-objs .lp-q-area { min-height: 0; }
.lp-round.has-objs .lp-fit { flex: 1 1 0; min-height: 0; gap: 8px; }
.lp-round.has-objs .lp-objs-wrap { flex: 1 1 0; min-height: 0; }
.lp-round.has-objs .lp-question { font-size: clamp(26px, 7.5vw, 48px); }
.lp-round.has-objs .lp-key { min-height: 48px; font-size: 26px; }
.lp-round.has-objs .lp-pad { gap: 6px; }
.lp-objs-wrap:empty { display: none; }
.lp-objs { position: relative; flex: none; }
.lp-obj-slot {
    position: absolute; box-sizing: border-box;
    border: 2px solid var(--border-strong); background: var(--surface);
}
.lp-obj {
    position: absolute; padding: 0; margin: 0; border: 0; background: none;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer; -webkit-tap-highlight-color: transparent; touch-action: manipulation;
    border-radius: 22%;
}
.lp-obj-img { width: 88%; height: 88%; object-fit: contain; pointer-events: none; transition: transform 0.12s, opacity 0.12s; }
.lp-obj-emo { font-size: 1.6em; line-height: 1; pointer-events: none; }
.lp-objs .lp-obj-emo { font-size: min(34px, 7vw); }
.lp-obj:active .lp-obj-img { transform: scale(0.9); }
.lp-obj.is-marked .lp-obj-img, .lp-obj.is-marked .lp-obj-emo { opacity: 0.55; }
.lp-obj-n {
    position: absolute; right: -4%; top: -4%; min-width: 58%; height: 58%;
    display: none; align-items: center; justify-content: center; padding: 0 3px; box-sizing: border-box;
    border-radius: 999px; background: var(--primary); color: var(--on-primary);
    font-family: var(--font-heavy); font-size: min(15px, 3.6vw); line-height: 1; pointer-events: none;
}
.lp-obj.is-marked .lp-obj-n { display: flex; }
.lp-obj.is-hinted .lp-obj-n { background: var(--learn-key-glow); color: var(--learn-key-glow-ink); }
/* CAMPS-LV LV-04 (Counting, circles): the star on the thing to start from. */
.lp-obj-star {
    position: absolute; left: -8%; top: -8%; width: 46%; height: 46%; pointer-events: none;
    filter: drop-shadow(0 0 1px var(--learn-key-glow-ink));
}
.lp-obj-star::before {
    content: ''; position: absolute; inset: 0; background: var(--learn-key-glow);
    clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.lp-teach .lp-objs, .lp-reteach .lp-objs { margin: 4px auto; }
/* LEARN-28 (Taking away within 20): a taken thing stays in its place,
   faded, with a cross over it; it can't be tapped or numbered. */
.lp-obj.is-gone { cursor: default; pointer-events: none; }
.lp-obj.is-gone .lp-obj-img, .lp-obj.is-gone .lp-obj-emo { opacity: 0.4; }
.lp-obj-x { position: absolute; inset: 6%; pointer-events: none; }
.lp-obj-x::before, .lp-obj-x::after {
    content: ''; position: absolute; left: 50%; top: -4%; width: 14%; height: 108%;
    margin-left: -7%; border-radius: 999px; background: var(--learn-gone);
    box-shadow: 0 0 0 1.5px var(--learn-gone-edge);
}
.lp-obj-x::before { transform: rotate(45deg); }
.lp-obj-x::after  { transform: rotate(-45deg); }
.lp-teach-fact.lp-teach-fact-s { font-size: clamp(32px, 9vw, 52px); }
.lp-landscape .lp-objs-wrap { flex: none; }
/* LEARN-31 (Learning to multiply): the groups are rings drawn behind
   the things, and each group's (or row's, or part's) total can be shown
   beside it: the hint shows every running total but the last, a miss and
   the cards show them all. A tally is sized in cqw (a share of the
   drawing's width), so it scales with the things. The lead is the
   strategy line above the question ("2 × 6 = 12 → double it"). */
.lp-objs.has-tally { container-type: inline-size; }
.lp-obj-ring {
    position: absolute; box-sizing: border-box; pointer-events: none;
    border: 2px dashed var(--border-strong); border-radius: 22px; background: var(--surface-2);
}
.lp-obj-tally {
    position: absolute; transform: translate(-50%, -50%); display: none;
    padding: 0.05em 0.4em; border-radius: 999px; line-height: 1.15; white-space: nowrap;
    font-family: var(--font-heavy); font-style: normal; pointer-events: none;
    background: var(--surface-2); color: var(--text-primary);
}
.lp-obj-tally.is-shown { display: block; }
.lp-obj-tally.is-hint.is-shown { background: var(--learn-key-glow); color: var(--learn-key-glow-ink); }
.lp-lead {
    font-family: var(--font-bold); font-size: clamp(18px, 5vw, 26px); line-height: 1.2;
    color: var(--text-secondary); text-align: center; padding: 0 12px;
}
.lp-lead[hidden] { display: none; }
.lp-round.has-objs .lp-lead { font-size: clamp(16px, 4.4vw, 22px); }
.lp-teach-lead { font-family: var(--font-bold); font-size: 20px; color: var(--text-secondary); }
/* The `clock` prompt (LEARN-21): an analog face drawn in SVG from tokens.
   A fixed character of a shaped answer (the colon of [ ]:[ ][ ]) sits
   between the boxes in the question's own ink. */
.lp-clock-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.lp-clock-face { fill: var(--surface); stroke: var(--text-primary); stroke-width: 4; }
.lp-clock-tick { stroke: var(--text-secondary); stroke-width: 1.5; stroke-linecap: round; }
.lp-clock-tick.is-five { stroke: var(--text-primary); stroke-width: 3; }
.lp-clock-num { fill: var(--text-primary); font-family: var(--font-heavy); font-size: 19px; text-anchor: middle; dominant-baseline: central; }
.lp-clock-hour { stroke: var(--text-primary); stroke-width: 8; stroke-linecap: round; }
.lp-clock-min { stroke: var(--primary-ink); stroke-width: 4.5; stroke-linecap: round; }
.lp-clock-pin { fill: var(--text-primary); }
.lp-slot-fix { font-weight: inherit; padding: 0 0.02em; }
/* The `sequence` prompt (LEARN-24): the numbers as stepping stones, the
   answer slot in the blank one's place. The hint's hop ('+5') arcs over
   each gap; a card draws the answer as a marked stone. fitSeq() shrinks a
   row that is wider than its room. */
.lp-question.lp-q-seq { font-size: clamp(26px, 8vw, 50px); }
.lp-seq { display: flex; align-items: center; justify-content: center; flex-wrap: nowrap; white-space: nowrap; padding-top: 0.9em; }
.lp-seq-n {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 1.5em; height: 1.3em; padding: 0 0.28em; box-sizing: border-box;
    border-radius: 0.5em; background: var(--surface-2); color: var(--text-primary);
    font-family: var(--font-heavy);
}
.lp-seq-n.is-answer { background: var(--primary); color: var(--on-primary); }
.lp-seq .lp-slot { padding: 0 0.1em; }
.lp-seq-gap { position: relative; flex: none; width: 0.55em; align-self: stretch; }
.lp-seq-gap.is-hop::before {
    content: ''; position: absolute; left: -0.6em; right: -0.6em; top: -0.42em; height: 0.4em;
    border: 0.07em solid var(--learn-key-glow); border-bottom: 0; border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}
.lp-seq-jump {
    position: absolute; left: 50%; top: -1.05em; transform: translateX(-50%); z-index: 1;
    font-style: normal; font-family: var(--font-heavy); font-size: 0.45em; line-height: 1;
    padding: 0.1em 0.35em; border-radius: 999px;
    background: var(--learn-key-glow); color: var(--learn-key-glow-ink);
}
.lp-teach-fact.lp-seq, .lp-reteach .lp-seq { font-size: clamp(26px, 8vw, 46px); }

.lp-bonus { width: min(320px, 80%); height: 10px; border-radius: 5px; background: var(--surface-2); overflow: hidden; }
.lp-bonus span { display: block; height: 100%; background: var(--learn-bar); transform-origin: 0 50%; }

.lp-controls { display: flex; flex-direction: column; gap: 10px; }
.lp-pad { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.lp-key {
    min-height: 64px; border-radius: var(--radius-lg);
    border: 1px solid var(--border); background: var(--surface);
    font-family: var(--font-heavy); font-size: 30px; color: var(--text-primary);
    box-shadow: var(--shadow-xs);
    transition: transform 0.08s, background 0.2s;
}
.lp .lp-key { color: var(--text-primary); }
.lp-key:active { transform: scale(0.95); background: var(--surface-2); }
/* LEARN-35b: the bottom row is blank · 0 · delete, as on the PIN pads.
   The delete key is the digits' size, radius and press feedback; its icon
   is the one --icon-delete (branding.css), drawn in the key's text colour. */
.lp-key.is-blank { background: none; border: 0; box-shadow: none; pointer-events: none; }
.cf-del-ico {
    display: inline-block; width: 1.15em; height: 1em; vertical-align: middle;
    background: currentColor;
    -webkit-mask: var(--icon-delete) center / contain no-repeat; mask: var(--icon-delete) center / contain no-repeat;
}
.lp .lp-key.is-glow { background: var(--learn-key-glow); border-color: var(--learn-key-glow); color: var(--learn-key-glow-ink); }
.lp .lp-key.is-dim  { background: var(--surface-2); color: var(--text-tertiary); box-shadow: none; }
/* The `choices` input (LEARN-22): 2–3 big buttons instead of the pad.
   Text choices share a row (> = <); pictures (two groups to compare)
   sit side by side and a text choice after them ("The same") takes a
   row of its own. A dropped choice (the hint) greys like a dimmed key;
   a wrong tap goes red and shakes, then the right one is ringed in PLAIN
   ink, never green (LEARN-10's rule for the slot). */
.lp-choices { display: flex; flex-wrap: wrap; gap: 10px; }
.lp-choice {
    flex: 1 1 0; min-width: 0; min-height: 96px; padding: 8px 6px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
    border-radius: var(--radius-lg); border: 2px solid var(--border); background: var(--surface);
    box-shadow: var(--shadow-xs); color: var(--text-primary);
    transition: transform 0.08s, background 0.2s, border-color 0.2s;
}
.lp .lp-choice { color: var(--text-primary); }
.lp-choice:active { transform: scale(0.96); }
.lp-choice-v { font-family: var(--font-heavy); font-size: clamp(34px, 11vw, 52px); line-height: 1; }
.lp-choice-note { font-size: 13px; color: var(--text-secondary); font-family: var(--font-bold); }
.lp-choice-dots { display: flex; justify-content: center; width: 100%; }
.lp-choice-dots:empty { display: none; }
.lp-choice-dots .lp-objs { max-width: 180px; margin-top: 6px; }
/* Pictures take the room the round leaves: on a phone one above the
   other (a wide button draws bigger things), on the wall side by side.
   fitChoicePics() sizes each drawing to its button. */
.lp-choices.has-pics { flex: 1 1 auto; min-height: 0; flex-direction: column; flex-wrap: nowrap; }
.lp-choices.has-pics .lp-choice.is-pic { flex: 1 1 0; min-height: 96px; padding: 10px; }
.lp-choices.has-pics .lp-choice.is-wide { flex: none; min-height: 56px; }
.lp-landscape .lp-choices.has-pics { flex-direction: row; flex-wrap: wrap; align-content: center; }
.lp-landscape .lp-choices.has-pics .lp-choice.is-pic { flex: 1 1 calc(50% - 5px); min-height: 220px; }
.lp-landscape .lp-choices.has-pics .lp-choice.is-wide { flex: 1 1 100%; }
.lp-choices.has-pics .lp-choice.is-wide .lp-choice-v { font-size: 24px; }
.lp .lp-choice.is-picked { border-color: var(--primary); }
.lp .lp-choice.is-wrong { border-color: var(--danger); background: var(--danger-soft); }
.lp .lp-choice.is-answer { border-color: var(--text-primary); border-width: 4px; }
.lp .lp-choice.is-dim { background: var(--surface-2); color: var(--text-tertiary); box-shadow: none; border-color: var(--surface-2); }
.lp .lp-choice.is-dim .lp-choice-note { color: var(--text-tertiary); }
.lp-choice.lp-shake { animation: lp-shake 0.45s ease-in-out; }
.lp-choice.lp-pop { animation: lp-stamp 0.45s ease-out; }
.lp-round.has-pics .lp-q-area { min-height: 0; flex: 0 0 auto; padding: 8px 0; }
.lp-question.lp-q-words { font-size: clamp(26px, 7.5vw, 44px); white-space: normal; width: auto; max-width: 100%; }
.lp-round.has-pics .lp-controls { flex: 1 1 auto; min-height: 0; }
/* A hint underlines the digits that decide (46 ? 43: the 6 and the 3). */
/* A word the module asks to stand out ("more", "less"): heavier, in the
   primary ink, underlined in the hint's yellow. */
.lp-stress {
    font-family: var(--font-heavy); font-weight: inherit; color: var(--primary-ink);
    text-decoration: underline; text-decoration-thickness: 0.1em; text-underline-offset: 0.14em;
    text-decoration-color: var(--learn-key-glow);
}
.lp .lp-stress { color: var(--primary-ink); }
.lp-em { font-style: normal; text-decoration: underline; text-decoration-thickness: 0.08em; text-underline-offset: 0.12em; text-decoration-color: var(--learn-key-glow); }
.lp-slot-pick i { width: 1em; }
/* The teach and "Remember" cards draw the pictures too, the answer ringed. */
.lp-choices.has-pics.lp-choices-card { width: 100%; max-width: 380px; flex: none; }
.lp-choices.has-pics.lp-choices-card .lp-choice { flex: none; width: 100%; min-height: 0; padding: 8px; box-sizing: border-box; }
.lp-choices-card .lp-choice { min-height: 0; box-shadow: none; }
.lp-teach-said { font-size: 18px; color: var(--text-secondary); font-family: var(--font-bold); }
.lp-aids { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.lp-aid { min-width: 112px; }
.lp-streak { font-family: var(--font-heavy); font-size: 18px; }

.lp-landscape .lp-round {
    display: grid; grid-template-columns: 1fr minmax(300px, 42%);
    grid-template-rows: auto auto auto 1fr; column-gap: 24px;
}
.lp-landscape .lp-controls { grid-column: 2; grid-row: 1 / span 4; justify-content: center; }
.lp-landscape .lp-q-area { min-height: 0; }
.lp-landscape .lp-round-top, .lp-landscape .lp-goal, .lp-landscape .lp-round-board, .lp-landscape .lp-q-area { grid-column: 1; }

.lp-q-area.lp-stamp { animation: lp-stamp 0.45s ease-out; }
.lp-q-area.lp-shake { animation: lp-shake 0.45s ease-in-out; }
/* LEARN-35b: the food reward — the theme's food art at --learn-fly-size
   with its +2 beside it; flyFood() pops, holds and flies it (WAAPI). */
.lp-fly {
    position: absolute; z-index: 60; pointer-events: none; opacity: 0;
    display: flex; align-items: center; gap: 0.1em; transform: translate(-50%, -50%);
    font-family: var(--font-heavy); font-size: calc(var(--learn-fly-size) * 0.3); line-height: 1; color: var(--learn-food);
    text-shadow: 0 0 3px var(--surface), 0 0 6px var(--surface);
    will-change: transform, opacity;
}
.lp-fly-ico { display: block; height: var(--learn-fly-size); width: auto; }
.lp-fly-ico.is-emo { height: auto; font-size: calc(var(--learn-fly-size) * 0.8); line-height: 1; }
/* The pill's icon: the same art, the size the flight lands at. */
.lp-food-ico { display: block; height: var(--learn-fly-land); width: auto; }
.lp-food-ico.is-emo { height: auto; font-size: calc(var(--learn-fly-land) * 0.8); line-height: 1; }

/* The goal: "We do it" / "You do it" and the boxes to fill, drawn small. */
.lp-goal { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 8px; }

.lp-tap-ico { font-family: var(--font-heavy); font-size: 30px; line-height: 1; color: var(--text-primary); }
   /* pre-v2.2.11; the glyph is now .lp-la */

/* The teach card */
.lp-teach {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
    padding: 24px; text-align: center; cursor: pointer;
}
.lp-teach-k { font-size: 20px; color: var(--text-secondary); font-family: var(--font-bold); }
.lp-teach-fact { font-size: clamp(44px, 13vw, 72px); font-family: var(--font-heavy); }
.lp-teach-tap { font-size: 15px; color: var(--text-secondary); }

/* The round card */
.lp-roundcard {
    flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
    padding: 24px 18px; text-align: center; overflow-y: auto;
}
.lp-card-title { font-family: var(--font-heavy); font-size: 28px; }

/* A moment ON the card: the shape, a rescue, the Summit. No overlay. */

.lp-card-btns { margin-top: 8px; width: 100%; max-width: 420px; }
.lp-card-btns .lp-btn { flex: 1; }
/* LEARN-13: on a phone the card's buttons are full width, stacked —
   Keep playing on top (it's first in the markup). */
@media (max-width: 640px) {
    .lp-card-btns { flex-direction: column; flex-wrap: nowrap; max-width: none; }
    .lp-card-btns .lp-btn { width: 100%; flex: none; }
}

/* ── Keyframes ─────────────────────────────────────────────── */
@keyframes lp-spin    { to { transform: rotate(360deg); } }
@keyframes lp-stamp   { 0% { transform: scale(1); } 35% { transform: scale(1.08); } 100% { transform: scale(1); } }
@keyframes lp-shake   { 0%, 100% { transform: translateX(0); } 20% { transform: translateX(-8px); } 40% { transform: translateX(7px); } 60% { transform: translateX(-5px); } 80% { transform: translateX(3px); } }
@keyframes lp-pop     { 0% { transform: scale(1); } 40% { transform: scale(1.25); } 100% { transform: scale(1); } }

/* ── Reduced motion: every animation above stops ───────────── */
@media (prefers-reduced-motion: reduce) {
    .lp-spinner { animation-duration: 3s; }
    .lp-q-area.lp-stamp,
.lp-q-area.lp-shake,
.lp-slot.lp-shake,
.lp-box.lp-pop,
.lp-choice.lp-shake,
.lp-choice.lp-pop { animation: none; }
    .lp-fly { display: none; }
    
    .lp-toast, .lp-box, .lp-key { transition: none; }
    .lp-key:active, .lp-choice:active { transform: none; }
    /* WILD-02: the camp's own tails are in css/camp-scene.css. */
}

/* ═══ LEARN-32: teach first ═══════════════════════════════════
   The "show me" cards, the round's ? button, "Got it" after a miss,
   support, the stacked sum, the clock's one hand / hour slice / 5s, and
   matched rows for comparing. Only declared tokens (L17). */
.lp-show-words { font-family: var(--font-bold); font-size: clamp(18px, 5vw, 24px); line-height: 1.3; max-width: 30ch; }
.lp-show .lp-teach-k { color: var(--text-primary); font-family: var(--font-heavy); font-size: 22px; }
.lp-show-btn { font-family: var(--font-bold); font-size: 15px; cursor: pointer; border: 0; }

/* A miss explains itself and waits for "Got it". */
.lp-why {
    display: flex; flex-direction: column; align-items: center; gap: 10px; width: min(92%, 440px);
    background: var(--surface-2); color: var(--text-primary); border-radius: var(--radius-lg);
    padding: 12px 14px; text-align: center; animation: lp-rise-in 0.25s ease-out;
}
.lp-why-text { font-family: var(--font-bold); font-size: clamp(17px, 4.6vw, 22px); line-height: 1.3; }
.lp-why-btn { min-width: 140px; }
@keyframes lp-rise-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Support on ("we do", a step-back, a boost): a quiet frame, nothing more. */
.lp-q-area.is-supported { outline: 2px dashed var(--border-strong); outline-offset: -6px; border-radius: var(--radius-lg); }

/* The stacked sum: a grid of columns (sign, then tens, ones), a line, the slot. */
.lp-q-col { font-size: clamp(38px, 11vw, 60px); }
.lp-colwrap { display: flex; align-items: center; justify-content: center; gap: 0.5em; }
.lp-col { display: grid; column-gap: 0.12em; row-gap: 0.04em; align-items: center; justify-items: center; font-family: var(--font-heavy); line-height: 1.05; }
.lp-col-h { font-family: var(--font-bold); font-size: 0.28em; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.04em; }
.lp-col-d { width: 0.8em; text-align: center; }
.lp-col-sign { width: 0.6em; text-align: center; color: var(--text-secondary); }
.lp-col-c { height: 0.55em; display: flex; align-items: flex-end; justify-content: center; }
.lp-col-carry { font-size: 0.45em; color: var(--primary); visibility: hidden; }
.lp-col-carry.is-shown { visibility: visible; }
.lp-col-line { height: 0.07em; background: var(--text-primary); width: 100%; border-radius: 0.04em; margin: 0.06em 0; }
.lp-slot-col { justify-self: end; gap: 0.12em; }
.lp-slot-col i.is-next { border-color: var(--learn-key-glow); }
.lp-col-help {
    display: flex; flex-direction: column; gap: 4px; font-family: var(--font-bold); font-size: clamp(14px, 3.8vw, 18px);
    color: var(--text-secondary); text-align: left; visibility: hidden; white-space: normal; max-width: 12em;
}
.lp-col-help.is-shown { visibility: visible; }
/* LEARN-35b: on a portrait stage the help lines sit UNDER the sum, in one row. */
.lp-q-area.is-tall .lp-colwrap { flex-direction: column; gap: 0.15em; }
.lp-q-area.is-tall .lp-col-help { flex-direction: row; gap: 14px; max-width: none; text-align: center; }
.lp-teach .lp-colwrap { font-size: clamp(34px, 10vw, 54px); }
.lp-teach .lp-col-help, .lp-overlay .lp-col-help { font-size: 16px; }

/* The clock (LEARN-32): the hour's slice, and the minutes by 5s round the edge. */
.lp-clock-zone { fill: var(--learn-key-glow); opacity: 0.35; }
.lp-clock-five { fill: var(--primary); font-family: var(--font-bold); font-size: 13px; text-anchor: middle; dominant-baseline: central; }

/* Matched rows: one above the other, lined up from the left, in every layout. */
.lp-choices.has-pics.is-stack { flex-direction: column; flex-wrap: nowrap; }
.lp-choices.is-stack .lp-choice.is-pic { align-items: flex-start; justify-content: center; }
.lp-landscape .lp-choices.has-pics.is-stack { flex-direction: column; flex-wrap: nowrap; align-content: stretch; }
.lp-landscape .lp-choices.has-pics.is-stack .lp-choice.is-pic { flex: 1 1 0; min-height: 120px; width: 100%; }

/* The "show me" replay sits over the round like "Remember": a card on the scrim. */
.lp-overlay-show { align-items: center; }
.lp-overlay-show .lp-teach {
    flex: none; width: min(94%, 520px); max-height: 92%; overflow-y: auto;
    background: var(--surface); color: var(--text-primary); border-radius: var(--radius-xl);
}
@media (prefers-reduced-motion: reduce) { .lp-why { animation: none; } }

/* The `coins` prompt (LEARN-25): coins and dollar bills drawn in SVG from
   tokens, each at the place and size the server sends (a dime is the
   smallest coin). The running totals are the `objects` tallies, sized a
   little smaller so '$4.99' fits under a coin. */
.lp-coins { position: relative; }
.lp-coin { position: absolute; display: block; pointer-events: none; }
.lp-coin-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.lp-coin-face { stroke-width: 3; }
.lp-coin-rim { fill: none; stroke-width: 2; stroke-dasharray: 3 3; }
.lp-coin.is-copper .lp-coin-face { fill: var(--learn-coin-copper); stroke: var(--learn-coin-copper-rim); }
.lp-coin.is-copper .lp-coin-rim { stroke: var(--learn-coin-copper-rim); }
.lp-coin.is-silver .lp-coin-face { fill: var(--learn-coin-silver); stroke: var(--learn-coin-silver-rim); }
.lp-coin.is-silver .lp-coin-rim { stroke: var(--learn-coin-silver-rim); }
.lp-coin-label {
    fill: var(--learn-coin-ink); font-family: var(--font-heavy); font-size: 30px;
    text-anchor: middle; dominant-baseline: central;
}
.lp-bill-face { fill: var(--learn-bill); stroke: var(--learn-bill-line); stroke-width: 3; }
.lp-bill-line { fill: none; stroke: var(--learn-bill-line); stroke-width: 2; }
.lp-bill-oval { fill: none; stroke: var(--learn-bill-line); stroke-width: 2; }
.lp-bill-label { fill: var(--learn-bill-ink); font-family: var(--font-heavy); font-size: 30px; text-anchor: middle; dominant-baseline: central; }
.lp-coin-tally { padding: 0.05em 0.3em; }

/* ═══ LEARN-37: the Look player ═══════════════════════════════
   A card is drawn finished; the player hides what each step will draw
   (lp-pl-off; an answer is only blanked, lp-pl-blank, so its box stays)
   and brings each piece back with lp-pl-in. Tokens only. */
.lp-pl-off { opacity: 0 !important; }
.lp-pl-blank { color: transparent !important; }
.lp-pl-in { animation: lp-pl-in 0.3s ease-out; }
@keyframes lp-pl-in { 0% { opacity: 0; transform: scale(0.6); } 100% { opacity: 1; transform: none; } }
svg .lp-pl-in, .lp-obj-ring.lp-pl-in, .lp-obj-tally.lp-pl-in { animation: lp-pl-fade 0.3s ease-out; }
@keyframes lp-pl-fade { from { opacity: 0; } to { opacity: 1; } }
.lp-pl-slot { display: inline-flex; min-width: 1.1em; justify-content: center; padding: 0 0.12em; margin: 0 0.1em;
    border: 3px solid var(--border-strong); border-radius: var(--radius-md); line-height: 1.1; }
.lp-obj-slot.is-glow { outline: 3px solid var(--learn-key-glow); outline-offset: -3px; }
.lp-clock-five.is-lit { fill: var(--text-primary); font-family: var(--font-heavy); font-size: 16px; }
.lp-play-foot { display: flex; align-items: center; justify-content: center; gap: 16px; flex-wrap: wrap; }
/* LOOK-CTA: Again is a quiet round "replay" button; the way forward (Play,
   ✓, →) is the loud thing in the row. */
.lp-play-foot { gap: 20px; }
.lp-again-btn {
    flex: none; width: 52px; height: 52px; padding: 0; border-radius: 50%;
    display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
    background: var(--surface); border: 2px solid var(--border-strong); color: var(--text-secondary);
}
.lp .lp-again-btn { color: var(--text-secondary); }
.lp-again-btn:active { transform: scale(0.94); }
.lp-again-ico { width: 26px; height: 26px; display: block; }
.lp-show-go { min-width: 180px; min-height: 60px; font-size: 22px; font-family: var(--font-heavy); }
/* BUG-06 (Andy, kids' feedback 2026-10-12): the moving "show me" picture made
   kids try to drag its things. Once it has played (.is-playing comes off),
   the way forward glows and bounces: the Play button, the → / ✓; in a played
   question, the ringed right answer glows. Reduced motion: a still glow ring. */
@keyframes lp-cta-bounce { 0%, 100% { translate: 0 0; } 50% { translate: 0 -7px; } }
@keyframes lp-cta-glow { 0%, 100% { box-shadow: 0 0 0 3px var(--bg), 0 0 0 4px transparent; } 50% { box-shadow: 0 0 0 4px var(--bg), 0 0 0 9px var(--learn-key-glow); } }
.lp-show:not(.is-playing) .lp-show-go { animation: lp-cta-bounce 1.1s ease-in-out 0.3s infinite, lp-cta-glow 1.1s ease-in-out 0.3s infinite; }
.lp-show:not(.is-playing) .lp-teach-tap .lp-tap-ico {
    display: inline-flex; align-items: center; justify-content: center; min-width: 56px; min-height: 56px; border-radius: 50%;
    background: var(--learn-key-glow); color: var(--learn-key-glow-ink);
    animation: lp-cta-bounce 1.1s ease-in-out 0.3s infinite;
}
.lp-round:not(.is-playing) .lp-choice.is-answer { animation: lp-cta-glow 1.4s ease-in-out 0.3s infinite; }
@media (prefers-reduced-motion: reduce) {
    .lp-show:not(.is-playing) .lp-show-go,
    .lp-round:not(.is-playing) .lp-choice.is-answer { animation: none; box-shadow: 0 0 0 4px var(--bg), 0 0 0 8px var(--learn-key-glow); }
    .lp-show:not(.is-playing) .lp-teach-tap .lp-tap-ico { animation: none; }
}
.lp-why-card { gap: 10px; }
.lp-overlay-why { align-items: center; }
@media (prefers-reduced-motion: reduce) {
    .lp-pl-in, svg .lp-pl-in, .lp-obj-ring.lp-pl-in, .lp-obj-tally.lp-pl-in { animation: none; }
}
.lp-reteach .lp-colwrap { font-size: clamp(34px, 10vw, 54px); }

/* ═══ LEARN-38: icons, rods, matched rows played ═══════════════ */
.lp-q-ico { display: inline-flex; align-items: flex-end; margin-right: 0.3em; vertical-align: bottom; }
.lp-ico { height: 1.6em; width: auto; display: block; }
.lp-ico-box { fill: var(--primary); stroke: var(--primary-ink, var(--text-primary)); stroke-width: 1.5; }
.lp-ico-less .lp-ico-box { fill: var(--learn-key-glow); }
.lp-ico-t { fill: var(--text-primary); font-family: var(--font-heavy); font-size: 26px; text-anchor: middle; dominant-baseline: central; }
.lp-obj.is-glow { filter: drop-shadow(0 0 4px var(--learn-key-glow)) drop-shadow(0 0 2px var(--learn-key-glow)); }
.lp-obj.is-dim, .lp-obj-ring.is-dim { opacity: 0.3; transition: opacity 0.3s; }
.lp-objs.is-rods .lp-obj-ring { border-radius: var(--radius-md); }
.lp-pl-slide { animation: lp-pl-slide 0.6s ease-out; }
@keyframes lp-pl-slide { from { opacity: 0; transform: translateX(120%); } to { opacity: 1; transform: none; } }
.lp-pick-row { display: flex; gap: 12px; justify-content: center; align-items: flex-end; width: 100%; max-width: 380px; }
.lp-pick { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 8px;
    border: 3px solid transparent; border-radius: var(--radius-lg); box-sizing: border-box; }
.lp-pick.is-answer { border-color: var(--text-primary); }
.lp-pick-v { font-family: var(--font-heavy); font-size: clamp(32px, 9vw, 48px); line-height: 1; }
.lp-pick .lp-objs { margin: 0 auto; }
@media (prefers-reduced-motion: reduce) { .lp-pl-slide { animation: none; } }
.lp-pick-row.is-stack { flex-direction: column; align-items: stretch; }
.lp-pick-row.is-stack .lp-pick { flex-direction: row; justify-content: flex-start; gap: 14px; }
.lp-pick-row.is-stack .lp-pick-v { min-width: 1.4em; text-align: right; }
.lp-pick-row.is-stack .lp-pick .lp-objs { margin: 0; flex: 1 1 auto; }
.lp-controls [hidden] { display: none !important; }

/* ═══ LEARN-39: the picture prompt (library art above the question) ═══ */
.lp-picture { display: flex; justify-content: center; flex: none; }
.lp-pic { display: flex; align-items: center; justify-content: center; aspect-ratio: 16 / 9;
    height: clamp(72px, 16vh, 150px); border-radius: var(--radius-lg); overflow: hidden; background: var(--surface-2); }
.lp-pic-card { height: clamp(72px, 14vh, 130px); }
.lp-pic-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.lp-pic-emo { font-size: clamp(40px, 9vh, 80px); line-height: 1; }

/* ═══ LEARN-41: picture sources, picture buttons, the match step ═══
   A drawn object (food, a plant, a thing) and a theme animal are shown
   whole in a square; a place (a camp backdrop) fills its box, its clear
   sky painted behind it and its horizon kept in view. */
.lp-pic.is-obj, .lp-pic.is-spr { aspect-ratio: 1; height: clamp(96px, 22vh, 190px); background: none; overflow: visible; }
.lp-pic.lp-pic-card.is-obj, .lp-pic.lp-pic-card.is-spr, .lp-pic.lp-pic-card.is-place { height: clamp(80px, 16vh, 150px); }
.lp-pic.is-obj .lp-pic-img { object-fit: contain; }
.lp-pic-spr { display: block; width: 100%; height: 100%; }
.lp-pic.is-place { position: relative; aspect-ratio: 16 / 10; height: clamp(96px, 22vh, 190px); background: linear-gradient(var(--learn-sky-top), var(--learn-sky-low)); }
.lp-pic.is-place .lp-pic-bd { position: absolute; inset: 0; object-position: 50% calc(var(--hz, 0.5) * 100%); }
.lp-pic-over { position: absolute; bottom: 4%; height: calc(var(--h, 0.5) * 100%); width: auto; left: calc(var(--x, 0.5) * 100%); transform: translateX(-50%); pointer-events: none; }
/* In a button the picture fills it; the button is labelled, the picture is not. */
.lp-pic.lp-pic-btn { height: 100%; width: 100%; max-height: 100%; aspect-ratio: auto; border-radius: var(--radius-md, 10px); }
.lp-pic.lp-pic-btn.is-obj, .lp-pic.lp-pic-btn.is-spr { background: none; }
.lp-choices.has-pics.is-imgs { flex-direction: row; flex-wrap: nowrap; align-items: stretch; }
.lp-choices.has-pics.is-imgs .lp-choice.is-img { flex: 1 1 0; min-width: 0; min-height: 96px; padding: 8px; }
.lp-choices.has-pics.is-imgs .lp-choice.is-img:has(.is-place) { padding: 5px; }
.lp-landscape .lp-choices.has-pics.is-imgs .lp-choice.is-img { flex: 1 1 0; min-height: 150px; }
.lp .lp-choice.is-img.is-dim .lp-pic { opacity: 0.3; filter: grayscale(1); }
/* The cards (Look, Why): the buttons a row under the picture. */
.lp-choices.has-pics.lp-choices-card.is-imgs { flex-direction: row; gap: 8px; max-width: 420px; }
.lp-choices.has-pics.lp-choices-card.is-imgs .lp-choice { flex: 1 1 0; width: auto; height: clamp(64px, 13vh, 120px); padding: 5px; }
.lp-choice.is-img.is-glow { box-shadow: 0 0 0 4px var(--learn-key-glow); }
/* LOOK-GHOST: .lp-pl-match (the answer button sliding across the card) is
   gone; the match step flies a copy of the art instead (ghostFly() in
   js/learn-prompts.js) and the button stays where it is, glowing. */
.lp-pl-ghost { will-change: transform, opacity; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, 0.18)); }
.lp-pl-slotfill { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; animation: lp-pl-fade 0.3s ease-out; }
.lp-ico-leaf { fill: var(--learn-leaf); stroke: var(--learn-shape-line); stroke-width: 2.5; stroke-linejoin: round; }
.lp-ico-eye { fill: var(--learn-shape-line); }

/* ═══ LEARN-46: the shape prompt (SVG, 0–100 box) ═══════════════
   Every line keeps its width at any size (non-scaling-stroke). Tones
   tell pieces apart and never carry meaning. Marks kept for after a miss
   (lp-sh-after) show with support or a miss; card-only marks (the fold)
   show on the Look card and the picture Why alone. Grown by LEARN-51
   (grid, labels, walk) and LEARN-55 (lines, rays, arcs, protractor). */
.lp-shape { container-type: inline-size; }
.lp-sh-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.lp-sh-svg * { vector-effect: non-scaling-stroke; }
.lp-sh-poly, .lp-sh-circle, .lp-sh-rect, .lp-sh-path { fill: none; stroke: none; }
.lp-sh-svg .is-fill { stroke: var(--surface); stroke-width: 1.5; stroke-linejoin: round; }
.lp-sh-svg .is-tone1 { fill: var(--learn-shape-1); }
.lp-sh-svg .is-tone2 { fill: var(--learn-shape-2); }
.lp-sh-svg .is-tone3 { fill: var(--learn-shape-3); }
.lp-sh-svg .is-tone4 { fill: var(--learn-shape-4); }
.lp-sh-svg .is-part { fill: var(--learn-shape-part); }
.lp-sh-svg .is-soft { fill: var(--learn-shape-soft); }
.lp-sh-svg .is-outline { stroke: var(--learn-shape-line); stroke-width: 3; stroke-linejoin: round; }
.lp-sh-svg .is-ghost { fill: none; stroke: var(--learn-shape-line); stroke-width: 1.5; stroke-dasharray: 4 4; opacity: 0.55; }
.lp-sh-seg line { stroke: var(--learn-shape-line); stroke-width: 3; stroke-linecap: round; }
.lp-sh-seg.is-cut line { stroke: var(--learn-shape-cut); stroke-width: 3.5; }
.lp-sh-seg.is-guide line { stroke: var(--learn-key-glow); stroke-width: 3; stroke-dasharray: 6 5; opacity: 0.9; }
.lp-sh-seg.is-side line { stroke: var(--learn-shape-mark); stroke-width: 5; }
.lp-sh-path.is-side { fill: none; stroke: var(--learn-shape-mark); stroke-width: 5; stroke-linecap: round; }   /* CAMPS-LV LV-04: a curved side traced */
.lp-sh-seg.is-grid line { stroke: var(--learn-shape-grid); stroke-width: 1.5; }
.lp-sh-seg.is-edge line { stroke: var(--learn-shape-mark); stroke-width: 4.5; }
.lp-sh-seg.is-sym line { stroke: var(--learn-shape-mark); stroke-width: 3; stroke-dasharray: 7 5; }
.lp-sh-seg.is-thin line { stroke-width: 2; }
.lp-sh-seg.is-bold line { stroke-width: 4.5; }
.lp-sh-end { fill: var(--learn-shape-line); stroke: none; }
.lp-sh-seg.is-edge .lp-sh-end, .lp-sh-seg.is-sym .lp-sh-end { fill: var(--learn-shape-mark); }
.lp-sh-dot { fill: var(--learn-shape-line); }
.lp-sh-dot.is-corner, .lp-sh-dot.is-mark { fill: var(--learn-shape-mark); }
.lp-sh-text { fill: var(--text-primary); font-family: var(--font-heavy); text-anchor: middle; dominant-baseline: central; }
.lp-sh-text.is-num { fill: var(--learn-shape-mark); }
.lp-sh-text.is-label { font-family: var(--font-bold); }
.lp-sh-text.is-soft { fill: var(--text-secondary); font-family: var(--font-bold); }
.lp-sh-svg .is-folded { fill: var(--learn-shape-part); fill-opacity: 0.55; stroke: var(--learn-shape-line); stroke-width: 2; stroke-dasharray: 5 4; }
.lp-sh-anim { transform-box: view-box; transform-origin: 0 0; }
.lp-sh-anim.is-moving { transition: transform 0.9s ease-in-out; }
.lp-sh-sqc { fill: none; stroke: var(--learn-shape-mark); stroke-width: 2.5; }
.lp-sh-arc path { fill: none; stroke: var(--learn-shape-mark); stroke-width: 2.5; }
.lp-sh-arct { fill: var(--learn-shape-mark); font-family: var(--font-heavy); text-anchor: middle; dominant-baseline: central; }
.lp-sh-pface { fill: var(--learn-shape-soft); fill-opacity: 0.55; stroke: var(--learn-shape-line); stroke-width: 1.5; }
.lp-sh-ptick { stroke: var(--learn-shape-line); stroke-width: 1; }
.lp-sh-ptick.is-ten { stroke-width: 1.6; }
.lp-sh-pnum { fill: var(--text-secondary); font-family: var(--font-bold); font-size: 5px; text-anchor: middle; dominant-baseline: central; }
.lp-sh-pnum.is-inner { font-size: 4.2px; opacity: 0.8; }
.lp-sh-pnum.is-hi { fill: var(--learn-shape-mark); font-family: var(--font-heavy); opacity: 1; }
.lp-sh-pdot { fill: var(--learn-shape-line); }
.lp-sh-walkdot { fill: var(--learn-shape-mark); stroke: var(--surface); stroke-width: 1.5; }
.lp-sh-walkt { fill: var(--learn-shape-mark); font-family: var(--font-heavy); font-size: 9px; text-anchor: middle; dominant-baseline: central; }
.lp-sh-walk .lp-sh-walkdot, .lp-sh-walk .lp-sh-walkt { transition: cx 0.25s, cy 0.25s, x 0.25s, y 0.25s; }
.lp-shape.is-live .lp-sh-after { opacity: 0; }
.lp-shape.is-live .lp-sh-after.is-shown { opacity: 1; transition: opacity 0.4s; }
.lp-shape.is-live .lp-sh-cardonly { display: none; }
.lp-sh-svg .lp-pl-off { opacity: 0 !important; }
/* On a card, the shapes stack like the round's buttons, each a share of the height. */
.lp-choices.has-pics.lp-choices-card.is-shapes { flex-direction: column; align-items: center; gap: 6px; }
.lp-choices.has-pics.lp-choices-card.is-shapes .lp-choice { flex: none; width: auto; max-width: 100%; padding: 6px 10px; }
.lp-choices-card.is-shapes .lp-shape { width: auto !important; height: min(16vh, 150px); max-width: 100%; margin: 0 auto; }
.lp-landscape .lp-choices.has-pics.lp-choices-card.is-shapes { flex-direction: row; }
.lp-choice .lp-shape { margin: 0 auto; }
/* The icons (LEARN-46): a shape, a glowing side, a corner dot, a cut. */
.lp-ico-shape { fill: var(--learn-shape-1); stroke: var(--learn-shape-line); stroke-width: 3; stroke-linejoin: round; }
.lp-ico-part { fill: var(--learn-shape-part); }
.lp-ico-glow { stroke: var(--learn-shape-mark); stroke-width: 7; stroke-linecap: round; }
.lp-ico-dot { fill: var(--learn-shape-mark); }
.lp-ico-cut { stroke: var(--learn-shape-line); stroke-width: 3; }
@media (prefers-reduced-motion: reduce) {
    .lp-sh-anim.is-moving, .lp-sh-walk .lp-sh-walkdot, .lp-sh-walk .lp-sh-walkt { transition: none; }
}
/* A shape question with shape buttons (LEARN-46): the drawing keeps two fifths
   of the room and the buttons sit in a row under it. */
.lp-round.has-pics.has-objs .lp-q-area { flex: 2 1 0; }
.lp-round.has-pics.has-objs .lp-controls { flex: 3 1 0; }
.lp-round.has-objs .lp-choices.has-pics.is-shapes { flex-direction: row; flex-wrap: nowrap; }
.lp-round.has-objs .lp-choices.has-pics.is-shapes .lp-choice.is-pic { flex: 1 1 0; min-width: 0; }
/* A card with a shape above shape buttons: the drawing a little smaller, the buttons in a row. */
.lp-teach > .lp-shape, .lp-reteach > .lp-shape { max-height: 24vh; width: auto !important; height: min(24vh, 200px); max-width: 100%; }
.lp-teach:has(> .lp-shape) .lp-choices-card.is-shapes, .lp-reteach:has(> .lp-shape) .lp-choices-card.is-shapes { flex-direction: row; }
.lp-teach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-shape, .lp-reteach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-shape { height: min(13vh, 110px); }
/* FIND-ONE-FIX: the row of shape buttons on a Look / Remember card ran off
   the right edge on a phone (three fixed 110px drawings plus padding in a
   342px card), so the third button was cut off and the row looked jammed.
   Each button now takes an equal share of the row and its drawing scales
   down inside it, keeping the same 110px ceiling on wide screens. */
.lp-teach:has(> .lp-shape) .lp-choices-card.is-shapes, .lp-reteach:has(> .lp-shape) .lp-choices-card.is-shapes { gap: 10px; }
.lp-teach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-choice, .lp-reteach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-choice { flex: 1 1 0; min-width: 0; max-width: 130px; }
.lp-teach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-shape, .lp-reteach:has(> .lp-shape) .lp-choices-card.is-shapes .lp-shape {
    width: 100% !important; height: auto; max-width: min(13vh, 110px); max-height: min(13vh, 110px); }
/* …and the prompt under it breaks evenly rather than leaving one word alone. */
.lp-teach-fact-s { text-wrap: balance; }
/* …and on a card with shape buttons the icon ("△ = ▷") gets its own line
   above the words, so the drawing, the buttons, the icon and the sentence
   read as four separate rows rather than one crowded run. */
.lp-teach:has(> .lp-choices-card.is-shapes) .lp-teach-fact .lp-q-ico,
.lp-reteach:has(> .lp-choices-card.is-shapes) .lp-teach-fact .lp-q-ico { display: flex; justify-content: center; margin: 0 auto 4px; }
.lp-choices.has-pics .lp-choice.is-pic:has(.lp-shape) { padding: 6px; }
.lp-sh-svg .is-row { fill: var(--learn-key-glow); fill-opacity: 0.22; stroke: var(--learn-shape-mark); stroke-width: 2.5; }
/* LEARN-55: the square-corner reference, the protractor's reading, the angle to find. */
.lp-sh-sqc.is-ref { stroke: var(--learn-key-glow); stroke-width: 3; stroke-dasharray: 5 4; }
.lp-sh-svg .is-read { fill: none; stroke: var(--learn-shape-mark); stroke-width: 2.5; }
.lp-sh-arc.is-whole path { stroke: var(--text-secondary); stroke-dasharray: 3 3; }
.lp-sh-arc.is-whole .lp-sh-arct { fill: var(--text-secondary); }
.lp-sh-arc.is-ask path { stroke: var(--learn-key-glow); stroke-width: 3; }
.lp-sh-arc.is-ask .lp-sh-arct { fill: var(--text-primary); }
.lp-choices.is-words { flex-direction: column; flex-wrap: nowrap; }
.lp-choices.is-words .lp-choice { flex: 1 1 0; min-height: 52px; }
.lp-choices.is-words .lp-choice-v { font-size: clamp(22px, 6.5vw, 30px); }
/* LV-07: a word button over 22 letters wraps to two lines, a size down, so it fits its button. */
.lp-choices.is-words.is-long .lp-choice-v { font-size: clamp(16px, 4.6vw, 24px); line-height: 1.1; }
.lp-landscape .lp-choices.is-words { flex-direction: row; }

/* ═══ LEARN-42 / 43 / 47: icons, letters, rows, day bars, fade_to ═══ */
.lp-ico-cloud { fill: var(--learn-k-cloud); stroke: var(--learn-shape-line); stroke-width: 3; stroke-linejoin: round; }
.lp-ico-sun { fill: var(--learn-k-sun); stroke: var(--learn-shape-line); stroke-width: 2.5; }
.lp-ico-ray { stroke: var(--learn-shape-line); stroke-width: 4; stroke-linecap: round; fill: none; }
.lp-ico-moon { fill: var(--learn-k-sun); stroke: var(--learn-shape-line); stroke-width: 2.5; stroke-linejoin: round; }
.lp-ico-heart { fill: var(--learn-k-heart); }
.lp-ico-night { fill: var(--learn-k-night); }
.lp-ico-sunbar { fill: var(--learn-k-sun); }
.lp-ico-frame { fill: none; stroke: var(--learn-shape-line); stroke-width: 3; }
.lp-ico-shade { fill: var(--learn-k-shade); }
.lp-ico-stick { stroke: var(--learn-k-bark); stroke-width: 5; stroke-linecap: round; }
.lp-ico-beam { fill: var(--learn-k-sun); opacity: 0.75; }
.lp-ico-l { fill: var(--text-primary); font-family: var(--font-teach); font-size: 48px; text-anchor: middle; }
.lp-ico-l.is-small { font-size: 40px; }
/* A letter (LEARN-43): big, in the teaching font, on a card-coloured tile. */
.lp-pic.is-letter { aspect-ratio: 1; height: clamp(96px, 22vh, 190px); background: var(--surface-2); }
.lp-pic-letter { font-family: var(--font-teach); color: var(--text-primary); line-height: 1; font-size: calc(clamp(96px, 22vh, 190px) * 0.72); }
.lp-pic.lp-pic-card.is-letter .lp-pic-letter { font-size: calc(clamp(80px, 16vh, 150px) * 0.72); }
.lp-pic.lp-pic-card.is-letter { height: clamp(80px, 16vh, 150px); }
.lp-pic.lp-pic-btn.is-letter { background: none; container-type: size; }
.lp-pic.lp-pic-btn .lp-pic-letter { font-size: min(82cqh, 72px); }
/* A row (LEARN-47): small scenes side by side, an empty slot at the end. */
.lp-pic.is-row { aspect-ratio: auto; height: auto; background: none; overflow: visible; }
.lp-pic-row { display: flex; gap: 6px; align-items: center; }
.lp-pic-cell { display: block; width: clamp(80px, 26vw, 150px); aspect-ratio: 16 / 9; border-radius: var(--radius-md, 10px); overflow: hidden; background: var(--surface-2); }
.lp-pic-slot { border: 3px dashed var(--learn-shape-line); background: none; box-sizing: border-box; }
.lp-pic-cell.is-obj .lp-pic-img { object-fit: contain; }
/* A day bar under a picture (LEARN-47): 24 hours, the light part centred. */
.lp-pic.has-bar { flex-direction: column; overflow: visible; background: none; }
.lp-pic.has-bar > .lp-pic-img { flex: 1 1 auto; min-height: 0; border-radius: var(--radius-md, 10px); }
/* v2.2.11: taller, with a sun in the day part and a moon in each night part. */
.lp-pic-bar { display: flex; width: 100%; height: 26px; flex: none; margin-top: 6px; border-radius: 9px; border: 2px solid var(--learn-shape-line); box-sizing: border-box; overflow: hidden; }
.lp-pic-bar > span { display: flex; align-items: center; justify-content: center; height: 100%; min-width: 0; }
.lp-pic-bar svg { width: 18px; height: 18px; flex: none; }
.lp-bar-n { background: var(--learn-k-night); }
.lp-bar-d { background: var(--learn-k-sun); }
.lp-bar-sun { fill: #fff6d6; stroke: var(--learn-shape-line); stroke-width: 1.4; }
.lp-bar-ray line { stroke: var(--learn-shape-line); stroke-width: 1.8; stroke-linecap: round; }
.lp-bar-moon { fill: #f7e7a8; }
/* LV-06 (sky): a tick at every hour on the day bar, and the day bars drawn as shapes (L4). */
.lp-pic-bar { position: relative; }
.lp-pic-bar::after { content: ''; position: absolute; inset: 0; pointer-events: none; opacity: 0.35;
    background: repeating-linear-gradient(90deg, transparent 0, transparent calc(100% / 24 - 1px), var(--learn-shape-line) calc(100% / 24 - 1px), var(--learn-shape-line) calc(100% / 24)); }
.lp-sh-rect.is-barday { fill: var(--learn-k-sun); stroke: none; }
.lp-sh-rect.is-barnight { fill: var(--learn-k-night); stroke: none; }
.lp-sh-rect.is-barframe { stroke: var(--learn-shape-line); stroke-width: 1.6; }
.lp-sh-seg.is-bartick line { stroke: var(--learn-shape-line); stroke-width: 0.8; opacity: 0.55; }
/* fade_to (LEARN-42): the next sky fades in over the picture. */
.lp-pic { position: relative; }
.lp-pic-fade { position: absolute; inset: 0; opacity: 0; transition: opacity 1.2s ease; }
.lp-pic-fade.is-in { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .lp-pic-fade { transition: none; } }
/* LEARN-47: the shadow drawing's tones (the `shape` prompt). */
.lp-sh-poly.is-ground, .lp-sh-rect.is-ground { fill: var(--learn-k-ground); stroke: none; }
.lp-sh-circle.is-sun { fill: var(--learn-k-sun); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-poly.is-shadow, .lp-sh-path.is-shadow { fill: var(--learn-k-shade); stroke: none; }
/* v2.2.11: Day and night's shadow scene: a sky and a soft hill under the painted tree. */
.lp-sh-rect.is-sky { fill: var(--learn-sky-top); stroke: none; opacity: 0.55; }
.lp-sh-path.is-ground { fill: var(--learn-k-ground); stroke: none; }
.lp-sh-circle.is-leaf, .lp-sh-poly.is-leaf { fill: var(--learn-leaf); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-rect.is-bark, .lp-sh-poly.is-bark { fill: var(--learn-k-bark); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-path.is-sunpath { fill: none; stroke: var(--learn-k-sun); stroke-width: 1.2; stroke-dasharray: 3 3; }
.lp-sh-rect.is-pane { fill: var(--learn-sky-top); stroke: var(--learn-shape-line); stroke-width: 1.5; }
.lp-sh-rect.is-cloudy { fill: var(--learn-k-cloud); stroke: var(--learn-shape-line); stroke-width: 1.5; }
.lp-sh-rect.is-solid { fill: var(--learn-k-bark); stroke: var(--learn-shape-line); stroke-width: 1.5; }
.lp-sh-poly.is-beam { fill: var(--learn-k-sun); stroke: none; opacity: 0.8; }
.lp-sh-svg .lp-sh-poly.is-beam.is-faint { opacity: 0.35; }
/* LEARN-42: scene buttons (16:9 weather and sky pictures) stay 16:9, two to a row, so each still reads as a place. */
.lp-choices.has-pics.is-imgs.is-scenes { flex-wrap: wrap; justify-content: center; align-content: center; }
.lp-choices.has-pics.is-imgs.is-scenes .lp-choice.is-img { flex: 0 1 calc(50% - 6px); min-height: 0; padding: 5px; }
.lp-choices.has-pics.is-imgs.is-scenes .lp-pic.lp-pic-btn { aspect-ratio: 16 / 9; height: auto; }
.lp-choices.has-pics.is-imgs.is-scenes .lp-pic.lp-pic-btn.has-bar { aspect-ratio: auto; }
.lp-choices.has-pics.is-imgs.is-scenes .lp-pic.lp-pic-btn.has-bar > .lp-pic-img { aspect-ratio: 16 / 9; height: auto; }
.lp-landscape .lp-choices.has-pics.is-imgs.is-scenes .lp-choice.is-img { flex: 0 1 calc(33% - 8px); min-height: 0; }
/* LEARN-47: wide shape buttons (a beam, a tree and its shadow): two to a row, each as tall as its drawing. */
.lp-choices.has-pics.is-shapes.is-wideshapes, .lp-round.has-objs .lp-choices.has-pics.is-shapes.is-wideshapes { flex-direction: row; flex-wrap: wrap; justify-content: center; align-content: center; }
.lp-choices.has-pics.is-shapes.is-wideshapes .lp-choice.is-pic, .lp-round.has-objs .lp-choices.has-pics.is-shapes.is-wideshapes .lp-choice.is-pic { flex: 0 1 calc(50% - 6px); min-width: 0; min-height: 0; height: auto; padding: 6px; }
.lp-landscape .lp-choices.has-pics.is-shapes.is-wideshapes .lp-choice.is-pic { flex: 0 1 calc(33% - 8px); }
.lp-choices.is-wideshapes .lp-choice .lp-shape { width: 100% !important; height: auto; }
.lp-choices.has-pics.lp-choices-card.is-wideshapes { flex-direction: row; flex-wrap: wrap; justify-content: center; max-width: 420px; }
.lp-choices.has-pics.lp-choices-card.is-wideshapes .lp-choice { flex: 0 1 calc(50% - 6px); padding: 5px; }
.lp-choices-card.is-wideshapes .lp-shape { height: auto !important; }
/* On a wide stage (a tablet, the wall) three in a row, never taller than the stage can spare. */
.lp-choices.has-pics.is-imgs.is-scenes .lp-choice.is-img,
.lp-choices.has-pics.is-shapes.is-wideshapes .lp-choice.is-pic,
.lp-round.has-objs .lp-choices.has-pics.is-shapes.is-wideshapes .lp-choice.is-pic { flex-basis: min(calc(50% - 6px), 30vh); }

/* ═══ LEARN-44, 45, 48, 49 (v2.2.9) ═══ */
/* Icons */
.lp-ico-x { stroke: var(--learn-k-heart); stroke-width: 6; stroke-linecap: round; fill: none; }
.lp-ico-yes { stroke: var(--learn-k-yes); stroke-width: 8; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.lp-ico-rock { fill: var(--learn-k-cloud); stroke: var(--learn-shape-line); stroke-width: 3; stroke-linejoin: round; }
.lp-ico-band { stroke: var(--learn-k-bark); stroke-width: 9; stroke-linecap: round; fill: none; }
.lp-ico-water { fill: var(--learn-k-water); }
.lp-ico-ice { fill: var(--learn-k-ice); stroke: var(--learn-shape-line); stroke-width: 3; stroke-linejoin: round; }
.lp-ico-l.is-tiny { font-size: 22px; }
/* LEARN-49: word buttons with their icon (hard · soft, float · sink, ice · water, yes · no). */
.lp-choice.has-ico { gap: 4px; }
.lp-choice-ico .lp-ico { height: clamp(34px, 7vh, 52px); }
.lp-choices.is-icos .lp-choice-v { font-size: clamp(24px, 7vw, 36px); }
/* LEARN-48: a picture button's name under it (the habitat, in the Learn levels). */
.lp-choice.is-img.has-cap { gap: 3px; }
.lp-choice.is-img.has-cap .lp-pic { flex: 1 1 auto; min-height: 0; }
.lp-choice-cap { flex: none; font-family: var(--font-heavy); font-size: clamp(13px, 3.6vw, 17px); line-height: 1.1; color: var(--text-primary); }
.lp-choices-card .lp-choice-cap { font-size: 12px; }
/* LEARN-48: How many kinds? Small cells for a long row; each kind's number in a badge. */
.lp-pic-row.is-many { gap: 4px; }
.lp-pic-row.is-many .lp-pic-cell { width: clamp(42px, 12vw, 92px); aspect-ratio: 1; }
.lp-pic-cell { position: relative; }
.lp-pic-cell.is-spr, .lp-pic-cell.is-obj { background: none; overflow: visible; }
.lp-pic-cell .lp-pic-spr { width: 100%; height: 100%; }
.lp-pic-cell.is-counted { box-shadow: 0 0 0 3px var(--learn-key-glow); }
.lp-kind-n { position: absolute; top: -6px; left: -4px; min-width: 22px; height: 22px; padding: 0 4px; box-sizing: border-box;
    border-radius: 11px; background: var(--learn-shape-mark); color: #fff; font: 15px/22px var(--font-heavy); text-align: center; }
.lp-pic-cell.is-again .lp-kind-n { opacity: 0.55; }
/* LV-06 (weather L4): a row cell's caption (the day letters M T W T F), at the cell's foot. */
.lp-pic-cap { position: absolute; left: 50%; bottom: 3px; transform: translateX(-50%); min-width: 1.3em; padding: 1px 4px; box-sizing: border-box;
    border-radius: 6px; background: var(--surface); color: var(--text-primary); font: 12px/1.3 var(--font-heavy); font-style: normal; text-align: center; pointer-events: none; }
.lp-pic-row.is-many.is-days .lp-pic-cell { width: clamp(56px, 17vw, 110px); }
.lp-pic-cell.is-small > :not(.lp-kind-n):not(.lp-pic-cap) { transform: scale(0.62); transform-origin: 50% 100%; }
/* LEARN-49: before → after, the arrow back (the `back_*` steps). */
.lp-pic.is-pair { aspect-ratio: auto; height: auto; background: none; overflow: visible; }
.lp-pic-row.is-pair .lp-pic-cell { width: clamp(80px, 30vw, 160px); aspect-ratio: 1; background: none; }
.lp-pic-row.is-pair .lp-pic-cell.is-scene, .lp-pic-row.is-pair .lp-pic-cell.is-place { aspect-ratio: 16 / 9; }
.lp-pair-arrows { position: relative; width: 44px; flex: none; }
.lp-pair-arrows svg { width: 44px; height: 44px; display: block; overflow: visible; }
.lp-pair-go, .lp-pair-back { stroke: var(--learn-shape-line); stroke-width: 3.5; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.lp-pair-back { opacity: 0; }
.lp-pair-back.is-on { opacity: 1; transition: opacity 0.3s; }
.lp-pair-back.is-ok { stroke: var(--learn-k-yes); }
.lp-pair-back.is-stop { stroke: var(--learn-k-heart); stroke-dasharray: 14 30; }
.lp-pair-mark { position: absolute; left: 50%; top: 100%; transform: translateX(-50%); font: 28px/1 var(--font-heavy); }
.lp-pair-mark.is-ok { color: var(--learn-k-yes); }
.lp-pair-mark.is-stop { color: var(--learn-k-heart); }
/* LEARN-49: the tub of water (Float or sink?) and the drop step. */
.lp-pic.has-tub { aspect-ratio: 1; overflow: visible; }
.lp-tub-wrap { position: relative; display: block; width: 100%; height: 100%; }
.lp-tub-wrap .lp-tub-thing { position: absolute; left: 25%; top: 0; width: 50%; height: 42%; object-fit: contain; z-index: 1; }
.lp-tub { position: absolute; left: 0; bottom: 0; width: 100%; height: 50%; }
.lp-tub-water { fill: var(--learn-k-water); opacity: 0.55; }
.lp-tub-rim { stroke: var(--learn-shape-line); stroke-width: 2.5; fill: none; vector-effect: non-scaling-stroke; }
.lp-tub-thing.is-float { animation: lp-float 1.6s ease-in forwards; }
.lp-tub-thing.is-sink { animation: lp-sink 1.6s ease-in forwards; }
@keyframes lp-float { 0% { top: 0; } 55% { top: 44%; } 75% { top: 30%; } 100% { top: 34%; } }
@keyframes lp-sink { 0% { top: 0; } 50% { top: 44%; } 100% { top: 56%; } }
/* LEARN-49: press (a fingertip; a soft thing squishes) and bend. */
.lp-finger { position: absolute; left: 50%; top: 0; width: 18%; height: 34%; margin-left: -9%; border-radius: 40% 40% 50% 50%;
    background: var(--learn-k-skin); border: 2px solid var(--learn-shape-line); z-index: 2; animation: lp-finger 1.6s ease-in-out forwards; }
@keyframes lp-finger { 0% { transform: translateY(-10%); } 45%, 65% { transform: translateY(45%); } 100% { transform: translateY(-10%); } }
.lp-pl-squish .lp-pic-img { animation: lp-squish 1.6s ease-in-out; transform-origin: 50% 100%; }
@keyframes lp-squish { 0%, 30% { transform: none; } 50%, 62% { transform: scale(1.12, 0.72); } 100% { transform: none; } }
.lp-pl-hard .lp-pic-img { animation: lp-hold 1.6s ease-in-out; }
@keyframes lp-hold { 0%, 44% { transform: none; } 50% { transform: translateY(2%); } 56%, 100% { transform: none; } }
.lp-pl-bend .lp-pic-img { animation: lp-bend 1.8s ease-in-out; transform-origin: 50% 90%; }
@keyframes lp-bend { 0% { transform: none; } 35%, 65% { transform: rotate(-16deg) skewX(-14deg) scaleY(0.9); } 100% { transform: none; } }
.lp-pl-stiff .lp-pic-img { animation: lp-stiff 1.8s ease-in-out; }
@keyframes lp-stiff { 0%, 30% { transform: none; } 38% { transform: rotate(-2deg); } 46% { transform: rotate(2deg); } 54% { transform: rotate(-1deg); } 62%, 100% { transform: none; } }
/* LEARN-45: the letter tiles (the `letters` input) and the word's boxes. */
.lp-tiles { display: grid; grid-template-columns: repeat(var(--n, 4), 1fr); gap: 8px; }
.lp-tiles[hidden] { display: none; }
.lp .lp-tile { font-family: var(--font-teach); font-size: 34px; min-height: 56px; text-transform: none; }
.lp .lp-tile.is-used { opacity: 0.3; box-shadow: none; }
.lp-slot-tiles { position: relative; gap: 0.12em; font-family: var(--font-teach); }
.lp-slot-tiles i { width: auto; min-width: 0.9em; padding: 0 0.08em; box-sizing: border-box; }
.lp-slot-tiles i.is-magic { margin-left: 0.35em; }
.lp-q-area.is-supported .lp-slot-tiles i.is-next { border-color: var(--learn-key-glow); box-shadow: 0 0 0 0.05em var(--learn-key-glow); }
.lp-slot-tiles i.is-lit { background: var(--learn-key-glow); color: var(--learn-key-glow-ink); }
.lp-slot-tiles i.is-vowel.is-long { color: var(--learn-shape-mark); }
.lp-magic-arc { position: absolute; right: 0.42em; top: -0.42em; width: 2.15em; height: 0.46em; box-sizing: border-box;
    border: 0.05em solid var(--border-strong); border-bottom: 0; border-radius: 50% 50% 0 0 / 100% 100% 0 0; pointer-events: none; }
.lp-magic-arc.is-on { border-color: var(--learn-shape-mark); border-width: 0.07em; }
.lp-build { display: flex; flex-direction: column; align-items: center; gap: 14px; font-size: clamp(30px, 8vw, 46px); margin-top: 0.3em; }
.lp-tray-card { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; }
.lp-tile-card { font-family: var(--font-teach); font-size: 0.62em; line-height: 1.2; padding: 0.05em 0.35em; border: 1px solid var(--border);
    border-radius: var(--radius-md, 10px); background: var(--surface); }
.lp-tile-card.is-used { opacity: 0.25; }
.lp-choices.is-teach .lp-choice-v { font-family: var(--font-teach); text-transform: none; }
.lp-teach-word { font-family: var(--font-teach); font-size: clamp(34px, 9vw, 48px); line-height: 1.1; }
.lp-slot-word b { font-size: 0.8em; padding: 0 0.2em; }
@media (prefers-reduced-motion: reduce) {
    .lp-tub-thing.is-float, .lp-tub-thing.is-sink, .lp-finger, .lp-pl-squish .lp-pic-img, .lp-pl-hard .lp-pic-img,
    .lp-pl-bend .lp-pic-img, .lp-pl-stiff .lp-pic-img { animation-duration: 0.01s; }
    .lp-tub-thing.is-float { top: 34%; }
    .lp-tub-thing.is-sink { top: 56%; }
}
/* A theme animal in a picture button keeps its shape: the largest square the button holds
   (a tall narrow button on a phone stretched the sprite strip). Fixes What animals need too. */
.lp-pic.lp-pic-btn.is-spr { container-type: size; }
.lp-pic.lp-pic-btn.is-spr .lp-pic-spr { width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); flex: none; }
/* Rows of animals and things (Babies' what comes next, How many kinds?): square cells. */
.lp-pic-row .lp-pic-cell.is-spr, .lp-pic-row .lp-pic-cell.is-obj { width: clamp(56px, 20vw, 120px); aspect-ratio: 1; }
.lp-pic-row.is-many .lp-pic-cell.is-spr, .lp-pic-row.is-many .lp-pic-cell.is-obj { width: clamp(40px, 14vw, 92px); }
.lp-pic-row:has(.is-spr, .is-obj) .lp-pic-slot { width: clamp(56px, 20vw, 120px); aspect-ratio: 1; }
/* LV-07: a row of 4 animals in a card (habitats L3's Why) stays inside the card on a wide screen. */
.lp-pic-card .lp-pic-row:has(> .lp-pic-cell:nth-child(4)) .lp-pic-cell.is-spr,
.lp-pic-card .lp-pic-row:has(> .lp-pic-cell:nth-child(4)) .lp-pic-cell.is-obj { width: clamp(48px, 18vw, 68px); }

/* v2.2.11: the goal line is empty outside a practice round (no boxes, no "We do it"). */
.lp-goal:empty { display: none; }
/* v2.2.11: the question in plain words, above its picture (round, Look card, Why). */
.lp-ask {
    font-family: var(--font-heavy); font-size: clamp(20px, 5.6vw, 28px); line-height: 1.2;
    color: var(--text-primary); text-align: center; padding: 0 12px; margin-bottom: 6px;
}
.lp-ask[hidden] { display: none; }
.lp-landscape .lp-ask { font-size: clamp(20px, 3vw, 30px); }
/* v2.2.11: a scene the question asks about is the biggest thing on screen (it was
   16vh while two object buttons below it stretched to fill the band). */
.lp-picture .lp-pic.is-scene:not(.lp-pic-card) { height: auto; width: min(82vw, 48vh, 480px); }
.lp-landscape .lp-picture .lp-pic.is-scene:not(.lp-pic-card) { width: min(40vw, 48vh, 480px); }
.lp-choices.has-pics.is-imgs:not(.is-scenes) .lp-choice.is-img { max-height: 30vh; }
/* v2.2.11: Line Awesome glyphs drawn inline (laIcon()): sized like the font's icons. */
.lp-la { display: inline-block; width: 1.25em; height: 1.25em; vertical-align: -0.25em; fill: currentColor; flex: none; }

/* v2.2.11: the goal line can be empty (hidden), so the landscape rows are pinned:
   without it the question would fall into an auto row and collapse. */
.lp-landscape .lp-round-top { grid-row: 1; }
.lp-landscape .lp-goal { grid-row: 2; }
.lp-landscape .lp-round-board { grid-row: 3; }
.lp-landscape .lp-q-area { grid-row: 4; }

/* ── CAMPS-02: a level's ten dots, and every game's end card ───────────
   Dark green when a question is answered right, grey to go, the current
   one ringed. A miss adds no dot. The card shows what the game earned
   (food and coins, never money) and the set of ten levels. */
.lp-round-dots { width: 100%; display: flex; justify-content: center; padding: 4px 0 2px; }
.lp-dots { display: flex; gap: 8px; justify-content: center; flex-wrap: nowrap; }
.lp-dot {
    width: 18px; height: 18px; border-radius: 50%;
    background: var(--learn-grey-light); border: 2px solid var(--learn-grey-light);
    transition: background 0.25s, border-color 0.25s;
}
.lp-dot.is-done { background: var(--success); border-color: var(--success); }
.lp-dot.is-asked { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary); }
.lp-dot.lp-pop { animation: lp-pop 0.5s ease-out; }
.lp-dots-set .lp-dot { width: 14px; height: 14px; }
@media (max-width: 360px) { .lp-dots { gap: 6px; } .lp-dot { width: 15px; height: 15px; } }
.lp-levelcard { position: relative; }
.lp-levelcard .lp-x-corner { position: absolute; top: 12px; left: 12px; }
.lp-card-earn { display: flex; gap: 22px; justify-content: center; align-items: center; }
.lp-earn { display: inline-flex; align-items: center; gap: 6px; font-family: var(--font-heavy); font-size: 26px; color: var(--text-primary); }
.lp-earn .lp-food-ico, .lp-earn .lp-coin-img, .lp-earn .lp-coin-svg { width: 40px; height: 40px; object-fit: contain; }
.lp-coin-a { fill: var(--wild-star); stroke: var(--wild-star-edge); stroke-width: 2; }
.lp-coin-b { fill: none; stroke: var(--wild-star-edge); stroke-width: 1.5; opacity: 0.6; }
@media (prefers-reduced-motion: reduce) { .lp-dot { transition: none; } .lp-dot.lp-pop { animation: none; } }

/* ═══ CAMPS-14…17: the new games' drawings ═══════════════════════════════
   Magnets and pushes (bar magnets, push arrows, a box, a ball, a swing),
   Rocks and fossils (rock layers with their grain), Built to survive (a
   body outline, one inside part lit), and Life cycles' ring of stages. */
.lp-sh-svg .is-magn { fill: var(--learn-k-magn); }
.lp-sh-svg .is-mags { fill: var(--learn-k-mags); }
.lp-sh-text.is-magt { fill: #FFFFFF; font-family: var(--font-heavy); }
.lp-sh-rect.is-sheet { fill: var(--surface); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-rect.is-cloth { fill: var(--learn-shape-4); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-rect.is-box { fill: var(--learn-k-bark); }
.lp-sh-rect.is-wall { fill: var(--learn-k-steel); }
.lp-sh-circle.is-ball { fill: var(--learn-k-magn); }
.lp-sh-seg.is-push line { stroke: var(--learn-k-push); stroke-width: 4.5; }
.lp-sh-seg.is-push .lp-sh-end { fill: var(--learn-k-push); }
.lp-sh-rect.is-frame { fill: none; stroke: var(--learn-shape-grid); stroke-width: 1.2; }
.lp-sh-svg .is-rock1 { fill: var(--learn-k-rock1); }
.lp-sh-svg .is-rock2 { fill: var(--learn-k-rock2); }
.lp-sh-svg .is-rock3 { fill: var(--learn-k-rock3); }
.lp-sh-svg .is-rock4 { fill: var(--learn-k-rock4); }
/* LV-07 (earth L6): a coal band, an ash band, round pebbles. */
.lp-sh-svg .is-coal { fill: var(--learn-k-coal); }
.lp-sh-svg .is-ash { fill: var(--learn-k-ash); }
.lp-sh-circle.is-pebble { stroke: var(--learn-shape-line); stroke-width: 1; }
.lp-sh-dot.is-grain { fill: var(--learn-shape-line); opacity: 0.35; }
.lp-sh-seg.is-grain line { stroke: var(--learn-shape-line); stroke-width: 1.2; opacity: 0.3; }
.lp-sh-svg .is-body { fill: var(--learn-k-body); stroke: var(--learn-shape-line); stroke-width: 2; stroke-linejoin: round; }
.lp-sh-seg.is-limb line { stroke: var(--learn-k-body); stroke-width: 9; }
.lp-sh-seg.is-bone line { stroke-width: 2; }
.lp-sh-svg .is-organ { fill: var(--learn-shape-soft); stroke: var(--learn-shape-line); stroke-width: 1.2; }
.lp-sh-svg .is-organ.is-dim { opacity: 0.35; }
.lp-sh-svg .is-organ.is-lit { fill: var(--learn-k-organ); stroke-width: 2.2; }
.lp-sh-seg.is-organ.is-lit line { stroke: var(--learn-k-organ); stroke-width: 3.2; }
.lp-sh-seg.is-organ.is-dim line { stroke: var(--learn-shape-line); }
.lp-sh-path.is-organ { fill: var(--learn-shape-soft); }
.lp-sh-path.is-organ.is-lit { fill: var(--learn-k-organ); }

/* CAMPS-15: a life cycle as a ring of stages, clockwise, arrows between. */
.lp-pic-row.is-ring { position: relative; display: grid; gap: clamp(18px, 6vw, 34px); justify-items: center; align-items: center; }
.lp-pic-row.is-ring4 { grid-template-columns: repeat(2, auto); grid-template-areas: "a b" "d c"; }
.lp-pic-row.is-ring4 > .lp-pic-cell:nth-child(1) { grid-area: a; }
.lp-pic-row.is-ring4 > .lp-pic-cell:nth-child(2) { grid-area: b; }
.lp-pic-row.is-ring4 > .lp-pic-cell:nth-child(3) { grid-area: c; }
.lp-pic-row.is-ring4 > .lp-pic-cell:nth-child(4) { grid-area: d; }
.lp-pic-row.is-ring3 { grid-template-columns: repeat(2, auto); grid-template-areas: "a a" "c b"; }
.lp-pic-row.is-ring3 > .lp-pic-cell:nth-child(1) { grid-area: a; }
.lp-pic-row.is-ring3 > .lp-pic-cell:nth-child(2) { grid-area: b; }
.lp-pic-row.is-ring3 > .lp-pic-cell:nth-child(3) { grid-area: c; }
.lp-pic-row.is-ring .lp-pic-cell { width: clamp(52px, 16vh, 104px); aspect-ratio: 1; }
.lp-pic-row.is-ring .lp-ring-arrows { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.lp-ring-arrows path { fill: none; stroke: var(--learn-shape-mark); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; }

/* ════════════════════════════════════════════════════════════
   CAMPS-LV (LV-02): shared renderer additions. Every colour is a token
   from css/branding.css.
   ════════════════════════════════════════════════════════════ */
/* R1: card and question lines wrap evenly, never to one orphan word. */
.lp-show-words, .lp-ask, .lp-teach-said, .lp-why-text, .lp-teach-lead, .lp-show .lp-teach-k { text-wrap: balance; }
/* R2: a played word's letters, faint in their boxes (S0f, S1); the kid taps the tiles. */
.lp-slot-tiles i.is-ghost { color: var(--text-tertiary); opacity: 0.6; border-style: dashed; }
.lp-slot-tiles i.is-ghost.is-lit { background: transparent; color: var(--text-secondary); opacity: 1; border-color: var(--learn-key-glow); }
.lp-slot-tiles i.is-pair { box-shadow: 0 0 0 0.06em var(--learn-key-glow); }

/* ── R3: the science and reading Look steps (js/learn-prompts.js) ── */
/* R3a fade_seq: each picture fades in over the last, which fades out. */
.lp-fade-layer { display: flex; align-items: center; justify-content: center; }
.lp-fade-layer > .lp-pic-img, .lp-fade-layer > .lp-pic-spr { width: 100%; height: 100%; }
.lp-pic.is-obj .lp-fade-layer .lp-pic-img, .lp-pic.is-spr .lp-fade-layer .lp-pic-img { object-fit: contain; }
.lp-fade-out { opacity: 0 !important; transition: opacity 1.2s ease; }
/* R3b approach: the copy that moves sits on the picture's lower right (or on the answer button). */
.lp-pl-copy { position: absolute; right: -4%; bottom: -4%; width: 48%; aspect-ratio: 1; z-index: 2; pointer-events: none;
    display: flex; align-items: center; justify-content: center; filter: drop-shadow(0 4px 6px var(--learn-shadow)); }
.lp-pl-copy.is-n1 { right: 30%; }
.lp-pl-copy.is-n2 { right: 64%; }
.lp-pl-copy > .lp-pic { width: 100%; height: 100%; background: none; }
.lp-pl-copy.is-on-btn { right: 4%; bottom: 4%; width: 46%; }
.lp-choice { position: relative; }
/* R3c pulse: a ring pulses twice, then a soft ring stays. */
.lp-pl-pulse { animation: lp-pl-pulse 0.75s ease-out 2; }
@keyframes lp-pl-pulse { 0% { box-shadow: 0 0 0 0 var(--learn-key-glow); } 60% { box-shadow: 0 0 0 12px var(--learn-key-glow); } 100% { box-shadow: 0 0 0 4px var(--learn-key-glow); } }
.lp-pic.is-pulsed, .lp-pic-cell.is-pulsed, .lp-choice.is-pulsed, .lp-shape.is-pulsed { box-shadow: 0 0 0 4px var(--learn-key-glow); }
.lp-pic.is-obj.is-pulsed, .lp-pic.is-spr.is-pulsed { box-shadow: none; filter: drop-shadow(0 0 6px var(--learn-key-glow)) drop-shadow(0 0 3px var(--learn-key-glow)); }
svg .lp-pl-pulse { animation: lp-pl-svgpulse 0.75s ease-out 2; transform-box: fill-box; transform-origin: center; }
@keyframes lp-pl-svgpulse { 0% { transform: scale(1); } 45% { transform: scale(1.12); } 100% { transform: scale(1); } }
svg .is-pulsed { filter: drop-shadow(0 0 2px var(--learn-key-glow)) drop-shadow(0 0 4px var(--learn-key-glow)); }
.lp-pic-cell.lp-pop, .lp-sbox i.lp-pop { animation: lp-pop 0.45s ease-out; }
/* R3e sound_box: 2–4 boxes under the picture; one lights. */
.has-sbox { flex-direction: column; align-items: center; gap: 8px; }
.lp-sbox { display: flex; gap: 8px; justify-content: center; flex: none; }
.lp-sbox i { display: flex; align-items: center; justify-content: center; width: clamp(34px, 10vw, 54px); aspect-ratio: 1;
    border: 3px solid var(--learn-shape-line); border-radius: 8px; box-sizing: border-box; font-style: normal;
    font-family: var(--font-teach); font-size: clamp(20px, 6vw, 32px); color: var(--learn-key-glow-ink); }
.lp-sbox i.is-lit { background: var(--learn-key-glow); border-color: var(--learn-key-glow); }
.lp-sbox i.is-long { animation: lp-sbox-swell 1.2s ease-in-out 1 forwards; }
@keyframes lp-sbox-swell { 0% { transform: scale(1); } 50% { transform: scale(1.3); } 100% { transform: scale(1.12); } }
.lp-sbox.is-btn { position: absolute; left: 50%; bottom: 4px; transform: translateX(-50%); gap: 4px; }
.lp-sbox.is-btn i { width: 18px; border-width: 2px; border-radius: 4px; font-size: 12px; }
/* R3f shrink_to: the pair glows. */
.lp-pic.is-letter.is-paired { box-shadow: 0 0 0 4px var(--learn-key-glow); }
.lp-choice.is-glow { box-shadow: 0 0 0 4px var(--learn-key-glow); }
/* R3g shine: a beam from the left reaches the thing; behind it (right) a light patch
   (all), a fainter one (some) or a shadow (none). The patch sits behind the picture. */
.lp-shine { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.lp-pic:has(> .lp-shine) > .lp-pic-img, .lp-pic:has(> .lp-shine) > .lp-tub-wrap { position: relative; z-index: 1; }
.lp-shine i { position: absolute; display: block; }
.lp-shine-beam { left: -6%; top: 30%; width: 36%; height: 40%; z-index: 2; opacity: 0.85;
    background: linear-gradient(90deg, var(--learn-k-sun), var(--learn-sun-glow));
    clip-path: polygon(0 38%, 100% 0, 100% 100%, 0 62%);
    transform-origin: left center; transform: scaleX(0); transition: transform 0.9s ease-out; }
.lp-shine.is-beam .lp-shine-beam { transform: scaleX(1); }
.lp-shine-far { right: -18%; top: 18%; width: 48%; height: 64%; border-radius: 50%; opacity: 0; transition: opacity 0.8s ease;
    background: radial-gradient(closest-side, var(--learn-k-sun), var(--learn-sun-glow) 55%, transparent); }
.lp-shine-shadow { right: -14%; top: 22%; width: 42%; height: 58%; border-radius: 50%; opacity: 0; transition: opacity 0.8s ease;
    background: radial-gradient(closest-side, var(--learn-k-shade), transparent); }
.lp-shine.is-all.is-far .lp-shine-far { opacity: 1; }
.lp-shine.is-some.is-far .lp-shine-far { opacity: 0.4; }
.lp-shine.is-some.is-far .lp-shine-shadow { opacity: 0.45; }
.lp-shine.is-none.is-far .lp-shine-shadow { opacity: 1; }
/* R3h light_on: the thing brightens with a soft halo. */
.lp-pl-lit { animation: lp-pl-lit 1.2s ease-out forwards; }
@keyframes lp-pl-lit { 0% { filter: brightness(0.85); } 100% { filter: brightness(1.18) drop-shadow(0 0 10px var(--learn-sun-glow)) drop-shadow(0 0 4px var(--learn-k-sun)); } }
/* R3i shade_over: a shade slides down over the sunny picture. */
.lp-shade { position: absolute; left: -2%; right: -2%; top: 0; height: 100%; z-index: 1; pointer-events: none;
    background: linear-gradient(var(--learn-k-shade), var(--learn-k-shade)), linear-gradient(var(--learn-k-shade), transparent 85%);
    border-top: 8px solid var(--learn-k-night); border-radius: 0 0 40% 40% / 0 0 14% 14%; transform: translateY(-104%); transition: transform 1.1s ease-out; }
.lp-shade.is-in { transform: none; }
/* R3j rings: sound rings pulse from a point; still rings at rest. */
.lp-rings { position: absolute; left: 50%; top: 40%; width: 64%; aspect-ratio: 3 / 2; transform: translate(-50%, -50%); z-index: 1; pointer-events: none; }
.lp-rings svg { width: 100%; height: 100%; overflow: visible; }
.lp-rings path { fill: none; stroke: var(--learn-shape-mark); stroke-width: 3.5; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.lp-rings.is-off { opacity: 0; }
.lp-rings.is-on path { animation: lp-rings 0.8s ease-out 3; }
.lp-rings.is-on path:nth-child(2n) { animation-delay: 0.2s; }
@keyframes lp-rings { 0% { opacity: 0; transform: scale(0.7); } 50% { opacity: 1; } 100% { opacity: 0.2; transform: scale(1.1); } }
.lp-rings path { transform-box: fill-box; transform-origin: center; }
/* R3k dust: the helper lands, pollen sticks, it flies to a second flower, the pollen lands. */
.lp-dust { position: absolute; inset: 0; pointer-events: none; z-index: 2; }
.lp-dust-flower { position: absolute; right: -12%; bottom: -6%; width: 42%; aspect-ratio: 1; opacity: 0; transition: opacity 0.5s ease; }
.lp-dust-flower > .lp-pic, .lp-dust-helper > .lp-pic { width: 100%; height: 100%; background: none; }
.lp-dust-helper { position: absolute; left: 30%; top: -8%; width: 40%; aspect-ratio: 1; transition: left 1.1s ease-in-out, top 1.1s ease-in-out; }
.lp-dust.is-second .lp-dust-flower { opacity: 1; }
.lp-dust.is-second .lp-dust-helper { left: 68%; top: 24%; width: 34%; }
.lp-dust-dots.is-flower { inset: 4% 22% 52% 22%; }
.lp-dust.is-now .lp-dust-helper { transition: none; }
.lp-dust-dots { position: absolute; inset: 20%; }
.lp-dust-dot { position: absolute; width: 17%; aspect-ratio: 1; border-radius: 50%; background: var(--learn-k-sun); border: 1px solid var(--learn-shape-line); opacity: 0; transition: opacity 0.4s ease; }
.lp-dust-dot.is-d0 { left: 10%; top: 60%; } .lp-dust-dot.is-d1 { left: 30%; top: 75%; } .lp-dust-dot.is-d2 { left: 55%; top: 70%; }
.lp-dust-dot.is-d3 { left: 75%; top: 55%; } .lp-dust-dot.is-d4 { left: 20%; top: 35%; } .lp-dust-dot.is-d5 { left: 65%; top: 30%; } .lp-dust-dot.is-d6 { left: 45%; top: 50%; }
.lp-dust.is-stuck .lp-dust-helper .lp-dust-dot { opacity: 1; }
.lp-dust.is-landed .lp-dust-helper .lp-dust-dot { opacity: 0; }
.lp-dust.is-landed .lp-dust-dots.is-flower .lp-dust-dot { opacity: 1; }
/* R3l backdrop_fill: the home fades in behind the animals that belong. */
.lp-bdfill { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 1.2s ease; border-radius: inherit; }
.lp-bdfill.is-in { opacity: 1; }
.lp-pic-cell.has-bd { overflow: hidden; }
.lp-pic-cell.has-bd > :not(.lp-bdfill) { position: relative; }
.lp-pic-cell.is-left { outline: 2px dashed var(--border-strong); outline-offset: 2px; }
/* R3m ring_spin: the ring's cells and arrows light in turn up to the gap. */
.lp-pic-row.is-ring .lp-pic-cell.is-lit { box-shadow: 0 0 0 3px var(--learn-key-glow); }
.lp-ring-arrows path.is-lit { stroke: var(--learn-key-glow); stroke-width: 5; }
@media (prefers-reduced-motion: reduce) {
    .lp-fade-out, .lp-shine-beam, .lp-shine-far, .lp-shine-shadow, .lp-shade, .lp-dust-flower, .lp-dust-helper, .lp-dust-dot, .lp-bdfill { transition: none; }
    .lp-pl-pulse, svg .lp-pl-pulse, .lp-pl-lit, .lp-rings.is-on path, .lp-sbox i.is-long, .lp-pic-cell.lp-pop, .lp-sbox i.lp-pop { animation: none; }
    .lp-pl-lit { filter: brightness(1.18) drop-shadow(0 0 10px var(--learn-sun-glow)) drop-shadow(0 0 4px var(--learn-k-sun)); }
    .lp-sbox i.is-long { transform: scale(1.12); }
}

/* ── R4: the math Look steps and drawings ── */
/* R4a: the frog on the stones; a path picture; a back hop's arc; marked and landing stones. */
.lp-seq-n, .lp-seq .lp-slot { position: relative; }
.lp-seq.has-frog { padding-top: 1.35em; }
.lp-seq-frog { position: absolute; left: 50%; bottom: 100%; width: 1.05em; height: 0.8em; transform: translate(-50%, 0.08em); z-index: 2; pointer-events: none; }
.lp-seq-frog svg { display: block; width: 100%; height: 100%; overflow: visible; }
.lp-frog-body { fill: var(--learn-leaf); stroke: var(--learn-shape-line); stroke-width: 1.6; }
.lp-frog-eye { fill: var(--learn-moon); }
.lp-frog-pupil { fill: var(--learn-shape-line); }
.lp-frog-mouth { fill: none; stroke: var(--learn-shape-line); stroke-width: 1.6; stroke-linecap: round; }
.lp-seq-frog.is-hop { animation: lp-frog-hop 0.45s ease-out; }
@keyframes lp-frog-hop { 0% { transform: translate(-50%, 0.08em); } 45% { transform: translate(-50%, -0.45em); } 100% { transform: translate(-50%, 0.08em); } }
.lp-seq-gap.is-back::after { content: ''; position: absolute; left: -0.62em; top: -0.5em; width: 0.16em; height: 0.16em;
    border-left: 0.07em solid var(--learn-key-glow); border-bottom: 0.07em solid var(--learn-key-glow); transform: rotate(45deg); }
.lp-seq-n.is-marked { box-shadow: inset 0 -0.12em 0 var(--learn-shape-mark); }
.lp-seq-n.is-land { box-shadow: 0 0 0 0.1em var(--learn-key-glow); }
.lp-path-wrap { display: flex; justify-content: center; max-width: 100%; }
.lp-path { font-size: clamp(20px, 6vw, 34px); }
.lp-objs-wrap:has(.lp-path-wrap) { flex-direction: column; gap: 8px; }
.lp-teach .lp-path, .lp-reteach .lp-path { font-size: clamp(20px, 6vw, 32px); }
/* R4b count_up: the part's tally, then each piece after it counts up; the "+" line under the picture. */
.lp-up-n { position: absolute; left: 50%; top: -0.2em; transform: translate(-50%, -100%); z-index: 2; pointer-events: none;
    padding: 0.05em 0.4em; border-radius: 999px; font-family: var(--font-heavy); font-style: normal; line-height: 1.15;
    font-size: clamp(12px, 3.6vw, 18px); white-space: nowrap; background: var(--surface-2); color: var(--text-primary); }
.lp-up-n.is-up { background: var(--learn-key-glow); color: var(--learn-key-glow-ink); }
.lp-up-n.is-start { background: var(--text-primary); color: var(--surface); }
.lp-obj.is-part, .lp-coin.is-part { filter: saturate(0.6); }
.lp-obj.is-upped, .lp-coin.is-upped { filter: drop-shadow(0 0 4px var(--learn-key-glow)); }
.lp-upline { font-family: var(--font-heavy); font-size: clamp(18px, 5vw, 26px); color: var(--text-primary); text-align: center; flex: none; }
/* R4c/R4d swap, join, snap: things slide to their new places; a rod or a flat snaps into being. */
.lp-pl-move { transition: left 0.9s ease-in-out, top 0.9s ease-in-out, width 0.9s ease-in-out, height 0.9s ease-in-out; }
.lp-pl-snap { animation: lp-pop 0.5s ease-out; }
/* R4d: a hundred flat (one piece, a 10 × 10 grid). */
.lp-obj-flat { position: absolute; box-sizing: border-box; border: 2px solid var(--learn-shape-line); border-radius: 6px; pointer-events: none;
    background-color: var(--learn-shape-soft);
    background-image: linear-gradient(var(--learn-shape-grid) 1px, transparent 1px), linear-gradient(90deg, var(--learn-shape-grid) 1px, transparent 1px);
    background-size: 10% 10%; }
.lp-obj-flat.is-fresh.lp-pl-slide { animation: lp-pl-slide 0.7s ease-out; }
/* R4e: clock quarters, the sweep, the day strip and its sun. */
.lp-clock-qw { fill: var(--learn-key-glow); opacity: 0.35; stroke: var(--learn-key-glow); stroke-width: 1.5; }
.lp-clock-qt { fill: var(--learn-key-glow-ink); font-family: var(--font-heavy); font-size: 15px; text-anchor: middle; dominant-baseline: central; }
.lp-clock-min, .lp-day-sun { transform-origin: 0 0; }
.lp-pl-turn { transition: transform 1s linear; }
.lp-day-half { fill: var(--learn-k-night); }
.lp-day-half.is-lit { stroke: var(--learn-key-glow); stroke-width: 4; }
.lp-day-light { fill: var(--learn-k-sun); opacity: 0.55; }
.lp-day-noon { stroke: var(--text-primary); stroke-width: 2; }
.lp-day-frame { fill: none; stroke: var(--learn-shape-line); stroke-width: 2.5; }
.lp-day-t { fill: var(--text-primary); font-family: var(--font-heavy); font-size: 17px; text-anchor: middle; dominant-baseline: central; }
.lp-day-sun circle { fill: var(--learn-k-sun); stroke: var(--learn-shape-line); stroke-width: 2; }
/* R4f: clocks and coins drawn as shapes (buttons). */
.lp-sh-circle.is-clockface { fill: var(--surface); stroke: var(--text-primary); stroke-width: 3; }
.lp-sh-seg.is-clocktick line { stroke: var(--text-primary); stroke-width: 2; }
.lp-sh-text.is-clocknum { fill: var(--text-primary); }
.lp-sh-seg.is-clockhour line { stroke: var(--text-primary); stroke-width: 5.5; }
.lp-sh-seg.is-clockmin line { stroke: var(--primary-ink); stroke-width: 3; }
.lp-sh-dot.is-clockpin { fill: var(--text-primary); }
.lp-sh-circle.is-coin.is-copper, .lp-sh-circle.is-coinrim.is-copper { fill: var(--learn-coin-copper); stroke: var(--learn-coin-copper-rim); stroke-width: 2.5; }
.lp-sh-circle.is-coin.is-silver, .lp-sh-circle.is-coinrim.is-silver { fill: var(--learn-coin-silver); stroke: var(--learn-coin-silver-rim); stroke-width: 2.5; }
.lp-sh-circle.is-coinrim { stroke-dasharray: 3 3; fill: none !important; }
.lp-sh-seg.is-coinedge line { stroke: var(--learn-coin-silver-rim); stroke-width: 1.4; }
.lp-sh-text.is-coinlabel { fill: var(--learn-coin-ink); }
.lp-sh-path.is-coinface { fill: none; stroke: var(--learn-coin-silver-rim); stroke-width: 2.4; stroke-linejoin: round; }
.lp-sh-rect.is-billface { fill: var(--learn-bill); stroke: var(--learn-bill-line); stroke-width: 3; }
.lp-sh-rect.is-billface.is-bill5 { stroke-width: 6; }
.lp-sh-rect.is-billline, .lp-sh-circle.is-billline { fill: none; stroke: var(--learn-bill-line); stroke-width: 2; }
.lp-sh-text.is-billlabel { fill: var(--learn-bill-ink); }
/* R4g: the unlabelled coin (a face, not a value) and its ridged edge; the $5 bill's heavier frame. */
.lp-coin-edge { stroke: var(--learn-coin-silver-rim); stroke-width: 1.6; }
.lp-coin-head { fill: none; stroke-width: 3; stroke-linejoin: round; }
.lp-coin.is-copper .lp-coin-head { stroke: var(--learn-coin-copper-rim); }
.lp-coin.is-silver .lp-coin-head { stroke: var(--learn-coin-silver-rim); }
.lp-bill-face.is-five { stroke-width: 7; }

/* ── R5: shared drawings ── */
/* R5e: a row of 2–3 pictures as one choice button. */
.lp-pic.lp-pic-btn.is-row { height: 100%; width: 100%; display: flex; align-items: center; justify-content: center; }
.lp-pic.lp-pic-btn.is-row .lp-pic-row { width: 100%; height: 100%; gap: 3px; justify-content: center; }
.lp-pic.lp-pic-btn.is-row .lp-pic-cell { width: auto; height: 100%; max-height: 100%; aspect-ratio: 1; flex: 1 1 0; min-width: 0; background: none; }
.lp-pic.lp-pic-btn.is-row .lp-pic-cell .lp-pic-img { object-fit: contain; }
/* LV-07 (habitats L4 "Which has more kinds?"): an animal in a row button stays square (a stretched
   pose strip shows two poses), and two row buttons with `stack` sit one above the other (a row of 5 needs the width). */
.lp-pic.lp-pic-btn.is-row .lp-pic-cell.is-spr { container-type: size; display: flex; align-items: center; justify-content: center; }
.lp-pic.lp-pic-btn.is-row .lp-pic-cell.is-spr .lp-pic-spr { width: min(100cqw, 100cqh); height: min(100cqw, 100cqh); flex: none; }
.lp-choices.has-pics.is-imgs.is-stack { flex-direction: column; }
.lp-choices.has-pics.is-imgs.is-stack .lp-choice.is-img { flex: 1 1 0; width: 100%; min-height: 72px; max-height: 128px; }
/* R5f: word cells in a picture row, arrows between the cells. */
.lp-pic-cell.is-word { display: flex; align-items: center; justify-content: center; aspect-ratio: auto; width: auto; min-width: 4.2em; min-height: 2.4em; padding: 0 0.5em;
    background: var(--surface-2); border: 2px solid var(--border-strong); box-sizing: border-box; }
.lp-pic-word { font-family: var(--font-heavy); font-size: clamp(15px, 4.4vw, 21px); color: var(--text-primary); white-space: nowrap; }
.lp-pic-row.has-words .lp-pic-slot { aspect-ratio: auto; width: 4.2em; min-height: 2.4em; }
.lp-row-arrow { flex: none; display: flex; align-items: center; }
.lp-row-arrow svg { width: 20px; height: 20px; }
.lp-row-arrow path { fill: none; stroke: var(--learn-shape-mark); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
@media (prefers-reduced-motion: reduce) {
    .lp-seq-frog.is-hop, .lp-pl-snap, .lp-obj-flat.is-fresh.lp-pl-slide { animation: none; }
    .lp-pl-move, .lp-pl-turn { transition: none; }
}
.lp-pic.is-obj.lp-pl-pulse, .lp-pic.is-spr.lp-pl-pulse, .lp-pic.is-letter.lp-pl-pulse { animation: lp-pl-pulse-f 0.75s ease-out 2; }
@keyframes lp-pl-pulse-f { 0% { filter: none; transform: scale(1); } 50% { filter: drop-shadow(0 0 10px var(--learn-key-glow)) drop-shadow(0 0 4px var(--learn-key-glow)); transform: scale(1.06); } 100% { filter: drop-shadow(0 0 6px var(--learn-key-glow)); transform: scale(1); } }
@media (prefers-reduced-motion: reduce) { .lp-pic.is-obj.lp-pl-pulse, .lp-pic.is-spr.lp-pl-pulse, .lp-pic.is-letter.lp-pl-pulse { animation: none; } }
.lp-objs-wrap:has(> .lp-upline) { flex-direction: column; gap: 6px; }
