/* ============================================================
   vocab.css — Vocabulary mode styles.

   All UI that lives under body.vocab-active or related session
   classes. Extracted from main.css during the vocab module
   cleanup. Pairs with js/vocab-study.js + js/vocab-srs.js.

   Section order:
     - Vocab mode foundation (toggle button, list, details panel)
     - Search bar
     - "+" Add-to-Deck buttons
     - Add-to-Deck popover
     - Center column swap (canvas ↔ decks panel)
     - Study session (canvas crop, answer field, complete cue,
       ratings, footer)
     - Deck-detail tabs (Cards / Schedule / Settings)
     - Per-deck SRS schedule panel
     - SRS parameters tab pane
   ============================================================ */

/* Theme-swap guard — set by the theme toggle handler in index.html
   while flipping body.dark. Disabling every transition for one frame
   prevents the cascade of background/color/border animations across
   the 6,000+ vocab DOM nodes that otherwise makes theme changes
   visibly "wave" across the page. */
body.theme-switching,
body.theme-switching *,
body.theme-switching *::before,
body.theme-switching *::after {
    transition: none !important;
    animation: none !important;
}

/* ── Vocabulary mode ───────────────────────────────────────────────
   Toggled by the Vocabulary button in toolbar-left. When active, the
   left column hides its kana grid and shows a scrollable vocabulary
   library populated from data/vocabulary.json (lazy-loaded). Middle
   and right columns are deliberately left untouched in this first
   slice — clicking a vocab item does nothing yet.                  */
/* Vocabulary toggle — when active, mirror the Trace/Recall accent
   highlight so the user has a single, unambiguous "you are here"
   indicator in the toolbar. */
.vocab-trigger.active {
    background: transparent;
    color: var(--accent);
    border: 1.5px solid var(--accent);
    font-weight: 700;
}
@media (hover: hover) {
    .vocab-trigger.active:hover {
        background: var(--accent-bg);
        color: var(--accent);
        border-color: var(--accent);
    }
}

/* While vocab mode is active, demote the canvas-side Trace/Recall
   highlight — the user isn't in either kana mode right now. The
   buttons remain clickable; clicking either also exits vocab mode
   (see traceBtn / studyBtn handlers in index.html). */
body.vocab-active .mode-toggle-btn.active {
    background: transparent;
    color: var(--text-muted);
    border: var(--dash-soft);
    font-weight: 600;
}

/* Default state: list hidden so the existing grid + subheaders show
   exactly as they did before this feature existed. */
.vocab-list { display: none; }

body.vocab-active #char-grid,
body.vocab-active .grid-subcol-headers {
    display: none;
}
body.vocab-active .vocab-list {
    display: block;
}

.vocab-list {
    /* Inherits scrolling from the parent .panel-body. Just a vertical
       stack of items. */
    padding: 2px 0;
}

.vocab-item {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 8px 12px;
    border-radius: 6px;
    border: 1px solid transparent;
    cursor: pointer;
    line-height: 1.2;
    transition: background 0.12s, border-color 0.12s;
    /* Fixed height — the JS virtualizer uses 56px to compute the
       window slice and spacer heights. Don't change this without
       updating VOCAB_ROW_HEIGHT in vocab-study.js. overflow:hidden
       guards against rare long meanings forcing a second line. */
    height: 56px;
    box-sizing: border-box;
    overflow: hidden;
    flex-shrink: 0;
}

/* Spacer divs above + below the rendered window keep the scrollbar
   sized as if every row were in the DOM, so scroll position +
   thumb size match a fully-rendered list. */
.vocab-list-spacer {
    flex-shrink: 0;
    pointer-events: none;
}

/* In vocab mode the list itself owns the scroll (instead of the
   panel-body wrapper) so the virtualizer can read a stable
   scrollTop and the spacer math stays simple. */
body.vocab-active .col-left .panel-body {
    overflow: hidden;
    padding: 0;
    display: flex;
    flex-direction: column;
}

body.vocab-active .vocab-list {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
}

/* Mobile: cols-row switches to display:block, breaking the flex chain
   that gives .vocab-list its desktop height. flex:1 1 0 inside a
   content-driven parent collapses to 0, so the virtualizer renders
   rows into a 0-height clipped container — the column looks empty.
   Give it a concrete height so the virtualizer's clientHeight is real. */
@media (max-width: 900px) {
    body.vocab-active .vocab-list {
        flex: none;
        height: 60vh;
    }
}

.vocab-item.selected {
    background: var(--accent-bg);
    border-color: var(--accent);
}

@media (hover: hover) {
    .vocab-item:hover {
        background: var(--accent-bg);
        border-color: var(--subtle-border);
    }
}

.vocab-word {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text);
}

.vocab-sub {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 0.78rem;
    color: var(--text-faint);
    margin-top: 2px;
}

.vocab-error {
    padding: 16px;
    color: var(--text-faint);
    font-size: 0.85rem;
    font-style: italic;
    text-align: center;
}

/* Right-panel swap — Character Details ↔ Vocabulary Details.
   The vocab panel is hidden by default and only appears when the
   user has Vocabulary mode toggled on. Both panels share the
   .char-details-panel base so spacing matches between them. */
.vocab-details-panel {
    display: none;
}

body.vocab-active #char-details {
    display: none;
}

body.vocab-active .vocab-details-panel {
    display: block;
}

/* panels.js sets .col-right .panel-box to `flex:0 1 auto` so it
   auto-sizes to its content — that worked when the panel only held
   a small character-details card, but vocab conjugation tables
   easily exceed col-center's locked height and stretch the cols-row.
   In vocab mode we flip the panel-box to fill the column instead,
   and rely on panel-body's existing overflow-y:auto to scroll. */
body.vocab-active .col-right .panel-box {
    flex: 1 1 0;
    min-height: 0;
    max-height: none;
}

body.vocab-active .col-right .panel-body {
    min-height: 0;
}

/* Mirror of the .vocab-list mobile fix: on mobile, cols-row is
   display:block so flex:1 1 0 collapses the panel-box to 0 height,
   hiding the details that were rendered into it. */
@media (max-width: 900px) {
    body.vocab-active .col-right .panel-box {
        flex: none;
        height: 60vh;
    }
}

.vocab-detail-headword {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 2.4rem;
    font-weight: 600;
    text-align: center;
    color: var(--text);
    margin-top: 12px;
    line-height: 1.1;
    word-break: break-word;
}

.vocab-detail-reading {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 1.1rem;
    text-align: center;
    color: var(--text-faint);
    margin-top: 6px;
}

.vocab-detail-romaji {
    font-size: 0.9rem;
    text-align: center;
    color: var(--text-faint);
    margin-top: 2px;
    font-style: italic;
}

.vocab-detail-meaning {
    font-size: 1rem;
    text-align: center;
    color: var(--text);
    margin: 14px 8px 4px 8px;
    line-height: 1.4;
}

.vocab-details-empty {
    padding: 24px 12px;
    color: var(--text-faint);
    font-size: 0.9rem;
    font-style: italic;
    text-align: center;
}

.vocab-detail-row {
    margin-top: 12px;
}

/* ── Search bar (left column, vocab mode) ─────────────────────────── */
.vocab-search-wrap {
    display: none;
    padding: 8px 4px 6px;
}

body.vocab-active .vocab-search-wrap {
    display: block;
}

.vocab-search-input {
    width: 100%;
    box-sizing: border-box;
    padding: 7px 12px;
    border: 1px solid var(--subtle-border);
    border-radius: 8px;
    background: var(--bg-card, transparent);
    color: var(--text);
    font-size: 0.9rem;
    font-family: inherit;
    outline: none;
    transition: border-color 0.15s;
}

.vocab-search-input:focus {
    border-color: var(--accent);
}

.vocab-search-input::placeholder {
    color: var(--text-faint);
}

/* Hide vocab items that don't match the current search term. */
.vocab-item.vocab-hidden {
    display: none;
}

.vocab-no-results {
    padding: 18px 12px;
    text-align: center;
    color: var(--text-faint);
    font-size: 0.85rem;
    font-style: italic;
}

/* ── "+" Add-to-Deck button on each .vocab-item ───────────────────── */
.vocab-item {
    position: relative;
    padding-right: 36px; /* room for the + button */
}

.vocab-add-btn {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    opacity: 0;
    transition: opacity 0.12s, background 0.12s, color 0.12s, border-color 0.12s;
}

.vocab-item:hover .vocab-add-btn,
.vocab-item.selected .vocab-add-btn,
.vocab-add-btn.in-deck,
.vocab-add-btn:focus-visible {
    opacity: 1;
}

.vocab-add-btn:hover {
    background: var(--accent-bg);
    border-color: var(--accent);
    color: var(--accent);
}

.vocab-add-btn.in-deck {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

/* "+ Add to Deck" pill inside the right details panel. Mirrors the
   toolbar mode buttons (Trace / Recall / Exercise / New Folder / New
   Deck) — dashed soft outline at rest, solid accent on hover. The
   .in-deck state borrows the .mode-toggle-btn.active look so "already
   added" reads as the selected/locked-in state. */
.vocab-detail-add-btn {
    position: static;
    width: auto;
    height: auto;
    transform: none;
    opacity: 1;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 18px auto 0;
    padding: 7px 16px;
    border: var(--dash-soft);
    border-radius: 8px;
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
    cursor: pointer;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}

@media (hover: hover) {
    .vocab-detail-add-btn:hover {
        border: 1.5px solid var(--accent);
        color: var(--accent);
        background: var(--accent-bg);
    }
}

.vocab-detail-add-btn.in-deck {
    border: 1.5px solid var(--accent);
    color: var(--accent);
    background: transparent;
    font-weight: 700;
}

@media (hover: hover) {
    .vocab-detail-add-btn.in-deck:hover {
        background: var(--accent-bg);
        border-color: var(--accent);
        color: var(--accent);
    }
}

.vocab-deck-plus {
    font-weight: 600;
    font-size: 1.05em;
    line-height: 1;
}

/* ── Conjugation table (Vocabulary Details) ───────────────────────── */
.vocab-conj {
    margin-top: 22px;
    padding-top: 14px;
    border-top: 1px dashed var(--subtle-border);
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.vocab-conj-block { display: flex; flex-direction: column; }

.vocab-conj-title {
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
    padding: 0 4px;
}

.vocab-conj-rows {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* 3-column grid: label | kanji form | reading. When the dictionary
   entry is kana-only, the row gets .no-kanji and the grid collapses
   to two columns so the reading doesn't float in the middle. */
.vocab-conj-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr) minmax(0, 1fr);
    gap: 10px;
    align-items: baseline;
    padding: 4px 6px;
    font-size: 0.85rem;
    border-radius: 4px;
}

.vocab-conj-row.no-kanji {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
}

.vocab-conj-row:hover {
    background: var(--accent-bg);
}

.vocab-conj-label {
    color: var(--text-faint);
    font-size: 0.78rem;
    font-weight: 600;
}

.vocab-conj-kanji {
    font-family: 'Noto Sans JP', sans-serif;
    color: var(--text);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vocab-conj-reading {
    font-family: 'Noto Sans JP', sans-serif;
    color: var(--text-faint);
    font-size: 0.8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Add-to-Deck popover ──────────────────────────────────────────── */
.vocab-add-popover {
    position: fixed;
    z-index: 9000;
    width: 240px;
    background: var(--bg-card, #fff);
    border: 1px solid var(--subtle-border);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    padding: 8px;
    font-size: 0.9rem;
}

body.dark .vocab-add-popover {
    background: var(--bg-card, #2a2a2c);
}

.vocab-pop-title {
    font-weight: 600;
    color: var(--text-faint);
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 4px 8px 6px;
}

.vocab-pop-decks {
    max-height: 200px;
    overflow-y: auto;
    margin-bottom: 4px;
}

.vocab-pop-deck {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 7px 10px;
    border: none;
    background: transparent;
    color: var(--text);
    text-align: left;
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
}

.vocab-pop-deck:hover:not(:disabled) {
    background: var(--accent-bg);
}

.vocab-pop-deck:disabled {
    cursor: default;
    color: var(--text-faint);
}

.vocab-pop-deck-check {
    color: var(--accent);
    font-weight: 600;
}

/* Popover folder row — collapsible group inside the picker. Mirrors
   the main folder-row pattern (chevron rotates on expand, nested
   decks indented under a left rail) but smaller and without the
   selection/hover affordances since the popover is a one-off pick. */
.vocab-pop-folder {
    display: flex;
    flex-direction: column;
}

.vocab-pop-folder-row {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 6px 10px;
    border: none;
    background: transparent;
    color: var(--text);
    text-align: left;
    border-radius: 6px;
    cursor: pointer;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
}

.vocab-pop-folder-row:hover {
    background: var(--accent-bg);
    color: var(--accent);
}

.vocab-pop-folder-chevron {
    display: inline-block;
    width: 0.9em;
    color: var(--text-faint);
    transition: transform 0.15s ease;
    font-size: 0.75rem;
    line-height: 1;
}

.vocab-pop-folder.is-expanded > .vocab-pop-folder-row .vocab-pop-folder-chevron {
    transform: rotate(90deg);
    color: var(--accent);
}

.vocab-pop-folder-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vocab-pop-folder-count {
    color: var(--text-faint);
    font-size: 0.78rem;
    font-weight: 500;
}

.vocab-pop-folder-decks {
    display: none;
    flex-direction: column;
    padding: 2px 0 4px 12px;
    margin-left: 10px;
    border-left: 2px solid var(--subtle-border);
}

.vocab-pop-folder.is-expanded > .vocab-pop-folder-decks {
    display: flex;
}

.vocab-pop-new {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 8px 10px;
    border: 1px dashed var(--subtle-border);
    border-radius: 6px;
    background: transparent;
    color: var(--accent);
    cursor: pointer;
    font: inherit;
}

.vocab-pop-new:hover {
    background: var(--accent-bg);
    border-color: var(--accent);
}

/* ── Center column swap: canvas ↔ vocab decks ─────────────────────── */
.vocab-decks-panel {
    display: none;
    flex-direction: column;
    /* Fill remaining height inside the fixed col-center, but allow
       shrinking so internal overflow scrollers actually kick in.
       Without `min-height: 0`, flex children refuse to shrink below
       their content size — letting the column expand past col-center. */
    flex: 1 1 0;
    min-height: 0;
    /* Top padding matches .vocab-search-wrap's padding-top so the
       center column's first content (tabs / toolbar) sits on the same
       baseline as the left column's search input. Bottom padding kept
       tight so the Study button hugs the column edge. */
    padding: 8px 16px 8px;
    box-sizing: border-box;
    overflow: hidden;
}

body.vocab-active .vocab-decks-panel {
    display: flex;
}

/* Mobile: cols-row stacks (display:block) and .col-center no longer
   carries the 660px floor, so flex:1 1 0 inside content-driven parent
   collapses to 0. Give the panel a concrete height — mirrors the
   .vocab-list and .col-right .panel-box mobile fixes.

   Scoped to NOT include the study-session state: the session view's
   `margin-top: auto` (see .vocab-study-ratings) pushes the rating
   buttons to the bottom of the panel, so a fixed 60vh would create
   dead space between the answer field and the buttons. Sessions
   size to content instead. */
@media (max-width: 900px) {
    body.vocab-active:not(.vocab-study-session) .vocab-decks-panel {
        flex: none;
        height: 60vh;
    }
    /* In study session, let the panel + its inner pane size to content
       so the meaning/answer/complete/ratings stack visibly under the
       canvas. overflow:visible defeats the clip that would otherwise
       hide the bottom widget when the flex chain collapses to 0. */
    body.vocab-active.vocab-study-session .vocab-decks-panel,
    body.vocab-active.vocab-study-session #vocab-study-session {
        flex: 0 0 auto;
        height: auto;
        min-height: 0;
        overflow: visible;
    }
}

/* Sub-views inside the decks panel — each fills the panel and lets a
   single inner section scroll. Non-flex element default is block, but
   we need flex+min-height:0 so descendant overflow scrollers actually
   constrain. The [hidden] override beats these (higher specificity)
   so toggling hidden still removes the view from layout. */
#vocab-decks-list-view,
#vocab-deck-detail-view,
#vocab-study-session {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-height: 0;
}

#vocab-decks-list-view[hidden],
#vocab-deck-detail-view[hidden],
#vocab-study-session[hidden] {
    display: none;
}

/* Inside list-view: toolbar at top, the decks list itself scrolls. */
#vocab-decks-list-view .vocab-decks-toolbar { flex: 0 0 auto; }
#vocab-decks-list-view .vocab-decks-list {
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
}

/* Inside deck-detail-view: tab strip pinned at top, Study button
   pinned at the bottom; the active tab pane fills the space between
   them and scrolls. */
#vocab-deck-detail-view .vocab-deck-tabs,
#vocab-deck-detail-view .vocab-deck-study-btn { flex: 0 0 auto; }

/* Hide the writing-canvas chrome when vocab mode is on. */
body.vocab-active .col-center .mode-tagline,
body.vocab-active .col-center .card-wrapper,
body.vocab-active .col-center .carousel-info-panel,
body.vocab-active .col-center .canvas-action-slot {
    display: none;
}

/* In canvas mode .col-center has 30px top/bottom padding for the
   "breathing room around the writing card" rhythm. Vocab mode has its
   own panel chrome with internal padding, so the col-center padding
   would push tabs ~30px below the left column's search bar and shove
   the Study button past the column edge. Zero it for the entire vocab
   mode — applying it during study session caused the body content to
   shift by ~30px when the session started, which on viewports tight
   enough to require scrolling visually "crunched" the site header
   against the URL bar. The canvas inside a session has its own
   margin-top so it still gets breathing room. */
body.vocab-active .col-center {
    padding-top: 0;
    padding-bottom: 0;
}

.vocab-decks-toolbar {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    margin-bottom: 12px;
    flex-wrap: wrap;
}

/* Mirrors .mode-toggle-btn (Trace / Recall / Exercise) — dashed soft
   outline at rest, solid accent border + accent-bg on hover. Keeps
   the toolbar's outline-first visual language consistent across
   modes. Both "+ New Folder" and "+ New Deck" share the treatment. */
.vocab-deck-new-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 16px;
    border: var(--dash-soft);
    background: transparent;
    color: var(--text-muted);
    border-radius: 8px;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    cursor: pointer;
    white-space: nowrap;
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}

@media (hover: hover) {
    .vocab-deck-new-btn:hover {
        border: 1.5px solid var(--accent);
        color: var(--accent);
        background: var(--accent-bg);
    }
}

.vocab-decks-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.vocab-deck-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 6px 10px;
    border: 1px solid transparent;
    color: var(--text);
    border-radius: 6px;
    cursor: pointer;
    text-align: left;
    font: inherit;
    transition: color 0.12s, background-position 0.3s ease;
    /* Progress meter — a soft accent-bg fill stretching from the left
       edge to --vocab-progress (set inline per row). Pure-gradient so
       the row can still react to hover via color without disturbing
       the fill. Cards "banked" in the future fill the bar; due/new
       cards leave it empty. */
    background-image: linear-gradient(
        to right,
        var(--accent-bg) 0%,
        var(--accent-bg) var(--vocab-progress, 0%),
        transparent var(--vocab-progress, 0%)
    );
}

.vocab-deck-row:hover {
    color: var(--accent);
}

.vocab-deck-row:focus-visible,
.vocab-folder-row:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

.vocab-deck-name {
    font-weight: 400;
    font-size: 0.95rem;
}

.vocab-deck-count {
    color: var(--text-faint);
    font-size: 0.85rem;
}

/* ── Folder rows ───────────────────────────────────────────────────
   A folder wraps a header (.vocab-folder-row) plus a collapsible
   container of nested deck rows (.vocab-folder-decks). The header
   matches the deck row's visual rhythm so the list reads as one
   coherent column; the chevron + slightly heavier weight signal
   "this is a group". */
.vocab-folder {
    display: flex;
    flex-direction: column;
}

.vocab-folder-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--subtle-border);
    background: var(--bg-card, transparent);
    color: var(--text);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color 0.12s, background 0.12s;
    user-select: none;
}

.vocab-folder-row:hover {
    border-color: var(--accent);
    background: var(--accent-bg);
}

.vocab-folder-chevron {
    display: inline-block;
    width: 1em;
    color: var(--text-faint);
    transition: transform 0.15s ease;
    font-size: 0.85rem;
    line-height: 1;
}

.vocab-folder.is-expanded > .vocab-folder-row .vocab-folder-chevron {
    transform: rotate(90deg);
    color: var(--accent);
}

/* Selected folder — the next "+ New Deck" lands here. Accent border +
   subtle accent-bg distinguishes it from a merely expanded folder. */
.vocab-folder.is-selected > .vocab-folder-row {
    border-color: var(--accent);
    background: var(--accent-bg);
    color: var(--accent);
}

.vocab-folder.is-selected > .vocab-folder-row .vocab-folder-name {
    color: var(--accent);
}

.vocab-folder-name {
    flex: 1;
    font-weight: 700;
    font-size: 1rem;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.vocab-folder-count {
    color: var(--text-faint);
    font-size: 0.85rem;
    flex-shrink: 0;
}

/* Rename / delete icons — hidden until the row is hovered or focused
   within. Matches the .vocab-add-btn opacity-reveal pattern so the
   default state stays clean. */
.vocab-folder-actions {
    display: inline-flex;
    gap: 4px;
    flex-shrink: 0;
    opacity: 0;
    transition: opacity 0.12s;
}

.vocab-folder-row:hover .vocab-folder-actions,
.vocab-folder-row:focus-within .vocab-folder-actions {
    opacity: 1;
}

.vocab-folder-action {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    font-size: 0.8rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.vocab-folder-action:hover {
    border-color: var(--accent);
    color: var(--accent);
    background: var(--accent-bg);
}

.vocab-folder-action-danger:hover {
    border-color: #b32a2a;
    color: #b32a2a;
    background: transparent;
}

/* Collapsible body — nested decks are indented and visually parented
   to the folder via a left rail. Collapsed by default; the folder
   itself adds .is-expanded when its open. */
.vocab-folder-decks {
    display: none;
    flex-direction: column;
    gap: 2px;
    padding: 4px 0 4px 14px;
    margin-left: 12px;
    border-left: 2px solid var(--subtle-border);
}

.vocab-folder.is-expanded > .vocab-folder-decks {
    display: flex;
}

/* Empty folder, expanded: hide the rail so the column doesn't show a
   dangling indent stub. The folder header still shows "0 decks" so
   the empty state is communicated without the visual artifact. */
.vocab-folder.is-expanded > .vocab-folder-decks:empty {
    display: none;
}

/* Drag-and-drop: source row dims, folder rows highlight when a deck
   is hovered over them. body.vocab-deck-dragging signals to other
   surfaces that a drag is in progress. */
.vocab-deck-row {
    user-select: none;
}

.vocab-deck-row.is-dragging {
    opacity: 0.4;
}

.vocab-folder-row.is-drag-over {
    border-color: var(--accent);
    background: var(--accent-bg);
    box-shadow: 0 0 0 2px var(--accent-bg);
}

body.vocab-deck-dragging .vocab-folder-row {
    border-style: dashed;
}

.vocab-no-decks,
.vocab-empty-deck {
    padding: 28px 16px;
    color: var(--text-faint);
    font-size: 0.9rem;
    font-style: italic;
    text-align: center;
    border: 1px dashed var(--subtle-border);
    border-radius: 10px;
}

/* Deck detail view — the panel header element was removed (deck title
   moved to the column eyebrow, Back button moved into the tab strip).
   The Back button keeps its pill styling because it now sits next to
   the tab labels and needs a visual peer-relationship with them. */
.vocab-deck-back-btn {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    border-radius: 14px;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.vocab-deck-back-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
}


.vocab-deck-action {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    font-size: 0.85rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
}

.vocab-deck-action:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.vocab-deck-action-danger:hover {
    border-color: #b32a2a;
    color: #b32a2a;
}

/* The deck-actions dropdown lives next to the center column eyebrow
   (alongside the pen dropdown), but should only appear when the user
   is in vocab mode AND has a specific deck open. main.css hides
   .col-options-dropdown globally in vocab mode — re-show this one
   only when body.vocab-deck-open is also set. */
.vocab-deck-actions-dropdown {
    display: none;
}

body.vocab-active.vocab-deck-open .vocab-deck-actions-dropdown {
    display: inline-flex;
}

/* Inside a running study session, deck-root operations (Move /
   Rename / Delete) aren't relevant — the user is mid-card. Swap the
   caret out for the Pen options dropdown so they can tweak stroke
   color / tolerance / particles without leaving the session, matching
   the Trace-mode UX. */
body.vocab-active.vocab-deck-open.vocab-study-session .vocab-deck-actions-dropdown {
    display: none;
}

body.vocab-active.vocab-study-session #pen-dropdown {
    display: inline-flex;
}

/* Stroke guides aren't applicable in a vocab study session — hide
   that one toggle inside the pen panel. Color / tolerance / particle
   / haptic stay. */
body.vocab-active.vocab-study-session #guides-toggle-btn {
    display: none;
}

/* Deck-actions dropdown panel — menu items styled to match the
   col-options-panel container provided by main.css. Each row holds an
   icon + label and reacts to hover with the accent. The Delete item
   gets a red hover so destructive intent is unambiguous. */
.vocab-deck-actions-panel .view-option {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 12px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}

@media (hover: hover) {
    .vocab-deck-actions-panel .view-option:hover {
        background: var(--accent-bg);
        color: var(--accent);
        border-color: var(--accent);
    }
    .vocab-deck-actions-panel .view-option-danger:hover {
        background: transparent;
        color: #b32a2a;
        border-color: #b32a2a;
    }
}

.vocab-deck-actions-panel .view-option-icon {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    font-size: 0.95rem;
}

.vocab-deck-actions-panel .view-option-label {
    flex: 1;
}

.vocab-deck-study-btn {
    width: 100%;
    padding: 10px;
    margin-top: 14px;
    margin-bottom: 8px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
    border-radius: 10px;
    font: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.12s;
}

.vocab-deck-study-btn:disabled {
    background: var(--text-faint);
    border-color: var(--text-faint);
    cursor: not-allowed;
    opacity: 0.7;
}

.vocab-deck-cards {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.vocab-deck-card {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border: 1px solid var(--subtle-border);
    border-radius: 8px;
    background: var(--bg-card, transparent);
    cursor: pointer;
}

.vocab-deck-card.selected {
    background: var(--accent-bg);
    border-color: var(--accent);
}

.vocab-deck-card-text {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.vocab-deck-card-kana {
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 1rem;
    color: var(--text);
}

.vocab-deck-card-meaning {
    font-size: 0.78rem;
    color: var(--text-faint);
    margin-top: 2px;
}

.vocab-deck-card-remove {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1px solid transparent;
    background: transparent;
    color: var(--text-faint);
    font-size: 1.05rem;
    line-height: 1;
    cursor: pointer;
    flex-shrink: 0;
}

.vocab-deck-card-remove:hover {
    border-color: var(--accent);
    color: var(--accent);
}

/* ── Study session — canvas + answer field ─────────────────────────
   When a study session is active, un-hide the canvas (.card-wrapper)
   that vocab mode normally hides. The mode-tagline + info panel +
   action slot stay hidden so the column reads: canvas → meaning →
   answer field → progress + exit. */
/* col-center needs a positioning context so the floated Exit Session
   button can pin to its top-right corner. */
body.vocab-active.vocab-study-session .col-center {
    position: relative;
}

/* Exit Session pinned to the top-right corner; Card-X-of-Y progress
   pinned to the top-left corner. Both sit above the canvas, in the
   same horizontal band, framing the session header. The original DOM
   stays in the footer — these rules lift them visually only. */
body.vocab-active.vocab-study-session .vocab-study-exit-btn {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 10;
}

body.vocab-active.vocab-study-session .vocab-study-progress {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 10;
    /* Match the visual weight of the Exit Session button's caption
       so they read as a pair across the top of the column. */
    line-height: 1.6;
}

/* Footer is now empty during a session — both its children (progress
   text + Exit Session button) are absolutely positioned to the top
   corners. Collapse it to zero vertical impact without using
   `display: none` (which would hide its position-absolute children
   along with it). */
body.vocab-active.vocab-study-session .vocab-study-footer {
    border-top: none;
    margin: 0;
    padding: 0;
    min-height: 0;
}

body.vocab-active.vocab-study-session .col-center .card-wrapper {
    display: flex;
    /* Cap the canvas so it doesn't eat the column. Normal Trace/Recall
       mode uses flex:1 to fill the whole column; vocab study needs to
       leave room beneath for the meaning prompt, answer field, and
       rating buttons. Top margin pushes the canvas down from the
       column-eyebrow + label band so it reads as visually centered
       above the content group rather than hugging the top edge. */
    flex: 0 0 auto;
    width: 320px;
    max-width: 320px;
    height: 320px;
    margin: 80px auto 0;
    padding: 0;
    gap: 0;
}

/* Mobile: the desktop 80px top margin + 320px canvas push the
   meaning / answer / ratings off-screen on a phone viewport. Tighten
   both — the absolute-positioned header (CARD X OF Y / EXIT SESSION)
   only needs ~14px of clearance, and 260px keeps the trace area
   finger-friendly while saving ~60px of vertical space. */
@media (max-width: 900px) {
    body.vocab-active.vocab-study-session .col-center .card-wrapper {
        width: 260px;
        max-width: 260px;
        height: 260px;
        /* Top margin leaves room for the absolutely-positioned header
           (CARD X OF Y left, EXIT SESSION right at top:14px) so the
           canvas sits below them rather than under them. */
        margin: 56px auto 0;
    }
}


/* The carousel-container inside has flex:1; aspect-ratio:1 — give it
   a deterministic 1:1 box at the wrapper's full size. */
body.vocab-active.vocab-study-session .col-center .carousel-container {
    flex: 0 0 100%;
    width: 100%;
    height: 100%;
}

/* Force the decks list + detail + summary views OUT of layout during a
   running study session. VocabStudy.start() already toggles their
   `hidden` attribute, but [hidden]'s display:none has very low CSS
   specificity and can be overridden by any sibling rule — this
   belt-and-suspenders block guarantees the column doesn't grow
   taller because a downstream tweak un-hid them. */
body.vocab-study-session #vocab-decks-list-view,
body.vocab-study-session #vocab-deck-detail-view,
body.vocab-study-session #vocab-study-summary {
    display: none !important;
}

/* Study button — re-style now that it's no longer disabled. */
.vocab-deck-study-btn:not(:disabled) {
    cursor: pointer;
}

.vocab-deck-study-btn:not(:disabled):hover {
    background: var(--accent-hover, var(--accent));
    border-color: var(--accent);
}

/* Scoped to the pane element via #id — otherwise this hits the body
   too (it also gets `vocab-study-session` as a class when a session
   is active), overriding shared.css's body padding and shifting the
   site header 22px up. */
#vocab-study-session {
    padding: 2px 12px 0;
}

/* Give the ratings row breathing room from the column bottom edge
   during a study session. The Card-X-of-Y progress and Exit Session
   buttons referenced by the old "footer hugs the edge" comment now
   live in the absolutely-positioned top corners, so the bottom of
   the panel houses the Hard / Medium / Easy buttons — those want
   normal padding underneath, not zero. */
body.vocab-study-session .vocab-decks-panel {
    padding-bottom: 14px;
}

/* Hide canvas chrome that doesn't apply during a vocab study session.
   These are kana-specific affordances (prev/next nav, flag-as-difficult
   for a single character) that don't translate to vocab cards. */
body.vocab-study-session #swipe-hint-left,
body.vocab-study-session #swipe-hint-right,
body.vocab-study-session #flag-btn {
    display: none !important;
}

.vocab-study-meaning {
    text-align: center;
    margin: 2px 0 4px;
}

.vocab-study-meaning-text {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text);
    letter-spacing: 0.005em;
    line-height: 1.2;
}

/* Success indicator — visible only once the whole word has been
   written. Triggered by body.vocab-study-awaiting-rating (added by
   VocabStudy.onCharacterComplete when charIdx hits the end). */
/* Word-complete indicator sits just ABOVE the Hard/Medium/Easy row.
   Uses `visibility: hidden` (not `display: none`) when inactive so the
   row's vertical space is reserved at all times — when it appears,
   nothing shifts. `margin-top: auto` absorbs the available space above
   it so it stays anchored above the ratings even as the column resizes. */
.vocab-study-complete {
    visibility: hidden;
    text-align: center;
    margin: auto 0 14px;
    font-size: 0.78rem;
    font-weight: 700;
    color: #238636; /* same green used in rate-easy:hover */
    letter-spacing: 0.02em;
    order: 2;
}

body.vocab-study-awaiting-rating .vocab-study-complete {
    visibility: visible;
    animation: vocab-complete-pop 0.4s ease;
}

/* Mobile: kill the auto top-margin so the meaning / answer / complete
   / ratings stack as one compact widget directly below the canvas
   instead of being pushed to the column bottom with a void above. */
@media (max-width: 900px) {
    body.vocab-active.vocab-study-session .vocab-study-meaning {
        margin: 14px 0 8px;
    }
    body.vocab-active.vocab-study-session .vocab-study-answer {
        margin: 0 0 10px;
    }
    body.vocab-active.vocab-study-session .vocab-study-complete {
        margin: 0 0 8px;
    }
    body.vocab-active.vocab-study-session .vocab-study-ratings {
        margin: 0;
    }
}

/* The definition stays visible after completion — the success indicator
   pops in above the answer field as an additional cue. Both reading
   contexts (what the word means + that the user wrote it) are useful
   while the user decides on a rating. */

.vocab-study-complete-check {
    display: inline-block;
    margin-right: 4px;
    color: #238636;
    font-weight: 700;
}

@keyframes vocab-complete-pop {
    0%   { opacity: 0; transform: scale(0.85); }
    100% { opacity: 1; transform: scale(1); }
}

/* Lock the writing canvas after the word is complete — the user has
   already finished tracing, the rating buttons drive what happens
   next. Without this, the user can keep over-tracing the last char
   indefinitely. The flag button still works (separate element). */
body.vocab-study-awaiting-rating #draw-canvas {
    pointer-events: none;
}

.vocab-study-answer {
    display: flex;
    justify-content: center;
    align-items: flex-end;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 6px;
    min-height: 32px;
    order: 1;
}

.vocab-study-slot {
    min-width: 26px;
    height: 30px;
    padding: 0 3px;
    font-family: 'Noto Sans JP', sans-serif;
    font-size: 1.1rem;
    line-height: 30px;
    text-align: center;
    color: var(--text-faint);
    border-bottom: 2px solid var(--subtle-border);
    transition: border-color 0.2s, background 0.2s, color 0.2s,
                transform 0.18s cubic-bezier(0.4, 0, 0.2, 1);
}

.vocab-study-slot.filled {
    color: var(--accent);
    border-color: var(--accent);
    /* Subtle "drop into place" — the kana settles after being written. */
    animation: vocab-slot-fill 0.25s ease;
}

.vocab-study-slot.current {
    border-color: var(--accent);
    background: var(--accent-bg);
}

@keyframes vocab-slot-fill {
    0%   { transform: translateY(-3px); opacity: 0.4; }
    100% { transform: translateY(0);    opacity: 1;   }
}

/* Footer — keeps Card X of Y + Exit Session out of the visual hierarchy
   so the answer field + rating buttons own the focus. Subtle top divider
   reinforces the "session metadata" grouping. */
.vocab-study-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 6px;
    padding-top: 4px;
    border-top: 1px solid var(--subtle-border);
}

.vocab-study-progress {
    color: var(--text-faint);
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 600;
}

.vocab-study-exit-btn {
    padding: 3px 10px;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    border-radius: 12px;
    font: inherit;
    font-size: 0.68rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    font-weight: 600;
    cursor: pointer;
    transition: color 0.12s, border-color 0.12s;
}

.vocab-study-exit-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
}

.vocab-study-summary {
    text-align: center;
    padding: 40px 20px;
}

.vocab-study-summary-title {
    font-size: 1.4rem;
    font-weight: 600;
    margin-bottom: 8px;
    color: var(--text);
}

.vocab-study-summary-stats {
    color: var(--text-faint);
    margin-bottom: 20px;
}

.vocab-study-summary-back {
    padding: 10px 22px;
    border: 1px solid var(--accent);
    background: var(--accent);
    color: #fff;
    border-radius: 10px;
    font: inherit;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: opacity 0.12s;
}

.vocab-study-summary-back:hover {
    opacity: 0.9;
}

.vocab-study-summary-breakdown {
    display: inline-block;
    margin-top: 6px;
    font-size: 0.85rem;
    color: var(--text-faint);
}

/* Self-rating row — Hard / Medium / Easy buttons. Always pressable
   mid-card; each advances to the next card and records the rating. */
.vocab-study-ratings {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 6px;
    /* The vocab-study-complete element above this row owns the
       `margin-top: auto` that pushes the bottom group (complete +
       ratings + footer) down. The ratings just sit naturally below it. */
    margin: 0;
    order: 3;
}

.vocab-rate-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    padding: 5px 8px 4px;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text);
    border-radius: 8px;
    font: inherit;
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s,
                transform 0.08s ease, box-shadow 0.15s;
}

.vocab-rate-btn:active {
    transform: scale(0.97);
}

.vocab-rate-interval {
    font-size: 0.62rem;
    font-weight: 500;
    opacity: 0.6;
    line-height: 1.05;
    font-variant-numeric: tabular-nums;
}

.vocab-rate-interval:empty {
    visibility: hidden;
}

.vocab-rate-hard:hover {
    background: rgba(179, 42, 42, 0.10);
    border-color: #b32a2a;
    color: #b32a2a;
}

.vocab-rate-medium:hover {
    background: rgba(204, 134, 38, 0.12);
    border-color: #cc8626;
    color: #cc8626;
}

.vocab-rate-easy:hover {
    background: rgba(35, 134, 54, 0.12);
    border-color: #238636;
    color: #238636;
}

/* When the word is fully written but the user hasn't rated yet,
   pulse the rating row so it's clear they need to pick one. */
body.vocab-study-awaiting-rating .vocab-study-ratings {
    animation: vocab-rate-pulse 1.6s ease-in-out infinite;
}

@keyframes vocab-rate-pulse {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-2px); }
}

body.vocab-study-awaiting-rating .vocab-rate-btn {
    box-shadow: 0 0 0 0 var(--accent-bg);
    animation: vocab-rate-glow 1.6s ease-in-out infinite;
}

@keyframes vocab-rate-glow {
    0%, 100% { box-shadow: 0 0 0 0 var(--accent-bg); }
    50% { box-shadow: 0 0 0 4px var(--accent-bg); }
}

/* ── Deck-detail tabs (Cards ↔ Schedule) ─────────────────────────── */
.vocab-deck-tabs {
    display: flex;
    align-items: center;
    gap: 4px;
    margin: 0 0 10px;
    border-bottom: 1px solid var(--subtle-border);
}

/* Back button sits inside the tab strip, right-justified to the
   column edge so it reads as a peer-navigation control. The
   margin-left: auto pushes it past the tab cluster. */
.vocab-deck-tabs .vocab-deck-back-btn {
    margin-left: auto;
    margin-bottom: 1px; /* sit on the same baseline as the tab labels */
}

.vocab-deck-tab {
    padding: 7px 14px;
    border: none;
    background: transparent;
    color: var(--text-faint);
    font: inherit;
    font-size: 0.88rem;
    font-weight: 600;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.12s, border-color 0.12s;
}

.vocab-deck-tab:hover {
    color: var(--text);
}

.vocab-deck-tab.active {
    color: var(--accent);
    border-bottom-color: var(--accent);
}

/* Hide non-active tab pane. Default (no data-active-tab) shows cards. */
.vocab-deck-tab-pane {
    display: none;
}

[data-active-tab="cards"] .vocab-deck-tab-pane[data-tab-pane="cards"],
[data-active-tab="schedule"] .vocab-deck-tab-pane[data-tab-pane="schedule"],
[data-active-tab="settings"] .vocab-deck-tab-pane[data-tab-pane="settings"] {
    display: flex;
    flex-direction: column;
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
    padding-right: 2px; /* small gutter so the scrollbar doesn't hug content */
}

/* ── Per-deck SRS schedule panel ─────────────────────────────────── */
.vocab-srs-panel {
    margin-top: 4px;
}

/* When the schedule tab is the active pane, override the generic pane
   rule so the OUTER pane no longer scrolls. The header + summary stay
   pinned and the list-wrap inside owns the scroll — gives column
   headers something stable to sticky against. */
[data-active-tab="schedule"] .vocab-deck-tab-pane[data-tab-pane="schedule"] {
    overflow: hidden;
}

[data-active-tab="schedule"] .vocab-srs-panel .vocab-srs-header,
[data-active-tab="schedule"] .vocab-srs-panel .vocab-srs-summary {
    flex: 0 0 auto;
}

.vocab-srs-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}


.vocab-srs-title {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.vocab-srs-reset {
    padding: 3px 10px;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    border-radius: 12px;
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.vocab-srs-reset:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.vocab-srs-reset:not(:disabled):hover {
    color: #b32a2a;
    border-color: #b32a2a;
}

.vocab-srs-summary {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
    margin-bottom: 10px;
}

.vocab-srs-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 7px 10px;
    background: var(--bg-card, transparent);
    border: 1px solid var(--subtle-border);
    border-radius: 6px;
    font-size: 0.85rem;
}

.vocab-srs-item-label {
    color: var(--text-faint);
}

.vocab-srs-item-value {
    font-weight: 600;
    color: var(--text);
}

.vocab-srs-list-wrap {
    background: var(--bg-card, transparent);
    border: 1px solid var(--subtle-border);
    border-radius: 8px;
    /* Own the scroll for the schedule list so the surrounding header +
       summary stay pinned. min-height: 0 + flex: 1 1 0 let it shrink
       inside the active schedule pane and overflow internally. */
    flex: 1 1 0;
    min-height: 0;
    overflow-y: auto;
}

/* Column-header row stays at the top of the scrolling list-wrap so
   the user can always see what each value column means while scrolling
   through long decks. */
.vocab-srs-list-header {
    position: sticky;
    top: 0;
    z-index: 1;
}

.vocab-srs-list-wrap.is-empty .vocab-srs-list-header,
.vocab-srs-list-wrap.is-empty .vocab-srs-list { display: none; }

.vocab-srs-list-wrap:not(.is-empty) .vocab-srs-empty { display: none; }

.vocab-srs-list-header,
.vocab-srs-row {
    display: grid;
    /* Kana column was 1.4em — barely one character wide, which made
       multi-char readings (e.g. あくいんあっか) wrap to one kana per
       line and balloon each row to 100px+ tall. Auto sizes to the
       widest reading; the meaning column flex-shrinks to compensate. */
    grid-template-columns: auto minmax(0, 1fr) 3em 3em 2.5em;
    gap: 8px;
    align-items: center;
    padding: 6px 10px;
    font-size: 0.82rem;
}

.vocab-srs-list-header {
    color: var(--text-faint);
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    background: var(--accent-bg);
    border-bottom: 1px solid var(--subtle-border);
}

.vocab-srs-list-header > span:nth-child(n+3) {
    text-align: right;
}

.vocab-srs-list {
    /* The parent .vocab-deck-tab-pane[data-tab-pane="schedule"] scrolls
       the whole pane, so no inner max-height/overflow needed here. */
}

.vocab-srs-row {
    border-bottom: 1px solid var(--subtle-border);
}

.vocab-srs-row:last-child {
    border-bottom: none;
}

.vocab-srs-glyph {
    font-family: 'Noto Sans JP', sans-serif;
    color: var(--text);
    white-space: nowrap;
}

.vocab-srs-meaning {
    color: var(--text-faint);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.vocab-srs-due,
.vocab-srs-int,
.vocab-srs-reps {
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--text);
}

.vocab-srs-row.due-now .vocab-srs-due {
    color: var(--accent);
    font-weight: 600;
}

.vocab-srs-row.overdue .vocab-srs-due {
    color: #b32a2a;
    font-weight: 600;
}

.vocab-srs-row.future .vocab-srs-due {
    color: var(--text-faint);
}

.vocab-srs-empty {
    padding: 18px 14px;
    color: var(--text-faint);
    font-size: 0.85rem;
    font-style: italic;
    text-align: center;
}

/* ── SRS parameters tab pane ─────────────────────────────────────── */
.vocab-params-pane {
    padding-top: 4px;
}

.vocab-params-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.vocab-params-title {
    margin: 0;
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--accent);
    text-transform: uppercase;
    letter-spacing: 0.06em;
}

.vocab-params-reset-btn {
    padding: 3px 10px;
    border: 1px solid var(--subtle-border);
    background: transparent;
    color: var(--text-faint);
    border-radius: 12px;
    font: inherit;
    font-size: 0.72rem;
    cursor: pointer;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.vocab-params-reset-btn:hover {
    color: #b32a2a;
    border-color: #b32a2a;
}

.vocab-params-body {
    display: flex;
    flex-direction: column;
    gap: 18px;
}

.vocab-params-group-title {
    margin: 0 0 8px 0;
    font-size: 0.72rem;
    font-weight: 700;
    color: var(--text-faint);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}

.vocab-params-rows {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.vocab-params-row {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.vocab-params-row-head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.vocab-params-label {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--text);
}

.vocab-params-value {
    font-variant-numeric: tabular-nums;
    color: var(--accent);
    font-weight: 600;
    font-size: 0.88rem;
}

.vocab-params-slider {
    width: 100%;
    margin: 2px 0;
    accent-color: var(--accent);
}

/* Select input for non-numeric params (e.g. session flow). Mirrors the
   slider's vertical rhythm so the rows stay aligned. */
.vocab-params-select {
    width: 100%;
    padding: 6px 10px;
    border: 1px solid var(--subtle-border);
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    margin: 2px 0;
}

.vocab-params-select:focus {
    outline: none;
    border-color: var(--accent);
}

.vocab-params-desc {
    font-size: 0.75rem;
    color: var(--text-faint);
    line-height: 1.35;
}
