/* Shared .doc-toc styles — used by documentation pages and lesson ToC. */
/* ─────────────────────────────────────────
    STICKY TABLE OF CONTENTS (doc-toc.js)
    Sits in the same rail the old docs-switcher used to occupy on desktop
    (opposite side from the app sidebar), collapses to a floating toggle +
    slide-up panel on phones.
───────────────────────────────────────── */
.doc-toc {
    position: fixed;
    z-index: var(--z-above, 10);
    top: 50%;
    left: 28px;
    width: 200px;
    max-height: 70vh;
    overflow-y: auto;
    padding: 14px 10px;
    transform: translateY(-50%);
    background: var(--bg, var(--color-surface, #fff));
    border: 1px solid var(--rule-heavy, var(--color-border, #e5e7eb));
    border-left: 3px solid var(--accent, var(--color-primary, #6366f1));
    border-radius: var(--radius, 14px);
    box-shadow: var(--shadow-sm, 0 8px 24px rgb(0 0 0 / .12));
}

.doc-toc-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 0 8px 10px;
    color: var(--ink-muted, var(--color-text-secondary, #64748b));
    font-size: .68rem;
    font-weight: 600;
    letter-spacing: .08em;
}

.doc-toc-heading-label {
  unicode-bidi: plaintext; /* truncate by the text's own direction */
  text-align: start;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Desktop-only minimize toggle — slides the fixed, vertically-centered
   panel almost entirely off the left edge of the screen so it stops
   sitting on top of the reading column, while leaving a thin sliver (with
   the heading row) visible as a handle to pull it back. Hidden on phones,
   which already collapse the whole ToC behind the floating .doc-toc-toggle
   button instead. */
.doc-toc-minimize-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    padding: 0;
    color: var(--ink-muted, var(--color-text-secondary, #64748b));
    background: none;
    border: none;
    border-radius: var(--radius-sm, 8px);
    cursor: pointer;
    transition: background-color .15s ease, color .15s ease, transform .2s ease;
}

.doc-toc-minimize-btn:hover,
.doc-toc-minimize-btn:focus-visible {
    color: var(--accent, var(--color-primary, #6366f1));
    background: var(--bg-tint, var(--color-surface-hover, rgb(127 127 127 / .08)));
}

/* Chevron points left when expanded (slides left/off-screen on click) and
   flips to point right once minimized (click would slide it back in). RTL
   page, but the panel's own slide direction is a fixed screen-edge
   (left), not a logical/direction-relative one, so the icon and the
   transform below both use physical left/right rather than
   start/end. */
.doc-toc-minimized .doc-toc-minimize-btn {
    transform: rotate(180deg);
}

.doc-toc-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.doc-toc-link {
    display: block;
    padding: 7px 8px;
    color: var(--ink-soft, var(--color-text-secondary, #64748b));
    border-radius: var(--radius-sm, 8px);
    font-size: .82rem;
    line-height: 1.35;
    text-decoration: none;
    transition: background-color .15s ease, color .15s ease;
}

.doc-toc-link:hover,
.doc-toc-link:focus-visible {
    color: var(--accent, var(--color-primary, #6366f1));
    background: var(--bg-tint, var(--color-surface-hover, rgb(127 127 127 / .08)));
}

.doc-toc-link--active {
    color: var(--bg, var(--color-surface, #fff));
    background: var(--ink, var(--color-text-primary, #111827));
    font-weight: 600;
}

.doc-toc-link--active:hover {
    color: var(--bg, var(--color-surface, #fff));
    background: var(--accent-mid, var(--color-primary-hover, #4f46e5));
}

.doc-toc-toggle {
    display: none;
    align-items: center;
    gap: 6px;
    position: fixed;
    z-index: var(--z-overlay, 4000);
    bottom: calc(var(--bottom-nav-height, 54px) + 16px + env(safe-area-inset-bottom));
    left: 16px;
    padding: 9px 14px;
    background: var(--accent, var(--color-primary, #6366f1));
    color: var(--bg, var(--color-surface, #fff));
    border: none;
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 600;
    box-shadow: 0 6px 18px rgba(17, 24, 39, .2);
    cursor: pointer;
}

/* ─────────────────────────────────────────
    DESKTOP — minimized ToC slides almost fully off the left edge of the
    screen instead of shrinking in place, so it's unambiguous where it
    went and how to get it back. A thin strip (matching the panel's own
    left border-radius) stays visible as a handle; clicking anywhere on
    that visible strip (see doc-toc.js's click handler) slides it back.
    Scoped to the desktop breakpoint only; on phones the ToC is already
    collapsed by default behind .doc-toc-toggle and this class doesn't
    apply there (see the mobile media query further down, which resets it).
───────────────────────────────────────── */
@media (min-width: 769px) {
    .doc-toc {
        transition: transform .25s cubic-bezier(0.4, 0, 0.2, 1);
    }

    .doc-toc.doc-toc-minimized {
        /* Shift left by the panel's own width, minus a fixed sliver kept
           on-screen as the visible grab handle. calc() (rather than a
           fixed translateX) keeps this correct regardless of how wide the
           panel ends up (e.g. a longer heading than usual). */
        transform: translateY(-50%) translateX(calc(-1 * (110%)));
        cursor: pointer;
        /* The panel's normal "spine" accent is on its left edge, which is
           exactly the part that's now off-screen — move it to the right
           edge instead so the sliver that's actually visible still reads
           as "part of a panel, click to pull it back" rather than a bare
           unmarked sliver. */
        border-left: 1px solid var(--rule-heavy, var(--color-border, #e5e7eb));
        border-right: 3px solid var(--accent, var(--color-primary, #6366f1));
    }

    .doc-toc.doc-toc-minimized:hover {
        /* A small nudge back toward the reading column on hover signals
           "this is interactive" before the user even clicks, same idea as
           a drawer handle that peeks out further when you mouse over it. */
        transform: translateY(-50%) translateX(calc(-1 * (105%)));
    }

    .doc-toc.doc-toc-minimized .doc-toc-heading {
        justify-content: flex-end;
        padding: 0;
    }
}

/* ─────────────────────────────────────────
    MOBILE — ToC becomes a floating toggle + slide-up panel
───────────────────────────────────────── */
@media (max-width: 768px) {
    .doc-toc {
        top: auto;
        left: 0;
        right: 0;
        /* Sits just above the bottom nav (same offset the toggle button already
     * uses) instead of bottom: 0 — flush-to-bottom put the panel's own
     * content, including its last list item, underneath/behind the fixed
     * bottom-nav bar since both are fixed-position with the panel painted
     * first. Anchoring here means the whole scrollable list — including the
     * final entry — stays above the nav instead of sliding behind it. */
        bottom: calc(var(--bottom-nav-height, 54px) + env(safe-area-inset-bottom));
        width: 100%;
        max-height: 60vh;
        transform: translateY(100%);
        border-left: none;
        border-top: 3px solid var(--accent);
        border-radius: 14px 14px 0 0;
        box-shadow: 0 -6px 20px rgba(17, 24, 39, .15);
        transition: transform .2s ease;
        z-index: calc(var(--z-overlay, 4000) - 1);
        /* The fixed .doc-toc-toggle is painted ABOVE this panel and sits over
         * its bottom-left corner (same bottom offset), so it covered the last
         * list item(s). Reserve room for it (button height ≈ 40px + its 16px
         * offset) so the list can always scroll clear of the button. */
        padding-bottom: 72px;
        scroll-padding-bottom: 72px;
    }

    .doc-toc.doc-toc-open {
        transform: translateY(0);
    }

    .doc-toc-toggle {
        display: inline-flex;
    }

    /* Mobile already collapses the whole panel behind .doc-toc-toggle —
       the in-panel minimize control is desktop-only, so hide it here to
       avoid a second, redundant collapse affordance once the slide-up
       panel is open. */
    .doc-toc-minimize-btn {
        display: none;
    }
}