/* Dokkai Reader — styles specific to reading.html.
   "Golden Page": a light, fully warm honey-gold reading surface — background
   and ink both living in the same warm gold family, distinct from Word
   Match's hanafuda dark theme, the portfolio page's own dark-ish mood, and
   the shared header's own dark masthead (--header-* tokens, untouched
   here). All of this page's color/shadow tokens are scoped to .reading-main
   — same token NAMES as style.css's shared :root (--accent, --bg-surface,
   etc.) but redefined locally, so every rule below that still reads
   var(--x) picks up this page's palette via normal CSS custom-property
   inheritance through the DOM, with no need to re-scope each selector
   under .reading-main. Typography/motion tokens (--font-display,
   --font-body, --ease-out, --ease-pop) are intentionally left shared.

   Because this was originally written as a DARK theme, going light meant
   more than swapping the token values: anywhere text sat on an
   accent-colored fill, dark-on-light legibility had to be re-checked
   (light-on-dark accent text like --accent-light is low-contrast against
   a pale accent-tint chip once the page itself is light, so hint chips /
   badges were flipped to --accent-dark), and .auth-btn's hardcoded white
   label (style.css, not editable here) needed a scoped override since it
   now sits on a light gold gradient instead of a dark one. */

/* .nav-current lives in style.css (shared header styling), along with the brand block that
   replaced the old .back-link and the sitewide .site-footer. */

/* ---------------------------------------------------------------------
   Page shell
   --------------------------------------------------------------------- */
/* body:has(.reading-main) gets the same token block as .reading-main itself (not a hardcoded
   background hex) so the full-bleed body color can't drift out of sync with the theme — body
   is an ancestor, and custom properties only cascade down the DOM, so body needs its own copy
   to reference via var(). Makes the theme full-bleed instead of a boxed dark column with the
   shared light :root --bg-page peeking through past .container's 1200px cap on wide viewports.
   :has() here only ever matches reading.html, since .reading-main only exists there. */
body:has(.reading-main),
.reading-main {
    --bg-page: #f7ecd2;
    --bg-surface: #fdf6e6;
    --bg-surface-alt: #f0e0bc;
    --border: #e0c690;
    --border-strong: #c9a563;
    --text-primary: #4a3510;
    --text-secondary: #7a6435;
    --text-muted: #a08a5c;
    --accent: #b8791f;
    --accent-light: #d99f3f;
    --accent-dark: #8f5c14;
    --accent-tint: rgba(184, 121, 31, 0.16);
    --accent-gradient: linear-gradient(135deg, var(--accent-light), var(--accent));
    --accent-gradient-hover: linear-gradient(135deg, var(--accent), var(--accent-dark));
    --shadow-sm: 0 2px 10px rgba(74, 53, 16, 0.10);
    --shadow-md: 0 14px 32px rgba(74, 53, 16, 0.18);
}

body:has(.reading-main) {
    background: var(--bg-page);
}

.reading-main {
    position: relative;
    isolation: isolate;
    background:
        radial-gradient(ellipse 70% 40% at 18% 0%, rgba(184, 121, 31, 0.10) 0%, transparent 60%),
        var(--bg-page);
    color: var(--text-primary);
    /* Top padding = the fixed masthead's rendered height + the ~25px of clearance the page
       has always had; the masthead is now one 64px row rather than two totalling 115px. */
    padding: 89px 40px 80px;
    min-height: 100vh;
}

/* .auth-btn (style.css, shared sitewide — not editable here) hardcodes a white label on
   var(--accent-gradient). That reads fine against the old dark theme's gradient but not
   against this page's light gold one, so the label color is overridden here, scoped to
   this page only via body:has(.reading-main). Dark ink reads better across the gradient's
   light-to-mid gold range than white does (which fails contrast at the gradient's lighter
   end); it isn't a perfect ratio at the gradient's darkest hover corner either, but it's
   the better tradeoff of the two, and it keeps the "ink on gold" theme consistent. */
body:has(.reading-main) .auth-btn,
body:has(.reading-main) .auth-btn-outline:hover {
    color: var(--text-primary);
}

.reading-title {
    font-family: var(--font-display);
    font-size: 2.4rem;
    font-weight: 700;
    margin: 0 0 12px;
}

.reading-subtitle {
    color: var(--text-secondary);
    max-width: 680px;
    line-height: 1.6;
    margin: 0 0 8px;
}

.reading-mic-hint {
    color: var(--accent-dark);
    background: var(--accent-tint);
    border: 1px solid var(--border);
    display: inline-block;
    padding: 8px 16px;
    font-size: 0.9rem;
    margin: 8px 0 8px;
}

.reading-guest-hint {
    color: var(--accent-dark);
    background: var(--accent-tint);
    border: 1px solid var(--border);
    display: inline-block;
    padding: 8px 16px;
    font-size: 0.9rem;
    margin: 0 0 30px;
}

.reading-section.hidden {
    display: none;
}

/* ---------------------------------------------------------------------
   Track select — a linear table-of-contents list, not a card grid
   (matches the .text-list pattern below: full-width rows, not boxes
   that wrap into a dashboard-like grid).
   --------------------------------------------------------------------- */
.track-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
    max-width: 700px;
}

.track-card {
    text-align: left;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    padding: 20px 24px;
    cursor: pointer;
    transition: all 0.2s ease;
    font-family: inherit;
    color: var(--text-primary);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    width: 100%;
}

.track-card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.track-card h3 {
    margin: 0;
    font-size: 1.2rem;
}

.track-meta {
    font-size: 0.9rem;
    color: var(--text-secondary);
    white-space: nowrap;
    flex: 0 0 auto;
}

/* ---------------------------------------------------------------------
   Level select — same linear list pattern as the track list above
   (was a wrapping card grid mirroring Word Match's level cards; now
   reads as a table of contents, one row per level).
   --------------------------------------------------------------------- */
.level-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
    max-width: 700px;
}

.level-card {
    text-align: left;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    padding: 16px 24px;
    cursor: pointer;
    transition: all 0.2s ease;
    font-family: inherit;
    color: var(--text-primary);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    width: 100%;
}

.level-card:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.level-card.locked {
    cursor: not-allowed;
    opacity: 0.55;
}

.level-card.locked:hover {
    border-color: var(--border);
    box-shadow: var(--shadow-sm);
    transform: none;
}

.level-lock-note {
    font-size: 0.8rem;
    color: var(--text-muted);
    font-style: italic;
    flex-basis: 100%;
}

.level-badge {
    display: inline-block;
    flex: 0 0 auto;
    background: var(--accent-tint);
    color: var(--accent-dark);
    font-weight: 700;
    font-size: 0.8rem;
    letter-spacing: 0.03em;
    padding: 4px 10px;
}

.level-card h3 {
    margin: 0;
    font-size: 1.1rem;
    flex: 0 0 auto;
}

.level-meta {
    font-size: 0.85rem;
    color: var(--text-secondary);
    margin-left: auto;
    white-space: nowrap;
    flex: 0 0 auto;
}

/* ---------------------------------------------------------------------
   Text list
   --------------------------------------------------------------------- */
.text-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
    max-width: 560px;
}

.text-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    text-align: left;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    padding: 16px 20px;
    cursor: pointer;
    font-family: inherit;
    font-size: 1rem;
    color: var(--text-primary);
    transition: all 0.2s ease;
}

.text-item:hover {
    border-color: var(--accent);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.text-item-check {
    color: var(--game-en-accent, #0e8a7d);
    font-weight: 700;
    margin-right: 8px;
}

.text-item .text-item-len {
    color: var(--text-muted);
    font-size: 0.85rem;
}

/* ---------------------------------------------------------------------
   Reader
   --------------------------------------------------------------------- */
.reader-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
    margin-bottom: 24px;
}

.reader-title {
    font-weight: 700;
    font-size: 1.1rem;
}

.reader-progress {
    margin-left: auto;
    font-size: 0.9rem;
    color: var(--text-secondary);
    font-weight: 600;
    background: var(--bg-surface-alt);
    padding: 6px 12px;
}

.ghost-btn {
    background: none;
    border: 1px solid var(--border);
    color: var(--text-primary);
    padding: 8px 16px;
    font-family: inherit;
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
    transition: all 0.2s ease;
}

.ghost-btn:hover {
    border-color: var(--accent);
    color: var(--accent-dark);
    background: var(--accent-tint);
}

.reader-body {
    display: flex;
    align-items: flex-start;
    gap: 20px;
    max-width: 940px;
    /* Room for the floating bottom control bar (~64px tall, 22px off the viewport
       edge) so it never overlaps the bottom of the passage or the skipped-words
       panel, even when either has scrolled fully into view. */
    margin-bottom: 110px;
}

.reader-passage-wrap {
    position: relative;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    padding: 40px;
    flex: 1 1 auto;
    min-width: 0;
}

.skipped-panel {
    flex: 0 0 220px;
    background: var(--bg-surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-sm);
    padding: 20px;
    max-height: 480px;
    overflow-y: auto;
}

.skipped-panel h3 {
    margin: 0 0 10px;
    font-size: 0.95rem;
    color: var(--text-primary);
}

.skipped-empty {
    margin: 0;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.5;
}

.skipped-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.skipped-list li {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    border-left: 2px solid var(--accent);
    padding: 2px 0 2px 10px;
}

/* Ordered so the row reads: surface, reading, [speakers pushed right], then the gloss on its
   own line underneath -- they belong with the word, not stranded under the gloss. */
.skipped-list .speak-group {
    order: 2;
    flex: 0 0 auto;
    margin-left: auto;
    display: flex;
    gap: 4px;
}

.skipped-word-surface {
    font-weight: 700;
    font-size: 1rem;
}

.skipped-word-reading {
    color: var(--text-muted);
    font-size: 0.8rem;
    margin-left: 6px;
}

.skipped-word-en {
    order: 3;
    flex-basis: 100%;
    color: var(--text-secondary);
    font-size: 0.82rem;
}

.reader-passage {
    margin: 0;
    font-size: 1.5rem;
    line-height: 2.4;
    letter-spacing: 0.02em;
}

.reader-word {
    padding: 2px 1px;
    border-radius: 2px;
    transition: background 0.25s ease, color 0.25s ease, box-shadow 0.25s ease, text-shadow 0.25s ease;
}

.reader-word.read {
    color: var(--text-muted);
}

/* Currently-spoken word: on the old near-black theme a soft layered glow read as a lit
   halo; against cream paper that same glow just looks washed out (light-colored text and
   a faint tinted halo both have too little contrast to read as "lit"). A solid
   highlighter-style fill with dark ink reads far more clearly on a light page — like a
   marker stroke on paper — with a crisp accent underline for definition instead of a blur. */
.reader-word.current {
    background: var(--accent-light);
    color: var(--text-primary);
    font-weight: 700;
    border-radius: 3px;
    box-shadow: inset 0 -3px 0 var(--accent-dark);
}

.hint-popup {
    position: absolute;
    top: 14px;
    left: 14px;
    pointer-events: none;
    background: var(--bg-surface-alt);
    border: 1px solid var(--accent);
    color: var(--text-primary);
    padding: 10px 16px;
    box-shadow: var(--shadow-md), 0 0 30px var(--accent-tint);
    display: flex;
    gap: 10px;
    align-items: baseline;
    font-size: 0.95rem;
    white-space: nowrap;
    max-width: calc(100% - 28px);
    overflow: hidden;
    text-overflow: ellipsis;
    z-index: 5;
}

/* The popup itself is pointer-events:none so it never intercepts a tap meant for the word
   underneath it -- but the speaker inside it has to be clickable, so it opts back in. */
.hint-popup .speak-btn {
    pointer-events: auto;
    margin-left: 4px;
}

.hint-reading {
    font-weight: 700;
    color: var(--accent-dark);
}

.hint-en {
    color: var(--text-secondary);
}

/* Floating bottom control bar — a podcast/audiobook-player style dock rather than the
   inline row under the passage the other pages' top-toolbar pattern would suggest. Mic
   and skip are the controls you reach for while your hands (and eyes) are busy with the
   passage/mic, so they live anchored to the bottom edge instead of scrolling away with
   the page. Left at document position (after .reader-body in the DOM); only taken out of
   flow visually via position:fixed, so nothing about reading.js's element lookups moves. */
/* .reader-controls is a fixed bar pinned to the bottom of the viewport, and its z-index:40
   below is sealed inside .reading-main's 'isolation: isolate' -- so the level that actually
   competes with the page footer is .container's. style.css gives .container AND .site-footer
   z-index:2 apiece, an exact tie, broken by DOM order in the footer's favour since it comes
   later. The footer therefore painted over the control bar and swallowed every click on Start
   Reading and Skip Word wherever the two overlapped -- on a 950px-tall viewport, all of them.
   (The footer's own z-index:2 was added so background shapes wouldn't swallow clicks on its
   links: the same bug, one layer up.) Raising the level here only, on the one page carrying a
   fixed bottom bar; the masthead sits outside .container at z-index:1000 and still wins. */
body:has(.reading-main) .container {
    z-index: 3;
}

.reader-controls {
    position: fixed;
    left: 50%;
    bottom: 22px;
    transform: translateX(-50%);
    z-index: 40;
    width: min(680px, calc(100% - 32px));
    margin: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 14px;
    row-gap: 8px;
    background: var(--bg-surface);
    border: 1px solid var(--border-strong);
    box-shadow: var(--shadow-md);
    padding: 14px 20px;
}

.reader-controls #reader-mic-btn {
    flex: 0 0 auto;
    font-size: 1rem;
    padding: 12px 22px;
    white-space: nowrap;
}

.reader-controls #reader-skip-btn {
    flex: 0 0 auto;
    white-space: nowrap;
}

/* The reader's own read of the microphone, shown so "is it hearing me?" is answerable at a
   glance -- the question the voice gate turns into a decision behind the scenes. Hidden until
   listening starts, since an idle meter is just noise in the bar. */
.reader-level {
    order: 1;
    display: none;
    flex: 0 0 auto;
    width: 54px;
    height: 6px;
    border-radius: 3px;
    background: var(--bg-surface-alt);
    border: 1px solid var(--border);
    overflow: hidden;
}

.reader-level.active {
    display: block;
}

.reader-level-fill {
    display: block;
    width: 0;
    height: 100%;
    background: var(--border-strong);
    transition: width 80ms linear;
}

/* Over the threshold -- this is what the gate counts as speech rather than room noise. */
.reader-level-fill.over {
    background: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
    .reader-level-fill { transition: none; }
}

/* Speak-this-word buttons, in the stall hint and on every skipped word. Sized to sit with
   the text rather than compete with it -- the word is the content, this is an affordance. */
.speak-btn {
    flex: 0 0 auto;
    margin-left: auto;
    padding: 2px 6px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    font-size: 0.85rem;
    line-height: 1.4;
    cursor: pointer;
    transition: background 0.15s var(--ease-out), border-color 0.15s var(--ease-out);
}

.speak-btn:hover {
    background: var(--accent-tint);
    border-color: var(--border-strong);
}

.speak-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

/* Non-symbol words are click/Enter targets for jumpToWord, so they need to look like it --
   subtle enough not to compete with the .current cursor, which is the thing being read. */
.reader-word[role='button'] { cursor: pointer; border-radius: 4px; }
.reader-word[role='button']:hover { background: var(--accent-tint); }
.reader-word[role='button']:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.reader-tap-hint {
    order: 2;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    font-size: .78rem;
    color: var(--text-muted);
    opacity: .8;
}

.reader-status {
    /* Own full-width row (order puts it under the buttons and the hint), and allowed to wrap:
       it now carries whole sentences explaining why recognition stopped, and the old
       nowrap + ellipsis inside a 680px bar shared with two buttons clipped them to "List…". */
    order: 3;
    flex: 1 1 100%;
    min-width: 0;
    color: var(--text-secondary);
    font-size: 0.85rem;
    margin: 0;
    text-align: left;
}

/* No message, no empty row -- otherwise the bar is permanently a line taller than it needs. */
.reader-status:empty {
    display: none;
}

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */
@media (max-width: 968px) {
    .reading-main {
        /* 56px mobile masthead + the same ~25px clearance (was 130px for the 105px bar). */
        padding: 81px 20px 60px;
    }

    .reader-body {
        flex-direction: column;
        margin-bottom: 130px;
    }

    .skipped-panel {
        flex-basis: auto;
        width: 100%;
        max-height: 220px;
    }

    .reader-passage-wrap {
        padding: 24px;
        width: 100%;
    }

    .reader-passage {
        font-size: 1.25rem;
        line-height: 2.2;
    }

    .hint-popup {
        left: 24px;
    }

    .track-card,
    .level-card {
        flex-wrap: wrap;
    }
}

@media (max-width: 560px) {
    .reader-controls {
        flex-wrap: wrap;
        justify-content: center;
        bottom: 12px;
        padding: 12px 16px;
        gap: 10px;
    }

    .reader-status {
        flex-basis: 100%;
        order: 3;
        white-space: normal;
    }
}
