/* Left sidebar navigation — Story 9.14.

   Locked class: ``.sidebar.is-collapsed`` is the only collapsed-state hook.
   Story 9.17 relies on this directly without an audit step.

   Design tokens (:root custom properties) live in static/css/tokens.css,
   which must be <link>ed before this stylesheet.
*/

html,
body {
    color: var(--color-text);
    font-family: var(--font-body);
    background-color: var(--color-bg);
}

button,
input,
select,
textarea,
table {
    font-family: var(--font-body);
}

h1,
h2,
h3,
.page-title,
.page-heading {
    font-family: var(--font-body);
    font-weight: 800;
    letter-spacing: 0;
    color: var(--nstx-ink);
    hyphens: none;
    overflow-wrap: normal;
    word-break: normal;
}

.nstx-panel {
    background: var(--color-surface-alt);
    border: 1px solid var(--color-border);
    border-radius: 0;
    box-shadow: none;
}

.nstx-section-label {
    color: var(--color-text-muted);
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    line-height: 1.2;
    text-transform: uppercase;
}

.nstx-action-primary,
.nstx-action-secondary,
.nstx-action-danger,
.nstx-action-disabled,
.nstx-action-select {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    min-height: 2.375rem;
    padding: 0.625rem 1.25rem;
    border: 1px solid var(--nstx-ink);
    border-radius: 0;
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    line-height: 1;
    text-decoration: none;
    text-transform: uppercase;
    transition: background-color var(--sidebar-transition), color var(--sidebar-transition);
}

.nstx-action-select {
    appearance: none;
    background-color: transparent;
    background-image:
        linear-gradient(45deg, transparent 50%, var(--nstx-ink) 50%),
        linear-gradient(135deg, var(--nstx-ink) 50%, transparent 50%);
    background-position:
        calc(100% - 1.05rem) 50%,
        calc(100% - 0.75rem) 50%;
    background-repeat: no-repeat;
    background-size: 0.3125rem 0.3125rem, 0.3125rem 0.3125rem;
    border: 1px solid var(--nstx-ink);
    border-radius: 0;
    color: var(--nstx-ink);
    cursor: pointer;
    min-width: 8rem;
    padding-right: 2rem;
}

.nstx-action-primary {
    background: var(--nstx-ink);
    color: var(--nstx-paper);
}

.nstx-action-secondary {
    background: transparent;
    color: var(--nstx-ink);
}

.nstx-action-secondary:hover {
    background: var(--nstx-ink);
    color: var(--nstx-paper);
}

.nstx-action-danger {
    border-color: var(--color-danger);
    color: var(--color-danger);
}

.nstx-action-danger:hover {
    background: var(--color-danger);
    border-color: var(--color-danger);
    color: var(--nstx-paper);
}

.nstx-action-primary:hover {
    background: transparent;
    color: var(--nstx-ink);
}

.nstx-action-disabled,
.nstx-action-primary:disabled,
.nstx-action-secondary:disabled,
.nstx-action-danger:disabled {
    background: var(--nstx-paper-3);
    border-color: var(--nstx-border);
    color: var(--nstx-ink-3);
    cursor: not-allowed;
    opacity: 1;
}

.nstx-action-disabled:hover,
.nstx-action-primary:disabled:hover,
.nstx-action-secondary:disabled:hover,
.nstx-action-danger:disabled:hover {
    background: var(--nstx-paper-3);
    border-color: var(--nstx-border);
    color: var(--nstx-ink-3);
}

.nstx-action-compact {
    min-height: 1.875rem;
    padding: 0.4375rem 0.75rem;
    font-size: 0.625rem;
}

.nstx-tabs {
    display: flex;
    align-items: center;
    gap: 1.25rem;
    border-bottom: 1px solid var(--color-border);
    overflow-x: auto;
}

.nstx-tab {
    appearance: none;
    background: transparent;
    border: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.75rem 0 0.625rem;
    border-bottom: 1px solid transparent;
    color: var(--nstx-ink-3);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-decoration: none;
    text-transform: uppercase;
    white-space: nowrap;
}

.nstx-tab:hover,
.nstx-tab.is-active {
    border-bottom-color: var(--nstx-ink);
    color: var(--nstx-ink);
}

.nstx-tab__count {
    color: var(--nstx-ink-3);
    font-size: 0.6875rem;
}

.nstx-status-good,
.nstx-status-bad,
.nstx-status-offline {
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
}

.nstx-status-good {
    color: var(--color-success);
}

.nstx-status-bad {
    color: var(--color-danger);
}

.nstx-status-offline {
    color: var(--color-text-muted);
}

.nstx-inverted-strip {
    display: flex;
    align-items: center;
    gap: 2rem;
    min-height: 2.25rem;
    padding: 0.5rem 1rem;
    border: 1px solid var(--nstx-ink);
    background: var(--nstx-ink);
    color: var(--nstx-paper);
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    overflow-x: auto;
    text-transform: uppercase;
    white-space: nowrap;
}

.nstx-inverted-strip__item {
    flex: 0 0 auto;
}

.nstx-inverted-strip__divider {
    color: var(--nstx-ink-3);
}

.dashboard-card h3,
.report-card h3,
.operational-card-title {
    font-family: var(--font-body);
    font-weight: 700;
    letter-spacing: 0;
    line-height: 1.2;
}

/* ---- Skip-to-main-content link ----------------------------------------- */
.skip-to-main {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 1000;
    padding: 0.5rem 1rem;
    background-color: var(--sidebar-bg);
    color: var(--nstx-ink-3);
    text-decoration: none;
    border: 1px solid var(--color-border);
    border-radius: 0;
}

.skip-to-main:focus {
    left: 0;
    outline: 2px solid var(--nstx-ink);
    outline-offset: 2px;
}

/* ---- Body layout ------------------------------------------------------- */
body.has-sidebar {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    min-height: 100vh;
}

body.has-sidebar > main {
    flex: 1;
    min-width: 0;
}

/* ---- Sidebar shell ----------------------------------------------------- */
.sidebar {
    width: var(--sidebar-width-expanded);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    background-color: var(--sidebar-bg);
    color: var(--sidebar-fg);
    border-right: 1px solid var(--color-border);
    height: 100vh;
    position: sticky;
    top: 0;
    overflow: hidden;
    transition: width var(--sidebar-transition);
}

.sidebar.is-collapsed,
html.rtd-sidebar-collapsed-preload .sidebar {
    width: var(--sidebar-width-collapsed);
}

/* ---- Logo -------------------------------------------------------------- */
.sidebar-logo {
    flex-shrink: 0;
    min-height: var(--app-chrome-height);
    padding: 0 1rem;
    display: flex;
    justify-content: center;
    align-items: center;
    background: var(--nstx-ink);
    color: var(--nstx-paper);
}

.sidebar.is-collapsed .sidebar-logo,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-logo {
    padding: 0 0.5rem;
}

.sidebar-logo-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
    transition: opacity var(--sidebar-transition);
}

.sidebar-logo-link:hover {
    opacity: 0.9;
}

.nstx-logo-lockup,
.sidebar-logo-full {
    display: inline-flex;
    align-items: center;
    white-space: nowrap;
}

.nstx-logo-word {
    color: var(--nstx-paper);
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 900;
    letter-spacing: 0;
    line-height: 1;
}

.nstx-logo-industries {
    margin-left: 0.45rem;
    color: rgba(255, 255, 255, 0.55);
    font-family: var(--font-mono);
    font-size: 0.47rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1;
    text-transform: uppercase;
}

.sidebar-logo-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    color: var(--nstx-paper);
    font-family: var(--font-display);
    font-size: 0.9375rem;
    font-weight: 900;
    letter-spacing: 0;
    line-height: 1;
}

/* Logo swap rule: full when expanded, mark when collapsed. Both logo
   variants live in the DOM at all times. The preload-class branch keeps the
   swap correct before first paint when the user's persisted state is
   collapsed but ``.is-collapsed`` has not yet been migrated onto the
   sidebar element. */
html:not(.rtd-sidebar-collapsed-preload) .sidebar:not(.is-collapsed) .sidebar-logo-mark {
    display: none;
}

.sidebar.is-collapsed .sidebar-logo-full,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-logo-full {
    display: none;
}

/* ---- Section list ------------------------------------------------------ */
.sidebar-nav {
    flex: 0 1 auto;
    overflow-y: auto;
    padding: 0 0 0.75rem;
}

.sidebar-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
}

.sidebar-nav-item {
    margin: 0;
}

.sidebar-nav-group {
    border-bottom: 1px solid var(--color-border);
}

.sidebar-nav-group-summary {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    min-height: 2.75rem;
    padding: 0.625rem 1rem;
    color: var(--sidebar-fg);
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1.2;
    list-style: none;
    text-transform: uppercase;
    transition: background-color var(--sidebar-transition), color var(--sidebar-transition);
}

.sidebar-nav-group-summary::-webkit-details-marker {
    display: none;
}

.sidebar-nav-group-summary::marker {
    content: "";
}

.sidebar-nav-group-summary:hover,
.sidebar-nav-group.is-active > .sidebar-nav-group-summary {
    background-color: var(--sidebar-bg-hover);
    color: var(--nstx-ink);
}

.sidebar-nav-group-chevron {
    margin-left: auto;
    transition: transform var(--sidebar-transition);
}

.sidebar-nav-group[open] .sidebar-nav-group-chevron {
    transform: rotate(180deg);
}

.sidebar-nav-children {
    list-style: none;
    margin: 0;
    padding: 0 0 0.5rem;
}

.sidebar-nav-child-item {
    margin: 0;
}

.sidebar-nav-link {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    padding: 0.5rem 1rem 0.5rem 1.75rem;
    color: var(--nstx-ink-2);
    font-family: var(--font-mono);
    text-decoration: none;
    font-size: 0.61rem;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    transition: background-color var(--sidebar-transition), color var(--sidebar-transition);
    white-space: nowrap;
    overflow: hidden;
}

.sidebar-nav-link:hover {
    background-color: var(--sidebar-bg-hover);
}

.sidebar-nav-link.is-active {
    background-color: var(--sidebar-active-bg);
    color: var(--sidebar-active-fg);
}

.sidebar-nav-link.is-active:hover {
    background-color: var(--sidebar-active-bg);
}

/* Collapsed: center the icon-slot; render the active-state pill as a
   ~48px square around it so "you are here" remains visible. */
.sidebar.is-collapsed .sidebar-nav-link,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-link {
    justify-content: center;
    padding: 0.75rem 0.5rem;
}

.sidebar.is-collapsed .sidebar-nav-group-summary,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-group-summary {
    justify-content: center;
    padding: 0.75rem 0.5rem;
}

.sidebar.is-collapsed .sidebar-nav-children,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-children {
    display: none;
}

.sidebar.is-collapsed .sidebar-nav-link.is-active,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-link.is-active {
    background-color: transparent;
}

.sidebar.is-collapsed .sidebar-nav-link.is-active .sidebar-icon-slot,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-link.is-active .sidebar-icon-slot {
    background-color: var(--sidebar-active-bg);
    color: var(--sidebar-active-fg);
    border-radius: 0;
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.sidebar.is-collapsed .sidebar-nav-group.is-active > .sidebar-nav-group-summary .sidebar-icon-slot,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-nav-group.is-active > .sidebar-nav-group-summary .sidebar-icon-slot {
    background-color: var(--sidebar-active-bg);
    color: var(--sidebar-active-fg);
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

/* ---- User identity block ---------------------------------------------- */
.sidebar-user {
    margin-top: auto;
    padding: 0.75rem 1rem;
    border-top: 1px solid var(--color-border);
    flex-shrink: 0;
}

.sidebar.is-collapsed .sidebar-user,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-user {
    padding: 0.75rem 0.5rem;
    text-align: center;
}

.sidebar-user__icon-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.5rem;
}

.sidebar.is-collapsed .sidebar-user__icon-row,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-user__icon-row {
    justify-content: center;
}

.sidebar-user__details {
    margin-top: 0.5rem;
    display: block;
}

.sidebar-user-name {
    font-weight: 600;
    font-family: var(--font-mono);
    font-size: 0.6875rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--sidebar-fg);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sidebar-user-email {
    color: var(--sidebar-fg-muted);
    font-size: 0.75rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    margin-top: 0.125rem;
}

.sidebar-user-signout-form {
    margin: 0.75rem 0 0;
}

.sidebar-user-signout {
    display: flex;
    width: 100%;
    min-height: 2.75rem;
    align-items: center;
    justify-content: center;
    padding: 0.72rem 1rem;
    background-color: transparent;
    color: var(--nstx-ink);
    border: 1px solid var(--nstx-ink);
    border-radius: 0;
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    line-height: 1;
    text-transform: uppercase;
    cursor: pointer;
    transition:
        background-color var(--sidebar-transition),
        color var(--sidebar-transition),
        border-color var(--sidebar-transition);
}

.sidebar-user-signout:hover {
    background-color: var(--nstx-ink);
    color: var(--nstx-paper);
}

.sidebar-user-signin {
    display: inline-block;
    margin-top: 0.5rem;
    color: var(--sidebar-fg);
    text-decoration: underline;
    font-size: 0.9375rem;
}

/* ---- Collapse / expand toggle ----------------------------------------- */
.sidebar-toggle {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    padding: 0.625rem 1rem;
    background: none;
    border: none;
    border-top: 1px solid var(--color-border);
    color: var(--sidebar-fg);
    font-family: var(--font-mono);
    font-size: 0.61rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    text-align: left;
    cursor: pointer;
    transition: background-color var(--sidebar-transition);
}

.sidebar-toggle:hover {
    background-color: var(--sidebar-bg-hover);
}

.sidebar.is-collapsed .sidebar-toggle,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-toggle {
    justify-content: center;
    padding: 0.75rem 0.5rem;
}

/* ---- Toggle's two state-spans ---------------------------------------- */
.sidebar.is-collapsed .sidebar-toggle-icon-when-expanded,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-toggle-icon-when-expanded {
    display: none;
}

html:not(.rtd-sidebar-collapsed-preload) .sidebar:not(.is-collapsed) .sidebar-toggle-icon-when-collapsed {
    display: none;
}

/* ---- Universal label hide on collapse --------------------------------
   Single rule that hides every label inside the sidebar when collapsed.
   The toggle button's label and the user's name/email/signout all follow
   this convention via the ``.sidebar-label`` class. The preload-class
   branch keeps labels hidden before first paint when the user's persisted
   state is collapsed.
*/
.sidebar.is-collapsed .sidebar-label,
html.rtd-sidebar-collapsed-preload .sidebar .sidebar-label {
    display: none;
}

/* Smooth opacity fade for labels and logo as they hide / show. */
.sidebar-label,
.sidebar-logo-full,
.sidebar-logo-mark {
    transition: opacity var(--sidebar-transition);
}

/* ---- Icon placeholder slot (Story 9.14 AC 4 contract) ----------------- */
.sidebar-icon-slot {
    width: 16px;
    height: 16px;
    display: inline-block;
    flex-shrink: 0;
}

/* ---- Mobile nav ------------------------------------------ */
/* The ``.mobile-nav`` wrapper (top app bar + scrim + overlay) is hidden by
   default and shown only under the ``@media (max-width: 767px)`` block
   below. The overlay's open/closed state is controlled by the ``[hidden]``
   HTML attribute on the panel + scrim (toggled by ``mobile_nav.js``);
   ``body.mobile-nav-open`` locks page scroll while the overlay is open.

   Distinct class name: the overlay uses ``.mobile-nav-overlay`` — NOT
   ``.sidebar.is-collapsed``. Story 9.17 (and others) rely on
   ``.sidebar.is-collapsed`` as a desktop-only contract; do not repurpose it.

   Palette: all colors come from the existing ``--sidebar-*`` custom
   properties — no new color literals. */
.mobile-nav {
    display: none;
}

@media (max-width: 767px) {
    /* Mobile foundation guard (Story 18.1 UAT fix). Clamps the layout
       viewport to the device width so the sticky top app bar and
       fixed-position overlay actually pin to what the user sees.
       Without this, any descendant of ``<main>`` with a hardcoded width
       (Tailwind ``min-w-[...]`` / ``w-[...]`` utilities, wide tables,
       page-header action rows) makes the body horizontally scrollable;
       the sticky bar then tracks horizontally with that scroll and the
       fixed overlay drifts off the visible viewport.
       This is a temporary belt — Story 18.2's "Responsive Foundation
       — Lists & Tables" pass is what removes the *source* of the
       overflow by collapsing those hardcoded widths. Once 18.2 lands
       this rule becomes a no-op and can stay (defence in depth) or
       be removed. Scoped to ``base.html`` pages because
       ``base_dashboard.html`` (TV / kiosk) does not link this
       stylesheet. */
    html,
    body {
        overflow-x: hidden;
    }

    /* Desktop sidebar stays hidden on mobile; the mobile nav above
       provides primary navigation + sign-out. */
    .sidebar {
        display: none;
    }

    body.has-sidebar {
        flex-direction: column;
    }

    /* Story 18.2 AC #1 — cap <main> at viewport width on mobile.
       In the column-flex body, <main> is a flex item sized cross-axis
       by ``align-items: stretch``. Stretch only sets a LOWER bound
       (item ≥ container cross-axis); it does not cap item width. The
       existing ``min-width: 0`` (above) likewise only allows main to
       shrink, not to be capped. With no upper bound, a wide intrinsic
       child (the canonical case: a ``<table class="min-w-full">`` with
       ``whitespace-nowrap`` cells whose summed column min-content is
       ~830px) propagates up through the auto-width block chain
       (.table-scroll-wrap → section → main) and grows main past the
       viewport. The 18.1 ``overflow-x: hidden`` clamp above hides the
       visual overflow but does not constrain ``<main>``'s computed
       width — verified empirically on /control where main rendered at
       862px on a 360px viewport.

       ``max-width: 100vw`` is the upper bound the cascade was missing.
       It caps main at the viewport, so descendants inherit a
       constrained content area and wide tables actually scroll inside
       their ``.table-scroll-wrap`` parents. AC #1 ("body's width
       equals device viewport width") then holds across every
       ``base.html`` page without per-page patches. */
    body.has-sidebar > main {
        max-width: 100vw;
    }

    .mobile-nav {
        display: block;
    }

    /* Sticky top app bar. ``position: sticky`` (NOT ``fixed``) so the bar
       stays in normal flow and ``<main>`` renders below it — never
       overlapping the page ``<h1>``. Sticky requires the bar to be a flow
       sibling of the scrolling content; ``base.html`` includes this
       partial as a direct child of ``<body>`` before ``<main>`` for that
       reason. */
    .mobile-app-bar {
        position: sticky;
        top: 0;
        z-index: 50;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 0.75rem;
        height: 56px;
        padding: 0 0.75rem;
        background-color: var(--sidebar-bg);
        color: var(--sidebar-fg);
        border-bottom: 1px solid var(--color-border);
    }

    .mobile-nav-menu-button,
    .mobile-nav-close-button {
        /* 44×44 hit target (roadmap D4). */
        display: inline-flex;
        align-items: center;
        justify-content: center;
        min-width: 44px;
        min-height: 44px;
        padding: 0.5rem;
        background: none;
        border: 1px solid transparent;
        color: var(--sidebar-fg);
        cursor: pointer;
        border-radius: 0;
        transition: background-color var(--sidebar-transition);
    }

    .mobile-nav-menu-button:hover,
    .mobile-nav-menu-button:focus-visible,
    .mobile-nav-close-button:hover,
    .mobile-nav-close-button:focus-visible {
        background-color: var(--sidebar-bg-hover);
        outline: none;
    }

    .mobile-nav-menu-button:focus-visible,
    .mobile-nav-close-button:focus-visible {
        outline: 2px solid var(--sidebar-active-bg);
        outline-offset: 2px;
    }

    .mobile-app-bar-brand {
        display: inline-flex;
        align-items: center;
        text-decoration: none;
        padding: 0.25rem 0.5rem;
    }

    .mobile-app-bar-logo {
        min-height: 28px;
    }

    /* The overlay panel itself. Covers the viewport, owns its scroll
       container (``overflow-y: auto``) so the section list + user/sign-
       out block stay reachable on 360×640 with large OS text.

       Sizing rationale (Story 18.1 UAT fix): explicit ``width: 100vw``
       and ``left: 0; top: 0`` (instead of ``inset: 0``) so the overlay's
       containing block can't drift when the underlying page has
       horizontal overflow on iOS Safari / mobile Chrome. ``max-width:
       100vw`` belts-and-braces against any wide descendant escaping the
       overlay. ``height: 100dvh`` (with a 100vh fallback below) avoids
       the iOS toolbar-collapse gap where ``vh`` is computed against the
       largest viewport state and leaves a band of empty space at the
       bottom.

       ``overflow-x: hidden`` lets long user names / a wide ``Sign Out``
       form get clipped or wrap inside the overlay rather than expanding
       the overlay box. */
    .mobile-nav-overlay {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        /* ``left: 0; right: 0`` is what actually pins the overlay to
           the viewport edges. ``width: 100%`` reinforces it via the
           overlay's containing block (the initial containing block for
           ``position: fixed``), which is the device-width layout
           viewport — unlike ``100vw``, which on iOS Safari resolves to
           the layout viewport including any horizontal page overflow
           and was making the overlay open wider than the screen with
           the labels off the left edge (Story 18.1 UAT fix). */
        width: 100%;
        height: 100%;
        height: 100dvh;
        z-index: 70;
        display: flex;
        flex-direction: column;
        background-color: var(--sidebar-bg);
        color: var(--sidebar-fg);
        overflow-y: auto;
        overflow-x: hidden;
        -webkit-overflow-scrolling: touch;
        transform: translateX(-100%);
        transition: transform var(--sidebar-transition);
    }

    .mobile-nav-overlay:not([hidden]) {
        transform: translateX(0);
    }

    /* ``[hidden]`` is the JS-toggled visibility hook; restore the
       overlay's flex layout when visible (the UA stylesheet's
       ``display: none`` for ``[hidden]`` would clobber flex otherwise). */
    .mobile-nav-overlay[hidden] {
        display: none;
    }

    .mobile-nav-overlay__header {
        flex-shrink: 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding: 0.5rem 1rem;
        border-bottom: 1px solid var(--color-border);
    }

    .mobile-nav-overlay__logo-link {
        display: inline-flex;
        align-items: center;
        text-decoration: none;
    }

    .mobile-nav-overlay__logo {
        max-width: 140px;
    }

    /* ``flex-shrink: 0`` (not ``flex: 1 1 auto``) so the nav block sizes
       to its natural content height. The user-info partial below it
       then sits directly under "Coming Soon" rather than being pushed
       to the bottom of the overlay with a stretch-gap above it (Story
       18.1 UAT fix). If total content still exceeds the viewport
       height (large OS text, narrow phone), ``overflow-y: auto`` on
       the overlay reveals the rest. */
    .mobile-nav-overlay__nav {
        flex-shrink: 0;
        padding: 0.25rem 0;
    }

    .mobile-nav-overlay__list {
        list-style: none;
        margin: 0;
        padding: 0;
    }

    .mobile-nav-overlay__item {
        margin: 0;
    }

    .mobile-nav-overlay__group-item {
        margin: 0;
        border-bottom: 1px solid var(--color-border);
    }

    .mobile-nav-overlay__group-summary {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        min-height: 44px;
        padding: 0.625rem 1rem;
        color: var(--nstx-ink-3);
        cursor: pointer;
        font-family: var(--font-mono);
        font-size: 0.61rem;
        font-weight: 700;
        letter-spacing: 0.18em;
        list-style: none;
        text-transform: uppercase;
    }

    .mobile-nav-overlay__group-summary::-webkit-details-marker {
        display: none;
    }

    .mobile-nav-overlay__group-summary::marker {
        content: "";
    }

    .mobile-nav-overlay__group.is-active > .mobile-nav-overlay__group-summary {
        background-color: var(--sidebar-bg-hover);
        color: var(--nstx-ink);
    }

    .mobile-nav-overlay__children {
        list-style: none;
        margin: 0;
        padding: 0 0 0.5rem;
    }

    /* ``min-height: 44px`` preserves the touch-target floor; vertical
       padding trimmed from 0.75rem to 0.4rem so the 11-item list fits
       a 640px-tall viewport alongside the header + user-info block
       (Story 18.1 UAT fix). */
    .mobile-nav-overlay__link {
        display: flex;
        align-items: center;
        gap: 0.75rem;
        min-height: 44px;
        padding: 0.4rem 1rem 0.4rem 1.75rem;
        color: var(--nstx-ink-2);
        font-family: var(--font-mono);
        text-decoration: none;
        font-size: 0.61rem;
        font-weight: 500;
        letter-spacing: 0.18em;
        text-transform: uppercase;
    }

    .mobile-nav-overlay__link:hover,
    .mobile-nav-overlay__link:focus-visible {
        background-color: var(--sidebar-bg-hover);
        outline: none;
    }

    .mobile-nav-overlay__link:focus-visible {
        outline: 2px solid var(--sidebar-active-bg);
        outline-offset: -2px;
    }

    .mobile-nav-overlay__link.is-active {
        background-color: var(--sidebar-active-bg);
        color: var(--sidebar-active-fg);
    }

    .mobile-nav-overlay__link.is-active:hover {
        background-color: var(--sidebar-active-bg);
    }

    .icon-mobile-nav {
        font-size: 24px;
        font-variation-settings: 'opsz' 24, 'wght' 400, 'FILL' 0, 'GRAD' 0;
        line-height: 1;
        vertical-align: middle;
    }

    .mobile-nav-overlay__link.is-active .icon-mobile-nav {
        font-variation-settings: 'opsz' 24, 'wght' 400, 'FILL' 1, 'GRAD' 0;
    }

    /* Reuse of ``partials/sidebar_user_info.html`` inside the overlay:
       the identity/sign-out block renders fully here because
       ``.sidebar.is-collapsed`` is never set on this surface (the
       desktop-collapse rules only fire inside ``.sidebar``). It sits
       directly under the section list with a top border + comfortable
       padding so the Sign Out button stays reachable; the prior
       ``margin-top: auto`` was removed so it doesn't get pushed to the
       bottom of the viewport with an empty gap above (Story 18.1 UAT
       fix). */
    .mobile-nav-overlay .sidebar-user {
        padding: 0.75rem 1rem 1rem;
        border-top: 1px solid var(--color-border);
        flex-shrink: 0;
    }
}

/* Body scroll lock while the overlay is open. Applied to ``<body>`` by
   ``mobile_nav.js``; lives outside the mobile media query so the lock
   stays in effect even if the viewport is rotated to landscape while the
   overlay is open. */
body.mobile-nav-open {
    overflow: hidden;
}
