/* ════════════════════════════════════════════════════════════════
 * css/symbol-library.css — Symbol & Kaomoji Library
 *
 * Additive, self-contained. Uses main.css design tokens only (light-mode
 * is automatic). Reserves height to prevent CLS (mirrors the gaming-identity
 * / style-builder / recents discipline). Respects prefers-reduced-motion;
 * >=44px touch targets; aria-driven <details> disclosure. The fadeIn keyframe
 * is declared locally so the module is not coupled to load order.
 *
 * Interior built by js/features/symbol-library.js (textContent only — never
 * innerHTML with symbol text). Featured (open) on /symbol-keyboard/ via
 * data-symbols-open="true" stamped by generate-pages.js.
 * ════════════════════════════════════════════════════════════════ */

/* ── Shell (collapsed reserve = summary row only) ── */
.sl {
    margin-top: var(--s-md);
    /* CLS reserve. The interior (<details> + grid) is built by JS, so the
     * collapsed shell reserves only the summary row (2-line title+sub, ~64px).
     * On the FEATURED page the mount ships data-symbols-open="true" at parse
     * time, so we reserve the about-to-open height there (see below) to avoid a
     * 64px -> open jump on first paint. Growth after the user types / picks a
     * chip / hits "Show more" is interaction-driven (CLS-exempt). */
    min-height: 64px;
}
.sl[hidden] { display: none; }

/* Featured page: JS sets details.open + builds the open grid in one runtime
 * step, so reserve that taller height on the parse-time attribute to keep the
 * first paint stable (summary ~64px + searchbar/chips/hint + 420px grid). */
.sl[data-symbols-open="true"] { min-height: 620px; }
@media (max-width: 600px) {
    .sl[data-symbols-open="true"] { min-height: 700px; }
}

/* ── Disclosure container (native <details>) ── */
.sl__disclosure {
    background: var(--c-surface);
    border: 1px solid var(--c-border);
    border-radius: var(--r-md);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    overflow: hidden;
}

/* ── Disclosure header (summary) ── */
.sl__summary {
    display: flex;
    align-items: center;
    gap: var(--s-sm);
    width: 100%;
    min-height: 64px;
    padding: var(--s-md);
    cursor: pointer;
    list-style: none;                 /* hide default marker (Firefox) */
    user-select: none;
    transition: background var(--t-fast);
}
.sl__summary::-webkit-details-marker { display: none; }   /* hide default marker (WebKit) */
.sl__summary:hover { background: var(--c-surface-hover); }
.sl__summary:focus-visible { outline: 2px solid var(--c-purple); outline-offset: -2px; }

.sl__summary-icon { font-size: 1.4rem; line-height: 1; flex-shrink: 0; }
.sl__summary-text { display: flex; flex-direction: column; gap: 0.1rem; flex: 1; min-width: 0; }
.sl__summary-title { font-size: 1.05rem; font-weight: 700; color: var(--c-text); }
.sl__summary-sub { font-size: 0.8rem; color: var(--c-text-muted); }
.sl__summary-chevron {
    flex-shrink: 0; color: var(--c-text-muted); font-size: 0.9rem;
    transition: transform var(--t-base);
}
.sl__disclosure[open] .sl__summary-chevron { transform: rotate(180deg); }

/* ── Body (revealed area) ── */
.sl__body {
    padding: 0 var(--s-md) var(--s-md);
    border-top: 1px solid var(--c-border);
}

/* ── Search bar ── */
.sl__searchbar {
    position: relative;
    display: flex;
    align-items: center;
    margin: var(--s-md) 0;
}
.sl__search-icon {
    position: absolute; left: 0.85rem; font-size: 0.95rem;
    color: var(--c-text-muted); pointer-events: none;
}
.sl__search {
    width: 100%; min-height: 44px;
    padding: 0.65rem 2.6rem;          /* room for icon (left) + clear (right) */
    border-radius: var(--r-full);
    border: 1px solid var(--c-border);
    background: var(--c-surface-solid, var(--c-surface));
    color: var(--c-text); font-size: 0.95rem; outline: none;
    transition: border-color var(--t-fast);
}
.sl__search::placeholder { color: var(--c-text-muted); }
.sl__search:focus { border-color: rgba(168, 85, 247, 0.6); }
.sl__search:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 2px; }
.sl__search::-webkit-search-decoration,
.sl__search::-webkit-search-cancel-button { -webkit-appearance: none; }

.sl__search-clear {
    position: absolute; right: 0.5rem;
    width: 44px; height: 44px; min-height: 44px;
    display: flex; align-items: center; justify-content: center;
    border-radius: var(--r-full); border: none; background: transparent;
    color: var(--c-text-muted); font-size: 0.9rem; cursor: pointer;
    transition: background var(--t-fast), color var(--t-fast);
}
.sl__search-clear:hover { background: var(--c-surface-hover); color: var(--c-text); }
.sl__search-clear:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 2px; }
.sl__search-clear[hidden] { display: none; }

/* ── Category chips ── */
.sl__chips {
    display: flex; flex-wrap: wrap; gap: var(--s-sm);
    margin-bottom: var(--s-md);
}
.sl__chip {
    display: inline-flex; align-items: center; gap: 0.4rem;
    min-height: 44px; padding: 0.4rem 0.85rem;
    border-radius: var(--r-full);
    border: 1px solid var(--c-border);
    background: transparent; color: var(--c-text);
    font-size: 0.82rem; font-weight: 600; cursor: pointer; white-space: nowrap;
    transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.sl__chip:hover { background: var(--c-surface-hover); border-color: var(--c-border-hover); transform: translateY(-1px); }
.sl__chip:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 2px; }
.sl__chip--active {
    border-color: transparent; color: #fff;
    background: var(--grad-brand, var(--c-purple));
}
.sl__chip--active:hover { background: var(--grad-brand, var(--c-purple)); }
.sl__chip-icon { font-size: 0.95rem; line-height: 1; }
.sl__chip-count {
    font-size: 0.72rem; font-weight: 700;
    padding: 0.05rem 0.4rem; border-radius: var(--r-full);
    background: rgba(255, 255, 255, 0.1); color: inherit;
}
.sl__chip--active .sl__chip-count { background: rgba(255, 255, 255, 0.25); }

/* While a search is live, results span ALL categories, so no single chip is
 * "active". The container softens slightly so it reads as "browsing across
 * everything" rather than a broken/unselected tab row. */
.sl__chips--searching { opacity: 0.7; }

/* ── Helper / status line (teaches one-tap copy; shows live results count) ── */
.sl__hint {
    margin: 0 0 var(--s-sm);
    font-size: 0.8rem;
    color: var(--c-text-muted);
    text-align: center;
}
.sl__hint[hidden] { display: none; }

/* ── Tile grid (CLS reserved) ── */
.sl__grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: var(--s-sm);
    min-height: 280px;                /* ~4 tile rows reserved -> no CLS on inject */
}

/* ── Symbol tile (tap to copy) ── */
.sl__tile {
    display: flex; align-items: center; justify-content: center;
    min-height: 56px; padding: 0.4rem;
    border-radius: var(--r-sm);
    border: 1px solid var(--c-border);
    background: rgba(255, 255, 255, 0.03);
    color: var(--c-text); cursor: pointer;
    overflow: hidden;
    transition: background var(--t-fast), border-color var(--t-fast), transform var(--t-fast);
}
.sl__tile:hover {
    background: var(--c-surface-hover);
    border-color: rgba(168, 85, 247, 0.45);
    transform: translateY(-2px);
}
.sl__tile:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 2px; }
.sl__tile-char {
    font-size: 1.5rem; line-height: 1.2;
    white-space: nowrap;
}

/* Wide tiles for kaomoji / multi-char faces (JS adds --wide when char is long) */
.sl__tile--wide { grid-column: span 3; }
.sl__tile--wide .sl__tile-char { font-size: 1.05rem; }

/* Copied confirmation — pure COLOR swap (no motion). Always applied on a
 * successful copy, including under prefers-reduced-motion, because it's the
 * clearest "which tile copied" signal. (Matches .gid / .sb green convention.) */
.sl__tile--done {
    background: rgba(34, 197, 94, 0.2);
    border-color: rgba(34, 197, 94, 0.45);
}
.sl__tile--done .sl__tile-char { color: var(--c-success); }

/* Optional pop flourish — JS adds this ONLY when motion is allowed. */
.sl__tile--pop { animation: slPop var(--t-base) ease; }
@keyframes slPop {
    0%   { transform: scale(1); }
    40%  { transform: scale(1.12); }
    100% { transform: scale(1); }
}

/* ── Empty / no-results state ── */
.sl__empty {
    grid-column: 1 / -1;              /* if rendered inside the grid; harmless outside */
    text-align: center; color: var(--c-text-muted);
    padding: var(--s-xl) var(--s-md); font-size: 0.95rem; margin: 0;
    min-height: 280px;               /* matches grid reserve — no jolt while typing */
    display: flex; align-items: center; justify-content: center;
}
.sl__empty[hidden] { display: none; }
.sl__empty .sl__empty-term { color: var(--c-text); font-weight: 600; }

/* ── "Show more" reveal button when capped ── */
.sl__more {
    display: block;
    margin: var(--s-md) auto 0;
    min-height: 44px;
    padding: 0.6rem 1.4rem;
    border-radius: var(--r-full);
    border: 1px solid var(--c-border);
    background: transparent;
    color: var(--c-text);
    font-size: 0.85rem; font-weight: 600; cursor: pointer;
    transition: background var(--t-fast), border-color var(--t-fast);
}
.sl__more:hover { background: var(--c-surface-hover); border-color: var(--c-border-hover); }
.sl__more:focus-visible { outline: 2px solid var(--c-purple); outline-offset: 2px; }
.sl__more[hidden] { display: none; }

/* ── Featured (open) styling for /symbol-keyboard/ ── */
.sl[data-symbols-open="true"] .sl__disclosure {
    border-color: rgba(168, 85, 247, 0.35);
    box-shadow: 0 0 0 1px rgba(168, 85, 247, 0.12), 0 8px 30px rgba(168, 85, 247, 0.08);
}
.sl[data-symbols-open="true"] .sl__summary {
    border-bottom: 2px solid transparent;
    border-image: var(--grad-brand) 1;
}
/* Featured pages promise 1000+ — show ~6 rows before scroll. */
.sl[data-symbols-open="true"] .sl__grid { min-height: 420px; }

/* ── Entry fade (cheap; applied to the grid container, NOT per-tile) ── */
.sl__grid { animation: slFadeIn var(--t-base) both; }
@keyframes slFadeIn {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* ── Mobile ── */
@media (max-width: 600px) {
    /* Drop the costly full-surface blur on mid-tier mobile GPUs (perf). */
    .sl__disclosure { backdrop-filter: none; -webkit-backdrop-filter: none; }
    /* 16px prevents iOS Safari from zooming the viewport on input focus. */
    .sl__search { font-size: 16px; }
    .sl__grid {
        grid-template-columns: repeat(auto-fill, minmax(58px, 1fr));
        min-height: 320px;
    }
    .sl__empty { min-height: 320px; }
    .sl[data-symbols-open="true"] .sl__grid { min-height: 460px; }
    .sl__tile { min-height: 52px; }
    .sl__tile-char { font-size: 1.35rem; }
    /* Kaomoji: span 4 narrower columns so the face isn't crushed. */
    .sl__tile--wide { grid-column: span 4; }
    .sl__tile--wide .sl__tile-char {
        font-size: 0.95rem;
        /* Long faces (up to 12 codepoints) must not clip mid-face: let them
         * shrink to fit the wide tile rather than truncate behind overflow. */
        white-space: nowrap;
        max-width: 100%;
    }
}

@media (max-width: 380px) {
    /* Keep kaomoji scannable as ~TWO columns instead of a slow full-width
     * single-column list (the 58px grid is ~5 cols at 360px, so span 3 yields
     * two faces per row). This is where the mobile bio audience lives. */
    .sl__tile--wide { grid-column: span 3; }
    .sl__tile--wide .sl__tile-char { font-size: 0.9rem; }
}

/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
    .sl__grid { animation: none; }
    .sl__tile--pop { animation: none; }   /* JS already gates this; belt-and-braces */
    .sl__tile:hover,
    .sl__chip:hover { transform: none; }
    .sl__summary-chevron { transition: none; }
}
