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

        /* Long-press is an app gesture here (hold to edit, hold to delete, hold to
           drag). On a phone the browser answers a long-press by raising its own
           text-selection / copy-paste bubble, which fights every one of those.
           Text is unselectable by default app-wide; anything the user actually
           types into or needs to copy out of opts back in below. */
        body {
            -webkit-user-select: none;
            -moz-user-select: none;
            -ms-user-select: none;
            user-select: none;
            -webkit-touch-callout: none;
        }
        input, textarea, select, [contenteditable="true"], .selectable {
            -webkit-user-select: text;
            -moz-user-select: text;
            -ms-user-select: text;
            user-select: text;
            -webkit-touch-callout: default;
        }

        /* The phone draws a SQUARE grey box behind whatever you tap or hold. On a round
           gear or a pill-shaped tab that square sticks out past the shape and reads as a
           glitch — most visible while the gear rotates. Kill it everywhere; the app
           already gives its own press feedback (hold fills, active states). */
        *, *::before, *::after {
            -webkit-tap-highlight-color: transparent;
        }
        /* Keyboard focus still needs to be visible, but it must follow the element's
           own shape instead of boxing it — inherit the radius rather than assuming one */
        button:focus, a:focus, [role="button"]:focus { outline: none; }
        button:focus-visible,
        a:focus-visible,
        select:focus-visible,
        [role="button"]:focus-visible {
            outline: 2px solid var(--accent-color);
            outline-offset: 2px;
            border-radius: inherit;
        }

        :root {
            /* Light Mode Colors */
            --bg-gradient-start: #a8c8ff;
            --bg-gradient-end: #2e59c8;
            --card-bg: white;
            --card-text: #333;
            --sidebar-bg: white;
            --sidebar-text: #333;
            --border-color: #e0e0e0;
            --shadow: rgba(0,0,0,0.2);
            --header-text: white;
            
            /* Accent Color (for future customization) */
            --accent-color: #667eea;
            --accent-color-hover: #8b9dff;
            
            /* Neutral Hover Colors (no tint) */
            --hover-bg-light: rgba(0, 0, 0, 0.04);
            --hover-bg-medium: rgba(0, 0, 0, 0.08);
            --hover-border: rgba(0, 0, 0, 0.15);
            
            /* Card Size (adjustable) */
            --card-width: 300px;
            --card-scale: 1;
        }

        body.dark-mode {
            /* Dark Mode Colors */
            --bg-gradient-start: #1a1a2e;
            --bg-gradient-end: #16213e;
            --card-bg: #2a2a3e;
            --card-text: #e0e0e0;
            --sidebar-bg: #2a2a3e;
            --sidebar-text: #e0e0e0;
            --border-color: #3a3a4e;
            --shadow: rgba(0,0,0,0.5);
            --header-text: #e0e0e0;
            
            /* Accent Color (dark mode) */
            --accent-color: #8b9dff;
            --accent-color-hover: #a5b4ff;
            
            /* Neutral Hover Colors (dark mode - no tint) */
            --hover-bg-light: rgba(255, 255, 255, 0.05);
            --hover-bg-medium: rgba(255, 255, 255, 0.1);
            --hover-border: rgba(255, 255, 255, 0.2);
        }


        html {
            background: linear-gradient(135deg, var(--bg-gradient-start) 0%, var(--bg-gradient-end) 100%);
            background-attachment: fixed;
            min-height: 100%;
            overflow-x: clip;
            overscroll-behavior-x: none;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: transparent;
            min-height: 100vh;
            width: 100%;
            padding: 20px;
            overflow-x: hidden;
            overflow-y: auto;
            overscroll-behavior-x: none;
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
            position: relative;
        }

        .header {
            text-align: center;
            color: var(--header-text);
            margin-bottom: 60px;
            position: relative;
        }

        /* Left icon group: hamburger + divider + streak bolt — mirrors
           .header-right-icons so both corners feel the same */
        .header-left-icons {
            position: absolute;
            top: 7px;
            left: 2px;
            display: flex;
            align-items: center;
            gap: 2px;
            z-index: 9999;
        }
        .header-left-icons .menu-toggle {
            position: static;
            top: auto;
            left: auto;
        }
        .streak-toggle {
            width: 40px;
            height: 40px;
            background: transparent;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.05em;
            color: white;
            position: relative;
            transition: background 0.15s;
        }
        .streak-toggle:hover { background: rgba(0, 0, 0, 0.1); }
        body.dark-mode .streak-toggle:hover { background: rgba(255, 255, 255, 0.1); }
        .streak-badge {
            position: absolute;
            top: 4px;
            right: 3px;
            min-width: 15px;
            height: 15px;
            padding: 0 3px;
            border-radius: 8px;
            background: var(--accent-color);
            color: white;
            font-size: 0.62em;
            font-weight: 700;
            line-height: 15px;
            pointer-events: none;
        }

        .menu-toggle {
            position: absolute;
            top: 7px;
            left: 2px;
            width: 44px;
            height: 44px;
            background: transparent;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 1.2em;
            z-index: 9999;
            color: white;
        }

        .menu-toggle:hover {
            background: rgba(0, 0, 0, 0.1);
        }

        body.dark-mode .menu-toggle:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        /* Right icon group: notification bell + divider + settings gear */
        .header-right-icons {
            position: absolute;
            top: 7px;
            right: 2px;
            display: flex;
            align-items: center;
            gap: 2px;
            z-index: 9999;
        }

        .header-icon-divider {
            width: 1px;
            height: 18px;
            background: rgba(255, 255, 255, 0.3);
            flex-shrink: 0;
            margin: 0 2px;
        }

        .settings-toggle, .notification-toggle {
            width: 40px;
            height: 40px;
            background: transparent;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            position: relative;
            transition: background 0.15s;
        }

        .settings-toggle:hover, .notification-toggle:hover {
            background: rgba(0, 0, 0, 0.1);
        }

        body.dark-mode .settings-toggle:hover, body.dark-mode .notification-toggle:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        /* Unread badge on bell */
        .notif-badge {
            position: absolute;
            top: 7px;
            right: 7px;
            width: 7px;
            height: 7px;
            background: #e74c3c;
            border-radius: 50%;
            pointer-events: none;
        }

        /* Notification modal */
        .notif-overlay {
            position: fixed;
            inset: 0;
            background: rgba(0, 0, 0, 0.5);
            z-index: 20000;
            display: none;
            align-items: center;
            justify-content: center;
            padding: 20px;
        }

        .notif-modal {
            background: var(--sidebar-bg);
            border-radius: 16px;
            width: 100%;
            max-width: 420px;
            max-height: 80vh;
            display: flex;
            flex-direction: column;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
        }

        .notif-modal-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 16px 20px;
            border-bottom: 1px solid var(--border-color);
            flex-shrink: 0;
        }

        .notif-modal-title {
            font-weight: 700;
            font-size: 0.95em;
            color: var(--card-text);
            letter-spacing: 0.05em;
            text-transform: uppercase;
        }

        .notif-modal-close {
            background: transparent;
            border: none;
            font-size: 1.4em;
            cursor: pointer;
            opacity: 0.5;
            color: var(--card-text);
            width: 32px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 6px;
            transition: opacity 0.2s;
        }
        .notif-modal-close:hover { opacity: 1; }

        .notif-list {
            overflow-y: auto;
            padding: 4px 16px 12px;
            flex: 1;
        }

        .notif-item {
            display: flex;
            align-items: flex-start;
            gap: 12px;
            padding: 14px 0;
            border-bottom: 1px solid var(--border-color);
        }
        .notif-item:last-child { border-bottom: none; }

        .notif-item-content { flex: 1; min-width: 0; }

        .notif-item-title {
            font-weight: 600;
            font-size: 0.88em;
            color: var(--card-text);
            margin-bottom: 3px;
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .notif-unread-dot {
            width: 7px;
            height: 7px;
            background: var(--accent-color);
            border-radius: 50%;
            flex-shrink: 0;
        }

        .notif-item-date {
            font-size: 0.75em;
            color: var(--card-text);
            opacity: 0.45;
            margin-bottom: 6px;
        }

        .notif-item-body {
            font-size: 0.83em;
            color: var(--card-text);
            opacity: 0.7;
            line-height: 1.55;
        }

        .notif-delete {
            background: transparent;
            border: none;
            cursor: pointer;
            opacity: 0.3;
            color: var(--card-text);
            padding: 4px;
            border-radius: 4px;
            flex-shrink: 0;
            transition: opacity 0.2s, color 0.2s;
            display: flex;
            align-items: center;
        }
        .notif-delete:hover { opacity: 0.9; color: #e74c3c; }

        .notif-empty {
            text-align: center;
            padding: 40px 20px;
            color: var(--card-text);
            opacity: 0.4;
            font-size: 0.9em;
        }

        /* Range slider — fully custom so the empty (right) track never renders dark
           on certain accent colors (a native accent-color quirk). The filled portion
           is painted as a gradient by adjustCardSize(). */
        input[type="range"] {
            -webkit-appearance: none;
            appearance: none;
            height: 6px;
            border-radius: 3px;
            background: var(--border-color);
            cursor: pointer;
        }
        input[type="range"]::-webkit-slider-thumb {
            -webkit-appearance: none;
            appearance: none;
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: var(--accent-color);
            border: 2px solid #fff;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
            cursor: pointer;
        }
        input[type="range"]::-moz-range-thumb {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: var(--accent-color);
            border: 2px solid #fff;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.25);
            cursor: pointer;
        }

        /* Theme color circle buttons — outlined ring, fills on select */
        .theme-color-dot {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            border: 3px solid var(--c);
            background: transparent;
            cursor: pointer;
            padding: 0;
            flex-shrink: 0;
            transition: transform 0.15s, background 0.2s;
            outline: none;
            -webkit-tap-highlight-color: transparent;
        }
        .theme-color-dot:hover { transform: scale(1.12); }
        .theme-color-dot.active {
            background: var(--c);
            transform: scale(1.08);
        }

        /* Flag tap + picker */
        .flag-tap {
            cursor: pointer;
            display: inline-block;
            transition: opacity 0.15s;
            user-select: none;
        }
        .flag-tap:hover { opacity: 0.75; }

        .flag-picker {
            position: absolute;
            left: 50%;
            transform: translateX(-50%);
            top: calc(100% + 6px);
            background: var(--sidebar-bg);
            border-radius: 10px;
            padding: 8px 10px;
            box-shadow: 0 8px 28px rgba(0,0,0,0.25);
            display: flex;
            align-items: center;
            gap: 6px;
            z-index: 10002;
        }

        .flag-picker-label {
            font-size: 0.75em;
            color: var(--card-text);
            opacity: 0.55;
            white-space: nowrap;
        }

        .flag-input {
            width: 46px;
            padding: 5px 6px;
            border: 1px solid var(--border-color);
            border-radius: 6px;
            background: var(--card-bg);
            color: var(--card-text);
            font-size: 0.95em;
            font-weight: 700;
            text-align: center;
            letter-spacing: 0.12em;
            text-transform: uppercase;
            outline: none;
        }
        .flag-input:focus { border-color: var(--accent-color); }

        .flag-confirm-btn {
            background: var(--accent-color);
            border: none;
            border-radius: 6px;
            color: white;
            width: 28px;
            height: 28px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.85em;
            transition: opacity 0.15s;
            flex-shrink: 0;
        }
        .flag-confirm-btn:hover { opacity: 0.85; }

        /* Desktop panel headers — show as title bars */
        .sidebar-header, .settings-header {
            display: flex;
            align-items: center;
            margin: -30px -30px 20px -30px;
            padding: 12px 16px;
            border-bottom: 1px solid var(--border-color);
        }

        .panel-header-title {
            flex: 1;
            text-align: center;
            font-size: 0.78em;
            font-weight: 700;
            letter-spacing: 0.07em;
            text-transform: uppercase;
            opacity: 0.55;
            color: var(--card-text);
        }

        .panel-header-spacer {
            width: 32px;
            flex-shrink: 0;
        }

        .sidebar-close, .settings-close {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 32px;
            height: 32px;
            background: none;
            border: none;
            cursor: pointer;
            font-size: 1.3em;
            color: var(--card-text);
            opacity: 0.45;
            border-radius: 6px;
            flex-shrink: 0;
            transition: opacity 0.15s;
        }

        .sidebar-close:hover, .settings-close:hover {
            opacity: 1;
            background: rgba(0,0,0,0.06);
        }

        body.dark-mode .sidebar-close:hover, body.dark-mode .settings-close:hover {
            background: rgba(255,255,255,0.08);
        }

        .header h1 {
            font-size: 1.4em;
            margin-bottom: 0;
            text-shadow: 1px 1px 3px rgba(0,0,0,0.25);
            font-weight: 700;
            letter-spacing: 0.02em;
        }

        /* The counter keeps its own shape and its full rounding — the drawer is a narrow
           tongue, not a full-width extension, so the counter's bottom edge stays visible
           either side of it. Only the bottom MARGIN goes; the drawer carries the gap. */
        .stats-bar {
            background: var(--card-bg);
            padding: 20px;
            border-radius: 15px;
            box-shadow: 0 4px 15px var(--shadow);
            display: flex;
            justify-content: space-around;
            margin-bottom: 0;
        }

        /* ===== Practice drawer — a narrow tongue dropping out of the counter =====
           NOT the full width of the counter (Paul, 2026-07-14): a centred box only as wide
           as its contents, hanging off the counter's bottom edge. Square on top where it
           meets the counter, rounded at the bottom, same background — so it reads as
           something the counter dropped, not as a second stacked card.
           It pulls up 15px to sit UNDER the counter's rounded corner, hiding its own square
           top edge behind it; that overlap is what makes the two look joined.
           It sits in normal flow, so opening it pushes the deck down — no overlap with it.
           The counter is z-index 1 so its shadow and body paint OVER the drawer's top edge;
           the drawer is 0 and tucks behind. */
        .stats-bar { position: relative; z-index: 1; }
        .practice-drawer {
            position: relative;
            z-index: 0;
            width: fit-content;
            max-width: 92%;
            margin: -15px auto 30px;
            padding-top: 15px;         /* the slice hidden behind the counter */
            background: var(--card-bg);
            border-radius: 0 0 15px 15px;
            box-shadow: 0 6px 14px var(--shadow);
            overflow: hidden;
        }
        /* Kept DELIBERATELY short (Paul, 2026-07-14): the drawer is a tray hanging off the
           counter, and it looked wrong when it stood nearly as tall as the counter itself.
           It should always read as shorter. Trim padding here before you grow anything. */
        .pd-body {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 8px;
            padding: 7px 12px 1px;
        }
        /* Collapsed = the grab line and nothing else, so the drawer can be tucked away.
           The drawer is fit-content, so with the body gone it would shrink to nothing and
           take the grab line with it — the min-width is what keeps a tab left to pull. */
        .practice-drawer.collapsed .pd-body { display: none; }
        .practice-drawer.collapsed { min-width: 110px; }

        /* All three buttons are the SAME size and round — the old 28px squares were
           genuinely hard to hit. 40px: big enough to press, and 46px made the filled
           play circle loom over the row (a filled disc reads larger than an outlined one
           at the same diameter). */
        .pd-btn {
            width: 36px;
            height: 36px;
            flex-shrink: 0;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            border: none;
            border-radius: 50%;
            background: var(--hover-bg-light);
            color: var(--card-text);
            cursor: pointer;
            transition: background 0.15s, transform 0.1s;
        }
        .pd-btn:hover { background: var(--border-color); }
        .pd-btn:active { transform: scale(0.93); }
        /* Being held — the press is registering, before it fires at 550ms */
        .pd-btn.pd-holding { transform: scale(0.92); }
        .pd-ico { width: 18px; height: 18px; display: block; }

        /* Nothing to undo. It keeps its place rather than disappearing, so the row never
           changes shape under the thumb — but it must LOOK dead, or it's a lie. */
        .pd-btn:disabled {
            opacity: 0.3;
            cursor: default;
            pointer-events: none;
        }
        /* Play/pause is the primary action, so it carries the accent as a filled circle.
           White glyph on accent reads in both themes — the accent is never light enough
           to lose it. */
        /* OPTICAL sizing, not geometric (Paul, 2026-07-14): at an identical 36px the play
           button looked much bigger than the rest, because a FILLED disc reads larger than
           an outlined circle, and its glyph is solid where the others are thin strokes.
           So it's drawn a couple of px smaller to LOOK the same size. Don't "correct" this
           back to 36px — matching the numbers is what made them look mismatched. */
        .pd-play {
            width: 34px;
            height: 34px;
            background: var(--accent-color);
            color: #fff;
        }
        .pd-play:hover { background: var(--accent-color); filter: brightness(1.08); }
        .pd-play .pd-ico { fill: currentColor; width: 16px; height: 16px; }

        /* Autoplay mode shows the real AUTOPLAY GLYPH in this button (a screen with a play
           triangle in it) instead of the plain play triangle — see updateTimerBar(). An
           "A" badge on the corner was tried and rejected (Paul, 2026-07-14): too small to
           read, and it isn't what autoplay looks like anywhere else. */
        /* Shuffle and reset are secondary: outlined glyphs, not filled */
        .pd-shuffle .pd-ico, .pd-reset .pd-ico { fill: none; }

        /* Big enough to read across the room, which the old 0.8em wasn't.
           tabular-nums stops the width jittering as the digits tick. */
        .pd-time {
            border: none;
            background: transparent;
            font-size: 1.25em;
            font-weight: 700;
            color: var(--card-text);
            font-variant-numeric: tabular-nums;
            letter-spacing: 0.01em;
            padding: 6px 10px;
            /* The clock needs MORE air than the buttons need from each other — on the
               shared flex gap alone it sat as tight to play as play sat to shuffle, and the
               row read as one crowded lump (Paul, 2026-07-14). */
            margin: 0 7px;
            border-radius: 10px;
            cursor: pointer;
            /* HOLD to edit — the browser's own long-press (text select, copy bubble)
               would fight ours on mobile */
            -webkit-user-select: none;
            user-select: none;
            -webkit-touch-callout: none;
            transition: background 0.15s;
        }
        .pd-time:hover { background: var(--hover-bg-light); }
        /* Held long enough to register — the press is being felt */
        .pd-time.pd-holding { background: var(--hover-bg-light); transform: scale(0.97); }
        .pd-time.pt-done { color: #1e8449; }
        body.dark-mode .pd-time.pt-done { color: #6ee7a0; }

        /* The grab line — the whole strip is the hit area, the little bar is just what
           you see. Full width so it's impossible to miss. */
        .pd-grab {
            display: block;
            width: 100%;
            height: 14px;
            border: none;
            background: transparent;
            cursor: pointer;
            padding: 0;
        }
        .pd-grab::after {
            content: '';
            display: block;
            width: 40px;
            height: 4px;
            margin: 0 auto;
            border-radius: 999px;
            background: var(--card-text);
            opacity: 0.22;
            transition: opacity 0.15s, width 0.15s;
        }
        .pd-grab:hover::after { opacity: 0.45; width: 52px; }
        /* Collapsed, the line IS the drawer — give it room to be tapped */
        .practice-drawer.collapsed .pd-grab { height: 26px; }

        /* Dark mode: the tinted button circles nearly vanish against the dark card, so
           the glyphs need to carry themselves — lift both the fill and the icon. */
        body.dark-mode .pd-btn {
            background: rgba(255, 255, 255, 0.08);
            color: #e8edf4;
        }
        body.dark-mode .pd-btn:hover { background: rgba(255, 255, 255, 0.16); }
        body.dark-mode .pd-play { background: var(--accent-color); color: #fff; }
        body.dark-mode .pd-time { color: #e8edf4; }
        body.dark-mode .pd-grab::after { background: #e8edf4; opacity: 0.28; }

        @media (max-width: 1024px) {
            .practice-drawer { margin: -15px auto 16px; }
            .pd-body { gap: 6px; padding: 6px 10px 1px; }
            .pd-time { font-size: 1.05em; padding: 4px 4px; }
        }
        /* Phone: the row is 4 buttons + the clock, and at 360px it grew to 92% of the
           counter's width — near enough to full width that the drawer stopped reading as a
           tray hanging off it. Shrink the contents so the drawer stays comfortably
           narrower AND shorter than the counter. */
        @media (max-width: 480px) {
            .pd-btn { width: 32px; height: 32px; }
            .pd-ico { width: 15px; height: 15px; }
            .pd-play { width: 30px; height: 30px; }              /* same optical trim */
            .pd-play .pd-ico { width: 14px; height: 14px; }
            .pd-body { gap: 4px; padding: 6px 8px 1px; }
            .pd-time { font-size: 0.95em; padding: 4px 2px; margin: 0 5px; }
            .pd-grab { height: 13px; }
        }

        /* ===== Mode tabs (Flashcards / Sentences) ===== */
        .mode-tabs {
            display: flex;
            gap: 6px;
            width: 100%;
            max-width: 520px;
            margin: 0 auto 22px;
            padding: 5px;
            background: var(--hover-bg-light);
            border-radius: 14px;
        }
        .mode-tab {
            flex: 1;
            min-width: 0;
            padding: 11px 12px;
            border: none;
            background: transparent;
            color: var(--card-text);
            opacity: 0.65;
            font-size: 0.92em;
            font-weight: 600;
            border-radius: 10px;
            cursor: pointer;
            transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .mode-tab:hover { opacity: 0.9; }
        .mode-tab.active {
            background: var(--card-bg);
            color: var(--accent-color);
            opacity: 1;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
        }
        @media (max-width: 420px) {
            .mode-tabs { gap: 3px; padding: 4px; }
            .mode-tab {
                padding: 9px 4px;
                font-size: 0.78em;
                border-radius: 8px;
            }
        }

        /* ===== Deck tabs — multiple flashcard collections ===== */
        .deck-tabs {
            display: flex;
            align-items: center;
            gap: 6px;
            overflow-x: auto;
            max-width: 520px;
            margin: -12px auto 18px;
            padding: 2px;
        }
        .deck-tab {
            display: inline-flex;
            align-items: center;
            gap: 4px;
            flex-shrink: 0;
            padding: 6px 12px;
            border-radius: 20px;
            border: 1.5px solid transparent;
            background: var(--card-bg);
            color: var(--card-text);
            font-size: 0.8em;
            font-weight: 600;
            cursor: pointer;
            user-select: none;
            box-shadow: 0 1px 3px rgba(0,0,0,0.12);
            transition: border-color 0.15s, background 0.15s;
        }
        .deck-tab.active {
            border-color: var(--accent-color);
            background: var(--card-bg);
            color: var(--accent-color);
            box-shadow: 0 2px 8px rgba(0,0,0,0.22);
        }
        /* Hold now opens the options menu, so the fill is neutral accent —
           it used to be red because the hold deleted the deck outright */
        @keyframes deck-tab-hold {
            0%   { background: transparent; border-color: var(--border-color); }
            100% { background: var(--hover-bg-medium); border-color: var(--accent-color); }
        }
        .deck-tab.holding {
            animation: deck-tab-hold 0.55s linear forwards;
            cursor: wait;
        }

        /* ===== Deck tab hold menu (Rename / Delete) ===== */
        .deck-menu {
            position: fixed;
            z-index: 4000;
            min-width: 170px;
            padding: 6px;
            border-radius: 12px;
            background: var(--card-bg);
            border: 1px solid var(--border-color);
            box-shadow: 0 8px 26px rgba(0,0,0,0.28);
            display: flex;
            flex-direction: column;
            gap: 2px;
        }
        .deck-menu-name {
            padding: 6px 10px 7px;
            font-size: 0.72em;
            font-weight: 700;
            letter-spacing: 0.04em;
            text-transform: uppercase;
            opacity: 0.5;
            color: var(--card-text);
            border-bottom: 1px solid var(--border-color);
            margin-bottom: 3px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .deck-menu-btn {
            width: 100%;
            padding: 9px 10px;
            border: none;
            border-radius: 8px;
            background: transparent;
            color: var(--card-text);
            font-size: 0.86em;
            font-weight: 600;
            text-align: left;
            cursor: pointer;
            transition: background 0.15s;
        }
        .deck-menu-btn:hover { background: var(--hover-bg-light); }
        .deck-menu-del { color: #c0392b; }
        .deck-menu-del:hover { background: rgba(231,76,60,0.08); }
        body.dark-mode .deck-menu-del { color: #f1948a; }
        /* Fills red across the 900ms hold — the fill IS the confirmation */
        @keyframes deck-menu-del-hold {
            0%   { background: rgba(231,76,60,0.08); }
            100% { background: rgba(231,76,60,0.55); }
        }
        .deck-menu-del.holding {
            animation: deck-menu-del-hold 0.9s linear forwards;
            cursor: wait;
        }
        .deck-tab-add {
            flex-shrink: 0;
            width: 26px;
            height: 26px;
            border-radius: 50%;
            border: 1.5px solid var(--accent-color);
            background: var(--card-bg);
            color: var(--accent-color);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 1;
            box-shadow: 0 1px 3px rgba(0,0,0,0.12);
            transition: opacity 0.2s, background 0.2s;
            padding: 0;
        }
        .deck-tab-add:hover { opacity: 1; background: rgba(102,126,234,0.1); }

        /* ===== Sentence Builder (mockup preview for now) ===== */
        .sb-wrap { max-width: 640px; margin: 6px auto 40px; color: var(--card-text); }
        .sb-head { text-align: center; margin-bottom: 26px; }
        .sb-icon { font-size: 2.2em; line-height: 1; opacity: 0.9; }
        .sb-head h2 {
            margin: 10px 0 6px; font-size: 1.7em; font-weight: 800;
            letter-spacing: -0.02em;
        }
        .sb-sub { opacity: 0.6; line-height: 1.55; font-size: 0.85em; max-width: 460px; margin: 0 auto; }
        .sb-card {
            background: var(--card-bg);
            border-radius: 16px;
            padding: 24px;
            box-shadow: 0 4px 16px var(--shadow);
            user-select: none; -webkit-user-select: none;
        }
        .sb-label {
            font-size: 0.72em; font-weight: 700; text-transform: uppercase;
            letter-spacing: 0.06em; opacity: 0.5; margin: 4px 0 8px;
        }
        .sb-slot, .sb-tile {
            padding: 11px 16px; border-radius: 10px; font-weight: 600; font-size: 1em;
            background: var(--hover-bg-light); border: 2px solid transparent;
        }
        .sb-slot.correct { border-color: #27ae60; background: rgba(39, 174, 96, 0.14); color: #1e8449; }
        .sb-slot.wrong   { border-color: #e05252; background: rgba(224, 82, 82, 0.14); color: #c0392b; }
        .sb-slot.empty   { border: 2px dashed var(--border-color); background: transparent; opacity: 0.55; }
        .sb-tile {
            background: var(--card-bg); border: 2px solid var(--border-color); cursor: grab;
            touch-action: none; user-select: none; -webkit-user-select: none;
            text-align: center;
            /* Builder tiles are <div>s and inherit color from .sb-wrap already;
               Practice sentence tiles are <button>s, which get an opaque UA
               color (black) that ignores inheritance — this makes both match. */
            color: inherit; font-family: inherit;
        }
        .sb-tile-word { font-weight: 600; }
        .sb-tile-sub {
            font-size: 0.72em; font-weight: 600; opacity: 0.85;
            margin-top: 3px; font-style: normal; white-space: nowrap;
        }
        .sb-mini { cursor: pointer; touch-action: none; }
        .sb-mini.on { border-color: #27ae60; }
        .sb-group { display: inline-flex; }
        .sb-group .sb-mini { border-radius: 0; }
        .sb-group .sb-mini:not(:first-child) { margin-left: -2px; border-left-style: dotted; }
        .sb-group .sb-mini:first-child { border-radius: 10px 0 0 10px; }
        .sb-group .sb-mini:last-child { border-radius: 0 10px 10px 0; }
        .sb-tile.flip { background: var(--hover-bg-light); max-width: 260px; }
        .sb-tile.flip .sb-tile-sub { white-space: normal; }
        /* Tap-to-flip: squash to edge-on at the midpoint (JS swaps the tile's
           content there), stretch back. Keyframes, not a transform transition —
           the drag system's FLIP slides set inline transforms and must not
           inherit a lingering transition. */
        @keyframes sb-tile-flip {
            0%   { transform: rotateX(0); }
            50%  { transform: rotateX(90deg); }
            100% { transform: rotateX(0); }
        }
        .sb-tile.flipping { animation: sb-tile-flip 0.22s ease-in-out; }
        .sb-breakdown { margin-top: 12px; font-size: 0.85em; }
        .sb-breakdown .sb-label { margin-bottom: 4px; }
        .sb-bd-row { margin-top: 4px; opacity: 0.85; }
        .sb-bd-pos {
            font-size: 0.78em; font-weight: 600; opacity: 0.65;
            border: 1px solid var(--border-color); border-radius: 6px;
            padding: 1px 5px; margin-left: 4px; white-space: nowrap;
        }
        .sb-bd-note { font-size: 0.85em; opacity: 0.6; margin: 1px 0 2px 12px; }
        .sb-bd-morphs { font-size: 0.9em; opacity: 0.75; margin: 1px 0 2px 12px; }
        .sb-bd-verified { color: #27ae60; font-weight: 700; font-size: 0.9em; margin-left: 4px; }

        .sb-bd-edit {
            border: none; background: transparent; color: var(--card-text);
            opacity: 0.6; cursor: pointer; font-size: 0.95em;
            padding: 0 4px; margin-left: 6px; line-height: 1; vertical-align: baseline;
        }
        .sb-bd-edit:hover { opacity: 1; }

        /* Correct This Word modal (✎ on a How it's built row) */
        .tc-word-line { display: flex; align-items: baseline; gap: 10px; margin-bottom: 14px; }
        .tc-word { font-size: 1.25em; font-weight: 700; }
        .tc-lang { font-size: 0.82em; opacity: 0.55; }
        .tc-optional { font-weight: 400; opacity: 0.55; font-size: 0.9em; }
        .tc-hint { font-size: 0.78em; opacity: 0.55; margin: 2px 0 8px; }

        /* ===== "How it's built" as tiles — a word IS its pieces in order =====
           Replaces three stacked inputs per part (~200px each), which meant one part
           filled the whole panel and you could never see the word laid out. */
        .tcm-strip {
            display: flex;
            align-items: stretch;
            flex-wrap: wrap;
            gap: 4px;
            padding: 2px 0 8px;
        }
        .tcm-join { align-self: center; opacity: 0.4; font-weight: 700; color: var(--card-text); }
        .tcm-tile {
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            gap: 1px;
            padding: 6px 10px;
            border-radius: 9px;
            border: 1.5px solid var(--border-color);
            background: var(--card-bg);
            color: var(--card-text);
            cursor: pointer;
            text-align: left;
            transition: border-color 0.15s, background 0.15s;
        }
        .tcm-form { font-weight: 700; font-size: 0.92em; }
        .tcm-type { font-size: 0.62em; text-transform: uppercase; letter-spacing: 0.05em; opacity: 0.55; }
        .tcm-gloss { font-size: 0.68em; opacity: 0.6; }
        /* Same colour language as the live preview, so the two views agree on sight */
        .tcm-root   { border-color: var(--accent-color); }
        .tcm-prefix { border-color: #e67e22; }
        .tcm-suffix { border-color: #2ecc71; }
        .tcm-infix  { border-color: #9b59b6; }
        .tcm-linker { border-color: #2ecc71; }
        .tcm-tile:hover { background: var(--hover-bg-light); }
        @keyframes tcm-hold {
            0%   { background: transparent; }
            100% { background: rgba(231,76,60,0.35); border-color: rgba(231,76,60,0.8); }
        }
        .tcm-tile.holding { animation: tcm-hold 0.65s linear forwards; cursor: wait; }
        /* The inline "write a piece" box, sitting under the tiles */
        .tcm-add { display: flex; gap: 6px; margin-top: 8px; }
        .tcm-add .edit-input { margin: 0; flex: 1; font-size: 0.86em; padding: 8px 10px; }
        .tcm-add-btn {
            flex: 0 0 auto;
            padding: 0 14px;
            border-radius: 9px;
            border: 1.5px solid var(--accent-color);
            background: transparent;
            color: var(--accent-color);
            font-size: 0.84em;
            font-weight: 700;
            cursor: pointer;
        }
        .tcm-add-btn:hover { background: var(--hover-bg-light); }
        body.dark-mode .tcm-add-btn { background: rgba(255,255,255,0.06); }

        .tcm-result { font-size: 0.82em; opacity: 0.75; color: var(--card-text); }
        .tcm-arrow { opacity: 0.5; }
        .tcm-empty { font-size: 0.76em; opacity: 0.5; color: var(--card-text); padding: 4px 0 8px; line-height: 1.4; }
        body.dark-mode .tcm-tile { background: rgba(255,255,255,0.07); color: #e8e8ef; }
        body.dark-mode .tcm-join,
        body.dark-mode .tcm-result,
        body.dark-mode .tcm-empty { color: #e0e0e0; }

        /* Live preview when a word is typed in pieces: maayo + +ng → maayong */
        .tc-parts-preview {
            margin: 7px 0 2px;
            padding: 9px 10px;
            border-radius: 9px;
            background: var(--hover-bg-light);
            border: 1px solid var(--border-color);
        }
        .tcp-row {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 5px;
            font-size: 0.86em;
        }
        .tcp-chip {
            padding: 3px 8px;
            border-radius: 7px;
            font-weight: 700;
            background: var(--card-bg);
            border: 1px solid var(--border-color);
            color: var(--card-text);
        }
        /* Colour tells you what each piece IS without a word of explanation */
        .tcp-root   { border-color: var(--accent-color); color: var(--accent-color); }
        .tcp-prefix { border-color: #e67e22; color: #b35b0f; }
        .tcp-suffix { border-color: #2ecc71; color: #1e8449; }
        .tcp-infix  { border-color: #9b59b6; color: #7d3c98; }
        .tcp-plus   { opacity: 0.45; font-weight: 700; color: var(--card-text); }
        .tcp-arrow  { opacity: 0.45; margin: 0 2px; color: var(--card-text); }
        .tcp-built  { font-weight: 800; color: var(--card-text); }
        .tcp-note {
            font-size: 0.72em;
            opacity: 0.6;
            margin-top: 6px;
            color: var(--card-text);
        }
        body.dark-mode .tc-parts-preview { background: rgba(255,255,255,0.06); border-color: rgba(255,255,255,0.15); }
        body.dark-mode .tcp-chip { background: rgba(255,255,255,0.08); color: #e8e8ef; }
        body.dark-mode .tcp-prefix { border-color: #e67e22; color: #f0a860; }
        body.dark-mode .tcp-suffix { border-color: #2ecc71; color: #6ee7a0; }
        body.dark-mode .tcp-infix  { border-color: #9b59b6; color: #c99ddb; }
        body.dark-mode .tcp-plus,
        body.dark-mode .tcp-arrow,
        body.dark-mode .tcp-built,
        body.dark-mode .tcp-note { color: #e0e0e0; }

        /* Card tab "Optional details" expander — keeps the tab down to the 4 fields
           a card actually needs, so the popup fits a phone without scrolling */
        .tc-more {
            width: 100%;
            padding: 9px 2px;
            margin: 2px 0 10px;
            border: none;
            background: transparent;
            color: var(--accent-color);
            font-size: 0.82em;
            font-weight: 600;
            text-align: left;
            cursor: pointer;
        }
        .tc-more-arrow { font-size: 0.75em; display: inline-block; width: 12px; }

        /* Advanced accordion — one section open at a time. Example/morph rows grow
           without limit, so this is the only way the popup can hold them and still
           never scroll. Closed rows show their value so nothing hides by folding. */
        .tc-acc { border-bottom: 1px solid var(--border-color); }
        .tc-acc:last-of-type { border-bottom: none; }
        .tc-acc-head {
            width: 100%;
            display: flex;
            align-items: center;
            gap: 7px;
            padding: 12px 2px;
            border: none;
            background: transparent;
            color: var(--card-text);
            font-size: 0.88em;
            font-weight: 600;
            text-align: left;
            cursor: pointer;
        }
        .tc-acc-arrow { font-size: 0.7em; opacity: 0.6; display: inline-block; width: 11px; }
        .tc-acc-val {
            margin-left: auto;
            font-weight: 400;
            font-size: 0.85em;
            opacity: 0.5;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            max-width: 46%;
        }
        /* A "How it's built" part row is ~200px tall (four stacked inputs), so even a
           cap of 6 comes to ~1500px — capping tight enough to fit would mean allowing
           ONE part, which is useless. So the OPEN section scrolls inside itself instead.
           The popup keeps its fixed shape and never grows a scrollbar of its own, which
           is the rule that actually matters. */
        .tc-acc-body {
            padding: 0 2px 12px;
            /* 180px is what's actually left once the six folded rows, the tabs, the
               verified checkbox and the buttons have taken their share of the 656px
               popup — measured, not guessed. Any taller and the POPUP itself scrolls,
               which is the thing we're preventing. */
            max-height: 180px;
            overflow-y: auto;
            overscroll-behavior: contain;   /* don't chain the scroll out to the page */
        }
        body.dark-mode .tc-acc { border-color: rgba(255,255,255,0.12); }
        body.dark-mode .tc-acc-head { color: #e0e0e0; }
        /* Two-line part block so nothing overflows the modal on a phone:
           line 1 = part text + remove, line 2 = type dropdown + meaning. */
        .tc-morph-row {
            border: 1px solid var(--border-color); border-radius: 8px;
            padding: 8px; margin-bottom: 8px;
        }
        .tc-morph-line { display: flex; gap: 6px; align-items: center; }
        .tc-morph-line + .tc-morph-line { margin-top: 6px; }
        .tc-morph-row .edit-input { margin: 0; }
        .tc-morph-form { flex: 1 1 auto; min-width: 0; }
        .tc-morph-type { flex: 0 0 42%; }
        .tc-morph-gloss { flex: 1 1 auto; min-width: 0; }
        .tc-morph-fn { flex: 1 1 auto; min-width: 0; }
        .tc-example { flex: 1 1 auto; min-width: 0; }
        /* Card | Advanced tabs — same look as the main Cards/Practice/Builder
           mode tabs: pill container, borderless tabs, raised active tab */
        .tc-tabs {
            display: flex;
            gap: 5px;
            margin: 10px 0 14px;
            padding: 5px;
            background: var(--hover-bg-light);
            border-radius: 14px;
        }
        .tc-tab {
            flex: 1; min-width: 0;
            padding: 9px 8px;
            border: none;
            background: transparent;
            color: var(--card-text);
            opacity: 0.65;
            font-weight: 600; font-size: 0.9em;
            border-radius: 10px;
            cursor: pointer; font-family: inherit;
            transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;
        }
        .tc-tab:hover { opacity: 0.9; }
        .tc-tab.active {
            background: var(--card-bg);
            color: var(--accent-color);
            opacity: 1;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
        }
        /* Related-word chips — tap to open that word's editor */
        .tc-chip { font-size: 0.82em; padding: 2px 10px; background: transparent; }
        .tc-morph-remove {
            flex: 0 0 auto; width: 26px; height: 26px; border-radius: 6px;
            border: 1px solid var(--border-color); background: transparent;
            color: var(--card-text); opacity: 0.6; cursor: pointer;
            font-size: 1em; line-height: 1; padding: 0;
        }
        .tc-morph-remove:hover { opacity: 1; }
        /* Native select styled to match the custom-dropdown trigger: no OS arrow,
           our own chevron, box-sizing so it never spills past the modal edge. */
        .tc-select {
            -webkit-appearance: none; -moz-appearance: none; appearance: none;
            box-sizing: border-box; width: 100%; min-width: 0;
            padding: 9px 30px 9px 12px; border-radius: 8px;
            border: 1px solid var(--border-color);
            background-color: var(--card-bg); color: var(--card-text);
            font-size: 0.9em; font-family: inherit; cursor: pointer;
            background-repeat: no-repeat; background-position: right 10px center;
            background-size: 12px;
            background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
        }
        .tc-select:focus { outline: none; border-color: var(--accent-color); }
        /* Inputs and selects stay WHITE in dark mode — design rule, same as
           .custom-input. The chevron stays dark since the box stays white. */
        body.dark-mode .tc-select {
            background-color: white;
            color: #333;
            border-color: #d0d0d0;
        }
        body.dark-mode .edit-input {
            background: white;
            color: #333;
            border-color: #d0d0d0;
        }
        /* Dark-mode label/hint contrast — accent-on-dark needs full strength,
           and the muted bits get a light tint instead of fading into the bg */
        body.dark-mode .edit-label { opacity: 1; }
        body.dark-mode .tc-optional { color: #cfd4ff; opacity: 0.75; }
        body.dark-mode .tc-hint { color: #e0e0e0; opacity: 0.7; }
        body.dark-mode .tc-verified { color: #e0e0e0; }
        .tc-verified {
            display: flex; align-items: center; gap: 8px;
            font-size: 0.88em; margin: 4px 0 14px; cursor: pointer;
        }
        .tc-verified input { width: 16px; height: 16px; accent-color: #27ae60; }
        .sb-lang-pill {
            border: 2px solid var(--border-color); background: var(--card-bg);
            color: var(--card-text); border-radius: 20px; padding: 5px 14px;
            font-size: 0.85em; font-weight: 600; cursor: pointer;
        }
        .sb-lang-pill.active { border-color: #27ae60; color: #1e8449; background: rgba(39, 174, 96, 0.1); }
        body.dark-mode .sb-lang-pill.active { color: #6ee7a0; }
        .sb-tile.affix { border-style: dashed; font-style: italic; }
        .sb-tile.correct { border-color: #27ae60; background: rgba(39, 174, 96, 0.14); color: #1e8449; }
        body.dark-mode .sb-tile.correct { color: #6ee7a0; }
        .sb-tile-clone {
            position: fixed; z-index: 9999; pointer-events: none; margin: 0;
            transform: scale(1.08) rotate(2deg);
            box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
            transition: none;
        }
        .sb-tile-ghost { opacity: 0.35; border-style: dashed; }
        #sbAssembly { min-height: 56px; align-items: center; }
        .sb-line-hint { cursor: default; }
        .sb-empty { opacity: 0.55; font-size: 0.9em; padding: 4px 0 12px; }
        .sb-mini {
            display: inline-flex; align-items: center; gap: 6px;
            background: var(--card-bg); border: 2px solid var(--border-color);
            border-radius: 10px; padding: 8px 12px; font-weight: 600; font-size: 0.92em;
            transition: border-color 0.2s, background 0.2s, color 0.2s;
        }
        .sb-mini.correct { border-color: #27ae60; background: rgba(39, 174, 96, 0.14); color: #1e8449; }
        body.dark-mode .sb-mini.correct { color: #6ee7a0; }
        /* Affix linked to its root: tiles pull together with a dotted seam — two tiles
           reading as one word (gi-|gutom). Only shown when the merged word is real. */
        .sb-tile.linked-l {
            border-top-right-radius: 0; border-bottom-right-radius: 0;
            border-right-style: dotted;
        }
        .sb-tile.linked-r {
            margin-left: -12px;
            border-top-left-radius: 0; border-bottom-left-radius: 0;
            border-left: none;
            animation: sbSnapIn 0.18s ease;
        }
        @keyframes sbSnapIn { from { margin-left: 2px; } to { margin-left: -12px; } }
        .sb-tile.wrong { border-color: #e05252; background: rgba(224, 82, 82, 0.14); color: #c0392b; }
        body.dark-mode .sb-tile.wrong { color: #f5a3a3; }
        .sb-match { color: #1e8449; font-weight: 700; margin-top: 4px; display: flex; align-items: center; gap: 8px; }
        .sb-speak { color: inherit; }
        body.dark-mode .sb-match { color: #6ee7a0; }
        .sb-nomatch { opacity: 0.5; font-size: 0.9em; margin-top: 4px; }
        .sb-warn { color: #b9770e; font-weight: 600; font-size: 0.92em; margin-top: 4px; }
        body.dark-mode .sb-warn { color: #f0b859; }
        .sb-remove-btn {
            background: none; border: none; cursor: pointer; font-size: 0.9em;
            color: var(--card-text); opacity: 0.45; padding: 2px 6px;
        }
        .sb-remove-btn:hover { opacity: 1; color: #e05252; }
        /* Phone: keep the builder centered with comfortable touch targets.
           Slimmer box padding + trimmed tile padding = more room per row in portrait,
           and a clear row gap so drops land in the right row. */
        @media (max-width: 600px) {
            .sb-wrap { max-width: 100%; padding: 0 2px; }
            .sb-card { padding: 14px 10px; }
            .sb-slot, .sb-tile { padding: 10px 12px; font-size: 0.98em; }
            .sb-answer-row, .sb-tiles { gap: 8px; row-gap: 14px; }
            .sb-tile-sub { font-size: 0.68em; }
        }
        .sb-note {
            font-size: 0.8em; opacity: 0.6; text-align: center;
            border-top: 2px solid rgba(128, 128, 128, 0.28);
            margin-top: 14px; padding-top: 12px;
        }
        body.dark-mode .sb-slot.correct { color: #6ee7a0; }
        body.dark-mode .sb-slot.wrong { color: #f5a3a3; }

        .stat {
            text-align: center;
            flex: 1;
            border-right: 1px solid var(--border-color);
        }

        .stat:last-child {
            border-right: none;
        }

        .stat-value {
            font-size: 2em;
            font-weight: bold;
            color: var(--card-text);
        }

        .stat-label {
            font-size: 0.9em;
            color: #666;
            margin-top: 5px;
        }

        .main-content {
            display: grid;
            grid-template-columns: 400px 1fr 400px;
            gap: 30px;
            align-items: start;
            transition: grid-template-columns 0.3s ease;
        }

        .main-content.sidebar-hidden {
            grid-template-columns: 1fr 400px;
        }

        .main-content.settings-hidden {
            grid-template-columns: 400px 1fr;
        }

        .main-content.sidebar-hidden.settings-hidden {
            grid-template-columns: 1fr;
        }

        .flashcard-area {
            min-width: 0;
        }

        .sidebar {
            background: var(--sidebar-bg);
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 4px 15px var(--shadow);
            transition: all 0.3s ease;
            overflow: hidden;
        }

        .sidebar.hidden {
            display: none;
        }

        .settings-panel {
            background: var(--sidebar-bg);
            padding: 30px;
            border-radius: 15px;
            box-shadow: 0 4px 15px var(--shadow);
            transition: all 0.3s ease;
            overflow-y: auto;
            overflow-x: hidden;
        }

        .settings-panel.hidden {
            display: none;
        }

        /* Daily Reset toggle switch */
        .toggle-switch {
            position: relative;
            display: inline-block;
            width: 36px;
            height: 20px;
            flex-shrink: 0;
        }
        .toggle-switch input {
            opacity: 0;
            width: 0;
            height: 0;
        }
        .toggle-slider {
            position: absolute;
            cursor: pointer;
            top: 0; left: 0; right: 0; bottom: 0;
            background: rgba(0,0,0,0.15);
            border-radius: 24px;
            transition: background 0.3s;
        }
        .toggle-slider::before {
            content: '';
            position: absolute;
            height: 14px;
            width: 14px;
            left: 3px;
            bottom: 3px;
            background: white;
            border-radius: 50%;
            transition: transform 0.3s;
        }
        .toggle-switch input:checked + .toggle-slider {
            background: var(--accent-color);
        }
        .toggle-switch input:checked + .toggle-slider::before {
            transform: translateX(16px);
        }
        body.dark-mode .toggle-slider {
            background: rgba(255,255,255,0.2);
        }

        /* Info icon + tooltip */
        .info-icon {
            width: 18px;
            height: 18px;
            border-radius: 50%;
            background: rgba(0,0,0,0.1);
            color: var(--card-text);
            font-size: 0.72em;
            font-weight: 700;
            display: flex;
            align-items: center;
            justify-content: center;
            cursor: pointer;
            opacity: 0.45;
            user-select: none;
            flex-shrink: 0;
            transition: opacity 0.2s;
        }
        .info-icon:hover { opacity: 0.75; }
        body.dark-mode .info-icon {
            background: rgba(255,255,255,0.15);
        }
        .info-tooltip {
            visibility: hidden;
            opacity: 0;
            transition: opacity 0.35s, visibility 0.35s;
            position: absolute;
            right: 0;
            top: calc(100% + 8px);
            width: 220px;
            background: var(--sidebar-bg);
            border: 1px solid rgba(0,0,0,0.1);
            border-radius: 8px;
            padding: 10px 12px;
            font-size: 0.82em;
            color: var(--card-text);
            box-shadow: 0 4px 12px var(--shadow);
            z-index: 100;
            line-height: 1.4;
        }
        .info-tooltip.visible { visibility: visible; opacity: 0.85; }
        body.dark-mode .info-tooltip {
            border-color: rgba(255,255,255,0.1);
        }

        /* ---- Word Browser Sheet ---- */
        .wb-overlay {
            position: fixed;
            inset: 0;
            background: rgba(0,0,0,0.45);
            z-index: 10002;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.25s ease;
        }
        .wb-overlay.open { opacity: 1; pointer-events: all; }

        .wb-sheet {
            position: fixed;
            bottom: 0;
            left: 0;
            right: 0;
            height: 75vh;
            height: 75svh;
            background: #fff;
            border-radius: 18px 18px 0 0;
            z-index: 10003;
            display: flex;
            flex-direction: column;
            transform: translateY(100%);
            transition: transform 0.3s ease;
            box-shadow: 0 -6px 30px rgba(0,0,0,0.18);
        }
        .wb-sheet.open { transform: translateY(0); }

        body.dark-mode .wb-sheet { background: #1e1e2e; }

        .wb-header {
            padding: 16px 16px 10px;
            border-bottom: 1px solid rgba(0,0,0,0.08);
            flex-shrink: 0;
        }
        body.dark-mode .wb-header { border-bottom-color: rgba(255,255,255,0.08); }

        .wb-header-top {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 10px;
        }
        .wb-back {
            background: none;
            border: none;
            cursor: pointer;
            color: var(--accent-color);
            font-size: 0.9em;
            font-weight: 700;
            padding: 4px 9px;
            border-radius: 6px;
            flex-shrink: 0;
        }
        .wb-back:hover { background: var(--hover-bg-medium); }

        .wb-title {
            font-size: 1em;
            font-weight: 700;
            color: var(--card-text);
            flex: 1;
        }
        .wb-search {
            width: 100%;
            box-sizing: border-box;
            padding: 9px 13px;
            border: 1px solid rgba(0,0,0,0.15);
            border-radius: 8px;
            font-size: 0.88em;
            background: var(--hover-bg-light, #f5f5f5);
            color: var(--card-text);
            outline: none;
        }
        .wb-search:focus { border-color: var(--accent-color); }
        body.dark-mode .wb-search {
            background: #ffffff;
            border-color: rgba(0,0,0,0.15);
            color: #111;
        }
        .wb-body {
            overflow-y: auto;
            flex: 1;
            padding: 12px 16px 32px;
            -webkit-overflow-scrolling: touch;
            overscroll-behavior: contain;
        }

        /* ---- Sidebar section labels ---- */
        .sidebar-section-label {
            font-size: 0.75em;
            font-weight: 700;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            color: var(--card-text);
            opacity: 0.65;
        }

        body.dark-mode .sidebar-section-label {
            opacity: 0.85;
        }

        .sidebar-section-header {
            display: flex;
            align-items: center;
            justify-content: flex-start;
            gap: 8px;
            margin-bottom: 8px;
            cursor: pointer;
            user-select: none;
        }

        .sidebar-section-arrow {
            font-size: 1em;
            opacity: 0.7;
            transition: transform 0.3s;
            color: var(--card-text);
            transform: rotate(0deg);
            flex-shrink: 0;
        }

        body.dark-mode .sidebar-section-arrow {
            opacity: 0.85;
        }

        .sidebar-section-arrow.open {
            transform: rotate(90deg);
        }

        .tts-card {
            background: #fff8e1;
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 14px;
            border: 1px solid var(--accent-color);
        }
        /* The cream STAYS in dark mode — Paul: "it stands out for a reason." The bug
           was never the yellow, it was that --card-text flipped to light and left light
           text sitting on a light panel. So: keep the cream, force the text DARK inside
           it. The panel reads as a highlighted card in both themes, which is the point. */
        body.dark-mode .tts-card {
            background: #fff8e1;
            border-color: var(--accent-color);
        }
        body.dark-mode .tts-card,
        body.dark-mode .tts-card p,
        body.dark-mode .tts-card label,
        body.dark-mode .tts-card span,
        body.dark-mode .tts-card .sidebar-section-header { color: #2f2f33; }
        /* Controls inside must sit on cream, not on the dark theme's surfaces */
        body.dark-mode .tts-card .btn {
            background: rgba(0,0,0,0.06);
            color: #2f2f33;
            border-color: rgba(0,0,0,0.18);
        }
        body.dark-mode .tts-card .btn:hover { background: rgba(0,0,0,0.12); }
        body.dark-mode .tts-card .custom-input {
            background: #fff;
            color: #2f2f33;
            border-color: rgba(0,0,0,0.18);
        }
        body.dark-mode .tts-card .custom-input::placeholder { color: #8a8a8a; }
        body.dark-mode .tts-card input[type="range"] { background: rgba(0,0,0,0.15); }
        body.dark-mode .tts-card .sidebar-section-arrow { color: #2f2f33; }

        /* These two classes are used BOTH inside the cream card and outside it (the
           corrections hint sits on the panel background). Outside, the background flips
           with the theme, so the text must flip too. Inside, the cream never flips, so
           the text must NOT — and the dark-mode rule has to be out-specified there or it
           would put light text back on cream, which is the exact bug being fixed. */
        .tts-muted { color: #888; }
        .tts-dim   { color: #aaa; }
        body.dark-mode .tts-muted { color: #c2c2d0; }
        body.dark-mode .tts-dim   { color: #a6a6b8; }
        .tts-card .tts-muted,
        body.dark-mode .tts-card .tts-muted { color: #6b6247; }
        .tts-card .tts-dim,
        body.dark-mode .tts-card .tts-dim { color: #756c52; }
        /* ---- Language Pills ---- */
        .lang-pills-bar {
            display: flex;
            flex-direction: column;
            gap: 8px;
            margin-bottom: 14px;
        }

        .lang-pills-header {
            display: flex;
            align-items: center;
            justify-content: space-between;
        }

        .lang-pills-label {
            font-size: 0.78em;
            font-weight: 700;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            opacity: 0.55;
            color: var(--sidebar-text);
        }

        .add-lang-btn {
            width: 25px;
            height: 25px;
            border-radius: 50%;
            border: 1.5px solid rgba(102,126,234,0.5);
            background: transparent;
            color: var(--accent-color);
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0.7;
            transition: opacity 0.2s, background 0.2s;
            padding: 0;
        }
        .add-lang-btn:hover { opacity: 1; background: rgba(102,126,234,0.1); }

        .lang-pills-row {
            display: flex;
            flex-wrap: wrap;
            gap: 6px;
            min-height: 26px;
        }

        .lang-pill {
            display: inline-flex;
            align-items: center;
            gap: 4px;
            padding: 4px 10px;
            border-radius: 20px;
            border: 1.5px solid rgba(0,0,0,0.13);
            background: transparent;
            font-size: 0.83em;
            font-weight: 500;
            color: var(--card-text);
            user-select: none;
            transition: border-color 0.15s, background 0.15s;
        }

        .lang-pill:hover {
            border-color: var(--accent-color);
            background: var(--hover-bg-light);
        }

        .lang-pill.active {
            border-color: var(--accent-color);
            background: rgba(102,126,234,0.10);
            color: var(--accent-color);
            font-weight: 600;
        }

        .lang-pill-text {
            cursor: pointer;
        }

        @keyframes pill-hold {
            0%   { background: transparent; border-color: var(--border-color); }
            100% { background: rgba(231,76,60,0.2); border-color: rgba(231,76,60,0.7); }
        }
        .lang-pill.holding {
            animation: pill-hold 0.6s linear forwards;
            cursor: wait;
        }

        body.dark-mode .lang-pill {
            border-color: rgba(255,255,255,0.2);
            color: #e0e0e0;
        }

        body.dark-mode .lang-pill.active {
            border-color: var(--accent-color);
            background: rgba(139,157,255,0.15);
            color: var(--accent-color);
        }

        /* ---- Category Checklist ---- */
        .cat-check-item {
            display: flex;
            align-items: center;
            gap: 9px;
            padding: 5px 2px;
            font-size: 0.85em;
            color: var(--card-text);
            cursor: pointer;
        }

        .cat-check-item input[type="checkbox"] {
            accent-color: var(--accent-color);
            width: 14px;
            height: 14px;
            cursor: pointer;
            flex-shrink: 0;
        }

        /* ---- Add inline inputs ---- */
        .add-inline-row {
            display: flex;
            align-items: center;
            gap: 6px;
            margin-top: 4px;
            padding: 2px 0;
        }

        .add-inline-btn {
            font-size: 0.83em;
            color: var(--accent-color);
            background: none;
            border: none;
            cursor: pointer;
            padding: 4px 0;
            opacity: 0.8;
        }

        .add-inline-btn:hover { opacity: 1; }

        .add-inline-input {
            flex: 1;
            font-size: 0.82em;
            padding: 5px 8px;
            border-radius: 5px;
            border: 1.5px solid rgba(0,0,0,0.15);
            background: transparent;
            color: var(--card-text);
            outline: none;
        }

        .add-inline-input:focus { border-color: var(--accent-color); }

        body.dark-mode .add-inline-input { border-color: rgba(255,255,255,0.2); }

        .add-inline-confirm {
            font-size: 0.82em;
            padding: 5px 10px;
            border-radius: 5px;
            border: none;
            background: var(--accent-color);
            color: white;
            cursor: pointer;
        }

        /* ---- Browse Library ---- */
        .browse-item {
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 8px 11px;
            border-radius: 7px;
            cursor: pointer;
            font-size: 0.87em;
            color: var(--card-text);
            margin-bottom: 2px;
            border: 1.5px solid transparent;
            transition: background 0.1s;
        }

        .browse-item:hover {
            background: var(--hover-bg-light);
        }

        body.dark-mode .browse-item:hover {
            background: rgba(255,255,255,0.06);
        }

        .browse-item.active {
            background: rgba(102,126,234,0.1);
            border-color: rgba(102,126,234,0.3);
            color: var(--accent-color);
            font-weight: 600;
        }

        body.dark-mode .browse-item.active {
            background: rgba(102,126,234,0.15);
        }

        .browse-item-right {
            display: flex;
            align-items: center;
            gap: 6px;
            flex-shrink: 0;
        }

        .browse-item-count {
            font-size: 0.78em;
            opacity: 0.45;
        }

        .browse-item-arrow {
            font-size: 0.68em;
            opacity: 0.4;
        }

        /* ---- Word Browser Groups ---- */
        .word-group {
            border-radius: 8px;
            background: var(--hover-bg-medium);
            margin-bottom: 8px;
            overflow: hidden;
        }

        .word-group-english {
            font-weight: 600;
            font-size: 0.95em;
            color: var(--card-text);
            padding: 9px 13px 5px;
        }

        .word-lang-row {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px 13px;
            border-top: 1px solid rgba(0,0,0,0.05);
        }
        body.dark-mode .word-lang-row { border-top-color: rgba(255,255,255,0.05); }

        .word-lang-left {
            flex: 1;
            min-width: 0;
            display: flex;
            flex-direction: column;
            gap: 1px;
        }
        .word-lang-badge {
            font-size: 0.68em;
            font-weight: 700;
            text-transform: uppercase;
            letter-spacing: 0.03em;
            color: var(--accent-color);
            opacity: 0.85;
        }
        .word-lang-translation {
            font-size: 0.95em;
            color: var(--card-text);
            font-weight: 600;
            word-break: break-word;
        }
        /* Word-as-pill: same oval outline as the language pills, sized to its
           text. Hold 600ms to open the word-node editor. */
        .word-pill {
            display: inline-block;
            align-self: flex-start;
            width: fit-content;
            max-width: 100%;
            border: 1.5px solid var(--accent-color);
            border-radius: 20px;
            padding: 3px 12px;
            cursor: pointer;
            user-select: none;
            -webkit-user-select: none;
            -webkit-touch-callout: none;
            transition: border-color 0.15s, background 0.15s;
        }
        .word-pill.holding {
            background: rgba(102,126,234,0.14);
        }
        .word-lang-actions {
            display: flex;
            align-items: center;
            gap: 5px;
            flex-shrink: 0;
        }

        .add-word-btn {
            padding: 8px 20px;
            background: var(--accent-color);
            color: white;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-weight: bold;
            transition: all 0.3s;
        }

        .add-word-btn:hover {
            background: var(--accent-color-hover);
            transform: translateY(-2px);
        }

        .add-word-btn:disabled {
            background: var(--hover-bg-medium);
            color: var(--card-text);
            cursor: not-allowed;
            transform: none;
            opacity: 0.5;
        }

        /* "In your deck" state — still clickable (tap to remove), so it
           can't look identical to :disabled's not-allowed styling. */
        .add-word-btn.added {
            background: var(--hover-bg-medium);
            color: var(--card-text);
            opacity: 0.75;
        }
        .add-word-btn.added:hover {
            background: rgba(200,80,80,0.15);
            color: rgba(200,80,80,0.9);
            transform: none;
            opacity: 1;
        }

        .custom-card {
            background: #f0f4ff;
            padding: 20px;
            border-radius: 10px;
            margin-top: 20px;
            border: 1px solid var(--accent-color);
        }

        .custom-card h3 {
            color: var(--accent-color);
            margin-bottom: 15px;
            text-align: center;
            font-size: 0.95em;
        }

        .custom-input {
            width: 100%;
            padding: 12px;
            margin-bottom: 10px;
            border: 2px solid #e0e0e0;
            border-radius: 8px;
            font-size: 1em;
            color: #333;
            background: white;
            box-sizing: border-box;
            appearance: auto;
        }

        select.custom-input {
            appearance: none;
            -webkit-appearance: none;
            background-image: none;
            padding-right: 36px;
            cursor: pointer;
        }

        .select-wrapper {
            position: relative;
            margin-bottom: 10px;
        }
        .select-wrapper select.custom-input {
            margin-bottom: 0;
        }
        .select-wrapper::after {
            content: '▶';
            position: absolute;
            right: 14px;
            top: 50%;
            transform: translateY(-50%) rotate(0deg);
            pointer-events: none;
            transition: transform 0.3s;
            color: #666;
            font-size: 0.78em;
            line-height: 1;
        }
        .select-wrapper.select-open::after {
            transform: translateY(-50%) rotate(90deg);
        }
        body.dark-mode .select-wrapper::after {
            color: #999;
        }
        /* Both boxes same color in dark mode as light — all arrows stay dark */
        body.dark-mode .custom-card .select-wrapper::after,
        body.dark-mode .tts-card .select-wrapper::after {
            color: #666;
        }
        body.dark-mode .custom-card .sidebar-section-arrow,
        body.dark-mode .tts-card .sidebar-section-arrow {
            color: #555;
        }

        /* Custom dropdown (replaces native <select> for customLanguage/customCategory
           so open/close state is fully JS-controlled — no native-popup event
           ambiguity, so the arrow can never be wrong). */
        .custom-dropdown-trigger {
            display: block;
            width: 100%;
            text-align: left;
            font-family: inherit;
            padding-right: 36px;
            cursor: pointer;
            margin-bottom: 0;
        }
        .custom-dropdown-list {
            display: none;
            position: absolute;
            top: calc(100% + 4px);
            left: 0;
            right: 0;
            z-index: 20;
            max-height: 260px;
            overflow-y: auto;
            background: white;
            border: 1px solid #ccc;
            border-radius: 8px;
            box-shadow: 0 6px 20px rgba(0,0,0,0.15);
            list-style: none;
            margin: 0;
            padding: 4px 0;
        }
        .custom-dropdown.select-open .custom-dropdown-list {
            display: block;
        }
        .custom-dropdown-option {
            padding: 10px 14px;
            font-size: 1em;
            color: #333;
            cursor: pointer;
        }
        .custom-dropdown-option:hover {
            background: rgba(102,126,234,0.1);
        }
        .custom-dropdown-option.selected {
            background: #667eea;
            color: white;
        }
        .custom-dropdown-divider {
            height: 1px;
            margin: 4px 10px;
            background: #ddd;
        }
        body.dark-mode .custom-dropdown-list {
            background: #2a2a2a;
            border-color: #444;
        }
        body.dark-mode .custom-dropdown-option {
            color: #eee;
        }
        body.dark-mode .custom-dropdown-option:hover {
            background: rgba(102,126,234,0.25);
        }
        body.dark-mode .custom-dropdown-divider {
            background: #444;
        }

        .custom-input:focus {
            outline: none;
            border-color: var(--accent-color);
        }

        body.dark-mode .custom-input {
            background: white;
            color: #333;
            border-color: #d0d0d0;
        }

        .action-buttons {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }

        .btn {
            flex: 1;
            padding: 12px;
            border: none;
            border-radius: 8px;
            font-weight: bold;
            cursor: pointer;
            transition: all 0.3s;
        }

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

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

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

        .btn-secondary:hover {
            background: var(--hover-bg-light);
            border-color: var(--hover-border);
        }

        .btn-active {
            background: transparent !important;
            color: var(--accent-color) !important;
            border-color: var(--accent-color) !important;
            border-width: 2px !important;
        }
        .btn-active:hover {
            background: var(--accent-color) !important;
            color: white !important;
        }

        .flashcard-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, var(--card-width));
            gap: 20px;
            justify-content: center;
            perspective: 1000px;
        }

        .mastered-section {
            grid-column: 1 / -1;
            margin-top: 40px;
            padding-top: 20px;
            border-top: 2px solid var(--border-color);
        }

        .mastered-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px 10px;
            background: transparent;
            color: var(--card-text);
            cursor: pointer;
            user-select: none;
            transition: all 0.3s;
        }

        .mastered-header:hover {
            background: var(--hover-bg-light);
        }

        .mastered-title {
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 1.1em;
            font-weight: 600;
            color: var(--card-text);
            opacity: 0.85;
        }

        .mastered-count {
            color: var(--card-text);
            padding: 2px 10px;
            font-size: 0.95em;
            font-weight: 600;
            opacity: 0.75;
        }

        .mastered-arrow {
            font-size: 1em;
            transition: transform 0.3s;
            color: var(--card-text);
            opacity: 0.7;
            transform: rotate(90deg);
        }

        .mastered-arrow.collapsed {
            transform: rotate(0deg);
        }

        .mastered-content {
            max-height: 0;
            overflow: hidden;
            transition: max-height 0.3s ease-out;
        }

        .mastered-content.expanded {
            max-height: none;
            padding: 20px 0;
        }

        .mastered-cards-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, var(--card-width));
            gap: 20px;
            justify-content: center;
        }

        .drag-handle {
            position: absolute;
            top: 50%;
            left: calc(10px * var(--card-scale));
            right: auto;
            transform: translateY(-50%);
            cursor: grab;
            font-size: calc(0.85em * var(--card-scale));
            color: rgba(102, 126, 234, 0.7);
            z-index: 20;
            padding: calc(5px * var(--card-scale)) calc(7px * var(--card-scale));
            opacity: 0.6;
            transition: all 0.3s;
            background: rgba(255, 255, 255, 0.9);
            border: calc(1.5px * var(--card-scale)) solid rgba(150, 150, 150, 0.3);
            border-radius: calc(6px * var(--card-scale));
            box-shadow: 0 2px 8px rgba(0,0,0,0.08);
        }

        .drag-handle:hover {
            opacity: 1;
            color: rgba(102, 126, 234, 1);
            border-color: rgba(102, 126, 234, 0.4);
            box-shadow: 0 2px 12px rgba(102, 126, 234, 0.25);
            transform: translateY(-50%) scale(1.1);
        }

        .drag-handle:active {
            cursor: grabbing;
            opacity: 1;
        }

        /* Hide the grip only when a NORMAL-mode card is flipped to its answer.
           In reverse mode the rest state IS flipped, so the grip must stay usable there. */
        .flashcard:not(.reverse-mode).flipped .drag-handle {
            opacity: 0;
            pointer-events: none;
        }

        .flashcard.locked .drag-handle {
            opacity: 0;
            pointer-events: none;
        }

        .flashcard {
            transition: all 0.3s ease;
        }

        /* ---- Custom drag visuals (desktop + touch) ---- */
        /* Custom drag: the clone that follows the finger — lifted + tilted like held. */
        /* A card that isn't set up properly says so, rather than failing quietly.
           Muted, not alarming — it's a to-do, not an error.
           ONE outline, not two: every card already carries a 2px accent border on the
           flipper, so the red RECOLOURS that border rather than drawing a second ring
           inside it. Adding a ring meant the theme's accent sat outside the red and the
           red read as the smaller of two outlines. Recolouring also costs no layout —
           the border is the same 2px setCardHeights() already measures. */
        .flashcard.needs-info .flashcard-flipper {
            border-color: rgba(231, 76, 60, 0.85);
        }
        body.dark-mode .flashcard.needs-info .flashcard-flipper {
            border-color: #e74c3c;
        }
        /* Lives in the FRONT footer, where the speaker sits on the back */
        .needs-info-btn {
            display: inline-flex;
            align-items: center;
            gap: 5px;
            padding: 3px 10px;
            border-radius: 20px;
            border: 1px solid rgba(231, 76, 60, 0.5);
            background: rgba(231, 76, 60, 0.10);
            color: #c0392b;
            font-size: calc(0.62em * var(--card-scale));
            font-weight: 700;
            letter-spacing: 0.03em;
            cursor: pointer;
            opacity: 0.85;
            transition: opacity 0.15s, background 0.15s;
        }
        .needs-info-btn:hover { opacity: 1; background: rgba(231, 76, 60, 0.20); }
        body.dark-mode .needs-info-btn { color: #e74c3c; }

        .flashcard.drag-clone {
            position: fixed;
            margin: 0 !important;
            opacity: 1 !important;
            transform: scale(1.06) rotate(1.5deg);
            box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
            cursor: grabbing;
            pointer-events: none;
            z-index: 9999;
            transition: none;   /* stick to the finger with zero lag (drop-settle sets its own transition inline) */
        }
        body.dark-mode .flashcard.drag-clone {
            box-shadow: 0 18px 44px rgba(0, 0, 0, 0.6);
        }
        /* The ghost slot showing where the card will drop — deliberately MUCH lighter than
           a studied/faded card (0.65) and outlined, so the two never look alike. !important
           beats .flashcard.faded, which is defined later and would otherwise win. */
        .flashcard.drag-placeholder {
            opacity: 0.18 !important;
            outline: 2px dashed var(--accent-color);
            outline-offset: -5px;
            border-radius: 14px;
        }
        body.dark-mode .flashcard.drag-placeholder {
            opacity: 0.26 !important;
        }
        /* While dragging, hide every card icon except the grip so you can't accidentally
           hit delete / studied / lock / speaker. They return (with their state) on drop. */
        body.dragging-active .lock-btn,
        body.dragging-active .studied-check,
        body.dragging-active .delete-btn,
        body.dragging-active .mastered-crown,
        body.dragging-active .flashcard-speaker {
            opacity: 0 !important;
            pointer-events: none !important;
        }
        /* No text selection / no page scroll interference while dragging. */
        body.dragging-active {
            user-select: none;
            -webkit-user-select: none;
        }
        .drag-handle {
            touch-action: none;
        }

        .lock-btn {
            position: absolute;
            bottom: calc(10px * var(--card-scale));
            right: calc(10px * var(--card-scale));
            width: calc(32px * var(--card-scale));
            height: calc(32px * var(--card-scale));
            background: transparent;
            border: calc(2px * var(--card-scale)) solid rgba(0, 0, 0, 0.15);
            border-radius: 50%;
            cursor: pointer;
            font-size: calc(1em * var(--card-scale));
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 100;
            transition: all 0.3s;
            backface-visibility: hidden;
        }

        /* Unlocked state - subtle and gray */
        .lock-btn.unlocked-state {
            color: rgba(150, 150, 150, 0.7);
            border-color: rgba(150, 150, 150, 0.4);
            opacity: 0.6;
            font-size: 0.95em;
        }

        .flashcard:hover .lock-btn.unlocked-state {
            border-color: rgba(150, 150, 150, 0.2);
        }

        /* Locked state - Gray circle with bold icon */
        .lock-btn.locked-state {
            background: rgba(100, 100, 100, 0.1);
            border-color: rgba(100, 100, 100, 0.4);
            color: rgba(50, 50, 50, 0.9);
            opacity: 1;
            font-size: 1.05em;
            font-weight: bold;
        }

        .flashcard:hover .lock-btn.locked-state {
            background: rgba(100, 100, 100, 0.2);
            border-color: rgba(100, 100, 100, 0.6);
        }

        .lock-btn:hover {
            transform: scale(1.15) !important;
            opacity: 1 !important;
        }

        .lock-btn.locked-state:hover {
            background: rgba(100, 100, 100, 0.25) !important;
            border-color: rgba(100, 100, 100, 0.7) !important;
        }

        body.dark-mode .lock-btn.unlocked-state {
            color: rgba(200, 200, 200, 0.7);
            border-color: rgba(200, 200, 200, 0.4);
            opacity: 0.6;
        }

        body.dark-mode .flashcard:hover .lock-btn.unlocked-state {
            color: rgba(200, 200, 200, 0.9);
            border-color: rgba(200, 200, 200, 0.6);
        }

        body.dark-mode .lock-btn.locked-state {
            background: rgba(180, 180, 180, 0.15);
            border-color: rgba(180, 180, 180, 0.4);
            color: rgba(220, 220, 220, 0.9);
        }

        body.dark-mode .flashcard:hover .lock-btn.locked-state {
            background: rgba(180, 180, 180, 0.25);
            border-color: rgba(180, 180, 180, 0.6);
        }

        /* Normal mode: icons hide when flipped to answer */
        .flashcard:not(.reverse-mode).flipped .drag-handle,
        .flashcard:not(.reverse-mode).flipped .lock-btn,
        .flashcard:not(.reverse-mode).flipped .mastered-crown,
        .flashcard:not(.reverse-mode).flipped .studied-check,
        .flashcard:not(.reverse-mode).flipped .delete-btn,
        /* Reverse mode: icons hide when NOT flipped (answer/front face showing) */
        .flashcard.reverse-mode:not(.flipped) .drag-handle,
        .flashcard.reverse-mode:not(.flipped) .lock-btn,
        .flashcard.reverse-mode:not(.flipped) .mastered-crown,
        .flashcard.reverse-mode:not(.flipped) .studied-check,
        .flashcard.reverse-mode:not(.flipped) .delete-btn,
        /* During flip animation — always hide */
        .flashcard.flipping-back .drag-handle,
        .flashcard.flipping-back .lock-btn,
        .flashcard.flipping-back .mastered-crown,
        .flashcard.flipping-back .studied-check,
        .flashcard.flipping-back .delete-btn {
            opacity: 0 !important;
            pointer-events: none;
            transition: none !important;
        }

        /* Dark mode icon adjustments - match light mode 0.6 opacity */
        body.dark-mode .drag-handle {
            background: rgba(255, 255, 255, 0.9);
            color: rgba(102, 126, 234, 0.7);
        }

        body.dark-mode .drag-handle:hover {
            color: rgba(102, 126, 234, 1);
        }

        body.dark-mode .mastered-crown {
            color: rgba(220, 220, 220, 0.7);
            border-color: rgba(220, 220, 220, 0.4);
        }

        body.dark-mode .mastered-crown.mastered {
            color: #ffc107;
            border-color: #ffc107;
        }

        body.dark-mode .delete-btn {
            color: rgba(200, 200, 200, 0.7);
            border-color: rgba(200, 200, 200, 0.2);
        }

        body.dark-mode .studied-check {
            border-color: #8a9ab0 !important;
            color: #ddd;
        }

        body.dark-mode .studied-check.checked {
            background: white !important;
            border-color: rgba(200, 200, 200, 0.6) !important;
            color: #333;
        }

        .flashcard {
            width: var(--card-width);
            min-height: calc(var(--card-width) * 0.5);
            cursor: pointer;
            position: relative;
            -webkit-user-select: none;
            user-select: none;
            -webkit-touch-callout: none;
        }

        .flashcard:hover .flashcard-flipper {
            box-shadow: 0 6px 20px rgba(0,0,0,0.15);
        }

        /* Flipper carries the card visuals so the whole card body flips */
        .flashcard-flipper {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            transform-style: preserve-3d;
            -webkit-transform-style: preserve-3d;
            transition: transform 0.6s;
            -webkit-transition: -webkit-transform 0.6s;
            border-radius: 15px;
            background: white;
            box-shadow: 0 4px 15px rgba(0,0,0,0.1);
            border: 2px solid var(--accent-color);
        }

        .flashcard.flipped .flashcard-flipper {
            transform: rotateY(180deg);
            -webkit-transform: rotateY(180deg);
        }

        .flashcard-front, .flashcard-back {
            backface-visibility: hidden;
            -webkit-backface-visibility: hidden;
            position: absolute;
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            box-sizing: border-box;
            overflow: hidden;
            background: white;
            border-radius: 13px;
        }

        .flashcard-back {
            transform: rotateY(180deg);
            -webkit-transform: rotateY(180deg);
        }

        .flashcard-text {
            font-size: calc(1.6em * var(--card-scale));
            font-weight: bold;
            text-align: center;
            color: #333;
            word-break: break-word;
            overflow-wrap: break-word;
            max-width: 100%;
            line-height: 1.25;
        }

        .flashcard-transliteration {
            font-size: calc(1.2em * var(--card-scale));
            color: #555;
            font-weight: 600;
            margin-top: calc(4px * var(--card-scale));
            text-align: center;
            word-break: break-word;
            overflow-wrap: break-word;
            max-width: 100%;
            line-height: 1.25;
        }

        .flashcard-pronunciation {
            font-size: calc(1.0em * var(--card-scale));
            color: #999;
            font-style: italic;
            margin-top: calc(8px * var(--card-scale));
            font-weight: 500;
            text-align: center;
            word-break: break-word;
            overflow-wrap: break-word;
            max-width: 100%;
            line-height: 1.3;
        }

        .flashcard-speaker {
            background: transparent;
            color: rgba(80, 80, 80, 0.65);
            border: none;
            border-radius: 50%;
            width: calc(30px * var(--card-scale));
            height: calc(30px * var(--card-scale));
            font-size: calc(1em * var(--card-scale));
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s;
            opacity: 0.7;
        }

        .flashcard-speaker:hover,
        .flashcard-speaker:active {
            background: var(--hover-bg-light);
            color: rgba(60, 60, 60, 0.9);
            border: 1px solid var(--hover-border);
            transform: scale(1.1);
            opacity: 1;
        }

        .flashcard-speaker:disabled {
            opacity: 0.3;
            cursor: default;
        }

        .flashcard-speaker:disabled:hover {
            background: transparent;
            border: none;
            transform: none;
        }

        .delete-btn {
            position: absolute;
            top: calc(10px * var(--card-scale));
            right: calc(10px * var(--card-scale));
            width: calc(32px * var(--card-scale));
            height: calc(32px * var(--card-scale));
            background: transparent;
            color: rgba(90, 90, 90, 0.9);
            border: calc(2px * var(--card-scale)) solid rgba(90, 90, 90, 0.25);
            border-radius: 50%;
            cursor: pointer;
            font-size: calc(1.0em * var(--card-scale));
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 100;
            opacity: 0.75;
            transition: opacity 0.3s, transform 0.3s, border-color 0.3s, background 0.3s;
            font-weight: bold;
        }
        .delete-btn-icon {
            width: calc(14px * var(--card-scale));
            height: calc(14px * var(--card-scale));
            flex-shrink: 0;
        }
        .modal-close-icon {
            width: 14px;
            height: 14px;
            flex-shrink: 0;
        }

        .flashcard:hover .delete-btn {
            opacity: 0.6;
        }

        /* Hover-capable devices only — on touch, :hover latches after a tap
           and the button stays red (e.g. tapping delete on a locked card) */
        @media (hover: hover) {
            .delete-btn:hover {
                opacity: 1 !important;
                background: rgba(220, 80, 80, 0.08) !important;
                border-color: rgba(200, 80, 80, 0.4) !important;
                color: rgba(200, 80, 80, 0.9) !important;
                transform: scale(1.15);
            }
        }

        /* ── Card inner sections ── */
        .card-header {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            gap: calc(3px * var(--card-scale));
            padding: calc(7px * var(--card-scale)) calc(36px * var(--card-scale)) calc(8px * var(--card-scale));
            border-bottom: 1px solid rgba(0,0,0,0.07);
            flex-shrink: 0;
        }

        .card-content {
            flex: 1;
            min-height: 0;
            overflow-y: auto;
            /* Cards size themselves (200–400px) — never show an inner scrollbar */
            scrollbar-width: none;
            -ms-overflow-style: none;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: calc(14px * var(--card-scale)) calc(40px * var(--card-scale));
            text-align: center;
        }

        .card-footer {
            border-top: 1px solid rgba(0,0,0,0.07);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: calc(7px * var(--card-scale));
            flex-shrink: 0;
        }

        /* Same height it always was — the front must not change shape, or the lock and
           the crown get squeezed. It just centres the "needs info" mark when there is one. */
        .card-footer-spacer {
            height: calc(44px * var(--card-scale));
            flex-shrink: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .language-badge {
            font-size: calc(0.75em * var(--card-scale));
            font-weight: 700;
            letter-spacing: 0.08em;
            text-transform: uppercase;
            color: #bbb;
        }

        .studied-check {
            position: absolute;
            top: calc(10px * var(--card-scale));
            left: calc(10px * var(--card-scale));
            width: calc(26px * var(--card-scale));
            height: calc(26px * var(--card-scale));
            background: #ffffff !important;
            border: calc(2px * var(--card-scale)) solid #a8b4c4 !important;
            color: #555;
            border-radius: calc(5px * var(--card-scale));
            cursor: pointer;
            font-size: calc(0.95em * var(--card-scale));
            font-weight: bold;
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10;
            opacity: 0.6;
            transition: opacity 0.3s, transform 0.3s;
            pointer-events: auto;
            box-shadow: none !important;
        }

        .studied-check::before {
            content: '';
            opacity: 0;
            transition: opacity 0.2s;
            color: #555;
        }

        .studied-check.checked::before {
            content: '✓';
            opacity: 1;
        }

        .studied-check.checked {
            background: #ffffff !important;
            border: calc(2px * var(--card-scale)) solid #6b7d94 !important;
            opacity: 1;
            box-shadow: none !important;
        }

        .flashcard:not(.reverse-mode).flipped:hover .studied-check,
        .flashcard.reverse-mode:not(.flipped):hover .studied-check {
            opacity: 0;
        }

        .studied-check:hover {
            opacity: 1 !important;
            background: #ffffff !important;
            border: calc(2px * var(--card-scale)) solid #6b7d94 !important;
            transform: scale(1.1);
            box-shadow: none !important;
        }

        body.dark-mode .studied-check::before {
            color: #333;
        }

        body.dark-mode .studied-check:hover {
            border: calc(2px * var(--card-scale)) solid #8f97a2 !important;
        }

        .mastered-crown {
            position: absolute;
            bottom: calc(10px * var(--card-scale));
            left: calc(10px * var(--card-scale));
            width: calc(32px * var(--card-scale));
            height: calc(32px * var(--card-scale));
            background: transparent;
            color: rgba(255, 255, 255, 0.4);
            border: calc(2px * var(--card-scale)) solid rgba(255, 255, 255, 0.4);
            border-radius: 50%;
            cursor: pointer;
            font-size: calc(1.2em * var(--card-scale));
            display: flex;
            align-items: center;
            justify-content: center;
            z-index: 10;
            opacity: 0.6;
            transition: all 0.3s;
        }

        .flashcard:not(.reverse-mode).flipped .mastered-crown,
        .flashcard.reverse-mode:not(.flipped) .mastered-crown {
            opacity: 0;
            pointer-events: none;
        }

        .mastered-crown.mastered {
            background: rgba(255, 193, 7, 0.2);
            border-color: #ffc107;
            color: #ffc107;
            opacity: 0.9;
        }

        .mastered-crown:hover {
            opacity: 1 !important;
            border-color: rgba(255, 255, 255, 0.8) !important;
            transform: scale(1.15);
        }

        .mastered-crown.mastered:hover {
            background: rgba(255, 193, 7, 0.3) !important;
            border-color: #ffc107 !important;
            transform: scale(1.15);
        }

        .flashcard.faded {
            opacity: 0.65;
        }

        .flashcard.faded:hover {
            opacity: 0.8;
        }

        .flashcard.flipping {
            pointer-events: none;
        }

        .stat {
            text-align: center;
            position: relative;
            cursor: help;
        }

        .stat-tooltip {
            position: absolute;
            bottom: 100%;
            left: 50%;
            transform: translateX(-50%);
            background: #333;
            color: white;
            padding: 8px 12px;
            border-radius: 6px;
            font-size: 0.85em;
            white-space: nowrap;
            opacity: 0;
            pointer-events: none;
            transition: opacity 0.3s;
            margin-bottom: 10px;
            z-index: 100;
        }

        .stat-tooltip::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            border: 5px solid transparent;
            border-top-color: #333;
        }

        .stat:hover .stat-tooltip {
            opacity: 1;
        }

        .empty-state {
            grid-column: 1 / -1;
            text-align: center;
            padding: 60px 20px;
            color: #999;
        }

        .empty-icon {
            font-size: 4em;
            margin-bottom: 20px;
            opacity: 0.3;
        }

        .speaker-btn {
            background: transparent;
            color: rgba(80, 80, 80, 0.7);
            border: none;
            border-radius: 50%;
            width: 32px;
            height: 32px;
            font-size: 1em;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s;
            margin: 0 8px;
            flex-shrink: 0;
            opacity: 0.7;
        }

        .speaker-btn:hover,
        .speaker-btn:active {
            background: var(--hover-bg-light);
            color: rgba(60, 60, 60, 0.9);
            border: 1px solid var(--hover-border);
            transform: scale(1.1);
            opacity: 1;
        }

        .speaker-btn:disabled {
            opacity: 0.3;
            cursor: default;
        }

        .speaker-btn:disabled:hover {
            background: transparent;
            border: none;
            transform: none;
        }

        body.dark-mode .speaker-btn {
            color: rgba(200, 200, 200, 0.6);
        }

        body.dark-mode .speaker-btn:hover,
        body.dark-mode .speaker-btn:active {
            background: rgba(150, 150, 150, 0.15);
            color: rgba(200, 200, 200, 0.9);
            border-color: rgba(150, 150, 150, 0.2);
        }

        @media (max-width: 1024px) {
            body {
                padding: 60px 20px 20px 20px;
            }

            .container {
                padding: 0;
            }

            .main-content {
                grid-template-columns: 1fr;
            }

            .main-content.sidebar-hidden,
            .main-content.settings-hidden,
            .main-content.sidebar-hidden.settings-hidden {
                grid-template-columns: 1fr;
            }

            /* Mobile: Move buttons much higher — the hamburger lives inside
               .header-left-icons now, so the group moves, not the button */
            .header-left-icons {
                top: -25px !important;
            }

            .header-right-icons {
                top: -25px !important;
            }

            /* Mobile: Sidebar becomes slide-out overlay */
            .sidebar {
                position: fixed;
                top: 0;
                left: 0;
                height: 100vh;
                width: 320px;
                max-width: 85vw;
                z-index: 10001;
                transform: translateX(-100%);
                border-radius: 0;
                margin: 0;
                overflow-y: auto;
                padding: 0;
            }

            .sidebar.open {
                transform: translateX(0);
            }

            .sidebar.hidden {
                display: block;
                transform: translateX(-100%);
            }

            /* Backdrop overlay */
            .menu-backdrop {
                position: fixed;
                top: 0;
                left: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.5);
                z-index: 10000;
                opacity: 0;
                pointer-events: none;
                transition: opacity 0.3s ease;
            }

            .menu-backdrop.active {
                opacity: 1;
                pointer-events: all;
            }

            /* Hide hamburger when mobile menu is open */
            .menu-toggle.hidden {
                opacity: 0;
                pointer-events: none;
            }

            /* Hide settings button when settings panel is open */
            .settings-toggle.hidden {
                opacity: 0;
                pointer-events: none;
            }

            /* Mobile: Settings panel becomes slide-out overlay from right */
            .settings-panel {
                position: fixed;
                top: 0;
                right: 0;
                height: 100vh;
                width: 320px;
                max-width: 85vw;
                z-index: 10001;
                transform: translateX(100%);
                border-radius: 0;
                margin: 0;
                overflow-y: auto;
                display: block !important; /* Override desktop hidden class */
                padding: 0;
            }

            .settings-panel.open {
                transform: translateX(0);
            }

            .settings-panel.hidden {
                display: block !important;
                transform: translateX(100%);
            }

            /* Settings backdrop overlay */
            .settings-backdrop {
                position: fixed;
                top: 0;
                left: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.5);
                z-index: 10000;
                opacity: 0;
                pointer-events: none;
                transition: opacity 0.3s ease;
            }

            .settings-backdrop.active {
                opacity: 1;
                pointer-events: all;
            }

            /* Sticky panel headers (mobile — override desktop styles) */
            .sidebar-header, .settings-header {
                display: flex;
                position: sticky;
                top: 0;
                z-index: 5;
                background: var(--sidebar-bg);
                align-items: center;
                height: 52px;
                padding: 0 6px;
                margin: 0;
                border-bottom: none;
                border-bottom: 1px solid var(--border-color);
                flex-shrink: 0;
            }

            .panel-header-title {
                flex: 1;
                text-align: center;
                font-size: 0.88em;
                font-weight: 700;
                letter-spacing: 0.08em;
                text-transform: uppercase;
                color: var(--sidebar-text);
                opacity: 0.7;
            }

            .panel-header-spacer {
                width: 40px;
                flex-shrink: 0;
            }

            /* Close buttons inside panel headers */
            .sidebar-close, .settings-close {
                display: flex;
                width: 40px;
                height: 40px;
                background: transparent;
                border: none;
                font-size: 1.5em;
                color: var(--sidebar-text);
                cursor: pointer;
                opacity: 0.5;
                align-items: center;
                justify-content: center;
                flex-shrink: 0;
                transition: opacity 0.2s;
            }

            .sidebar-close:hover, .settings-close:hover {
                opacity: 1;
            }

            /* Inner content padding for both panels */
            .sidebar-inner, .settings-inner {
                padding: 16px;
            }

            /* Ensure sidebar content scrolls on mobile */
            .sidebar {
                overflow-y: auto;
                overflow-x: hidden;
            }
        }

        @media (max-width: 768px) {
            .stats-bar {
                flex-direction: row;
                padding: 10px 12px;
                gap: 0;
                /* stays 0 — the practice drawer is joined to the counter's bottom edge
                   and carries the gap below itself */
                margin-bottom: 0;
            }

            .stat-value {
                font-size: 1.3em;
            }

            .stat-label {
                font-size: 0.72em;
                margin-top: 2px;
            }

            /* Tooltips on mobile — wrap text, stay on screen */
            .stat-tooltip {
                white-space: normal;
                max-width: 110px;
                text-align: center;
                font-size: 0.78em;
            }

            /* First stat (Total Cards) — anchor to left so tooltip doesn't go off left edge */
            .stat:first-child .stat-tooltip {
                left: 0;
                transform: none;
            }
            .stat:first-child .stat-tooltip::after {
                left: calc(50% - 10px);
                transform: none;
            }

            /* Last stat (Mastered) — anchor to right so tooltip doesn't go off right edge */
            .stat:last-child .stat-tooltip {
                left: auto;
                right: 0;
                transform: none;
            }
            .stat:last-child .stat-tooltip::after {
                left: auto;
                right: calc(50% - 10px);
                transform: none;
            }
        }

        /* ── Mobile card sizing ── */
        @media (max-width: 1024px) {
            /* Cards never overflow the screen — capped to viewport width */
            .flashcard-grid,
            .mastered-cards-grid {
                grid-template-columns: repeat(auto-fill, min(var(--card-width), calc(100vw - 40px)));
            }

            .flashcard {
                width: min(var(--card-width), calc(100vw - 40px));
                min-height: calc(min(var(--card-width), calc(100vw - 40px)) * 0.5);
            }

            /* Landscape: cards stretch to fill the row — fixed-width tracks
               leave big side margins that read as spread out */
            @media (orientation: landscape) {
                .flashcard-grid,
                .mastered-cards-grid {
                    gap: 12px;
                    /* Min track is 85% of card size so one more column fits,
                       then the columns stretch back up to fill the row */
                    grid-template-columns: repeat(auto-fill, minmax(min(calc(var(--card-width) * 0.85), calc(100vw - 40px)), 1fr));
                }

                .flashcard {
                    width: 100%;
                }
            }

            /* Two-column mode: slider at minimum (200px) — portrait only, in
               landscape the normal auto-fill grid uses the full width */
            @media (orientation: portrait) {
                body.mobile-two-col .flashcard-grid,
                body.mobile-two-col .mastered-cards-grid {
                    grid-template-columns: repeat(2, 1fr);
                    gap: 10px;
                }

                body.mobile-two-col .flashcard {
                    width: min(100%, var(--card-width));
                }
            }
        }

        /* ---- Export Modal ---- */
        .export-modal-overlay {
            position: fixed;
            inset: 0;
            /* Above the word-browser sheet (10002/10003) — otherwise confirm/
               prompt modals opened from inside it (e.g. deleteFromCatalog's
               "are you sure") render fully hidden behind it: display:flex but
               invisible and unclickable, which looked like delete "not working"
               when really the dialog just couldn't be seen or reached. */
            z-index: 10500;
            background: rgba(0,0,0,0.55);
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .export-modal {
            background: var(--bg-gradient-start);
            color: #333;
        }
        /* DARK MODE RULE (Paul, 2026-07-09): modals do NOT use the theme
           gradient in dark mode — the theme picker writes those colors as
           INLINE styles that override dark-mode CSS, leaving dark text on a
           dark theme color. In dark mode every modal sits on the app's dark
           surface (--card-bg) with LIGHT text. White boxes/inputs inside keep
           their own #333 — they stay white by design. */
        body.dark-mode .export-modal {
            background: var(--card-bg);
            color: #e0e0e0;
        }
        .export-modal {
            border-radius: 15px;
            padding: 22px;
            width: 320px;
            max-width: 90vw;
            max-height: 80vh;
            overflow-y: auto;
            position: relative;
            border: 2px solid var(--accent-color);
        }
        /* A custom dropdown's option list is absolutely positioned but still
           counts toward this modal's own scroll-overflow calculation — without
           this, opening a dropdown near the bottom of a modal made the whole
           modal scroll too, on top of the dropdown's own internal scroll. */
        .export-modal:has(.custom-dropdown.select-open) {
            overflow: visible;
        }
        .export-modal h3 {
            color: var(--accent-color);
            margin-bottom: 14px;
            font-size: 1.15em;
            text-align: center;
            padding: 0 24px;
        }
        .export-modal-close {
            position: absolute;
            top: 12px;
            right: 15px;
            background: white;
            border: none;
            font-size: 1.6em;
            cursor: pointer;
            color: #333;
            opacity: 0.7;
            line-height: 1;
            border: 1.5px solid rgba(0,0,0,0.12);
            border-radius: 50%;
            width: 28px;
            height: 28px;
            padding: 0;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .export-modal-close:hover { opacity: 1; }

        /* ---- Edit Card Modal ---- */
        .edit-card-modal {
            width: 320px;
            padding: 20px;
        }
        .edit-card-modal h3 {
            margin-bottom: 12px;
        }
        .edit-field-group {
            margin-bottom: 9px;
        }
        .edit-label {
            display: block;
            font-size: 0.78em;
            font-weight: 700;
            letter-spacing: 0.06em;
            text-transform: uppercase;
            color: var(--accent-color);
            margin-bottom: 4px;
            opacity: 0.8;
        }
        .edit-input {
            width: 100%;
            padding: 9px 12px;
            border: 1.5px solid rgba(102,126,234,0.3);
            border-radius: 8px;
            font-size: 1em;
            font-family: inherit;
            background: white;
            color: #333;
            transition: border-color 0.2s;
            box-sizing: border-box;
        }
        textarea.edit-input {
            resize: vertical;
            min-height: 44px;
        }
        .edit-input:focus {
            outline: none;
            border-color: var(--accent-color);
        }
        .edit-actions {
            display: flex;
            gap: 10px;
            margin-top: 12px;
        }
        .edit-save-btn {
            flex: 1;
            padding: 11px;
            border-radius: 9px;
            border: none;
            background: var(--accent-color);
            color: white;
            font-weight: 700;
            font-size: 0.95em;
            cursor: pointer;
            transition: opacity 0.2s;
        }
        .edit-save-btn:hover { opacity: 0.85; }
        .edit-cancel-btn {
            flex: 1;
            padding: 11px;
            border-radius: 9px;
            border: 1.5px solid rgba(102,126,234,0.25);
            background: var(--card-bg);
            color: var(--card-text);
            font-weight: 600;
            font-size: 0.95em;
            cursor: pointer;
            transition: opacity 0.2s;
        }
        .edit-cancel-btn:hover { opacity: 0.7; }

        .export-option-btn {
            width: 100%;
            min-height: 72px;
            padding: 13px 16px;
            margin-bottom: 10px;
            border-radius: 10px;
            background: var(--accent-color);
            color: white;
            border: 1.5px solid var(--accent-color);
            background: white;
            color: #333;
            font-size: 0.92em;
            font-weight: 600;
            cursor: pointer;
            text-align: center;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            transition: background 0.15s, border-color 0.15s, color 0.15s;
        }
        .export-option-btn:hover {
            background: var(--accent-color);
            color: white;
        }
        .export-option-btn small {
            display: block;
            font-weight: normal;
            color: rgba(51,51,51,0.65);
            font-size: 0.82em;
            margin-top: 3px;
        }
        .export-option-btn:hover small {
            color: rgba(255,255,255,0.8);
        }
        .export-option-btn:hover { opacity: 0.88; }
        .export-option-btn.primary-opt {
            background: var(--accent-color);
            color: white;
            border-color: var(--accent-color);
        }
        .export-option-btn.primary-opt small { color: rgba(255,255,255,0.8); }
        .export-back-btn {
            background: white;
            border: 1.5px solid #ddd;
            border-radius: 8px;
            padding: 8px 14px;
            font-size: 0.88em;
            cursor: pointer;
            color: #333;
        }
        .export-back-btn:hover { border-color: #aaa; }
        .export-confirm-btn {
            background: var(--accent-color);
            border: none;
            border-radius: 8px;
            padding: 8px 18px;
            font-size: 0.88em;
            font-weight: 600;
            cursor: pointer;
            color: white;
            flex: 1;
        }
        .export-confirm-btn:hover { background: var(--accent-color-hover); }
        .export-confirm-btn.danger { background: #e74c3c; }
        .export-confirm-btn.danger:hover { background: #c0392b; }
        .export-white-box {
            background: white;
            border-radius: 10px;
            padding: 14px 16px;
            color: #333;
            margin-bottom: 14px;
        }
        .export-white-box p { color: #444; font-size: 0.88em; line-height: 1.55; }
        .export-check-row {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 7px 0;
            border-bottom: 1px solid #f0f0f0;
            color: #333;
            font-size: 0.9em;
        }
        .export-check-row:last-child { border-bottom: none; }
        .export-check-row input[type="checkbox"] {
            width: 18px;
            height: 18px;
            cursor: pointer;
            accent-color: var(--accent-color);
            flex-shrink: 0;
        }
        .export-cat-box {
            background: white;
            border-radius: 10px;
            padding: 10px 14px;
            margin-bottom: 14px;
            max-height: 200px;
            overflow-y: auto;
            color: #333;
        }
        .export-cat-box .cat-check-item { color: #333; }

        /* ---- Delete from catalog button ---- */
        .delete-catalog-btn {
            background: none;
            border: none;
            cursor: pointer;
            font-size: 0.82em;
            opacity: 0.35;
            padding: 2px 4px;
            border-radius: 4px;
            color: var(--card-text);
            flex-shrink: 0;
            transition: opacity 0.15s, color 0.15s;
        }
        .delete-catalog-btn:hover { opacity: 1; color: rgba(200,80,80,0.9); }
        .delete-catalog-btn.holding {
            animation: cat-trash-hold 0.6s linear forwards;
            cursor: wait;
        }
        @keyframes cat-trash-hold {
            0%   { background: transparent; opacity: 0.35; }
            100% { background: rgba(231,76,60,0.25); opacity: 1; color: rgba(200,80,80,0.9); }
        }

        /* Delete button in category checklist — more visible than word-browser trash */
        .cat-delete-btn {
            background: none;
            border: none;
            cursor: pointer;
            font-size: 1em;
            opacity: 0.55;
            padding: 3px 6px;
            border-radius: 4px;
            color: #222;
            flex-shrink: 0;
            transition: opacity 0.15s;
        }
        .cat-delete-btn:hover { opacity: 1; }
        body.dark-mode .cat-delete-btn { opacity: 0.65; color: #fff; }
        @media (min-width: 1025px) {
            .cat-delete-btn { font-size: 1.2em; opacity: 0.6; }
        }

        /* Small phone adjustments — iPhone SE 1st/2nd gen (320–375px) */
        @media (max-width: 375px) {
            body {
                padding: 20px 12px;
            }
            .header {
                margin-bottom: 40px;
            }
            .header h1 {
                font-size: 1.15em;
                letter-spacing: 0;
                padding: 0 90px;
            }
        }
        .pr-acts { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
        .pr-btn { font-size: 0.8em; padding: 6px 14px; }
        .pr-btn-primary {
            background: var(--accent-color);
            border-color: var(--accent-color);
            color: #fff;
        }
        /* This is a QUESTION the user has to read and answer — not a footnote. It was wearing
           .sb-note's footnote styling (0.6 opacity, 0.8em, a top rule) which faded it to
           nearly unreadable (Paul, 2026-07-14).
           ⚠️ It renders on the WRITING SURFACE (.pw-tiles) and on the saved rows, and BOTH of
           those stay WHITE in dark mode — same as the cards. So this text is DARK in both
           themes. Do NOT add a body.dark-mode rule lightening it: that paints white on white,
           which is exactly the bug this replaced. Check the surface, not the theme. */
        .pr-del-q {
            margin: 2px 0 4px;
            font-weight: 600;
            opacity: 1;
            font-size: 0.92em;
            color: #2c3e50;
            border-top: none;
            padding-top: 0;
        }

        /* A joined piece keeps its tile's colour inside the finished word — maayo[ng] — so
           the construction stays visible after the join (Paul, 2026-07-14). The colour is
           set inline from the tile; it is always either a user-picked tile colour or the
           accent, both of which read in light AND dark mode. Bolding carries the highlight
           even where the colour is close to the body text. */
        .pw-seg-affix { font-weight: 800; }
        .pr-dot {
            display: inline-block;
            width: 7px; height: 7px;
            border-radius: 50%;
            margin-right: 6px;
            vertical-align: middle;
            flex: none;
        }
        .pr-dot-word { background: #27ae60; }
        .pr-dot-phrase { background: #d9a521; }
        .pr-dot-sentence { background: #3577d4; }
        /* Card level dot — centered in each face's header, under the language
           name and above the separator line. Living inside the flipper faces
           means it flips and fades with the card like every other face element. */
        .card-header-dot {
            opacity: 0.6;
            margin: 0;
            pointer-events: none;
        }

        .card-content::-webkit-scrollbar { display: none; }

        /* ============================================
           STORY ONBOARDING (MyWikaStoryOnboarding)
           First-launch popup carousel over a dimmed
           backdrop. Modal is card-bg in both themes —
           never the gradient.
           ============================================ */
        .story-onboarding {
            position: fixed;
            inset: 0;
            z-index: 30000; /* above everything — app tops out at 20000 */
            background: rgba(0, 0, 0, 0.55);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 16px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }
        .story-onboarding.visible { opacity: 1; }

        .story-modal {
            position: relative;
            width: min(92vw, 480px);
            height: min(80vh, 600px);
            background: var(--card-bg);
            color: var(--card-text);
            border-radius: 18px;
            box-shadow: 0 12px 40px var(--shadow);
            overflow: hidden;
            transform: scale(0.96);
            transition: transform 0.3s ease;
        }
        .story-onboarding.visible .story-modal { transform: scale(1); }

        .story-close {
            position: absolute;
            top: 10px;
            right: 10px;
            z-index: 2;
            width: 34px;
            height: 34px;
            border: none;
            border-radius: 50%;
            background: transparent;
            color: var(--card-text);
            font-size: 1.5em;
            line-height: 1;
            opacity: 0.6;
            cursor: pointer;
            transition: opacity 0.2s ease, background 0.2s ease;
        }
        .story-close:hover {
            opacity: 1;
            background: var(--hover-bg-medium);
        }

        .story-track {
            display: flex;
            height: 100%;
            will-change: transform;
            touch-action: pan-y;
        }

        .story-slide {
            flex: 0 0 100%;
            min-width: 0;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            text-align: center;
            padding: clamp(20px, 6vw, 40px);
            padding-bottom: clamp(60px, 10vh, 80px); /* keep clear of the dots */
            user-select: none;
            -webkit-user-select: none;
            /* tiny/landscape screens: scroll instead of clipping
               ("safe" keeps the top reachable when content overflows) */
            justify-content: safe center;
            overflow-y: auto;
        }

        .story-illustration {
            width: clamp(100px, 22vmin, 160px);
            height: clamp(100px, 22vmin, 160px);
            min-height: 70px; /* may flex-shrink on short screens, but never vanish */
            object-fit: contain;
            margin-bottom: clamp(14px, 3vh, 26px);
            pointer-events: none;
        }
        .story-illustration-placeholder {
            border: 2px dashed var(--border-color);
            border-radius: 16px;
        }

        .story-header {
            font-size: clamp(1.25em, 4.5vw, 1.6em);
            font-weight: 700;
            margin-bottom: clamp(8px, 1.6vh, 14px);
        }

        .story-body {
            font-size: clamp(0.95em, 3vw, 1.08em);
            line-height: 1.6;
            max-width: 400px;
            opacity: 0.92;
        }

        .story-cta {
            margin-top: clamp(18px, 3vh, 28px);
            padding: 13px 30px;
            border: none;
            border-radius: 10px;
            background: var(--accent-color);
            color: white;
            font-size: 0.95em;
            font-weight: 600;
            cursor: pointer;
            transition: background 0.2s ease;
        }
        .story-cta:hover { background: var(--accent-color-hover); }

        .story-dots {
            position: absolute;
            bottom: clamp(18px, 3.5vh, 28px);
            left: 0;
            right: 0;
            display: flex;
            justify-content: center;
            gap: 10px;
        }
        .story-dot {
            width: 9px;
            height: 9px;
            border-radius: 50%;
            border: none;
            padding: 0;
            background: var(--border-color);
            cursor: pointer;
            transition: background 0.25s ease, transform 0.25s ease;
        }
        .story-dot.active {
            background: var(--accent-color);
            transform: scale(1.25);
        }

        /* Desktop prev/next arrows — hidden on touch-only devices,
           where swiping is the natural gesture */
        .story-arrow {
            display: none;
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            z-index: 2;
            width: 38px;
            height: 38px;
            border: none;
            border-radius: 50%;
            background: transparent;
            color: var(--card-text);
            font-size: 1.7em;
            line-height: 1;
            padding: 0 0 4px;
            opacity: 0.6;
            cursor: pointer;
            transition: opacity 0.2s ease, background 0.2s ease;
        }
        .story-arrow-prev { left: 8px; }
        .story-arrow-next { right: 8px; }
        .story-arrow:hover {
            opacity: 1;
            background: var(--hover-bg-medium);
        }
        .story-arrow.hidden { visibility: hidden; }
        @media (hover: hover) and (pointer: fine) {
            .story-arrow { display: block; }
        }

        /* Header logo re-opens the story */
        .logo-tap { cursor: pointer; }

        /* ============================================
           PRACTICE — WRITE-FIRST (rework 2026-07-10)
           Writing areas + language pair selects. Inputs
           get an explicit dark-mode surface — never rely
           on inherited card-bg alone.
           ============================================ */
        /* Each writing block: a small header (label + inline language select)
           above its textarea — deliberately NOT a src→dst translator row */
        .pw-block { margin-top: 12px; }
        .pw-block:first-of-type { margin-top: 0; }
        .pw-block-head {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-bottom: 8px;
        }
        .pw-inline-sel {
            width: auto;
            max-width: 180px;
        }
        .pw-area {
            width: 100%;
            padding: 12px 14px;
            border: 1.5px solid var(--border-color);
            border-radius: 12px;
            background: var(--card-bg);
            color: var(--card-text);
            font-size: 1em;
            line-height: 1.55;
            font-family: inherit;
            /* Both boxes start identical and AUTO-GROW with the text
               (pwAutoGrow) — no manual resize, no scrollbar inside */
            min-height: 100px;
            resize: none;
            overflow-y: hidden;
        }
        .pw-area:focus {
            outline: none;
            border-color: var(--accent-color);
        }
        .pw-area + .pw-area { margin-top: 10px; }
        .pw-area::placeholder { color: var(--card-text); opacity: 0.65; }
        .pw-speak {
            flex-shrink: 0;
            margin-left: auto;
        }
        /* Inputs stay WHITE in dark mode — same design rule as .tc-select
           and .edit-input */
        body.dark-mode .pw-area {
            background: white;
            color: #333;
            border-color: #d0d0d0;
        }
        /* The box stays white in dark mode, so the placeholder must stay
           dark too — inheriting --card-text (light) makes it invisible */
        body.dark-mode .pw-area::placeholder { color: #333; }

        /* Action buttons under the target sentence */
        /* Clear sits alone on the left; Verify + Save pair on the right (Paul, 2026-07-14).
           Clear is destructive and used to sit shoulder-to-shoulder with Save. */
        .pw-actions {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 8px;
            margin-top: 12px;
        }
        .pw-actions-main {
            display: flex;
            gap: 8px;
        }

        /* The Tiles toggle lives in the card's header now. That header is .sb-label — which
           is UPPERCASE at 0.72em and SHARED with the streak and breakdown panels — so the
           button has to opt out of the inherited casing, letter-spacing and opacity, and
           take an absolute font-size. Inheriting 0.8em of 0.72em rendered it microscopic. */
        .pw-head-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            gap: 12px;
        }
        .pw-head-row .pw-btn {
            text-transform: none;
            letter-spacing: normal;
            opacity: 1;
            font-size: 0.78rem;
            flex-shrink: 0;
        }
        /* Compact gray chips — quiet, no heavy borders (Paul: the big
           bordered buttons looked weird in the builder) */
        .pw-btn {
            padding: 7px 13px;
            border: none;
            border-radius: 8px;
            background: var(--hover-bg-light);
            color: var(--card-text);
            font-size: 0.8em;
            font-weight: 600;
            cursor: pointer;
            opacity: 0.85;
            transition: background 0.2s ease, color 0.2s ease, opacity 0.2s ease;
        }
        .pw-btn:hover {
            background: var(--hover-bg-medium);
            opacity: 1;
        }
        .pw-btn-primary {
            background: var(--accent-color);
            color: white;
            opacity: 1;
        }
        .pw-btn-primary:hover { background: var(--accent-color-hover); }
        /* Saved-sentence drag reorder — grip + lifted row */
        .pw-saved-handle {
            cursor: grab;
            touch-action: none;
            opacity: 0.35;
            flex-shrink: 0;
            padding: 2px;
            user-select: none;
            -webkit-user-select: none;
        }
        .pw-saved-row:hover .pw-saved-handle { opacity: 0.7; }
        /* While dragging: the clone follows the pointer, the original row
           stays as a dashed ghost placeholder (same look as tile drags) */
        .pw-row-clone {
            position: fixed; z-index: 9999; pointer-events: none; margin: 0;
            transform: scale(1.02);
            box-shadow: 0 10px 24px rgba(0, 0, 0, 0.25);
            background: var(--card-bg);
            transition: none;
            will-change: transform;
        }
        /* While ANY row is held, every row travels light — no + Deck / speaker
           buttons anywhere until the drop (Paul 2026-07-12) */
        .pw-row-clone .pw-saved-acts,
        #pwSaved.pw-dragging .pw-saved-acts { display: none; }
        .pw-saved-row.pw-lifted { opacity: 0.35; border-style: dashed; }

        /* Hold-to-clear feedback — fills red over the 600ms hold, same feel
           as the language-pill hold */
        .pw-clear-btn.holding {
            animation: pill-hold 0.6s linear forwards;
            cursor: wait;
        }
        /* Tiles toggle — reads as a switch: green outline on, red outline off */
        #pwSplitBtn.on, #pwSplitBtn.off { border: 1.5px solid transparent; opacity: 1; }
        #pwSplitBtn.on {
            border-color: #1e8449;
            color: #1e8449;
            background: rgba(46, 204, 113, 0.10);
        }
        #pwSplitBtn.off {
            border-color: #c0392b;
            color: #c0392b;
            background: rgba(231, 76, 60, 0.07);
        }
        body.dark-mode #pwSplitBtn.on { border-color: #2ecc71; color: #6ee7a0; }
        body.dark-mode #pwSplitBtn.off { border-color: #e74c3c; color: #f1948a; }

        .pw-verify-btn.on {
            background: rgba(46, 204, 113, 0.18);
            color: #1e8449;
            opacity: 1;
        }
        body.dark-mode .pw-verify-btn.on { color: #6ee7a0; }
        /* Verified sentence goes green */
        .pw-area.pw-verified {
            border-color: #2ecc71;
            background: #f0faf4;
        }
        body.dark-mode .pw-area.pw-verified {
            background: #eafaf1;
            color: #1e6b40;
        }

        /* Word tiles from the split — sb-tile look, living INSIDE the text-box
           frame (Paul 2026-07-12: keep the text box, put the tiles in it) */
        .pw-tiles {
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            align-content: flex-start;
            padding: 12px 14px;
            border: 1.5px solid var(--border-color);
            border-radius: 12px;
            background: var(--card-bg);
            min-height: 100px;   /* same starting size as the text boxes */
        }
        body.dark-mode .pw-tiles {
            background: white;   /* inputs stay white in dark mode — same rule as .pw-area */
            border-color: #d0d0d0;
        }
        /* Verified while in tile mode — same green frame the textarea gets
           (this class was set by pwApplyVerify but never styled until now) */
        .pw-tiles.pw-verified-tiles { border-color: #2ecc71; background: #f0faf4; }
        body.dark-mode .pw-tiles.pw-verified-tiles { background: #eafaf1; }
        .pw-tiles .sb-tile {
            cursor: pointer;
            /* phone-friendly tap target — a short affix like "ng" still
               gets a full-size tile to hit */
            min-width: 44px;
            min-height: 44px;
        }
        /* The tile box is white in dark mode, so the tiles go light too —
           dark tiles on a white field looked wrong (Paul 2026-07-12) */
        body.dark-mode .pw-tiles .sb-tile {
            background: #f4f4f7;
            border-color: #d4d6e0;
            color: #1c1c1e;
        }
        /* Joined pieces: each its own card tile, snapped at the dotted seam.
           Text pulls tight so the group reads as one word. */
        .pw-tile-group { display: inline-flex; }
        .pw-tile-group .pw-tile.linked-l { padding-right: 4px; }
        .pw-tile-group .pw-tile.linked-r {
            padding-left: 4px;
            /* the builder's -12px overlap clips the host word here —
               butt the tiles edge-to-edge instead, dotted seam between.
               The seam is THIS tile's own dotted left border (the overlap
               paints over the previous tile's edge, so it must live here) */
            margin-left: -2px;
            border-left: 2px dotted currentColor;
            animation: none;
        }
        /* An affix tile stands out — its own color, or accent by default */
        .pw-affix-tile {
            color: var(--accent-color);
            font-weight: 800;
        }
        .pw-seg-flipped {
            opacity: 0.85;
            font-style: italic;
        }
        .pw-modal-hint {
            font-size: 0.75em;
            opacity: 0.65;
            line-height: 1.5;
            margin-top: 6px;
        }

        /* Saved sentences list — tap to reload, hold to remove */
        .pw-saved-row {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 12px;
            margin-top: 8px;
            border: 1.5px solid var(--border-color);
            border-radius: 10px;
            cursor: pointer;
            user-select: none;
            -webkit-user-select: none;
            transition: background 0.2s ease;
        }
        .pw-saved-row:hover { background: var(--hover-bg-light); }
        /* Dark mode: saved rows read as faded-white cards with black text
           (Paul 2026-07-12) — same idea as the always-white flashcards */
        body.dark-mode .pw-saved-row {
            background: rgba(255, 255, 255, 0.82);
            border-color: rgba(255, 255, 255, 0.25);
            color: #1c1c1e;
        }
        body.dark-mode .pw-saved-row:hover { background: rgba(255, 255, 255, 0.92); }
        .pw-saved-check {
            color: #1e8449;   /* dark green — readable on the light rows in both themes */
            font-weight: 800;
            flex-shrink: 0;
        }
        .pw-saved-texts { min-width: 0; }
        /* Full sentence always readable — wrap, never truncate (Paul 2026-07-12) */
        .pw-saved-dst {
            font-weight: 600;
            white-space: normal;
            overflow-wrap: break-word;
        }
        .pw-saved-dst.verified { color: #1e8449; }
        /* rows are faded-white in dark mode too, so the DARK green stays readable */
        body.dark-mode .pw-saved-dst.verified { color: #1e8449; }
        body.dark-mode .pw-saved-row .speaker-btn { color: #3a3a3c; }
        .pw-saved-src {
            font-size: 0.8em;
            opacity: 0.6;
            white-space: normal;
            overflow-wrap: break-word;
        }
        .pw-saved-acts {
            display: flex;
            align-items: center;
            gap: 6px;
            margin-left: auto;
            flex-shrink: 0;
        }
        .pw-to-deck {
            border: 1.5px solid var(--accent-color);
            border-radius: 8px;
            background: var(--card-bg);
            color: var(--accent-color);
            font-size: 0.8em;
            font-weight: 700;
            padding: 5px 10px;
            cursor: pointer;
            white-space: nowrap;
            transition: background 0.2s ease, color 0.2s ease;
        }
        .pw-to-deck:hover {
            background: var(--accent-color);
            color: white;
        }

        /* Tile edit popup — card-bg surface + light text in dark mode,
           white inputs (edit-input) */
        .pw-modal-overlay {
            position: fixed;
            inset: 0;
            z-index: 30000;
            background: rgba(0, 0, 0, 0.55);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 16px;
        }
        .pw-modal {
            width: min(92vw, 360px);
            background: var(--card-bg);
            color: var(--card-text);
            border-radius: 16px;
            box-shadow: 0 12px 40px var(--shadow);
            padding: 20px;
        }
        .pw-modal-title {
            font-weight: 700;
            font-size: 1.05em;
            margin-bottom: 12px;
        }
        .pw-modal-label {
            display: block;
            font-size: 0.8em;
            opacity: 0.7;
            margin: 10px 0 4px;
        }
        .pw-modal .edit-input { width: 100%; box-sizing: border-box; }
        .pw-colors {
            display: flex;
            gap: 8px;
            margin-top: 4px;
        }
        .pw-swatch {
            width: 26px;
            height: 26px;
            border-radius: 50%;
            border: 2px solid var(--border-color);
            background: var(--card-bg);
            cursor: pointer;
            padding: 0;
        }
        .pw-swatch.on {
            border-color: var(--accent-color);
            transform: scale(1.15);
        }
        .pw-modal-btns {
            display: flex;
            justify-content: flex-end;
            gap: 10px;
            margin-top: 18px;
        }

        /* ============================================
           STREAK POPUP — centered, theme-color calendar.
           Dark mode = card-bg surface + light text.
           ============================================ */
        .streak-overlay {
            position: fixed;
            inset: 0;
            z-index: 30000;
            background: rgba(0, 0, 0, 0.55);
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 16px;
            overflow: hidden;
        }
        .streak-modal {
            position: relative;
            /* Narrow ("smaller and longer") card. min-height keeps every view the
               SAME size (Paul didn't want them resizing per tab); height:auto lets
               it grow past that only if a view's content needs it, so nothing ever
               clips inside (iOS renders text taller than desktop). sizeStreakPopup()
               measures the real rendered size and uniformly scales the WHOLE card
               (transform) to fit the VISIBLE viewport (visualViewport — accurate on
               installed iOS, unlike innerHeight which overreports). Fits any phone,
               proportional (never skinny), never clips/scrolls. (Paul, 2026-07-16) */
            width: 330px;
            min-height: 660px;
            height: auto;
            transform-origin: center center;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            background: var(--card-bg);
            color: var(--card-text);
            border-radius: 18px;
            box-shadow: 0 12px 40px var(--shadow);
            padding: 22px;
        }
        .streak-cal {
            flex: 1;
            min-height: 0;
            overflow-y: auto;
            align-content: start;
        }
        /* ===== Personal goals (2026-07-13) — the panel lives in the streak popup,
           not in Settings: the goal belongs next to the flame, and one home means
           no second copy to drift out of sync. ===== */
        /* ===== Crown rank popup — Got it / Almost / Not yet ===== */
        .rank-modal {
            width: min(90vw, 340px);
            padding: 24px 20px 18px;
            border-radius: 18px;
            background: var(--card-bg);
            box-shadow: 0 18px 50px rgba(0,0,0,0.35);
            text-align: center;
        }
        .rank-q { font-size: 0.82em; opacity: 0.55; color: var(--card-text); }
        .rank-word {
            font-size: 1.35em;
            font-weight: 700;
            color: var(--card-text);
            margin: 2px 0 18px;
            word-break: break-word;
        }
        .rank-btn {
            width: 100%;
            display: flex;
            flex-direction: column;
            gap: 2px;
            padding: 11px 14px;
            margin-bottom: 8px;
            border-radius: 12px;
            border: 1.5px solid var(--border-color);
            background: transparent;
            color: var(--card-text);
            cursor: pointer;
            text-align: left;
            transition: background 0.15s, border-color 0.15s;
        }
        .rank-btn-main { font-size: 0.95em; font-weight: 700; }
        .rank-btn-sub { font-size: 0.74em; opacity: 0.55; }
        .rank-got:hover    { border-color: #2ecc71; background: rgba(46,204,113,0.10); }
        .rank-almost:hover { border-color: var(--accent-color); background: var(--hover-bg-light); }
        .rank-notyet:hover { border-color: #e67e22; background: rgba(230,126,34,0.10); }
        .rank-cancel {
            width: 100%;
            padding: 9px;
            margin-top: 2px;
            border: none;
            background: transparent;
            color: var(--card-text);
            opacity: 0.5;
            font-size: 0.85em;
            font-weight: 600;
            cursor: pointer;
        }
        body.dark-mode .rank-btn {
            background: rgba(255,255,255,0.06);
            border-color: rgba(255,255,255,0.18);
            color: #e8e8ef;
        }
        body.dark-mode .rank-got:hover    { border-color: #2ecc71; background: rgba(46,204,113,0.18); }
        body.dark-mode .rank-notyet:hover { border-color: #e67e22; background: rgba(230,126,34,0.18); }
        body.dark-mode .rank-cancel { color: #e0e0e0; }

        .streak-gear {
            position: absolute;
            top: 10px;
            left: 10px;
            width: 38px;
            height: 38px;
            border: none;
            border-radius: 50%;
            background: transparent;
            color: var(--card-text);
            font-size: 1.15em;
            opacity: 0.45;
            cursor: pointer;
            z-index: 2;
            transition: opacity 0.15s, transform 0.2s;
        }
        .streak-gear:hover { opacity: 0.9; }
        .streak-gear.on { opacity: 1; transform: rotate(60deg); color: var(--accent-color); }

        #streakSettings { padding: 46px 22px 22px; overflow-y: auto; }
        .streak-set-title {
            font-size: 1.15em;
            font-weight: 700;
            color: var(--card-text);
            margin-bottom: 6px;
            text-align: center;
        }
        .streak-set-lead {
            font-size: 0.8em;
            line-height: 1.45;
            color: var(--card-text);
            opacity: 0.6;
            text-align: center;
            margin-bottom: 18px;
        }
        .streak-set-label {
            display: block;
            font-size: 0.72em;
            font-weight: 700;
            letter-spacing: 0.05em;
            text-transform: uppercase;
            opacity: 0.55;
            color: var(--card-text);
            margin: 14px 0 6px;
        }
        .streak-set-hint {
            font-size: 0.76em;
            line-height: 1.4;
            opacity: 0.5;
            color: var(--card-text);
            margin-top: 6px;
        }
        .streak-target-row { display: flex; align-items: center; gap: 8px; justify-content: center; }
        .streak-step {
            flex: 0 0 auto;
            width: 36px;
            height: 36px;
            border-radius: 9px;
            border: 1px solid var(--border-color);
            background: var(--card-bg);
            color: var(--card-text);
            font-size: 1.15em;
            font-weight: 700;
            cursor: pointer;
        }
        .streak-step:hover { border-color: var(--accent-color); color: var(--accent-color); }
        .streak-target-input { width: 84px; text-align: center; margin: 0; }
        .streak-target-unit {
            font-size: 0.8em;
            opacity: 0.6;
            color: var(--card-text);
            text-align: center;
            margin-top: 7px;
        }
        .streak-quick { display: flex; gap: 6px; margin-top: 11px; }
        .streak-quick-btn {
            flex: 1;
            padding: 7px 0;
            border-radius: 8px;
            border: 1px solid var(--border-color);
            background: transparent;
            color: var(--card-text);
            font-size: 0.82em;
            font-weight: 600;
            cursor: pointer;
        }
        .streak-quick-btn.on {
            border-color: var(--accent-color);
            color: var(--accent-color);
            background: var(--hover-bg-light);
        }
        /* In dark mode these sat on a transparent background with a dark border and
           read as near-black holes. Give them a lifted surface and a visible edge. */
        body.dark-mode .streak-quick-btn {
            background: rgba(255, 255, 255, 0.08);
            border-color: rgba(255, 255, 255, 0.20);
            color: #e8e8ef;
        }
        body.dark-mode .streak-quick-btn:hover {
            background: rgba(255, 255, 255, 0.14);
            border-color: var(--accent-color);
        }
        body.dark-mode .streak-quick-btn.on {
            background: rgba(102, 126, 234, 0.30);
            border-color: var(--accent-color);
            color: #fff;
        }
        /* The reassurance that makes changing the goal safe to do */
        .streak-set-note {
            margin-top: 18px;
            padding: 10px 12px;
            border-radius: 9px;
            background: var(--hover-bg-light);
            font-size: 0.76em;
            line-height: 1.45;
            opacity: 0.75;
            color: var(--card-text);
        }
        body.dark-mode .streak-set-note { background: rgba(255,255,255,0.06); color: #e0e0e0; }
        /* Same problem as the quick picks — rgba(255,255,255,0.05) on a dark panel is
           barely a surface at all, so the − / + read as dark holes. Lift them. */
        body.dark-mode .streak-step {
            background: rgba(255, 255, 255, 0.10);
            border-color: rgba(255, 255, 255, 0.22);
            color: #f0f0f5;
        }
        body.dark-mode .streak-step:hover {
            background: rgba(255, 255, 255, 0.18);
            border-color: var(--accent-color);
            color: var(--accent-color);
        }

        /* Progress toward today's goal, under the streak number */
        .streak-goalbar { padding: 0 22px; margin-bottom: 4px; }
        .streak-goalbar .sg-line {
            display: flex;
            justify-content: space-between;
            font-size: 0.74em;
            opacity: 0.65;
            color: var(--card-text);
            margin-bottom: 4px;
        }
        .streak-goalbar .sg-pct { font-weight: 700; }
        .streak-goalbar .sg-track {
            height: 5px;
            border-radius: 3px;
            background: var(--border-color);
            overflow: hidden;
        }
        .streak-goalbar .sg-fill {
            height: 100%;
            border-radius: 3px;
            background: var(--accent-color);
            transition: width 0.3s;
        }
        .streak-goalbar .sg-fill.done { background: #2ecc71; }
        .streak-goalbar .sg-sub {
            font-size: 0.7em;
            opacity: 0.5;
            color: var(--card-text);
            margin-top: 3px;
            text-align: right;
        }
        body.dark-mode .streak-goalbar .sg-sub { color: #e0e0e0; }
        .st-range-goal { padding: 0; margin-top: 12px; }
        body.dark-mode .streak-goalbar .sg-line { color: #e0e0e0; }
        body.dark-mode .streak-goalbar .sg-track { background: rgba(255,255,255,0.14); }

        .streak-close {
            position: absolute;
            top: 10px;
            right: 10px;
            width: 38px;
            height: 38px;
            border: none;
            border-radius: 50%;
            background: transparent;
            color: var(--card-text);
            font-size: 1.5em;
            line-height: 1;
            opacity: 0.6;
            cursor: pointer;
            /* must sit ABOVE the animated flame — its transform creates a
               stacking context that was swallowing taps on the X */
            z-index: 10;
        }
        .streak-close:hover { opacity: 1; background: var(--hover-bg-medium); }
        /* Big status icon on top — 🔥 today done · 💧 cooling · ❄️ dead */
        .streak-status {
            text-align: center;
            font-size: 3.2em;
            line-height: 1.1;
            margin: 2px auto 0;
            width: fit-content;   /* don't span the row — keeps the X reachable */
        }
        .streak-status.lit { animation: boltPulse 2.2s ease-in-out infinite; }
        @keyframes boltPulse {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.1); }
        }
        .streak-hero-num {
            text-align: center;
            font-size: 2.3em;
            font-weight: 800;
            color: var(--accent-color);
            line-height: 1.1;
        }
        .streak-hero-num.dead { color: var(--card-text); opacity: 0.4; }
        .streak-date {
            text-align: center;
            font-size: 0.88em;
            font-weight: 700;
            margin-top: 8px;
        }
        .streak-sub {
            display: flex;
            justify-content: center;
            gap: 14px;
            font-size: 0.85em;
            opacity: 0.7;
            margin: 3px 0 12px;
        }
        /* Small weekly streak strip — this week's days light up as you go */
        .streak-next {
            display: flex;
            justify-content: center;
            gap: 7px;
            margin: 10px 0 2px;
        }
        .st-mini-day {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 2px;
        }
        .st-mini-label {
            font-size: 0.68em;
            font-weight: 700;
            opacity: 0.5;
        }
        .st-mini-dot {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            border: 1.5px solid var(--border-color);
            display: grid;
            place-items: center;
            font-size: 0.95em;
            line-height: 1;
            text-align: center;
            box-sizing: border-box;
        }
        /* Water day = light faded blue · fire day = the full darker accent */
        .st-mini-day.st-tier-water .st-mini-dot {
            background: rgba(102, 126, 234, 0.22);
            background: color-mix(in srgb, var(--accent-color) 25%, transparent);
            border-color: transparent;
        }
        .st-mini-day.st-tier-fire .st-mini-dot {
            background: var(--accent-color);
            border-color: var(--accent-color);
        }
        .st-mini-day.now .st-mini-dot { outline: 2px solid var(--accent-color); outline-offset: 1px; }
        /* Same segmented look as the Cards | Practice mode tabs */
        .streak-tabs {
            display: flex;
            gap: 6px;
            padding: 5px;
            background: var(--hover-bg-light);
            border-radius: 14px;
            margin-bottom: 14px;
        }
        .streak-tab {
            flex: 1;
            min-width: 0;
            padding: 9px 12px;
            border: none;
            background: transparent;
            color: var(--card-text);
            opacity: 0.65;
            font-size: 0.88em;
            font-weight: 600;
            border-radius: 10px;
            cursor: pointer;
            transition: background 0.2s, color 0.2s, opacity 0.2s, box-shadow 0.2s;
        }
        .streak-tab.active {
            background: var(--card-bg);
            color: var(--accent-color);
            opacity: 1;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
        }
        .streak-cal-head {
            text-align: center;
            font-weight: 600;
            font-size: 0.9em;
            margin-bottom: 10px;
        }
        .st-month-nav {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 12px;
        }
        .st-nav-btn {
            width: 30px;
            height: 30px;
            border: none;
            border-radius: 50%;
            background: transparent;
            color: var(--card-text);
            font-size: 1.2em;
            cursor: pointer;
            opacity: 0.7;
        }
        .st-nav-btn:hover { background: var(--hover-bg-medium); opacity: 1; }
        .st-nav-btn:disabled { opacity: 0.25; cursor: default; }
        .st-month-label { min-width: 140px; text-align: center; }

        /* Month grid — width capped so 7 square rows fit the fixed frame
           with NO scrolling */
        .streak-cal-month {
            display: grid;
            grid-template-columns: repeat(7, 1fr);
            gap: 3px;
            /* Fill the card width (much fuller than the old 292px cap so it is
               never slim) but bound cell size so the square grid can't grow so
               tall it clips the card. 336px = ~48px cells, fits the fixed frame
               with the short-screen hero compaction. (Paul, 2026-07-15) */
            max-width: 336px;
            margin: 0 auto;
            width: 100%;
            padding: 5px;
        }
        .st-cell {
            position: relative;
            aspect-ratio: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 0.8em;
            border-radius: 50%;
            min-width: 0;
            text-align: center;
        }
        .st-cell-num {
            width: 100%;
            text-align: center;
            line-height: 1;
        }
        /* Spillover days from the neighboring month — visible but faded */
        .st-cell.st-other { opacity: 0.35; }
        /* Bridged rest day — the 48h grace, streak-freeze style */
        .st-flake {
            position: absolute;
            top: -2px;
            right: 0;
            font-size: 0.7em;
            color: #5dade2;
            z-index: 1;
        }
        .st-rest .st-cell-num { opacity: 0.6; }

        /* Perfect week — 7/7 days collapse into one continuous bar */
        .streak-cal-week.st-week-perfect { gap: 0; }
        .st-week-perfect .st-week-cell {
            border-radius: 0;
            border-left-width: 0;
            background: var(--accent-color);
        }
        .st-week-perfect .st-week-cell:first-child {
            border-radius: 10px 0 0 10px;
            border-left-width: 1.5px;
        }
        .st-week-perfect .st-week-cell:last-child { border-radius: 0 10px 10px 0; }
        .st-week-perfect .st-week-cell .st-week-name,
        .st-week-perfect .st-week-cell .st-week-date,
        .st-week-perfect .st-week-cell .st-week-count { color: white; }
        .st-wd { opacity: 0.5; font-weight: 700; aspect-ratio: auto; padding: 4px 0; }
        .st-dot {
            position: absolute;
            inset: 3px;
            border-radius: 50%;
            background: var(--accent-color);
            opacity: 0;
        }
        .st-cell-num { position: relative; z-index: 1; pointer-events: none; }
        .st-l1 .st-dot { opacity: 0.22; }
        .st-l2 .st-dot { opacity: 0.5; }
        .st-l3 .st-dot { opacity: 1; }
        .st-l3 .st-cell-num, .st-l2 .st-cell-num { color: white; font-weight: 700; }
        .st-l1 .st-cell-num { font-weight: 700; }
        /* Today = solid filled circle (Google-style) with a white inner ring so
           it reads as TODAY even next to a high-performance day (which is also
           an accent fill). Number always white. Inner ring = no overflow. */
        .st-cell.st-today {
            background: var(--accent-color);
            box-shadow: inset 0 0 0 2px rgba(255, 255, 255, 0.85);
        }
        .st-cell.st-today .st-cell-num { color: #fff; font-weight: 700; }
        .st-daycell { cursor: pointer; user-select: none; -webkit-user-select: none; }
        .st-week-cell { cursor: pointer; user-select: none; -webkit-user-select: none; }
        /* Tapped day — a detached ring in a contrasting shade so it reads as
           clearly different from today's filled circle, stays visible over any
           performance fill, and works in light AND dark mode. The inner gap
           (card-bg) separates the ring from the fill; the ring itself uses
           card-text so it flips dark-on-light / light-on-dark. */
        .st-cell.st-selected {
            box-shadow: 0 0 0 2px var(--card-bg), 0 0 0 3.5px var(--card-text);
            font-weight: 800;
        }
        .st-week-cell.st-selected { border-color: var(--accent-color); border-width: 2.5px; }

        /* Week row */
        .streak-cal-week {
            display: grid;
            grid-template-columns: repeat(7, 1fr);
            gap: 4px;
        }
        .st-week-cell {
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 3px;
            padding: 8px 0;
            border: 1.5px solid var(--border-color);
            border-radius: 10px;
            font-size: 0.75em;
        }
        .st-week-cell.st-today { border-color: var(--accent-color); }
        .st-week-name { opacity: 0.6; }
        .st-week-date { font-weight: 700; }
        .st-week-count { color: var(--accent-color); font-weight: 800; }
        .st-week-cell.st-l1 { background: rgba(128, 128, 160, 0.08); }
        .st-week-cell.st-l2 { background: rgba(128, 128, 160, 0.16); }
        .st-week-cell.st-l3 { background: var(--accent-color); }
        .st-week-cell.st-l3 .st-week-count,
        .st-week-cell.st-l3 .st-week-name,
        .st-week-cell.st-l3 .st-week-date { color: white; }

        /* Week summary fills the fixed frame under the 7-day row */
        .streak-cal-week { grid-template-rows: min-content; }
        .st-week-summary { grid-column: 1 / -1; }
        .st-week-summary .st-day-row {
            padding: 4px 14px;
            margin-bottom: 4px;
        }
        .st-week-summary .st-day-num { font-size: 1.15em; }
        .st-week-summary .sb-label { margin-top: 8px !important; margin-bottom: 5px; }
        .streak-cal-week .st-week-cell { padding: 6px 0; }
        .st-best-day {
            text-align: center;
            font-size: 0.82em;
            font-weight: 700;
            color: var(--accent-color);
            margin-top: 14px;   /* more gap above the Best day line (Paul, 2026-07-15) */
        }

        /* Day detail */
        .st-day-row {
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 12px 14px;
            border: 1.5px solid var(--border-color);
            border-radius: 12px;
            margin-bottom: 8px;
        }
        .st-day-icon { font-size: 1.3em; }
        .st-day-num {
            font-size: 1.5em;
            font-weight: 800;
            color: var(--accent-color);
            min-width: 34px;
            text-align: center;
        }
        .st-day-label { opacity: 0.75; }
