/* Estrela — Matemática exercise mockup — shared by Addition.razor and
   Subtraction.razor.

   Not a scoped .razor.css file, because two components need it. Every
   selector is namespaced under .mm-page to replace the isolation that
   scoping used to give: class names like .badge, .item and .counter would
   otherwise collide with Bootstrap across the rest of the app. */
.mm-page {
    --sky: #EAF4FB;
    --sky-deep: #CDE7F5;
    --teal: #137A72;
    --teal-dark: #0B5750;
    --coral: #FF6E5A;
    --coral-dark: #E0503D;
    --sun: #FFC94D;
    --sun-dark: #E0A422;
    --ink: #213142;
    --ink-soft: #5A6B7B;
    --paper: #FFFFFF;
    --ok: #3FAE6A;
    --warn: #E0503D;
    --radius: 22px;

    background: var(--sky);
    font-family: 'Nunito', sans-serif;
    color: var(--ink);
    min-height: 100vh;
    box-sizing: border-box;
    margin: -1.1rem -1.5rem 0 -2rem;
}

.mm-page .frame {
    max-width: 920px;
    margin: 0 auto;
    padding: 28px 20px 60px;
    box-sizing: border-box;
}

/* --- top switcher --- */
.mm-page .switcher {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: 26px;
}

.mm-page .switcher button {
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: 14px;
    letter-spacing: .02em;
    border: none;
    background: var(--paper);
    color: var(--ink-soft);
    padding: 11px 20px;
    border-radius: 999px;
    cursor: pointer;
    box-shadow: 0 2px 0 rgba(33,49,66,.08);
    transition: all .18s ease;
}

.mm-page .switcher button.active {
    background: var(--teal);
    color: #fff;
    box-shadow: 0 3px 0 var(--teal-dark);
}

.mm-page .switcher button:not(.active):hover {
    color: var(--ink);
}

.mm-page .view {
    animation: mmFade .35s ease;
}

@keyframes mmFade {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}

/* ================= STUDENT VIEW ================= */
.mm-page .student-card {
    background: var(--paper);
    border-radius: 32px;
    padding: 34px 30px 30px;
    box-shadow: 0 14px 0 rgba(19,122,114,.08), 0 4px 18px rgba(33,49,66,.06);
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
}

.mm-page .student-topline {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.mm-page .badge {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: var(--teal-dark);
    background: var(--sky-deep);
    padding: 6px 14px;
    border-radius: 999px;
}

.mm-page .score-counters {
    display: flex;
    gap: 10px;
}

.mm-page .counter {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: 14px;
    padding: 5px 12px;
    border-radius: 999px;
    display: flex;
    align-items: center;
    gap: 4px;
}

.mm-page .counter-correct { background: #E5F4EA; color: #2E8A54; }
.mm-page .counter-wrong { background: #FDE7E4; color: var(--coral-dark); }

.mm-page h1.q-title {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: 26px;
    margin: 14px 0 2px;
    color: var(--ink);
}

.mm-page .q-sub {
    color: var(--ink-soft);
    font-weight: 600;
    font-size: 15px;
    margin: 0 0 26px;
}

.mm-page .equation {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: 52px;
    text-align: center;
    color: var(--teal-dark);
    margin: 6px 0 30px;
    letter-spacing: .01em;
}

.mm-page .equation .op { color: var(--coral); }

.mm-page .equation .answer-slot {
    display: inline-block;
    min-width: 70px;
    border-bottom: 5px solid var(--sun);
    color: var(--ink);
}

.mm-page .groups-wrap {
    display: flex;
    justify-content: center;
    gap: 36px;
    flex-wrap: wrap;
    margin-bottom: 8px;
}

.mm-page .group {
    background: var(--sky);
    border-radius: 20px;
    padding: 16px 18px 12px;
    min-width: 200px;
}

.mm-page .group-label {
    text-align: center;
    font-weight: 800;
    font-size: 13px;
    color: var(--ink-soft);
    margin-bottom: 10px;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.mm-page .items {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 8px;
}

.mm-page .item {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    border-radius: 10px;
    user-select: none;
    box-sizing: border-box;
}

.mm-page .item.slot-empty {
    border: 2px dashed var(--sky-deep);
    background: transparent;
}

.mm-page .item.apple {
    cursor: pointer;
    transition: transform .15s ease, background .15s ease;
}

.mm-page .item.apple:hover {
    transform: scale(1.15);
    background: rgba(255,255,255,.7);
}

.mm-page .item.apple.gone {
    visibility: hidden;
}

.mm-page .item.slot-filled {
    animation: mmLandIn .32s ease;
    background: var(--sun);
    box-shadow: 0 0 0 3px var(--sun-dark) inset;
}

@keyframes mmLandIn {
    0% { transform: scale(.4) translateY(-14px); opacity: 0; }
    60% { transform: scale(1.2) translateY(2px); opacity: 1; }
    100% { transform: scale(1) translateY(0); }
}

.mm-page .bridge-note {
    text-align: center;
    font-weight: 700;
    font-size: 14px;
    color: var(--teal-dark);
    background: var(--sky-deep);
    display: inline-block;
    padding: 8px 16px;
    border-radius: 14px;
    margin: 18px auto 0;
}

.mm-page .bridge-note.muted {
    background: var(--sky);
    color: var(--ink-soft);
}

.mm-page .bridge-row { text-align: center; }

/* The explanation shown after a correct answer, before it is earned: laid out
   but invisible, so its space is already there and nothing below it - the
   progress dots, a footer - jumps down the moment the child answers.
   visibility, not opacity: hidden this way it is also out of the
   accessibility tree, so a screen reader cannot read out the answer early. */
.mm-page .bridge-row.is-pending { visibility: hidden; }

.mm-page .refresh-btn {
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: 13px;
    color: var(--teal-dark);
    background: var(--sky-deep);
    border: none;
    padding: 8px 18px;
    border-radius: 999px;
    cursor: pointer;
    transition: all .15s ease;
}

.mm-page .refresh-btn:hover {
    background: var(--teal);
    color: #fff;
}

.mm-page .answers {
    display: flex;
    justify-content: center;
    gap: 14px;
    margin-top: 28px;
    flex-wrap: wrap;
}

.mm-page .answer-btn {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 700;
    font-size: 22px;
    background: var(--paper);
    border: 3px solid var(--sky-deep);
    color: var(--ink);
    padding: 10px 26px;
    border-radius: 16px;
    cursor: pointer;
    transition: all .15s ease;
}

.mm-page .answer-btn:hover {
    border-color: var(--teal);
    transform: translateY(-2px);
}

.mm-page .answer-btn.correct { background: var(--ok); border-color: var(--ok); color: #fff; }
.mm-page .answer-btn.wrong { background: var(--warn); border-color: var(--warn); color: #fff; }

.mm-page .feedback {
    text-align: center;
    font-family: 'Baloo 2', sans-serif;
    font-weight: 700;
    font-size: 18px;
    margin-top: 20px;
    min-height: 26px;
    color: var(--ok);
}

.mm-page .feedback.is-wrong { color: var(--warn); }

.mm-page .progress-strip {
    display: flex;
    gap: 6px;
    justify-content: center;
    margin-top: 26px;
}

/* Host content under the exercise - the staff Edit button. Centred like the
   exercise's own controls; clamp() so it gives way on a short phone screen. */
.mm-page .exercise-footer {
    display: flex;
    justify-content: center;
    margin-top: clamp(10px, 3vh, 26px);
}

.mm-page .dot {
    width: 34px;
    height: 8px;
    border-radius: 99px;
    background: var(--sky-deep);
}

.mm-page .dot.done { background: var(--sun); }
.mm-page .dot.current { background: var(--teal); }

/* ================= TEACHER VIEW ================= */
.mm-page .teacher-card {
    background: var(--paper);
    border-radius: 28px;
    padding: 30px 30px 26px;
    box-shadow: 0 4px 18px rgba(33,49,66,.06);
    box-sizing: border-box;
}

.mm-page .teacher-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    margin-bottom: 22px;
    flex-wrap: wrap;
    gap: 10px;
}

.mm-page .teacher-head h2 {
    font-family: 'Baloo 2', sans-serif;
    font-size: 22px;
    margin: 0;
    color: var(--ink);
}

.mm-page .teacher-head p {
    margin: 4px 0 0;
    color: var(--ink-soft);
    font-weight: 600;
    font-size: 14px;
}

.mm-page .module-pill {
    background: var(--sky);
    color: var(--teal-dark);
    font-weight: 800;
    font-size: 13px;
    padding: 8px 16px;
    border-radius: 999px;
}

.mm-page table.roster {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.mm-page table.roster th {
    text-align: left;
    font-weight: 800;
    color: var(--ink-soft);
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: .05em;
    padding: 0 10px 10px;
    border-bottom: 2px solid var(--sky);
    background: transparent;
    font-family: 'Nunito', sans-serif;
}

.mm-page table.roster td {
    padding: 12px 10px;
    border-bottom: 1px solid var(--sky);
    vertical-align: middle;
}

.mm-page .student-name { font-weight: 700; }

.mm-page .bar-track {
    width: 100%;
    height: 10px;
    background: var(--sky);
    border-radius: 99px;
    overflow: hidden;
}

.mm-page .bar-fill {
    height: 100%;
    border-radius: 99px;
    background: var(--teal);
}

.mm-page .bar-fill.low { background: var(--coral); }
.mm-page .bar-fill.mid { background: var(--sun); }

.mm-page .flag {
    font-weight: 800;
    font-size: 12px;
    padding: 5px 11px;
    border-radius: 999px;
    display: inline-block;
}

.mm-page .flag.attn { background: #FDE7E4; color: var(--coral-dark); }
.mm-page .flag.ok { background: #E5F4EA; color: #2E8A54; }
.mm-page .flag.watch { background: #FFF3DA; color: var(--sun-dark); }

.mm-page .legend {
    display: flex;
    gap: 18px;
    margin-top: 18px;
    font-size: 12px;
    font-weight: 700;
    color: var(--ink-soft);
    flex-wrap: wrap;
}

.mm-page .legend span {
    display: flex;
    align-items: center;
    gap: 6px;
}

.mm-page .legend i {
    width: 10px;
    height: 10px;
    border-radius: 3px;
    display: inline-block;
}

.mm-page .caption {
    text-align: center;
    color: var(--ink-soft);
    font-size: 13px;
    margin-top: 22px;
    font-weight: 600;
}

/* =========================================================================
   PHONES — fit the whole exercise on screen, no scrolling to the answers.

   The layout is a nested flex column (page > main > article > mm-page >
   frame > view > student-card) so the card fills exactly the space left
   under the nav bar. Every vertical size is then expressed as
   clamp(min, vh, max) so the contents shrink continuously with viewport
   height: fixed pixel sizes gave a cliff where short phones (320x568 and
   below) pushed the answer buttons off screen.

   The desktop rule uses min-height:100vh and negative margins sized for the
   desktop article padding (2rem/1.5rem); on phones that padding is a
   symmetric 1.5rem, so the horizontal margins are re-stated here.
   ========================================================================= */
@media (max-width: 640.98px) {
    .mm-page {
        min-height: 0;
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        margin: -1.1rem -1.5rem 0;
    }

    /* margin-inline 0 undoes the desktop margin:0 auto. In a flex column an
       auto side margin stops the item stretching: the frame shrank to its
       content and was centred, so every exercise came out a different width
       (274-373px on a 393px iPhone) with dead space either side. */
    .mm-page .frame {
        flex: 1;
        min-height: 0;
        min-width: 0;
        margin-left: 0;
        margin-right: 0;
        display: flex;
        flex-direction: column;
        max-width: none;
        padding: clamp(5px, 1.2vh, 8px) 10px clamp(6px, 1.4vh, 10px);
    }

    .mm-page .view {
        flex: 1;
        min-height: 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
    }

    .mm-page .switcher {
        margin-bottom: clamp(5px, 1.2vh, 8px);
        gap: 6px;
    }

    .mm-page .switcher button {
        font-size: clamp(11px, 1.8vh, 12px);
        padding: clamp(5px, 1vh, 7px) 12px;
    }

    .mm-page .student-card,
    .mm-page .teacher-card {
        flex: 1;
        min-height: 0;
        min-width: 0;
        display: flex;
        flex-direction: column;
        border-radius: 20px;
        padding: clamp(8px, 1.4vh, 12px) 12px clamp(7px, 1.2vh, 10px);
        box-shadow: 0 4px 12px rgba(33,49,66,.08);
    }

    .mm-page .badge,
    .mm-page .counter {
        font-size: min(clamp(9.5px, 1.6vh, 11px), 3.2vw);
        padding: 3px 9px;
    }

    /* Narrow screens: let the module badge give way rather than shove the
       score chips past the right edge. */
    .mm-page .student-topline {
        gap: 6px;
        min-width: 0;
    }

    .mm-page .badge {
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .mm-page .score-counters {
        flex: none;
    }

    .mm-page h1.q-title {
        font-size: clamp(14px, 2.6vh, 17px);
        margin: clamp(4px, 1vh, 8px) 0 2px;
    }

    .mm-page .q-sub {
        font-size: clamp(10px, 1.7vh, 12px);
        margin: 0 0 clamp(4px, 1.2vh, 8px);
    }

    .mm-page .equation {
        font-size: clamp(24px, 5.6vh, 34px);
        margin: 2px 0 clamp(6px, 1.6vh, 10px);
    }

    .mm-page .equation .answer-slot {
        min-width: clamp(34px, 9vw, 46px);
        border-bottom-width: 4px;
    }

    /* Keep the two groups side by side — stacking them is what pushed the
       answers off screen. */
    .mm-page .groups-wrap {
        gap: 8px;
        flex-wrap: nowrap;
        margin-bottom: 0;
        min-width: 0;
    }

    .mm-page .group {
        min-width: 0;
        flex: 1;
        border-radius: 14px;
        padding: clamp(5px, 1.1vh, 8px);
    }

    .mm-page .group-label {
        font-size: clamp(9px, 1.5vh, 10px);
        letter-spacing: .04em;
        margin-bottom: clamp(4px, 0.9vh, 6px);
    }

    /* minmax(0, 1fr), not 1fr: a 1fr track refuses to shrink below its
       content's minimum, which pinned the two groups at 317px wide and
       clipped the card. With a 0 floor the tracks — and the apples sized at
       width:100% — shrink to whatever the screen actually has. */
    .mm-page .items {
        grid-template-columns: repeat(5, minmax(0, 1fr));
        gap: clamp(3px, 0.8vh, 5px);
        justify-items: stretch;
        min-width: 0;
    }

    /* Sized from the grid column (width:100% + aspect-ratio), capped by a
       height-based clamp — never sized from vh alone. A tall, narrow screen
       (Galaxy Z Fold 5 folded: 344x882) has plenty of vh and almost no width,
       so a vh-only size forced a 384px min-content width and the card was
       clipped on the right. */
    .mm-page .item {
        width: 100%;
        max-width: clamp(20px, 4.2vh, 26px);
        height: auto;
        aspect-ratio: 1 / 1;
        font-size: min(clamp(13px, 2.6vh, 16px), 4.6vw);
        border-radius: 8px;
    }

    .mm-page .bridge-note {
        font-size: clamp(9.5px, 1.6vh, 11px);
        padding: clamp(4px, 0.9vh, 6px) 10px;
        margin: clamp(5px, 1.5vh, 10px) auto 0;
        border-radius: 10px;
    }

    /* Both inline style="margin-top" overrides on the hint rows come from the
       mockup markup; neutralise them so spacing stays fluid here. */
    .mm-page .bridge-row[style] {
        margin-top: 0 !important;
    }

    .mm-page .refresh-btn {
        font-size: clamp(10px, 1.5vh, 11px);
        padding: clamp(4px, 0.9vh, 6px) 14px;
    }

    .mm-page .answers {
        gap: 8px;
        margin-top: clamp(6px, 1.8vh, 12px);
    }

    .mm-page .answer-btn {
        font-size: clamp(15px, 2.8vh, 18px);
        padding: clamp(5px, 1.1vh, 7px) clamp(12px, 4vw, 16px);
        border-width: 2px;
        border-radius: 12px;
    }

    .mm-page .feedback {
        font-size: clamp(11px, 1.9vh, 13px);
        margin-top: clamp(4px, 1.2vh, 8px);
        min-height: clamp(14px, 2.2vh, 18px);
    }

    .mm-page .progress-strip {
        margin-top: clamp(6px, 1.5vh, 10px);
        gap: 5px;
    }

    .mm-page .dot {
        width: 22px;
        height: 6px;
    }

    /* Explanatory footnote is the first thing to go — it is commentary on the
       mockup, not part of the exercise. */
    .mm-page .caption {
        display: none;
    }

    /* 12 roster rows cannot shrink to fit, so the teacher card scrolls
       internally instead of stretching the document. */
    .mm-page .teacher-card {
        overflow-y: auto;
    }

    .mm-page .teacher-head {
        margin-bottom: 12px;
    }

    .mm-page .teacher-head h2 {
        font-size: clamp(14px, 2.6vh, 17px);
    }

    .mm-page .teacher-head p,
    .mm-page .module-pill {
        font-size: clamp(10px, 1.6vh, 11px);
    }

    /* table-layout:fixed so the columns can shrink: with the default auto
       layout the header text ("PROGRESSO NO MÓDULO") held the table at a
       309px minimum, which overflowed a 344px-wide screen. */
    .mm-page table.roster {
        font-size: clamp(11px, 1.8vh, 12px);
        table-layout: fixed;
        width: 100%;
    }

    .mm-page table.roster th,
    .mm-page table.roster td {
        overflow-wrap: anywhere;
    }

    .mm-page table.roster th:nth-child(1),
    .mm-page table.roster td:nth-child(1) {
        width: 30%;
    }

    .mm-page table.roster th:nth-child(2),
    .mm-page table.roster td:nth-child(2),
    .mm-page table.roster th:nth-child(3),
    .mm-page table.roster td:nth-child(3) {
        width: 22%;
    }

    .mm-page table.roster td {
        padding: clamp(5px, 1.1vh, 8px) 6px;
    }

    .mm-page table.roster th {
        font-size: 10px;
        padding: 0 6px 8px;
    }

    .mm-page .legend {
        gap: 10px;
        font-size: 10px;
        margin-top: 12px;
    }
}

/* =========================================================================
   TABLETS - the same promise as the phone rules above (invariant 12), by a
   different route.

   The phone rules shrink every element with clamp(min, vh, max), and their
   maxima are phone-sized: stretched to an iPad they would draw an 18px answer
   button in the middle of a 1024px screen. So a tablet keeps the desktop
   sizes, gets exactly the screen that is left below the bars, and
   wwwroot/exercise-fit.js scales the exercise down only when it does not fit
   - which on an iPad Mini in landscape was various-even-odd outright, and
   several more once a route strip sat above them.

   Shell pinned through :has(), as for generated pages below, so the list
   pages are untouched. overflow-y:auto rather than hidden: past the fit
   script's floor the exercise scrolls rather than losing its answers. The
   width range stops where the phone rules start; the touch clause catches a
   tablet in landscape wider than 1024px. Same devices as the folding band.
   ========================================================================= */
@media (min-width: 641px) and (max-width: 1024.98px),
       (min-width: 641px) and (hover: none) and (pointer: coarse) {
    .page:has(.mm-page) {
        height: 100dvh;
    }

    .page:has(.mm-page) main {
        min-height: 0;
        overflow-y: auto;
    }

    .page:has(.mm-page) article.content {
        display: flex;
        flex-direction: column;
        flex: 1;
        min-height: 0;
    }

    .mm-page {
        flex: 1;
        min-height: 0;
        overflow-y: auto;
    }

    /* Desktop pads for a page that scrolls - 60px under the card alone. */
    .mm-page .frame {
        padding: clamp(8px, 1.5vh, 16px) 16px;
    }

    .mm-page .student-card {
        padding: clamp(14px, 2.4vh, 26px) clamp(16px, 2.6vw, 28px);
    }

    /* The title again, under the card. */
    .mm-page .caption {
        display: none;
    }
}

/* NO MODULE BADGE ("Módulo 1 · Somar até 100"), on any screen. It names
   where the exercise sits in the curriculum, which the breadcrumb above already
   says, and it took a row of its own above the title - a row the exercise
   needs more. The title moves up into that row and the score counters float
   in its top-right corner, the way the generated pages already have them.

   The title keeps clear of the counters with padding rather than sharing a
   flex row with them: the two are siblings in several components (the
   scaffold, the stepped renderer, the hand-written modules), and a row would
   have meant changing the markup of every one of them. Generated
   pages are excluded - their own rule, below, hides the title as well.

   Mobile first, then desktop: asked for once the space it freed on a tablet
   had been seen. */
.mm-page:not(.mm-page--html) .student-topline .badge {
    display: none;
}

/* The corner sits at the card's own padding, which differs per screen size -
   desktop here, tablet and phone below. */
.mm-page:not(.mm-page--html) .student-card > .student-topline {
    position: absolute;
    top: 34px;
    right: 30px;
    z-index: 1;
    margin: 0;
}

.mm-page:not(.mm-page--html) h1.q-title {
    margin-top: 0;
    padding-right: 7.5rem;
}

@media (min-width: 641px) and (max-width: 1024.98px),
       (min-width: 641px) and (hover: none) and (pointer: coarse) {
    .mm-page:not(.mm-page--html) .student-card > .student-topline {
        top: clamp(14px, 2.4vh, 26px);
        right: clamp(16px, 2.6vw, 28px);
    }
}

/* The phone card has less padding than the tablet one, so its corner differs. */
@media (max-width: 640.98px) {
    .mm-page:not(.mm-page--html) .student-card > .student-topline {
        top: clamp(8px, 1.4vh, 12px);
        right: 12px;
    }
}

/* Very short viewports (small phones, or a phone in landscape): even at the
   clamp minimums the decorative rows do not fit. Drop the two that carry no
   information the child needs — the static instruction line, which the live
   hint below the groups repeats, and the progress dots. */
@media (max-width: 640.98px) and (max-height: 540px) {
    .mm-page .q-sub,
    .mm-page .progress-strip {
        display: none;
    }
}

/* =========================================================================
   VISUAL MODELS for the modules built on ExerciseScaffold.
   All namespaced under .mm-page, same as the rest of this file, and sized
   with clamp() so they shrink with the viewport rather than forcing scroll.
   ========================================================================= */
.mm-page .ex-visual {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    min-height: 0;
}

/* --- counting: number chips --- */
.mm-page .chip-row {
    display: flex;
    gap: clamp(4px, 1.2vw, 10px);
    flex-wrap: wrap;
    justify-content: center;
}

.mm-page .num-chip {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(14px, 3.4vh, 22px);
    min-width: clamp(34px, 9vw, 54px);
    padding: clamp(4px, 1vh, 10px) clamp(4px, 1.5vw, 10px);
    text-align: center;
    border-radius: 12px;
    background: var(--sky);
    color: var(--teal-dark);
}

.mm-page .num-chip.gap {
    background: var(--sun);
    color: var(--ink);
    box-shadow: 0 0 0 3px var(--sun-dark) inset;
}

/* --- even/odd: paired counters --- */
.mm-page .pair-grid {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(3px, 1vw, 8px);
    justify-content: center;
    max-width: 100%;
}

.mm-page .pair-col {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 3px;
    border-radius: 8px;
    background: var(--sky);
}

.mm-page .pair-col.leftover {
    background: #fde7e4;
    box-shadow: 0 0 0 2px var(--coral) inset;
}

.mm-page .pair-item {
    font-size: clamp(11px, 2.2vh, 16px);
    line-height: 1;
    width: clamp(15px, 3vh, 20px);
    height: clamp(15px, 3vh, 20px);
    display: flex;
    align-items: center;
    justify-content: center;
}

.mm-page .pair-item.empty {
    opacity: 0.25;
}

/* --- friends of 10/20: one or two ten-frames --- */
.mm-page .frames-wrap {
    display: flex;
    gap: clamp(6px, 2vw, 14px);
    flex-wrap: wrap;
    justify-content: center;
}

.mm-page .ten-frame-box {
    background: var(--sky);
    border-radius: 14px;
    padding: clamp(5px, 1.1vh, 9px);
}

.mm-page .item.slot-known {
    background: var(--sky-deep);
}

/* --- splitsen: split tree --- */
.mm-page .split-tree {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.mm-page .split-total,
.mm-page .split-part {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(16px, 3.6vh, 26px);
    min-width: clamp(40px, 10vw, 60px);
    padding: clamp(4px, 1vh, 9px);
    text-align: center;
    border-radius: 12px;
    background: var(--sky-deep);
    color: var(--teal-dark);
}

.mm-page .split-part.unknown {
    background: var(--sun);
    color: var(--ink);
}

.mm-page .split-branches {
    position: relative;
    width: clamp(80px, 30vw, 150px);
    height: clamp(14px, 3vh, 26px);
}

.mm-page .split-leg {
    position: absolute;
    top: 0;
    width: 50%;
    height: 100%;
    border-top: 3px solid var(--sky-deep);
}

.mm-page .split-leg.left {
    left: 0;
    border-left: 3px solid var(--sky-deep);
    border-radius: 8px 0 0 0;
}

.mm-page .split-leg.right {
    right: 0;
    border-right: 3px solid var(--sky-deep);
    border-radius: 0 8px 0 0;
}

.mm-page .split-parts {
    display: flex;
    gap: clamp(20px, 12vw, 70px);
}

.mm-page .split-counters {
    display: flex;
    flex-wrap: wrap;
    gap: 3px;
    justify-content: center;
    max-width: 100%;
    margin-top: 0.4rem;
}

.mm-page .split-dot {
    width: clamp(9px, 1.8vh, 14px);
    height: clamp(9px, 1.8vh, 14px);
    border-radius: 50%;
}

.mm-page .split-dot.known { background: var(--teal); }
.mm-page .split-dot.rest { background: var(--sun); }

/* --- bead board --- */
.mm-page .bead-board {
    display: flex;
    flex-direction: column;
    gap: clamp(3px, 0.9vh, 7px);
}

.mm-page .bead-row {
    display: flex;
    gap: clamp(3px, 1vw, 7px);
    padding: clamp(2px, 0.6vh, 5px);
    border-radius: 10px;
    cursor: pointer;
    transition: background-color .15s ease;
}

.mm-page .bead-row.lit {
    background: var(--sun);
}

.mm-page .bead {
    width: clamp(13px, 2.8vh, 22px);
    height: clamp(13px, 2.8vh, 22px);
    border-radius: 50%;
    background: var(--coral);
    box-shadow: inset 0 -2px 0 rgba(0, 0, 0, .12);
}

/* --- bead pool (Division.razor) ---
   The loose beads waiting to be dealt into bead-board's rows. Same bead
   shape, tappable and with a hover cue, since these move on tap and the
   rows' beads don't. */
.mm-page .bead-pool {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(3px, 1vw, 7px);
    justify-content: center;
    margin-bottom: clamp(6px, 1.4vh, 12px);
    min-height: clamp(13px, 2.8vh, 22px);
}

.mm-page .pool-bead {
    cursor: pointer;
    transition: transform .1s ease;
}

.mm-page .pool-bead:hover {
    transform: scale(1.15);
}

/* An empty row slot: an outline only, so the child can see how many beads
   are still needed to fill this group. */
.mm-page .bead-empty {
    background: transparent;
    border: 2px dashed var(--ink-soft, #5a6b7b);
    box-shadow: none;
}

/* --- measurement: length bars --- */
.mm-page .length-stack {
    width: min(100%, 22rem);
    display: flex;
    flex-direction: column;
    gap: clamp(6px, 1.6vh, 12px);
}

.mm-page .length-row {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.mm-page .length-label {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    color: var(--teal-dark);
    width: 1.2rem;
}

.mm-page .length-bar {
    height: clamp(14px, 3vh, 22px);
    border-radius: 99px;
}

.mm-page .length-bar.a { background: var(--teal); }
.mm-page .length-bar.b { background: var(--coral); }

/* --- measurement: balance scale --- */
.mm-page .balance {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.mm-page .beam {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: min(100%, 18rem);
    padding: clamp(4px, 1vh, 8px) clamp(6px, 2vw, 12px);
    border-radius: 99px;
    background: var(--sky-deep);
    transition: transform .3s ease;
}

.mm-page .pan {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(12px, 2.4vh, 17px);
    color: var(--teal-dark);
    background: #fff;
    border-radius: 99px;
    padding: clamp(3px, 0.8vh, 6px) clamp(6px, 2vw, 12px);
}

.mm-page .stand {
    width: clamp(8px, 2vw, 14px);
    height: clamp(20px, 5vh, 40px);
    background: var(--ink-soft);
    border-radius: 0 0 6px 6px;
}

/* --- measurement: analog clock --- */
.mm-page .clock {
    position: relative;
    width: clamp(90px, 22vh, 150px);
    height: clamp(90px, 22vh, 150px);
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 4px var(--teal) inset;
}

.mm-page .clock .hand {
    position: absolute;
    left: 50%;
    bottom: 50%;
    transform-origin: bottom center;
    border-radius: 99px;
    background: var(--ink);
}

.mm-page .clock .hand.hour {
    width: 4px;
    height: 28%;
    margin-left: -2px;
}

.mm-page .clock .hand.minute {
    width: 3px;
    height: 40%;
    margin-left: -1.5px;
    background: var(--coral);
}

.mm-page .clock .pin {
    position: absolute;
    left: 50%;
    top: 50%;
    width: 8px;
    height: 8px;
    margin: -4px 0 0 -4px;
    border-radius: 50%;
    background: var(--teal-dark);
}

.mm-page .clock .tick {
    position: absolute;
    left: 50%;
    top: 4px;
    width: 2px;
    height: 6px;
    margin-left: -1px;
    background: var(--sky-deep);
    transform-origin: center calc(clamp(90px, 22vh, 150px) / 2 - 4px);
}

/* --- skip counting: 100-chart --- */
.mm-page .hundred-chart {
    display: grid;
    grid-template-columns: repeat(10, minmax(0, 1fr));
    gap: clamp(1px, 0.4vw, 3px);
    width: min(100%, 24rem);
}

.mm-page .chart-cell {
    font-family: 'Trebuchet MS', sans-serif;
    font-weight: 700;
    font-size: clamp(7px, 1.5vh, 11px);
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 3px;
    background: var(--sky);
    color: var(--ink-soft);
}

.mm-page .chart-cell.start {
    background: var(--teal);
    color: #fff;
}

.mm-page .chart-cell.jump {
    background: var(--sun);
    color: var(--ink);
}

.mm-page .chart-cell.landing {
    background: var(--coral);
    color: #fff;
}

/* =========================================================================
   ADDITION — alternative representations (JumpingOnTheNumberLine.razor,
   SplittingTheNumber.razor, MangoStory.razor)
   ========================================================================= */
.mm-page .method-chips {
    display: flex;
    gap: clamp(3px, 1vw, 6px);
    flex-wrap: wrap;
    justify-content: center;
    margin-bottom: clamp(4px, 1.2vh, 10px);
}

.mm-page .method-chip {
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: clamp(9px, 1.5vh, 11px);
    padding: clamp(3px, 0.7vh, 5px) clamp(6px, 2vw, 11px);
    border: none;
    border-radius: 999px;
    background: var(--sky);
    color: var(--ink-soft);
    text-decoration: none;
    cursor: pointer;
}

.mm-page .method-chip.active {
    background: var(--teal);
    color: #fff;
}

/* --- number line --- */
.mm-page .numline {
    position: relative;
    width: min(100%, 24rem);
    padding-top: clamp(18px, 4vh, 32px);
}

.mm-page .numline-track {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    height: clamp(26px, 6vh, 44px);
    border-top: 3px solid var(--teal-dark);
}

.mm-page .numline-tick {
    position: relative;
    width: 1px;
    height: clamp(4px, 1vh, 7px);
    background: var(--sky-deep);
}

.mm-page .numline-tick.major {
    height: clamp(8px, 1.8vh, 12px);
    background: var(--teal-dark);
}

.mm-page .tick-label {
    position: absolute;
    top: clamp(9px, 2vh, 14px);
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Baloo 2', sans-serif;
    font-weight: 700;
    font-size: clamp(9px, 1.7vh, 12px);
    color: var(--ink-soft);
}

.mm-page .numline-marker {
    position: absolute;
    top: clamp(-2px, 0.4vh, 2px);
    transform: translateX(-50%);
    font-size: clamp(14px, 3vh, 21px);
    transition: left .35s ease;
}

/* The arc is a half-ellipse: only the top border is drawn, so a jump reads as
   a hop over the line rather than a bar along it. */
.mm-page .numline-arc {
    position: absolute;
    top: clamp(2px, 0.8vh, 6px);
    height: clamp(14px, 3.2vh, 26px);
    border: 3px solid var(--sun-dark);
    border-bottom: none;
    border-radius: 50% 50% 0 0 / 100% 100% 0 0;
}

.mm-page .numline-arc.second {
    border-color: var(--coral);
}

.mm-page .arc-label {
    position: absolute;
    top: clamp(-11px, -2.4vh, -8px);
    left: 50%;
    transform: translateX(-50%);
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(10px, 1.9vh, 13px);
    color: var(--teal-dark);
    background: #fff;
    padding: 0 3px;
    border-radius: 6px;
}

.mm-page .numline-actions {
    display: flex;
    gap: clamp(5px, 2vw, 10px);
    justify-content: center;
    margin-top: clamp(12px, 2.6vh, 20px);
}

.mm-page .jump-btn {
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: clamp(11px, 2vh, 14px);
    padding: clamp(5px, 1.1vh, 8px) clamp(10px, 3vw, 16px);
    border: none;
    border-radius: 999px;
    background: var(--sun);
    color: var(--ink);
    cursor: pointer;
}

.mm-page .jump-btn:disabled {
    background: var(--sky);
    color: var(--ink-soft);
    cursor: default;
}

/* --- bond: split chips + equation chain --- */
.mm-page .chip-picker {
    display: flex;
    gap: clamp(3px, 1vw, 6px);
    flex-wrap: wrap;
    justify-content: center;
    margin-top: clamp(6px, 1.4vh, 11px);
}

.mm-page .pick-chip {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(12px, 2.2vh, 16px);
    min-width: clamp(24px, 6vw, 34px);
    padding: clamp(3px, 0.8vh, 6px);
    border: 2px solid var(--sky-deep);
    border-radius: 10px;
    background: #fff;
    color: var(--ink);
    cursor: pointer;
}

.mm-page .pick-chip.active {
    background: var(--teal);
    border-color: var(--teal);
    color: #fff;
}

.mm-page .chain {
    margin-top: clamp(6px, 1.4vh, 11px);
    display: flex;
    flex-direction: column;
    gap: 3px;
    align-items: center;
}

.mm-page .chain-line {
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(12px, 2.3vh, 17px);
    padding: clamp(2px, 0.6vh, 5px) clamp(8px, 2.5vw, 14px);
    border-radius: 10px;
    background: var(--sky);
    color: var(--teal-dark);
}

.mm-page .chain-line.good {
    background: #e5f4ea;
    color: #2e8a54;
}

.mm-page .chain-line.off {
    background: #fde7e4;
    color: var(--coral-dark);
}

/* --- story: carton and basket --- */
.mm-page .story-scene {
    display: flex;
    gap: clamp(8px, 3vw, 18px);
    align-items: flex-start;
    justify-content: center;
    flex-wrap: wrap;
}

.mm-page .carton {
    position: relative;
    background: #e8d5b7;
    border-radius: 12px;
    padding: clamp(5px, 1.2vh, 9px);
    box-shadow: inset 0 0 0 2px #cbb392;
    transition: box-shadow .3s ease, background-color .3s ease;
}

.mm-page .carton.sealed {
    background: var(--sun);
    box-shadow: inset 0 0 0 3px var(--sun-dark);
}

.mm-page .carton-label,
.mm-page .basket-label {
    display: block;
    text-align: center;
    font-family: 'Nunito', sans-serif;
    font-weight: 800;
    font-size: clamp(9px, 1.6vh, 12px);
    color: var(--ink-soft);
    margin-top: 3px;
}

/* Live count under each container, updating on every tap. */
.mm-page .count-badge {
    display: block;
    text-align: center;
    font-family: 'Baloo 2', sans-serif;
    font-weight: 800;
    font-size: clamp(16px, 3.4vh, 26px);
    line-height: 1.1;
    color: var(--teal-dark);
    /* Tabular figures so 9 -> 10 does not shift the label under it. */
    font-variant-numeric: tabular-nums;
    transition: color .2s ease;
}

.mm-page .count-badge.full {
    color: var(--sun-dark);
}

.mm-page .basket {
    background: var(--sky);
    border-radius: 12px;
    padding: clamp(5px, 1.2vh, 9px);
    max-width: clamp(90px, 34vw, 150px);
}

.mm-page .basket-items {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(2px, 0.8vw, 5px);
    justify-content: center;
}

.mm-page .mango {
    font-size: clamp(15px, 3vh, 22px);
    line-height: 1;
    cursor: pointer;
    transition: transform .15s ease;
}

.mm-page .mango:hover {
    transform: scale(1.15);
}

.mm-page .mango.gone {
    visibility: hidden;
}

/* --- stepped board (SteppedExerciseRenderer) ---------------------------
   One question worked out in stages, every stage on screen at once. Lives here
   rather than in scoped CSS for the same reason the rest of this file does:
   .mm-page namespacing is what lets the exercise components share a look. */
.mm-page .step-row {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 1.5rem 2.5rem;
    margin: 1.1rem 0 0.4rem;
}

.mm-page .step-slot {
    display: inline-flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.45rem 1rem;
    border-radius: 1rem;
    font-weight: 800;
    font-size: clamp(1.5rem, 4.5vw, 2.3rem);
    line-height: 1.2;
    /* Transparent rather than absent, so a slot does not shift by a border's
       width when it becomes the live one. */
    border: 2px solid transparent;
    transition: background-color .18s ease, border-color .18s ease, opacity .18s ease;
}

/* The slot the child is answering now. */
.mm-page .step-slot.is-live {
    background: #e8f4fd;
    border-color: #bfe0f7;
}

/* Its turn has not come. Dimmed, but still legible: the child is meant to see
   what is coming, just not to answer it yet. */
.mm-page .step-slot.is-locked {
    opacity: 0.45;
}

/* Done. Stays on the board with its answer in place - that standing record is
   what the next slot reads from. */
.mm-page .step-slot.is-solved .step-value {
    color: var(--ok, #2e8a54);
}

.mm-page .step-equals,
.mm-page .step-value {
    white-space: nowrap;
}

@media (max-width: 640.98px) {
    .mm-page .step-row {
        gap: 0.8rem 1.2rem;
    }
}

/* --- generated pages (HtmlExerciseRenderer) ----------------------------
   The frame a model-written exercise runs in. Sized by the page itself via the
   MM bootstrap's height message; this is the starting size and the ceiling. */
/* THE FRAME OWNS ITS HEIGHT. The page inside does not measure itself and does
   not ask - see HtmlExerciseHost.Bootstrap for the reversal and why.

   A fixed height is what makes vh and dvh mean something inside the frame: a
   generated page written with clamp(..., vh) scales to THIS box, which is
   stable, instead of to a box that was being sized from the page. */
.mm-page .html-exercise-frame {
    display: block;
    width: 100%;
    height: min(78vh, 46rem);
    min-height: 26rem;
    border: 0;
    border-radius: 1rem;
    background: transparent;
    overflow: hidden;
}

/* A TEACHER'S PEEK holds two frames, one over the other, so a new copy of the
   child's page loads out of sight - see HtmlExerciseRenderer. The box takes
   the frame's sizing rules, here and in the phone block below, and both
   frames fill it: the hidden one then lays the copy out at exactly the size
   it will be shown at. Wrapped without this, the frame lost its stretch on a
   phone and fell back to the browser's 150px default. */
.mm-page .html-peek-frames {
    position: relative;
    height: min(78vh, 46rem);
    min-height: 26rem;
}

.mm-page .html-peek-frames > .html-exercise-frame {
    position: absolute;
    inset: 0;
    height: 100%;
    min-height: 0;
}

/* NO max-height, deliberately. There was one - 80vh - and on a short window it
   capped the frame below the height the page had reported, so the content
   scrolled INSIDE the iframe and the answer buttons went off the bottom. An
   exercise is allowed to be taller than the window; the page scrolls, which is
   what a child expects. The runaway case is bounded in html-exercise.js
   instead, where a reported height is clamped before it is applied. */

/* NO HEADER ROW ABOVE THE FRAME, on any screen. The title is already the last
   crumb in the breadcrumb right above it, and the "Html" badge names a
   renderer, which means nothing to a child. Together they cost ~70px of a
   tablet's height - enough that a page which fitted only did so scaled down.
   Phones and tablets first; desktop followed, as for the module badge.

   The counters stay, floated into the card's top-right corner over the frame.
   A generated page centres its content, so that corner is empty on the pages
   there are; the counters are not interactive, so nothing underneath loses a
   tap target to them. The corner is the desktop card's padding here; the
   phone-and-tablet block below moves it in. */
.mm-page--html .badge,
.mm-page--html h1.q-title {
    display: none;
}

.mm-page--html .student-topline {
    position: absolute;
    top: 34px;
    right: 30px;
    z-index: 1;
    margin: 0;
}

/* --- generated pages on phones and tablets ------------------------------
   THE FRAME TAKES EXACTLY WHAT IS LEFT OF THE SCREEN. Invariant 12: a child
   must reach the answers without scrolling. A fixed frame height cannot
   promise that, because what sits above the frame varies - a breadcrumb that
   wraps to two lines, a route strip or none. Both earlier attempts guessed:
   min(78vh, 46rem) ran 150px off an iPad Mini in landscape, and
   calc(100dvh - 13rem) only ever applied below 641px.

   So the shell is pinned to the viewport and the frame is the one flexible
   thing in a column of fixed things. It still has a fixed height in the sense
   HtmlExerciseHost needs - set by the layout, never by the page - so vh inside
   it stays stable and the old sizing loop cannot come back.

   Through :has() rather than on the shell for every page: pinning
   article.content to the viewport is what crushed the list tables on phones,
   and lists have no business inside this rule. Global, not in MainLayout's
   scoped stylesheet, because the layout cannot see which page it is holding.

   The same media query as the folding band in app.css: phones, tablets, and a
   touch tablet in landscape that is wider than 1024px. */
@media (max-width: 1024.98px), (hover: none) and (pointer: coarse) {
    .page:has(.mm-page--html) {
        height: 100dvh;
    }

    .page:has(.mm-page--html) main {
        min-height: 0;
        overflow-y: auto;
    }

    .page:has(.mm-page--html) article.content {
        display: flex;
        flex-direction: column;
        flex: 1;
        min-height: 0;
    }

    .mm-page--html,
    .mm-page--html .frame,
    .mm-page--html .view,
    .mm-page--html .student-card {
        flex: 1;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }

    /* Desktop pads the frame for a page that scrolls; here every pixel of it
       comes out of the exercise. */
    .mm-page--html .frame {
        max-width: none;
        width: 100%;
        padding: clamp(6px, 1.2vh, 12px) clamp(8px, 1.5vw, 16px);
    }

    .mm-page--html .student-card {
        border-radius: 20px;
        padding: clamp(8px, 1.4vh, 14px) clamp(10px, 2vw, 18px);
    }

    /* The counters' corner at this card's smaller padding - see the
       header rule above this block. */
    .mm-page--html .student-topline {
        top: clamp(8px, 1.4vh, 14px);
        right: clamp(10px, 2vw, 18px);
    }

    /* The title again, under the card - on a screen with no height to spare
       it is the first thing to go. */
    .mm-page--html .caption {
        display: none;
    }

    /* The floor is a fallback, not a target: on a screen too short even for
       that, the page scrolls rather than the frame folding to nothing. */
    .mm-page--html .html-exercise-frame {
        flex: 1;
        height: auto;
        min-height: 12rem;
    }

    .mm-page--html .html-peek-frames {
        flex: 1;
        height: auto;
        min-height: 12rem;
    }

    .mm-page--html .html-peek-frames > .html-exercise-frame {
        height: 100%;
        min-height: 0;
    }
}
