/* =================================================================
   TEACHER'S PLAN — v4 viewer (Review Lesson / Teach Lesson)

   Mobile first. One layout that adds panes as the screen allows:
     phone   → header, event rail, one column
     tablet  → + the lesson navigator down the left
     desktop → + the session record and lesson reference on the right

   Type scales from ONE number, --tp-fs, driven by the A A A control.
   Everything here is an em so the whole view grows together — the
   people reading this off a table at arm's length are not all young.
   ================================================================= */

.tp-v4 {
    /* --tp-fs scales THE SCRIPT ONLY — see the A A A block below.
       It used to scale this root font-size, which meant the header, the event
       rail, the tally strip and the action bar all grew with it inside a
       fixed-height box. On a phone at the largest step that left the teacher
       the set title and nothing else: the lines they were supposed to read
       aloud were the first thing squeezed out by the control that exists to
       make them readable. Chrome is now a fixed 15px at every step. */
    --tp-fs: 1;
    font-size: 15px;

    --tp-panel: #FFFFFF;
    --tp-panel-2: #F5F6FA;
    --tp-panel-3: #EDEFF5;
    --tp-rule: #E4E6EF;
    --tp-ink: #14161F;
    --tp-ink-soft: #565C70;
    --tp-ink-faint: #7F8598;

    --tp-teacher: #4F46E5;  --tp-teacher-wash: #EEEDFD;
    --tp-student: #0D8A80;  --tp-student-wash: #E1F4F1;
    --tp-note: #A8500A;     --tp-note-wash: #FDF2E2;
    --tp-do: #4E5766;       --tp-do-wash: #EEF0F4;
    --tp-skip: #7F8598;     --tp-skip-wash: #EEF0F4;

    --tp-serif: 'Iowan Old Style', 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;

    display: flex;
    flex-direction: column;
    min-height: 0;

    /* The shell's header and nav sit above this. --tp-app-chrome is measured
       and set by _syncAppChrome() in teacher-plan-module.js; 170px is only the
       pre-measurement fallback, and dvh keeps the action row above a phone's
       collapsing browser bar.

       Nothing set --tp-app-chrome until v0.7.96.0, so the 170px fallback was
       always what ran. On a phone the real chrome was 398px, which built a
       674px box starting 458px down an 844px screen: 288px of the module hung
       below the fold, with its own scrolling pane inside it, so the page and
       the pane both scrolled and the Learned/Help/Skip bar sat off-screen. */
    height: calc(100vh - var(--tp-app-chrome, 170px));
    height: calc(100dvh - var(--tp-app-chrome, 170px));
    min-height: 520px;
    background: var(--tp-panel);
    color: var(--tp-ink);
    border: 1px solid var(--tp-rule);
    border-radius: 12px;
    overflow: hidden;
    position: relative;
    outline: none;
}

/* The steps can be bolder than they were, because they no longer have to pay
   for the chrome growing alongside the text. */
.tp-v4[data-fs="large"]  { --tp-fs: 1.25; }
.tp-v4[data-fs="xlarge"] { --tp-fs: 1.55; }

[data-theme="dark"] .tp-v4 {
    --tp-panel: #171A21;
    --tp-panel-2: #1E222B;
    --tp-panel-3: #262B35;
    --tp-rule: #2E3441;
    --tp-ink: #F2F4F9;
    --tp-ink-soft: #A7AEC0;
    --tp-ink-faint: #7A8194;

    --tp-teacher: #9A93F7;  --tp-teacher-wash: #272150;
    --tp-student: #4BD3C2;  --tp-student-wash: #0E3B36;
    --tp-note: #EDAD57;     --tp-note-wash: #3D2C13;
    --tp-do: #A3AAB9;       --tp-do-wash: #252A35;
    --tp-skip: #8A91A2;     --tp-skip-wash: #252A35;
}

.tp-v4 * { box-sizing: border-box; }
.tp-v4 p { max-width: none; margin: 0 0 .5em; }
.tp-v4 p:last-child { margin-bottom: 0; }
.tp-v4 .tp-muted { color: var(--tp-ink-soft); font-size: .85em; }
.tp-v4 code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .85em; background: var(--tp-panel-2);
    border: 1px solid var(--tp-rule); padding: 1px 5px; border-radius: 4px;
}
.tp-eyebrow {
    font-size: .68em; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    color: var(--tp-ink-faint); margin: 0 0 .6em;
}
.tp-tok { color: var(--tp-teacher); font-weight: 600; }

/* ---------- header ---------- */
.tp-head {
    flex: 0 0 auto; display: flex; align-items: center; gap: .7em; flex-wrap: wrap;
    padding: .6em .9em; border-bottom: 1px solid var(--tp-rule); background: var(--tp-panel-2);
}
.tp-head-id { flex: 1 1 14em; min-width: 0; }
.tp-head-id h4 {
    margin: 0; font-family: var(--tp-serif); font-size: 1.1em; font-weight: 600; line-height: 1.25;
    display: flex; align-items: center; gap: .45em; flex-wrap: wrap;
}
.tp-head-id h4 em { font-style: normal; color: var(--tp-ink-faint); font-size: .8em; font-family: inherit; }
.tp-head-id .tp-sub { font-size: .72em; font-weight: 650; color: var(--tp-ink-faint); }
.tp-v4 .tp-theme-badge {
    font-size: .6em; font-weight: 700; letter-spacing: .06em; color: #fff;
    border-radius: 999px; padding: .2em .7em;
}

/* Transparent by default: above 768px .tp-modebar and the gear stay direct
   flex children of .tp-head, so the desktop header is byte-for-byte the layout
   it always was. The phone block below turns this into the second header row. */
.tp-head-actions { display: contents; }

/* Phone/tablet only. The desktop header shows the text-size group and the two
   panel buttons inline, where they cost nothing, and Teach mode there keeps the
   app shell — so neither the gear nor the teach bar has a job above 768px. */
.tp-gear-btn,
.tp-teachbar { display: none; }

/* Mode tabs — the two big highlighted choices this screen is built around */
.tp-modebar {
    display: flex; gap: 3px; padding: 3px; order: 3; flex: 1 1 100%;
    background: var(--tp-panel-3); border-radius: .6em;
}
.tp-modebar button {
    flex: 1 1 0; font: inherit; font-size: .88em; font-weight: 700; cursor: pointer;
    border: 0; border-radius: .5em; background: transparent; color: var(--tp-ink-soft);
    padding: .6em .8em; white-space: nowrap;
    display: inline-flex; align-items: center; justify-content: center; gap: .45em;
}
.tp-modebar button[aria-selected="true"] { background: var(--tp-teacher); color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.18); }
.tp-modebar button:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: 2px; }

.tp-fsctl {
    display: flex; align-items: center; gap: .25em; padding: 2px;
    border: 1px solid var(--tp-rule); border-radius: .5em; background: var(--tp-panel);
}
.tp-fsctl button {
    font: inherit; font-weight: 700; border: 0; background: transparent; color: var(--tp-ink-soft);
    cursor: pointer; border-radius: .35em; min-height: 1.9em; padding: .2em .5em; line-height: 1;
}
.tp-fsctl button[aria-pressed="true"] { background: var(--tp-teacher); color: #fff; }
.tp-fsctl .tp-a1 { font-size: .72em; }
.tp-fsctl .tp-a2 { font-size: .88em; }
.tp-fsctl .tp-a3 { font-size: 1.02em; }

.tp-icon-btn {
    font: inherit; font-size: .9em; cursor: pointer; border: 1px solid var(--tp-rule);
    background: var(--tp-panel); color: var(--tp-ink-soft); border-radius: .5em;
    width: 2.2em; height: 2.2em; display: grid; place-items: center;
}
.tp-icon-btn:hover { color: var(--tp-ink); border-color: var(--tp-ink-faint); }

/* Whether the record reached the server, for as long as it hasn't. */
.tp-savestate {
    font-size: .7em; font-weight: 700; letter-spacing: .05em; border-radius: 999px;
    padding: .2em .6em; white-space: nowrap; border: 1px solid transparent;
}
.tp-savestate[data-state="idle"], .tp-savestate:empty { display: none; }
.tp-savestate[data-state="saving"] { color: var(--tp-ink-faint); }
.tp-savestate[data-state="saved"] { color: var(--tp-student); }
.tp-savestate[data-state="error"] {
    color: var(--tp-note); background: var(--tp-note-wash); border-color: var(--tp-note);
}

/* Announcements for screen readers — visually gone, never display:none. */
.tp-sr-live {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* ---------- who is being taught ---------- */
.tp-stu-btn {
    font: inherit; font-size: .82em; font-weight: 650; cursor: pointer;
    border: 1px solid var(--tp-rule); background: var(--tp-panel); color: var(--tp-ink);
    border-radius: 999px; padding: .25em .7em .25em .25em;
    display: inline-flex; align-items: center; gap: .45em;
}
.tp-stu-btn:hover { border-color: var(--tp-teacher); }
.tp-stu-btn.tp-stu-none { color: var(--tp-ink-faint); padding-left: .7em; }
.tp-stu-self { font-size: .82em; font-weight: 650; color: var(--tp-ink-faint); }
.tp-stu-av {
    flex: 0 0 auto; width: 1.9em; height: 1.9em; border-radius: 50%; display: grid; place-items: center;
    background: var(--tp-teacher); color: #fff; font-size: .78em; font-weight: 700;
}
.tp-stu-nm { max-width: 11em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-stu-caret { color: var(--tp-ink-faint); font-size: .8em; }
.tp-stu-row {
    width: 100%; font: inherit; font-size: .9em; text-align: left; cursor: pointer;
    border: 1px solid transparent; background: transparent; color: var(--tp-ink);
    border-radius: .55em; padding: .5em .6em; margin-bottom: .25em;
    display: flex; align-items: center; gap: .6em;
}
.tp-stu-row:hover { background: var(--tp-panel-2); }
.tp-stu-row.on { background: var(--tp-teacher-wash); border-color: var(--tp-teacher); }
.tp-stu-row-nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-stu-row-n { font-size: .78em; color: var(--tp-ink-faint); font-variant-numeric: tabular-nums; }
.tp-stu-tick { color: var(--tp-teacher); font-weight: 700; }

/* ---------- event rail ---------- */
.tp-rail {
    flex: 0 0 auto; display: flex; gap: .3em; overflow-x: auto; padding: .5em .9em;
    border-bottom: 1px solid var(--tp-rule); background: var(--tp-panel);
    scrollbar-width: thin;
}
.tp-rail button {
    flex: 0 0 auto; font: inherit; font-size: .82em; font-weight: 650; cursor: pointer;
    border: 1px solid var(--tp-rule); background: var(--tp-panel-2); color: var(--tp-ink-soft);
    border-radius: 999px; padding: .35em .85em; white-space: nowrap;
    display: inline-flex; align-items: center; gap: .4em;
}
.tp-rail button[aria-selected="true"] {
    background: var(--tp-teacher); border-color: var(--tp-teacher); color: #fff;
}
.tp-rail .tp-n {
    font-size: .8em; font-weight: 700; opacity: .7; font-variant-numeric: tabular-nums;
}

/* ---------- panes ---------- */
.tp-panes { flex: 1 1 auto; display: flex; min-height: 0; }
.tp-pane-nav, .tp-pane-side { display: none; }
.tp-pane-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; min-height: 0; }
.tp-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; padding: .9em; }

.tp-pane-title {
    flex: 0 0 auto; font-size: .66em; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
    color: var(--tp-ink-faint); padding: .75em 1em .55em; border-bottom: 1px solid var(--tp-rule);
    display: flex; align-items: center; gap: .5em;
}
.tp-pane-title-sep { border-top: 1px solid var(--tp-rule); margin-top: .4em; }
.tp-pane-title .tp-cnt { margin-left: auto; font-variant-numeric: tabular-nums; }
.tp-pane-scroll { flex: 1 1 auto; overflow-y: auto; min-height: 0; }

/* ---------- lesson overview ---------- */
.tp-overview { display: flex; flex-direction: column; gap: 1em; }
.tp-ov-block { }
.tp-ov-block > .tp-eyebrow { display: flex; align-items: center; gap: .5em; }
.tp-ov-n {
    font-size: .9em; font-weight: 700; color: var(--tp-ink-faint); background: var(--tp-panel-2);
    border: 1px solid var(--tp-rule); border-radius: 999px; padding: 0 .45em; font-variant-numeric: tabular-nums;
}
.tp-ov-goals {
    background: var(--tp-teacher-wash); border: 1px solid var(--tp-teacher);
    border-radius: .7em; padding: .85em 1em;
}
.tp-ov-goals > .tp-eyebrow { color: var(--tp-teacher); }
.tp-ov-goals ul { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: .4em; }
.tp-ov-goals li { font-size: .92em; line-height: 1.5; }
.tp-ov-setup { font-size: .92em; line-height: 1.5; }
.tp-ov-state { font-size: .85em; color: var(--tp-ink-soft); font-weight: 650; }
.tp-chips { display: flex; flex-wrap: wrap; gap: .3em; }
.tp-chip {
    font-size: .82em; font-weight: 600; border-radius: .35em; padding: .15em .5em;
    background: var(--tp-panel-2); border: 1px solid var(--tp-rule); color: var(--tp-ink);
}
.tp-chip-word { border-color: var(--tp-teacher); color: var(--tp-teacher); background: var(--tp-teacher-wash); }
.tp-chip-fn { color: var(--tp-ink-soft); }
.tp-chip-prop { border-color: var(--tp-note); color: var(--tp-note); background: var(--tp-note-wash); }
.tp-legend-row { display: flex; gap: .55em; align-items: baseline; margin-bottom: .3em; font-size: .85em; }
.tp-legend-row code { flex: 0 0 auto; color: var(--tp-teacher); }
.tp-ov-events { border-top: 1px solid var(--tp-rule); padding-top: .9em; }
.tp-ov-ev { display: flex; align-items: center; gap: .6em; padding: .35em 0; }
.tp-ov-ev-n {
    flex: 0 0 auto; width: 1.7em; height: 1.7em; border-radius: .4em; display: grid; place-items: center;
    background: var(--tp-panel-2); border: 1px solid var(--tp-rule); color: var(--tp-ink-soft);
    font-size: .78em; font-weight: 700;
}
.tp-ov-ev-nm { flex: 1 1 auto; min-width: 0; font-size: .92em; }
.tp-ov-ev-nm em { font-style: normal; color: var(--tp-ink-faint); font-size: .85em; }
.tp-ov-ev-c { flex: 0 0 auto; font-size: .78em; color: var(--tp-ink-faint); font-variant-numeric: tabular-nums; }

/* ---------- review list ---------- */
.tp-rv-summary { display: flex; gap: .4em; flex-wrap: wrap; margin-bottom: .9em; }
.tp-rv-desc { font-size: .9em; line-height: 1.5; margin-bottom: .9em; color: var(--tp-ink-soft); }
.tp-rv-setup { margin-bottom: .9em; }
.tp-rv-row { border: 1px solid var(--tp-rule); border-radius: .6em; margin-bottom: .5em; overflow: hidden; }
.tp-rv-btn {
    width: 100%; font: inherit; text-align: left; cursor: pointer; border: 0;
    background: var(--tp-panel); color: var(--tp-ink); padding: .6em .75em;
    display: flex; align-items: center; gap: .6em;
}
.tp-rv-btn:hover { background: var(--tp-panel-2); }
.tp-rv-btn:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: -2px; }
.tp-rv-status {
    flex: 0 0 auto; width: 1.6em; height: 1.6em; border-radius: 50%; display: grid; place-items: center;
    border: 1.5px solid var(--tp-rule); background: var(--tp-panel-2); color: var(--tp-ink-faint);
    font-size: .78em; font-weight: 700;
}
.tp-rv-status.learned { background: var(--tp-student); border-color: var(--tp-student); color: #fff; }
.tp-rv-status.help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-rv-status.skipped { background: var(--tp-skip-wash); border-color: var(--tp-skip); color: var(--tp-skip); }
.tp-rv-txt { flex: 1 1 auto; min-width: 0; }
.tp-rv-focus { display: block; font-size: .9em; font-weight: 650; line-height: 1.3; }
.tp-rv-peek {
    display: block; font-size: .8em; color: var(--tp-ink-faint); line-height: 1.35;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tp-rv-badges { flex: 0 0 auto; display: flex; gap: .25em; flex-wrap: wrap; max-width: 38%; justify-content: flex-end; }
.tp-rv-badge {
    font-size: .68em; font-weight: 700; border-radius: 999px; padding: .1em .5em;
    border: 1px solid var(--tp-rule); color: var(--tp-ink-faint); white-space: nowrap;
}
.tp-rv-badge.f { border-color: var(--tp-teacher); color: var(--tp-teacher); }
.tp-rv-badge.n { border-color: var(--tp-note); color: var(--tp-note); }
.tp-rv-detail { display: none; padding: .1em .75em .75em; border-top: 1px solid var(--tp-rule); }
.tp-rv-row[data-open="true"] .tp-rv-detail { display: block; }

/* ---------- the set body, shared by both modes ---------- */
.tp-lane { margin-bottom: .7em; }
.tp-lane-label {
    font-size: .66em; font-weight: 800; letter-spacing: .08em; text-transform: uppercase;
    margin: .6em 0 .25em;
}
.tp-l-teacher { color: var(--tp-teacher); }
.tp-l-student { color: var(--tp-student); }
.tp-l-do { color: var(--tp-do); }
.tp-l-note { color: var(--tp-note); }

/* Spoken lines get the display face and real size — the teacher is
   reading these aloud off the screen, often at arm's length. Stage
   directions stay small and quiet, because nobody says them. */
.tp-v4 .tp-activity-teacher,
.tp-v4 .tp-activity-response {
    display: block; padding: 0; margin: 0 0 .3em; background: none; border-radius: 0;
}
.tp-v4 .tp-teacher-icon,
.tp-v4 .tp-response-icon { display: none; }
.tp-v4 .tp-teacher-text,
.tp-v4 .tp-response-text {
    font-family: var(--tp-serif); font-size: calc(1.12em * var(--tp-fs)); line-height: 1.4; font-weight: 400;
}
.tp-v4 .tp-teacher-text { color: var(--tp-ink); }
.tp-v4 .tp-response-text { color: var(--tp-student); }
/* Authors can put line breaks in a plan; the teacher has to see them. */
.tp-v4 .tp-teacher-text,
.tp-v4 .tp-response-text,
.tp-v4 .tp-action-text,
.tp-v4 .tp-note-text,
.tp-setup-card p,
.tp-ov-setup,
.tp-rv-desc { white-space: pre-wrap; }
.tp-v4 .tp-activity-teacher + .tp-activity-teacher,
.tp-v4 .tp-activity-response + .tp-activity-response {
    padding-top: .3em; border-top: 1px dashed var(--tp-rule);
}

.tp-v4 .tp-activity-action {
    display: flex; align-items: flex-start; gap: .5em; margin-bottom: .3em;
    padding: .4em .6em; background: var(--tp-do-wash); border-radius: .45em;
}
.tp-v4 .tp-action-icon {
    width: 1.5em; height: 1.5em; flex: 0 0 auto; background: var(--tp-panel);
    color: var(--tp-do); font-size: .78em;
}
.tp-v4 .tp-action-text { font-size: calc(.88em * var(--tp-fs)); line-height: 1.45; color: var(--tp-ink-soft); }

.tp-v4 .tp-activity-note {
    display: flex; gap: .5em; margin-bottom: .7em; padding: .6em .75em;
    background: var(--tp-note-wash); border: 1px solid var(--tp-note); border-left-width: 3px;
    border-radius: .5em;
}
.tp-v4 .tp-note-icon { color: var(--tp-note); font-size: .9em; flex: 0 0 auto; }
.tp-v4 .tp-note-text { font-size: calc(.86em * var(--tp-fs)); line-height: 1.5; color: var(--tp-ink); }
.tp-v4 .tp-note-text b {
    font-size: .82em; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: var(--tp-note);
}

.tp-setup-card {
    background: var(--tp-do-wash); border: 1px solid var(--tp-rule); border-left: 3px solid var(--tp-do);
    border-radius: .55em; padding: .65em .8em;
}
.tp-setup-card p { font-size: .88em; line-height: 1.5; }
.tp-setup-card-lg { max-width: 34em; margin: 0 auto; text-align: left; }

/* ---------- teach mode ---------- */
.tp-tm-banner {
    flex: 0 0 auto; display: flex; align-items: center; gap: .5em; padding: .55em .9em;
    background: var(--tp-note-wash); color: var(--tp-note);
    font-size: .82em; font-weight: 700; border-bottom: 1px solid var(--tp-rule);
}
.tp-tm-stage { flex: 1 1 auto; overflow-y: auto; min-height: 0; padding: 1em .9em; }
.tp-tm-inner { max-width: 44em; margin: 0 auto; }
.tp-tm-setlabel {
    display: flex; align-items: baseline; gap: .55em; flex-wrap: wrap;
    margin-bottom: .9em; padding-bottom: .7em; border-bottom: 1px solid var(--tp-rule);
}
.tp-tm-setlabel .tp-k {
    font-size: .66em; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--tp-ink-faint);
}
.tp-tm-setlabel h5 {
    margin: 0; flex: 1 1 100%; font-family: var(--tp-serif);
    font-size: 1.25em; font-weight: 600; line-height: 1.25;
}
.tp-tm-status {
    font-size: .72em; font-weight: 700; border-radius: 999px; padding: .15em .6em; border: 1px solid;
}
.tp-tm-status.learned { background: var(--tp-student-wash); border-color: var(--tp-student); color: var(--tp-student); }
.tp-tm-status.help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-tm-status.skipped { background: var(--tp-skip-wash); border-color: var(--tp-skip); color: var(--tp-skip); }
.tp-tm-again { font-size: .72em; font-weight: 700; color: var(--tp-ink-faint); }

.tp-tm-meter { flex: 0 0 auto; height: 3px; background: var(--tp-panel-3); }
.tp-tm-meter div { height: 100%; background: var(--tp-student); transition: width .25s ease; }

.tp-tm-actions {
    flex: 0 0 auto; display: grid; gap: .4em; padding: .7em .9em;
    grid-template-columns: 2.4em 1fr 1.25fr 1.25fr 2.4em;
    border-top: 1px solid var(--tp-rule); background: var(--tp-panel-2);
}
.tp-tm-actions button {
    font: inherit; font-size: .84em; font-weight: 700; cursor: pointer;
    min-height: 3em; border-radius: .6em; border: 1.5px solid; padding: .3em;
    display: inline-flex; align-items: center; justify-content: center; gap: .35em;
}
.tp-tm-actions button:disabled { opacity: .35; cursor: not-allowed; }
.tp-tm-actions kbd {
    display: none; font-size: .8em; font-family: inherit; font-weight: 700;
    border: 1px solid currentColor; border-radius: 3px; padding: 0 .3em; opacity: .7;
}
.tp-btn-nav { background: var(--tp-panel); border-color: var(--tp-rule); color: var(--tp-ink-faint); font-size: 1.1em !important; }
.tp-btn-skip { background: var(--tp-panel); border-color: var(--tp-rule); color: var(--tp-ink-soft); }
.tp-btn-help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-btn-learned { background: var(--tp-student); border-color: var(--tp-student); color: #fff; }
.tp-tm-actions button:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: 2px; }
.tp-tm-pos {
    flex: 0 0 auto; padding: 0 .9em .7em; font-size: .74em; color: var(--tp-ink-faint);
    text-align: center; background: var(--tp-panel-2); font-variant-numeric: tabular-nums;
}

/* ---------- gates ---------- */
.tp-tm-gate {
    flex: 1 1 auto; overflow-y: auto; min-height: 0; padding: 2em 1.2em;
    text-align: center; display: flex; flex-direction: column; align-items: center; justify-content: center;
}
.tp-glyph { font-size: 2em; color: var(--tp-teacher); margin-bottom: .35em; }
.tp-tm-gate h5 { margin: 0 0 .35em; font-family: var(--tp-serif); font-size: 1.35em; font-weight: 600; }
.tp-tm-gate > p { font-size: .9em; line-height: 1.55; color: var(--tp-ink-soft); max-width: 40ch; }
.tp-gate-sub { font-size: .85em; color: var(--tp-ink-faint); margin-bottom: 1em; }
.tp-gate-note { font-size: .8em; color: var(--tp-ink-faint); margin-top: 1em; max-width: 42ch; }
.tp-gate-tally { display: flex; gap: .4em; flex-wrap: wrap; justify-content: center; margin: 1em 0; }
.tp-gate-pill {
    font-size: .78em; font-weight: 700; border-radius: 999px; padding: .2em .7em; border: 1px solid;
}
.tp-gp-learned { background: var(--tp-student-wash); border-color: var(--tp-student); color: var(--tp-student); }
.tp-gp-help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-gp-skip { background: var(--tp-skip-wash); border-color: var(--tp-skip); color: var(--tp-skip); }
.tp-gate-btns { display: flex; gap: .5em; flex-wrap: wrap; justify-content: center; margin-top: .5em; }
.tp-gate-btns button {
    font: inherit; font-size: .88em; font-weight: 700; cursor: pointer; min-height: 2.8em;
    padding: .5em 1.2em; border-radius: .6em; border: 1px solid var(--tp-rule);
    background: var(--tp-panel); color: var(--tp-ink);
}
.tp-gate-btns .tp-primary { background: var(--tp-teacher); border-color: var(--tp-teacher); color: #fff; }
.tp-gate-btns button:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: 2px; }

.tp-gate-scroll { flex: 1 1 auto; overflow-y: auto; min-height: 0; padding: 1.2em .9em 2em; }
.tp-gate-lead { text-align: center; margin-bottom: 1.4em; }
.tp-gate-lead h5 { margin: 0 0 .2em; font-family: var(--tp-serif); font-size: 1.35em; font-weight: 600; }
.tp-gate-foot { margin-top: 1.6em; display: flex; justify-content: center; gap: .6em; flex-wrap: wrap; }
.tp-gate-foot button {
    font: inherit; font-size: .95em; font-weight: 700; cursor: pointer; min-height: 3em;
    padding: .6em 1.6em; border-radius: .6em; border: 1px solid var(--tp-teacher);
    background: var(--tp-teacher); color: #fff;
}
.tp-gate-foot button:not(.tp-primary) {
    background: var(--tp-panel); color: var(--tp-ink); border-color: var(--tp-rule);
}
.tp-gate-done {
    font-size: .86em; line-height: 1.5; color: var(--tp-student);
    background: var(--tp-student-wash); border: 1px solid var(--tp-student);
    border-radius: .5em; padding: .5em .8em; max-width: 46ch; margin: 0 auto;
}
.tp-gate-done i { margin-right: .4em; }

/* ---------- navigator ---------- */
.tp-nav-ev { border-bottom: 1px solid var(--tp-rule); }
.tp-nav-ev-head {
    width: 100%; font: inherit; text-align: left; cursor: pointer; border: 0; background: transparent;
    color: var(--tp-ink); padding: .6em .8em; display: flex; align-items: center; gap: .55em;
}
.tp-nav-ev-head:hover { background: var(--tp-panel-3); }
.tp-nav-ev[data-active="true"] > .tp-nav-ev-head { background: var(--tp-teacher-wash); }
.tp-nav-idx {
    flex: 0 0 auto; width: 1.5em; height: 1.5em; border-radius: .4em; display: grid; place-items: center;
    background: var(--tp-panel); border: 1px solid var(--tp-rule); color: var(--tp-ink-soft);
    font-size: .74em; font-weight: 700;
}
.tp-nav-ev[data-active="true"] .tp-nav-idx { background: var(--tp-teacher); border-color: var(--tp-teacher); color: #fff; }
.tp-nav-ev-txt { flex: 1 1 auto; min-width: 0; }
.tp-nav-ev-txt b { display: block; font-size: .84em; font-weight: 650; line-height: 1.3; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-nav-ev-txt span { display: block; font-size: .72em; color: var(--tp-ink-faint); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-nav-prog { flex: 0 0 auto; display: flex; gap: 2px; }
.tp-nav-prog i { width: 4px; height: 12px; border-radius: 2px; background: var(--tp-panel-3); display: block; }
.tp-nav-prog i.learned { background: var(--tp-student); }
.tp-nav-prog i.help { background: var(--tp-note); }
.tp-nav-prog i.skipped { background: var(--tp-skip); }
.tp-nav-sets { display: none; padding-bottom: .35em; }
.tp-nav-ev[data-open="true"] .tp-nav-sets { display: block; }
.tp-nav-set {
    width: 100%; font: inherit; font-size: .8em; text-align: left; cursor: pointer; border: 0;
    border-left: 3px solid transparent; background: transparent; color: var(--tp-ink-soft);
    padding: .35em .8em .35em 1.2em; display: flex; align-items: center; gap: .45em;
}
.tp-nav-set:hover { background: var(--tp-panel-3); color: var(--tp-ink); }
.tp-nav-set[data-current="true"] {
    background: var(--tp-panel); color: var(--tp-ink); font-weight: 650; border-left-color: var(--tp-teacher);
}
.tp-nav-dot {
    flex: 0 0 auto; width: 1.3em; height: 1.3em; border-radius: 50%; display: grid; place-items: center;
    border: 1px solid var(--tp-rule); background: var(--tp-panel); color: var(--tp-ink-faint);
    font-size: .72em; font-weight: 700;
}
.tp-nav-dot.learned { background: var(--tp-student); border-color: var(--tp-student); color: #fff; }
.tp-nav-dot.help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-nav-dot.skipped { background: var(--tp-skip-wash); border-color: var(--tp-skip); color: var(--tp-skip); }
.tp-nav-nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- session record ---------- */
.tp-side-tally { flex: 0 0 auto; display: grid; grid-template-columns: repeat(4, 1fr); border-bottom: 1px solid var(--tp-rule); }
.tp-side-tally > div { padding: .6em .3em; text-align: center; border-right: 1px solid var(--tp-rule); }
.tp-side-tally > div:last-child { border-right: 0; }
.tp-side-tally b { display: block; font-size: 1.15em; font-weight: 700; font-variant-numeric: tabular-nums; }
.tp-side-tally span { font-size: .64em; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; color: var(--tp-ink-faint); }
.tp-t-learned b { color: var(--tp-student); }
.tp-t-help b { color: var(--tp-note); }
.tp-t-skip b { color: var(--tp-skip); }
.tp-t-open b { color: var(--tp-ink-faint); }

.tp-rec-ev {
    font-size: .66em; font-weight: 800; letter-spacing: .07em; text-transform: uppercase;
    color: var(--tp-ink-faint); padding: .8em 1em .3em;
}
.tp-rec-row { display: flex; align-items: center; gap: .5em; padding: .3em 1em; font-size: .82em; }
.tp-rec-nm { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tp-rec-att { flex: 0 0 auto; font-size: .8em; font-weight: 700; color: var(--tp-ink-faint); }
.tp-pill {
    flex: 0 0 auto; font-size: .72em; font-weight: 700; border-radius: 999px;
    padding: .1em .55em; border: 1px solid var(--tp-rule); color: var(--tp-ink-faint); white-space: nowrap;
}
.tp-pill.learned { background: var(--tp-student-wash); border-color: var(--tp-student); color: var(--tp-student); }
.tp-pill.help { background: var(--tp-note-wash); border-color: var(--tp-note); color: var(--tp-note); }
.tp-pill.skipped { background: var(--tp-skip-wash); border-color: var(--tp-skip); color: var(--tp-skip); }
.tp-ref-wrap { padding: .9em 1em 1.5em; }
.tp-ref-group { margin-bottom: 1.1em; font-size: .95em; }

/* ---------- bottom sheet (roster / reference) ---------- */
/* Anchored to the VIEWPORT, not to .tp-v4. It used to be position:absolute
   inside .tp-v4, which on a phone extends below the fold — so the sheet was
   bottom-aligned to a bottom that was off-screen and its Close button could
   not be reached without scrolling the page behind it. */
.tp-sheet {
    position: fixed; inset: 0; z-index: 40; background: rgba(15, 17, 22, .45);
    display: none; align-items: flex-end; justify-content: center;
}
.tp-sheet[data-open="true"] { display: flex; }
.tp-sheet-panel {
    width: 100%; max-width: 34em; display: flex; flex-direction: column;
    max-height: 82vh;
    max-height: 82dvh;
    background: var(--tp-panel); border-radius: 1em 1em 0 0;
    padding: .5em 1.1em calc(1.1em + env(safe-area-inset-bottom));
}
.tp-sheet-grab { width: 2.5em; height: 4px; border-radius: 2px; background: var(--tp-rule); margin: .2em auto .8em; }
.tp-sheet-body { flex: 1 1 auto; overflow-y: auto; min-height: 0; }
.tp-sheet-close {
    flex: 0 0 auto; margin-top: .8em; font: inherit; font-size: .88em; font-weight: 700; cursor: pointer;
    min-height: 2.8em; border-radius: .6em; border: 1px solid var(--tp-rule);
    background: var(--tp-panel-2); color: var(--tp-ink);
}

/* ---------- tablet: the lesson navigator appears ---------- */
@media (min-width: 780px) {
    .tp-modebar { order: 0; flex: 0 0 auto; }
    .tp-rail { display: none; }
    .tp-pane-nav {
        display: flex; flex-direction: column; min-height: 0;
        flex: 0 0 clamp(200px, 22vw, 280px);
        border-right: 1px solid var(--tp-rule); background: var(--tp-panel-2);
    }
    .tp-body, .tp-tm-stage, .tp-gate-scroll { padding-left: 1.4em; padding-right: 1.4em; }
    .tp-tm-actions { grid-template-columns: 2.6em 1fr 1.3fr 1.3fr 2.6em; }
}

/* Below 1180px the session-record pane is gone, so the running tally rides
   above the main column instead — a teacher should never have to guess how
   much of the lesson is still open. */
.tp-compact-tally { flex: 0 0 auto; }
.tp-compact-tally .tp-side-tally { border-bottom: 1px solid var(--tp-rule); }

/* ---------- desktop: the session record appears ---------- */
@media (min-width: 1180px) {
    .tp-pane-side {
        display: flex; flex-direction: column; min-height: 0;
        flex: 0 0 clamp(240px, 21vw, 330px);
        border-left: 1px solid var(--tp-rule); background: var(--tp-panel-2);
    }
    .tp-icon-btn { display: none; }
    .tp-compact-tally { display: none; }
    .tp-tm-actions kbd { display: inline-block; }
}

/* ---------- phone ---------- */
@media (max-width: 768px) {
    /* 520px is taller than the space a phone has left after the shell, so on a
       phone it is the floor that pushes the module below the fold rather than
       a guard against it collapsing. The measured height is the whole point
       here, so let it apply. */
    .tp-v4 {
        min-height: 0;
        border-radius: 0;
        border-left: 0;
        border-right: 0;
    }

    /* One scroll surface. The module owns the viewport it was given; the page
       behind it must not scroll as well. */
    .tp-body,
    .tp-tm-stage,
    .tp-gate-scroll {
        padding-left: .8em;
        padding-right: .8em;
        overscroll-behavior: contain;
    }

    /* The teacher is standing up with one hand on the phone — the outcome
       buttons are the one thing that must be unmissable. */
    .tp-tm-actions {
        grid-template-columns: 2.6em 1fr 1.15fr 1.4fr 2.6em;
        gap: .35em;
        padding: .6em .7em calc(.6em + env(safe-area-inset-bottom));
    }

    .tp-tm-actions button {
        min-height: 3.2em;
    }

    /* The header wraps to five rows at this width. Tighten what it costs
       without hiding any of it — every control in there is still reachable. */
    .tp-head {
        gap: .45em;
        padding: .5em .6em;
    }

    /* Mid-lesson the event rail and the running tally are review aids: Teach
       mode already carries its own progress meter and prints
       "Set 1 of 8 · 0/8 closed · Event 1 of 8" under the action bar. Dropping
       both here buys back roughly 170px for the script, which is the only
       thing on this screen the teacher is actually reading aloud. */
    .tp-v4[data-mode="teach"] .tp-rail,
    .tp-v4[data-mode="teach"] .tp-compact-tally {
        display: none;
    }

    /* Every label in here is em-relative off `.tp-v4 { font-size: 15px }`, so
       the .6–.78em label classes land between 9px and 11.7px — under the 12px
       floor the rest of the phone shell holds to, and this is the one module
       read at arm's length while standing up. Pin the offenders rather than
       inflating the root, which would drag the script copy up with them. */
    .tp-v4 .tp-theme-badge,
    .tp-v4 .tp-eyebrow,
    .tp-v4 .tp-pane-title,
    .tp-v4 .tp-pane-title .tp-cnt,
    .tp-v4 .tp-nav-ev-txt span,
    .tp-v4 .tp-side-tally span,
    .tp-v4 .tp-chip,
    .tp-v4 .tp-ov-ev-c,
    .tp-v4 .tp-ov-ev-nm em,
    .tp-v4 .tp-ov-ev-n,
    .tp-v4 .tp-rec-ev,
    .tp-v4 .tp-stu-row-n,
    .tp-v4 .tp-chip-n,
    .tp-v4 .tp-rv-tag,
    .tp-v4 .tp-pill,
    .tp-v4 .tp-tm-status,
    .tp-v4 .tp-sub {
        font-size: 12px;
    }

    /* ---------- header: four wrapped rows down to two ---------- */

    /* Was ~200px at 390px wide — a quarter of the screen, including one row
       holding a single orphaned 44px icon button that the wrap had pushed onto
       its own line. Everything set once and left alone moves behind the gear. */
    .tp-head {
        row-gap: .5em;
    }

    /* A 14em basis plus the student button does not fit in 366px, so the
       student wrapped to a line of its own. Let the title take what is left
       after the button instead — two rows, not three. */
    .tp-head-id { flex: 1 1 8em; }
    .tp-head > .tp-stu-btn { flex: 0 1 auto; max-width: 46%; }

    .tp-head-actions {
        display: flex;
        align-items: center;
        gap: .5em;
        flex: 1 1 100%;
        order: 3;
    }

    /* order: 3 is what puts the mode bar on its own line inside .tp-head; once
       it is inside the wrapper that job belongs to the wrapper, and the stale
       order would sort the gear ahead of it. */
    .tp-modebar { order: 0; flex: 1 1 auto; }

    .tp-modebar button {
        padding: .42em .6em;
        font-size: .82em;
    }

    .tp-gear-btn {
        display: grid;
        place-items: center;
        flex: 0 0 auto;
        width: 2.6em;
        min-height: 44px;
        font: inherit;
        font-size: .95em;
        cursor: pointer;
        border: 1px solid var(--tp-rule);
        border-radius: .5em;
        background: var(--tp-panel);
        color: var(--tp-ink-soft);
    }

    .tp-gear-btn:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: 2px; }

    /* Their contents now live in the gear's sheet. */
    .tp-fsctl,
    .tp-head > .tp-icon-btn { display: none; }

    /* The sheet copy is the only one on a phone, so it must not inherit the
       hide above. */
    .tp-sheet .tp-fsctl-sheet {
        display: flex;
        width: 100%;
    }

    .tp-sheet .tp-fsctl-sheet button {
        flex: 1 1 0;
        min-height: 44px;
    }

    .tp-set-group { margin-bottom: 1.1em; }

    .tp-set-row {
        display: flex;
        align-items: center;
        gap: .8em;
        width: 100%;
        min-height: 52px;
        padding: .6em .7em;
        font: inherit;
        text-align: left;
        cursor: pointer;
        border: 1px solid var(--tp-rule);
        border-radius: .6em;
        background: var(--tp-panel);
        color: var(--tp-ink);
        margin-bottom: .45em;
    }

    .tp-set-row span { flex: 1 1 auto; min-width: 0; }
    .tp-set-row b { display: block; font-size: 14px; font-weight: 650; }
    .tp-set-row em { display: block; font-style: normal; font-size: 12px; color: var(--tp-ink-faint); }
    .tp-set-row .tp-set-go { color: var(--tp-ink-faint); }

    /* ---------- Teach mode: the focus bar ---------- */

    .tp-teachbar {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        gap: .6em;
        padding: .5em .7em;
        padding-top: calc(.5em + env(safe-area-inset-top));
        border-bottom: 1px solid var(--tp-rule);
        background: var(--tp-panel-2);
    }

    .tp-teachbar-id { flex: 1 1 auto; min-width: 0; }
    .tp-teachbar-id b {
        display: block; font-family: var(--tp-serif); font-size: 15px; font-weight: 600;
        line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }
    .tp-teachbar-id span {
        display: block; font-size: 12px; color: var(--tp-ink-faint);
        overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
    }

    .tp-teachbar .tp-stu-btn { flex: 0 1 auto; min-width: 0; max-width: 40%; }

    .tp-exit-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        gap: .35em;
        min-height: 44px;
        padding: .4em .8em;
        font: inherit;
        font-size: 13px;
        font-weight: 700;
        cursor: pointer;
        border: 1px solid var(--tp-rule);
        border-radius: .5em;
        background: var(--tp-panel);
        color: var(--tp-ink-soft);
    }

    .tp-exit-btn:focus-visible { outline: 2px solid var(--tp-teacher); outline-offset: 2px; }

    /* In Teach mode the header and the mode toggle are redundant — the teach
       bar already says which lesson and which student, and Exit is the way
       back. Everything else belongs to the script and the marking buttons. */
    .tp-v4[data-mode="teach"] .tp-head { display: none; }

    /* The module owns the whole viewport in focus mode, so nothing above it is
       left to measure. */
    body.tp-teach-focus .tp-v4 { --tp-app-chrome: 0px; }

    body.tp-teach-focus .tp-tm-stage { flex: 1 1 auto; min-height: 0; }
}

/* ---------- Teach focus: the app shell steps aside ----------
   Set by TeacherPlanModule._syncTeachFocus() when Teach mode is entered at or
   below 768px, and removed on leaving Teach, on destroy(), and on a resize
   back above the breakpoint. It hides global chrome, so the removal paths
   matter more than the addition: a leaked class would leave the next module
   with no header at all. */
body.tp-teach-focus .header,
body.tp-teach-focus .construction-banner,
body.tp-teach-focus #migration-lockdown-banner,
body.tp-teach-focus .nav-context,
/* The floating bug button sits in the top-right corner, which is exactly where
   Exit now lives — it covered it outright at 768px. */
body.tp-teach-focus #bugReportBtn,
body.tp-teach-focus .bug-report-float-btn {
    display: none !important;
}

body.tp-teach-focus .container {
    padding: 0 !important;
    margin: 0 !important;
}

/* One scroll surface. The stage scrolls; the page behind it does not. */
body.tp-teach-focus {
    overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
    .tp-v4 * { transition: none !important; animation: none !important; }
}
