/* scoped to body[data-active-page="trainer"] so seamless nav can not leak these onto other pages */
/* Standalone /trainer page overrides. Sits on top of app_core.css + style.css +
   trainer.css. Keeps the dark theme, hides the overlays that are out of scope
   for this first (core) pass, and supplies the toast + loading-overlay styles
   that only live in the per-page CSS elsewhere. */

body[data-active-page="trainer"].theme-dark, body[data-active-page="trainer"].theme-dark #app {
    background: var(--bg, #050912);
}

/* Hide non-active screens; let style.css decide the active screen's display. */
body[data-active-page="trainer"] #app .screen:not(.active) { display: none; }

/* Toast styles come from the shared app_core.css (.learn-toast). */

/* ── Loading overlay (shown while a task is fetched). ── */
body[data-active-page="trainer"] #trainer-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 9000;
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(5, 9, 18, .55);
    backdrop-filter: blur(2px);
}
body[data-active-page="trainer"] #trainer-loading-overlay.is-visible { display: flex; }
body[data-active-page="trainer"] #trainer-loading-overlay .trainer-loading-spinner {
    width: 64px;
    height: 68px;
    background: url("/static/images/energy_purchase_rabbit_loop.gif") center / contain no-repeat;
}

/* Task-number grid: 10 per row on tablet/desktop (base is 5). */
@media (min-width: 600px) {
    body[data-active-page="trainer"] .task-number-grid { grid-template-columns: repeat(10, minmax(0, 1fr)); }
}

/* Theme cards: 3 per row on tablet/desktop (base is 2). */
@media (min-width: 600px) {
    body[data-active-page="trainer"] .category-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* Show the rail XP card on desktop. The generic `.xp-progress-card { display:none }`
   at ≥1024 (hides the in-page card, and can leak from lessons.css during a seamless
   swap) also matches this rail card — re-show it with higher specificity. */
@media (min-width: 1024px) {
    body[data-active-page="trainer"] .desktop-service-xp { display: block; }
    /* The in-page XP card is desktop-hidden; the rail one takes over (scoped to
       the screen so it doesn't also hide the rail card, which has the same class). */
    body[data-active-page="trainer"] #screen-categories .xp-progress-card { display: none; }
}

/* XP card layout copied from /learn (learn.css) — trainer.css used display:flex,
   which crammed the "Опыт"/value and the bar into one row. Make it a block: meta
   row on top, full-width track below. */
body[data-active-page="trainer"] .xp-progress-card { display: block; }
body[data-active-page="trainer"] .xp-progress-meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
    color: var(--text-hint);
    font-size: 12px;
    font-weight: 700;
}
body[data-active-page="trainer"] .xp-progress-track {
    width: 100%;
    height: 9px;
    overflow: hidden;
    border-radius: 999px;
    background: color-mix(in srgb, var(--text-hint) 18%, transparent);
}
body[data-active-page="trainer"] .xp-progress-fill {
    height: 100%;
    border-radius: inherit;
    background: linear-gradient(90deg, #2f80ed, #56ccf2);
    box-shadow: 0 0 14px rgba(47, 128, 237, 0.45);
    transition: width 2.4s cubic-bezier(0.2, 0.85, 0.2, 1);
}

/* Shake feedback for empty answer (base .shake may not exist in style.css). */
body[data-active-page="trainer"] .shake { animation: trainerShake 0.4s ease; }
@keyframes trainerShake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}

/* ── subject menu — copied from /learn so it matches Обучение exactly ── */
body[data-active-page="trainer"] .subject-menu {
    position: absolute;
    top: calc(100% + 8px);
    left: -16px;
    z-index: 80;
    width: min(100vw, 480px);
    max-width: min(100vw, 480px);
    padding: 22px 14px 16px;
    border-top: 1px solid var(--card-border);
    border-bottom: 1px solid var(--card-border);
    border-right: 0;
    border-left: 0;
    border-radius: 0;
    background: var(--bg);
    box-shadow: 0 18px 28px rgba(0, 0, 0, 0.2);
}
body[data-active-page="trainer"] .subject-menu::before {
    content: "";
    position: absolute;
    top: -8px;
    left: 30px;
    width: 16px;
    height: 16px;
    background: var(--bg);
    border-left: 1px solid var(--card-border);
    border-top: 1px solid var(--card-border);
    transform: rotate(45deg);
}
body[data-active-page="trainer"] .subject-menu button {
    font-family: inherit;
}
body[data-active-page="trainer"].theme-light .subject-menu {
    box-shadow: 0 18px 30px rgba(15, 23, 42, 0.14);
}
body[data-active-page="trainer"] .subject-course-section {
    display: grid;
    gap: 10px;
}
body[data-active-page="trainer"] .subject-course-section + .subject-course-section, body[data-active-page="trainer"] .subject-course-empty {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--card-border);
}
body[data-active-page="trainer"] .subject-course-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    color: var(--text);
    font-size: 15px;
    font-weight: 900;
}
body[data-active-page="trainer"] .subject-course-title {
    color: var(--text);
    font-size: 15px;
    font-weight: 900;
}
body[data-active-page="trainer"] .subject-course-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
}
body[data-active-page="trainer"] .subject-course-card {
    width: 100%;
    min-height: 78px;
    border: 1px solid transparent;
    border-radius: 14px;
    padding: 8px 6px;
    background: transparent;
    color: var(--text);
    font-size: 11px;
    font-weight: 900;
    line-height: 1.1;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 7px;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
body[data-active-page="trainer"] .subject-course-card.active {
    border-color: rgba(86, 204, 242, 0.78);
    box-shadow: 0 0 0 2px rgba(86, 204, 242, 0.22);
}
body[data-active-page="trainer"] .subject-course-card.highlight-card {
    border-color: rgba(239, 68, 68, 0.74);
    background:
        radial-gradient(circle at 88% 10%, rgba(239, 68, 68, 0.16), transparent 38%),
        color-mix(in srgb, var(--card-bg) 92%, var(--accent) 8%);
    box-shadow:
        0 0 0 2px rgba(239, 68, 68, 0.16),
        0 10px 24px rgba(239, 68, 68, 0.16);
}
body[data-active-page="trainer"] .subject-course-card.add-card {
    color: var(--text);
    border-color: transparent;
}
body[data-active-page="trainer"] .subject-course-card.soon-card {
    cursor: default;
    opacity: 0.7;
}
body[data-active-page="trainer"] .subject-course-icon {
    width: 38px;
    height: 38px;
    object-fit: contain;
    display: block;
}
body[data-active-page="trainer"] .subject-course-plus {
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--text);
    line-height: 1;
}
body[data-active-page="trainer"] .subject-course-plus svg {
    width: 34px;
    height: 34px;
    display: block;
    fill: none;
    stroke: currentColor;
    stroke-width: 3.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
body[data-active-page="trainer"] .subject-course-name {
    max-width: 100%;
    min-height: 24px;
    overflow-wrap: normal;
    word-break: normal;
}
body[data-active-page="trainer"] .subject-course-soon {
    margin-top: -2px;
    padding: 4px 7px;
    border-radius: 999px;
    background: rgba(77, 158, 255, 0.14);
    color: var(--accent-soft);
    font-size: 10px;
    font-weight: 900;
    line-height: 1;
    text-transform: uppercase;
}
body[data-active-page="trainer"] .subject-course-new {
    margin-top: -2px;
    padding: 4px 7px;
    border-radius: 999px;
    background: rgba(239, 68, 68, 0.16);
    color: #ff8b7c;
    font-size: 9px;
    font-weight: 900;
    line-height: 1;
    text-transform: uppercase;
}
body[data-active-page="trainer"] .subject-course-card:active {
    background: var(--card-bg);
}
body[data-active-page="trainer"] .subject-course-empty {
    color: var(--text-hint);
    font-size: 13px;
    font-weight: 800;
    text-align: center;
}
@media (hover: none) and (pointer: coarse) and (min-width: 700px) and (max-width: 1180px) {
    body[data-active-page="trainer"] .subject-menu {
        width: min(100vw, 720px);
        max-width: min(100vw, 720px);
    }
}
/* Tablet (in-page status bar, before the desktop rail kicks in at 1024): the
   subject dropdown spans the full screen width like on phones — the coarse cap
   above left a gap on the right. Two classes so it beats that cap. */
@media (min-width: 700px) and (max-width: 1023px) {
    body[data-active-page="trainer"] .lessons-subject-menu.subject-menu {
        left: -16px;
        width: 100vw;
        max-width: 100vw;
    }
}
@media (max-width: 380px) {
    body[data-active-page="trainer"] .subject-menu {
        padding-left: 14px;
        padding-right: 14px;
    }
    body[data-active-page="trainer"] .subject-course-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 8px;
    }
    body[data-active-page="trainer"] .subject-course-card {
        min-height: 72px;
        padding: 7px 4px;
        font-size: 10px;
    }
    body[data-active-page="trainer"] .subject-course-icon, body[data-active-page="trainer"] .subject-course-plus {
        width: 32px;
        height: 32px;
    }
    body[data-active-page="trainer"] .subject-course-plus svg {
        width: 28px;
        height: 28px;
    }
}

@media (min-width: 1024px) {
    body[data-active-page="trainer"] .desktop-service-status .desktop-service-subject-menu {
        right: -16px;
        left: auto;
        width: var(--desktop-service-rail-width, 340px);
        max-width: var(--desktop-service-rail-width, 340px);
        border-right: 1px solid var(--card-border);
        border-left: 1px solid var(--card-border);
        border-radius: 14px;
    }

    body[data-active-page="trainer"] .desktop-service-status .desktop-service-subject-wrap {
        position: static;
    }

    body[data-active-page="trainer"] .desktop-service-status .desktop-service-subject-menu::before {
        right: auto;
        left: 30px;
    }
}

/* Gap between the hint/skip row and the answer/options/upload area (mobile) so
   they don't glue together. */
body[data-active-page="trainer"] #answer-input-container,
body[data-active-page="trainer"] #options-container,
body[data-active-page="trainer"] #upload-container {
    margin-top: 12px;
}

/* The two side fab tabs (Справочный материал / Черновик) — narrow shared width. */
body[data-active-page="trainer"] .ref-fab,
body[data-active-page="trainer"] .draft-fab {
    box-sizing: border-box;
    width: 30px;
    padding-left: 4px;
    padding-right: 4px;
    /* Round the bottom-left corner only — flat on top. */
    border-radius: 0 0 0 10px;
}
/* Where they meet, «Справочный материал» sits ON TOP of «Черновик». */
body[data-active-page="trainer"] .ref-fab { z-index: 62; }
body[data-active-page="trainer"] .draft-fab { z-index: 61; }

/* Draft board full-screen overlay must clear the mini-app top chrome in EVERY
   orientation — the base landscape rule sets `padding-top: 5vh` without the safe
   area, so on a tablet/landscape mini-app the offset was lost. This scoped rule
   wins over both. (On desktop the board is embedded in the aside — safe area is 0
   there, so this just adds the base 20px, which the aside layout already expects.) */
body[data-active-page="trainer"] #draft-board .draft-board-panel {
    padding-top: calc(20px + max(var(--app-safe-top, 0px), env(safe-area-inset-top, 0px)));
    /* Full width (not a centered 480px column) so the header aligns with the task
       content — 16px sides on phones, 24px on tablets (same as #app). */
    width: 100%;
    max-width: none;
}

/* Draft board header: arrow + «Черновик» on the LEFT (like the solve-screen header),
   not a centered title. Drawing tools sit on the right. */
body[data-active-page="trainer"] .draft-board-head {
    justify-content: flex-start;
    padding: 0 0 16px;          /* same spacing around the arrow as the solve header */
}
body[data-active-page="trainer"] .draft-board-center {
    justify-content: flex-start;
    gap: 14px;
    width: auto;
}
body[data-active-page="trainer"] .draft-board-back {
    position: static;
    transform: none;
}
body[data-active-page="trainer"] .draft-board-back:active {
    transform: scale(0.94);
}
body[data-active-page="trainer"] .draft-board-title {
    font-size: 20px;
    font-weight: 700;
    text-align: left;
}
/* Drawing tools float as a vertical palette on the RIGHT side of the board, not in
   the header. */
body[data-active-page="trainer"] .draft-canvas-wrap .draft-toolbar {
    position: absolute;
    top: 58px; right: 10px; left: auto;
    transform: none;
    z-index: 6;
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    width: auto; max-width: none;
    padding: 5px;
    background: var(--card-bg);
    border: 1px solid var(--card-border);
    border-radius: 12px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.32);
    overflow: visible;
}
body[data-active-page="trainer"] .draft-canvas-wrap .draft-size-popover {
    top: 58px; right: 62px; left: auto;
    transform: none;
    z-index: 7;
}
/* The board is always white (paper), so the palette stays light-themed regardless of
   the app theme — otherwise the icons (var(--text) = light in dark mode) vanish. */
body[data-active-page="trainer"] .draft-canvas-wrap .draft-toolbar {
    background: #ffffff;
    border-color: #d5dae3;
}
body[data-active-page="trainer"] .draft-canvas-wrap .draft-tool {
    background: #eef1f7;
    border-color: #d5dae3;
    color: #334155;
}
body[data-active-page="trainer"] .draft-canvas-wrap .draft-tool.active {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}
/* «Черновик» has short text — extra top/bottom padding makes the tab taller
   (vertical-rl text stays centered). */
body[data-active-page="trainer"] .draft-fab {
    padding-top: 44px;
    padding-bottom: 44px;
}

/* «Сообщить об ошибке» popup: read bold like in the lessons. The trainer's body
   is 400, but the popup (shared reports.css) should match the lessons' 800. */
body[data-active-page="trainer"] #report-modal { font-weight: 800; }

/* «Решение» appended onto the task condition card in the review. */
body[data-active-page="trainer"] .solve-card .solution-appended {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px solid var(--card-border);
}
body[data-active-page="trainer"] .solve-card .solution-heading {
    font-size: 16px;
    font-weight: 800;
    color: var(--text);
    margin-bottom: 10px;
}
/* The trainer's global `* { margin:0; padding:0 }` reset (trainer_base.css) clobbers
   the shared report form's own spacing, so it rendered cramped vs the lesson. Restore
   the reports.css values with a trainer-scoped selector that outweighs the reset. */
body[data-active-page="trainer"] #report-modal .report-dialog { padding: 20px 18px 24px; }
body[data-active-page="trainer"] #report-modal .report-close { padding: 0; }
body[data-active-page="trainer"] #report-modal .report-title { margin-bottom: 4px; }
body[data-active-page="trainer"] #report-modal .report-subtitle { margin-bottom: 14px; }
body[data-active-page="trainer"] #report-modal .report-reasons { margin-bottom: 14px; }
body[data-active-page="trainer"] #report-modal .report-reason { padding: 10px 12px; }
body[data-active-page="trainer"] #report-modal .report-label { margin-bottom: 6px; }
body[data-active-page="trainer"] #report-modal .report-comment { padding: 10px 12px; margin-bottom: 14px; }
@media (orientation: landscape) {
    body[data-active-page="trainer"] #report-modal .report-dialog { padding: 14px 16px 16px; }
    body[data-active-page="trainer"] #report-modal .report-subtitle { margin-bottom: 8px; }
    body[data-active-page="trainer"] #report-modal .report-reasons { margin-bottom: 8px; }
    body[data-active-page="trainer"] #report-modal .report-reason { padding: 7px 10px; }
    body[data-active-page="trainer"] #report-modal .report-comment { padding: 8px 10px; margin-bottom: 10px; }
}

/* Mobile/tablet: reserve room on the right so the fixed side fabs don't cover the
   task text / answer. Reset on desktop (fabs are hidden there). */
/* Mobile/tablet: smaller condition + solution text and tighter edges so the solve
   page isn't so long. */
@media (max-width: 1023px) {
    body[data-active-page="trainer"][data-active-screen="screen-solve"] #app {
        padding-left: 12px;
        padding-right: 12px;
    }
    body[data-active-page="trainer"] #screen-solve .solve-card {
        padding: 12px;
    }
    body[data-active-page="trainer"] #screen-solve .task-text,
    body[data-active-page="trainer"] #screen-solve .solution-text,
    body[data-active-page="trainer"] #screen-exam-attempt .task-text {
        font-size: 14px;
        line-height: 1.55;
    }
    body[data-active-page="trainer"] #screen-solve .solution-heading {
        font-size: 15px;
    }
}

body[data-active-page="trainer"] #screen-solve {
    padding-right: 22px;    /* condition tucks slightly UNDER the side fabs (which sit
                               on top) so it reads as touching them — no visible gap */
    /* Clear the fixed answer bar (input + [Пропустить][Ответить] ≈ 130px + safe area)
       so tall in-flow content (e.g. the open hint chat) never hides under it. */
    padding-bottom: calc(140px + var(--app-safe-bottom, env(safe-area-inset-bottom, 0px)));
}

/* ── Mobile/tablet: answer as a fixed bottom bar ──────────────────────────────
   Collapsed by default (only [Пропустить][Ответить]); tapping «Ответить» slides
   the input up, then a second tap submits. (Desktop resets this in the split.) */
body[data-active-page="trainer"] #answer-input-container {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 55;
    margin: 0;
    padding: 8px 12px calc(10px + var(--app-safe-bottom, 0px));
    background: var(--bg);
    border-top: 1px solid var(--card-border);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
}
/* Compact bottom bar: smaller input + shorter buttons. */
body[data-active-page="trainer"] #answer-input-container .answer-input {
    padding: 9px 14px;
    font-size: 15px;
    border-width: 1px;
}
body[data-active-page="trainer"] #answer-input-container .answer-input-row {
    display: flex;
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 0;        /* skip + submit touch → one merged control */
    align-items: stretch;
}
body[data-active-page="trainer"] #answer-input-container .answer-input {
    order: -1;            /* always on top, always visible */
    flex: 1 1 100%;
}
/* Пропустить (left, smaller) + Ответить (right, bigger) look like one connected
   control: no gap between them, and the touching corners are flat. */
body[data-active-page="trainer"] #answer-input-container .task-skip-btn {
    order: 1; flex: 1 1 30%; min-width: 0; height: 46px; font-size: 13px;
    border-radius: var(--radius-sm);            /* Пропустить — modest outer corner */
    border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: none;
}
body[data-active-page="trainer"] #answer-input-container .btn-submit {
    order: 2; flex: 1 1 70%; width: auto; min-width: 0; height: 46px; margin: 0; font-size: 14px;
    border-radius: var(--radius-sm);             /* Ответить — same modest corner as Пропустить */
    border-top-left-radius: 0; border-bottom-left-radius: 0;
}

/* Solution/review screen: [Показать решение | Далее] merged like [Пропустить |
   Ответить] AND pinned to the bottom in place of the (now-hidden) answer bar.
   Correct → both buttons; incorrect → only «Показать решение» (Далее appears once
   the solution is opened). A single visible button fills the bar. */
body[data-active-page="trainer"] .result-nav-row {
    display: flex; column-gap: 0; align-items: stretch;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 55;
    margin: 0;
    padding: 8px 12px calc(10px + var(--app-safe-bottom, 0px));
    background: var(--bg);
    border-top: 1px solid var(--card-border);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
}
body[data-active-page="trainer"] .result-solution-btn {
    flex: 1 1 50%; min-width: 0; height: 46px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--card-bg); border: 1px solid var(--card-border); border-right: none;
    color: var(--text); font: inherit; font-size: 14px; font-weight: 800; cursor: pointer;
    border-radius: var(--radius-sm);
    border-top-right-radius: 0; border-bottom-right-radius: 0;
}
body[data-active-page="trainer"] .result-next-btn {
    flex: 1 1 50%; min-width: 0; height: 46px; margin: 0; font-size: 14px;
    border-radius: var(--radius-sm);
    border-top-left-radius: 0; border-bottom-left-radius: 0;
}
/* Only one button visible → it fills the bar with full rounding. */
body[data-active-page="trainer"] .result-nav-row.is-single .result-solution-btn {
    border-right: 1px solid var(--card-border);
    border-radius: var(--radius-sm);
}
body[data-active-page="trainer"] .result-nav-row.is-single .result-next-btn {
    border-radius: var(--radius-sm);
}

/* Phone/tablet: the help bar is a merged pair [Подсказка от Заппи | Разобрать
   решение], styled like [Пропустить | Ответить] and shown on EVERY task. (Desktop
   hides this inline panel — its split UI is handled separately.) */
body[data-active-page="trainer"] #ai-hint-panel {
    display: flex;
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 0;               /* the two touch → one merged control */
    align-items: stretch;
    margin: 0 0 16px;            /* flush against the task card — no top gap */
}
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab,
body[data-active-page="trainer"] #ai-hint-panel .btn-giveup {
    flex: 1 1 50%; min-width: 0; height: auto; min-height: 58px; margin: 0;
    font-size: 13px; white-space: normal; line-height: 1.15; text-align: center;
}
/* Let «Подсказка от Заппи» wrap onto two lines like «Разобрать решение с Заппи»
   (its label is nowrap+ellipsis by default). */
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab-label {
    white-space: normal;
    line-height: 1.15;
    overflow: visible;
    text-overflow: clip;
}
/* Drop the neural-net (AI) icon and the «-1» energy pill inside «Подсказка от Заппи»
   — just the label. */
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab .ai-hint-icon,
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab .energy-cost-pill {
    display: none;
}
/* Everywhere else the AI (neural-net) glyph is replaced by Zappi's round avatar. */
body[data-active-page="trainer"] .ai-hint-icon {
    background: url("/static/images/zappi_lesson_chat.png") center / cover no-repeat;
    -webkit-mask: none;
    mask: none;
    border-radius: 50%;
    width: 20px;
    height: 20px;
    display: inline-block;
    flex: 0 0 auto;
}
/* Round Zappi avatar straddling the seam where the two buttons meet. */
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab { position: relative; }
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab::after {
    content: "";
    position: absolute;
    right: 0; top: 50%;
    transform: translate(50%, -50%);
    width: 36px; height: 36px;
    border-radius: 50%;
    background: #0e1a2e url("/static/images/zappi_lesson_chat.png") center / cover no-repeat;
    box-shadow: 0 0 0 3px var(--bg), 0 2px 6px rgba(0, 0, 0, 0.35);
    z-index: 3;
    pointer-events: none;
}
/* No outline around the energy pills (-1/-2 ⚡). */
body[data-active-page="trainer"] .energy-cost-pill {
    border: none;
    box-shadow: none;
    outline: none;
}
/* «Отправить решение» (part 2): -2⚡ shows bare, without the pill chip frame. */
body[data-active-page="trainer"] #btn-upload .energy-cost-pill {
    border: none;
    background: none;
    padding: 0;
}
body[data-active-page="trainer"] #ai-hint-panel .ai-hint-fab {         /* Подсказка — left */
    border-radius: var(--radius-sm);
    border-top-right-radius: 0; border-bottom-right-radius: 0;
    padding-right: 24px;        /* keep the -1⚡ pill clear of the seam avatar */
}
body[data-active-page="trainer"] #ai-hint-panel .btn-giveup {         /* Разобрать — right */
    border-radius: var(--radius-sm);
    border-top-left-radius: 0; border-bottom-left-radius: 0;
    padding-left: 24px;         /* keep the label clear of the seam avatar */
}
/* «Пропустить» (multiple-choice tasks, где нет поля ответа) — отдельной строкой ниже. */
body[data-active-page="trainer"] #ai-hint-panel .task-skip-btn {
    order: 3; flex: 1 1 100%;
}

/* ── Hint/solution chat, styled exactly like the lesson chat (обучение) ─────────
   renderAiHintMessages() builds the same DOM (avatar + bubble), so we port the
   .lesson-chat-* styles here (the trainer doesn't load lessons.css). */
body[data-active-page="trainer"] #ai-hint-box {
    padding: 2px 2px 8px;
    border: none;
    background: none;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    overflow-y: auto;
}
/* The message wrapper is now just a flex row/column; the real bubble is its child. */
body[data-active-page="trainer"] #ai-hint-box .ai-hint-message.lesson-chat-message {
    max-width: none; width: auto; padding: 0; border: none; background: none;
    border-radius: 0; box-shadow: none; white-space: normal;
    display: flex; align-items: flex-end; gap: 9px; margin: 0 0 12px;
}
body[data-active-page="trainer"] #ai-hint-box .ai-hint-message.lesson-chat-assistant {
    align-items: flex-start; flex-direction: column-reverse; gap: 7px;
}
body[data-active-page="trainer"] #ai-hint-box .ai-hint-message.lesson-chat-user { justify-content: flex-end; }
body[data-active-page="trainer"] #ai-hint-box .lesson-zappi-avatar {
    flex: 0 0 34px; width: 34px; height: 34px; padding: 0;
    border-radius: 14px; background: #1d1d1d;
    border: 1px solid rgba(39, 119, 255, 0.32);
    object-fit: cover; box-shadow: 0 8px 18px rgba(39, 119, 255, 0.18);
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-bubble {
    max-width: min(94%, 720px); padding: 13px 14px;
    border-radius: 18px 18px 18px 6px;
    border: 1px solid rgba(39, 119, 255, 0.22);
    background: rgba(8, 20, 38, 0.88);
    color: var(--text); font-size: 15px; line-height: 1.38; font-weight: 500;
    box-shadow: 0 12px 26px rgba(0, 0, 0, 0.16);
    white-space: normal;
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-assistant .lesson-chat-bubble {
    width: min(100%, 720px); max-width: 100%; border-radius: 18px 18px 18px 8px;
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-text { color: var(--text); }
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-text b,
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-text strong {
    color: var(--text); font-weight: 700;
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-user .lesson-chat-bubble {
    border-radius: 18px 18px 6px 18px; background: #2777ff;
    border-color: rgba(255, 255, 255, 0.12); color: #fff;
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-user .lesson-chat-text,
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-user .lesson-chat-text b,
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-user .lesson-chat-text strong {
    color: #fff; font-weight: 500;
}
/* Drop the AI icon + «Заппи» title from the chat header. */
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-sheet-title {
    display: none;
}
/* Chat feed: full width and taller. */
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-sheet-panel { width: 100%; }
body[data-active-page="trainer"] #ai-hint-box {
    width: 100%;
    height: 44vh;
    max-height: 44vh;
}
/* The chat container is rounded the same as its input row (18px). */
body[data-active-page="trainer"] .ai-hint-sheet-panel {
    border-radius: 18px;
}

/* ── Phone/tablet: «Разобрать с Заппи» is its own fixed bar just above the
   [home | Далее] bar, and the chat opens as a full-screen bottom sheet from it. ── */
@media (max-width: 1023px) {
    /* «Разобрать с Заппи» is pulled out into a fixed bar, so #solution-box has no
       in-flow content left — strip its card frame so it doesn't render as an empty
       bordered box on the review screen. */
    body[data-active-page="trainer"] #solution-box {
        margin: 0;
        padding: 0;
        border: none;
        background: none;
    }
    body[data-active-page="trainer"] #solution-box .solution-ai-btn {
        position: fixed;
        left: 0; right: 0;
        bottom: calc(64px + var(--app-safe-bottom, 0px));   /* sits on top of [home|Далее] */
        z-index: 56;
        width: auto;
        margin: 0;
        height: 52px;
        border: none;
        border-radius: 0;
        background: var(--accent);
        color: var(--accent-text);
        box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.28);
    }

    /* ONLY the «Разобрать с Заппи» chat (solution-explanation mode) becomes a
       full-screen bottom sheet. The «Подсказка» hint chat keeps its inline look. */
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode {
        position: fixed;
        inset: 0;
        z-index: 210;
    }
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode .ai-hint-sheet-backdrop {
        display: block;
        position: absolute; inset: 0;
        background: rgba(0, 0, 0, 0.45);
        pointer-events: auto;
    }
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode .ai-hint-sheet-panel {
        position: absolute;
        left: 0; right: 0; bottom: 0;
        width: 100%;
        height: 50vh; max-height: 50vh;   /* half-screen sheet in the review */
        /* override ai_hints.css `.solution-ai-btn + .ai-hint-sheet .panel { margin:0 0 6px !important }`
           which otherwise lifts the sheet 6px off the bottom edge */
        margin: 0 !important;
        border: none;                     /* no side/bottom frame… */
        border-top: 1px solid rgba(77, 158, 255, 0.24);   /* …only the top outline */
        border-radius: 18px 18px 0 0;
        transform: translateY(0);
        transition: transform 0.26s ease;
        padding-bottom: calc(10px + var(--app-safe-bottom, 0px));
    }
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode.is-collapsed .ai-hint-sheet-panel {
        transform: translateY(100%);
    }
    /* The message feed fills the sheet (head on top, input pinned at the bottom).
       #ai-hint-box lives inside .ai-hint-sheet-body, so that wrapper must grow too —
       otherwise the feed clumps at the top and the input floats mid-panel. */
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode .ai-hint-sheet-body {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
    }
    body[data-active-page="trainer"] #ai-hint-sheet.is-solution-mode #ai-hint-box {
        flex: 1 1 auto;
        min-height: 0;
        height: auto; max-height: none;
    }
}

/* Input row + send button + thinking dots — identical to the lesson chat.
   No wrapping frame: the input and the send button each carry their own border. */
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: stretch;
    gap: 0;                 /* input flows straight into the send button */
    margin-top: 6px;
    padding: 0;
    border: none;
    background: none;
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-input {
    width: 100%;
    height: 50px;
    min-height: 50px;
    box-sizing: border-box;
    border: 1px solid rgba(148, 163, 184, 0.22);
    border-radius: 14px 0 0 14px;   /* square on the side that meets the button */
    padding: 12px 13px;
    background: rgba(2, 8, 23, 0.52);
    color: var(--text);
    font: inherit;
    font-size: 14px;
    line-height: 1.3;
    outline: none;
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-input:focus {
    border-color: rgba(39, 119, 255, 0.72);
    box-shadow: 0 0 0 3px rgba(39, 119, 255, 0.14);
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-send {
    min-width: 102px;
    height: 50px;
    min-height: 50px;
    box-sizing: border-box;
    margin-left: -1px;      /* overlap borders so the seam is a single line */
    padding: 0 13px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    border: 1px solid rgba(39, 119, 255, 0.3);
    border-radius: 0 15px 15px 0;   /* square on the side that meets the input */
    background: rgba(39, 119, 255, 0.13);
    color: var(--text);
    font: inherit;
    font-size: 13px;
    font-weight: 900;
    cursor: pointer;
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-send:disabled {
    opacity: 0.45;
    cursor: default;
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-send-cost {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    font-weight: 800;
    white-space: nowrap;
}
body[data-active-page="trainer"] #ai-hint-sheet .ai-hint-send-cost img {
    width: 14px;
    height: 14px;
}
/* «Думает…» dots + typing cursor — ported from the lesson. */
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-text.is-thinking::after {
    content: "";
    display: inline-block;
    width: 1.35em;
    margin-left: 3px;
    text-align: left;
    vertical-align: baseline;
    animation: lessonThinkingDots 1.05s steps(4, end) infinite;
}
body[data-active-page="trainer"] #ai-hint-box .lesson-chat-text.is-typing::after {
    content: "";
    display: inline-block;
    width: 7px;
    height: 1em;
    margin-left: 3px;
    border-radius: 4px;
    background: currentColor;
    vertical-align: -0.16em;
    animation: lessonTypingCursor 0.75s steps(2, start) infinite;
}
@keyframes lessonThinkingDots {
    0%   { content: ""; }
    25%  { content: "."; }
    50%  { content: ".."; }
    75%, 100% { content: "..."; }
}
@keyframes lessonTypingCursor {
    0%, 45%   { opacity: 1; }
    46%, 100% { opacity: 0; }
}

/* ── Light theme: the ported chat is built with dark surfaces, so on a white page
   the assistant bubbles + input read as dark-on-dark. Give them light surfaces. ── */
body.theme-light[data-active-page="trainer"] #ai-hint-box .lesson-chat-bubble,
body.theme-light[data-active-page="trainer"] #ai-hint-box .lesson-chat-assistant .lesson-chat-bubble {
    background: #eef2fb;
    border-color: rgba(30, 111, 255, 0.2);
    color: var(--text);
    box-shadow: 0 8px 20px rgba(15, 30, 60, 0.08);
}
body.theme-light[data-active-page="trainer"] #ai-hint-box .lesson-chat-user .lesson-chat-bubble {
    background: #2777ff;                 /* keep the blue user bubble */
    border-color: rgba(39, 119, 255, 0.35);
    color: #fff;
}
body.theme-light[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-form {
    background: #eef2fb;
    border-color: rgba(30, 111, 255, 0.2);
}
body.theme-light[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-input {
    background: #fff;
    border-color: rgba(30, 111, 255, 0.24);
    color: var(--text);
}
body.theme-light[data-active-page="trainer"] #ai-hint-sheet .ai-hint-question-send {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* Phone/tablet: while the user is TYPING in the hint chat (its input is focused),
   hide the fixed answer/upload bar — it is pinned to the bottom and would otherwise
   cover the chat input. (This media query is the inverse of the desktop split, so on
   desktop — where the bar is inline and the chat lives in the aside — nothing hides.) */
@media (max-width: 1023px) {
    body[data-active-page="trainer"].ai-hint-input-focused #answer-input-container,
    body[data-active-page="trainer"].ai-hint-input-focused #upload-container {
        display: none !important;
    }
}

/* Photo-upload answer — same fixed bottom bar: photo input on top, then
   [Пропустить][Отправить решение], with «Разобрать с Заппи» below. JS sets its
   display to flex on mobile so flex-wrap + order apply. */
body[data-active-page="trainer"] #upload-container {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 55;
    margin: 0;
    padding: 10px 14px calc(12px + var(--app-safe-bottom, 0px));
    background: var(--bg);
    border-top: 1px solid var(--card-border);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
    flex-wrap: wrap;
    row-gap: 8px;
    column-gap: 0;        /* skip + submit touch → one merged control */
    align-items: stretch;
}
body[data-active-page="trainer"] #upload-container .input-label { order: -4; flex: 1 1 100%; margin: 0; }
body[data-active-page="trainer"] #upload-container .upload-area { order: -3; flex: 1 1 100%; min-height: 92px; padding: 12px; }
body[data-active-page="trainer"] #upload-container #file-preview { order: -2; flex: 1 1 100%; }
/* Пропустить (left, smaller) + Отправить решение (right, bigger) merge into one
   connected control: no gap, flat touching corners. */
body[data-active-page="trainer"] #upload-container .task-skip-btn {
    order: 1; flex: 1 1 30%; min-width: 0; height: 58px;
    border-radius: var(--radius-sm);            /* Пропустить — modest outer corner */
    border-top-right-radius: 0; border-bottom-right-radius: 0; border-right: none;
}
body[data-active-page="trainer"] #upload-container #btn-upload {
    order: 2; flex: 1 1 70%; width: auto; min-width: 0; height: 58px; margin: 0;
    border-radius: var(--radius-sm);             /* Отправить — same modest corner as Пропустить */
    border-top-left-radius: 0; border-bottom-left-radius: 0;
}
/* Extra bottom room so the (taller) upload bar never covers the task. */
body[data-active-page="trainer"] #screen-solve.has-upload-bar { padding-bottom: 230px; }

/* Photo-solution previews: small fixed-size thumbnails in a single row that scrolls
   sideways — adding photos fills the row, it never grows the upload block taller. */
body[data-active-page="trainer"] #upload-container #file-preview-list {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 8px;
    padding: 8px;
    -webkit-overflow-scrolling: touch;
}
body[data-active-page="trainer"] #upload-container #file-preview-list .file-preview-item {
    flex: 0 0 auto;
    width: 56px;
}
body[data-active-page="trainer"] #upload-container #file-preview-list .file-preview-item img {
    width: 56px;
    height: 56px;
    aspect-ratio: auto;
}
/* «+» tile to add more photos, sized like a thumbnail, at the end of the row. */
body[data-active-page="trainer"] #upload-container #file-preview-list .file-preview-add {
    flex: 0 0 auto;
    width: 56px; height: 56px;
    border-radius: 8px;
    border: 1px dashed var(--card-border);
    background: var(--card-bg);
    color: var(--text-hint);
    font-size: 28px; font-weight: 400; line-height: 1;
    display: inline-flex; align-items: center; justify-content: center;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
}
/* Shrink the per-thumb controls to fit the small tiles. */
body[data-active-page="trainer"] #upload-container #file-preview-list .file-preview-remove {
    width: 18px; height: 18px; top: 2px; right: 2px; font-size: 13px; line-height: 1;
}
body[data-active-page="trainer"] #upload-container #file-preview-list .file-preview-index {
    padding: 1px 5px; font-size: 10px; right: 3px; bottom: 3px;
}

/* ── Desktop split solve screen: task left, tabbed chat/board/reference right ──
   Desktop-with-mouse only. Phones and tablets (touch) keep the app's original
   fab-triggered chat / draft-board / reference overlays. */
body[data-active-page="trainer"] .solve-aside { display: none; }

@media (min-width: 1024px) {
    /* Fabs are hidden on desktop — no fab gutter/bottom-bar needed; instead the
       solve content gets comfortable side margins. */
    body[data-active-page="trainer"] #screen-solve,
    body[data-active-page="trainer"] #screen-solve.has-upload-bar {
        padding-left: 40px;
        padding-right: 40px;
        padding-bottom: 0;
    }
    body[data-active-page="trainer"] #answer-input-container,
    body[data-active-page="trainer"] #upload-container,
    body[data-active-page="trainer"] .result-nav-row {
        position: static; margin: 0; padding: 0;
        background: none; border-top: none; box-shadow: none;
    }
    /* Review «Далее» floats as a bottom-centre bar, like the answer bar. */
    body[data-active-page="trainer"] .result-nav-row {
        position: fixed;
        left: 50%; bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: min(960px, calc(100vw - 48px));
        margin: 0; padding: 10px 14px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }
    /* The solution-explanation chat lives in the aside on desktop, so the inline
       «Задать вопрос Заппи» button is redundant. */
    body[data-active-page="trainer"][data-active-screen="screen-solve"] #solution-box .solution-ai-btn {
        display: none;
    }
    /* …which leaves #solution-box empty — strip its card frame so it doesn't show. */
    body[data-active-page="trainer"][data-active-screen="screen-solve"] #solution-box {
        margin: 0; padding: 0; border: none; background: none;
    }
    body[data-active-page="trainer"] #answer-input-container .answer-input { display: block; }
    body[data-active-page="trainer"] #answer-input-container .answer-input-row { flex-wrap: nowrap; column-gap: 8px; }
    /* Undo the mobile "merged buttons": on desktop the answer is inline and skip
       lives with the hint FAB, so restore normal radii/heights/gaps. */
    body[data-active-page="trainer"] #answer-input-container .btn-submit,
    body[data-active-page="trainer"] #answer-input-container .task-skip-btn,
    body[data-active-page="trainer"] #upload-container #btn-upload,
    body[data-active-page="trainer"] #upload-container .task-skip-btn {
        height: auto; border-right: 1px solid var(--card-border); border-radius: var(--radius-sm);
    }
    body[data-active-page="trainer"] #answer-input-container .task-skip-btn,
    body[data-active-page="trainer"] #upload-container .task-skip-btn { border-radius: 999px; }
    body[data-active-page="trainer"] #answer-input-container .btn-submit,
    body[data-active-page="trainer"] #upload-container #btn-upload { border-right: none; }
    body[data-active-page="trainer"] #upload-container { column-gap: 8px; }

    /* ── Desktop answer bar: floating pill pinned to the bottom-centre, above all
       the solve-screen content. [Пропустить | Ввод | Ответить] in one row. ──────── */
    body[data-active-page="trainer"] #answer-input-container {
        position: fixed;
        left: 50%;
        bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: min(960px, calc(100vw - 48px));   /* same width as the centred column */
        margin: 0;
        padding: 10px 14px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }
    body[data-active-page="trainer"] #answer-input-container .answer-input-row {
        align-items: stretch;
    }
    /* Desktop: the condition photo opens full-screen on click. */
    body[data-active-page="trainer"] #screen-solve .task-img-zoom .pinch-img { cursor: zoom-in; }
    body[data-active-page="trainer"] #answer-input-container .answer-input-row .task-skip-btn {
        order: -1;                        /* Пропустить at the far left */
        flex: 0 0 auto;
        min-height: 0; height: 46px;
        margin-right: auto;               /* push [Ввод | Ответить] to the right edge */
        padding: 0 18px;
        box-shadow: none;
        border-radius: var(--radius-sm) !important;
        border: 1px solid var(--card-border) !important;
    }
    body[data-active-page="trainer"] #answer-input-container .answer-input {
        flex: 0 0 auto; width: 300px; max-width: 46vw; min-width: 0;
        height: 46px; box-sizing: border-box;
    }
    body[data-active-page="trainer"] #answer-input-container .btn-submit {
        flex: 0 0 auto; height: 46px; padding: 0 26px;
    }
    /* Clear space at the bottom of both columns so the last content isn't stuck
       behind the floating answer bar (bar ≈ 66px tall + 24px offset + shadow). */
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .solve-main {
        padding-bottom: 140px;
    }
    /* Part 2: the floating photo card is much taller — clear it too. */
    body[data-active-page="trainer"] #screen-solve.solve-has-upload .solve-main {
        padding-bottom: 300px;
    }

    /* ── Desktop: the photo-solution upload floats as a bottom-centre card too. ──── */
    body[data-active-page="trainer"] #upload-container {
        position: fixed;
        left: 50%;
        bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: min(960px, calc(100vw - 48px));   /* same width as the centred column */
        margin: 0;
        padding: 14px 16px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
        display: flex; flex-wrap: wrap; row-gap: 10px; column-gap: 0; align-items: stretch;
    }
    /* Label + photo picker span the full width; skip + submit share the last row as
       one merged control (zero gap + flat inner corners), like on phones. */
    body[data-active-page="trainer"] #upload-container > .input-label,
    body[data-active-page="trainer"] #upload-container > .upload-area,
    body[data-active-page="trainer"] #upload-container > #file-preview {
        flex: 1 1 100%; margin: 0;
    }
    body[data-active-page="trainer"] #upload-container .task-skip-btn {
        order: 10; flex: 0 0 auto; width: auto; margin: 0; height: 50px;
        border-radius: var(--radius-sm) 0 0 var(--radius-sm) !important;
        border-right: none !important;
    }
    body[data-active-page="trainer"] #upload-container #btn-upload {
        order: 11; flex: 1 1 auto; margin: 0; height: 50px;
        border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    }

    /* Light theme: a white floating card on a white page needs a firmer edge to
       read — stronger border + a deeper drop shadow. */
    body.theme-light[data-active-page="trainer"] #answer-input-container,
    body.theme-light[data-active-page="trainer"] #upload-container,
    body.theme-light[data-active-page="trainer"] .result-nav-row {
        border-color: rgba(30, 111, 255, 0.3);
        box-shadow: 0 14px 34px rgba(15, 30, 60, 0.2), 0 1px 3px rgba(15, 30, 60, 0.14);
    }

    /* ── Right «Подсказка» pane: just the chat. The hint panel (fab + Разобрать +
       Пропустить) is emptied — «Разобрать» moves under the task condition, Пропустить
       to the answer bar — so hide the panel entirely. ── */
    body[data-active-page="trainer"] .aside-pane-hint .ai-hint-panel { display: none !important; }
    /* «Разобрать решение с Заппи» under the task condition (left column). */
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .solve-main > #btn-giveup {
        display: flex;
        width: 100%;
        margin: 12px 0 0;
        min-height: 52px;
        border-radius: var(--radius-sm);
    }
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .solve-body {
        display: flex;
        align-items: stretch;
        gap: 20px;
    }
    /* Left and right are equal halves. */
    body[data-active-page="trainer"] .solve-main { flex: 1 1 0; min-width: 0; }
    /* Compact task condition on desktop — smaller text, tighter card. The exam
       attempt (condition + result solution) matches the solve screen. */
    body[data-active-page="trainer"] #screen-solve .solve-card { padding: 15px 18px; }
    body[data-active-page="trainer"] #screen-solve .task-text,
    body[data-active-page="trainer"] #screen-exam-attempt .task-text { font-size: 14px; line-height: 1.5; }
    body[data-active-page="trainer"] #screen-solve .task-meta-row { margin-bottom: 6px; }
    body[data-active-page="trainer"] .solve-aside {
        display: flex;
        flex-direction: column;
        gap: 12px;
        flex: 1 1 0;
        min-width: 0;
        position: sticky;
        top: calc(12px + var(--app-safe-top, 0px));   /* clear the mini-app top chrome */
        align-self: flex-start;
    }
    /* The floating fabs + the left-column hint panel are replaced by the tabs
       (the hint panel moves into the «Подсказка от Заппи» tab). */
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .ref-fab,
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .draft-fab,
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .solve-main .ai-hint-panel {
        display: none !important;
    }

    /* Three toggle buttons. */
    body[data-active-page="trainer"] .aside-tabs { display: flex; gap: 8px; }
    body[data-active-page="trainer"] .aside-tab {
        flex: 1 1 0;
        min-width: 0;
        padding: 11px 8px;
        border: 1px solid var(--card-border);
        border-radius: 12px;
        background: var(--card-bg);
        color: var(--text-hint);
        font-size: 12px;
        font-weight: 800;
        cursor: pointer;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        opacity: 0.55;                    /* inactive tabs dimmed */
        transition: opacity 0.15s, background 0.15s, color 0.15s, border-color 0.15s;
    }
    /* Tab colours match the mobile fabs. */
    body[data-active-page="trainer"] .aside-tab[data-tab="board"] {   /* Черновик — brown */
        background: #b57b38; border-color: rgba(89, 52, 20, 0.4); color: #fff8df;
    }
    body[data-active-page="trainer"] .aside-tab[data-tab="ref"] {     /* Справочный — accent */
        background: var(--accent); border-color: var(--accent); color: #fff;
    }
    /* «Подсказка от Заппи» tab carries Zappi's avatar next to the label. */
    body[data-active-page="trainer"] .aside-tab[data-tab="hint"] {
        display: inline-flex; align-items: center; justify-content: center; gap: 6px;
    }
    body[data-active-page="trainer"] .aside-tab[data-tab="hint"] .ai-hint-icon {
        width: 18px; height: 18px; flex: 0 0 auto;
    }
    /* The selected tab is the bright one (its colour identity stays). */
    body[data-active-page="trainer"] .aside-tab.active {
        opacity: 1;
        box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.9);   /* highlight the open pane's tab */
    }

    /* ── Collapse the right pane: » in the tabs row hides it, the task column
       centres like the lesson screen, « on the right edge brings it back. ── */
    body[data-active-page="trainer"] .aside-collapse-btn {
        flex: 0 0 auto;
        width: 36px;
        border: 1px solid var(--card-border);
        border-radius: 12px;
        background: var(--card-bg);
        color: var(--text-hint);
        font-size: 17px;
        line-height: 1;
        cursor: pointer;
        transition: color 0.15s, border-color 0.15s;
    }
    body[data-active-page="trainer"] .aside-collapse-btn:hover { color: var(--text); }
    body[data-active-page="trainer"] .solve-body.aside-collapsed .solve-aside { display: none; }
    body[data-active-page="trainer"][data-active-screen="screen-solve"] .solve-body.aside-collapsed {
        justify-content: center;
    }
    body[data-active-page="trainer"] .solve-body.aside-collapsed .solve-main {
        flex: 0 1 min(960px, 100%);
        max-width: min(960px, 100%);
    }
    /* The header (back + title) joins the same centred column, so the whole page
       reads as one vertical strip. */
    body[data-active-page="trainer"] #screen-solve:has(.solve-body.aside-collapsed) .screen-header {
        width: min(960px, 100%);
        margin-left: auto;
        margin-right: auto;
    }
    body[data-active-page="trainer"] #aside-expand-btn {
        position: fixed;
        right: 0; top: 50%;
        transform: translateY(-50%);
        z-index: 70;
        width: 44px; height: 128px;
        align-items: center; justify-content: center;
        border: none;
        border-radius: 16px 0 0 16px;
        background: var(--accent);
        color: #fff;
        font-size: 26px;
        font-weight: 900;
        cursor: pointer;
        box-shadow: -6px 0 18px rgba(30, 111, 255, 0.4);
        transition: width 0.15s ease;
    }
    body[data-active-page="trainer"] #aside-expand-btn:hover { width: 52px; }

    /* Only the active pane is shown. */
    body[data-active-page="trainer"] .aside-pane { display: none; flex: 1 1 auto; min-height: 0; }
    body[data-active-page="trainer"] .solve-aside[data-tab="hint"]  .aside-pane-hint,
    body[data-active-page="trainer"] .solve-aside[data-tab="board"] .aside-pane-board,
    body[data-active-page="trainer"] .solve-aside[data-tab="ref"]   .aside-pane-ref {
        display: flex;
        flex-direction: column;
    }
    /* Hint pane: just the chat (the panel is hidden above — Разобрать/Пропустить
       moved elsewhere). */
    body[data-active-page="trainer"] .aside-pane-hint { gap: 10px; }

    /* AI chat embedded inline in the hint pane (not the fixed bottom-sheet) —
       full width of the pane, tall. */
    body[data-active-page="trainer"] #solve-aside .ai-hint-sheet {
        position: static; inset: auto; display: block !important;
        background: none; z-index: auto; width: 100%;
    }
    body[data-active-page="trainer"] #solve-aside .ai-hint-sheet-backdrop { display: none; }
    body[data-active-page="trainer"] #solve-aside .ai-hint-sheet-panel {
        position: static; width: 100%; max-width: none;
        height: calc(100vh - 240px); min-height: 420px; max-height: none; margin: 0;
        border-radius: 18px; border: 1px solid var(--card-border);
        transform: none;
    }
    /* Message feed fills the tall panel so the input sits at the very bottom
       (otherwise #ai-hint-box's fixed 44vh leaves empty space below the input). */
    body[data-active-page="trainer"] #solve-aside .ai-hint-sheet-body {
        flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column;
    }
    body[data-active-page="trainer"] #solve-aside #ai-hint-box {
        flex: 1 1 auto; min-height: 0; height: auto; max-height: none;
    }

    /* Draft board embedded inline (not the fixed full-screen overlay). */
    body[data-active-page="trainer"] #solve-aside .draft-board {
        position: static; inset: auto; display: block !important;
        background: none; z-index: auto; backdrop-filter: none;
    }
    body[data-active-page="trainer"] #solve-aside .draft-board-panel {
        position: static; width: 100%; max-width: none;
        height: calc(100vh - 240px); min-height: 420px; max-height: none; margin: 0;
        border-radius: 16px; border: 1px solid var(--card-border);
        /* Header is hidden on desktop, so the board gets the single filling row and
           only a slim uniform padding (no safe-area top). */
        grid-template-rows: minmax(0, 1fr);
        padding: 8px;
    }
    body[data-active-page="trainer"] #solve-aside .draft-board-back { display: none; }
    /* No «Черновик» title / report flag on desktop — drop the whole header. */
    body[data-active-page="trainer"] #solve-aside .draft-board-head { display: none; }
    body[data-active-page="trainer"] #solve-aside .draft-canvas-wrap { border-radius: 16px; }

    /* Part 2 (photo): the floating upload card is tall and overlaps the aside's
       bottom, so shrink the chat/board panes to clear it. */
    body[data-active-page="trainer"] #screen-solve.solve-has-upload #solve-aside .ai-hint-sheet-panel,
    body[data-active-page="trainer"] #screen-solve.solve-has-upload #solve-aside .draft-board-panel {
        height: calc(100vh - 400px);
    }
    body[data-active-page="trainer"] #screen-solve.solve-has-upload #solve-aside .aside-pane-ref {
        max-height: calc(100vh - 400px);
    }

    /* Reference-material pane. */
    body[data-active-page="trainer"] .aside-pane-ref {
        background: var(--card-bg);
        border: 1px solid var(--card-border);
        border-radius: 16px;
        padding: 14px;
        gap: 10px;
        max-height: calc(100vh - 240px);
        overflow-y: auto;
    }
    /* The pages are flex children of a capped column — WITHOUT this they shrink to
       fit and every sheet renders as a cropped strip. Keep natural height; the pane
       scrolls instead. */
    body[data-active-page="trainer"] .aside-pane-ref .ref-zoom {
        flex: 0 0 auto;
    }
    body[data-active-page="trainer"] .aside-pane-ref .reference-img {
        width: 100%; display: block; border-radius: 10px;
    }
}

/* ── Leave-a-task confirmation (Zappi), ported from the lesson exit sheet ────── */
body[data-active-page="trainer"] .trainer-exit-sheet {
    position: fixed; inset: 0; z-index: 10001;
    opacity: 0; pointer-events: none;
    transition: opacity 0.18s ease;
}
body[data-active-page="trainer"] .trainer-exit-sheet.is-open { opacity: 1; pointer-events: auto; }
body[data-active-page="trainer"] .trainer-exit-backdrop {
    position: absolute; inset: 0; border: 0;
    background: rgba(0, 0, 0, 0.42);
}
body[data-active-page="trainer"] .trainer-exit-panel {
    position: absolute; left: 0; right: 0; bottom: 0;
    max-width: 520px; margin: 0 auto;
    padding: 22px 18px calc(18px + var(--app-safe-bottom, 0px));
    border-radius: 24px 24px 0 0;
    border: 1px solid rgba(39, 119, 255, 0.22); border-bottom: 0;
    background: var(--bg);
    box-shadow: 0 -18px 42px rgba(0, 0, 0, 0.32);
    transform: translateY(110%);
    transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
body[data-active-page="trainer"] .trainer-exit-sheet.is-open .trainer-exit-panel { transform: translateY(0); }
body[data-active-page="trainer"] .trainer-exit-gif {
    display: block; width: min(136px, 38vw); height: auto;
    margin: 0 auto 10px; border-radius: 18px;
}
body[data-active-page="trainer"] .trainer-exit-title {
    color: var(--text); font-size: 21px; line-height: 1.12; font-weight: 900; text-align: center;
}
body[data-active-page="trainer"] .trainer-exit-panel p {
    margin: 8px 0 18px; color: var(--text-hint);
    font-size: 14px; line-height: 1.35; font-weight: 700; text-align: center;
}
body[data-active-page="trainer"] .trainer-exit-primary,
body[data-active-page="trainer"] .trainer-exit-secondary {
    width: 100%; min-height: 50px; border-radius: 16px;
    font: inherit; font-size: 14px; font-weight: 900; cursor: pointer;
}
body[data-active-page="trainer"] .trainer-exit-primary {
    border: 0; background: #2777ff; color: #fff;
    box-shadow: 0 12px 24px rgba(39, 119, 255, 0.28);
}
body[data-active-page="trainer"] .trainer-exit-secondary {
    margin-top: 10px; border: 1px solid rgba(148, 163, 184, 0.26);
    background: transparent; color: var(--text-hint);
}
/* Phones + tablets: the exit sheet spans the full width instead of a centered
   520px card. Only the true desktop split (min-width:1024 + hover + fine pointer)
   keeps the centered card — same gate used for the rest of the mobile/tablet UI. */
@media (max-width: 1023px) {
    body[data-active-page="trainer"] .trainer-exit-panel { max-width: none; }
}
/* Desktop (computer): match the lessons (обучение) exit-panel width. */
@media (min-width: 1024px) {
    body[data-active-page="trainer"] .trainer-exit-panel {
        max-width: min(960px, 100%);
        margin-left: auto;
        margin-right: auto;
    }
}

/* ── Full-screen verdict modal (Правильно/Неправильно) ──────────────────────────
   Pops up over everything after a part-1 answer; the button reveals the review. */
body[data-active-page="trainer"] .result-modal {
    position: fixed; inset: 0; z-index: 10002;
    display: none;
}
body[data-active-page="trainer"] .result-modal.is-open { display: block; }
body[data-active-page="trainer"] .result-modal-panel {
    position: absolute; inset: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    text-align: center;
    padding: calc(28px + var(--app-safe-top, 0px)) 22px calc(24px + var(--app-safe-bottom, 0px));
    background: var(--bg);
    animation: resultModalPop 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}
@keyframes resultModalPop {
    from { opacity: 0; transform: scale(0.9); }
    to   { opacity: 1; transform: scale(1); }
}
body[data-active-page="trainer"] .result-modal-body {
    flex: 1 1 auto;
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 6px;
}
body[data-active-page="trainer"] .result-modal-icon .result-gif {
    display: block; width: min(220px, 56vw); height: auto; margin: 0 auto 6px;
    border-radius: 20px;
}
body[data-active-page="trainer"] .result-modal-text {
    color: var(--text); font-size: 28px; font-weight: 950; line-height: 1.1;
}
body[data-active-page="trainer"] .result-modal-answer {
    margin-top: 8px; color: var(--text-hint);
    font-size: 16px; font-weight: 700; line-height: 1.35;
}
/* «Оцени Заппи» when it rides along on the verdict modal. */
body[data-active-page="trainer"] .result-modal-body .ai-hint-rating {
    width: min(420px, 90vw);
    margin: 22px 0 0;
    flex: 0 0 auto;
}
/* Action bar inside the modal: [Показать решение | Далее] merged like the answer
   pair. Incorrect verdict shows «Показать решение» only (.is-single). */
body[data-active-page="trainer"] .result-modal-actions {
    flex: 0 0 auto;
    display: flex; column-gap: 0; align-items: stretch;
    width: min(420px, 90vw); margin-top: 20px;
}
body[data-active-page="trainer"] .result-modal-solution-btn {
    flex: 1 1 50%; min-width: 0; height: 54px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--card-bg); border: 1px solid var(--card-border); border-right: none;
    color: var(--text); font: inherit; font-size: 15px; font-weight: 900; cursor: pointer;
    border-radius: 16px; border-top-right-radius: 0; border-bottom-right-radius: 0;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.16s ease;
}
body[data-active-page="trainer"] .result-modal-next-btn {
    flex: 1 1 50%; min-width: 0; height: 54px; margin: 0;
    font: inherit; font-size: 15px; font-weight: 900;
    border-radius: 16px; border-top-left-radius: 0; border-bottom-left-radius: 0;
    box-shadow: 0 12px 26px rgba(39, 119, 255, 0.3);
}
body[data-active-page="trainer"] .result-modal-retry-btn {
    flex: 1 1 100%; min-width: 0; height: 54px; margin: 0;
    font: inherit; font-size: 15px; font-weight: 900;
    border-radius: 16px;
    box-shadow: 0 12px 26px rgba(39, 119, 255, 0.3);
}
body[data-active-page="trainer"] .result-modal-solution-btn:active,
body[data-active-page="trainer"] .result-modal-next-btn:active,
body[data-active-page="trainer"] .result-modal-retry-btn:active { transform: scale(0.97); }
/* Only one button → it fills the bar with full rounding. */
body[data-active-page="trainer"] .result-modal-actions.is-single .result-modal-solution-btn {
    border-right: 1px solid var(--card-border); border-radius: 16px;
}
body[data-active-page="trainer"] .result-modal-actions.is-single .result-modal-next-btn {
    border-radius: 16px;
}
/* Desktop: the verdict/score modal stays a full-screen dark takeover, but the
   text/score column is constrained (exit-sheet width) and the action pair is
   pinned bottom-centre exactly like the floating answer bar. */
@media (min-width: 1024px) {
    body[data-active-page="trainer"] .result-modal-body {
        width: min(960px, calc(100vw - 48px));
        margin: 0 auto;
    }
    body[data-active-page="trainer"] .result-modal-actions {
        position: fixed;
        left: 50%; bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        width: min(960px, calc(100vw - 48px));
        margin: 0;
        padding: 10px 14px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }
}

/* ── Exam attempt (/trainer/exam): everything below the topbar matches the
      solve screen (/trainer/learn) on tablets and desktop — same flat cards,
      same centred column, same text sizes (set next to the solve rules above).
      The topbar (title + timer + number strip) keeps its own exam styling. ── */
@media (min-width: 700px) {
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-note,
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-current-task,
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-result-card,
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-result-row {
        background: var(--card-bg);
        border: 1px solid var(--card-border);
        border-radius: var(--radius);
        box-shadow: none;
    }
    /* The review list has NO outer frame — its rows are the cards. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-review {
        background: transparent;
        border: 0;
        border-radius: 0;
        box-shadow: none;
        padding: 0;
    }
}

@media (min-width: 700px) and (max-width: 1023px) {
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] #app {
        padding-left: 12px;
        padding-right: 12px;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-current-task {
        padding: 12px;   /* .solve-card on tablets */
    }
}

/* The note sits inside .solve-main (above the condition) — the shell's grid
   gap no longer spaces it, so give it its own bottom margin. */
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-note {
    margin-bottom: 14px;
}

/* ── Answer bar [Введи ответ | Сохранить]: pinned like the solve screen's
      answer bar — fixed bottom bar on phones/tablets, floating bottom-centre
      pill on desktop. (The row lives inside the task card; review/result modes
      hide the card and the bar with it.) ── */
@media (max-width: 1023px) {
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 55;
        display: flex;
        gap: 8px;
        margin: 0;
        padding: 8px 12px calc(10px + var(--app-safe-bottom, 0px));
        background: var(--bg);
        border-top: 1px solid var(--card-border);
        box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row .exam-attempt-answer-input {
        flex: 1 1 auto;
        min-width: 0;
        height: 46px;
        box-sizing: border-box;
        padding: 9px 14px;
        font-size: 15px;
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row .exam-attempt-answer-submit {
        flex: 0 0 auto;
        width: auto;
        height: 46px;
        margin: 0;
        padding: 0 18px;
    }
    /* Clear the fixed bar so the last content isn't stuck behind it. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-shell {
        padding-bottom: calc(84px + var(--app-safe-bottom, 0px));
    }

    /* Never let the exam page scroll sideways. Targeted: only the CONTENT
       column is constrained (the topbar and the number strip keep their
       deliberate -12px edge bleeds and the sticky header stays intact). Wide
       inline content (long formulas, wide options) clips/wraps inside its own
       card instead of pushing the page. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-body,
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-main {
        min-width: 0;
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-main > * {
        min-width: 0;
        max-width: 100%;
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-current-task {
        overflow-x: clip;
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-option span {
        min-width: 0;
        overflow-wrap: anywhere;
    }
    /* The page-level scroller is the <html> element — body's overflow-x:hidden
       (app_core.css) doesn't stop IT from scrolling sideways. */
    html:has(body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"]) {
        overflow-x: hidden;
    }

    /* Part 2 (photo): fixed bottom bar like the solve screen's #upload-container. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload {
        position: fixed;
        left: 0; right: 0; bottom: 0;
        z-index: 55;
        margin: 0;
        display: flex;
        flex-wrap: wrap;
        row-gap: 8px;
        padding: 10px 14px calc(12px + var(--app-safe-bottom, 0px));
        background: var(--bg);
        border-top: 1px solid var(--card-border);
        box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
    }
    /* Taller upload bar → more room below the task. */
    body[data-active-page="trainer"] #screen-exam-attempt:has(.exam-attempt-upload) .exam-attempt-shell {
        padding-bottom: calc(240px + var(--app-safe-bottom, 0px));
    }

    /* Review mode: «Сдать пробник» is pinned to the bottom in place of the
       answer bar. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-submit-final {
        position: fixed;
        left: 12px;
        right: 12px;
        bottom: calc(10px + var(--app-safe-bottom, 0px));
        z-index: 55;
        width: auto;
        height: 52px;
        margin: 0;
        box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.3);
    }
}

/* Part 2 upload internals — compact, mirrors the solve #upload-container:
   slim upload area, 56px thumbnails in one sideways-scrolling row, full-width
   submit. Applies on every width (the geometry above differs per breakpoint). */
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .upload-area {
    flex: 1 1 100%;
    min-height: 92px;
    padding: 12px;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .exam-attempt-file-preview {
    flex: 1 1 100%;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .file-preview-list {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    gap: 8px;
    padding: 8px;
    -webkit-overflow-scrolling: touch;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .file-preview-item {
    flex: 0 0 auto;
    width: 56px;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .file-preview-item img {
    width: 56px;
    height: 56px;
    aspect-ratio: auto;
}
/* «+» tile to add more photos, sized like a thumbnail (mirrors the solve one). */
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .file-preview-add {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    border-radius: 8px;
    border: 1px dashed var(--card-border);
    background: var(--card-bg);
    color: var(--text-hint);
    font-size: 28px;
    font-weight: 400;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .exam-attempt-saved-photos {
    flex: 1 1 100%;
}
body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload .exam-attempt-photo-submit {
    flex: 1 1 100%;
    width: auto;
    height: 58px;
    margin: 0;
    border-radius: var(--radius-sm);
}

@media (min-width: 1024px) {
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-current-task {
        padding: 15px 18px;   /* .solve-card on desktop */
    }

    /* With the right pane expanded the screen spans (almost) the full width,
       exactly like the solve screen — overrides trainer.css's centred 920px
       column. Collapsed mode centres the content back to 960px below. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] #screen-exam-attempt {
        width: 100%;
        max-width: none;
        margin-right: 0;
        margin-left: 0;
    }
    /* Collapsed pane: the topbar/strip join the centred 960px column so the
       whole page reads as one vertical strip (mirrors the solve screen header).
       The note lives inside .solve-main (above the condition) and centres with it. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] #screen-exam-attempt:has(.solve-body.aside-collapsed) .exam-attempt-topbar,
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] #screen-exam-attempt:has(.solve-body.aside-collapsed) .exam-attempt-number-strip {
        width: min(960px, 100%);
        margin-left: auto;
        margin-right: auto;
    }

    /* Desktop: the condition photo opens full-screen on click (like solve). */
    body[data-active-page="trainer"] #screen-exam-attempt .task-img-zoom .pinch-img {
        cursor: zoom-in;
    }

    /* Split like the solve screen: content column + the right pane. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .solve-body {
        display: flex;
        align-items: stretch;
        gap: 20px;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .solve-body.aside-collapsed {
        justify-content: center;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .solve-main {
        flex: 1 1 0;
        min-width: 0;
        /* Clear the floating answer bar (≈66px tall + 24px offset + shadow). */
        padding-bottom: 140px;
    }
    /* Part 2: the floating photo card is much taller — clear it too. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .solve-main:has(.exam-attempt-upload) {
        padding-bottom: 320px;
    }
    /* The fabs are replaced by the aside tabs (same as the solve screen). */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .ref-fab,
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .draft-fab {
        display: none;
    }

    /* Floating bottom-centre answer bar (mirrors #answer-input-container).
       Shrink-wraps its content — the exam bar has no «Пропустить», so a full
       960px pill would be mostly empty around a small input. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row {
        position: fixed;
        left: 50%;
        bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: auto;
        max-width: calc(100vw - 48px);
        display: flex;
        gap: 8px;
        margin: 0;
        padding: 10px 14px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row .exam-attempt-answer-input {
        flex: 0 0 auto;
        width: 300px;
        max-width: 46vw;
        min-width: 0;
        height: 46px;
        box-sizing: border-box;
    }
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-answer-row .exam-attempt-answer-submit {
        flex: 0 0 auto;
        width: auto;
        height: 46px;
        margin: 0;
        padding: 0 26px;
    }

    /* Desktop header: title left, timer CENTRED, «Сдать вариант» at the right. */
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-topbar {
        display: grid;
        grid-template-columns: 1fr auto 1fr;
        align-items: center;
        column-gap: 16px;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-task-heading {
        padding-right: 0;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-top-controls {
        position: static;
        display: contents;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-clock {
        grid-column: 2;
        justify-self: center;
    }
    body[data-active-page="trainer"][data-active-screen="screen-exam-attempt"] .exam-attempt-submit-top {
        grid-column: 3;
        justify-self: end;
    }

    /* The answer bar stays centred on the SCREEN; the aside panes below are
       height-capped so the bar never covers the board/reference (same trick
       as the solve screen's 240px viewport reserve). */

    /* Review/result modes: the draft & reference pane makes no sense while
       submitting or reading the verdict — hide it and centre the content
       (same geometry as the collapsed pane). */
    body[data-active-page="trainer"] #screen-exam-attempt.is-review-mode .solve-aside,
    body[data-active-page="trainer"] #screen-exam-attempt.is-result-mode .solve-aside,
    body[data-active-page="trainer"] #screen-exam-attempt.is-review-mode #aside-expand-btn,
    body[data-active-page="trainer"] #screen-exam-attempt.is-result-mode #aside-expand-btn {
        display: none !important;
    }
    body[data-active-page="trainer"] #screen-exam-attempt.is-review-mode .solve-body,
    body[data-active-page="trainer"] #screen-exam-attempt.is-result-mode .solve-body {
        justify-content: center;
    }
    body[data-active-page="trainer"] #screen-exam-attempt.is-review-mode .solve-main,
    body[data-active-page="trainer"] #screen-exam-attempt.is-result-mode .solve-main {
        flex: 0 1 min(960px, 100%);
        max-width: min(960px, 100%);
    }
    body[data-active-page="trainer"] #screen-exam-attempt.is-review-mode .exam-attempt-topbar,
    body[data-active-page="trainer"] #screen-exam-attempt.is-result-mode .exam-attempt-topbar {
        width: min(960px, 100%);
        margin-left: auto;
        margin-right: auto;
    }

    /* Review mode: «Сдать пробник» floats bottom-centre like the answer bar. */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-submit-final {
        position: fixed;
        left: 50%;
        bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: min(560px, calc(100vw - 48px));
        height: 56px;
        margin: 0;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }

    /* Part 2 (photo): the upload card floats bottom-centre like the solve one;
       the aside panes shrink to clear it (mirrors #screen-solve.solve-has-upload). */
    body[data-active-page="trainer"] #screen-exam-attempt .exam-attempt-upload {
        position: fixed;
        left: 50%;
        bottom: calc(24px + var(--app-safe-bottom, 0px));
        transform: translateX(-50%);
        z-index: 900;
        width: min(960px, calc(100vw - 48px));
        margin: 0;
        display: flex;
        flex-wrap: wrap;
        row-gap: 8px;
        padding: 10px 14px;
        column-gap: 8px;
        background: var(--bg);
        border: 1px solid var(--card-border);
        border-radius: 18px;
        box-shadow: 0 16px 40px rgba(0, 0, 0, 0.45);
    }
    body[data-active-page="trainer"] #screen-exam-attempt:has(.exam-attempt-upload) #exam-aside .draft-board-panel {
        height: calc(100vh - 560px);
        min-height: 240px;
    }
    body[data-active-page="trainer"] #screen-exam-attempt:has(.exam-attempt-upload) #exam-aside .aside-pane-ref {
        max-height: calc(100vh - 560px);
        overflow-y: auto;
    }
    /* (Board/reference heights live in the «mirrors #solve-aside» block below —
       the exam reserves 430px of viewport: taller header + the centred answer
       bar floating over the aside's bottom corner.) */

    /* Draft board embedded inline in the exam aside (mirrors #solve-aside). */
    body[data-active-page="trainer"] #exam-aside .draft-board {
        position: static; inset: auto; display: block !important;
        background: none; z-index: auto; backdrop-filter: none;
    }
    body[data-active-page="trainer"] #exam-aside .draft-board-panel {
        position: static; width: 100%; max-width: none;
        /* 430px reserve (solve keeps 240px): the exam header is taller and the
           centred answer bar floats over the aside's bottom corner. */
        height: calc(100vh - 430px); min-height: 300px; max-height: none; margin: 0;
        border-radius: 16px; border: 1px solid var(--card-border);
        grid-template-rows: minmax(0, 1fr);
        padding: 8px;
    }
    body[data-active-page="trainer"] #exam-aside .aside-pane-ref {
        max-height: calc(100vh - 430px);
        overflow-y: auto;
    }
    body[data-active-page="trainer"] #exam-aside .draft-board-back { display: none; }
    body[data-active-page="trainer"] #exam-aside .draft-board-head { display: none; }
    body[data-active-page="trainer"] #exam-aside .draft-canvas-wrap { border-radius: 16px; }
}

/* ── Trainer first-visit intro (ported from style.css §section-intro; the
      legacy copy is dormant there behind body[data-active-screen] kill-switch
      rules, which are intentionally NOT ported). Phones/tablets only. ── */
body.section-intro-active {
    overflow: hidden !important;
    touch-action: none !important;
    overscroll-behavior: contain;
}

.section-intro-overlay {
    position: fixed;
    inset: 0;
    z-index: 9994;
    display: flex;
    justify-content: center;
    align-items: stretch;
    padding:
        max(18px, var(--app-safe-top, env(safe-area-inset-top, 0px)))
        max(16px, var(--app-safe-right, env(safe-area-inset-right, 0px)))
        max(18px, var(--app-safe-bottom, env(safe-area-inset-bottom, 0px)))
        max(16px, var(--app-safe-left, env(safe-area-inset-left, 0px)));
    background:
        radial-gradient(circle at 50% 12%, rgba(30, 111, 255, 0.18), transparent 32%),
        linear-gradient(180deg, color-mix(in srgb, var(--bg-secondary) 78%, #05080f), var(--bg));
    color: var(--text);
    opacity: 0;
    pointer-events: none;
    transform: translateY(8px);
    transition: opacity 0.22s ease, transform 0.22s ease;
    overflow: hidden;
}

.section-intro-overlay.instant {
    opacity: 1;
    transform: translateY(0);
    transition: none;
}

.section-intro-overlay.active {
    opacity: 1;
    pointer-events: auto;
    transform: translateY(0);
}

.section-intro-overlay::before,
.section-intro-overlay::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.section-intro-overlay::before {
    background:
        radial-gradient(circle at 50% 16%, rgba(77, 158, 255, 0.28), transparent 30%),
        radial-gradient(circle at 14% 78%, rgba(30, 111, 255, 0.18), transparent 28%),
        radial-gradient(circle at 92% 82%, rgba(53, 211, 255, 0.14), transparent 24%);
    opacity: 0;
    transform: scale(0.92);
}

.section-intro-overlay::after {
    width: 34%;
    background: linear-gradient(112deg, transparent 0%, rgba(255, 255, 255, 0.16) 48%, transparent 100%);
    opacity: 0;
    transform: translateX(-130%) skewX(-12deg);
}

.section-intro-overlay.active::before {
    animation: sectionIntroAuraIn 0.82s cubic-bezier(0.16, 1, 0.3, 1) both;
}

.section-intro-overlay.active::after {
    animation: sectionIntroSweep 0.95s cubic-bezier(0.16, 1, 0.3, 1) 0.08s both;
}

.section-intro-overlay * {
    touch-action: auto;
}

.section-intro-panel {
    position: relative;
    z-index: 1;
    width: min(100%, 480px);
    min-height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 24px;
}

.section-intro-overlay.active .section-intro-panel {
    animation: sectionIntroPanelIn 0.42s cubic-bezier(0.18, 0.9, 0.2, 1) both;
}

.section-intro-top {
    display: flex;
    align-items: center;
    gap: 14px;
}

.section-intro-icon {
    position: relative;
    width: 72px;
    height: 72px;
    border-radius: 22px;
    display: grid;
    place-items: center;
    background: linear-gradient(145deg, rgba(30, 111, 255, 0.26), rgba(77, 158, 255, 0.08));
    box-shadow: 0 18px 44px rgba(30, 111, 255, 0.18);
    overflow: hidden;
}

.section-intro-icon::before {
    content: "";
    position: absolute;
    inset: -55%;
    background: conic-gradient(from 180deg, transparent, rgba(255, 255, 255, 0.34), transparent 42%);
    opacity: 0;
    transform: rotate(-40deg);
}

.section-intro-overlay.active .section-intro-icon::before {
    animation: sectionIntroIconSheen 0.95s ease-out 0.18s both;
}

.section-intro-icon img {
    position: relative;
    z-index: 1;
    width: 42px;
    height: 42px;
    object-fit: contain;
}

.section-intro-overlay.active .section-intro-icon {
    animation: sectionIntroIconPop 0.56s cubic-bezier(0.18, 1.2, 0.2, 1) both;
}

.section-intro-eyebrow {
    color: var(--link);
    font-size: 13px;
    font-weight: 900;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

.section-intro-overlay.active .section-intro-eyebrow,
.section-intro-overlay.active .section-intro-body h2,
.section-intro-overlay.active .section-intro-body p,
.section-intro-overlay.active .section-intro-body li,
.section-intro-overlay.active .section-intro-cta {
    animation: sectionIntroItemIn 0.48s cubic-bezier(0.18, 0.9, 0.2, 1) both;
}

.section-intro-overlay.active .section-intro-eyebrow { animation-delay: 0.04s; }
.section-intro-overlay.active .section-intro-body h2 { animation-delay: 0.08s; }
.section-intro-overlay.active .section-intro-body p { animation-delay: 0.13s; }
.section-intro-overlay.active .section-intro-body li:nth-child(1) { animation-delay: 0.18s; }
.section-intro-overlay.active .section-intro-body li:nth-child(2) { animation-delay: 0.22s; }
.section-intro-overlay.active .section-intro-body li:nth-child(3) { animation-delay: 0.26s; }
.section-intro-overlay.active .section-intro-cta { animation-delay: 0.31s; }

.section-intro-body h2 {
    max-width: 360px;
    margin: 0 0 12px;
    color: var(--text);
    font-size: clamp(32px, 9vw, 48px);
    line-height: 0.95;
    font-weight: 950;
    letter-spacing: 0;
}

.section-intro-body p {
    max-width: 430px;
    margin: 0;   /* the legacy page zeroed this via its global reset */
    color: color-mix(in srgb, var(--text) 82%, var(--text-hint));
    font-size: 16px;
    line-height: 1.45;
    font-weight: 650;
}

.section-intro-body ul {
    list-style: none;
    display: grid;
    gap: 10px;
    margin: 20px 0 0;
    padding: 0;   /* the legacy page zeroed this via its global reset */
}

.section-intro-body li {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    color: var(--text);
    font-size: 14px;
    line-height: 1.35;
    font-weight: 800;
}

.section-intro-dot {
    width: 10px;
    height: 10px;
    margin-top: 5px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--accent) 18%, transparent);
}

.section-intro-cta {
    position: relative;
    width: 100%;
    min-height: 60px;
    margin-top: 8px;
    border: 0;
    border-radius: 18px;
    background: var(--accent);
    color: var(--accent-text);
    font: inherit;
    font-size: 16px;
    font-weight: 950;
    cursor: pointer;
    box-shadow: 0 18px 36px rgba(30, 111, 255, 0.32);
    overflow: hidden;
}

.section-intro-cta::after {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: -40%;
    width: 34%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.36), transparent);
    transform: skewX(-14deg);
}

.section-intro-overlay.active .section-intro-cta::after {
    animation: sectionIntroButtonSheen 1.15s ease-out 0.62s both;
}

.section-intro-cta:active {
    transform: translateY(1px) scale(0.99);
}

body.theme-light .section-intro-overlay {
    background:
        radial-gradient(circle at 50% 12%, rgba(30, 111, 255, 0.16), transparent 32%),
        linear-gradient(180deg, #ffffff, #eef5ff);
}

body.theme-light .section-intro-icon {
    background: linear-gradient(145deg, rgba(30, 111, 255, 0.16), rgba(125, 184, 255, 0.08));
    box-shadow: 0 18px 44px rgba(30, 111, 255, 0.12);
}

/* Unlike the legacy version, the intro also shows on desktop (no ≥1024 hide).
   Above the trainer's desktop side nav (10020) and service rail (10010) so the
   overlay really covers everything, like on /rating. */
body[data-active-page="trainer"] .section-intro-overlay {
    z-index: 10030;
}

@keyframes sectionIntroAuraIn {
    0% {
        opacity: 0;
        transform: scale(0.92);
        filter: blur(6px);
    }
    48% {
        opacity: 1;
        transform: scale(1.02);
        filter: blur(0);
    }
    100% {
        opacity: 0.78;
        transform: scale(1);
        filter: blur(0);
    }
}

@keyframes sectionIntroSweep {
    0% {
        opacity: 0;
        transform: translateX(-130%) skewX(-12deg);
    }
    18% {
        opacity: 0.56;
    }
    100% {
        opacity: 0;
        transform: translateX(390%) skewX(-12deg);
    }
}

@keyframes sectionIntroPanelIn {
    from {
        opacity: 0.01;
        transform: translateY(18px) scale(0.975);
        filter: blur(3px);
    }
    to {
        opacity: 1;
        transform: translateY(0) scale(1);
        filter: blur(0);
    }
}

@keyframes sectionIntroIconPop {
    0% {
        opacity: 0;
        transform: translateY(14px) scale(0.66) rotate(-7deg);
    }
    54% {
        opacity: 1;
        transform: translateY(-4px) scale(1.12) rotate(2deg);
    }
    78% {
        transform: translateY(1px) scale(0.98) rotate(-1deg);
    }
    100% {
        opacity: 1;
        transform: translateY(0) scale(1) rotate(0);
    }
}

@keyframes sectionIntroIconSheen {
    0% {
        opacity: 0;
        transform: rotate(-40deg);
    }
    32% {
        opacity: 1;
    }
    100% {
        opacity: 0;
        transform: rotate(140deg);
    }
}

@keyframes sectionIntroItemIn {
    from {
        opacity: 0;
        transform: translateY(14px);
        filter: blur(2px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
        filter: blur(0);
    }
}

@keyframes sectionIntroButtonSheen {
    0% {
        left: -42%;
        opacity: 0;
    }
    18% {
        opacity: 1;
    }
    100% {
        left: 112%;
        opacity: 0;
    }
}
