/* =================================================================
   SHELL FRAME (v0.25.3.0)
   Bob and Mariel Ward School of Filipino Languages

   The frame every screen sits in, for all three zones:

     ≥1024px  a 220px sidebar (the menu, always open) and a 56px top bar
              that names the screen; content capped at 1080px.
     769–1023 the same top bar; the menu is the slide-out drawer.
     ≤768px   the phone app bar (core.css) and, when a zone fills it,
              the 5-slot tab bar (js/tab-bar.js).

   The sidebar IS the drawer (#mobileNavMenu), laid out differently. One
   menu means one set of items, one click handler and one place where
   roles hide what a role cannot open (auth-manager.js hides items with
   ADMIN_ZONE_ROLES, and that is the same markup in both layouts).

   Loaded after core.css and theme.css so these rules win on source order
   without !important.
   ================================================================= */

:root {
    --shell-sidebar: 220px;
    --shell-bar: 56px;
    --shell-content: 1080px;
    /* How far a fixed, left-anchored element must stand off the left edge
       so the sidebar does not cover it. 0 below 1024px. */
    --shell-left: 0px;
}

/* ---- the menu's brand block (every width) -------------------------------
   The school name moved here from the top bar, which names the screen. */
.mobile-nav-header {
    gap: 8px;
}

.mobile-nav-brand {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
}

.mobile-nav-logo {
    width: 36px;
    height: 36px;
    flex: none;
    object-fit: contain;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    padding: 2px;
}

.mobile-nav-brand-name {
    display: flex;
    flex-direction: column;
    min-width: 0;
    font-size: var(--as-fs-md);
    font-weight: 700;
    line-height: 1.15;
    /* The full name (v0.25.14.0) takes two lines; the version is under it. */
    text-wrap: balance;
}

.mobile-nav-brand-name small {
    font-size: var(--as-fs-xs);
    font-weight: 500;
    opacity: 0.88;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ---- menu items are buttons (keyboard-operable) -------------------------
   They were <div>s with click handlers: no Tab stop, no Enter, no role.
   This only undoes what the browser gives a <button>. It is wrapped in
   :where() so it has no specificity at all, and every .mobile-nav-* rule in
   core.css (indent, colour, the login/logout tints) still wins over it. */
:where(button.mobile-nav-item) {
    width: 100%;
    margin: 0;
    font: inherit;
    text-align: left;
    background: none;
    border: 0;
    border-radius: 0;
    color: var(--text-primary);
}

.mobile-nav-item:focus-visible,
.mobile-nav-close:focus-visible,
.status-pill-action:focus-visible,
.status-pill-info:focus-visible,
.tab-bar-item:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: -2px;
}

/* A closed group is closed to the keyboard too. max-height: 0 hides it from
   the eye only; without this Tab walked through every hidden row. The
   visibility change waits for the collapse animation to finish. */
.mobile-nav-submenu {
    visibility: hidden;
    transition: max-height 0.3s ease, visibility 0s linear 0.3s;
}

.mobile-nav-submenu.expanded {
    visibility: visible;
    transition: max-height 0.3s ease, visibility 0s linear 0s;
}

/* ---- switched-off activities (v0.25.7.0) -------------------------------
   Listed, readable, and labelled "Coming soon" — not a faded row that
   ignores the tap. core.css sets pointer-events: none on them. */
.mobile-nav-item.under-development {
    opacity: 1;
    color: var(--text-secondary);
    cursor: default;
}

.mobile-nav-item.under-development > i:first-child {
    opacity: 0.55;
}

.mobile-nav-soon {
    margin-left: auto;
    padding: 2px 8px;
    border-radius: var(--as-r-pill, 999px);
    background: var(--as-warn-wash);
    color: var(--as-warn);
    font-size: var(--as-fs-xs);
    font-weight: 700;
    white-space: nowrap;
}

/* ---- the Admin zone's groups (v0.25.6.0) ------------------------------
   People / Content / System, and System Admin's own five. A label says what
   the entry under it is, so it goes when that entry is hidden for this role
   (School Admin for a deck-manager, System Admin for all but an admin). */
.mobile-nav-group-label:has(+ .hidden),
.mobile-nav-group-label:has(+ [style*="display: none"]) {
    display: none;
}

.mobile-nav-group-label.mobile-nav-group-nested {
    padding-left: 52px;
}

.mobile-nav-subitem.mobile-nav-nested.mobile-nav-grouped {
    padding-left: 80px;
}

.mobile-nav-subhead.mobile-nav-nested {
    padding-left: 64px;
}

/* ---- the status pill ----------------------------------------------------
   One pill, one state. Review mode, when on, replaces "Under construction":
   it is the one the reader can do something about. */
.status-pill {
    display: inline-flex;
    align-items: center;
    flex: none;
    margin-left: 10px;
}

.status-pill-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 28px;
    padding: 0 10px;
    border-radius: var(--as-r-pill, 999px);
    font-size: var(--as-fs-xs);
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
}

.status-pill-construction {
    background: var(--as-warn-wash);
    color: var(--as-warn);
    border: 1px solid color-mix(in srgb, var(--as-warn) 30%, transparent);
}

.status-pill .preview-mode-banner {
    display: none;
    background: var(--as-brand-wash);
    color: var(--as-brand-deep);
    border: 1px solid color-mix(in srgb, var(--as-brand) 35%, transparent);
    padding-right: 3px;
}

.status-pill .preview-mode-banner.visible {
    display: inline-flex;
}

.status-pill:has(.preview-mode-banner.visible) .status-pill-construction {
    display: none;
}

.status-pill-info {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    height: 100%;
    padding: 0;
    border: 0;
    background: none;
    color: inherit;
    font: inherit;
    cursor: pointer;
}

.status-pill-action {
    height: 22px;
    padding: 0 10px;
    border: 0;
    border-radius: var(--as-r-pill, 999px);
    background: var(--as-brand-fill);
    color: var(--as-on-brand, #fff);
    font: inherit;
    font-weight: 700;
    cursor: pointer;
}

.status-pill-action:hover {
    background: var(--as-brand-fill-hover);
}

/* ---- the lesson chip and its sheet (js/lesson-chip.js, v0.25.7.0) ------
   Phone only: one row, "Cebuano · Lesson 4", in place of the two selects. */
.lesson-chip {
    display: none;
}

.lesson-sheet {
    position: fixed;
    inset: 0;
    z-index: 10060;
    display: grid;
    align-items: end;
}

.lesson-sheet-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 18, 30, 0.5);
}

.lesson-sheet-panel {
    position: relative;
    display: grid;
    gap: 14px;
    padding: 10px 18px calc(18px + env(safe-area-inset-bottom, 0px));
    background: var(--as-surface);
    color: var(--as-ink);
    border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.2);
}

.lesson-sheet-grip {
    justify-self: center;
    width: 40px;
    height: 4px;
    border-radius: 2px;
    background: var(--as-line-strong);
}

.lesson-sheet-title {
    margin: 0;
    font-size: 17px;
}

.lesson-sheet-field {
    display: grid;
    gap: 6px;
    font-size: 13px;
    font-weight: 700;
    color: var(--as-ink2);
}

.lesson-sheet-field select {
    min-height: 48px;
    padding: 0 12px;
    border: 1px solid var(--as-line-strong);
    border-radius: 12px;
    background: var(--as-surface);
    color: var(--as-ink);
    font: inherit;
    font-size: var(--as-fs-md);
    font-weight: 400;
}

.lesson-sheet-hint {
    margin: -4px 0 0;
    font-size: 13px;
    color: var(--as-ink2);
}

.lesson-sheet-done {
    min-height: 48px;
    border: 0;
    border-radius: 12px;
    background: var(--as-brand-fill);
    color: var(--as-on-brand, #fff);
    font: inherit;
    font-size: var(--as-fs-md);
    font-weight: 700;
    cursor: pointer;
}

.lesson-chip:focus-visible,
.lesson-sheet-done:focus-visible,
.lesson-sheet-field select:focus-visible {
    outline: 2px solid var(--as-brand);
    outline-offset: 2px;
}

/* ---- the phone tab bar (js/tab-bar.js) ---------------------------------
   Phone only. Empty until a zone fills it; while it shows, the page keeps
   room for it at the bottom. An activity's own bottom dock takes the place
   of the tab bar, never both. */
.tab-bar {
    display: none;
}

@media (max-width: 768px) {
    /* The chip takes the selects' row. */
    .header-controls .header-selectors {
        display: none;
    }

    /* A 56px app bar and the chip's row, nothing above or below them:
       theme.css's `body.mobile-phone .header { padding: 12px 0 }` outranked
       core.css's padding: 0 and added 24px to every phone screen. That
       rule now applies only above 768px (v0.25.63.0), so a plain .header
       does it here. */
    .header {
        padding: 0;
    }

    .header-content {
        grid-template-rows: 56px auto;
    }

    .lesson-chip {
        grid-row: 2;
        grid-column: 1 / -1;
        display: flex;
        align-items: center;
        gap: 8px;
        min-width: 0;
        min-height: 44px;
        margin: 0 4px 8px;
        padding: 0 14px;
        border: 1px solid var(--as-line);
        border-radius: var(--as-r-pill, 999px);
        background: var(--as-sunk);
        color: var(--as-ink);
        font: inherit;
        font-size: var(--as-fs-sm);
        font-weight: 600;
        text-align: left;
        cursor: pointer;
    }

    .lesson-chip > i { color: var(--as-ink2); flex: none; }

    .lesson-chip-text {
        flex: 1 1 auto;
        min-width: 0;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    body.has-tab-bar .tab-bar {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        z-index: 890;
        display: grid;
        grid-auto-columns: minmax(0, 1fr);
        grid-auto-flow: column;
        height: calc(58px + env(safe-area-inset-bottom, 0px));
        padding-bottom: env(safe-area-inset-bottom, 0px);
        background: var(--as-surface);
        border-top: 1px solid var(--as-line);
        box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
    }

    body.has-tab-bar:has(.as-dock:not([hidden])) .tab-bar {
        display: none;
    }

    body.has-tab-bar .container {
        padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px));
    }

    .tab-bar-item {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 3px;
        min-width: 0;
        min-height: var(--as-tap, 44px);
        padding: 4px 2px;
        border: 0;
        background: none;
        color: var(--as-ink2);
        font: inherit;
        font-size: var(--as-fs-xs);
        font-weight: 600;
        cursor: pointer;
    }

    .tab-bar-item i {
        font-size: var(--as-fs-lg);
    }

    .tab-bar-item span {
        max-width: 100%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }

    .tab-bar-item[aria-current="page"] {
        color: var(--as-brand);
    }

    /* The phone pill: Review as a word plus its action; no construction
       notice. Folded to its hard-hat icon it was "an odd orangish circle
       with an odd symbol" (bug-2026-09-29-040351) — its words were only a
       tooltip, which a touch screen never shows, and it does nothing when
       tapped. The words cost a third of the app bar, so on a phone it goes
       (v0.25.78.0); a wider screen still says it in full. */
    .status-pill {
        margin-left: 6px;
    }

    .status-pill-construction {
        display: none;
    }

    /* Review mode is one eye on a phone. Tapping it explains the mode and
       offers Log in (showReviewModeInfo() in app.js), so nothing is lost by
       folding the words and the button away. */
    .status-pill .preview-mode-banner {
        width: 36px;
        height: 36px;
        padding: 0;
        justify-content: center;
    }

    .status-pill .preview-mode-banner .status-pill-text,
    .status-pill .preview-mode-banner .status-pill-action {
        display: none;
    }

    .status-pill-info {
        width: 100%;
        justify-content: center;
        font-size: 15px;
    }

    .header-title {
        flex-wrap: nowrap;
        align-items: center;
    }

    .mobile-app-title {
        flex: 1 1 auto;
    }
}

/* =================================================================
   TOP BAR  (≥769px)
   The header is one 56px row: the screen and its group on the left, the
   status pill, then language, lesson and the settings. The school name
   is in the menu; the old context bar would only repeat the title, so
   its steppers move up here.
   ================================================================= */
@media (min-width: 769px) {
    .header {
        padding: 0;
        margin-bottom: 20px;
    }

    .header-content {
        width: 100%;
        max-width: none;
        min-height: var(--shell-bar);
        padding: 0 20px;
        flex-wrap: nowrap;
        gap: 12px;
    }

    .header-title {
        flex: 1 1 auto;
        min-width: 0;
        gap: 0;
        /* A size container (v0.25.17.0): it takes the space the controls
           leave, and the pill below folds to fit it. It used to shrink
           under the pill instead, and on a 1280px screen in Preview the
           next control sat on top of "Sign in". */
        container-type: inline-size;
        container-name: header-title;
    }

    /* Too narrow for the words: the eye and Sign in. */
    @container header-title (max-width: 380px) {
        .status-pill .preview-mode-banner .status-pill-text { display: none; }
        /* The construction pill folds to its hard hat too (v0.25.19.0): at
           1280px on a Teacher's Zone page it ran under the offline button. */
        .status-pill .status-pill-construction .status-pill-text { display: none; }
    }

    /* Too narrow for both: the eye alone, which opens the explanation
       with Sign in (showReviewModeInfo). */
    @container header-title (max-width: 240px) {
        .status-pill .preview-mode-banner .status-pill-action { display: none; }
        .status-pill .preview-mode-banner { padding-right: 10px; }
    }

    .header-title h1,
    .version-desktop,
    .version-inline-mobile {
        display: none;
    }

    /* The group above the screen, as on every PageHeader. */
    .mobile-app-title {
        display: flex;
        flex-direction: column-reverse;
        min-width: 0;
        line-height: 1.2;
    }

    .mobile-app-title b {
        font-size: 17px;
        font-weight: 700;
        color: var(--text-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .mobile-app-title small {
        font-size: var(--as-fs-xs);
        font-weight: 700;
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--text-secondary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }

    .mobile-app-title small:empty {
        display: none;
    }

    .header-controls {
        flex: none;
        flex-wrap: nowrap;
        gap: 8px;
    }

    .mobile-nav-toggle {
        margin-right: 0;
        padding: 6px 10px;
        font-size: var(--as-fs-lg);
    }

    /* The toggle leads the bar: it is the way to everything else. */
    #mobileNavToggle {
        order: -2;
    }

    .header-title {
        order: -1;
    }

    .lesson-selector .select-control {
        max-width: 210px;
    }

    .mobile-app-title {
        flex: 0 1 auto;
        min-width: 110px;
    }

    /* Icon buttons with a tooltip and an accessible name. */
    #advancedFilterBtn > span:not(.filter-indicator),
    #themeToggle > span {
        display: none;
    }

    .mobile-step-btn {
        display: grid;
        place-items: center;
        width: 36px;
        height: 36px;
        border: 1px solid var(--border-color);
        border-radius: 8px;
        background: var(--bg-primary);
        color: var(--text-secondary);
        cursor: pointer;
        font-size: 13px;
    }

    .mobile-step-btn:hover {
        color: var(--primary);
        border-color: var(--primary);
    }

    /* The floating bug button is the reporter above a phone. It stays in
       its corner, lined up with the bar, and the bar keeps clear of it. */
    #mobileBugBtn {
        display: none;
    }

    .header-content {
        padding-right: 76px;
    }

    .bug-report-float-btn {
        top: 6px;
    }

    .nav-context {
        display: none;
    }
}

/* The header is flex above 768px, so the toggle is moved in front of the
   title by `order`; that needs the title and controls to be siblings in
   one flex row, which they are once .header-controls stops being a box. */
@media (min-width: 769px) {
    .header-controls {
        display: contents;
    }

    .header-selectors {
        display: flex;
        gap: 8px;
        flex: none;
    }
}

/* One row with a sidebar (≥1024px, v0.25.17.0). The title area keeps room
   for the screen's name and the pill's eye; the two selects give way to it
   (down to a readable 104px each) instead of running over the name. At
   1024px the controls took 685px and left the title 11. */
@media (min-width: 1024px) {
    .header-title {
        min-width: 170px;
    }

    .header-selectors {
        flex: 0 1 auto;
        min-width: 0;
    }

    /* Only the selects give way: the icon buttons keep their 36–44px. */
    .header-controls > :not(.header-selectors) {
        flex-shrink: 0;
    }

    .header-selectors .language-selector,
    .header-selectors .lesson-selector {
        flex: 0 1 auto;
        min-width: 0;
    }

    .header-selectors .select-control {
        min-width: 104px;
        width: 100%;
        text-overflow: ellipsis;
    }
}

/* Tablet: two rows. The menu button, the screen and the pill on the first;
   the lesson controls on the second, left-aligned rather than spread. */
@media (min-width: 769px) and (max-width: 1023px) {
    .header-content {
        flex-wrap: wrap;
        justify-content: flex-start;
        padding: 8px 76px 8px 16px;
        row-gap: 8px;
    }

    .header-title {
        flex: 1 1 calc(100% - 60px);
    }
}

/* =================================================================
   SIDEBAR  (≥1024px)
   ================================================================= */
@media (min-width: 1024px) {
    :root {
        --shell-left: var(--shell-sidebar);
        --layout-width: 100%;
    }

    body {
        padding-left: var(--shell-sidebar);
    }

    .mobile-nav-menu,
    .mobile-nav-menu.open {
        left: 0;
        width: var(--shell-sidebar);
        box-shadow: none;
        border-right: 1px solid var(--border-color);
        transition: none;
        /* Under every modal, toast and editor overlay (all 900+). */
        z-index: 800;
        padding-bottom: 24px;
        scrollbar-width: thin;
    }

    .mobile-nav-overlay,
    .mobile-nav-overlay.show,
    #mobileNavToggle,
    .mobile-nav-close {
        display: none;
    }

    .mobile-nav-header {
        position: sticky;
        top: 0;
        z-index: 1;
        box-sizing: border-box;
        height: var(--shell-bar);
        padding: 0 14px;
    }

    .mobile-nav-logo {
        width: 30px;
        height: 30px;
    }

    .mobile-nav-brand-name {
        font-size: var(--as-fs-sm);
    }

    .mobile-nav-brand-name small {
        font-size: var(--as-fs-xs);
    }

    .mobile-nav-item {
        gap: 10px;
        min-height: 40px;
        padding: 8px 14px;
        font-size: var(--as-fs-sm);
        border-bottom: 0;
    }

    .mobile-nav-item i {
        width: 18px;
    }

    .mobile-nav-category:not(.mobile-nav-subcategory) {
        font-weight: 700;
        border-top: 1px solid var(--border-color);
    }

    .mobile-nav-subitem {
        padding-left: 40px;
        font-size: 13.5px;
    }

    .mobile-nav-subcategory {
        padding-left: 26px;
        font-size: 13.5px;
    }

    .mobile-nav-nested {
        padding-left: 52px;
    }

    .mobile-nav-group-label {
        padding: 10px 14px 4px 26px;
    }

    .mobile-nav-group-label.mobile-nav-group-nested {
        padding-left: 40px;
    }

    .mobile-nav-subitem.mobile-nav-nested.mobile-nav-grouped {
        padding-left: 64px;
    }

    .mobile-nav-subhead.mobile-nav-nested {
        padding-left: 52px;
    }

    .mobile-nav-item.active {
        box-shadow: inset 3px 0 0 var(--primary);
    }

    /* Content: capped for reading, except the editors that are built
       to use the width (the Deck Builder and its lesson editor). */
    .container {
        max-width: calc(var(--shell-content) + 2 * var(--layout-pad));
    }

    body[data-route="deck-builder"] .container,
    body.tpd-open .container {
        max-width: none;
    }

    /* Live Teaching is read across the room as much as at arm's length, so
       it takes the width (v0.25.78.0, bug-2026-10-01-195121) — up to a cap
       that still keeps a line of the script readable on an ultra-wide. */
    body[data-route="teacher-plan-follow"] .container {
        max-width: calc(1600px + 2 * var(--layout-pad));
    }
}

/* Teach focus and print: the frame steps aside with the rest of the chrome.
   No !important on screen (v0.25.63.0): (0,2,1) ties `body.has-tab-bar
   .tab-bar` and comes after it; nothing else sets the menu's display; and
   (0,1,1) outranks the sidebar's `body` padding. */
body.tp-teach-focus .mobile-nav-menu,
body.tp-teach-focus .tab-bar {
    display: none;
}

body.tp-teach-focus {
    padding-left: 0;
}

@media print {
    .mobile-nav-menu,
    .tab-bar,
    .status-pill {
        display: none !important;
    }

    body {
        padding-left: 0 !important;
    }
}
