/* ==========================================
   BASE / LAYOUT
   Brand tokens come from tokens.css (vendored copy of
   yorubadict/public/_tokens.css). Layout is deliberately compact:
   the top bar is a single slim row, not a hero block, so the
   actual game gets almost the whole viewport.
   ========================================== */
* { box-sizing: border-box; }

html, body {
    margin: 0;
    padding: 0;
    background: var(--background-primary);
    color: var(--text-primary);
    font-family: var(--font-body);
    /* overscroll-behavior-y was here to stop elastic "rubber-band"
       scroll past the end of the page, but empirically (tested with a
       real headless Chromium instance against the live site) setting
       ANY non-default value of it on html/body - none, contain, even
       just re-asserting a value - completely breaks real wheel/touch
       scrolling on levels whose content overflows the viewport, while
       leaving programmatic scrollTo() working, which is what made it
       so easy to miss. Removed entirely: a working page that
       occasionally bounces slightly past its own end is far better
       than a page that cannot scroll its overflowing content at all.
       Belt-and-suspenders against any single element (see
       #theme-selector below - the actual known culprit) forcing
       horizontal page overflow, which is what causes mobile browsers
       to render an unwanted zoomed-out-then-in initial view. */
    overflow-x: hidden;
}

#app-wrapper {
    max-width: 640px;
    margin: 0 auto;
    padding: 0 12px 24px;
}

#top-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 4px;
    margin-bottom: 10px;
    border-bottom: 1px solid var(--border-subtle);
}

#brand-mark {
    display: flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: var(--step--1);
    color: var(--brand-indigo);
    text-decoration: none;
    opacity: 0.75;
    letter-spacing: 0.02em;
    transition: opacity 0.15s;
}

/* Now a link back to the games landing page - full opacity on
   hover/focus is the only affordance signaling that, since it's
   deliberately understated (this is a slim utility bar, not a nav). */
#brand-mark:hover,
#brand-mark:focus-visible {
    opacity: 1;
}

#brand-mark img {
    display: block;
}

#top-bar-controls {
    display: flex;
    align-items: center;
    gap: 8px;
}

#theme-selector {
    font-family: var(--font-body);
    font-size: var(--step--1);
    padding: 6px 10px;
    border-radius: 8px;
    border: 1px solid var(--border-subtle);
    background: var(--surface);
    color: var(--text-primary);
    /* A native <select> sizes itself to its longest option's full text
       by default - level names can be long ("Level 3: Body Parts
       (Ẹ̀yà Ara) — speaker1"), which was forcing horizontal page
       overflow on narrow phones (and, with it, an unwanted initial
       zoomed view, and the fullscreen button pushed off-screen).
       Capping the width and truncating instead fixes both. */
    max-width: 130px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

#game-container {
    text-align: center;
}

/* ==========================================
   START OVERLAY
   ========================================== */
#start-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(251, 246, 236, 0.85); /* --background-primary, translucent */
    backdrop-filter: blur(5px);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 1000;
}

#playlist-menu {
    text-align: center;
    padding: 24px;
}

#playlist-menu h2 {
    font-family: var(--font-display);
    color: var(--brand-indigo);
    margin: 0 0 16px;
}

.playlist-btn {
    display: block;
    width: 240px;
    margin: 0 auto 12px;
    padding: 16px 24px;
    font-size: var(--step-0);
    font-family: var(--font-display);
    font-weight: 600;
    background-color: var(--brand-indigo);
    color: var(--text-tertiary);
    border: none;
    border-radius: var(--radius);
    cursor: pointer;
    box-shadow: var(--shadow);
    transition: transform 0.2s, background-color 0.2s;
}

.playlist-btn:hover {
    background-color: var(--brand-indigo-deep);
    transform: scale(1.05);
}

/* Disabled until app.js confirms this category actually has levels for
   the current data (see initializePlaylistMenu) - avoids offering a
   playlist that would just show an empty game. */
.playlist-btn:disabled {
    background-color: var(--border-subtle);
    color: var(--text-secondary);
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}

/* ==========================================
   STAGE ROW - prev/next navigation flanks the image as a symmetric
   pair, instead of a separate text-button row below it.
   ========================================== */
#stage-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
}

.icon-btn {
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid var(--border-subtle);
    background: var(--surface);
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}

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

/* Smaller variant for the hint toggle sitting beside the answer slots
   (see #answer-row) - doesn't need to match the nav buttons' size. */
.icon-btn-small {
    width: 30px;
    height: 30px;
}

/* Shown while toggled on: tone hint (see app.js toggleToneHint) or
   active fullscreen (see toggleFullscreen). */
#hint-btn.active,
#fullscreen-btn.active {
    background: var(--brand-accent);
    border-color: var(--brand-accent-deep);
    color: var(--brand-indigo-deep);
}

#skip-btn {
    border-color: rgba(198, 56, 90, 0.35); /* --accent-games */
    color: var(--accent-games);
}
#skip-btn:hover { background: rgba(198, 56, 90, 0.08); }

/* ==========================================
   ANSWER ROW - hint toggle sits beside the slots, but the slots (not
   the row as a whole) must be the thing centered on the page. Classic
   1fr/auto/1fr grid centering: the middle column sizes to the slots'
   content and is centered independent of the side columns, so the
   hint button (in the first column) reads as ancillary rather than
   shifting the "true" center.
   ========================================== */
#answer-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 10px;
    margin: 10px 0;
}

#answer-row .slots-container {
    grid-column: 2;
}

#hint-btn {
    grid-column: 1;
    justify-self: end; /* hugs the right edge of its column, i.e. just left of the slots */
}

/* ==========================================
   IMAGE PROMPT AREA
   ========================================== */
.prompt-container {
    position: relative;
    width: 200px;
    height: 200px;
    border-radius: var(--radius);
    overflow: hidden;
    cursor: pointer;
    box-shadow: var(--shadow);
    transition: transform 0.1s ease;
}

.prompt-container:active {
    transform: scale(0.95);
}

#prompt-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.audio-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(21, 26, 61, 0.3); /* --brand-indigo-deep, translucent */
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0.75;
    transition: opacity 0.2s ease;
}

.prompt-container:hover .audio-overlay {
    opacity: 1;
}

/* Correct-answer checkmark badge - hidden by default, shown briefly via
   JS toggling .show (see app.js's playWinningSequence). */
.correct-badge {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(251, 246, 236, 0.55);
    opacity: 0;
    transform: scale(0.6);
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.correct-badge.show {
    opacity: 1;
    transform: scale(1);
}

/* ==========================================
   QUEUE SLOTS
   ========================================== */
.slots-container {
    display: flex;
    justify-content: center;
    gap: 8px;
    min-height: 46px;
}

.slot {
    position: relative;
    width: 48px;
    height: 48px;
    border: 2px dashed var(--border-subtle);
    border-radius: 8px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 1.35rem;
    font-weight: bold;
    color: var(--text-primary);
    transition: border-color 0.2s, background-color 0.2s, transform 0.2s;
}

/* Applied to every filled slot the instant a win is detected, for a
   clear, immediate visual "yes, that's right" independent of the
   text feedback message. */
.slots-container.correct .slot {
    border-color: var(--accent-courses);
    border-style: solid;
    background: rgba(47, 122, 77, 0.12); /* --accent-courses, translucent */
    transform: scale(1.08);
}

/* Tone-hint dot above each slot - always rendered (see app.js's
   renderQueue), only made visible while the hint is toggled on. This
   replaces the old "Tone Hint: mid mid high" text line entirely. */
.slot::before {
    content: '';
    position: absolute;
    top: -8px;
    left: 50%;
    transform: translateX(-50%);
    width: 16px;
    height: 5px;
    border-radius: 3px;
    opacity: 0;
    transition: opacity 0.15s;
}

/* Orange/gray/blue, not red/gray/blue - a colorblind-safe combination
   (Okabe-Ito palette) that works across every common form of color
   vision deficiency, unlike red-based schemes. Also stops "high tone"
   from sharing a color with the (semantically unrelated) Skip button,
   which used the same red before. */
.slot.tone-high::before { background: var(--brand-accent-deep); }
.slot.tone-mid::before  { background: var(--text-secondary); }
.slot.tone-low::before  { background: var(--accent-videos); }

.slots-container.show-hint .slot::before {
    opacity: 1;
}

/* ==========================================
   TOAST - transient feedback (correct/skip/error/level-complete),
   floating over the page rather than reserving a permanent line.
   Hidden (opacity 0, no pointer events) until app.js's showToast()
   adds .show; auto-hidden again after its duration.
   ========================================== */
#toast {
    position: fixed;
    top: 64px;
    left: 50%;
    transform: translate(-50%, -6px);
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    box-shadow: var(--shadow);
    border-radius: 999px;
    padding: 8px 18px;
    font-size: var(--step--1);
    font-weight: 700;
    color: var(--text-secondary);
    opacity: 0;
    pointer-events: none;
    max-width: 90vw;
    text-align: center;
    transition: opacity 0.2s ease, transform 0.2s ease;
    z-index: 500;
}

#toast.show {
    opacity: 1;
    transform: translate(-50%, 0);
}

#toast.correct  { color: var(--accent-courses); border-color: rgba(47, 122, 77, 0.35); }
#toast.skipping { color: var(--accent-games); border-color: rgba(198, 56, 90, 0.35); }
#toast.error    { color: var(--accent-games); border-color: rgba(198, 56, 90, 0.35); }
#toast.info     { color: var(--brand-indigo); border-color: var(--border-subtle); }

/* ==========================================
   TONAL SYLLABLE MATRIX
   Each tone gets its own bordered panel with a colored accent bar,
   plus a small glyph badge overlapping the border (not a full text
   label line) - color alone isn't reliable for colorblind users, so
   the glyph stays as a compact, non-color-dependent cue instead of
   dropping it entirely. Colors are orange/gray/blue (not red-based) -
   the Okabe-Ito colorblind-safe palette's two most distinguishable
   hues across every common type of color vision deficiency (the
   red-green pair that trips up most colorblind users is the one
   combination this avoids entirely).
   ========================================== */
.syllable-matrix {
    display: flex;
    flex-direction: column;
    gap: 14px; /* slightly more than before - the badges overlap the top edge */
    margin-top: 14px;
}

.tone-group {
    position: relative;
    text-align: left;
    background: var(--surface);
    border: 1px solid var(--border-subtle);
    border-left-width: 5px;
    border-radius: 10px;
    padding: 8px 10px 10px;
}

.tone-group-high { border-left-color: var(--brand-accent-deep); }
.tone-group-mid  { border-left-color: var(--text-secondary); }
.tone-group-low  { border-left-color: var(--accent-videos); }

.tone-badge {
    position: absolute;
    top: -9px;
    left: 10px;
    font-family: var(--font-mono);
    font-size: 0.85rem;
    line-height: 1;
    padding: 2px 6px;
    border-radius: 999px;
    background: var(--surface);
    border: 1px solid currentColor;
}

.tone-group-high .tone-badge { color: var(--brand-accent-deep); }
.tone-group-mid  .tone-badge { color: var(--text-secondary); }
.tone-group-low  .tone-badge { color: var(--accent-videos); }

/* Pills sit close together (small gap) rather than the wide-spaced
   grid before, and are larger/chunkier for easier tapping. */
.bank-row {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(66px, 1fr));
    gap: 5px;
}

.bank-row button {
    padding: 14px 10px;
    border-radius: 10px;
    font-size: var(--step-0);
    font-family: var(--font-yoruba);
    font-weight: 700;
    cursor: pointer;
    transition: transform 0.1s;
}

.bank-row button:active {
    transform: scale(0.92);
}

/* Tone-specific button fills, harmonized with the brand accent
   palette (same three accents as the panel border/label above). */
.btn-high { background-color: rgba(154, 106, 8, 0.10); border: 2px solid rgba(154, 106, 8, 0.35); color: var(--brand-accent-deep); }
.btn-mid  { background-color: var(--background-secondary); border: 2px solid var(--border-subtle); color: var(--text-primary); }
.btn-low  { background-color: rgba(46, 111, 158, 0.10); border: 2px solid rgba(46, 111, 158, 0.35); color: var(--accent-videos); }
