:root {
    --bg-primary: #ffffff;
    --bg-secondary: #f5f5f5;
    --bg-tertiary: #e9e9e9;
    --text-primary: #1a1a1a;
    --text-secondary: #666666;
    --accent: #2563eb;
    --accent-hover: #1d4ed8;
    --border: #e0e0e0;
    --card-bg: #ffffff;
    --shadow: rgba(0, 0, 0, 0.1);
    --success: #10b981;
    --warning: #f59e0b;
    --danger: #ef4444;

    /* POS colors */
    --pos-noun: #3b82f6;
    --pos-verb: #10b981;
    --pos-adj: #8b5cf6;
    --pos-adv: #14b8a6;
    --pos-pron: #f59e0b;
    --pos-other: #6b7280;

    /* Nav height for page offset */
    --nav-height: 56px;
}

[data-theme="dark"] {
    --bg-primary: #0f172a;
    --bg-secondary: #1e293b;
    --bg-tertiary: #334155;
    --text-primary: #f5f5f5;
    --text-secondary: #94a3b8;
    --accent: #3b82f6;
    --accent-hover: #60a5fa;
    --border: #334155;
    --card-bg: #1e293b;
    --shadow: rgba(0, 0, 0, 0.3);
}

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    background-color: var(--bg-primary);
    color: var(--text-primary);
    line-height: 1.6;
    transition: background-color 0.3s, color 0.3s;
}

.page {
    display: none;
    min-height: calc(100vh - var(--nav-height));
    padding-top: var(--nav-height);
}

.page.active {
    display: block;
}

/* Landing Page */
.landing-container {
    max-width: 600px;
    margin: 0 auto;
    padding: 2rem;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.landing-header {
    text-align: center;
    margin-bottom: 3rem;
}

.landing-header h1 {
    font-size: 3rem;
    margin-bottom: 0.5rem;
    color: var(--accent);
}

.tagline {
    font-size: 1.2rem;
    color: var(--text-secondary);
}

.hero {
    text-align: center;
    margin-bottom: 3rem;
}

.hero h2 {
    font-size: 1.5rem;
    margin-bottom: 1.5rem;
}

.features {
    list-style: none;
    font-size: 1.1rem;
    color: var(--text-secondary);
}

.features li {
    margin: 0.5rem 0;
}

.auth-section {
    position: relative;
}

.theme-toggle-container {
    position: absolute;
    top: -3rem;
    right: 0;
}

.login-form {
    background: var(--card-bg);
    padding: 2rem;
    border-radius: 8px;
    box-shadow: 0 2px 8px var(--shadow);
}

.login-form h3 {
    margin-bottom: 1.5rem;
    text-align: center;
}

.form-group {
    margin-bottom: 1.5rem;
}

.form-group label,
.form-group-label {
    display: block;
    margin-bottom: 0.5rem;
    font-weight: 500;
}

/* ── Reusable button-radio (segmented control) ─────────────────────────────
 * Single-choice picker rendered as buttons. Markup:
 *   <div class="btn-radio" role="radiogroup" data-value="FI">
 *     <button class="btn-radio-option" role="radio" data-value="FI" aria-checked="true">…</button>
 *     <button class="btn-radio-option" role="radio" data-value="ET" aria-checked="false">…</button>
 *   </div>
 * Wired up in app.ts via bindBtnRadio(rootId), which keeps data-value on the
 * container in sync with aria-checked / .is-active on each option button. */
.btn-radio {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0;
    border: 1px solid var(--border);
    border-radius: 6px;
    overflow: hidden;
    background: var(--bg-primary);
}
.btn-radio-option {
    appearance: none;
    border: none;
    background: transparent;
    color: var(--text-primary);
    padding: 0.55rem 1rem;
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
    border-right: 1px solid var(--border);
}
.btn-radio-option:last-child {
    border-right: none;
}
.btn-radio-option:hover:not(.is-active) {
    background: var(--bg-secondary);
}
.btn-radio-option.is-active {
    background: var(--accent);
    color: white;
    font-weight: 600;
    box-shadow: inset 0 0 0 1px var(--accent);
}
.btn-radio-option:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -2px;
    z-index: 1;
}

.form-group input,
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 0.75rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 1rem;
    background: var(--bg-primary);
    color: var(--text-primary);
}

.form-group textarea {
    resize: vertical;
    font-family: inherit;
}

/* Dropzone wrapping the textarea so we can show drag-and-drop affordances
   and an EPUB-loaded pill without affecting the textarea's own layout. */
.dropzone {
    position: relative;
    border: 2px dashed transparent;
    border-radius: 8px;
    padding: 4px;
    margin: -4px;
    transition: border-color 120ms ease, background-color 120ms ease, box-shadow 120ms ease;
}

.dropzone:hover {
    border-color: color-mix(in srgb, var(--accent) 35%, transparent);
    background-color: color-mix(in srgb, var(--accent) 4%, transparent);
}

.dropzone.drag-over {
    border-color: var(--accent);
    background-color: color-mix(in srgb, var(--accent) 10%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 25%, transparent);
}

/* Visible, tall, clickable CTA below the textarea. Doubles as the file
   picker trigger (it's a <label for=fileInput>) and as the obvious "drop a
   file here" target. */
.dropzone-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.85rem;
    margin-top: 0.75rem;
    padding: 1.5rem 1.25rem;
    min-height: 96px;
    border: 2px dashed color-mix(in srgb, var(--accent) 45%, var(--border));
    border-radius: 10px;
    background: color-mix(in srgb, var(--bg-secondary) 50%, transparent);
    color: var(--text-secondary);
    text-align: left;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease,
                color 120ms ease, transform 120ms ease, box-shadow 120ms ease;
}

.dropzone-cta:hover {
    border-color: var(--accent);
    background-color: color-mix(in srgb, var(--accent) 8%, transparent);
    color: var(--text-primary);
    transform: translateY(-1px);
    box-shadow: 0 2px 6px color-mix(in srgb, var(--accent) 15%, transparent);
}

.dropzone-cta:active {
    transform: translateY(0);
    box-shadow: none;
}

/* When a file is being dragged anywhere over the dropzone, the CTA becomes
   the most prominent target so the user can clearly drop on it. */
.dropzone.drag-over .dropzone-cta {
    border-color: var(--accent);
    background-color: color-mix(in srgb, var(--accent) 14%, transparent);
    color: var(--accent);
}

.dropzone-cta-icon {
    font-size: 2rem;
    line-height: 1;
    flex-shrink: 0;
}

.dropzone-cta-text {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    line-height: 1.3;
}

.dropzone-cta-text strong {
    font-size: 1rem;
    color: inherit;
    font-weight: 600;
}

.dropzone-cta-sub {
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.dropzone-cta-sub code {
    padding: 0 0.25rem;
    border-radius: 3px;
    font-size: 0.8rem;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    color: var(--accent);
}

/* Chapter list shown in place of the textarea when an EPUB is loaded. Mirrors
   the textarea's height so the form layout doesn't jump, and scrolls when a
   book has more chapters than fit. */
.dropzone-chapters {
    list-style: none;
    margin: 0;
    padding: 0.5rem;
    max-height: 18rem;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-primary);
    counter-reset: chapter;
}

.dropzone-chapters li {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
    padding: 0.45rem 0.6rem;
    border-radius: 4px;
    font-size: 0.9rem;
    line-height: 1.35;
    counter-increment: chapter;
}

.dropzone-chapters li:hover {
    background: color-mix(in srgb, var(--accent) 8%, transparent);
}

.dropzone-chapters li::before {
    content: counter(chapter, decimal-leading-zero);
    flex-shrink: 0;
    min-width: 2rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    font-size: 0.8rem;
}

.dropzone-chapters .chapter-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--text-primary);
}

.dropzone-chapters .chapter-size {
    flex-shrink: 0;
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-variant-numeric: tabular-nums;
}

/* Drag-over overlay covers the entire dropzone (textarea + CTA) so the
   user sees an unambiguous "release to import" signal anywhere they
   release. Hidden by default. */
.dropzone-overlay {
    position: absolute;
    inset: 4px;
    border-radius: 8px;
    background: color-mix(in srgb, var(--accent) 18%, transparent);
    color: var(--accent);
    display: none;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 1.1rem;
    pointer-events: none;
    z-index: 2;
}

.dropzone.drag-over .dropzone-overlay {
    display: flex;
}

/* "EPUB loaded" pill sits above the textarea when a book is held in app
   state. Filename + chapter count + a small clear button. */
.dropzone-loaded {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.85rem;
    margin-bottom: 0.5rem;
    border-radius: 8px;
    background: color-mix(in srgb, var(--accent) 10%, var(--bg-secondary));
    border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
    font-size: 0.9rem;
    color: var(--text-primary);
}

.dropzone-loaded .loaded-icon {
    font-size: 1.2rem;
}

.dropzone-loaded .loaded-meta {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.dropzone-loaded .loaded-filename {
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dropzone-loaded .loaded-sub {
    font-size: 0.8rem;
    color: var(--text-secondary);
}

.dropzone-loaded .loaded-clear {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-secondary);
    border-radius: 4px;
    padding: 0.25rem 0.6rem;
    font-size: 0.8rem;
    cursor: pointer;
    transition: background-color 120ms ease, color 120ms ease;
}

.dropzone-loaded .loaded-clear:hover {
    background: var(--bg-primary);
    color: var(--text-primary);
}

.help-text {
    margin-top: 1rem;
    font-size: 0.875rem;
    color: var(--text-secondary);
    text-align: center;
}

/* Theme Toggle */
.theme-toggle {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 50%;
    width: 2.5rem;
    height: 2.5rem;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.2rem;
    transition: all 0.2s;
}

.theme-toggle:hover {
    background: var(--bg-tertiary);
}

/* Buttons */
.btn {
    padding: 0.75rem 1.5rem;
    border: none;
    border-radius: 4px;
    font-size: 1rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s;
}

/* Catch-all disabled treatment so any .btn (textbox, sync, dialog confirm)
   reads as inactive — previously only .btn-parse had this. */
.btn:disabled,
.btn[aria-disabled="true"] {
    opacity: 0.55;
    cursor: not-allowed;
    /* Suppress the hover/active colour shifts so the disabled look is
       stable even when the cursor passes over the button. */
    pointer-events: none;
}

.btn-primary {
    background: var(--accent);
    color: white;
}

.btn-primary:hover {
    background: var(--accent-hover);
}

.btn-secondary {
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

.btn-secondary:hover {
    background: var(--bg-tertiary);
}

/* Destructive primary action — used by showConfirm({ danger: true }) for
   delete / unsubscribe / unpublish flows. */
.btn-danger {
    background: #dc2626;
    color: white;
}
.btn-danger:hover {
    background: #b91c1c;
}

.btn-large {
    padding: 1rem 2rem;
    font-size: 1.1rem;
}

.btn-link {
    background: none;
    color: var(--accent);
    text-decoration: underline;
    padding: 0.5rem;
}

.btn-review {
    padding: 1rem 1.5rem;
    font-size: 1rem;
    min-width: 100px;
}

.btn-again {
    background: var(--danger);
    color: white;
}

.btn-hard {
    background: var(--warning);
    color: white;
}

.btn-good {
    background: var(--success);
    color: white;
}

.btn-easy {
    background: var(--accent);
    color: white;
}

.btn-ignore,
.btn-known {
    background: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

/* Dashboard */
.app-header {
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
    padding: 1rem 2rem;
}

.header-content {
    max-width: 1200px;
    margin: 0 auto;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.logo {
    font-size: 1.5rem;
    color: var(--accent);
}

.header-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
}

.user-menu {
    color: var(--text-secondary);
}

.dashboard-main {
    max-width: 1200px;
    margin: 0 auto;
    padding: 2rem;
}

/* KPI Tiles */
.kpi-section {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 1.5rem;
    margin-bottom: 2rem;
}

.kpi-tile {
    background: var(--card-bg);
    padding: 1.5rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px var(--shadow);
    border: 1px solid var(--border);
}

.kpi-tile h3 {
    font-size: 0.875rem;
    color: var(--text-secondary);
    margin-bottom: 0.5rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.kpi-value {
    font-size: 2rem;
    font-weight: bold;
    color: var(--accent);
}

/* Actions Section */
.actions-section {
    display: flex;
    gap: 1rem;
    margin-bottom: 2rem;
    flex-wrap: wrap;
}

/* Decks Section */
.decks-section h2 {
    margin-bottom: 1rem;
}

.decks-list {
    display: grid;
    gap: 1rem;
}

.deck-item {
    background: var(--card-bg);
    padding: 1.5rem;
    border-radius: 8px;
    border: 1px solid var(--border);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1rem;
}

.deck-info h3 {
    margin-bottom: 0.5rem;
}

.deck-info p {
    color: var(--text-secondary);
    font-size: 0.875rem;
}

.deck-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

/* Modal */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

.modal.active {
    display: flex;
}

.modal-content {
    background: var(--card-bg);
    border-radius: 8px;
    width: 90%;
    max-width: 600px;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 4px 16px var(--shadow);
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1.5rem;
    border-bottom: 1px solid var(--border);
}

.modal-close {
    background: none;
    border: none;
    font-size: 2rem;
    cursor: pointer;
    color: var(--text-secondary);
    line-height: 1;
}

.modal-body {
    padding: 1.5rem;
}

.modal-actions {
    display: flex;
    gap: 1rem;
    justify-content: flex-end;
    margin-top: 1.5rem;
}

/* Review Page */
.review-main {
    max-width: 800px;
    margin: 0 auto;
    padding: 2rem;
}

.card-container {
    margin-bottom: 2rem;
}

.card {
    background: var(--card-bg);
    border-radius: 12px;
    box-shadow: 0 4px 12px var(--shadow);
    border: 1px solid var(--border);
    min-height: 400px;
    position: relative;
    overflow: hidden;
}

.card-front,
.card-back {
    padding: 2rem;
    min-height: 400px;
    display: flex;
    flex-direction: column;
}

.card-back {
    display: none;
}

.card.flipped .card-front {
    display: none;
}

.card.flipped .card-back {
    display: flex;
}

.card-badge {
    position: absolute;
    top: 1rem;
    right: 1rem;
    background: var(--accent);
    color: white;
    padding: 0.25rem 0.75rem;
    border-radius: 12px;
    font-size: 0.875rem;
    font-weight: 500;
}

.card-content {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.card-content p {
    font-size: 1.25rem;
    line-height: 1.8;
    margin-bottom: 1rem;
}

.highlight {
    background: var(--accent);
    color: white;
    padding: 0.2rem 0.4rem;
    border-radius: 4px;
}

.card-lemma {
    font-size: 1.5rem;
    margin-bottom: 1rem;
    color: var(--accent);
}

.card-meaning {
    font-size: 1.2rem;
    margin-bottom: 1rem;
}

.card-grammar {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
    font-style: italic;
}

.card-examples {
    margin-bottom: 1rem;
}

.card-examples h4 {
    margin-bottom: 0.5rem;
    font-size: 0.875rem;
    text-transform: uppercase;
    color: var(--text-secondary);
}

.card-examples ul {
    list-style: none;
    padding-left: 0;
}

.card-examples li {
    padding: 0.5rem 0;
    border-bottom: 1px solid var(--border);
}

.card-deck-counts {
    color: var(--text-secondary);
    font-size: 0.875rem;
    margin-top: 1rem;
}

.review-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 1rem;
}

/* Responsive */
@media (max-width: 768px) {
    .landing-header h1 {
        font-size: 2rem;
    }

    .kpi-section {
        grid-template-columns: 1fr;
    }

    .actions-section {
        flex-direction: column;
    }

    .review-actions {
        grid-template-columns: repeat(2, 1fr);
    }

    .deck-item {
        flex-direction: column;
        align-items: flex-start;
    }
}


/* ── Parse page ──────────────────────────────────────────────────────────── */

.parse-main {
    max-width: 700px;
    margin: 2rem auto;
    padding: 0 1rem;
}

.parse-form-section h2 {
    margin-bottom: 0.25rem;
}

.parse-description {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
}

.char-count {
    font-size: 0.8rem;
    color: var(--text-secondary);
    font-weight: normal;
    float: right;
}

.char-count-warn { color: orange; }
.char-count-over { color: var(--color-error, red); font-weight: bold; }

.lang-warning {
    background: #fff3cd;
    border: 1px solid #ffc107;
    border-radius: 4px;
    padding: 0.6rem 1rem;
    margin-bottom: 1rem;
    font-size: 0.9rem;
    color: #856404;
}

.lang-switch-btn {
    margin: -0.5rem 0 1rem;
    padding: 0;
    border: none;
    background: none;
    color: var(--accent);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    cursor: pointer;
}

.lang-switch-btn:hover {
    color: var(--accent-hover);
}

.lang-switch-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 2px;
}

[data-theme="dark"] .lang-warning {
    background: #3a2e00;
    border-color: #ffc107;
    color: #ffd966;
}

.hidden { display: none !important; }

.btn-large {
    width: 100%;
    padding: 0.75rem;
    font-size: 1rem;
    margin-top: 0.5rem;
}

.parse-buttons {
    display: flex;
    gap: 0.75rem;
    margin-top: 0.5rem;
}

.btn-parse {
    flex: 1;
    padding: 0.75rem 1rem;
    font-size: 1rem;
}

.btn-parse:disabled {
    opacity: 0.6;
    cursor: not-allowed;
}

/* ── Results page ────────────────────────────────────────────────────────── */

/* Pin the entire results page to the viewport so the page itself can never
   scroll — only the sidebar and table-section scroll, inside their own
   columns. position: fixed takes the page out of body flow, so no amount
   of inner content can push the body taller than 100vh. */
#results-page.page {
    position: fixed;
    top: var(--nav-height);
    left: 0;
    right: 0;
    bottom: 0;
    padding-top: 0;
    min-height: 0;
    overflow: hidden;
}

.results-main {
    max-width: 1180px;
    margin: 0 auto;
    padding: 1rem;
    /* Vertical stack: header row, divider, then a horizontal split for the
       chapter sidebar + the main results body. */
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    height: 100%;
    overflow: hidden;
}

.results-split {
    flex: 1;
    min-height: 0;
    display: flex;
    gap: 1.5rem;
}

/* Two-row flex stack: the summary header stays put while only the table
   section below scrolls. NOTE: do NOT set overflow:hidden here — Firefox
   would then treat .results-body as the sticky scroll container instead
   of the actual scroller (.results-table-section), and the sticky thead
   wouldn't pin. The flex children's own constraints keep this in bounds. */
.results-body {
    flex: 1;
    min-width: 0;
    min-height: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
}

/* Chapter-filter sidebar: appears on the left of the results page only when
   an EPUB is loaded. Fills its column height; scrolls within itself. */
.results-chapter-nav {
    flex-shrink: 0;
    width: 240px;
    height: 100%;
    overflow-y: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-secondary);
    padding: 0.75rem;
}

.chapter-nav-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.chapter-nav-list li {
    margin: 0;
}

/* "Whole book" row pinned at the top of the sidebar so it remains
   reachable as the user scrolls through 30+ chapters. Underlined to
   separate it from the chapter list below. */
.chapter-nav-list .chapter-nav-whole-book {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-secondary);
    padding-bottom: 0.4rem;
    margin-bottom: 0.4rem;
    border-bottom: 1px solid var(--border);
}

.chapter-nav-item {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    width: 100%;
    padding: 0.4rem 0.55rem;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 5px;
    text-align: left;
    cursor: pointer;
    color: var(--text-primary);
    font-family: inherit;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.chapter-nav-item:hover {
    background-color: color-mix(in srgb, var(--accent) 8%, transparent);
}

.chapter-nav-item.active {
    background-color: color-mix(in srgb, var(--accent) 14%, transparent);
    border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}

.chapter-nav-label {
    font-size: 0.88rem;
    line-height: 1.3;
    word-break: break-word;
}

.chapter-nav-sub {
    font-size: 0.72rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

/* On narrow viewports drop the locked viewport layout entirely. The whole
   page scrolls as one and the sidebar stacks above the results. */
@media (max-width: 768px) {
    #results-page.page {
        position: static;
        top: auto;
        left: auto;
        right: auto;
        bottom: auto;
        padding-top: var(--nav-height);
        min-height: calc(100vh - var(--nav-height));
        overflow: visible;
    }
    .results-main {
        height: auto;
        overflow: visible;
    }
    .results-split {
        flex-direction: column;
        min-height: 0;
    }
    .results-body {
        height: auto;
        overflow: visible;
        padding-right: 0;
    }
    .results-chapter-nav {
        width: 100%;
        height: auto;
        max-height: 240px;
    }
}

.results-summary {
    margin-bottom: 1.5rem;
    flex-shrink: 0;
}

.results-stats {
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.results-meta {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin: 0.5rem 0 0.35rem;
}

.results-pill {
    display: inline-flex;
    align-items: center;
    padding: 0.2rem 0.55rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 600;
}

.results-help {
    margin-top: 0.35rem;
    color: var(--text-secondary);
    font-size: 0.85rem;
}

/* Deck comprehension projection (deck detail only) */
.deck-comprehension {
    margin-top: 0.6rem;
    padding: 0.65rem 0.85rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-secondary);
}

.deck-comprehension-headline {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}

.deck-comprehension-headline strong {
    color: var(--text-primary);
    font-size: 1.05rem;
}

.deck-comprehension-detail {
    margin-left: 0.4rem;
    font-size: 0.8rem;
}

.deck-unlocks {
    margin-top: 0.45rem;
    font-size: 0.85rem;
    color: var(--text-secondary);
}

.deck-unlocks summary {
    cursor: pointer;
    font-weight: 600;
}

.deck-unlock-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.3rem 1rem;
}

.deck-unlock-item {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
}

.deck-unlock-lemma {
    color: var(--text-primary);
    font-weight: 600;
}

.deck-unlock-pos {
    font-size: 0.72rem;
    text-transform: lowercase;
}

.deck-unlock-gain {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
}

/* Visual frame stacking a fixed header table on top and a scrolling body
   table below. Splitting <thead> into its own table is the only way to
   guarantee the header NEVER scrolls — `position: sticky` on table cells
   misbehaves on Firefox when the scroll container has rounded corners.
   Both tables share class-based column widths so they line up exactly. */
.results-table-section {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.word-table-header-wrap {
    flex-shrink: 0;
    /* `overflow: hidden` makes this a scroll container, which lets
       `scrollbar-gutter: stable` reserve the same right-side gutter that
       the body's scrollbar takes, so columns line up. */
    overflow: hidden;
    scrollbar-gutter: stable;
}

.word-table-header {
    margin: 0;
}

.word-table-scroll {
    flex: 1;
    min-height: 0;
    width: 100%;
    overflow-x: auto;
    overflow-y: auto;
    /* Reserve a scrollbar gutter even when the body table doesn't overflow
       yet, so the body's column edges stay where they were when it does
       overflow. Combined with the same gutter on the header keeps columns
       aligned regardless of scrollbar state. */
    scrollbar-gutter: stable;
}

.word-table {
    width: 100%;
    /* `separate` so the sticky thead can have rounded corners on its first
       and last <th> cells; row-level border-bottoms on td/th still render
       cleanly without merging. */
    border-collapse: separate;
    border-spacing: 0;
    font-size: 0.95rem;
    table-layout: fixed;
}

.word-table th {
    text-align: left;
    padding: 0.6rem 0.75rem;
    border-bottom: 2px solid var(--border-color);
    color: var(--text-secondary);
    font-weight: 600;
    white-space: nowrap;
}

.word-table td {
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}

.word-table tbody tr:hover {
    background: var(--hover-bg, rgba(0,0,0,0.04));
}

[data-theme="dark"] .word-table tbody tr:hover {
    background: rgba(255,255,255,0.05);
}

.sort-btn {
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    font-weight: inherit;
    cursor: pointer;
    padding: 0;
}

.sort-btn.active {
    color: var(--text-primary);
}

.col-row    { width: 3rem; text-align: right; color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.col-lemma  { width: 13rem; font-weight: 500; word-wrap: break-word; vertical-align: top; }
.col-def    { color: var(--text-secondary); font-size: 0.85rem; word-wrap: break-word; }
.col-grammar { color: var(--text-secondary); font-size: 0.8rem; font-style: italic; }
.grammar-label { background: var(--bg-secondary, #f0f0f0); padding: 2px 6px; border-radius: 3px; }
.col-count  { width: 7rem; text-align: left; font-variant-numeric: tabular-nums; }
.col-actions { width: 13rem; }

.no-gloss { color: var(--text-secondary); opacity: 0.5; }
.no-grammar { color: var(--text-secondary); opacity: 0.5; font-style: normal; }
.is-hidden { display: none; }

/* Lemma cell — lemma + abbreviated POS pill on one line, optional example
   below. The POS column itself has been removed; the abbreviated pill
   inherits column space from the lemma column. */
.lemma-pos-grid {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
}
.lemma-side {
    word-wrap: break-word;
}
.pos-side {
    flex: 0 0 auto;
}

.example-toggle {
    display: block;
    margin-top: 0.25rem;
    padding: 0;
    background: none;
    border: none;
    font-family: inherit;
    font-size: 0.75rem;
    color: var(--accent);
    cursor: pointer;
    user-select: none;
    text-align: left;
}
.example-toggle[aria-expanded="true"] {
    color: var(--text-secondary);
}

.example-text {
    display: block;
    margin-top: 0.25rem;
    padding-left: 0.75rem;
    border-left: 2px solid var(--accent);
    font-size: 0.8rem;
    color: var(--text-secondary);
    font-style: italic;
    line-height: 1.5;
    overflow-wrap: anywhere;
}
.example-text.hidden {
    display: none;
}

/* Multiple possible meanings (ambiguity flow) --------------------------- */
.ambiguity-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
    margin-top: 0.25rem;
    padding: 0.1rem 0.45rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 999px;
    font-family: inherit;
    font-size: 0.72rem;
    color: var(--warning);
    cursor: pointer;
    user-select: none;
}
.ambiguity-chip.is-open {
    color: var(--text-secondary);
}

.ambiguity-row > td {
    padding: 0;
    background: var(--bg-secondary);
}
.ambiguity-panel {
    padding: 0.75rem 1rem;
    border-left: 2px solid var(--warning);
}
.ambiguity-panel-title {
    margin: 0 0 0.4rem;
    font-size: 0.85rem;
    font-weight: 600;
}
.ambiguity-example {
    margin: 0 0 0.6rem;
    font-size: 0.82rem;
    font-style: italic;
    color: var(--text-secondary);
    line-height: 1.5;
}
.ambiguity-candidates {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.ambiguity-candidate {
    padding: 0.5rem 0.6rem;
    background: var(--bg-primary);
    border: 1px solid var(--border);
    border-radius: 6px;
}
.ambiguity-candidate.is-known {
    opacity: 0.7;
}
.ambiguity-candidate-head {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.ambiguity-candidate-lemma {
    font-weight: 600;
}
.ambiguity-candidate-gloss {
    color: var(--text-secondary);
    font-size: 0.85rem;
}
.ambiguity-candidate-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.45rem;
}
.ambiguity-candidate-actions button {
    padding: 0.2rem 0.55rem;
    font-family: inherit;
    font-size: 0.75rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    cursor: pointer;
}
.ambiguity-candidate-actions button:disabled {
    cursor: default;
    opacity: 0.6;
}
.ambiguity-candidate-actions button.is-active {
    border-color: var(--accent);
    color: var(--accent);
}
.ambiguity-panel-foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.6rem;
    flex-wrap: wrap;
    margin-top: 0.6rem;
}
.ambiguity-study-hint {
    font-size: 0.72rem;
    color: var(--text-secondary);
}
.ambiguity-flag-btn {
    padding: 0.2rem 0.55rem;
    font-family: inherit;
    font-size: 0.72rem;
    background: none;
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-secondary);
    cursor: pointer;
}

@media (max-width: 600px) {
    .results-meta { gap: 0.4rem; }
    .results-pill { font-size: 0.75rem; }
    .results-help { font-size: 0.8rem; }
    .col-def     { display: none; }
    .col-grammar { display: none; }
}

/* ── Global Navigation (#24) ────────────────────────────────────────────── */

.global-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: var(--nav-height);
    background: var(--card-bg);
    border-bottom: 1px solid var(--border);
    z-index: 100;
}

.nav-content {
    max-width: 1200px;
    height: 100%;
    margin: 0 auto;
    padding: 0 1.5rem;
    display: flex;
    align-items: center;
    gap: 2rem;
}

.nav-logo {
    font-size: 1.25rem;
    font-weight: 700;
    color: var(--accent);
    text-decoration: none;
    flex-shrink: 0;
}

.nav-logo:hover {
    color: var(--accent-hover);
}

.nav-links {
    display: flex;
    gap: 0.25rem;
    flex: 1;
}

.nav-link {
    padding: 0.5rem 0.75rem;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 0.875rem;
    font-weight: 500;
    border-radius: 6px;
    transition: all 0.15s;
}

.nav-link:hover:not(.disabled) {
    color: var(--text-primary);
    background: var(--bg-secondary);
}

.nav-link.active {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.nav-link.disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.nav-icon-btn {
    width: 36px;
    height: 36px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s;
}

.nav-lang-dropdown {
    position: relative;
}

.nav-lang-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 32px;
    padding: 0 0.6rem;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-primary);
    color: var(--text-primary);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.nav-lang-current {
    display: inline-flex;
    align-items: center;
    font-size: 1.15rem;
    line-height: 1;
}

/* Flat-design SVG flag. Sized by parent font-size so different placements
 * (nav toggle, dropdown option, languages-page row) scale independently
 * without touching markup. The rounded corners + soft outline give it a
 * sticker-y / cartoony feel that reads at small sizes. */
.lang-flag {
    height: 1em;
    width: auto;
    display: inline-block;
    flex-shrink: 0;
    border-radius: 3px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.08);
    overflow: hidden;
}

.nav-lang-toggle:hover,
.nav-lang-toggle[aria-expanded="true"] {
    border-color: var(--accent);
    background: var(--bg-secondary);
}

.nav-lang-toggle:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

.nav-lang-caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid var(--text-secondary);
    transition: transform 0.15s;
}

.nav-lang-toggle[aria-expanded="true"] .nav-lang-caret {
    transform: rotate(180deg);
}

.nav-lang-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 0;
    margin: 0;
    padding: 0.35rem;
    list-style: none;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px var(--shadow);
    z-index: 200;
}

.nav-lang-menu.hidden {
    display: none;
}

.nav-lang-option {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.5rem 0.7rem;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: 0.92rem;
    text-align: left;
    cursor: pointer;
}

.nav-lang-option-flag {
    display: inline-flex;
    align-items: center;
    font-size: 1.3rem;
    line-height: 1;
}

/* Flag-only options in the nav dropdown: compact, square-ish rows with
 * the flag (and optional checkmark) hugging center. Names are surfaced via
 * data-tooltip rather than visible text. */
.nav-lang-option-flagonly {
    justify-content: flex-start;
    padding: 0.4rem 0.55rem;
}

.nav-lang-option-flagonly .nav-lang-option-check {
    margin-left: 0.35rem;
}

.nav-lang-option:hover,
.nav-lang-option:focus-visible {
    background: var(--bg-secondary);
    outline: none;
}

.nav-lang-option[aria-selected="true"] {
    color: var(--accent);
    font-weight: 600;
}

.nav-lang-option-check {
    color: var(--accent);
    font-weight: 700;
    margin-left: 0.35rem;
}

.nav-lang-menu-divider {
    height: 1px;
    margin: 0.3rem 0;
    background: var(--border);
}

.nav-lang-menu-manage {
    color: var(--text-secondary);
    font-size: 0.88rem;
}

.nav-icon-btn:hover:not(.disabled) {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.nav-icon-btn.disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.nav-hamburger {
    display: none;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    width: 36px;
    height: 36px;
    border: none;
    background: transparent;
    cursor: pointer;
    padding: 8px;
}

.nav-hamburger span {
    display: block;
    width: 100%;
    height: 2px;
    background: var(--text-primary);
    border-radius: 1px;
    transition: all 0.2s;
}

/* Mobile nav */
.nav-mobile-overlay {
    position: fixed;
    top: var(--nav-height);
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 99;
}

.nav-mobile-menu {
    background: var(--card-bg);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    border-bottom: 1px solid var(--border);
}

.nav-mobile-link {
    padding: 0.75rem 1rem;
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 1rem;
    font-weight: 500;
    border-radius: 8px;
}

.nav-mobile-link:hover:not(.disabled) {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.nav-mobile-link.active {
    color: var(--accent);
    background: color-mix(in srgb, var(--accent) 10%, transparent);
}

.nav-mobile-link.disabled {
    opacity: 0.4;
}

@media (max-width: 640px) {
    .nav-links,
    .nav-actions {
        display: none;
    }

    .nav-hamburger {
        display: flex;
    }

    .nav-content {
        justify-content: space-between;
    }
}

/* ── Results header with back button ────────────────────────────────────── */

.results-header {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-shrink: 0;
    padding-bottom: 0.5rem;
    margin-bottom: 0.75rem;
    border-bottom: 1px solid var(--border);
}

.results-header h2 {
    flex: 1;
}

/* ── Issue #20: Results table polish ────────────────────────────────────── */

.word-table thead th {
    background: var(--bg-secondary);
    /* Bottom border draws the line between header band and rows. Top
       border is provided by the parent .results-table-section's frame. */
    border-bottom: 1px solid var(--border);
}

.word-table thead th:first-child {
    border-top-left-radius: 8px;
}

.word-table thead th:last-child {
    border-top-right-radius: 8px;
}

/* Zebra striping */
.word-table tbody tr:nth-child(even) {
    background: var(--bg-secondary);
}

.word-table tbody tr:nth-child(even):hover {
    background: var(--bg-tertiary);
}

/* POS filter chips */
.pos-filter-bar {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid var(--border);
    flex-shrink: 0; /* sits in the fixed top stack of .results-body */
}

.pos-filter-chip {
    padding: 0.35rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.15s;
}

.pos-filter-chip:hover {
    background: var(--bg-tertiary);
}

.pos-filter-chip.active {
    background: var(--accent);
    border-color: var(--accent);
    color: white;
}

/* POS pill colors */
.pos-pill {
    display: inline-block;
    padding: 0.15rem 0.5rem;
    border-radius: 4px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.025em;
}

.pos-pill[data-pos="NOUN"],
.pos-pill[data-pos="PROPN"] {
    background: color-mix(in srgb, var(--pos-noun) 15%, transparent);
    color: var(--pos-noun);
}

.pos-pill[data-pos="VERB"],
.pos-pill[data-pos="AUX"] {
    background: color-mix(in srgb, var(--pos-verb) 15%, transparent);
    color: var(--pos-verb);
}

.pos-pill[data-pos="ADJ"] {
    background: color-mix(in srgb, var(--pos-adj) 15%, transparent);
    color: var(--pos-adj);
}

.pos-pill[data-pos="ADV"] {
    background: color-mix(in srgb, var(--pos-adv) 15%, transparent);
    color: var(--pos-adv);
}

.pos-pill[data-pos="PRON"],
.pos-pill[data-pos="DET"] {
    background: color-mix(in srgb, var(--pos-pron) 15%, transparent);
    color: var(--pos-pron);
}

.pos-pill[data-pos="NUM"],
.pos-pill[data-pos="ADP"],
.pos-pill[data-pos="CCONJ"],
.pos-pill[data-pos="SCONJ"],
.pos-pill[data-pos="PART"],
.pos-pill[data-pos="INTJ"],
.pos-pill[data-pos="X"] {
    background: color-mix(in srgb, var(--pos-other) 15%, transparent);
    color: var(--pos-other);
}

/* Grammar badge (inline on lemma cell) */
.grammar-badge {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.4rem;
    background: var(--bg-tertiary);
    border-radius: 3px;
    font-size: 0.7rem;
    color: var(--text-secondary);
    font-style: italic;
    font-weight: normal;
    vertical-align: middle;
}

/* Word actions: known toggle pill + ignore icon button */
.word-actions {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.word-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 0.78rem;
    cursor: pointer;
    user-select: none;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.word-pill:hover:not([disabled]) {
    border-color: var(--accent);
    color: var(--text-primary);
}
.word-pill.is-active {
    background: color-mix(in srgb, var(--accent) 25%, transparent);
    border-color: color-mix(in srgb, var(--accent) 60%, transparent);
    color: var(--text-primary);
}
.word-pill[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}
.word-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    padding: 0;
    border-radius: 999px;
    border: 1px solid var(--border);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.word-icon-btn:hover:not([disabled]) {
    border-color: var(--accent);
    color: var(--text-primary);
}
.word-icon-btn.is-active {
    background: color-mix(in srgb, #d04444 25%, transparent);
    border-color: color-mix(in srgb, #d04444 60%, transparent);
    color: var(--text-primary);
}
.word-icon-btn[disabled] {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Portal tooltip — appended to <body> by initPortalTooltips so it can escape
   ancestor overflow:hidden / overflow-x:auto containers. Appears immediately
   on hover/focus. The trigger element marks itself with [data-tooltip="…"]. */
.portal-tooltip {
    position: fixed;
    transform: translate(-50%, -100%);
    padding: 0.25rem 0.5rem;
    background: var(--text-primary);
    color: var(--card-bg);
    border-radius: 4px;
    font-size: 0.72rem;
    font-weight: 500;
    white-space: nowrap;
    pointer-events: none;
    z-index: 1000;
    opacity: 0;
    transition: opacity 0.05s linear;
}
.portal-tooltip.visible {
    opacity: 1;
}

/* Multi-line variant used by chapter previews (first 50 chars … last 50).
   Left-aligned: anchors its left edge to the trigger via JS-set `left`, so
   transform only handles the vertical lift. */
.portal-tooltip.rich {
    max-width: 320px;
    padding: 0.5rem 0.75rem;
    font-size: 0.8rem;
    font-weight: 400;
    line-height: 1.4;
    white-space: pre-line;
    text-align: left;
    transform: translateY(-100%);
}

.example-text .highlight-form,
.review-example .highlight-form {
    background: color-mix(in srgb, var(--accent) 25%, transparent);
    padding: 0.1rem 0.2rem;
    border-radius: 2px;
    font-weight: 600;
    font-style: normal;
}

/* ── Issue #21: Parser page polish ──────────────────────────────────────── */

/* Button hierarchy: Custom is primary, Basic is outline */
.btn-outline {
    background: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border);
}

.btn-outline:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.parse-buttons .btn-parse[data-parser="custom"] {
    order: -1; /* Put Custom first */
}

.parser-hint {
    display: block;
    font-size: 0.7rem;
    font-weight: normal;
    opacity: 0.8;
    margin-top: 0.15rem;
}

/* Coverage gauge */
.coverage-gauge {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.75rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 999px;
}

.coverage-gauge-label {
    font-size: 0.75rem;
    color: var(--text-secondary);
    font-weight: 500;
}

.coverage-gauge-bar {
    width: 80px;
    height: 6px;
    background: var(--bg-tertiary);
    border-radius: 3px;
    overflow: hidden;
}

.coverage-gauge-fill {
    height: 100%;
    background: var(--success);
    border-radius: 3px;
    transition: width 0.3s ease;
}

.coverage-gauge-fill.low { background: var(--danger); }
.coverage-gauge-fill.medium { background: var(--warning); }
.coverage-gauge-fill.high { background: var(--success); }

.coverage-gauge-value {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--text-primary);
    min-width: 2.5rem;
}

/* ── Post-parse coverage reveal (aha moment #1) ──────────────────────────
   Self-contained block. A queued reading-surface redesign will re-home the
   #coverage-reveal panel; keep this block + renderCoverageReveal() as one
   movable unit. Role tokens only — works across every theme skin. */
.coverage-reveal {
    margin: 0.75rem 0 0.25rem;
}
.coverage-reveal.hidden { display: none; }

.coverage-reveal-inner {
    border: 1px solid color-mix(in srgb, var(--accent) 30%, var(--border));
    background: color-mix(in srgb, var(--accent) 6%, var(--bg-secondary));
    border-radius: 12px;
    padding: 1rem 1.15rem;
}

.coverage-reveal-headline {
    margin: 0 0 0.6rem;
    font-family: var(--font-disp, inherit);
    font-size: 1.35rem;
    line-height: 1.25;
    color: var(--text-primary);
    font-weight: 500;
}

.coverage-reveal-figure {
    color: var(--accent);
    font-weight: 700;
    /* Tabular figures keep the count-up from shifting layout as digits change. */
    font-variant-numeric: tabular-nums;
}

/* Two-segment preview bar: a solid "known" floor + a lighter "gain" preview
   stacked to its right, both animating from 0 on entrance. */
.coverage-reveal-bar {
    display: flex;
    width: 100%;
    height: 10px;
    background: var(--bg-tertiary);
    border-radius: 999px;
    overflow: hidden;
    margin: 0.35rem 0 0.7rem;
}
.coverage-reveal-known {
    height: 100%;
    width: 0;
    background: var(--success);
}
.coverage-reveal-gain {
    height: 100%;
    width: 0;
    background: color-mix(in srgb, var(--accent) 55%, transparent);
}

.coverage-reveal-projection {
    margin: 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
}
.coverage-reveal-projection strong { color: var(--text-primary); }

@media (prefers-reduced-motion: reduce) {
    /* JS collapses to the final frame; also drop any transition so a re-render
       never eases. Widths are set inline by renderCoverageReveal. */
    .coverage-reveal-known,
    .coverage-reveal-gain { transition: none; }
}

/* Toast notifications */
.toast-container {
    position: fixed;
    top: calc(var(--nav-height) + 1rem);
    right: 1rem;
    z-index: 1000;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.toast {
    padding: 0.75rem 1rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 4px 12px var(--shadow);
    font-size: 0.875rem;
    animation: toast-in 0.3s ease;
    max-width: 300px;
}

.toast.info {
    border-left: 4px solid var(--accent);
}

.toast.success {
    border-left: 4px solid var(--success);
}

@keyframes toast-in {
    from {
        opacity: 0;
        transform: translateX(100%);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes toast-out {
    from {
        opacity: 1;
        transform: translateX(0);
    }
    to {
        opacity: 0;
        transform: translateX(100%);
    }
}

.toast.hiding {
    animation: toast-out 0.3s ease forwards;
}

.toast.error {
    border-left: 4px solid var(--danger);
}

/* ============================================================
   PR-3: Role-based visibility, nav, and surfaces
   ============================================================ */

/* Generic role gate — JS toggles .role-hidden on [data-role-show] elements */
.role-hidden { display: none !important; }

/* While auth is resolving, hide everything that depends on role to avoid flash */
body[data-auth-state="loading"] [data-role-show] { display: none !important; }

/* ── Buttons (size + block variants) ─────────────────────────── */
.btn-lg {
    padding: 0.875rem 1.75rem;
    font-size: 1.05rem;
}
.btn-sm {
    padding: 0.4rem 0.75rem;
    font-size: 0.85rem;
}
.btn-block {
    display: block;
    width: 100%;
    text-align: center;
}

/* ── Navigation: user menu + admin cluster ──────────────────── */
.nav-user-menu {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.nav-user-email {
    color: var(--text-secondary);
    font-size: 0.9rem;
    max-width: 14rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.nav-admin {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding-left: 0.75rem;
    margin-left: 0.5rem;
    border-left: 1px solid var(--border);
}
.nav-admin-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--warning);
    font-weight: 600;
}
.nav-link-admin {
    color: var(--text-secondary);
}
.nav-link-admin:hover {
    color: var(--warning);
}
.nav-mobile-divider {
    margin-top: 1.25rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
    color: var(--warning);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}
.nav-mobile-link-admin {
    color: var(--warning) !important;
}
.nav-mobile-cta {
    color: var(--accent) !important;
    font-weight: 600;
}
.nav-mobile-signout {
    background: none;
    border: 0;
    cursor: pointer;
    text-align: left;
    width: 100%;
    color: var(--text-secondary);
    font: inherit;
}

/* ── Anonymous landing ──────────────────────────────────────── */
.landing-main {
    max-width: 1100px;
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
}
.hero-section {
    text-align: center;
    padding: 3rem 0 2.5rem;
}
.hero-title {
    font-size: clamp(2rem, 5vw, 3.25rem);
    line-height: 1.15;
    margin-bottom: 1.25rem;
    color: var(--text-primary);
    letter-spacing: -0.02em;
}
.hero-subtitle {
    font-size: 1.15rem;
    color: var(--text-secondary);
    max-width: 38rem;
    margin: 0 auto 2rem;
}
.hero-cta {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

/* Anonymous landing parse form — the public demo. Sits under the hero copy,
   above the value grid. Left-aligned inside a centered card so the textarea
   and controls read like a form rather than centered marketing text. */
.landing-parse-form {
    max-width: 40rem;
    margin: 2rem auto 0;
    text-align: left;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.5rem;
}
.landing-lang-group {
    margin-bottom: 1rem;
}
.landing-parse-form textarea {
    width: 100%;
    resize: vertical;
}
.landing-upload-hint {
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}
.landing-form-actions {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: 1rem;
}

/* Anonymous-only results chrome: sign-up ribbon + privacy footer. */
.anon-signup-ribbon {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    background: var(--card-bg);
    border: 1px solid var(--accent);
    border-radius: 10px;
    padding: 0.9rem 1.1rem;
    margin-bottom: 1.25rem;
}
.anon-ribbon-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}
.anon-ribbon-text strong {
    color: var(--text-primary);
}
.anon-ribbon-text span {
    font-size: 0.9rem;
    color: var(--text-secondary);
}
.anon-ribbon-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
}
.anon-privacy-footer {
    margin: 1.25rem 0 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
}

.value-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1.25rem;
    margin: 3rem 0;
}
.value-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.5rem;
}
.value-card h3 {
    margin: 0.75rem 0 0.5rem;
    font-size: 1.1rem;
}
.value-card p {
    color: var(--text-secondary);
    font-size: 0.95rem;
}
.value-icon {
    font-size: 2rem;
    line-height: 1;
}
.landing-cta-section {
    text-align: center;
    padding: 3rem 0 1rem;
}
.landing-cta-section h2 {
    margin-bottom: 1.25rem;
    font-size: 1.5rem;
}
.landing-cta-lede {
    max-width: 46ch;
    margin: 0 auto 1.5rem;
    color: var(--text-secondary);
    line-height: 1.55;
}

/* ── About / how it works ───────────────────────────────────── */
.about-main {
    max-width: 820px;
    margin: 0 auto;
    padding: 3rem 1.5rem 4rem;
}
.about-hero {
    text-align: center;
    margin-bottom: 3rem;
}
.about-hero h1 {
    font-size: clamp(1.75rem, 4vw, 2.5rem);
    margin-bottom: 1rem;
}
.about-lede {
    color: var(--text-secondary);
    font-size: 1.1rem;
    max-width: 36rem;
    margin: 0 auto;
}
.about-steps {
    display: grid;
    gap: 1.25rem;
    margin-bottom: 3rem;
}
.about-step {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.5rem 1.5rem 1.5rem 4.5rem;
    position: relative;
}
.about-step-num {
    position: absolute;
    left: 1.25rem;
    top: 1.25rem;
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 50%;
    background: var(--accent);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
}
.about-step h3 {
    margin: 0 0 0.4rem;
    font-size: 1.1rem;
}
.about-step p {
    color: var(--text-secondary);
    margin: 0;
    font-size: 0.95rem;
}

/* ── Sign-in ────────────────────────────────────────────────── */
.signin-main {
    max-width: 420px;
    margin: 0 auto;
    padding: 4rem 1.5rem;
}
.signin-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 2rem;
    box-shadow: 0 2px 12px var(--shadow);
}
.signin-card h1 {
    text-align: center;
    margin-bottom: 0.5rem;
    font-size: 1.6rem;
}
.signin-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 1.25rem;
    border-bottom: 1px solid var(--border);
}
.signin-tab {
    flex: 1;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0.75rem 0.5rem;
    color: var(--text-secondary);
    font-size: 0.95rem;
    font-weight: 500;
    cursor: pointer;
    transition: color 0.15s, border-color 0.15s;
}
.signin-tab:hover {
    color: var(--text-primary);
}
.signin-tab.active {
    color: var(--text-primary);
    border-bottom-color: var(--accent, #2563eb);
}
.admin-users-main {
    max-width: 960px;
    margin: 0 auto;
    padding: 2rem 1.5rem;
}
.admin-users-header {
    margin-bottom: 1.5rem;
}
.admin-users-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--border);
    border-radius: 8px;
}
.admin-users-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.95rem;
}
.admin-users-table th,
.admin-users-table td {
    padding: 0.75rem 1rem;
    text-align: left;
    border-bottom: 1px solid var(--border);
}
.admin-users-table thead th {
    background: var(--card-bg);
    font-weight: 600;
    color: var(--text-secondary);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.admin-users-table tbody tr:last-child td {
    border-bottom: none;
}
.admin-users-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
    user-select: none;
}
.admin-users-toggle input:disabled + span {
    opacity: 0.5;
    cursor: not-allowed;
}
.signin-lede {
    color: var(--text-secondary);
    text-align: center;
    margin-bottom: 1.5rem;
    font-size: 0.95rem;
}
.signin-error {
    background: rgba(239, 68, 68, 0.08);
    border: 1px solid var(--danger);
    color: var(--danger);
    padding: 0.625rem 0.875rem;
    border-radius: 6px;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}
.signin-switch {
    text-align: center;
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin-top: 1.25rem;
}
.form-hint {
    color: var(--text-secondary);
    font-weight: 400;
    font-size: 0.85rem;
}

/* ── Dashboard ──────────────────────────────────────────────── */
.dashboard-main {
    max-width: 980px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.dashboard-header h1 {
    font-size: 1.75rem;
    margin-bottom: 0.4rem;
}
.dashboard-lede {
    color: var(--text-secondary);
    margin-bottom: 2rem;
}
.dashboard-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 1rem;
    margin-bottom: 2.5rem;
}
.stat-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.25rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.stat-label {
    color: var(--text-secondary);
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.stat-value {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--accent);
}
.dashboard-actions {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-bottom: 2.5rem;
}
.action-card {
    display: block;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1.25rem 1.5rem;
    color: inherit;
    text-decoration: none;
    transition: border-color 0.15s, transform 0.15s;
}
.action-card:hover {
    border-color: var(--accent);
    transform: translateY(-1px);
}
.action-card h3 {
    margin: 0 0 0.4rem;
    font-size: 1.05rem;
    color: var(--accent);
}
.action-card p {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0;
}
.dashboard-activity {
    margin-bottom: 2.5rem;
}
.dashboard-activity h2 {
    font-size: 1.15rem;
    margin-bottom: 1rem;
}
.activity-chart {
    display: flex;
    align-items: flex-end;
    gap: 0.35rem;
    height: 110px;
    padding: 0.75rem 1rem 0.5rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
}
.activity-bar-slot {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    height: 100%;
    min-width: 0;
}
.activity-bar {
    width: 100%;
    max-width: 28px;
    border-radius: 3px 3px 0 0;
    background: var(--accent);
    opacity: 0.85;
}
.activity-count {
    margin-top: 0.2rem;
    font-size: 0.65rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
    min-height: 0.9rem;
}
.dashboard-decks {
    margin-top: 1rem;
}
.dashboard-decks h2 {
    font-size: 1.15rem;
    margin-bottom: 1rem;
}
.dashboard-decks-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}
.deck-card {
    display: block;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1rem 1.25rem;
    color: inherit;
    text-decoration: none;
}
.deck-card h4 {
    margin: 0 0 0.25rem;
    font-size: 1rem;
}
.deck-meta {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0;
}
.empty-state {
    color: var(--text-secondary);
    font-style: italic;
}

/* ── Embedded Text catalog (cold start) ─────────────────────── */
.dashboard-cold-start,
.inspect-catalog {
    margin-top: 1.5rem;
}
.dashboard-cold-start h2,
.inspect-catalog h2 {
    font-size: 1.15rem;
    margin-bottom: 0.35rem;
}
.cold-start-lede {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0 0 1rem;
}
.cold-start-alt {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0.85rem 0 0;
}
.catalog-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 0.75rem;
}
.catalog-card {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1rem 1.25rem;
}
.catalog-card-head {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
}
.catalog-tag {
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 0.12rem 0.5rem;
    border-radius: 999px;
    border: 1px solid var(--border);
    color: var(--text-secondary);
}
.catalog-diff-easy        { color: #1a7f37; border-color: #1a7f3755; }
.catalog-diff-easy-medium  { color: #4d7c0f; border-color: #4d7c0f55; }
.catalog-diff-medium       { color: #9a6700; border-color: #9a670055; }
.catalog-diff-medium-hard  { color: #c2410c; border-color: #c2410c55; }
.catalog-diff-hard         { color: #b3261e; border-color: #b3261e55; }
.catalog-attribution { margin-top: 0.5rem; font-size: 0.72rem; opacity: 0.65; line-height: 1.35; }
.catalog-title {
    margin: 0.1rem 0 0;
    font-size: 1rem;
}
.catalog-meta {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0;
}
.catalog-fit {
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-primary, inherit);
}
.catalog-fit-prompt {
    font-weight: 500;
}
.catalog-load {
    margin-top: 0.5rem;
    align-self: flex-start;
}

/* ── Parse history ──────────────────────────────────────────── */
.history-main {
    max-width: 980px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.history-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.5rem;
}
.history-header h1 {
    font-size: 1.75rem;
    margin-bottom: 0.5rem;
}
.history-lede {
    color: var(--text-secondary);
    margin: 0;
}
.history-list {
    display: grid;
    gap: 0.75rem;
}
.history-row {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 1rem 1.25rem;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 1rem;
    align-items: start;
}
.history-row-main {
    min-width: 0;
}
.history-row-meta {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0 0 0.45rem;
}
.history-row-preview {
    margin: 0;
    overflow-wrap: anywhere;
}
.history-row-counts {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0.45rem 0 0;
}

/* ── Inspect (lightweight user parse) ───────────────────────── */
.inspect-main {
    max-width: 760px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.inspect-header h1 {
    font-size: 1.75rem;
    margin-bottom: 0.5rem;
}
.inspect-lede {
    color: var(--text-secondary);
    margin-bottom: 2rem;
}
.inspect-form {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}
.parse-privacy-chip {
    margin: 0.75rem 0 0;
    padding: 0.625rem 0.75rem;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    color: var(--text-secondary);
    background: var(--surface-subtle);
    font-size: 0.875rem;
    line-height: 1.4;
}

/* ── Decks ───────────────────────────────────────────────────── */
.decks-main,
.review-main,
.languages-main {
    max-width: 980px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.decks-header h1,
.known-words-header h2,
.review-header h1,
.languages-header h1,
.placeholder-main h1 {
    font-size: 1.75rem;
    margin-bottom: 0.5rem;
}
.decks-lede,
.known-words-lede,
.review-lede,
.languages-lede,
.placeholder-lede {
    color: var(--text-secondary);
    margin-bottom: 1.5rem;
}
.known-words-lang-hint {
    color: var(--text-secondary);
    font-size: 0.88rem;
    margin: 0.25rem 0 0;
}
.languages-list {
    display: grid;
    gap: 0.75rem;
    margin-bottom: 2rem;
}
.language-row {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1rem 1.25rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}
.language-row-info {
    display: flex;
    align-items: center;
    gap: 0.85rem;
}

.language-row-flag {
    display: inline-flex;
    align-items: center;
    font-size: 2rem;
    line-height: 1;
}

.language-row-flag .lang-flag {
    border-radius: 4px;
}

.language-row-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.languages-section-heading {
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-secondary);
    font-weight: 700;
    margin: 1.25rem 0 0.5rem;
}

.languages-section-heading:first-child {
    margin-top: 0;
}
.language-row-name {
    font-weight: 600;
    font-size: 1.05rem;
}
.language-row-sub {
    color: var(--text-secondary);
    font-size: 0.85rem;
}
.language-row-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.language-row.is-active {
    border-color: var(--accent);
    background: color-mix(in srgb, var(--accent) 6%, var(--card-bg));
}
.language-row-active-badge {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--accent);
    font-weight: 700;
}
.languages-note {
    color: var(--text-secondary);
    font-size: 0.88rem;
}
.languages-account {
    margin-top: 2.5rem;
}
.account-delete {
    color: #dc2626;
    border-color: color-mix(in srgb, #dc2626 45%, transparent);
}
.account-delete:hover {
    background: color-mix(in srgb, #dc2626 8%, transparent);
    border-color: #dc2626;
}
.decks-list {
    display: grid;
    gap: 1rem;
}
.deck-list-item {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.25rem 1.5rem;
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: flex-start;
}
.deck-list-item h2 {
    margin: 0 0 0.35rem;
    font-size: 1.1rem;
}
.deck-list-title {
    color: inherit;
    text-decoration: none;
}
.deck-list-title:hover,
.deck-list-title:focus {
    text-decoration: underline;
}
.deck-list-meta {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.deck-list-actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: flex-end;
}
.deck-badge {
    display: inline-block;
    margin-left: 0.4rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    vertical-align: middle;
}
.deck-badge-official {
    background: var(--accent-soft, rgba(37, 99, 235, 0.12));
    color: var(--accent, #2563eb);
}
.deck-badge-subscribed {
    background: rgba(34, 197, 94, 0.12);
    color: rgb(22, 163, 74);
}
.results-save-public {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.5rem;
    font-size: 0.9rem;
    color: var(--text-secondary);
}
.known-words-panel {
    margin-top: 2rem;
    padding-top: 2rem;
    border-top: 1px solid var(--border);
    display: grid;
    gap: 1rem;
}
.known-words-header {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: end;
}
.known-words-lang {
    min-width: 180px;
}
.known-words-lang .form-group-label,
.known-words-lang label,
.known-words-form label {
    display: block;
    font-size: 0.82rem;
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
    font-weight: 500;
}
.known-words-form textarea {
    width: 100%;
}
.known-words-form {
    display: grid;
    gap: 0.6rem;
}
.known-words-actions {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}
.known-words-summary,
.known-words-unresolved {
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.known-words-unresolved {
    border-left: 3px solid var(--warning);
    padding-left: 0.85rem;
}
.known-words-list {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
.known-word-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.3rem 0.45rem 0.3rem 0.7rem;
    background: var(--card-bg);
}
.known-word-pos {
    color: var(--text-secondary);
    font-size: 0.78rem;
}
.known-word-delete {
    width: 1.35rem;
    height: 1.35rem;
    border: 1px solid var(--border);
    border-radius: 50%;
    background: var(--bg-secondary);
    color: var(--text-secondary);
    cursor: pointer;
    line-height: 1;
}
.known-word-delete:hover {
    color: var(--danger);
    border-color: var(--danger);
}

@media (max-width: 760px) {
    .known-words-header {
        align-items: stretch;
        flex-direction: column;
    }
}

/* ── Vocab page ─────────────────────────────────────────────── */
.vocab-main {
    max-width: 1080px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.vocab-header {
    display: flex;
    justify-content: space-between;
    gap: 1.5rem;
    align-items: end;
    margin-bottom: 1.5rem;
}
.vocab-header h1 {
    font-size: 1.75rem;
    margin: 0 0 0.5rem;
}
.vocab-lede {
    color: var(--text-secondary);
    margin: 0;
    max-width: 640px;
}
.vocab-stats {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}
.vocab-import-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 1rem;
    margin-bottom: 2.5rem;
}
.vocab-import-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 14px;
    padding: 1.25rem 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}
.vocab-import-card h2 {
    margin: 0;
    font-size: 1.1rem;
}
.vocab-import-lede {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.vocab-import-lede a {
    color: var(--accent);
}
.vocab-import-card textarea,
.vocab-import-card select {
    width: 100%;
}
.vocab-file-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.6rem;
    border: 2px dashed var(--border);
    border-radius: 14px;
    padding: 2.5rem 1.5rem;
    min-height: 180px;
    cursor: pointer;
    transition: border-color 0.15s, background-color 0.15s;
}
.vocab-file-cta:hover,
.vocab-file-cta.is-drag {
    border-color: var(--accent);
    background-color: var(--bg-secondary);
}
.vocab-file-icon {
    font-size: 2.75rem;
    line-height: 1;
}
.vocab-file-text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.vocab-file-text strong {
    font-weight: 600;
    font-size: 1.05rem;
}
.vocab-file-sub {
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.vocab-anki-step {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}
.vocab-anki-buttons {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}
/* Small underlined link beneath the connect/sync buttons that opens the
   Anki import settings popup. Same treatment as the "Setup instructions"
   link so the two read as peers. */
.vocab-anki-link {
    display: inline-block;
    margin-top: 0.4rem;
    align-self: flex-start;
    font-size: 0.85rem;
    color: var(--accent);
    text-decoration: underline;
}
.vocab-anki-link:hover { text-decoration: none; }

/* The settings popup can open ON TOP of the import modal (via the step-2
   "Import settings" link). Both share the .modal z-index (2000); since the
   import modal comes later in the DOM it would otherwise win the stacking
   contest and swallow clicks. Lift the settings modal above it. */
#anki-settings-modal {
    z-index: 2100;
}
.anki-settings-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    margin: 0.5rem 0 1rem;
}
.vocab-anki-help {
    margin-top: auto;
    align-self: flex-start;
    font-size: 0.88rem;
    color: var(--accent);
    text-decoration: underline;
}
.vocab-anki-help:hover {
    text-decoration: none;
}
.anki-setup-steps {
    margin: 0 0 1rem;
    padding-left: 1.25rem;
    display: grid;
    gap: 0.75rem;
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.45;
}
.anki-setup-steps strong {
    color: var(--text-primary);
}
.anki-setup-steps a {
    color: var(--accent);
}
.anki-setup-code {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.1rem 0.4rem;
    font-family: var(--font-mono, monospace);
    font-size: 0.9em;
    user-select: all;
}
.anki-setup-steps kbd {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-bottom-width: 2px;
    border-radius: 5px;
    padding: 0.05rem 0.45rem;
    font-family: var(--font-mono, monospace);
    font-size: 0.85em;
    color: var(--text-primary);
}
.anki-setup-substeps {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
    display: grid;
    gap: 0.5rem;
    list-style-type: lower-alpha;
}
.anki-setup-config {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 1rem;
    margin: 0.5rem 0 0;
    font-family: var(--font-mono, monospace);
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text-primary);
    overflow-x: auto;
    white-space: pre;
    user-select: all;
}
.anki-setup-config-finnest {
    color: rgb(34, 197, 94);
    font-weight: 600;
}
.anki-setup-copy-wrap {
    position: relative;
}
.anki-setup-copy-btn {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 1;
}
.anki-setup-copy {
    padding-right: 5.5rem;
}
.vocab-list-section h2 {
    font-size: 1.15rem;
    margin: 0 0 0.75rem;
}
.vocab-list-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.5rem;
}
.vocab-list-header h2 {
    margin: 0;
}
.vocab-delete-all {
    color: var(--danger);
    border-color: var(--danger);
}
.vocab-delete-all:hover:not(:disabled) {
    background: var(--danger);
    color: white;
}
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

@media (max-width: 760px) {
    .vocab-header {
        flex-direction: column;
        align-items: stretch;
    }
}

/* ── Review ─────────────────────────────────────────────────── */
.review-header {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: end;
    margin-bottom: 1.5rem;
}
.review-filter {
    min-width: 220px;
}
.review-filter label {
    display: block;
    font-size: 0.82rem;
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}
.review-filter select {
    width: 100%;
}
.review-card {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 1.5rem;
    display: grid;
    gap: 1.25rem;
}
.review-card-front,
.review-card-back {
    display: grid;
    gap: 0.75rem;
}
.review-front-text {
    margin: 0;
    font-size: 1.3rem;
    line-height: 1.5;
}
.review-card-back h2 {
    margin: 0;
    font-size: 1.2rem;
}
.review-pos {
    color: var(--text-secondary);
    font-size: 0.82rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.review-meaning {
    margin: 0;
    color: var(--text-secondary);
}
.review-decks {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}
.review-deck-pill {
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.25rem 0.6rem;
    font-size: 0.82rem;
    color: var(--text-secondary);
}
/* The example sentence is the card's richest context: shown first in the
   back, larger and higher-contrast than the supporting metadata below it.
   The target occurrence form is bolded via the same .highlight-form token
   used elsewhere (parse results, deck detail examples). */
.review-example {
    border-left: 3px solid var(--accent);
    padding-left: 0.85rem;
    color: var(--text-primary);
    font-size: 1.1rem;
    line-height: 1.5;
}
.review-example-source {
    display: block;
    margin-top: 0.35rem;
    color: var(--text-secondary);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}
.review-actions,
.review-secondary-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* ── Placeholders (empty states) ────────────────────────────── */
.placeholder-main {
    max-width: 720px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.placeholder-card {
    background: var(--card-bg);
    border: 1px dashed var(--border);
    border-radius: 12px;
    padding: 2rem;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    color: var(--text-secondary);
}

/* ── Admin feedback ─────────────────────────────────────────── */
.admin-feedback-main {
    max-width: 1040px;
    margin: 0 auto;
    padding: 2.5rem 1.5rem 4rem;
}
.admin-feedback-header {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    align-items: end;
    margin-bottom: 1.5rem;
}
.admin-feedback-filter {
    min-width: 220px;
}
.admin-feedback-filter label {
    display: block;
    font-size: 0.82rem;
    color: var(--text-secondary);
    margin-bottom: 0.35rem;
}
.admin-feedback-filter select {
    width: 100%;
}
.admin-feedback-list {
    display: grid;
    gap: 1rem;
}
.admin-feedback-item {
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    padding: 1rem;
    display: grid;
    gap: 1rem;
}
.admin-feedback-item-header {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
}
.admin-feedback-item h2 {
    margin: 0 0 0.25rem;
    font-size: 1.2rem;
}
.admin-feedback-meta,
.admin-feedback-note,
.admin-feedback-review-note {
    margin: 0;
    color: var(--text-secondary);
    font-size: 0.9rem;
}
.admin-feedback-status {
    align-self: flex-start;
    border: 1px solid var(--border);
    border-radius: 999px;
    padding: 0.25rem 0.6rem;
    font-size: 0.82rem;
    color: var(--text-secondary);
    white-space: nowrap;
}
.admin-feedback-flag-badge {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 600;
    vertical-align: middle;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    color: var(--text-secondary);
}
.admin-feedback-correction-inputs {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.35rem;
}
.admin-feedback-correction-inputs input,
.admin-feedback-correction-inputs select {
    padding: 0.45rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    font-size: 0.9rem;
}
.admin-feedback-correction-inputs input {
    flex: 1 1 auto;
    min-width: 0;
}
.admin-feedback-correction-hint {
    margin: 0.35rem 0 0;
    font-size: 0.78rem;
    color: var(--text-secondary);
}
.admin-feedback-comparison {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1rem;
}
.admin-feedback-comparison > div {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.85rem;
}
.admin-feedback-comparison p {
    margin: 0.25rem 0 0;
}
.admin-feedback-label {
    color: var(--text-secondary);
    font-size: 0.78rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.admin-feedback-actions {
    display: grid;
    grid-template-columns: minmax(220px, 1fr) auto auto auto;
    gap: 0.75rem;
    align-items: center;
}
.admin-feedback-review-input {
    width: 100%;
    padding: 0.65rem;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: var(--bg-primary);
    color: var(--text-primary);
}

@media (max-width: 760px) {
    .admin-feedback-header,
    .admin-feedback-item-header {
        align-items: stretch;
        flex-direction: column;
    }
    .admin-feedback-comparison,
    .admin-feedback-actions {
        grid-template-columns: 1fr;
    }
}

/* ── Results deck CTA ───────────────────────────────────────── */
.results-deck-cta {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
    margin-top: 1rem;
}
.results-save-form {
    width: 100%;
    max-width: 420px;
    display: grid;
    gap: 0.6rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--border);
    border-radius: 12px;
    background: var(--bg-elevated);
}
.results-save-form.hidden {
    display: none;
}
.results-save-form label {
    font-size: 0.85rem;
    color: var(--text-secondary);
}
.results-save-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
}

/* ── Admin banner ───────────────────────────────────────────── */
.admin-banner {
    background: rgba(245, 158, 11, 0.12);
    border-bottom: 1px solid var(--warning);
    padding: 0.5rem 1.5rem;
    font-size: 0.85rem;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.admin-banner-label {
    background: var(--warning);
    color: #1a1a1a;
    padding: 0.1rem 0.5rem;
    border-radius: 4px;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    text-transform: uppercase;
}

/* ── Correction modal ───────────────────────────────────────── */
.modal {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
}
.modal.hidden { display: none; }
.modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
}
.modal-card {
    position: relative;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 10px 40px var(--shadow);
    padding: 1.75rem;
    width: 100%;
    max-width: 460px;
    max-height: 90vh;
    overflow-y: auto;
}
.modal-close {
    position: absolute;
    top: 0.5rem;
    right: 0.75rem;
    background: none;
    border: 0;
    font-size: 1.5rem;
    color: var(--text-secondary);
    cursor: pointer;
    line-height: 1;
}
.modal-card h3 {
    margin-bottom: 0.5rem;
}
.modal-lede {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin-bottom: 1.25rem;
}
.modal-hint {
    background: var(--bg-secondary);
    border-left: 3px solid var(--accent);
    color: var(--text-secondary);
    font-size: 0.85rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 1rem;
    border-radius: 4px;
}
.modal-readonly {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 0.5rem 0.75rem;
    font-family: ui-monospace, Menlo, monospace;
}
.modal-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
    margin-top: 1.25rem;
}
.correction-mode {
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.75rem 0.85rem;
}
.correction-mode legend {
    padding: 0 0.35rem;
    font-size: 0.82rem;
    color: var(--text-secondary);
}
.correction-mode-option {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    padding: 0.25rem 0;
    cursor: pointer;
}
.correction-mode-option input {
    margin-top: 0.2rem;
}

/* ── Results "Suggest fix" cell ─────────────────────────────── */
.col-actions {
    text-align: right;
    white-space: nowrap;
    min-width: 13rem;
}
.word-actions {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 0.35rem;
    flex-wrap: wrap;
}
.word-state-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.15rem 0.45rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 700;
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}
.word-state-badge.known {
    background: rgba(16, 185, 129, 0.12);
    color: var(--success);
}
.word-state-badge.ignored {
    background: rgba(107, 114, 128, 0.16);
    color: var(--text-secondary);
}
.correction-btn {
    color: var(--accent);
    padding: 0.25rem 0.5rem;
}
.word-state-btn {
    padding: 0.25rem 0.35rem;
    text-decoration: none;
}
.word-state-btn[data-lemma-status="ignored"] {
    color: var(--text-secondary);
}
.word-state-btn:disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

/* ── Mobile (375 px) tweaks ─────────────────────────────────── */
@media (max-width: 600px) {
    .nav-user-email { display: none; }
    .nav-admin { display: none; }     /* admin nav surfaces via mobile menu */
    .hero-section { padding: 1.5rem 0 1.5rem; }
    .hero-cta { flex-direction: column; align-items: stretch; }
    .hero-cta .btn { width: 100%; }
    .value-grid { grid-template-columns: 1fr; }
    .dashboard-stats { grid-template-columns: repeat(2, 1fr); }
    .dashboard-actions { grid-template-columns: 1fr; }
    .history-header { flex-direction: column; }
    .history-row { grid-template-columns: 1fr; }
    .history-row .btn { width: 100%; }
    /* Narrow the results-table columns so row + lemma + count + actions fit
       close to a 375px viewport instead of forcing horizontal table scroll
       just to reach the known/ignore/correction controls, which were
       previously pinned off the right edge by a 13rem min-width carried
       over from desktop. */
    .col-row     { width: 2rem; }
    .col-lemma   { width: 7.5rem; }
    .col-count   { width: 4rem; }
    .col-count .sort-btn { white-space: normal; }
    .col-actions { width: 9.5rem; min-width: 9.5rem; padding-left: 0.25rem; padding-right: 0.25rem; }
    .word-actions { justify-content: flex-start; }
    .col-actions .correction-btn,
    .col-actions .word-state-btn { padding: 0.25rem 0.25rem; font-size: 0.85rem; }
    .results-meta { flex-wrap: wrap; gap: 0.5rem; }
    .modal-card { padding: 1.25rem; }
    /* The ambiguity panel lives in a colspan cell that otherwise inherits
       the (wider) fixed table-column widths above; clamp it to the
       scroll container's own width so candidate rows and their actions
       stay reachable without being clipped past the viewport edge. */
    .ambiguity-panel { max-width: calc(100vw - 3rem); }
    .ambiguity-candidate-actions button { min-height: 2rem; padding: 0.35rem 0.55rem; }
}

/* ============================================================
   Design v2 alignment
   Mirrors the ink/paper visual system from design/finnest v2.html
   while preserving the vanilla TS app and API-backed DOM.
   ============================================================ */

:root,
[data-theme="dark"] {
    --bg-primary: oklch(0.165 0.008 250);
    --bg-secondary: oklch(0.21 0.008 250);
    --bg-tertiary: oklch(0.25 0.010 250);
    --text-primary: oklch(0.96 0.005 90);
    --text-secondary: oklch(0.72 0.008 90);
    --accent: oklch(0.72 0.19 38);
    --accent-hover: oklch(0.80 0.14 85);
    --border: oklch(0.30 0.010 250);
    --card-bg: oklch(0.165 0.008 250);
    --shadow: rgba(0, 0, 0, 0.35);
    --success: oklch(0.78 0.13 145);
    --warning: oklch(0.80 0.14 85);
    --danger: oklch(0.64 0.18 28);
    --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    --font-sans: "IBM Plex Sans", -apple-system, "Segoe UI", system-ui, sans-serif;
    --font-disp: "Fraunces", "Times New Roman", serif;
    --nav-height: 56px;
}

[data-theme="light"] {
    --bg-primary: oklch(0.97 0.005 85);
    --bg-secondary: oklch(1 0 0);
    --bg-tertiary: oklch(0.92 0.005 85);
    --text-primary: oklch(0.18 0.008 250);
    --text-secondary: oklch(0.42 0.010 250);
    --accent: oklch(0.55 0.19 35);
    --accent-hover: oklch(0.62 0.14 80);
    --border: oklch(0.82 0.008 85);
    --card-bg: oklch(0.97 0.005 85);
    --shadow: rgba(25, 23, 19, 0.10);
}

html,
body {
    min-height: 100%;
    background: var(--bg-primary);
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: 14px;
    line-height: 1.45;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

body {
    overflow-x: hidden;
}

a {
    color: inherit;
}

::selection {
    background: var(--accent);
    color: oklch(0.125 0.008 250);
}

.global-nav {
    background: var(--bg-primary);
    border-bottom: 1px solid var(--border);
}

.nav-content {
    max-width: none;
    padding: 0 24px;
    gap: 24px;
}

.nav-logo {
    font-family: var(--font-disp);
    font-size: 0;
    font-weight: 800;
    line-height: 1;
    color: var(--text-primary);
    letter-spacing: 0;
}

.nav-logo::before {
    content: "FinnEst";
    font-size: 22px;
}

.nav-logo::after {
    content: ".";
    color: var(--accent);
    font-size: 22px;
}

.nav-links {
    flex: 0 0 auto;
    gap: 2px;
}

.nav-link {
    padding: 8px 14px;
    color: var(--text-secondary);
    border-radius: 4px;
    font-size: 13px;
    line-height: 1;
}

.nav-link:hover,
.nav-link.active {
    color: var(--text-primary);
    background: transparent;
}

.nav-link.active {
    box-shadow: inset 0 -2px 0 var(--accent);
}

.nav-admin {
    border-left-color: var(--border);
}

.nav-actions {
    margin-left: auto;
}

.nav-icon-btn,
.theme-toggle {
    width: 32px;
    height: 32px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: var(--text-secondary);
}

.nav-icon-btn:hover,
.theme-toggle:hover {
    background: var(--bg-secondary);
    color: var(--text-primary);
}

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.45rem;
    min-height: 32px;
    padding: 6px 12px;
    border: 1px solid var(--border);
    border-radius: 4px;
    background: transparent;
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: 12.5px;
    font-weight: 500;
    line-height: 1;
    text-decoration: none;
}

.btn:hover {
    border-color: var(--text-secondary);
    color: var(--text-primary);
}

.btn-primary {
    background: var(--accent);
    border-color: var(--accent);
    color: oklch(0.125 0.008 250);
    font-weight: 700;
}

.btn-primary:hover {
    background: var(--accent-hover);
    border-color: var(--accent-hover);
    color: oklch(0.125 0.008 250);
}

.btn-outline,
.btn-secondary {
    background: transparent;
    color: var(--text-secondary);
}

.btn-link {
    border-color: transparent;
    color: var(--text-secondary);
    text-decoration: none;
}

.btn-lg {
    min-height: 40px;
    padding: 10px 18px;
    font-size: 14px;
}

.page {
    background: var(--bg-primary);
}

.landing-main,
.about-main,
.dashboard-main,
.inspect-main,
.decks-main,
.review-main,
.admin-main {
    max-width: 1180px;
    margin: 0 auto;
    padding: 32px 32px 80px;
}
/* `.results-main` intentionally excluded — it owns its own viewport-locked
   flex layout (see the dedicated rule near the top of this file). */

.hero-section {
    min-height: calc(100vh - var(--nav-height) - 240px);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: flex-start;
    padding: 48px 0 36px;
    text-align: left;
}

.hero-section::before {
    content: "live parser";
    display: inline-flex;
    align-items: center;
    margin-bottom: 18px;
    padding: 5px 9px;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-secondary);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}

.hero-title {
    max-width: 980px;
    margin-bottom: 18px;
    color: var(--text-primary);
    font-family: var(--font-disp);
    font-size: clamp(44px, 8vw, 112px);
    font-weight: 800;
    line-height: 0.93;
    letter-spacing: 0;
}

.hero-subtitle {
    max-width: 720px;
    margin: 0 0 24px;
    color: var(--text-secondary);
    font-size: clamp(17px, 2vw, 22px);
    line-height: 1.35;
}

.hero-cta {
    justify-content: flex-start;
}

.value-grid,
.dashboard-stats,
.dashboard-actions,
.about-steps {
    gap: 1px;
    background: var(--border);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.value-card,
.stat-card,
.action-card,
.about-step,
.signin-card,
.placeholder-card,
.review-card,
.known-words-card,
.results-save-form,
.modal-card {
    background: var(--bg-secondary);
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

/* Modal popups float on a backdrop, not inline with the flat-card grid — give
   them the rounded sitewide popup treatment instead of the squared card look. */
.modal-card {
    border-radius: 14px;
}

/* Spinner that lives inside the dialog Confirm button. Uses currentColor so
   it picks up whatever text colour the button is rendering (primary in the
   normal case, button-on-danger in the destructive variant). */
.dialog-btn-spinner {
    display: inline-block;
    width: 0.9em;
    height: 0.9em;
    margin-right: 0.5em;
    border: 2px solid currentColor;
    border-top-color: transparent;
    border-radius: 50%;
    animation: dialog-modal-spin 0.8s linear infinite;
    vertical-align: -0.15em;
}
@keyframes dialog-modal-spin {
    to { transform: rotate(360deg); }
}
.dialog-modal-remember {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.75rem 0 0;
    font-size: 0.9rem;
    color: var(--text-secondary);
    cursor: pointer;
    user-select: none;
}
.dialog-modal-remember.hidden {
    display: none;
}
.dialog-modal-remember input {
    margin: 0;
    cursor: pointer;
}

/* ── Anki import modal ──────────────────────────────────────── */
.modal-card-wide {
    max-width: 620px;
}
.anki-import-stage {
    display: flex;
    flex-direction: column;
    gap: 0.85rem;
}
.anki-import-stage.hidden {
    display: none;
}
.anki-import-toolbar {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.anki-import-filter {
    flex: 1;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    font-size: 0.9rem;
}
.anki-import-filter:focus {
    outline: none;
    border-color: var(--accent);
}
.anki-import-tree-wrap {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 0.5rem;
    max-height: 360px;
    overflow-y: auto;
}
.anki-import-tree {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}
.anki-deck-children {
    display: contents;
}
.anki-deck-row {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.2rem 0.35rem;
    padding-left: calc(0.35rem + (var(--anki-depth, 0) * 1.1rem));
    border-radius: 6px;
}
.anki-deck-row:hover {
    background: var(--card-bg);
}
.anki-deck-toggle {
    width: 1.25rem;
    height: 1.25rem;
    border: 0;
    background: none;
    color: var(--text-secondary);
    font-size: 0.75rem;
    cursor: pointer;
    padding: 0;
    border-radius: 4px;
}
.anki-deck-toggle:hover {
    background: var(--bg-primary);
    color: var(--text-primary);
}
.anki-deck-toggle.is-leaf {
    visibility: hidden;
    cursor: default;
}
.anki-deck-label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex: 1;
    cursor: pointer;
    padding: 0.1rem 0;
}
.anki-deck-check {
    flex-shrink: 0;
    cursor: pointer;
}
.anki-deck-name {
    font-size: 0.92rem;
    color: var(--text-primary);
    word-break: break-word;
}
.anki-import-empty {
    color: var(--text-secondary);
    font-size: 0.9rem;
    text-align: center;
    padding: 1rem 0;
    margin: 0;
}
.anki-import-summary {
    margin: 0;
    font-size: 0.85rem;
    color: var(--text-secondary);
}
.anki-import-fields {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    max-height: 360px;
    overflow-y: auto;
    padding-right: 0.25rem;
}
.anki-import-field-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
    gap: 0.75rem;
    align-items: center;
}
.anki-import-field-label {
    font-size: 0.9rem;
    color: var(--text-primary);
    word-break: break-word;
}
.anki-import-field-select {
    width: 100%;
}
.field-picker {
    position: relative;
    width: 100%;
}
.field-picker-toggle {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--bg-secondary);
    color: var(--text-primary);
    font-size: 0.92rem;
    cursor: pointer;
    text-align: left;
}
.field-picker-toggle:hover,
.field-picker-toggle[aria-expanded="true"] {
    border-color: var(--accent);
}
.field-picker-current {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.field-picker-caret {
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-top: 5px solid var(--text-secondary);
    transition: transform 0.15s ease;
}
.field-picker-toggle[aria-expanded="true"] .field-picker-caret {
    transform: rotate(180deg);
}
.field-picker-menu {
    /* Fixed so it escapes the modal-card and .anki-import-fields overflow
       boxes — otherwise the dropdown gets clipped to whichever scroll
       container it lives in. Positioned via JS on open. */
    position: fixed;
    z-index: 2050;
    margin: 0;
    padding: 0.25rem;
    list-style: none;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 8px 24px var(--shadow);
    max-height: 240px;
    overflow-y: auto;
}
.field-picker-menu.hidden {
    display: none;
}
.field-picker-menu li {
    list-style: none;
}
.field-picker-option {
    display: flex;
    width: 100%;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.4rem 0.6rem;
    border: 0;
    background: none;
    color: var(--text-primary);
    font-size: 0.9rem;
    cursor: pointer;
    border-radius: 6px;
    text-align: left;
}
.field-picker-option:hover,
.field-picker-option:focus-visible {
    background: var(--bg-secondary);
}
.field-picker-option.is-active {
    color: var(--accent);
    font-weight: 600;
}
.field-picker-option-label {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.field-picker-option-check {
    flex-shrink: 0;
}
.field-examples-tip {
    position: fixed;
    /* Must beat the modal (z-index: 2000 via the design-v2 override) since the
       tip is appended to <body> rather than inside the modal card. */
    z-index: 2100;
    max-width: 280px;
    padding: 0.6rem 0.8rem;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 6px 20px var(--shadow);
    font-size: 0.85rem;
    color: var(--text-primary);
    pointer-events: none;
    opacity: 0;
    transform: translateX(-4px);
    transition: opacity 0.12s ease, transform 0.12s ease;
}
.field-examples-tip.visible {
    opacity: 1;
    transform: translateX(0);
}
.field-examples-tip-title {
    font-size: 0.72rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 0.3rem;
}
.field-examples-tip-row {
    padding: 0.15rem 0;
    word-break: break-word;
}
.field-examples-tip-row + .field-examples-tip-row {
    border-top: 1px dashed var(--border);
    margin-top: 0.25rem;
    padding-top: 0.35rem;
}
.anki-import-include-new {
    display: grid;
    grid-template-columns: auto 1fr;
    column-gap: 0.6rem;
    row-gap: 0.15rem;
    align-items: center;
    padding: 0.5rem 0.75rem;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    user-select: none;
}
.anki-import-include-new input {
    grid-column: 1;
    grid-row: 1 / span 2;
    margin: 0;
    cursor: pointer;
}
.anki-import-include-new > span:first-of-type {
    grid-column: 2;
    grid-row: 1;
    color: var(--text-primary);
    font-size: 0.92rem;
}
.anki-import-include-new-hint {
    grid-column: 2;
    grid-row: 2;
    color: var(--text-secondary);
    font-size: 0.8rem;
}
.anki-import-estimate {
    margin: 0.25rem 0 0;
    font-size: 0.92rem;
    color: var(--accent);
    font-weight: 500;
}
/* Replace mode is destructive (delete-then-add); flag it visually so users
   notice the difference between additive and replacing imports. */
.anki-import-replace input:checked ~ span,
.anki-import-replace input:checked ~ .anki-import-include-new-hint {
    color: var(--danger);
}

/* "Replace existing vocabulary" + its "Preserve manually-imported words"
   sub-option share one card so they read as a unit. The group provides the
   card chrome; the inner labels drop their own background/border. */
.anki-settings-replace-group {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
}
.anki-settings-replace-group:has(#anki-settings-replace-mode:checked) {
    border-color: var(--danger);
}
.anki-settings-grouped {
    background: none;
    border: 0;
    border-radius: 0;
    padding: 0;
}
/* The preserve sub-option animates in/out when Replace is toggled. Collapsed
   by default; .expanded grows max-height + fades in. A slight indent marks
   it as a child of the Replace option. */
.anki-settings-subgroup {
    overflow: hidden;
    max-height: 0;
    opacity: 0;
    margin-top: 0;
    padding-left: 0;
    transition: max-height 0.25s ease, opacity 0.2s ease,
                margin-top 0.25s ease, padding-left 0.25s ease;
}
.anki-settings-subgroup.expanded {
    max-height: 160px;
    opacity: 1;
    margin-top: 0.5rem;
    padding-left: 1rem;
}
.anki-import-progress {
    height: 6px;
    background: var(--bg-secondary);
    border-radius: 999px;
    overflow: hidden;
}
.anki-import-progress-bar {
    height: 100%;
    width: 0%;
    background: var(--accent);
    transition: width 0.2s ease;
}

@media (max-width: 600px) {
    .anki-import-field-row {
        grid-template-columns: 1fr;
        gap: 0.3rem;
    }
}

.value-card {
    padding: 24px;
}

.value-icon {
    display: none;
}

.value-card h3,
.action-card h3,
.about-step h3 {
    color: var(--text-primary);
    font-size: 15px;
}

.value-card p,
.action-card p,
.about-step p,
.dashboard-lede,
.decks-lede,
.review-lede,
.inspect-lede,
.about-lede,
.signin-lede {
    color: var(--text-secondary);
}

.landing-cta-section,
.about-hero,
.dashboard-header,
.inspect-header,
.decks-header,
.review-header,
.admin-header,
.results-header {
    border-bottom: 1px solid var(--border);
    padding-bottom: 24px;
    margin-bottom: 24px;
}

.landing-cta-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    text-align: left;
}

h1,
h2 {
    color: var(--text-primary);
    letter-spacing: 0;
}

.dashboard-header h1,
.about-hero h1,
.signin-card h1,
.inspect-header h1,
.decks-header h1,
.review-header h1,
.admin-header h1 {
    font-family: var(--font-disp);
    font-weight: 800;
}

.form-group input,
.form-group select,
.form-group textarea,
.known-words-card textarea,
#inspect-text,
#parse-text,
#results-deck-title {
    background: oklch(0.125 0.008 250);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text-primary);
    font-family: var(--font-sans);
}

[data-theme="light"] .form-group input,
[data-theme="light"] .form-group select,
[data-theme="light"] .form-group textarea,
[data-theme="light"] .known-words-card textarea,
[data-theme="light"] #inspect-text,
[data-theme="light"] #parse-text,
[data-theme="light"] #results-deck-title {
    background: oklch(1 0 0);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus,
#inspect-text:focus,
#parse-text:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 1px var(--accent);
}

.word-table,
.data-table {
    border-collapse: separate;
    border-spacing: 0;
}

/* .data-table still wants its own framed look (it appears outside the
   results-table-section card). The word-table inside the results page is
   already framed by .results-table-section, so don't double up. */
.data-table {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: 8px;
    overflow: hidden;
}

.word-table th,
.word-table td {
    border-bottom-color: var(--border);
}

.word-table th {
    color: var(--text-secondary);
    font-family: var(--font-mono);
    font-size: 11px;
    letter-spacing: 0.04em;
    text-transform: none;
}

.word-table tbody tr:hover {
    background: var(--bg-tertiary);
}

.pos-badge,
.results-pill,
.tag {
    border-radius: 999px;
    font-family: var(--font-mono);
}

.toast {
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    color: var(--text-primary);
}

/* Review column: a centered, comfortably-narrow card reads better than a
   full-width panel with everything jammed against the left edge. Scoped to
   .review-main (overrides the shared decks/languages max-width above) and
   left unset at <=600px, where the page already fills the viewport. */
.review-main {
    max-width: 700px;
}

@media (max-width: 760px) {
    .nav-content {
        padding: 0 16px;
        gap: 12px;
    }

    .nav-links {
        display: none;
    }

    .nav-hamburger {
        display: flex;
    }

    .landing-main,
    .about-main,
    .signin-main,
    .dashboard-main,
    .inspect-main,
    .decks-main,
    .review-main,
    .admin-main {
        padding: 24px 16px 64px;
    }

    .hero-title {
        font-size: clamp(42px, 16vw, 64px);
    }

    .landing-cta-section {
        align-items: flex-start;
        flex-direction: column;
    }
}

/* ============================================================
   Two-dimensional theming: skin × mode
   ------------------------------------------------------------
   "ink"  skin = the existing INK/PAPER Design v2 system (default).
   "aalto" skin = the Alvar-Aalto prototype
       (design/claude-design/finnest-prototype.html):
       light "Paimio" · dark "Sanatorium". All values below are
       copied verbatim from that prototype's declared oklch tokens,
       then mapped onto this app's existing role-token vocabulary.
   Mode is `data-theme` (light/dark); skin is `data-skin`.
   ============================================================ */

/* Word-status role tokens the reading surface will consume. Defined under
   BOTH skins. For the ink skin these are sensible picks from the live palette
   (accent for "new"; a restrained sage / warm amber for known / learning that
   read on both the INK ground and the PAPER override). Aalto overrides them
   with the prototype's own values further down. */
:root,
[data-skin="ink"][data-theme="dark"],
[data-skin="ink"]:not([data-theme="light"]) {
    --known: oklch(0.74 0.11 155);
    --learning: oklch(0.80 0.13 85);
    --new: var(--accent);
}
[data-skin="ink"][data-theme="light"] {
    --known: oklch(0.55 0.11 155);
    --learning: oklch(0.60 0.13 75);
    --new: var(--accent);
}

/* ── Theme picker menu (skin-agnostic; mirrors the language dropdown) ── */
.nav-theme-dropdown {
    position: relative;
}
#theme-toggle[aria-expanded="true"] {
    background: var(--bg-secondary);
    color: var(--text-primary);
}
.theme-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 176px;
    margin: 0;
    padding: 0.35rem;
    list-style: none;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 8px 24px var(--shadow);
    z-index: 200;
}
.theme-menu.hidden {
    display: none;
}
.theme-menu-heading {
    padding: 0.4rem 0.7rem 0.2rem;
    font-family: var(--font-mono);
    font-size: 10px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.theme-menu-divider {
    height: 1px;
    margin: 0.3rem 0.4rem;
    background: var(--border);
}
.theme-option {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    padding: 0.45rem 0.7rem;
    border: none;
    border-radius: 5px;
    background: transparent;
    color: var(--text-primary);
    font: inherit;
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s;
}
.theme-option:hover {
    background: var(--bg-secondary);
}
.theme-option:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: -1px;
}
.theme-option-swatch {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    flex: none;
    border: 1px solid var(--border);
    background:
        linear-gradient(135deg, var(--sw-a, #444) 0 50%, var(--sw-b, #999) 50% 100%);
}
.theme-option-swatch[data-swatch="ink-dark"]   { --sw-a: oklch(0.165 0.008 250); --sw-b: oklch(0.72 0.19 38); }
.theme-option-swatch[data-swatch="ink-light"]  { --sw-a: oklch(0.97 0.005 85);  --sw-b: oklch(0.55 0.19 35); }
.theme-option-swatch[data-swatch="aalto-light"]{ --sw-a: oklch(0.945 0.018 80); --sw-b: oklch(0.480 0.115 248); }
.theme-option-swatch[data-swatch="aalto-dark"] { --sw-a: oklch(0.180 0.025 250); --sw-b: oklch(0.72 0.13 245); }
.theme-option-label {
    flex: 1;
}
.theme-option-check {
    opacity: 0;
    color: var(--accent);
    font-size: 12px;
}
.theme-option.selected .theme-option-check,
.theme-option[aria-selected="true"] .theme-option-check {
    opacity: 1;
}
.theme-option.selected .theme-option-label {
    font-weight: 600;
    color: var(--text-primary);
}

/* ── Aalto skin · light "Paimio" (default aalto mode) ────────────────────
   Verbatim oklch from the prototype's :root/[data-theme="paper"]. */
[data-skin="aalto"],
[data-skin="aalto"][data-theme="light"] {
    /* raw palette */
    --paper:    oklch(0.970 0.012 78);
    --paper-2:  oklch(0.945 0.018 80);
    --cream:    oklch(0.925 0.025 80);
    --cream-2:  oklch(0.895 0.030 78);
    --birch:    oklch(0.810 0.060 75);
    --birch-2:  oklch(0.730 0.070 70);
    --birch-3:  oklch(0.620 0.075 60);
    --blue:     oklch(0.480 0.115 248);
    --blue-2:   oklch(0.395 0.125 250);
    --ink-color: oklch(0.200 0.020 250);

    /* mapped onto the app's role-token vocabulary */
    --bg-primary:    var(--paper);
    --bg-secondary:  var(--paper-2);
    --bg-tertiary:   var(--cream-2);
    --card-bg:       var(--paper-2);
    --text-primary:  oklch(0.200 0.020 250);
    --text-secondary: oklch(0.50 0.015 250);
    --accent:        var(--blue);
    --accent-hover:  var(--blue-2);
    --border:        oklch(0.84 0.020 75);
    --shadow:        oklch(0.20 0.020 250 / 0.14);
    --success:       oklch(0.55 0.10 155);
    --warning:       oklch(0.65 0.10 80);
    --danger:        oklch(0.555 0.160 30);

    --known:    oklch(0.55 0.10 155);
    --learning: oklch(0.65 0.10 80);
    --new:      var(--blue);

    /* prototype's radii + type */
    --r-sm: 6px;
    --r-md: 12px;
    --r-lg: 22px;
    --font-mono: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
    --font-sans: "Inter Tight", -apple-system, "Segoe UI", system-ui, sans-serif;
    --font-disp: "Newsreader", "GT Sectra", "Times New Roman", serif;
}

/* ── Aalto skin · dark "Sanatorium" ──────────────────────────────────────
   Verbatim oklch from the prototype's [data-theme="ink"] Sanatorium block. */
[data-skin="aalto"][data-theme="dark"] {
    --birch:     oklch(0.50 0.055 70);
    --birch-2:   oklch(0.42 0.060 65);
    --birch-3:   oklch(0.34 0.055 60);
    --cream:     oklch(0.230 0.025 250);

    --bg-primary:    oklch(0.180 0.025 250);
    --bg-secondary:  oklch(0.225 0.025 250);
    --bg-tertiary:   oklch(0.265 0.025 250);
    --card-bg:       oklch(0.140 0.025 250);
    --text-primary:  oklch(0.96 0.012 80);
    --text-secondary: oklch(0.58 0.015 240);
    --accent:        oklch(0.72 0.13 245);
    --accent-hover:  oklch(0.62 0.13 248);
    --border:        oklch(0.32 0.022 250);
    --shadow:        rgba(0, 0, 0, 0.45);
    --success:       oklch(0.74 0.11 155);
    --warning:       oklch(0.78 0.11 80);

    --known:    oklch(0.74 0.11 155);
    --learning: oklch(0.78 0.11 80);
    --new:      oklch(0.72 0.13 245);
}

/* ── Aalto skin · feel details (CSS-first, token-driven, aalto only) ──────
   The prototype's shape language: soft radii, hairline borders, serif
   reading surfaces, the italic-serif brand with accent dot. No markup
   restructuring — everything keys off the existing DOM. */

[data-skin="aalto"] body {
    font-feature-settings: "ss01", "cv11";
}

/* Brand: prototype's .brand — italic display serif + accent dot, reading
   "FinnEst" (owner correction, grill Q53: capital F + capital E). The ink
   skin's logo (::before "FinnEst" + ::after ".") is left untouched; here we
   restyle those same pseudo-elements for the Aalto voice. */
[data-skin="aalto"] .nav-logo {
    font-family: var(--font-disp);
    font-style: italic;
    font-weight: 600;
    letter-spacing: -0.025em;
}
[data-skin="aalto"] .nav-logo::before {
    content: "FinnEst";
    font-size: 24px;
}
[data-skin="aalto"] .nav-logo::after {
    content: "·";
    font-style: normal;
    color: var(--accent);
    font-size: 24px;
    margin-left: 1px;
}

/* Buttons / pills / tags pick up the pill radius + hairline language. */
[data-skin="aalto"] .btn,
[data-skin="aalto"] .btn-sm,
[data-skin="aalto"] .btn-lg {
    border-radius: 999px;
}
[data-skin="aalto"] .btn-primary {
    color: var(--paper, #fff);
    font-weight: 600;
}
[data-skin="aalto"] .nav-icon-btn,
[data-skin="aalto"] #theme-toggle {
    border-radius: 999px;
}
[data-skin="aalto"] .results-pill,
[data-skin="aalto"] .pos-filter-chip,
[data-skin="aalto"] .tag,
[data-skin="aalto"] .grammar-label {
    border-radius: 999px;
}

/* Panels / cards get the soft elevation + gentle radius from the prototype. */
[data-skin="aalto"] .value-grid,
[data-skin="aalto"] .dashboard-stats,
[data-skin="aalto"] .dashboard-actions,
[data-skin="aalto"] .about-steps,
[data-skin="aalto"] .data-table {
    border-radius: var(--r-md);
}
[data-skin="aalto"] .modal-card {
    border-radius: var(--r-lg);
    box-shadow: 0 32px 80px var(--shadow);
}
[data-skin="aalto"] .theme-menu,
[data-skin="aalto"] .nav-lang-menu {
    border-radius: var(--r-md);
}

/* Display headings + hero switch to the Newsreader serif voice. */
[data-skin="aalto"] .hero-title,
[data-skin="aalto"] .dashboard-header h1,
[data-skin="aalto"] .about-hero h1,
[data-skin="aalto"] .signin-card h1,
[data-skin="aalto"] .inspect-header h1,
[data-skin="aalto"] .decks-header h1,
[data-skin="aalto"] .review-header h1,
[data-skin="aalto"] .admin-header h1 {
    font-family: var(--font-disp);
    font-weight: 500;
    letter-spacing: -0.025em;
}

/* Paste / Inspect textareas get the serif reading feel + larger size
   (prototype .paste-box textarea: var(--font-disp), 20px, line-height 1.55). */
[data-skin="aalto"] #landing-text,
[data-skin="aalto"] #inspect-text,
[data-skin="aalto"] #parse-text {
    font-family: var(--font-disp);
    font-size: 18px;
    line-height: 1.55;
    border-radius: var(--r-md);
}
[data-skin="aalto"] .landing-parse-form {
    border-radius: var(--r-lg);
}
/* Aalto textarea grounds: paper-cream in Paimio, deep ink in Sanatorium,
   overriding the ink skin's hardcoded oklch fills. */
[data-skin="aalto"] #landing-text,
[data-skin="aalto"] #inspect-text,
[data-skin="aalto"] #parse-text {
    background: var(--bg-secondary);
}

/* ============================================================
   PROTOTYPE LANDING (Claude Design "Aalto edition")
   Ported from design/aalto-landing.jsx + finnest-prototype.html.
   The prototype's [data-aalto="bold"] decorations become the
   landing's default look. Rules are token-driven so the landing
   renders in both skins; the birch/vase/wordmark/blue-band
   decorations are gated to [data-skin="aalto"] where the birch +
   raw palette tokens exist. Scoped under .landing-wrap so it
   overrides the older .hero-title / .value-grid base rules for
   the landing only, leaving the About/dashboard heroes untouched.
   ============================================================ */
.landing-wrap {
    max-width: 1080px;
    margin: 0 auto;
    padding: 56px 40px 80px;
    position: relative;
}

/* Vertical AALTO wordmark — aalto skin + wide viewport only. */
.aalto-mark {
    display: none;
    position: absolute;
    left: 12px;
    top: 8px;
    bottom: 80px;
    width: 24px;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    pointer-events: none;
}
[data-skin="aalto"] .aalto-mark { display: flex; }
.aalto-mark .vstrip {
    width: 8px;
    flex: 1;
    background-color: var(--birch);
    background-image: repeating-linear-gradient(
        0deg,
        oklch(from var(--birch) calc(l - 0.10) c h / 0.4) 0 1px,
        transparent 1px 9px,
        oklch(from var(--birch) calc(l - 0.06) c h / 0.3) 9px 10px,
        transparent 10px 32px
    );
    border-radius: 4px;
}
.aalto-mark .vlabel {
    writing-mode: vertical-rl;
    transform: rotate(180deg);
    font-family: var(--font-mono);
    font-size: 9.5px;
    letter-spacing: 0.36em;
    text-transform: uppercase;
    color: var(--text-secondary);
    white-space: nowrap;
}

/* Savoy-vase silhouette — aalto skin + wide viewport only, with a
   slow ambient drift. Reduced-motion visitors get the static form. */
.vase-svg {
    display: none;
    position: absolute;
    right: -20px;
    top: 8px;
    width: 220px;
    height: 320px;
    color: var(--birch);
    opacity: 0.55;
    pointer-events: none;
    transform-origin: 50% 15%;
}
[data-skin="aalto"] .vase-svg {
    display: block;
    animation: vase-drift 13s ease-in-out infinite alternate;
}
@keyframes vase-drift {
    0%   { transform: translateY(0)     rotate(-0.6deg); }
    100% { transform: translateY(-10px) rotate(0.8deg); }
}
@media (prefers-reduced-motion: reduce) {
    [data-skin="aalto"] .vase-svg { animation: none; }
}

/* Eyebrow with live pulse dot. */
.landing-wrap .hero-eyebrow {
    font-family: var(--font-mono);
    font-size: 11px;
    color: var(--text-secondary);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    margin-bottom: 22px;
    display: flex;
    align-items: center;
    gap: 10px;
}
.landing-wrap .hero-eyebrow .pulse {
    display: inline-block;
    width: 7px;
    height: 7px;
    background: var(--known);
    border-radius: 50%;
    box-shadow: 0 0 0 0 var(--known);
    animation: landing-pulse 2s infinite;
}
@keyframes landing-pulse {
    0%, 100% { box-shadow: 0 0 0 0 oklch(from var(--known) l c h / 0.5); }
    50%      { box-shadow: 0 0 0 7px oklch(from var(--known) l c h / 0); }
}
@media (prefers-reduced-motion: reduce) {
    .landing-wrap .hero-eyebrow .pulse { animation: none; }
}

/* Hero headline + subtitle — override the base .hero-title/.hero-subtitle
   sizing for the landing only. */
.landing-wrap .hero-title.hero-h {
    font-family: var(--font-disp);
    font-size: clamp(40px, 7vw, 68px);
    font-weight: 400;
    letter-spacing: -0.03em;
    line-height: 0.98;
    margin-bottom: 22px;
    color: var(--text-primary);
    max-width: 18ch;
}
[data-skin="ink"] .landing-wrap .hero-title.hero-h { font-weight: 600; }
.landing-wrap .hero-title.hero-h em {
    font-style: italic;
    color: var(--accent);
    font-weight: inherit;
}
.landing-wrap .hero-subtitle.hero-sub {
    font-size: 17px;
    color: var(--text-secondary);
    max-width: 580px;
    line-height: 1.55;
    margin-bottom: 36px;
    font-family: var(--font-disp);
    font-weight: 400;
}
[data-skin="ink"] .landing-wrap .hero-subtitle.hero-sub { font-family: var(--font-sans); }
.landing-wrap .hero-sub-quiet {
    display: block;
    margin-top: 10px;
    font-size: 14px;
    color: var(--text-secondary);
    opacity: 0.8;
    font-family: var(--font-sans);
}

/* Paste box — soft radius, focus ring, birch-lined left edge under aalto. */
.landing-wrap .landing-parse-form { margin: 0; }
.landing-wrap .paste-box {
    position: relative;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    border-radius: var(--r-lg, 22px);
    transition: border-color 0.15s, box-shadow 0.2s;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.landing-wrap .paste-box:focus-within {
    border-color: var(--accent);
    box-shadow: 0 0 0 4px oklch(from var(--accent) l c h / 0.12);
}
[data-skin="aalto"] .landing-wrap .paste-box { padding-left: 32px; }
[data-skin="aalto"] .landing-wrap .paste-box::before {
    content: "";
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 24px;
    background-color: var(--birch);
    background-image:
        repeating-linear-gradient(
            0deg,
            oklch(from var(--birch) calc(l - 0.12) c h / 0.45) 0 1px,
            transparent 1px 9px,
            oklch(from var(--birch) calc(l - 0.06) c h / 0.3) 9px 10px,
            transparent 10px 28px
        ),
        radial-gradient(ellipse 60% 14% at 40% 38%, oklch(from var(--birch) calc(l - 0.10) c h / 0.25), transparent 70%),
        radial-gradient(ellipse 50% 10% at 60% 78%, oklch(from var(--birch) calc(l - 0.10) c h / 0.20), transparent 70%);
}
.landing-wrap .paste-box #landing-text {
    width: 100%;
    min-height: 240px;
    max-height: 70vh;
    overflow-y: auto;
    padding: 28px 32px 24px;
    font-family: var(--font-disp);
    font-size: 20px;
    line-height: 1.55;
    color: var(--text-primary);
    background: transparent;
    border: none;
    border-radius: 0;
    resize: vertical;
    box-sizing: border-box;
}
.landing-wrap .paste-box #landing-text:focus { outline: none; }
.landing-wrap .paste-box #landing-text::placeholder {
    color: var(--text-secondary);
    font-style: italic;
}
.landing-wrap .paste-foot {
    position: relative;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 14px 20px 16px;
    border-top: 1px solid var(--border);
    background: var(--bg-primary);
    flex-wrap: wrap;
}
.landing-wrap .paste-foot .meter {
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-secondary);
    letter-spacing: 0.02em;
}
.landing-wrap .paste-foot .meter .char-count {
    color: var(--text-primary);
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    /* Override the base .char-count { float: right } so the "N / cap" count
       stays inline before the "chars" suffix inside the meter. */
    float: none;
    font-size: inherit;
}
.landing-wrap .paste-foot-spacer { flex: 1 1 auto; }
.landing-wrap .paste-foot .landing-lang { flex: none; }
.landing-wrap .paste-foot #landing-submit .kbd {
    font-family: var(--font-mono);
    font-size: 10px;
    border: 1px solid currentColor;
    padding: 1px 5px;
    border-radius: 4px;
    opacity: 0.55;
    font-weight: 400;
    margin-left: 6px;
}

/* Demo chips ("or try →"). */
.demo-chips {
    margin-top: 18px;
    display: flex;
    gap: 10px;
    align-items: center;
    font-family: var(--font-mono);
    font-size: 11.5px;
    color: var(--text-secondary);
    flex-wrap: wrap;
    letter-spacing: 0.02em;
}
.demo-chip {
    cursor: pointer;
    padding: 6px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    color: var(--text-secondary);
    transition: all 0.12s;
    font-size: 11px;
    font-family: var(--font-mono);
    background: var(--bg-primary);
}
.demo-chip:hover:not(:disabled) {
    border-color: var(--text-primary);
    color: var(--text-primary);
    background: var(--bg-tertiary);
}
.demo-chip:disabled { opacity: 0.5; cursor: default; }

/* Freemium strip — 3 columns; aalto gets the full-bleed blue band. */
.landing-wrap .freemium-strip.value-grid {
    margin-top: 64px;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 0;
    background: transparent;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    border-left: none;
    border-right: none;
    border-radius: 0;
    overflow: hidden;
    position: relative;
}
.landing-wrap .freemium-cell { padding: 28px 28px 30px; }
.landing-wrap .freemium-cell + .freemium-cell { border-left: 1px solid var(--border); }
.landing-wrap .freemium-num {
    font-family: var(--font-disp);
    font-style: italic;
    font-size: 30px;
    font-weight: 500;
    color: var(--accent);
    margin-bottom: 6px;
    font-feature-settings: "tnum";
    line-height: 1;
}
.landing-wrap .freemium-h {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 6px;
    letter-spacing: -0.005em;
}
.landing-wrap .freemium-p {
    font-size: 13px;
    color: var(--text-secondary);
    line-height: 1.55;
}
[data-skin="aalto"] .landing-wrap .freemium-strip.value-grid {
    background: var(--blue);
    border: none;
    border-radius: var(--r-lg, 22px);
    padding: 8px;
}
[data-skin="aalto"] .landing-wrap .freemium-cell {
    color: var(--paper);
    padding: 24px 24px 26px;
}
[data-skin="aalto"] .landing-wrap .freemium-cell + .freemium-cell {
    border-left: 1px solid oklch(from var(--paper) l c h / 0.18);
}
[data-skin="aalto"] .landing-wrap .freemium-num { color: var(--birch); }
[data-skin="aalto"] .landing-wrap .freemium-h { color: var(--paper); }
[data-skin="aalto"] .landing-wrap .freemium-p { color: oklch(from var(--paper) l c h / 0.78); }

/* Colophon — quiet credit + palette swatches. */
.colophon {
    margin-top: 56px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 18px;
    font-family: var(--font-mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.colophon .swatches { display: flex; gap: 6px; align-items: center; }
.colophon .sw {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 1px solid var(--border);
    display: inline-block;
}
.colophon .sw.b { background: var(--accent); border-color: var(--accent); }
.colophon .sw.k { background: var(--text-primary); border-color: var(--text-primary); }
.colophon .sw.w { background: var(--bg-primary); }
[data-skin="aalto"] .colophon .sw.w { background: var(--paper); }
[data-skin="aalto"] .colophon .sw.r { background: var(--birch); border-color: var(--birch-3, var(--birch)); }

/* Word-list export controls on the results page (all roles). */
.results-export {
    display: flex;
    gap: 8px;
    margin: 6px 0 4px;
    flex-wrap: wrap;
}
.results-export.hidden { display: none; }

/* ── Mobile: decorations hide, paste foot stacks, single-column band ── */
@media (max-width: 760px) {
    .landing-wrap { padding: 32px 20px 64px; }
    .aalto-mark, .vase-svg { display: none !important; }
    .landing-wrap .hero-title.hero-h { font-size: clamp(34px, 11vw, 46px); }
    [data-skin="aalto"] .landing-wrap .paste-box { padding-left: 0; }
    [data-skin="aalto"] .landing-wrap .paste-box::before { display: none; }
    .landing-wrap .paste-box #landing-text { font-size: 17px; padding: 20px; min-height: 200px; }
    .landing-wrap .paste-foot { padding: 12px 14px 14px; }
    .landing-wrap .paste-foot-spacer { flex-basis: 100%; height: 0; }
    .landing-wrap .freemium-strip.value-grid { grid-template-columns: 1fr; }
    .landing-wrap .freemium-cell + .freemium-cell { border-left: none; border-top: 1px solid var(--border); }
    [data-skin="aalto"] .landing-wrap .freemium-cell + .freemium-cell { border-top: 1px solid oklch(from var(--paper) l c h / 0.18); }
    .colophon { flex-direction: column; gap: 10px; }
}

/* ============================================================
   READING SURFACE — Read / Words tabs + the living text.
   The Read view renders the source text with tappable, state-
   colored word spans; Words is the existing lemma table. Token
   colors consume the --known / --learning / --new role tokens
   (defined under both skins), so this styling is skin-agnostic
   with a couple of typography overrides for the Aalto voice.
   ============================================================ */

/* ── Tab bar ── */
.results-tabs {
    display: flex;
    gap: 0.25rem;
    margin: 0.75rem 0 0.5rem;
    border-bottom: 1px solid var(--border);
}
.results-tabs.hidden { display: none; }
.results-tab {
    appearance: none;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    padding: 0.5rem 0.9rem;
    font: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--text-secondary);
    cursor: pointer;
    min-height: 44px;
}
.results-tab:hover { color: var(--text-primary); }
.results-tab.active {
    color: var(--text-primary);
    border-bottom-color: var(--accent);
}
.results-tab:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
    border-radius: 4px;
}

/* ── Read view (the living text) ── */
.read-view { margin-top: 0.25rem; }
.read-view.hidden { display: none; }

.read-text {
    max-width: 42rem;
    margin: 1rem 0 2rem;
    /* Clean readable sans under Ink; the Aalto override below switches to the
       display serif for a book-like reading feel. */
    font-family: var(--font-sans, inherit);
    font-size: 1.15rem;
    line-height: 1.7;
    color: var(--text-primary);
}
[data-skin="aalto"] .read-text {
    font-family: var(--font-disp);
    font-size: 1.25rem;
    line-height: 1.75;
}
.read-para { margin: 0 0 1.1rem; }
.read-para:last-child { margin-bottom: 0; }
.read-empty { color: var(--text-secondary); font-style: italic; }

/* Tappable word span. Base = a "new" (unknown, no card) word gets a soft accent
   underline; known/learning override via role tokens; ignored renders neutral
   (uncolored) — the least-noisy treatment for a deliberately suppressed word. */
.read-token {
    cursor: pointer;
    border-radius: 3px;
    padding: 0 1px;
    transition: background 0.08s;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}
.read-token:hover { background: color-mix(in srgb, var(--text-primary) 8%, transparent); }
.read-token:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}
/* new: not known, no study card — the words worth learning. */
.read-token.is-new {
    color: var(--new);
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, var(--new) 45%, transparent);
}
/* learning: selected to study (pending review card). */
.read-token.is-learning {
    color: var(--learning);
    background: color-mix(in srgb, var(--learning) 14%, transparent);
}
/* known: a settled word — quiet, low-emphasis. */
.read-token.is-known {
    color: var(--known);
}
/* neutral / ignored: plain body text, no coloring. */
.read-token.is-neutral {
    color: inherit;
}
/* An ambiguous surface gets a subtle dotted underline cue that it holds more
   than one meaning behind the tap. */
.read-token.is-ambiguous {
    text-decoration: underline dotted;
    text-decoration-color: color-mix(in srgb, var(--new) 60%, transparent);
    text-underline-offset: 3px;
}

/* ── Reading popover ── */
.read-popover-backdrop {
    position: fixed;
    inset: 0;
    z-index: 60;
    background: transparent;
}
.read-popover-backdrop.hidden { display: none; }

.read-popover {
    position: absolute;
    z-index: 61;
    width: min(22rem, calc(100vw - 2rem));
    max-height: 70vh;
    overflow-y: auto;
    background: var(--card-bg);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 18px 44px var(--shadow);
    padding: 0.9rem 1rem 1rem;
}
.read-popover.hidden { display: none; }
.read-popover:focus-visible { outline: none; }
.read-popover-close {
    position: absolute;
    top: 0.35rem;
    right: 0.45rem;
    appearance: none;
    background: none;
    border: none;
    font-size: 1.25rem;
    line-height: 1;
    color: var(--text-secondary);
    cursor: pointer;
    width: 32px;
    height: 32px;
    border-radius: 8px;
}
.read-popover-close:hover { color: var(--text-primary); background: var(--bg-tertiary); }

.read-pop-sense { margin-top: 0.15rem; }
.read-pop-sense + .read-pop-sense {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid var(--border);
}
.read-pop-head { display: flex; flex-direction: column; gap: 0.15rem; padding-right: 1.5rem; }
.read-pop-surface {
    font-family: var(--font-disp, inherit);
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--text-primary);
}
.read-pop-lemma-line {
    font-size: 0.85rem;
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 0.3rem;
    flex-wrap: wrap;
}
.read-pop-gloss {
    margin: 0.4rem 0 0.6rem;
    color: var(--text-primary);
    font-size: 0.95rem;
}
.read-pop-lemma { font-weight: 600; margin: 0 0 0.3rem; }
.read-pop-empty, .read-pop-nudge {
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0.4rem 0 0;
}
.read-pop-actions {
    display: flex;
    gap: 0.4rem;
    flex-wrap: wrap;
    margin-top: 0.3rem;
}
.read-pop-btn {
    appearance: none;
    border: 1px solid var(--border);
    background: var(--bg-secondary);
    color: var(--text-primary);
    border-radius: 999px;
    padding: 0.4rem 0.8rem;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    min-height: 36px;
}
.read-pop-btn:hover:not(:disabled) { border-color: var(--accent); }
.read-pop-btn:disabled { opacity: 0.5; cursor: default; }
.read-pop-known.is-active {
    background: color-mix(in srgb, var(--known) 18%, transparent);
    border-color: var(--known);
    color: var(--known);
}
.read-pop-study.is-active {
    background: color-mix(in srgb, var(--learning) 18%, transparent);
    border-color: var(--learning);
    color: var(--learning);
}
.read-pop-ignore.is-active {
    background: var(--bg-tertiary);
    color: var(--text-secondary);
}
.read-pop-hint {
    margin: 0.5rem 0 0;
    font-size: 0.78rem;
    color: var(--text-secondary);
}

/* Bottom sheet on narrow screens: pin to the viewport bottom, full-width,
   scrollable, with tap targets kept >=44px. */
@media (max-width: 440px) {
    .read-popover {
        position: fixed;
        left: 0;
        right: 0;
        bottom: 0;
        top: auto !important;
        width: 100%;
        max-height: 75vh;
        border-radius: 16px 16px 0 0;
        padding: 1.1rem 1.15rem 1.6rem;
    }
    .read-popover-backdrop:not(.hidden) {
        background: color-mix(in srgb, var(--text-primary) 25%, transparent);
    }
    .read-pop-btn { min-height: 44px; padding: 0.55rem 1rem; }
    .read-popover-close { width: 44px; height: 44px; }
}
