/* ============================================================
   css/category-picker.css — category.php picker UI (chat 2.5)
   ============================================================
   Reused as-is from style.css (already loaded on category.php):
   .categories-grid, .cat-card, .cat-icon, .cat-name, .cat-count,
   .section-label, .section-title — same classes the homepage's
   category cards already use, so this picker looks native to the
   site with zero new grid/card CSS needed.
   ============================================================ */

/* Background — same visual language as index.php's .hero-bg (image,
   filter/overlay, subtle fixed-parallax feel), applied here at the
   body level via a page-specific class rather than reusing .hero-bg
   directly. Reason: .hero-bg is position:absolute + inset:0, sized by
   filling its .hero ancestor (position:relative, min-height:100vh) —
   a bare div without that wrapper renders with ~zero usable height.
   Wrapping this page's content in .hero itself was ruled out too:
   that class also carries min-height:100vh, flex-centering, and
   overflow:hidden, which would badly mangle the picker/puzzle layout.
   This targets body.category-page specifically (set on category.php
   only), so no other page is affected, and no separate DOM element or
   z-index stacking is needed at all — confirmed against the real
   style.css (chat 2.5), not guessed. */
body.category-page {
    /* Chat 2.36 — supersedes chat 2.34/2.35's split-layer approach.
       That split the gradient (always on body, instant) from the photo
       (on ::before, fading in separately) — but negative-z-index
       descendants paint ABOVE their stacking context root's own
       background, not below it. So once the photo faded in, it would
       have covered the gradient instead of being dimmed by it — wrong
       layering direction, on top of the missing-stacking-context bug
       from 2.35. Simplest correct fix: put gradient and photo back
       together as one multi-layer background-image (exactly like the
       original, pre-fade version — first-listed layer paints on top,
       same as any standard CSS background-image stack), on the
       ::before element, and fade that combined unit in as one piece.
       Body itself keeps only a plain solid-color fallback: always
       instant, no image dependency, so the page is never blank even if
       JS never runs — just a dark, intentional-looking backdrop until
       (or if) the photo layer arrives. position:relative + z-index:0
       still needed here so the ::before's z-index:-1 stacks correctly
       behind body's own text/card content instead of escaping to the
       document root (the actual missing-image bug from chat 2.34). */
    position: relative;
    z-index: 0;
    background-color: #0e0c0a;
}

body.category-page::before {
    content: '';
    position: fixed;
    inset: 0;
    z-index: -1;
    background-image:
        linear-gradient(to bottom, rgba(14,12,10,0.55) 0%, rgba(14,12,10,0.8) 45%, rgba(14,12,10,0.94) 100%),
        url('/images/library.jpg');
    background-size: cover;
    background-position: center 30%;
    opacity: 0;
    transition: opacity 0.5s ease-out;
    pointer-events: none;
}

body.category-page.bg-ready::before {
    opacity: 1;
}

#picker-view {
    max-width: 960px;
    margin: 0 auto;
    /* Top padding raised chat 2.24 (60px→96px) to clear the
       absolutely-positioned .picker-nav-bar, matching the ~6rem
       clearance the other three pages use. Same mechanism as
       index.php (content wrapper's own top padding clears the nav). */
    padding: 96px 24px 80px;
}
/* Desktop nav bar — new, chat 2.23. Genuinely separate mechanism from
   both .site-nav-minimal (style.css — a small fixed corner box sized
   just for the hamburger) and the shared .nav-desktop.header-nav-
   desktop rule (also style.css — the centered-row treatment dashboard.
   php/builder.php/print-builder.php still use). Mirrors index.php's
   own real nav bar as closely as this page's structure allows:
   position:absolute (not fixed) so it scrolls away with the page the
   same way index.php's does, spanning the full viewport width via
   left:0/right:0 rather than being constrained to #picker-view's own
   960px max-width. No logo here by design — the picker's own large
   centered logo below already carries that; direct feedback confirmed
   a second, smaller one was unwanted. */
.picker-nav-bar {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 1.25rem 1.5rem;
}
@media (min-width: 760px) {
    .picker-nav-bar { padding: 1.5rem 3rem; }
}

.picker-header {
    text-align: center;
    margin-bottom: 32px;
}

/* Mode context heading + Classic link (chat 2.7) — replaces the earlier
   segmented mode-toggle control. That control looked and behaved like a
   real button (solid gold fill, matching the homepage's actual CTAs),
   but there was nothing to actually toggle to yet (Classic is disabled)
   — a real affordance mismatch. .mode-title/.nav-brand are reused as-is
   from style.css (same Playfair Display treatment and logo mark used
   elsewhere on the site), so this reads as consistent site branding
   rather than a one-off control. */
.picker-logo {
    justify-content: center;
    margin-bottom: 1.25rem;
    transition: transform .15s ease;
    animation: picker-logo-hint 2s ease-in-out .6s 1;
}
.picker-logo:active {
    transform: scale(0.95);
}
@keyframes picker-logo-hint {
    0%, 100% { filter: drop-shadow(0 0 0 rgba(201,168,76,0)); }
    50%      { filter: drop-shadow(0 0 12px rgba(201,168,76,0.6)); }
}
.picker-logo .nav-brand-text {
    font-size: 1.6rem;
}
.picker-mode-heading {
    font-size: clamp(2.2rem, 7vw, 3.4rem);
    margin-bottom: 0.5rem;
}
.picker-classic-link {
    display: inline-block;
    margin-top: 6px;
    font-size: .85rem;
    color: rgba(245,237,216,0.6);
    text-decoration: none;
    transition: color .2s;
}
.picker-classic-link:hover { color: var(--gold); }

/* Subcategory step — pill row replacing the category grid in place */
#picker-subcategory-wrap {
    display: none;
}

/* Count picker (chat 2.8) — "how many questions/words, up to 12" step
   between choosing a subcategory and actually generating. Mirrors
   #picker-subcategory-wrap's display:none/reveal pattern and
   #picker-subcategory-title's typography exactly, for visual
   continuity between the two steps. */
#picker-count-wrap {
    display: none;
    text-align: center;
    max-width: 420px;
    margin: 0 auto;
}
#picker-count-title {
    font-family: 'Playfair Display', serif;
    font-size: 1.6rem;
    margin: 0 0 28px;
}
.count-picker {
    margin-bottom: 28px;
}
.count-picker-value {
    font-family: 'Playfair Display', serif;
    font-size: 2.4rem;
    color: var(--gold);
    margin-bottom: 20px;
}
.count-picker-value span:last-child {
    font-family: 'DM Sans', sans-serif;
    font-size: 1rem;
    color: var(--ink-soft);
    letter-spacing: .04em;
    margin-left: 6px;
}
.count-slider {
    width: 100%;
    -webkit-appearance: none;
    appearance: none;
    height: 4px;
    border-radius: 2px;
    background: rgba(201,168,76,0.2);
    outline: none;
    cursor: pointer;
}
.count-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--gold);
    border: 2px solid var(--ink);
    cursor: pointer;
    transition: background .2s;
}
.count-slider::-webkit-slider-thumb:hover { background: var(--gold-light); }
.count-slider::-moz-range-thumb {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--gold);
    border: 2px solid var(--ink);
    cursor: pointer;
    transition: background .2s;
}
.count-slider::-moz-range-thumb:hover { background: var(--gold-light); }
.count-slider::-moz-range-track {
    height: 4px;
    border-radius: 2px;
    background: rgba(201,168,76,0.2);
}
.count-picker-scale {
    display: flex;
    justify-content: space-between;
    font-size: .72rem;
    color: var(--ink-muted);
    margin-top: 8px;
}
.difficulty-picker {
    margin: 4px 0 28px;
    padding-top: 20px;
    border-top: 1px solid rgba(245,237,216,0.08);
}
.difficulty-btn-group {
    display: flex;
    gap: 10px;
    justify-content: center;
    flex-wrap: wrap;
}
.difficulty-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 12px 20px;
    border-radius: 10px;
    border: 1px solid rgba(201,168,76,0.25);
    background: rgba(28,26,22,0.5);
    color: var(--ink-soft);
    cursor: pointer;
    transition: background .2s, border-color .2s, color .2s;
    font-family: 'DM Sans', sans-serif;
}
.difficulty-btn:hover { border-color: rgba(201,168,76,0.5); }
.difficulty-btn-label {
    font-size: .85rem;
    font-weight: 500;
    letter-spacing: .03em;
}
.difficulty-btn-size {
    font-size: .7rem;
    color: var(--ink-muted);
}
.difficulty-btn.active {
    background: var(--gold);
    border-color: var(--gold);
    color: var(--ink);
}
.difficulty-btn.active .difficulty-btn-size {
    color: rgba(14,12,10,0.65);
}
.difficulty-picker-note {
    font-size: .78rem;
    color: var(--ink-soft);
    margin: 14px 0 0;
    line-height: 1.5;
}
.picker-start-btn {
    display: inline-block;
    background: var(--gold);
    color: var(--ink);
    border: none;
    padding: .9rem 2.5rem;
    border-radius: 50px;
    font-family: 'DM Sans', sans-serif;
    font-size: .85rem;
    font-weight: 500;
    letter-spacing: .1em;
    text-transform: uppercase;
    cursor: pointer;
    transition: background .2s, transform .15s ease;
}
.picker-start-btn:hover { background: var(--gold-light); }
.picker-start-btn:active { transform: scale(0.97); }
.picker-back-link {
    display: inline-block;
    color: rgba(245,237,216,0.55);
    font-size: .85rem;
    text-decoration: none;
    margin-bottom: 18px;
    cursor: pointer;
}
.picker-back-link:hover { color: var(--gold); }
#picker-subcategory-title {
    font-family: 'Playfair Display', serif;
    font-size: 1.6rem;
    margin: 0 0 20px;
}
.subcat-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}
.subcat-pill {
    padding: 12px 22px;
    border-radius: 50px;
    border: 1px solid rgba(201,168,76,0.3);
    background: rgba(28,26,22,0.5);
    color: var(--cream);
    font-family: 'DM Sans', sans-serif;
    font-size: .88rem;
    cursor: pointer;
    transition: background .2s, border-color .2s;
}
.subcat-pill:hover {
    background: rgba(201,168,76,0.12);
    border-color: var(--gold);
}

.picker-error {
    display: none;
    margin-top: 24px;
    padding: 14px 18px;
    border-radius: 10px;
    background: rgba(196,130,106,0.12);
    border: 1px solid rgba(196,130,106,0.35);
    color: rgba(245,237,216,0.9);
    font-size: .85rem;
    text-align: center;
}

/* Scoped override for the shared .categories-grid (style.css) — that
   class uses a fixed column count (2/3/5 by breakpoint), which leaves
   large empty cells when there are only one or two real categories
   (content-driven, so this is the actual current state). auto-fit
   sizes columns to however many categories genuinely exist instead,
   so a single card doesn't look like a broken empty box. Loaded on
   both index.php and category.php, so this fixes it in both places
   without touching style.css itself. */
.categories-grid {
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)) !important;
}

/* #picker-category-grid / #home-category-grid mobile override
   (chat 2.7; extended to #home-category-grid per direct request) —
   originally ID-scoped to category.php's own grid only, deliberately
   NOT touching the homepage's #home-category-grid (same shared
   .categories-grid class, different id): category.php's photo
   background made the shared frame's border too subtle (barely
   visible, especially on the right edge), so this gave each card its
   own real border/background/radius instead. The homepage kept the
   auto-fit "mosaic tile" look (single shared frame, 1px hairline
   gaps) at every width — but on a real mobile viewport, auto-fit's
   minmax(180px, 1fr) doesn't leave room for 2 columns, so it silently
   collapsed to a single full-width column instead of matching
   category.php's real 2-column layout. Direct request: make the two
   pages' mobile category grids match. Extended to #home-category-grid
   as well, same rules, same breakpoint — no separate homepage-specific
   styling needed since the two grids use identical markup/classes. */
@media (max-width: 479px) {
    #picker-category-grid,
    #home-category-grid {
        grid-template-columns: repeat(2, 1fr) !important;
        gap: 12px;
        background: none;
        border: none;
        border-radius: 0;
        overflow: visible;
    }
    #picker-category-grid .cat-card,
    #home-category-grid .cat-card {
        background: rgba(28,26,22,0.65);
        border: 1px solid rgba(201,168,76,0.25);
        border-radius: 10px;
    }
    #picker-category-grid .cat-card:hover,
    #picker-category-grid .cat-card:active,
    #home-category-grid .cat-card:hover,
    #home-category-grid .cat-card:active {
        background: rgba(201,168,76,0.1);
        border-color: rgba(201,168,76,0.4);
    }
}

/* Mobile scroll container — #picker-view only (chat 2.7). Category.php-
   exclusive element, safe to keep scoped here. #game-screen's own
   mobile scroll handling — needed by BOTH this page and puzzle.php's
   non-Daily branch now (chat 2.9 continued) — moved to the shared
   puzzle.css, correctly scoped with :has(.category-puzzle-embed)
   rather than a bare #game-screen selector, which would otherwise
   also match puzzle.php's Daily branch (a different element using the
   same id, with its own already-correct .page-wrap-based mobile
   treatment that must never be touched). See puzzle.css for the full
   reasoning and the two-pass history of getting this right. */
@media (max-width: 639px) {
    #picker-view {
        height: 100dvh;
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
    }
}

/* "Browse all topics" — includes/topic-tabs.php, shared by index.php
   and category.php.

   Fourth revision. Three layers now, outermost to innermost:
     .topics-master — one master toggle. Closed by default, and its
                      <summary> IS the visible text "Browse all
                      topics" — when closed, that's the section's
                      entire footprint, nothing else renders at all.
     .topic-tabs    — category names, revealed once the master is
                      open. Plain text now, not pills (see below) —
                      fixed position, never reordered regardless of
                      which one is open.
     .topic-panels  — one shared area below the whole category row,
                      revealing whichever category's topic list
                      matches the open one.

   Category names dropped the pill treatment this round, matching the
   topic-level links one layer down: direct feedback that two stacked
   levels of bordered/filled buttons (category pills containing topic
   pills) was genuinely hard to visually parse. Both levels are now
   plain text that highlights (color change, no box) on hover/open —
   one consistent visual language top to bottom instead of two.

   Tab/panel matching is still :has() + a shared data-cat attribute
   (the category slug), generated per-category in includes/topic-
   tabs.php's own inline <style> block — nothing hand-maintained here.
   :has() support confirmed current (Chrome/Edge 105+, Safari 15.4+,
   Firefox 121+, "Baseline widely available" as of 2026).

   Native <details name="topic-tabs"> groups (HTML Living Standard;
   shipped Chrome/Edge 120, Safari 17.2, Firefox 130) still make the
   category row a mutually exclusive accordion in the browser itself.
   Everything here is real <details>/<summary>, no JS anywhere in this
   file, and fully crawlable regardless of open/closed state — Google
   crawls <details> content identically either way (confirmed since
   the 2019 mobile-first indexing update), including now-triple-nested
   content under the master toggle. */
.topic-tabs-section {
    max-width: 1100px;
    margin: 0 auto;
    padding: 40px 20px;
    text-align: center;
}
/* category.php's whole picker area (#picker-view — category name,
   "‹ All Categories", etc.) is left-aligned by existing design, and
   this section already read correctly sitting inside that context as-
   is — center-aligning is specifically an index.php fix (that page's
   headings/content are centered throughout, and this section was the
   one piece not matching). body.category-page is the same page-
   scoping class already used elsewhere in this file for exactly this
   kind of split. */
body.category-page .topic-tabs-section {
    text-align: left;
}

/* The master toggle — deliberately styled as a heading-weight piece
   of text rather than a button/pill, since when closed this IS the
   entire section as far as a visitor can see. */
.topics-master-summary {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    list-style: none;
    color: var(--cream, #F5EDD8);
    font-family: 'Playfair Display', serif;
    font-size: 1.6rem;
    transition: color .2s;
}
.topics-master-summary::-webkit-details-marker { display: none; }
.topics-master-summary::marker { content: ''; }
.topics-master-summary:hover {
    color: var(--gold);
}
.topics-master-summary::after {
    content: '';
    width: 8px;
    height: 8px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    transition: transform .2s;
    flex-shrink: 0;
}
.topics-master[open] .topics-master-summary::after {
    transform: rotate(-135deg);
}

.topic-tabs {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    column-gap: 28px;
    row-gap: 14px;
    margin-top: 28px;
}
/* text-align doesn't reach a flex container's own layout — this is
   the flex-specific half of the same index.php-only centering above. */
body.category-page .topic-tabs {
    justify-content: flex-start;
}
/* Plain text, not a pill — border/background/radius/padding all
   removed this round. Chevron (below) is the only shape carried over
   from the pill version; everything else is color + weight now. */
.topic-tab-summary {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    list-style: none;
    color: rgba(245,237,216,0.75);
    font-family: 'DM Sans', sans-serif;
    font-size: 15px;
    font-weight: 500;
    transition: color .15s;
}
.topic-tab-summary::-webkit-details-marker { display: none; }
.topic-tab-summary::marker { content: ''; }
.topic-tab-summary:hover {
    color: var(--gold);
}
.topic-tab-summary::after {
    content: '';
    width: 6px;
    height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(45deg);
    transition: transform .2s;
    flex-shrink: 0;
}
.topic-tab[open] .topic-tab-summary::after {
    transform: rotate(-135deg);
}
.topic-tab-name {
    white-space: nowrap;
}
/* Open state — bold + gold, no fill. Position never changes; this is
   the only visual effect [open] has. */
.topic-tab[open] .topic-tab-summary {
    color: var(--gold);
    font-weight: 700;
}

/* Shared panel area — one per category, all hidden by default; the
   matching one is revealed by the :has() rules generated in
   includes/topic-tabs.php. Sits in normal document flow (not
   absolutely positioned), so whatever's below it on the page (the
   Daily Puzzle section, etc.) is naturally pushed down by however tall
   the open panel actually is — no reserved/guessed height needed.
   Numbered (<ol>, real browser-generated 1/2/3 markers), three columns
   on desktop, stepping down at narrower widths. break-inside:avoid
   keeps each <li> a single intact unit so one never straddles a
   column break. */
.topic-panel {
    display: none;
    list-style: decimal;
    margin: 20px 0 0;
    padding: 24px 0 0 20px;
    border-top: 1px solid rgba(201,168,76,0.15);
    column-count: 3;
    column-gap: 32px;
    text-align: left;
}
.topic-panel li {
    break-inside: avoid;
    -webkit-column-break-inside: avoid;
    margin-bottom: 10px;
    padding-left: 4px;
}
.topic-panel li::marker {
    color: rgba(201,168,76,0.55);
    font-size: 13px;
}
.topic-panel a {
    color: rgba(245,237,216,0.7);
    text-decoration: none;
    font-size: 14px;
    font-family: 'DM Sans', sans-serif;
    line-height: 1.5;
    transition: color .15s;
}
.topic-panel a:hover {
    color: var(--gold);
}

/* Column count steps down before there's room to run three, same
   general responsive discipline as the rest of this file — one set of
   markup, CSS carries the breakpoints. */
@media (max-width: 900px) {
    .topic-panel { column-count: 2; }
}
@media (max-width: 639px) {
    .topic-panel { column-count: 1; }
}

/* Mobile — larger tap targets on the master toggle and category row,
   same ~640px breakpoint used throughout this file. */
@media (max-width: 639px) {
    .topics-master-summary {
        font-size: 1.4rem;
    }
    .topic-tab-summary {
        font-size: 16px;
    }
}

/* Desktop scroll container — #picker-view, unconditionally. Originally
   scoped to :has(.topics-details[open]) on the assumption that the
   topics list was the only thing that could push #picker-view taller
   than one screen — wrong: the subcategory step and the count/
   difficulty step can both do the same thing on a shorter browser
   window, with nothing to do with the topics list at all (direct
   report: the Start Puzzle button on the count/difficulty step was
   unreachable). This was always a latent gap in #picker-view — it
   never had its own scroll handling for ANY of its steps before the
   topics list existed, it just hadn't been hit yet. Since
   html.puzzle-page/body are deliberately non-scrolling at desktop
   widths (puzzle.css — the same reason .page-wrap and
   .category-puzzle-embed handle their own scroll instead of relying
   on body), #picker-view needs to do the same here, for all of its
   steps, all the time — not conditionally. Scrollbar chrome stays
   hidden (scrollbar-width:none/::-webkit-scrollbar{display:none})
   rather than styled — scrolling itself (wheel/trackpad/touch) is
   unaffected, only the visible track/thumb is suppressed, same as the
   picker's mobile scroll container above. */
@media (min-width: 640px) {
    #picker-view {
        max-height: 94vh;
        overflow-y: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    #picker-view::-webkit-scrollbar {
        display: none;
    }
}

/* Everything below this point — the desktop peek-bar hide, the
   .category-puzzle-embed card itself (including its desktop scroll
   containment), and the Save button styles — moved to the shared
   puzzle.css (chat 2.9 continued), since puzzle.php's non-Daily
   branch now uses this exact same card structure for a saved
   puzzle's own desktop view, not just category.php's browsing view.
   Kept in one file rather than duplicated, same discipline as
   .puzzle-view-mode/-path/-logo before it — see puzzle.css for the
   full content and the corrected, properly-scoped versions of the
   two rules that weren't safe to copy as-is. */
