/* ═══════════════════════════════════════════════════════════════
   XES — lobby page styles (/lobby.html)
   Two-column app layout: left action panel + right slide out panel.
   ═══════════════════════════════════════════════════════════════ */

body {
    display: flex;
    flex-direction: column;
    height: 100vh;
    overflow: hidden;
    /* Static lobby backdrop (replaces the old animated background engine). */
    background: #0b0f1a url('/bg.png') center / cover no-repeat fixed;
}

.app-layout {
    display: flex;
    flex: 1;
    overflow: hidden;
    gap: 0;
}

/* ── Left Panel ── */
.panel-left {
    width: 360px;
    min-width: 300px;
    max-width: 400px;
    flex-shrink: 0;
    position: relative;
    overflow-y: auto;
    padding: 34px 28px 20px;   /* a little drop from the top bar */
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 18px;
    border-right: 1px solid rgba(255,255,255,0.05);
    scrollbar-width: thin;
    scrollbar-color: var(--dark-border) transparent;
    isolation: isolate;     /* contains the .panel-brand z-index:-1 watermark */
}

/* Faint XES bubble watermark — lower-left, behind the panel content
   (z-index:-1 within the isolated .panel-left, above the static body bg). */
.panel-brand {
    position: absolute;
    bottom: 18px;
    left: -14px;
    width: 250px;
    height: auto;
    opacity: 0.3;
    pointer-events: none;
    z-index: -1;
    user-select: none;
}

/* ── Avatar top controls — Add Friend / History pinned to the panel's top
   corners (a row across the top of the box; the circle sits below). ── */
/* Add Friend + History now flank the speaker (mid-height), each a labelled
   action button like Call/Mute/Games — the call-box "ring" from the brief. */
.avatar-cluster {
    width: 100%;
    display: flex;
    justify-content: center;
    position: relative;
}
.speaker-row {
    position: relative;
    z-index: 1;                       /* above the sound-wave behind it */
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
}

/* Decorative sound-wave emanating from behind the buttons. The path itself is
   generated (lightly random) per page-load by js/callwaves.js, so it's smooth
   but a touch different each visit, and costs nothing after first paint. */
.call-wave {
    position: absolute;
    left: 50%; top: 50%;
    transform: translate(-50%, calc(-50% + 6px));
    width: 100vw; height: 80px;         /* spans the whole window; matches the JS viewBox */
    z-index: 0;
    pointer-events: none;
    overflow: visible;
    filter: drop-shadow(0 0 3px rgba(255,255,255,0.18));
    /* The wave is now the "Waves" background preset — shown only when it's
       picked (it's the default). opacity (not display) keeps it laid out so
       callwaves.js can still measure its width to build the dots. */
    opacity: 1;
    transition: opacity 0.3s ease;
}
/* Layouts where the call box is a bounded panel (centred / social / chat) keep the
   wave inside that panel — otherwise the 100vw wave spills over the chat / DM boxes
   beside it and turns the panel into a sideways scroller. Only the quiet layout (a
   lone centred column) lets it span the window. callwaves.js refits the dots to the
   new width via a ResizeObserver. */
.app-layout[data-layout="centred"] .call-wave,
.app-layout[data-layout="social"] .call-wave { width: 100%; }
/* In the quiet + centred layouts the call box doesn't need its own scrollbar, so
   let the full-width wave (and the watermark) spill past it instead of turning the
   panel into a sideways scroller — overflow-y:auto silently promotes overflow-x to
   auto, and the 100vw wave then makes the column scroll left/right. The app-layout
   (overflow:hidden) still clips the spill at the window edge, so the waves preset
   renders exactly as before. */
.app-layout[data-layout="quiet"] .panel-left,
.app-layout[data-layout="social"] .panel-left,
.app-layout[data-layout="centred"] .panel-left { overflow: visible; }
.circle-side-btn {
    flex-shrink: 0;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(13, 15, 22, 0.92);
    border: 1.5px solid rgba(255, 255, 255, 0.14);
    color: var(--text-primary);
    cursor: pointer;
    transition: background 0.2s, border-color 0.2s, transform 0.15s;
}
.circle-side-btn:hover:not(:disabled) {
    background: rgba(255, 255, 255, 0.12);
    border-color: rgba(255, 255, 255, 0.22);
}
.circle-side-btn:active:not(:disabled) { transform: scale(0.93); }
.circle-side-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.circle-side-btn svg { width: 22px; height: 22px; }
/* ── Add Friend + History flank buttons (square, smaller) ──
   Add Friend = rose, History = vivid blue — matching the call-box theme and the
   pink-left / blue-right speaker glow. */
.action-btn.btn-addfriend, .action-btn.btn-history {
    width: 38px; height: 38px;
    background: transparent;
    border: 2px solid rgba(255,255,255,0.9);   /* beats .action-btn{border:none} */
    color: #fff;
    border-radius: 6px;   /* override .action-btn's 50% to make them square */
}
.action-btn.btn-addfriend svg, .action-btn.btn-history svg { width: 18px; height: 18px; }
/* Hover keeps the button hollow — only the border + a soft glow take the colour. */
.btn-addfriend:hover:not(:disabled) {
    border-color: #f43f5e;
    box-shadow: 0 0 13px rgba(244,63,94,0.5);
}
.btn-history:hover:not(:disabled) {
    border-color: #3b82f6;
    box-shadow: 0 0 13px rgba(59,130,246,0.5);
}
#add-friend-btn:disabled { opacity: 1; cursor: default; }   /* outline stays crisp when inactive */

/* ── Nav Brand Logo — hero font styling ── */
.nav-brand {
    font-family: "Bungee", Impact, system-ui, sans-serif;
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: .07em;
    color: var(--text);
    text-shadow: 0 0 26px rgba(59, 130, 246, 0.35);
    line-height: 1;
    white-space: nowrap;
}
/* Staff buttons in the left stack — mods see Moderation (amber), admins also
   get Admin below it (a brighter gold so the two are distinct). Shown by
   admin.js refreshNav. */

/* ── Action Buttons Row (Call + Mute, kept toward the middle) ── */
.action-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 14px;
    width: 100%;
    margin-top: 8px;
    /* Sit above the absolute side-button overlay (z-index 6) so Call/Mute always
       win taps on mobile; the row's empty space stays click-through so it never
       blocks the side buttons. */
    position: relative;
    z-index: 10;
    pointer-events: none;
}
.action-row .action-btn-wrap { pointer-events: auto; }

.action-btn-wrap {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
}

.action-btn {
    border: none;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.2s ease;
}

.action-btn svg { width: 28px; height: 28px; flex-shrink: 0; }
.action-btn:active            { transform: scale(0.93); }
.action-btn:disabled          { opacity: 0.35; cursor: not-allowed; }
.action-btn:disabled:active   { transform: none; }

/* Call button — same size as the secondary buttons, green colour. */
.btn-call {
    width: 56px;
    height: 56px;
    background: #149845;          /* close to the original, a touch deeper */
    box-shadow: 0 4px 20px rgba(34,197,94,0.5);
    color: #fff;
}
.btn-call:hover:not(:disabled) {
    background: #137c3a;
    box-shadow: 0 6px 28px rgba(34,197,94,0.65);
}

.btn-call.btn-call-searching {
    background: #f59e0b;
    box-shadow: 0 4px 20px rgba(245,158,11,0.5);
    animation: callPulse 1.2s ease-in-out infinite;
}

.btn-call.btn-call-active {
    background: var(--danger);
    box-shadow: 0 4px 20px rgba(255,71,87,0.5);
}
.btn-call.btn-call-active:hover { background: #e8384a; }

/* Mute / Friend / Room — medium secondary buttons */
.btn-secondary {
    width: 56px;
    height: 56px;
    background: #24262f;          /* solid dark grey */
    border: 1.5px solid rgba(255,255,255,0.15);
    color: var(--text-primary);
}
.btn-secondary:hover:not(:disabled) {
    background: #33363f;
    border-color: rgba(255,255,255,0.28);
}
.btn-secondary.muted {
    background: rgba(255,71,87,0.18);
    border-color: var(--danger);
    color: var(--danger);
}

/* Mute (mic) button — beside Call, same size, transparent (just the icon).
   The icon turns red when muted (see .btn-mute.muted in activity.css). */
.btn-mute {
    width: 56px;
    height: 56px;
    background: none;
    color: #fff;
}
.btn-mute svg { width: 30px; height: 30px; }

.action-label {
    font-size: 0.75rem;
    color: #fff;
    font-weight: 500;
}

/* ── Call Options Wrapper (flanking buttons + presets row) ── */
.call-options-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Outer gap (4px) + the row's own 6px side padding = 10px each side, matching
       the 10px gap between the two cogs — so all four buttons are evenly spaced. */
    gap: 4px;
    width: 100%;
    margin-top: 8px;
    position: relative;
    z-index: 10;
    pointer-events: none;
}
.call-options-wrapper .action-btn {
    pointer-events: auto;
}

/* ── Call Options Row ── */
.call-options-row {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 0.8rem;
    color: var(--text-secondary);
    flex-wrap: wrap;
    justify-content: center;
    pointer-events: auto;
}

/* Toggle tracks: a defined dark fill (inset outline, no layout shift) so the
   call-option controls don't wash out over bright backgrounds like the cloud preset. */
.call-options-row .pill-track {
    background: var(--deep-blue);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.16);
}


/* ── Call Hint ── */
.call-hint {
    font-size: 0.85rem;
    color: #fff;
    text-align: center;
}

/* Status hint row: a small spinning die (left) + the hint pill, one line. */
.call-hint-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: fit-content;
    max-width: 100%;
    margin: 0 auto;
}
/* The die: shown only while searching.  Rotation is driven by HintDieSpinner
   in app.js (rAF) rather than a CSS @keyframes — see the comment on .dice in
   activity.css for why. */
.hint-die {
    display: none;
    position: relative;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}
.call-hint-row.searching .hint-die { display: block; }
.hint-die .hint-die-stage {
    position: absolute;
    inset: 0;
    perspective: 160px;
}
.hint-die .dice {
    position: absolute;
    inset: 0;
    margin: auto;
    width: var(--size);
    height: var(--size);
    --size: 14px;
}
.hint-die .dice-face { padding: 1px; gap: 1px; }
.hint-die .dice-face .dot { width: 3px; height: 3px; }

/* Chat text box → translucent black so it reads as a solid field over the
   animated background. Lobby-only override (room.html doesn't load this file);
   the .drag-over and :focus states keep their own higher-specificity styling. */
.chat-text-input {
    background: rgba(0,0,0,0.4);
}

/* No box behind the call controls — they sit directly on the static backdrop;
   the text-shadow (below) keeps the labels + hint legible over the photo. */
.call-options-row,
.call-hint {
    padding: 7px 16px;
    color: #fff;
}
/* Tighter side padding on the cog box so the outer buttons (add-friend / history)
   sit an even 10px from the cogs — see .call-options-wrapper gap. The cogs' own
   spacing is untouched. (Overrides the shared .call-hint padding above.) */
.call-options-row { padding-left: 6px; padding-right: 6px; }
/* The bottom hint hugs its text — tightest box, ~1px off the content (all presets). */
.call-hint { padding: 2px 11px; }
/* Static /bg.png backdrop — give the lobby control text a soft shadow so it
   stays legible over an arbitrary photo. */
.call-options-row,
.call-hint,
.action-label {
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.85);
}

.hint-em {
    color: #fff;
    font-style: normal;
    font-weight: 600;
}

/* The "Connected — you're live" status text. Greens up while in a call. */
.hint-live {
    color: #4ade80;
    font-weight: 300;
    font-family: "Exo 2", sans-serif;
    letter-spacing: 0.04em;
    font-size: 0.8rem;
}
/* Partner avatar + flat flag sit before the "Connected!" text (avatar, then flag). */
.hint-avatar {
    display: inline-block;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    overflow: hidden;
    background: #161a26;
    vertical-align: middle;
    margin-right: 6px;
}
.hint-avatar:empty { display: none; }
.hint-avatar .av-img { width: 100%; height: 100%; display: block; }
/* flag-icons span is 1.333em wide — a modest font-size keeps the flag compact. */
.hint-flag {
    display: inline-block;
    font-size: 0.95rem;
    line-height: 1;
    vertical-align: middle;
    margin-right: 6px;
}
.hint-flag:empty { display: none; }

/* ── Trust level badge shown next to the partner's name ── */
.partner-level-badge {
    display: inline-flex;
    gap: 4px;
    margin-left: 6px;
    vertical-align: middle;
}
.trust-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1.4;
    border: 1px solid transparent;
}
.trust-badge.trust-new {
    background: rgba(139, 92, 246, 0.15);
    color: #c4b5fd;
    border-color: rgba(139, 92, 246, 0.4);
}
.trust-badge.trust-level {
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    border-color: rgba(255, 255, 255, 0.08);
}
.trust-badge.trust-guest {
    background: rgba(245, 158, 11, 0.15);
    color: #fcd34d;
    border-color: rgba(245, 158, 11, 0.4);
}

/* ── Guidelines ── */
.guidelines-box      { width: 100%; padding-top: 4px; }
.guidelines-box h4   { font-size: 0.95rem; font-weight: 700; color: var(--text-primary); margin-bottom: 10px; }
.guidelines-box ul   { list-style: disc; padding-left: 18px; display: flex; flex-direction: column; gap: 5px; }
.guidelines-box li   { font-size: 0.82rem; color: var(--text-secondary); line-height: 1.4; }

.moderation-notice {
    font-size: 0.78rem;
    color: #f87171;
    font-weight: 500;
    text-align: center;
    line-height: 1.4;
    padding: 0 4px;
}

/* ── Chat column (wraps message list, announcement, and input strip) ── */
.chat-area {
    flex: 1;
    min-width: 0;
    min-height: 0;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #0d0f14;
    border: 1px solid rgba(255,255,255,0.07);
}


.chat-area-messages {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 12px 2px;
    scrollbar-width: thin;
    scrollbar-color: rgba(255,255,255,0.2) transparent;
    overscroll-behavior: contain;
}
.chat-area-messages::-webkit-scrollbar { width: 6px; }
.chat-area-messages::-webkit-scrollbar-track { background: transparent; }
.chat-area-messages::-webkit-scrollbar-thumb {
    background: rgba(255,255,255,0.2);
    border-radius: 3px;
}
.chat-area-messages::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.35); }
@media (hover: none) and (pointer: coarse) {
    .chat-area-messages { scrollbar-width: none; }
    .chat-area-messages::-webkit-scrollbar { display: none; }
}
/* Stack chat messages from the bottom so newest are visible. The
   announcement (when present) sticks to the top instead, so it pushes
   margin-top:auto onto the next sibling. */
.chat-area-messages > :first-child:not(.lobby-announcement) { margin-top: auto; }
.chat-area-messages > .lobby-announcement + * { margin-top: auto; }

/* Admin broadcast card. Lives inside #chat-messages as a flow item so
   it scrolls off naturally as messages pile up; centred, capped width. */
/* Admin broadcast — a terminal/ASCII card matching the call-time bio box
   (monospace, thin frame, no coloured quote bar). Keeps the logo + "admin"
   header; the body sits in its own monospace frame with links still live. */
.lobby-announcement {
    align-self: stretch;
    width: 100%;
    margin: 12px 0 0;
    background: rgba(10, 12, 20, 0.9);
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 6px;
    padding: 14px 8px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    flex-shrink: 0;
}
.lobby-announcement.hidden { display: none; }
.lobby-announcement-head {
    display: flex;
    align-items: center;
    gap: 12px;
}
.lobby-announcement-remove {
    margin-left: auto;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.15);
    color: var(--text-secondary);
    width: 24px;
    height: 24px;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.85rem;
    line-height: 1;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    flex-shrink: 0;
}
.lobby-announcement-remove:hover {
    background: rgba(225, 84, 84, 0.18);
    border-color: rgba(225, 84, 84, 0.5);
    color: #fff;
}
.lobby-announcement-logo {
    width: 36px;
    height: 36px;
    object-fit: contain;
    flex-shrink: 0;
}
.lobby-announcement-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}
.lobby-announcement-sender {
    font-family: 'Space Mono', ui-monospace, monospace;
    font-weight: 700;
    font-size: 0.9rem;
    color: var(--text-primary);
    letter-spacing: 0.02em;
}
.lobby-announcement-time {
    font-family: 'Space Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.08em;
}
.lobby-announcement-body {
    font-family: 'Space Mono', ui-monospace, monospace;
    color: var(--text-primary);
    font-size: 0.82rem;
    line-height: 1.55;
    white-space: pre-wrap;
    word-wrap: break-word;
}
@media (max-width: 600px) {
    .lobby-announcement {
        width: 100%;
        margin: 8px 0 0;
        padding: 12px 8px;
    }
    .lobby-announcement-logo { width: 30px; height: 30px; }
}

/* New-user skip help — progressive coaching card shown when a user rapidly
   skips calls (tier 1 = short nudge, tier 2 = the full filter explanation). */
.skip-help {
    position: fixed;
    inset: 0;
    z-index: 4000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.55);
    backdrop-filter: blur(3px);
    animation: skip-help-fade 0.16s ease-out;
}
.skip-help.hidden { display: none; }
@keyframes skip-help-fade { from { opacity: 0; } to { opacity: 1; } }
.skip-help-card {
    position: relative;
    width: 100%;
    max-width: 420px;
    background: rgba(14, 17, 28, 0.98);
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 14px;
    padding: 22px 22px 20px;
    box-shadow: 0 24px 70px rgba(0, 0, 0, 0.6);
}
.skip-help-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 10px;
    padding-right: 24px;
}
.skip-help-body {
    font-size: 0.9rem;
    line-height: 1.55;
    color: var(--text-secondary);
}
.skip-help-body strong { color: var(--text-primary); }
.skip-help-body em { font-style: italic; color: var(--text-primary); }
.skip-help-body a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; }
.skip-help-ok {
    margin-top: 18px;
    width: 100%;
    padding: 10px;
    border: none;
    border-radius: 9px;
    background: var(--deep-blue);
    color: #fff;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: filter 0.15s;
}
.skip-help-ok:hover { filter: brightness(1.12); }
.skip-help-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 6px;
    background: rgba(255, 255, 255, 0.06);
    color: var(--text-secondary);
    font-size: 0.8rem;
    line-height: 1;
    cursor: pointer;
    transition: background 0.14s, color 0.14s;
}
.skip-help-close:hover { background: rgba(255, 255, 255, 0.12); color: var(--text-primary); }

/* ── Responsive ── */
@media (max-width: 800px) {
    html { overflow: hidden; height: 100dvh; }
    /* `height: 100dvh` alone isn't enough — the global `min-height: 100vh`
       from styles.css wins on mobile when the URL bar is showing (vh =
       largest viewport, dvh = current). Body silently grows past the
       visible region and the chat-strip ends up behind the URL bar.
       Set min-height explicitly to keep body inside the visible viewport. */
    body { height: 100dvh; min-height: 100dvh; }

    .app-layout { flex-direction: column; }

    .panel-left {
        width: 100%;
        max-width: 100%;
        min-width: 0;
        padding: 16px;
        gap: 12px;
        border-right: none;
        border-bottom: 1px solid rgba(255,255,255,0.05);
        /* Top box takes whatever height its content needs; chat-area
           below uses flex:1 to fill what's left. No scroll on panel-left. */
        flex-shrink: 0;
    }

    /* The big primary buttons (Call / Games) — shrink them + the gap to fit narrow phones. */
    .btn-call, .btn-secondary, .btn-mute { width: 50px; height: 50px; }
    /* The flank buttons sit beside the 36px cogs — keep them close to that size
       (not 50px) with a fuller icon so they don't read as oversized + empty. */
    .action-btn.btn-addfriend, .action-btn.btn-history { width: 40px; height: 40px; }
    .action-btn.btn-addfriend svg, .action-btn.btn-history svg { width: 21px; height: 21px; }
    .circle-side-btn { width: 42px; height: 42px; }
    .action-row { gap: 8px; }

    .guidelines-box    { display: none; }
    .moderation-notice { display: none; }

    .chat-area { flex: 1; min-height: 0; }

    /* On mobile the panel-left scrolls and is easy to miss, so float the
       post-call rate strip just above the chat input instead. */
    .rate-inline {
        position: fixed;
        bottom: calc(72px + env(safe-area-inset-bottom, 0px));
        left: 12px;
        right: 12px;
        width: auto; /* clear the base width:100% so left/right define the box (was overhanging the right edge) */
        z-index: 140;
        background: #1a1c25;
        border-color: rgba(255, 255, 255, 0.1);
        box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.55);
    }
}

/* ── Game Picker Modal ── */
.game-picker-drawer .side-drawer-head {
    border-bottom: 1px solid rgba(var(--primary-rgb), 0.18);
}

/* Out-of-call banner — explains solo mode + offers the Solo / Invite toggle. */
.game-mode-banner {
    background: rgba(var(--primary-rgb), 0.06);
    border: 1px solid rgba(var(--primary-rgb), 0.22);
    border-radius: 8px;
    padding: 12px 14px;
    margin-bottom: 12px;
}
.game-mode-banner.hidden { display: none; }
.game-mode-banner-text {
    font-size: 0.82rem;
    color: var(--text-secondary);
    line-height: 1.45;
    margin: 0;
    text-align: center;
}
.game-mode-banner-text strong { color: var(--text-primary); }

.game-picker-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
}

/* Each game is a tile plus (out of a call) its own Solo / Invite buttons. */
.game-picker-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.game-picker-actions {
    display: flex;
    gap: 6px;
}
.game-picker-action {
    flex: 1;
    padding: 6px 8px;
    font-size: 0.72rem;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    border-radius: 6px;
    cursor: pointer;
    border: 1px solid rgba(var(--primary-rgb), 0.3);
    background: rgba(var(--primary-rgb), 0.06);
    color: var(--text-primary);
    transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.game-picker-action:hover { background: rgba(var(--primary-rgb), 0.16); border-color: rgba(var(--primary-rgb), 0.5); }
.game-picker-action:active { transform: scale(0.97); }

.game-picker-card {
    display: block;
    position: relative;
    aspect-ratio: 320 / 190;       /* matches the landscape icon image aspect */
    padding: 0;
    background: rgba(var(--primary-rgb), 0.05);
    border: 1px solid rgba(var(--primary-rgb), 0.2);
    border-radius: 0;
    color: var(--text-primary);
    cursor: pointer;
    overflow: hidden;
    transition: background 0.15s, border-color 0.15s, transform 0.12s;
}
.game-picker-card:hover {
    background: rgba(var(--primary-rgb), 0.14);
    border-color: rgba(var(--primary-rgb), 0.5);
}
.game-picker-card:active { transform: scale(0.97); }

/* During an invite the picker locks all cards and the chosen one shows a
 * spinning ring overlay so the user knows we're waiting for the partner. */
.game-picker-list.inviting .game-picker-card:not(.waiting) { opacity: 0.4; }
.game-picker-card.waiting { position: relative; cursor: progress; }
.game-picker-card.waiting::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 56px;
    height: 56px;
    margin: -28px 0 0 -28px;
    border-radius: 50%;
    border: 3px solid rgba(var(--primary-rgb), 0.18);
    border-top-color: rgba(var(--primary-rgb), 0.95);
    animation: game-invite-spin 0.9s linear infinite;
    pointer-events: none;
}
.game-picker-card.waiting .game-picker-icon { opacity: 0.45; }
@keyframes game-invite-spin {
    to { transform: rotate(360deg); }
}

/* Emoji fallback (used only if iconImg is missing) */
.game-picker-icon {
    font-size: 2rem;
    line-height: 1;
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* When the icon is an image, fill the whole card */
.game-picker-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* Pacman PNG runs too wide visually — inset it 20px horiz / 1px vert.
   Card background is forced black so the gutters around the image show
   as pacman-arcade black. */
.game-picker-card[data-game-id="pacman"] { background: #000; }
.game-picker-card[data-game-id="pacman"] .game-picker-img {
    width: calc(100% - 40px);
    height: calc(100% - 2px);
    margin: 1px 20px;
}
/* Game name overlaid at the bottom with a dark gradient for readability */
.game-picker-name {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 18px 8px 8px;
    background: linear-gradient(to top, rgba(0,0,0,0.78) 0%, rgba(0,0,0,0.55) 50%, rgba(0,0,0,0) 100%);
    color: #fff;
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    text-shadow: 0 1px 2px rgba(0,0,0,0.6);
    letter-spacing: 0.02em;
}

/* ── Game Invite Prompt ── */
.game-invite-text {
    font-size: 0.95rem;
    color: var(--text-primary);
    text-align: center;
    margin: 6px 0;
}
.game-invite-footer { gap: 10px; }

/* ── Game Overlay (covers the whole viewport while a game is active) ── */
.game-overlay {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: linear-gradient(135deg, #0a0e27 0%, #15161d 100%);
}

/* Floating leave-game X — no header bar, no title */
.game-overlay-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 10;
    width: 38px;
    height: 38px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(var(--primary-rgb), 0.4);
    color: var(--primary);
    cursor: pointer;
    padding: 0;
    border-radius: 50%;
    backdrop-filter: blur(4px);
    transition: background 0.15s, color 0.15s, border-color 0.15s, transform 0.12s, box-shadow 0.15s;
}
.game-overlay-close svg { width: 20px; height: 20px; display: block; }
.game-overlay-close:hover {
    background: var(--primary);
    border-color: var(--primary);
    color: #04181d;
    transform: scale(1.08);
    box-shadow: 0 4px 14px rgba(var(--primary-rgb), 0.4);
}
.game-overlay-close:active { transform: scale(0.96); }

.game-overlay-body {
    position: absolute;
    inset: 0;
    overflow: auto;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 24px 20px 28px;
    /* Still scrollable, but no visible bar — kills the global peach thumb here. */
    scrollbar-width: none;
}
.game-overlay-body::-webkit-scrollbar { display: none; }

@media (max-width: 800px) {
    .game-overlay-close { top: 8px; right: 8px; width: 34px; height: 34px; }
    .game-overlay-body  { padding: 18px 12px 20px; }
}

/* ── Game Invite Card (compact, game prompt on top, actions below) ── */
.game-invite-banner {
    position: fixed;
    top: 70px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    background: linear-gradient(160deg, #14121d 0%, #0a0b12 100%);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-top: 2px solid rgba(var(--primary-rgb), 0.55);
    border-radius: 0;
    box-shadow: 0 18px 50px -10px rgba(0,0,0,0.8);
    z-index: 1500;
    color: var(--text-primary);
    font-family: "Exo 2", sans-serif;
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    animation: slideIn 0.25s ease;
}

.game-invite-title {
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    line-height: 1.2;
    white-space: nowrap;
}
.game-invite-title #game-invite-name {
    color: var(--primary);
    font-weight: 700;
    text-transform: capitalize;
}

.game-invite-actions {
    display: flex;
    gap: 8px;
}

.game-invite-btn {
    padding: 4px 18px;
    border-radius: 0;
    border: 1px solid rgba(255,255,255,0.12);
    font-size: 0.8rem;
    font-weight: 700;
    cursor: pointer;
    transition: var(--transition);
    background: transparent;
    color: var(--text-secondary);
    min-width: 64px;
}

.game-invite-yes {
    background: var(--success);
    color: #000;
    border-color: var(--success);
}
.game-invite-yes:hover { background: #1aff95; }

.game-invite-no:hover { color: var(--text-primary); background: rgba(255,255,255,0.06); }

@media (max-width: 800px) {
    .game-invite-banner { top: 64px; padding: 8px 12px; gap: 6px; }
    .game-invite-title { font-size: 0.8rem; }
}

/* ── Game invite-link modal (host shares a link, waits for a joiner) ── */
.game-share-modal {
    position: fixed;
    inset: 0;
    z-index: 2100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(4, 8, 12, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: fadeIn 0.18s ease;
}
.game-share-modal.hidden { display: none; }

.game-share-card {
    position: relative;
    width: 100%;
    max-width: 420px;
    background: rgba(13, 15, 22, 0.97);
    border: 1px solid rgba(var(--primary-rgb), 0.4);
    border-radius: 12px;
    box-shadow: 0 12px 48px rgba(0,0,0,0.6), 0 0 30px rgba(var(--primary-rgb), 0.14);
    padding: 26px 24px 22px;
    color: var(--text-primary);
}

.game-share-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: 8px;
    background: rgba(255,255,255,0.05);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.game-share-close:hover { background: rgba(255,255,255,0.12); color: var(--text-primary); }

.game-share-title {
    margin: 0 0 8px;
    font-size: 1.1rem;
    font-weight: 700;
    text-align: center;
}
.game-share-title #game-share-game {
    color: var(--primary);
    text-transform: capitalize;
}
.game-share-sub {
    margin: 0 0 18px;
    font-size: 0.84rem;
    color: var(--text-secondary);
    line-height: 1.45;
    text-align: center;
}

.game-share-linkrow {
    display: flex;
    gap: 8px;
    margin-bottom: 16px;
}
.game-share-input {
    flex: 1;
    min-width: 0;
    padding: 10px 12px;
    font-size: 0.82rem;
    border-radius: 8px;
    border: 1px solid rgba(var(--primary-rgb), 0.3);
    background: rgba(0,0,0,0.35);
    color: var(--text-primary);
    font-family: inherit;
}
.game-share-input:focus { outline: none; border-color: var(--primary); }
.game-share-copy {
    flex: 0 0 auto;
    padding: 10px 18px;
    font-size: 0.82rem;
    font-weight: 700;
    border-radius: 8px;
    border: 1px solid var(--primary, var(--primary));
    background: var(--primary, var(--primary));
    color: #04181d;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s, opacity 0.15s;
}
.game-share-copy:hover { background: #2ee6ff; }
.game-share-copy:active { transform: scale(0.97); }
.game-share-copy:disabled { opacity: 0.45; cursor: default; }

.game-share-waiting {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    font-size: 0.82rem;
    color: var(--text-secondary);
}
.game-share-spinner {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    border: 2px solid rgba(var(--primary-rgb), 0.25);
    border-top-color: var(--primary, var(--primary));
    animation: gs-spin 0.8s linear infinite;
}
@keyframes gs-spin { to { transform: rotate(360deg); } }

@media (max-width: 800px) {
    .game-share-card { padding: 24px 18px 20px; }
    .game-share-title { font-size: 1rem; }
}

/* ── Opponent-reconnecting notice (floats over a live invite-link game) ── */
.game-reconnect-notice {
    position: absolute;
    top: 14px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 12;
    display: flex;
    align-items: center;
    gap: 9px;
    padding: 8px 16px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--text-primary);
    background: rgba(13, 15, 22, 0.95);
    border: 1px solid rgba(var(--primary-rgb), 0.4);
    border-radius: 999px;
    box-shadow: 0 6px 22px rgba(0,0,0,0.5);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    animation: fadeIn 0.18s ease;
}
.game-reconnect-notice.hidden { display: none; }
.game-reconnect-spinner {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: 2px solid rgba(var(--primary-rgb), 0.25);
    border-top-color: var(--primary, var(--primary));
    animation: gs-spin 0.8s linear infinite;
}

/* ── Invite-link landing (what a ?play= visitor sees first) ── */
.game-join-card { text-align: center; }
.game-join-emoji {
    font-size: 2.6rem;
    line-height: 1;
    margin-bottom: 10px;
}
.game-join-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 6px;
}
.game-join-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    width: 100%;
    padding: 13px 16px;
    font-size: 0.95rem;
    font-weight: 700;
    border-radius: 10px;
    cursor: pointer;
    transition: background 0.15s, transform 0.1s, border-color 0.15s;
}
.game-join-btn svg { width: 18px; height: 18px; }
.game-join-primary {
    border: 1px solid var(--primary, var(--primary));
    background: var(--primary, var(--primary));
    color: #04181d;
}
.game-join-primary:hover { background: #2ee6ff; }
.game-join-secondary {
    border: 1px solid rgba(var(--primary-rgb), 0.4);
    background: rgba(var(--primary-rgb), 0.07);
    color: var(--text-primary);
}
.game-join-secondary:hover { background: rgba(var(--primary-rgb), 0.16); }
.game-join-btn:active { transform: scale(0.98); }
.game-join-fineprint {
    margin: 14px 0 0;
    font-size: 0.72rem;
    color: var(--text-secondary);
    opacity: 0.85;
}

/* ── Voice pill (over an invite game with audio chat) ── */
.game-voice-pill {
    position: absolute;
    top: 14px;
    left: 14px;
    z-index: 12;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--text-primary);
    background: rgba(13, 15, 22, 0.95);
    border: 1px solid rgba(var(--primary-rgb), 0.4);
    border-radius: 999px;
    box-shadow: 0 6px 22px rgba(0,0,0,0.5);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, transform 0.1s;
    animation: fadeIn 0.18s ease;
}
.game-voice-pill.hidden { display: none; }
.game-voice-pill:active { transform: scale(0.97); }
.game-voice-pill .game-voice-mic { width: 15px; height: 15px; display: none; }
.game-voice-pill .game-voice-spinner {
    width: 13px; height: 13px; border-radius: 50%;
    border: 2px solid rgba(var(--primary-rgb), 0.25);
    border-top-color: var(--primary, var(--primary));
    animation: gs-spin 0.8s linear infinite;
    display: none;
}
/* connecting → spinner; live → mic icon; muted → red mic + dim */
.game-voice-pill.connecting .game-voice-spinner { display: inline-block; }
.game-voice-pill.live { border-color: rgba(46, 230, 137, 0.55); }
.game-voice-pill.live .game-voice-mic { display: inline-block; color: #2ee689; }
.game-voice-pill.live.muted { border-color: rgba(255, 71, 87, 0.6); }
.game-voice-pill.live.muted .game-voice-mic { color: #ff4757; }
.game-voice-pill.failed { opacity: 0.7; cursor: default; }

@media (max-width: 800px) {
    .game-voice-pill { top: 10px; left: 10px; padding: 7px 12px; font-size: 0.75rem; }
}

/* ═══════════════════════════════════════════════════════════════
   Side drawers (Filters, Friends) — slide in from the right
   ═══════════════════════════════════════════════════════════════ */

.drawer-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.45);
    z-index: 1199;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
}
.drawer-backdrop.show {
    opacity: 1;
    pointer-events: auto;
}

.side-drawer {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 440px;
    max-width: 92vw;
    background: #0a0c14;
    border-left: 1px solid rgba(255,255,255,0.06);
    /* Shadow only when the drawer is actually open. With it on at all
       times, the box-shadow leaks ~56px back across the right edge of
       the viewport even though `translateX(100%)` has moved the drawer
       itself off-screen — that's the blurred right-edge halo. */
    box-shadow: none;
    z-index: 1200;
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.28s ease;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.side-drawer.open {
    transform: translateX(0);
    box-shadow: -16px 0 40px rgba(0,0,0,0.6);
}
/* Carousel between menu tabs: the outgoing panel slides off to the LEFT while
   the incoming one slides in from the right, so they never cross over (no flash
   of the background between them). */
.side-drawer.menu-exit {
    transform: translateX(-100%);
}
/* Clipping viewport for the menu carousel. The menu drawers live inside (as
   absolute children) and slide within it, so the exiting panel is clipped at
   the panel's left edge rather than showing mid-screen on desktop. */
.menu-stack {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: 440px;
    max-width: 92vw;
    overflow: hidden;
    z-index: 1200;
    pointer-events: none;          /* click-through to the lobby when closed */
    box-shadow: none;
    transition: box-shadow 0.28s ease;
}
.menu-stack.open {
    pointer-events: auto;
    box-shadow: -16px 0 40px rgba(0, 0, 0, 0.6);
}
.menu-stack .side-drawer {
    position: absolute;
    inset: 0;
    width: 100%;
    max-width: none;
    z-index: auto;
}
.menu-stack .side-drawer.open { box-shadow: none; }

.side-drawer-head {
    position: relative;
    padding: 18px 18px 14px;
    flex-shrink: 0;
    border-bottom: 1px solid rgba(95, 115, 255, 0.18);
}

.side-drawer-close {
    position: absolute;
    top: 10px;
    right: 12px;
    background: transparent;
    border: none;
    color: var(--text-secondary);
    font-size: 1.1rem;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 6px;
    line-height: 1;
    z-index: 2;
    transition: background 0.15s, color 0.15s;
}
.side-drawer-close:hover {
    background: rgba(255,255,255,0.08);
    color: var(--text-primary);
}

.side-drawer-body {
    flex: 1;
    overflow-y: auto;
    padding: 8px 18px 24px;
    scrollbar-width: thin;
}

/* Drawer scrollbars: dark-grey + non-intrusive, overriding the global brand-cyan
   thumb (styles.css) so the slide-out panels don't get a bright blue bar. */
.side-drawer-body,
.dm-body {
    scrollbar-color: var(--dark-border) transparent;
}
/* When the dm-dock is hosting #chat-area (Call mode) the body must pass its
   height through so the chat-area's flex column works — messages fill the
   middle, input pins to the bottom. */
.dm-body.dm-call-chat {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
    padding: 0;
}
.dm-body.dm-call-chat #chat-area {
    flex: 1;
    min-height: 0;
    border: none;
    background: transparent;
}
.side-drawer-body::-webkit-scrollbar-track,
.dm-body::-webkit-scrollbar-track { background: transparent; }
.side-drawer-body::-webkit-scrollbar-thumb,
.dm-body::-webkit-scrollbar-thumb { background: var(--dark-border); }
.side-drawer-body::-webkit-scrollbar-thumb:hover,
.dm-body::-webkit-scrollbar-thumb:hover { background: #3a3e4d; }

/* ── Side-drawer typography (shared, applies to filters/friends/history/games) ── */
.side-drawer {
    font-family: "Exo 2", -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}

/* ── Filters drawer ── */
.filter-section { margin-top: 26px; }
.filter-section:first-of-type { margin-top: 0; }

.filter-h {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: "Exo 2", "Exo 2", sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    letter-spacing: 0.18em;
    color: var(--text-primary);
    text-transform: uppercase;
    margin-bottom: 12px;
}

.filter-icon { font-size: 1.1rem; }

.filter-sublabel {
    color: var(--text-secondary);
    font-size: 0.85rem;
    font-style: italic;
    margin: 0 0 14px;
}

/* Earned gender filter — locked state for users below the trust bar. */
.filter-section.filter-locked .radio-row {
    opacity: 0.45;
    cursor: not-allowed;
}
.filter-locked-note {
    margin: 8px 0 0;
    padding: 8px 10px;
    font-size: 0.8rem;
    line-height: 1.4;
    color: #fde68a;
    background: rgba(252, 211, 77, 0.1);
    border: 1px solid rgba(252, 211, 77, 0.25);
    border-radius: 8px;
}

.radio-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 14px;
    margin: 2px 0;
    border-radius: 10px;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 0.95rem;
    user-select: none;
    transition: background 0.15s;
}
.radio-row:hover { background: rgba(255, 255, 255, 0.05); }
.radio-row:has(input[type="radio"]:checked) {
    background: linear-gradient(90deg, rgba(var(--primary-rgb), 0.10), rgba(108, 99, 255, 0.08) 80%);
}
.radio-row input[type="radio"] {
    appearance: none;
    -webkit-appearance: none;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(255,255,255,0.30);
    border-radius: 50%;
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
    transition: border-color 0.15s;
}
.radio-row input[type="radio"]:checked {
    border-color: rgba(255, 255, 255, 0.85);
}
.radio-row input[type="radio"]:checked::after {
    content: '';
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #fff;
}

.gender-symbol {
    font-weight: 700;
    margin-left: 2px;
}
.gender-symbol.female    { color: #ff7ad9; }
.gender-symbol.male      { color: #4ea8ff; }
.gender-symbol.nonbinary { color: #b794f4; }

.chips-input {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    padding: 12px 14px;
    margin-bottom: 10px;
    transition: border-color 0.18s;
}
.chips-input:focus-within {
    border-color: rgba(255, 255, 255, 0.3);
}

.chips-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 6px;
}
.chips-wrap:empty { margin-bottom: 0; }

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(255, 255, 255, 0.14);
    color: var(--text-primary);
    padding: 5px 8px 5px 10px;
    border-radius: 7px;
    font-size: 0.82rem;
    font-weight: 600;
    line-height: 1.15;
}
.chip-flag { font-size: 1rem; line-height: 1; flex-shrink: 0; }
/* Interests — a stable colour per tag (hue set inline by _hueFor). */
.chip-interest {
    background: hsla(var(--chip-hue), 60%, 48%, 0.18);
    border-color: hsla(var(--chip-hue), 70%, 62%, 0.5);
    color: hsl(var(--chip-hue), 85%, 80%);
}
.chip-interest .chip-x { color: hsl(var(--chip-hue), 80%, 82%); }
/* Avoided countries — same flag, a red wash so it reads as "skip". */
[data-chip-field="excluded-countries"] .chip {
    background: rgba(225, 70, 70, 0.12);
    border-color: rgba(225, 95, 95, 0.4);
}
.chip-x {
    background: transparent;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 1rem;
    padding: 0 4px;
    line-height: 1;
}
.chip-x:hover { color: #fff; }

.chips-text {
    width: 100%;
    background: transparent;
    border: none;
    color: var(--text-primary);
    font-size: 0.95rem;
    outline: none;
    padding: 2px 0;
}
.chips-text::placeholder {
    color: rgba(255, 255, 255, 0.45);
    font-size: 0.95rem;
    font-style: italic;
}

/* Filters auto-apply — this is just a quiet confirmation, not a button. */
.filter-status {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 18px;
    margin: 22px auto 6px;
    font-size: 0.84rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--text-secondary);
    opacity: 0;
    transform: translateY(2px);
    transition: opacity 0.3s, transform 0.3s;
    pointer-events: none;
}
.filter-status.show { opacity: 1; transform: none; }
.filter-status svg { width: 15px; height: 15px; }
.filter-status.saved { color: #6fe0a6; }
.filter-status.error { color: #ff8f8f; }

.filter-help {
    margin-top: 22px;
    padding: 14px 16px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 10px;
    color: var(--text-secondary);
    font-size: 0.82rem;
    line-height: 1.55;
}
.filter-help p:last-child { margin-bottom: 0; }
.filter-help p { margin-bottom: 10px; }
.filter-help u { color: var(--text-primary); text-decoration: none; font-weight: 600; }

/* ── Friends drawer ── */
/* Friends panel — sharp style, matching the Video room panel. */
.fr-topbar { display: flex; align-items: center; gap: 8px; padding: 12px 14px; }
/* Filters / Call history / Games: the title bar lives inside .side-drawer-body so
   it scrolls away with the content (like #profile-drawer's heading). Drop its own
   horizontal padding so it lines up with the body's content. */
.side-drawer-body > .fr-topbar { padding: 4px 0 14px; }
.side-drawer-body > .fr-topbar .fr-title-left { padding-left: 0; }
.fr-iconbtn {
    width: 38px; height: 38px; border-radius: 9px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); color: var(--text-secondary);
    cursor: pointer; transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.fr-iconbtn svg { width: 20px; height: 20px; }
.fr-iconbtn:hover { background: rgba(255,255,255,0.1); color: var(--text-primary); }
.fr-close {
    margin-left: auto; flex-shrink: 0;
    width: 38px; height: 38px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.12); color: var(--text-secondary);
    cursor: pointer; transition: background 0.16s, color 0.16s, border-color 0.16s;
}
.fr-close svg { width: 18px; height: 18px; transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); }
.fr-close:hover { background: rgba(225,60,60,0.16); border-color: rgba(225,60,60,0.45); color: #fff; }
.fr-close:hover svg { transform: rotate(90deg); }   /* twist the X */
.fr-title {
    flex: 1; min-width: 0;
    font-size: 1.05rem; font-weight: 700; color: var(--text-primary);
    margin: 0; padding: 0 6px;
    display: flex; align-items: center; justify-content: center; gap: 4px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Left-aligned panel title (Filters / Video room / Friends); close stays on the right. */
.fr-title.fr-title-left { justify-content: flex-start; padding-left: 4px; }
/* Friends bar: the title fills the left, so Add/Sent/close group on the right. */
#friends-head .fr-close { margin-left: 0; }

.friends-title {
    font-family: "Exo 2", "Exo 2", sans-serif;
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: 0.08em;
    background: linear-gradient(135deg, var(--primary) 0%, var(--accent) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    display: flex;
    align-items: center;
    gap: 0;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}


.friends-add-panel {
    padding: 14px 18px;
    border-bottom: 1px solid rgba(95, 115, 255, 0.12);
    background: rgba(10, 12, 30, 0.45);
}
.friends-add-row {
    display: flex;
    gap: 8px;
}
.friends-add-input {
    flex: 1;
    min-width: 0;
    padding: 9px 12px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--text-primary);
    font-size: 0.92rem;
    font-family: inherit;
    transition: border-color 0.15s;
}
.friends-add-input:focus {
    outline: none;
    border-color: var(--primary);
}
.friends-add-btn {
    padding: 9px 16px;
    border: none;
    border-radius: 10px;
    background: var(--primary);
    color: #04222b;
    font-weight: 700;
    font-size: 0.88rem;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: filter 0.15s;
}
.friends-add-btn:disabled { opacity: 0.5; cursor: default; }
.friends-add-btn:hover:not(:disabled) { filter: brightness(1.07); }
.friends-add-msg {
    margin-top: 8px;
    font-size: 0.82rem;
    color: var(--text-secondary);
}
.friends-add-msg.error   { color: #e15050; }
.friends-add-msg.success { color: #5ac88a; }

.friends-empty {
    text-align: center;
    padding: 40px 24px 0;
    color: var(--text-secondary);
}
.friends-empty h3 {
    font-family: "Exo 2", "Exo 2", sans-serif;
    font-size: 1.05rem;
    color: var(--text-primary);
    font-weight: 600;
    letter-spacing: 0.02em;
    margin-bottom: 6px;
}
.friends-empty p {
    font-size: 0.88rem;
    line-height: 1.5;
    max-width: 240px;
    margin: 0 auto;
}

/* The whole friends drawer uses one unified background — no inset cards */
.friends-drawer .side-drawer-body {
    padding: 0;
    background: #0a0c14;
}

.friends-section { padding: 0; }
.friends-section-h {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--text-secondary);
    padding: 14px 16px 8px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.friends-pill {
    background: var(--primary);
    color: #fff;
    font-size: 0.7rem;
    padding: 1px 8px;
    border-radius: 999px;
    font-weight: 700;
}

.friends-rows { display: flex; flex-direction: column; }

/* Flat rows — full bleed, divider, hover highlight */
.friend-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 16px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    background: transparent;
    transition: background 0.12s;
}
.friend-row:hover { background: rgba(255,255,255,0.03); }
.friend-row.pending { background: rgba(255,165,0,0.06); }

.friend-avatar {
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    overflow: hidden;
    background: #161a26;
}
.friend-avatar .av-img { width: 100%; height: 100%; display: block; }

.friend-main { flex: 1; min-width: 0; }
.friend-name-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}
.friend-name {
    font-weight: 600;
    color: var(--text-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
}
.friend-sub {
    font-size: 0.78rem;
    color: var(--text-secondary);
}
.friend-unread {
    background: var(--primary);
    color: #fff;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 1px 7px;
    border-radius: 999px;
    min-width: 18px;
    text-align: center;
}

/* Unread badge that sits on the envelope (Message) button */
.friend-btn { position: relative; }
.friend-msg.has-unread {
    background: rgba(225,84,84,0.12);
    border-color: #e15454;
    color: #ff8a8a;
}
.msg-unread-dot {
    position: absolute;
    top: -5px;
    right: -5px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: 999px;
    background: #e15454;
    color: #fff;
    font-size: 0.66rem;
    font-weight: 800;
    line-height: 16px;
    text-align: center;
    box-shadow: 0 0 0 2px var(--bg-secondary, #1a1f2e);
    pointer-events: none;
}
.friend-row.has-unread { background: rgba(225,84,84,0.05); }

.friend-actions {
    display: flex;
    gap: 4px;
    flex: 0 0 auto;
}
.friend-btn {
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.04);
    color: var(--text-primary);
    cursor: pointer;
    font-size: 0.9rem;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    padding: 0;
}
.friend-btn:hover    { background: rgba(255,255,255,0.1); }
.friend-msg:hover    { background: var(--primary); border-color: var(--primary); color: #fff; }
.friend-call:hover   { background: #2bb673; border-color: #2bb673; color: #fff; }
.friend-accept       { color: #2bb673; }
.friend-accept:hover { background: #2bb673; color: #fff; border-color: #2bb673; }
.friend-decline,
.friend-remove       { color: #e15454; }
.friend-decline:hover,
.friend-remove:hover { background: #e15454; color: #fff; border-color: #e15454; }

/* Inline rename input */
.friend-rename-input {
    background: rgba(0,0,0,0.3);
    border: 1px solid var(--primary);
    border-radius: 4px;
    color: var(--text-primary);
    font: inherit;
    font-weight: 600;
    padding: 2px 6px;
    width: 160px;
    outline: none;
}

/* ── Sent Requests cards ────────────────────────────────────────── */
.sent-cards { padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; }

.sent-card {
    background: rgba(var(--primary-rgb), 0.16);
    border: 1px solid rgba(var(--primary-rgb), 0.18);
    border-radius: 10px;
    padding: 12px 14px;
    color: var(--text-primary);
    font-family: "Exo 2", sans-serif;
    transition: background 0.12s;
}
.sent-card:hover { background: rgba(var(--primary-rgb), 0.22); }

.sent-card-row {
    display: flex;
    align-items: center;
    gap: 12px;
}
.sent-card-avatar {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    overflow: hidden;
    background: #161a26;
    border: 1px solid rgba(var(--primary-rgb), 0.25);
}
.sent-card-avatar .av-img { width: 100%; height: 100%; display: block; }

.sent-card-main { flex: 1; min-width: 0; }
.sent-card-username {
    font-weight: 700;
    font-size: 0.97rem;
    color: var(--text-primary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 3px;
}
.sent-card-meta {
    display: flex;
    gap: 8px;
    align-items: center;
    font-size: 0.78rem;
}
.sent-card-status {
    background: rgba(var(--primary-rgb), 0.15);
    color: var(--primary);
    font-weight: 700;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    padding: 2px 7px;
    border-radius: 999px;
    border: 1px solid rgba(var(--primary-rgb), 0.3);
}
.sent-card-date {
    color: var(--text-secondary);
    font-size: 0.78rem;
}

.sent-revoke {
    flex: 0 0 auto;
    padding: 6px 14px;
    background: transparent;
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 7px;
    color: var(--text-secondary);
    font-family: "Exo 2", sans-serif;
    font-size: 0.82rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    white-space: nowrap;
}
.sent-revoke:hover {
    background: rgba(225,84,84,0.15);
    border-color: #e15454;
    color: #ff8a8a;
}

/* ── Thread view (DM) ───────────────────────────────────────────── */
.thread-back {
    background: none;
    border: none;
    color: var(--text-primary);
    font-size: 1.6rem;
    line-height: 1;
    padding: 0 8px 0 0;
    cursor: pointer;
    vertical-align: middle;
}
.thread-back:hover { color: var(--primary); }
/* Conversation title doubles as a back button (mirrors the dock). */
.thread-back-name { cursor: pointer; }
.thread-back-name:hover { color: #fff; }

.thread-view {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.thread-toolbar {
    display: flex;
    justify-content: flex-end;
    padding: 8px 12px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}
.thread-clear {
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    color: var(--text-secondary);
    border-radius: 6px;
    padding: 5px 10px;
    font-size: 0.78rem;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.thread-clear:hover {
    background: #e15454;
    border-color: #e15454;
    color: #fff;
}
.thread-messages {
    flex: 1;
    overflow-y: auto;
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.thread-empty {
    text-align: center;
    color: var(--text-secondary);
    font-style: italic;
    padding: 40px 16px;
}

/* Flat, like the global chat — no bubbles. Own messages get a faint deep-blue
   band fading to the left; partner messages are plain text. */
.msg {
    max-width: 100%;
    align-self: stretch;
    padding: 3px 4px;
    border-radius: 0;
    background: none;
    color: var(--text-primary);
    word-wrap: break-word;
    line-height: 1.4;
    font-size: 0.9rem;
}
.msg-mine {
    text-align: right;
    padding-right: 6px;
    background: linear-gradient(to left, rgba(28, 72, 112, 0.3), transparent);
}
.msg-theirs {
    text-align: left;
}
.msg-body { white-space: pre-wrap; }
.msg-time {
    font-size: 0.66rem;
    opacity: 0.5;
    margin-top: 2px;
    text-align: right;
}
.msg-theirs .msg-time { text-align: left; }
.msg.failed { outline: 1px solid #e15454; }

.thread-compose {
    display: flex;
    gap: 6px;
    padding: 10px 12px;
    border-top: 1px solid rgba(255,255,255,0.06);
    background: rgba(0,0,0,0.2);
}
.thread-compose input {
    flex: 1;
    background: rgba(255,255,255,0.05);
    border: 1px solid rgba(255,255,255,0.1);
    border-radius: 18px;
    color: var(--text-primary);
    padding: 8px 14px;
    font: inherit;
    outline: none;
}
.thread-compose input:focus { border-color: var(--primary); }
.thread-send {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: none;
    background: var(--primary);
    color: #fff;
    cursor: pointer;
    font-size: 0.9rem;
    transition: opacity 0.15s;
}
.thread-send:hover { opacity: 0.9; }

/* Make the friends-drawer body fill the height so the thread compose sits at the bottom */
.friends-drawer .side-drawer-body { display: flex; flex-direction: column; min-height: 0; }
.friends-drawer .side-drawer-body > .thread-view { flex: 1; min-height: 0; }

/* Red dot when there are incoming requests */
.nav-item.has-request { position: relative; }
.nav-item.has-request::after {
    content: '';
    position: absolute;
    top: 6px;
    right: 6px;
    width: 8px;
    height: 8px;
    background: #e15454;
    border-radius: 50%;
    box-shadow: 0 0 0 2px var(--bg-primary, #0d0f14);
}

/* Numeric unread badge on a nav button (FRIENDS pill, etc). Anchors
   to the top-right; the parent .nav-item is already a flex column so
   we force the badge out of flow with absolute positioning. */
.nav-item { position: relative; }
.nav-badge {
    position: absolute;
    top: 2px;
    right: 2px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    box-sizing: border-box;
    background: #e15454;
    color: #fff;
    font-size: 0.65rem;
    font-weight: 700;
    line-height: 16px;
    text-align: center;
    border-radius: 8px;
    box-shadow: 0 0 0 2px var(--bg-primary, #0d0f14);
    pointer-events: none;
}
.nav-badge.hidden { display: none; }

/* Add Friend button — visual feedback once a request has been sent */
.action-btn.btn-sent {
    background: rgba(43,182,115,0.18) !important;
    border-color: #2bb673 !important;
    color: #2bb673 !important;
    cursor: default;
}

/* Mobile: drawer fills the screen */
@media (max-width: 600px) {
    .side-drawer { width: 100%; max-width: 100%; }
    .menu-stack { width: 100%; max-width: 100%; }
}

/* ── Gender picker modal ──
   Palette + title font come from .modal-themed; only the bits below
   are gender-specific. */
.gender-modal-intro {
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.5;
    margin-bottom: 18px;
}
.gender-modal-intro strong { color: #f87171; }
/* Guest-expiry heads-up — a quieter, boxed note under the intro. */
.gender-modal-note {
    color: var(--text-secondary);
    font-size: 0.82rem;
    line-height: 1.5;
    margin: -6px 0 18px;
    padding: 9px 12px;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
}

.gender-options {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-bottom: 14px;
}

.gender-option {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 8px;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.gender-option:hover { background: rgba(255, 255, 255, 0.06); border-color: rgba(255, 255, 255, 0.25); }
.gender-option input[type="radio"] {
    appearance: none;
    width: 18px;
    height: 18px;
    border: 2px solid rgba(255,255,255,0.35);
    border-radius: 50%;
    position: relative;
    flex-shrink: 0;
}
.gender-option input[type="radio"]:checked { border-color: rgba(255, 255, 255, 0.85); }
.gender-option input[type="radio"]:checked::after {
    content: '';
    position: absolute;
    inset: 3px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
}
.gender-option-label { font-size: 0.95rem; color: var(--text-primary); }

.gender-confirm-row {
    margin: 14px 0 4px;
    padding: 10px 12px;
    background: rgba(255, 71, 87, 0.08);
    border: 1px solid rgba(255, 71, 87, 0.3);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.gender-confirm-row-label {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text-primary);
    line-height: 1.4;
}
.gender-confirm-row input[type="checkbox"] {
    accent-color: var(--accent);
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    margin-top: 2px;
}
.gender-confirm-row a {
    color: var(--accent);
    text-decoration: underline;
}

/* (#gender-submit-btn is now styled by the shared boxed-button chain
    further down — keeps gender modal, profile save and room-join all
    in lockstep.) */

.gender-guidelines {
    margin: 14px 0 4px;
    padding: 10px 12px;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: 8px;
    font-size: 0.82rem;
    color: var(--text-secondary);
}
.gender-guidelines summary {
    cursor: pointer;
    color: var(--text-primary);
    font-weight: 600;
    letter-spacing: 0.02em;
    list-style: none;
}
.gender-guidelines summary::-webkit-details-marker { display: none; }
.gender-guidelines summary::before {
    content: '▸';
    display: inline-block;
    margin-right: 8px;
    color: var(--text-secondary);
    transition: transform 0.15s;
}
.gender-guidelines[open] summary::before { transform: rotate(90deg); }
.gender-guidelines ul {
    margin: 8px 0 0;
    padding-left: 22px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.gender-guidelines li { line-height: 1.4; }
.gender-guidelines strong { color: #f87171; }
.gender-guidelines-link {
    margin: 10px 0 0;
    font-size: 0.82rem;
}
.gender-guidelines-link a {
    color: var(--primary);
    text-decoration: underline;
    text-underline-offset: 2px;
}
.gender-guidelines-link a:hover { opacity: 0.85; }

/* ── Profile summary in settings modal ── */
.profile-summary {
    margin-bottom: 16px;
    padding: 14px;
    background: rgba(var(--primary-rgb), 0.05);
    border: 1px solid rgba(var(--primary-rgb), 0.18);
    border-radius: 10px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
/* Inline editors (Username + Email rows share the same chassis) */
.profile-row-username .profile-username-view,
.profile-row-username .profile-username-editor,
.profile-row-email .profile-email-view,
.profile-row-email .profile-email-editor {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}
.profile-row-username .profile-username-view.hidden,
.profile-row-username .profile-username-editor.hidden,
.profile-row-email .profile-email-view.hidden,
.profile-row-email .profile-email-editor.hidden {
    display: none;
}
/* Label + edit pencil cluster on the LEFT of the row (the value sits right). */
.profile-field-head { display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; }
.profile-inline-edit {
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 2px 6px;
    font-size: 0.9rem;
    line-height: 1;
    border-radius: 4px;
    transition: color .15s, background .15s;
}
.profile-inline-edit:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.08);
}
.profile-username-editor input,
.profile-email-editor input,
.profile-password-editor input {
    width: 200px;
    max-width: 100%;
    padding: 4px 8px;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 3px;
    color: #fff;
    font-size: 0.9rem;
    font-family: inherit;
}
.profile-username-editor input:focus,
.profile-email-editor input:focus,
.profile-password-editor input:focus {
    outline: none;
    border-color: rgba(var(--primary-rgb), 0.7);
}
/* Two stacked inputs (current + new) with the save/cancel row beneath. */
.profile-password-editor { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.profile-password-actions { display: flex; gap: 6px; }
.profile-inline-save,
.profile-inline-cancel {
    background: none;
    border: 1px solid rgba(255, 255, 255, 0.25);
    color: rgba(255, 255, 255, 0.85);
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 3px;
    font-size: 0.85rem;
    line-height: 1.2;
    transition: color .15s, border-color .15s, background .15s;
}
.profile-inline-save:hover  { border-color: #10b981; color: #d1fae5; background: rgba(16, 185, 129, 0.15); }
.profile-inline-cancel:hover { border-color: rgba(255,255,255,0.6); color: #fff; }
.profile-inline-save:disabled,
.profile-inline-cancel:disabled { opacity: 0.5; cursor: progress; }
.profile-field-error {
    color: #f87171;
    font-size: 0.78rem;
    padding: 2px 0 0;
}
.profile-field-error.hidden { display: none; }

/* Password show/hide eye — overlaid inside the input on the right.
   The form-group keeps its existing padding; we just absolute-position
   the toggle button and pad the input on the right so text doesn't run
   under the icon. */
.form-group.password-group {
    position: relative;
}
.form-group.password-group input {
    padding-right: 42px;
}
.password-toggle {
    position: absolute;
    right: 6px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    color: var(--text-secondary);
    font-size: 1.05rem;
    cursor: pointer;
    padding: 6px 8px;
    border-radius: 6px;
    line-height: 1;
    transition: color .15s, background .15s;
}
.password-toggle:hover { color: var(--text-primary); background: rgba(255,255,255,0.06); }
.password-toggle.active { color: var(--primary); }

/* Email-change verify block — appears after ✓ is hit on the editor, holds
   the 6-digit code input + Resend link. Sits below the email row, full
   width of the modal-body container. */
.profile-email-verify {
    margin: 6px 0 0;
    padding: 10px 12px;
    background: rgba(var(--primary-rgb), 0.05);
    border: 1px solid rgba(var(--primary-rgb), 0.18);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.profile-email-verify.hidden { display: none; }
.profile-email-verify-hint {
    margin: 0;
    font-size: 0.82rem;
    color: var(--text-secondary);
    line-height: 1.4;
}
.profile-email-verify-hint strong { color: #fff; word-break: break-all; }
.profile-email-verify-row {
    display: inline-flex;
    align-items: center;
    gap: 8px;
}
.profile-email-verify-row input {
    width: 140px;
    padding: 6px 10px;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.25);
    border-radius: 4px;
    color: #fff;
    font-size: 1.05rem;
    font-family: 'SF Mono', Menlo, monospace;
    letter-spacing: 4px;
    text-align: center;
}
.profile-email-verify-row input:focus {
    outline: none;
    border-color: rgba(var(--primary-rgb), 0.7);
}
.profile-email-verify-actions {
    display: flex;
    gap: 12px;
}

/* Signup verify view (login modal, register tab) — the 6-digit code
   input that replaces the form after Create Account is pressed.
   Buttons use the site-wide .btn-text style from styles.css; we only
   need a flex row + spacing here. */
.auth-verify-intro {
    margin: 0 0 14px;
    color: var(--text-secondary);
    font-size: 0.92rem;
    line-height: 1.45;
}
.auth-verify-intro strong { color: #fff; word-break: break-all; }
.auth-code-input {
    text-align: center;
    letter-spacing: 8px;
    font-family: 'SF Mono', Menlo, monospace;
    font-size: 1.2rem;
}
.auth-verify-actions {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    margin-top: 12px;
}

/* Success-flash state — the primary verify button turns green for ~800ms
   between "code was right" and "next thing happens" (modal closing /
   logged-in state lighting up), so the action gets a beat of feedback. */
.btn-primary.btn-success-flash,
.btn-primary.btn-success-flash:hover {
    background: linear-gradient(135deg, #10b981 0%, #059669 100%);
    box-shadow: 0 5px 15px rgba(16, 185, 129, 0.45);
    transform: none;
}
.profile-inline-save.btn-success-flash,
.profile-inline-save.btn-success-flash:hover {
    background: rgba(16, 185, 129, 0.25);
    border-color: #10b981;
    color: #d1fae5;
}
.profile-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    font-size: 0.9rem;
    min-width: 0;
}
.profile-row > * { min-width: 0; }
.profile-label {
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.75rem;
    flex-shrink: 0;
}
.profile-trust-num {
    color: var(--text-secondary);
    font-weight: 400;
    margin-left: 4px;
}
.profile-value {
    color: var(--text-primary);
    font-weight: 600;
    min-width: 0;
    text-align: right;
    /* Ellipsize only when the value genuinely outgrows the row.
       The old 60% cap was sized for a much narrower modal. */
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ── Country typeahead dropdown ── */
.country-suggest {
    position: absolute;
    z-index: 5;
    left: 0;
    right: 0;
    margin-top: 4px;
    background: #15172a;
    border: 1px solid rgba(255, 255, 255, 0.12);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
    max-height: 240px;
    overflow-y: auto;
    padding: 4px;
}
.chips-input { position: relative; }

.country-suggest-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: transparent;
    border: none;
    border-radius: 6px;
    color: var(--text-primary);
    cursor: pointer;
    text-align: left;
    font-size: 0.92rem;
}
.country-suggest-item:hover,
.country-suggest-item.active {
    background: rgba(255, 255, 255, 0.08);
}
.country-suggest-flag {
    font-size: 1.15rem;
    line-height: 1;
    width: 1.5em;
    text-align: center;
    flex-shrink: 0;
}

/* Save button: hidden when there's nothing to save, glowing when dirty */
/* ── Bio textarea (gender modal + profile) ── */
.gender-bio-group { margin: 14px 0 4px; }
.gender-bio-group label,
.profile-bio-block label {
    display: block;
    color: var(--text-secondary);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    margin-bottom: 6px;
}
.gender-bio-group .label-hint,
.profile-bio-block .label-hint {
    text-transform: none;
    font-weight: 400;
    letter-spacing: 0;
    color: var(--text-secondary);
    opacity: 0.7;
    display: block;
    margin-top: 2px;
}

#gender-bio,
#profile-bio {
    width: 100%;
    background: linear-gradient(145deg, #0d0d0d, #1a1b22);
    border: 1px solid var(--dark-border);
    border-radius: var(--radius-sm);
    color: var(--text-primary);
    font-size: 0.92rem;
    padding: 10px 12px;
    resize: vertical;
    font-family: inherit;
    transition: var(--transition);
}
#gender-bio:focus,
#profile-bio:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 12px var(--primary-glow);
}

.profile-bio-block {
    margin-top: 8px;
    padding-top: 10px;
    border-top: 1px dashed rgba(var(--primary-rgb), 0.18);
}

.btn-bio-save {
    margin-top: 8px;
    background: linear-gradient(135deg, var(--primary), var(--accent));
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 6px 14px;
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    box-shadow: 0 3px 12px var(--primary-glow);
    transition: transform 0.12s;
}
.btn-bio-save:hover { transform: scale(1.03); }
.btn-bio-save:disabled { opacity: 0.7; cursor: default; transform: none; }

/* ── Profile: Allow Incoming Calls toggle ────────────────────────── */
.profile-toggle-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding-top: 10px;
    border-top: 1px dashed rgba(255,255,255,0.08);
    margin-top: 10px;
}
.profile-toggle-row .profile-label { font-weight: 600; }
/* Friends-only explainer above the call/DM switches. Carries the separator so
   the first switch right below it drops its own. */
.profile-toggle-hint {
    margin: 16px 0 0;
    padding-top: 12px;
    border-top: 1px dashed rgba(255,255,255,0.08);
    font-size: 0.78rem;
    line-height: 1.45;
    color: var(--text-secondary);
}
.profile-toggle-hint + .profile-toggle-row { border-top: none; margin-top: 6px; }

/* .modal-themed lives in styles.css so both lobby.html and
   room.html (which only loads styles.css) get the same look. */

/* ── Profile modal layout
   Let the page scroll the overlay (no internal scrollbar on the
   card) and lay the lower form-groups out in 2 columns that
   collapse to 1 when the modal is narrow. */
#settings-modal {
    align-items: flex-start;
    overflow-y: auto;
    padding: 40px 16px;
    /* Drop the heavy scrim (.modal sets 0.9 opacity + blur 15px) right down —
       this is where you switch the ambient background, so you need to SEE it
       changing behind the card. Other modals keep the strong overlay. */
    background: rgba(10, 14, 39, 0.5);
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
#settings-modal .modal-content {
    /* Layout overrides — palette comes from .modal-themed. */
    max-width: 1100px;
    max-height: none;
    overflow: visible;
    margin: 0 auto;
}
/* Pill toggles inside the profile modal switch to purple to match
   the new card palette (the global toggle elsewhere stays cyan). */
#settings-modal .pill-toggle input:checked + .pill-track {
    background: var(--accent);
}
/* Two side-by-side cards: profile summary on the left, settings
   block on the right. Each takes half the modal width and both
   stretch to the same height regardless of content. */
#settings-modal .modal-body {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 20px;
    align-items: stretch;
}
#settings-modal .modal-body > .profile-summary,
#settings-modal .modal-body > .settings-block {
    margin: 0;
    height: 100%;
    border-radius: 0;
    /* Never let an inner box grow wider than its grid cell — long
       usernames etc. should ellipsise, not push the card outwards. */
    min-width: 0;
    overflow: hidden;
}
/* The four device pickers stack vertically inside the right-hand
   card (it's now too narrow for a 2-column grid). */
.settings-block {
    background: rgba(var(--primary-rgb), 0.05);
    border: 1px solid rgba(var(--primary-rgb), 0.18);
    border-radius: 10px;
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.settings-block .form-group { margin-bottom: 0; }
/* Save button stretches across the bottom of the settings-block.
   The bottom-alignment is now provided by .donate-block's
   margin-top: auto (which sits between the pickers and the save),
   so save itself doesn't need margin-top: auto. */
.settings-block #save-settings-btn {
    align-self: stretch;
    width: 100%;
}
/* Collapse to a single stacked column on narrower viewports. */
@media (max-width: 720px) {
    #settings-modal .modal-body { grid-template-columns: 1fr; }
}

/* ── Profile: Sign-in / Sign-out row ──────────────────────────────── */
.profile-auth-row {
    padding-top: 14px;
    margin-top: 14px;
    border-top: 1px dashed rgba(255,255,255,0.08);
}
.profile-auth-hint {
    color: var(--text-secondary);
    font-size: 0.9rem;
    margin: 0 0 16px;
    line-height: 1.4;
}
#profile-signin-btn,
#profile-signout-btn { width: 100%; }

/* ── Danger zone — self-service account deletion at the very bottom ── */
.profile-danger-zone {
    margin-top: 18px;
    padding-top: 16px;
    border-top: 1px dashed rgba(255, 80, 80, 0.25);
}
.profile-delete-btn {
    width: 100%;
    padding: 10px 14px;
    background: transparent;
    color: #ff6b6b;
    border: 1px solid rgba(255, 80, 80, 0.4);
    border-radius: 10px;
    font-weight: 700;
    font-size: 0.9rem;
    cursor: pointer;
    transition: background .15s, border-color .15s, color .15s;
}
.profile-delete-btn:hover {
    background: rgba(255, 80, 80, 0.12);
    border-color: rgba(255, 80, 80, 0.7);
    color: #ff8a8a;
}
.profile-delete-btn:disabled { opacity: 0.6; cursor: default; }
.profile-delete-confirm {
    margin-top: 12px;
    padding: 14px;
    background: rgba(255, 80, 80, 0.06);
    border: 1px solid rgba(255, 80, 80, 0.25);
    border-radius: 10px;
}
.profile-delete-hint {
    margin: 0 0 12px;
    font-size: 0.82rem;
    line-height: 1.45;
    color: var(--text-secondary);
}
.profile-delete-hint strong { color: var(--text-primary); }
.profile-delete-row { display: flex; align-items: center; gap: 8px; }
.profile-delete-row input {
    flex: 1;
    min-width: 0;
    padding: 8px 10px;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 8px;
    color: var(--text-primary);
    font-family: 'Space Mono', ui-monospace, monospace;
    letter-spacing: 4px;
    text-align: center;
}
.profile-delete-actions { margin-top: 10px; }

/* Shared button chassis (sign-in/out/save/upgrade/confirm/join-room)
   lives in styles.css so both lobby and room get the same look. */

/* Donate block — sits flush at the bottom of the settings-block,
   directly above the Save button. The auto top-margin pulls the
   whole bottom pair (donate hint + button + save) down so they
   line up with the bottom edge of the profile card next to it. */
.donate-block {
    margin-top: auto;
    padding-top: 12px;
    border-top: 1px dashed rgba(255, 255, 255, 0.08);
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.donate-block-hint {
    color: var(--text-secondary);
    font-size: 0.82rem;
    line-height: 1.45;
    margin: 0;
}
#profile-donate-btn { width: 100%; }

/* ── Profile drawer — account panel relocated out of the old settings modal,
   restyled to match the sharp panel look (neutral fields, solid-cyan CTAs). ── */
#profile-drawer .side-drawer-body { display: flex; flex-direction: column; gap: 18px; }
/* Heading scrolls with the content (no fixed top bar). */
.profile-heading { margin: 0; font-size: 1.05rem; font-weight: 700; color: var(--text-primary); }
/* Country row: flat flag sits flush to the left of the name, slightly smaller. */
.profile-country-val { display: inline-flex; align-items: center; gap: 6px; }
.profile-country-val .fi { font-size: 0.82em; flex-shrink: 0; border-radius: 2px; }
/* Flat list on the drawer's own dark bg — no nested cyan cards. */
#profile-drawer .profile-summary { display: flex; flex-direction: column; gap: 4px; background: none; border: none; padding: 0; }
#profile-drawer .profile-row { padding: 4px 0; }
#profile-drawer .form-group input,
#profile-drawer .form-group select,
#profile-drawer #profile-bio,
#profile-drawer .profile-username-editor input,
#profile-drawer .profile-email-editor input,
#profile-drawer .profile-email-verify input {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    box-shadow: none;
}
#profile-drawer .form-group input:focus,
#profile-drawer .form-group select:focus,
#profile-drawer #profile-bio:focus {
    border-color: var(--primary);
    box-shadow: none;
    background: rgba(255, 255, 255, 0.05);
}
#profile-drawer .settings-block {
    background: none;
    border: none;
    padding: 0;
}
#profile-drawer #save-settings-btn,
#profile-drawer #profile-signin-btn {
    background: var(--primary);
    border: none;
    color: #04222b;
    border-radius: 10px;
    text-transform: none;
    letter-spacing: 0.02em;
    font-weight: 700;
    padding: 12px;
}
#profile-drawer #save-settings-btn:hover,
#profile-drawer #profile-signin-btn:hover {
    background: var(--primary);
    color: #04222b;
    filter: brightness(1.07);
}
#profile-drawer #profile-signout-btn,
#profile-drawer #profile-donate-btn {
    border-radius: 10px;
    text-transform: none;
    letter-spacing: 0.02em;
}
/* Email-verify box → neutral; editors focus cyan not purple. */
#profile-drawer .profile-email-verify {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(255, 255, 255, 0.1);
}
#profile-drawer .profile-username-editor input:focus,
#profile-drawer .profile-email-editor input:focus {
    border-color: var(--primary);
}
/* Bio save → solid cyan, no gradient/glow. */
#profile-drawer .btn-bio-save {
    background: var(--primary);
    color: #04222b;
    box-shadow: none;
}
/* Dividers → solid hairline, not dashed. */
#profile-drawer .profile-auth-row,
#profile-drawer .donate-block {
    border-top-style: solid;
    border-top-color: rgba(255, 255, 255, 0.08);
}

/* ── Call History Drawer ──────────────────────────────────────────── */
.history-count {
    color: var(--text-secondary);
    font-weight: 600;
    font-size: 0.78rem;
    letter-spacing: 0.02em;
    /* The emoji star renders higher than the surrounding text baseline, so
       nudge the whole count down 1px to line up with the "Call history" title. */
    position: relative;
    top: 1px;
}
/* Emojis sit flush against the next glyph — give them breathing room. */
.history-count .hc-emoji { margin-right: 5px; }
/* Call History stretches edge-to-edge — the rows have their own 16px gutter,
   no inner box. The scrolling body drops its horizontal padding; the title bar
   (which scrolls with the rows) is re-indented to 16px to line up with them.
   The empty-state keeps its standard padding via .friends-empty. */
.history-drawer .side-drawer-body { padding-left: 0; padding-right: 0; }
.history-drawer .side-drawer-body > .fr-topbar { padding-left: 16px; padding-right: 16px; }
.history-list { display: flex; flex-direction: column; }
/* Flat, edge-to-edge cells — no rounded card. A thin separator between
   rows is the only divider. Hover just dims the row background up a touch. */
.history-row {
    padding: 11px 16px 12px;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    transition: background 0.15s;
}
.history-row:hover { background: rgba(255,255,255,0.035); }
.history-row-main { display: flex; align-items: center; gap: 12px; }
.history-who { flex: 1; min-width: 0; display: flex; align-items: center; gap: 10px; }
.history-avatar { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; background: #161a26; }
.history-avatar .av-img { width: 100%; height: 100%; display: block; }
.history-name { color: var(--text-primary); letter-spacing: 0.005em; }
/* Country (far left) and date (far right) share the same horizontal
   bounds as the top row — meta sits directly under .history-row-main
   with identical left/right reach so country lines up with the dot and
   date lines up with the last action button. */
.history-meta {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 12px;
    /* Clear the 32px action buttons above — without this the date crowds the
       call button while the country (under the shorter name) sits lower. */
    margin-top: 10px;
    padding-right: 2px;
    font-size: 0.78rem;
    color: var(--text-secondary);
}
.history-country, .history-when { font-size: inherit; color: inherit; font-family: inherit; }
.history-actions { display: flex; gap: 6px; }
.history-btn {
    width: 32px; height: 32px;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: 8px;
    border: 1px solid rgba(255,255,255,0.1);
    background: rgba(255,255,255,0.04);
    color: var(--text-primary);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
}
.history-btn:hover { background: rgba(255,255,255,0.1); }
/* Call button is the online indicator now — lit green when the partner is
   reachable, brightens to a solid pill on hover. Disabled (offline) drops
   back to the standard dim look via .history-btn.disabled. */
.history-call:not(.disabled) {
    color: #2bb673;
    border-color: rgba(43,182,115,0.45);
    background: rgba(43,182,115,0.12);
}
.history-call:not(.disabled):hover { background: #2bb673; border-color: #2bb673; color: #fff; }
.history-add:hover { background: rgba(251,191,36,0.18); border-color: rgba(251,191,36,0.5); color: #fbbf24; }
.history-btn.disabled, .history-btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}
.history-report:hover { background: rgba(255, 71, 87, 0.18); border-color: rgba(255, 71, 87, 0.5); color: #ff8a93; }

/* Inline report form expanded under a history row when 🚩 is clicked.
   The parent .history-row is now flex-direction:column so the form just
   slots in as another column child at full width. */
.history-report-form {
    margin-top: 4px;
    padding: 12px;
    background: rgba(255, 71, 87, 0.06);
    border: 1px solid rgba(255, 71, 87, 0.25);
    border-radius: 8px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
.history-report-form.hidden { display: none; }
.history-report-title {
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--text-primary);
}
.history-report-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.history-report-details {
    width: 100%;
    box-sizing: border-box;
    padding: 8px 10px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.12);
    background: rgba(0,0,0,0.25);
    color: var(--text-primary);
    font-family: inherit;
    font-size: 0.85rem;
    resize: vertical;
}
.history-report-actions {
    display: flex;
    gap: 8px;
    justify-content: flex-end;
}
.history-report-btn {
    padding: 6px 14px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.12);
    background: rgba(255,255,255,0.04);
    color: var(--text-primary);
    cursor: pointer;
    font-size: 0.85rem;
    transition: background 0.15s, border-color 0.15s, color 0.15s, opacity 0.15s;
}
.history-report-btn:hover { background: rgba(255,255,255,0.1); }
.history-report-btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.history-report-send {
    background: rgba(255, 71, 87, 0.18);
    border-color: rgba(255, 71, 87, 0.5);
    color: #ff8a93;
}
.history-report-send:hover {
    background: rgba(255, 71, 87, 0.3);
    border-color: rgba(255, 71, 87, 0.7);
}
.history-report-msg {
    font-size: 0.82rem;
    min-height: 1.1em;
    color: var(--text-secondary);
}
.history-report-msg.success { color: #4ade80; }
.history-report-msg.error   { color: #ff8a93; }

/* ── Call Overlay (outbound + inbound) ────────────────────────────── */
.call-overlay {
    position: fixed; inset: 0;
    background: rgba(0,0,0,0.7);
    backdrop-filter: blur(4px);
    z-index: 9999;
    display: flex; align-items: center; justify-content: center;
}
.call-overlay.hidden { display: none; }
.call-card {
    background: var(--bg-secondary, #1a1f2e);
    border: 1px solid rgba(255,255,255,0.08);
    border-radius: 16px;
    padding: 32px 40px;
    min-width: 320px;
    text-align: center;
    box-shadow: 0 20px 60px rgba(0,0,0,0.6);
}
.call-card-title {
    font-size: 1rem;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 1px;
    margin-bottom: 8px;
}
.call-card-name {
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--text-primary);
    margin-bottom: 24px;
    word-break: break-word;
}
.call-card-actions { display: flex; gap: 12px; justify-content: center; }
.call-btn {
    padding: 12px 24px;
    border-radius: 999px;
    border: 0;
    font-size: 0.95rem;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.12s, filter 0.15s;
}
.call-btn:hover { transform: scale(1.03); }
.call-btn-accept { background: #22c55e; color: #fff; }
.call-btn-decline { background: #ef4444; color: #fff; }
.call-btn-silence { background: #475569; color: #fff; }
.call-card-spinner {
    width: 48px; height: 48px;
    border-radius: 50%;
    border: 4px solid rgba(255,255,255,0.1);
    border-top-color: var(--primary, #8b5cf6);
    margin: 0 auto 16px;
    animation: callspin 0.9s linear infinite;
}
@keyframes callspin { to { transform: rotate(360deg); } }
.call-card-pulse {
    width: 64px; height: 64px;
    border-radius: 50%;
    background: var(--primary, #8b5cf6);
    margin: 0 auto 16px;
    position: relative;
    animation: callpulse 1.4s ease-out infinite;
}
.call-card-pulse::after {
    content: '📞';
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 1.8rem;
    animation: callshake 0.6s ease-in-out infinite;
}
@keyframes callpulse {
    0%   { box-shadow: 0 0 0 0 rgba(139,92,246,0.6); }
    100% { box-shadow: 0 0 0 28px rgba(139,92,246,0); }
}
@keyframes callshake {
    0%,100% { transform: rotate(-8deg); }
    50%     { transform: rotate(8deg); }
}


/* ── Post-call rate (inline, lives in panel-left under the call hint) ── */
.rate-inline {
    width: 100%;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: 10px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    animation: rate-inline-in 220ms ease-out;
}
.rate-inline.hidden { display: none; }
@keyframes rate-inline-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

.rate-inline-row {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    color: var(--text-secondary);
}
.rate-inline-prompt {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.rate-inline-prompt strong { color: var(--text-primary); }

.rate-inline-btn {
    width: 40px;
    height: 40px;
    border-radius: 10px;
    border: 1px solid rgba(255, 255, 255, 0.12);
    background: #15161d;
    cursor: pointer;
    font-size: 1.15rem;
    line-height: 1;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.rate-inline-btn:hover {
    background: #1d1f29;
    border-color: rgba(255, 255, 255, 0.22);
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.05) inset;
}
#rate-inline-up:hover    { background: rgba(34, 197, 94, 0.18); border-color: rgba(34, 197, 94, 0.6); }
#rate-inline-down:hover  { background: rgba(239, 68, 68, 0.18); border-color: rgba(239, 68, 68, 0.6); }
#rate-inline-block:hover { background: rgba(239, 68, 68, 0.28); border-color: rgba(239, 68, 68, 0.75); }

.rate-inline-close {
    width: 24px;
    height: 24px;
    border: none;
    background: none;
    color: var(--text-dim);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    margin-left: 2px;
}
.rate-inline-close:hover { color: var(--text-primary); }

.rate-inline-form {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.rate-inline-form.hidden { display: none; }

.rate-inline-reasons {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}
.rate-chip {
    padding: 4px 9px;
    border-radius: 999px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    background: rgba(255, 255, 255, 0.04);
    color: var(--text-secondary);
    font-size: 0.72rem;
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s;
}
.rate-chip:hover { background: rgba(139, 92, 246, 0.12); border-color: rgba(139, 92, 246, 0.4); }
.rate-chip.selected {
    background: rgba(139, 92, 246, 0.22);
    border-color: var(--primary);
    color: var(--text-primary);
}

#rate-inline-details {
    width: 100%;
    padding: 6px 8px;
    background: #15161d;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 6px;
    color: var(--text-primary);
    font-size: 0.78rem;
    font-family: inherit;
    resize: vertical;
}
#rate-inline-details:focus { outline: none; border-color: var(--primary); }

.rate-inline-form-actions {
    display: flex;
    gap: 6px;
    justify-content: flex-end;
    align-items: center;
}
.rate-inline-send {
    padding: 5px 12px;
    border-radius: 6px;
    border: 1px solid var(--primary);
    background: var(--primary);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
}
.rate-inline-send:hover { filter: brightness(1.1); }
.rate-inline-skip {
    padding: 5px 8px;
    background: none;
    border: none;
    color: var(--text-dim);
    font-size: 0.75rem;
    cursor: pointer;
    text-decoration: underline;
}
.rate-inline-skip:hover { color: var(--text-secondary); }

/* ── Control-row cog buttons — the layout cog + the Games button share this
   square footprint (siblings in .call-options-row). ── */
.bg-cog {
    flex-shrink: 0;
    width: 38px;
    height: 38px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: 2px solid rgba(255,255,255,0.9);   /* match the add-friend / history flank buttons */
    border-radius: 6px;
    color: #fff;
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s;
}
.bg-cog svg { width: 18px; height: 18px; }
/* The layout cog twists a third-turn each tap to reflect the active layout (profilepanel.js). */
#layout-cog { transition: background 0.15s, color 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1); }
.bg-cog:hover {
    border-color: #8b5cf6;
    box-shadow: 0 0 13px rgba(139, 92, 246, 0.5);
}

/* ═══════════════════════════════════════════════════════════════════
   Gamified profile panel — the right column (#panel-right).
   Levels + XP bar, streak, stat tiles, quest badges, theming dock.
   Rendered by js/profilepanel.js. Hidden ≤980px (mobile uses the modal).
   ═══════════════════════════════════════════════════════════════════ */
.panel-right {
    width: 304px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 16px;
    padding: 18px 16px;
    overflow-y: auto;
    background: #0b0d12;
    border-left: 1px solid rgba(255,255,255,0.06);
    scrollbar-width: thin;
}
.profile-card { display: flex; flex-direction: column; gap: 16px; }

/* ── Call-stats — a flush section at the top of the right panel during a call,
   separated by a hairline divider (no box; matches the chat dividers). panel-right
   is hidden in quiet + ≤980px, so it's scoped to the non-quiet desktop layouts
   automatically; the floating top-right timer/label are suppressed there (below)
   so this section owns the readout. ──────────────────────────────────────────── */
.call-stats { display: none; }
body.in-call .call-stats {
    display: flex;
    flex-direction: column;
    gap: 4px;
    /* Pull up so the first row's text lines up with the neighbour panel's header
       text (chat tab bar ≈ 12px from the top; panel padding-top is 18px). */
    margin-top: -7px;
    padding: 0 0 11px;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}
.call-stats-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.call-stats-label { font-size: 0.68rem; font-weight: 400; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-primary); }
.call-stats-val { font-size: 0.72rem; color: rgba(255, 255, 255, 0.72); }
/* The single #call-timer is relocated into the Time slot here; drop its fixed
   positioning so it sits in-flow. It keeps its own Space Mono font (activity.css). */
.call-stats .call-timer { position: static; }
.call-stats-conn { display: inline-flex; align-items: center; gap: 7px; }
.conn-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-secondary); flex-shrink: 0; }
.conn-dot.conn-good { background: #4ade80; box-shadow: 0 0 7px rgba(74, 222, 128, 0.6); }
.conn-dot.conn-fair { background: #fbbf24; box-shadow: 0 0 7px rgba(251, 191, 36, 0.55); }
.conn-dot.conn-poor { background: #ff5a6a; box-shadow: 0 0 7px rgba(255, 90, 106, 0.55); }
.mic-muted { display: none; text-transform: uppercase; }
body.partner-muted .mic-live  { display: none; }
body.partner-muted .mic-muted { display: inline; }
/* Centred's right panel has zero padding (DMs fill it edge-to-edge), so pad the
   section there (and no negative pull — there's no panel padding to counter). */
.app-layout[data-layout="centred"] .call-stats { margin-top: 0; padding: 12px 13px 12px; }

/* On non-quiet desktop the call-stats section owns the mute status, so the
   floating muted label (inside .app-layout) is hidden there; the card's Mic row
   shows it instead. (The timer isn't hidden — it's relocated into the card by
   js/profilepanel.js, so there's no duplicate to suppress.) Quiet + mobile keep
   the floating label. */
@media (min-width: 981px) {
    .app-layout[data-layout="social"]  .muted-label,
    .app-layout[data-layout="centred"] .muted-label { display: none; }
}

.pp-head { display: flex; align-items: center; gap: 10px; }
.pp-usericon { width: 22px; height: 22px; flex-shrink: 0; color: var(--text-secondary); }
.pp-head-meta { flex: 1; min-width: 0; }   /* fill .pp-head so the name only ellipsises on real overflow */
/* Flag (or fallback glyph) + name share the first line, vertically centred. */
.pp-name-row { display: flex; align-items: center; gap: 8px; min-width: 0; }
.pp-name { min-width: 0; font-weight: 700; font-size: 1.02rem; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Member/Guest + staff badge on one flush line under the name. */
.pp-sub { display: flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); }
.pp-badge {
    flex-shrink: 0;
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 0.56rem;
    font-weight: 800;
    letter-spacing: 0.07em;
    text-transform: uppercase;
}
.pp-badge-admin { background: linear-gradient(135deg, #ffd24d, #ff8c42); color: #1a1206; }
.pp-badge-mod   { background: linear-gradient(135deg, #7c4ddb, #5a3aa8); color: #fff; }
/* Country flag on the Member line — slightly larger than the text so it reads
   as a small graphic rather than inline punctuation. */
/* Country flag as the lead icon (stands in for the avatar). */
.pp-flag { font-size: 1.3rem; line-height: 1; flex-shrink: 0; }

/* Server-rendered avatar image — fills whatever round/square box holds it. */
.av-img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* Admin System-avatar tab row. */
.sysav-row { display: flex; align-items: center; gap: 16px; margin-top: 6px; }
.sysav-preview { display: inline-flex; width: 72px; height: 72px; border-radius: 50%; overflow: hidden; background: #161a26; border: 2px solid var(--primary); flex-shrink: 0; }

/* Avatar (robot monster) in the profile head — click to open the chooser. */
.pp-avatar {
    position: relative; flex-shrink: 0;
    width: 52px; height: 52px; padding: 0;
    border-radius: 50%; overflow: hidden;
    border: 2px solid rgba(var(--primary-rgb), 0.5);
    background: #161a26; cursor: pointer;
    transition: border-color 0.15s, transform 0.12s;
}
.pp-avatar:hover { border-color: var(--primary); transform: scale(1.04); }
.pp-avatar svg { width: 100%; height: 100%; display: block; }
.pp-avatar-pencil {
    position: absolute; right: -1px; bottom: -1px;
    width: 18px; height: 18px; border-radius: 50%;
    background: var(--primary); color: #04181d;
    font-size: 0.62rem; line-height: 18px; text-align: center;
    border: 2px solid #0b0e16;
}
.profile-card--menu .pp-avatar { width: 56px; height: 56px; }

/* Avatar chooser modal */
.pp-av-modal {
    position: fixed; inset: 0; z-index: 4200;
    display: flex; align-items: center; justify-content: center;
    padding: 20px; background: rgba(0,0,0,0.6); backdrop-filter: blur(3px);
}
.pp-av-modal.hidden { display: none; }
.pp-av-card {
    width: 100%; max-width: 360px;
    background: #11141d; border: 1px solid rgba(255,255,255,0.1);
    border-radius: 14px; padding: 16px; box-shadow: 0 24px 70px rgba(0,0,0,0.6);
    font-family: "Exo 2", sans-serif;
}
.pp-av-head { display: flex; align-items: center; justify-content: space-between; font-size: 0.95rem; font-weight: 500; color: #fff; margin-bottom: 12px; }
.pp-av-close { background: rgba(255,255,255,0.06); border: none; color: var(--text-secondary); width: 26px; height: 26px; border-radius: 6px; cursor: pointer; }
.pp-av-close:hover { background: rgba(255,255,255,0.12); color: #fff; }
.pp-av-preview { position: relative; width: 84px; height: 84px; margin: 0 auto 14px; border-radius: 50%; overflow: hidden; background: #161a26; border: 2px solid var(--primary); }
.pp-av-preview svg { width: 100%; height: 100%; display: block; }
.pp-av-preview .avfx-canvas { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2; }
.pp-av-slider { margin-bottom: 14px; }
.pp-av-grid {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
    touch-action: pan-y pinch-zoom;
}
.pp-av-tile { aspect-ratio: 1; padding: 0; border-radius: 12px; overflow: hidden; background: #161a26; border: 2px solid transparent; cursor: pointer; transition: border-color 0.12s, transform 0.12s; }
.pp-av-tile:hover { transform: scale(1.05); }
.pp-av-tile.sel { border-color: var(--primary); }
.pp-av-tile svg, .pp-av-tile .av-img { width: 100%; height: 100%; display: block; }
.pp-av-slide-controls { display: flex; justify-content: center; gap: 8px; margin-top: 8px; }
.pp-av-slide-btn {
    width: 36px; height: 28px; border-radius: 8px; border: 1px solid rgba(255,255,255,0.12);
    background: rgba(255,255,255,0.05); color: var(--text-secondary); font-size: 1.35rem;
    line-height: 1; cursor: pointer; display: flex; align-items: center; justify-content: center;
    transition: background 0.15s, color 0.15s;
}
.pp-av-slide-btn:hover { background: rgba(255,255,255,0.1); color: var(--text-primary); }
.pp-av-actions { display: flex; gap: 8px; }
.pp-av-btn { flex: 1; padding: 9px; border-radius: 9px; font-size: 0.85rem; font-weight: 500; font-family: "Exo 2", sans-serif; cursor: pointer; border: 1px solid rgba(255,255,255,0.14); background: rgba(255,255,255,0.05); color: var(--text-primary); transition: background 0.15s, filter 0.15s; }
.pp-av-btn:hover { background: rgba(255,255,255,0.1); }
.pp-av-set { border-color: rgba(var(--primary-rgb), 0.5); color: var(--primary); }
.pp-av-set:hover { background: rgba(var(--primary-rgb), 0.12); }
.pp-av-save { background: var(--primary); color: #04181d; border-color: var(--primary); }
.pp-av-save:hover { filter: brightness(1.1); background: var(--primary); }
.pp-av-style-row { display: flex; align-items: center; gap: 8px; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 12px; }
.pp-av-style {
    flex: 1; padding: 8px 12px; padding-right: 34px;
    border-radius: 8px; background: #161a26; color: var(--text-primary);
    border: 1px solid rgba(255,255,255,0.14); font-size: 0.82rem; font-family: "Exo 2", sans-serif; cursor: pointer;
    /* custom chevron so the triangle isn't jammed against the edge */
    appearance: none; -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%239aa0aa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 12px center;
}
/* Previously-chosen avatars — a horizontal scroll strip you can re-pick from. */
.pp-av-recent-label { font-size: 0.72rem; color: var(--text-secondary); margin: 0 0 6px; }
.pp-av-recent { display: flex; gap: 6px; overflow-x: auto; overflow-y: hidden; padding-bottom: 6px; margin-bottom: 12px; scrollbar-width: thin; }
.pp-av-rtile { flex: 0 0 auto; width: 44px; height: 44px; padding: 0; border-radius: 10px; overflow: hidden; background: #161a26; border: 2px solid transparent; cursor: pointer; transition: border-color 0.12s, transform 0.12s; }
.pp-av-rtile:hover { transform: scale(1.06); }
.pp-av-rtile.sel { border-color: var(--primary); }

/* Nav profile button shows the user's avatar when they have one. */
#nav-profile .nav-avatar.has-avatar { width: 30px; height: 30px; border-radius: 50%; overflow: hidden; }
#nav-profile .nav-avatar.has-avatar svg { width: 100%; height: 100%; display: block; }

.pp-section-h { font-size: 0.66rem; letter-spacing: 0.09em; text-transform: uppercase; color: var(--text-secondary); margin-bottom: 9px; }

/* Level + XP bar to the next tier */
.pp-level-name { font-size: 0.8rem; font-weight: 600; color: var(--text-primary); margin-bottom: 9px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.pp-bar { height: 8px; border-radius: 6px; background: rgba(255,255,255,0.08); overflow: hidden; }
.pp-bar > span { display: block; height: 100%; border-radius: 6px; background: linear-gradient(90deg, var(--primary), #7c5cff); transition: width 0.5s ease; }
.pp-bar--top > span { background: linear-gradient(90deg, #ffcf5c, #ff8a3d); }
.pp-bar-label { margin-top: 6px; font-size: 0.74rem; color: var(--text-secondary); }
.pp-bar-label b { color: var(--text-primary); font-weight: 700; }
.pp-new { font-size: 0.58rem; font-weight: 800; letter-spacing: 0.06em; color: #04222b; background: var(--primary); padding: 1px 5px; border-radius: 4px; }

/* Streak */
/* Compact one-liner — the streak is a self-deprecating "losing streak" gag now,
   so it stays small and dry rather than a celebratory tile. */
.pp-streak { display: flex; align-items: center; gap: 8px; background: rgba(255,255,255,0.04); border-radius: 9px; padding: 7px 11px; }
.pp-streak-flame { font-size: 1rem; filter: grayscale(0.3); }
.pp-streak-line { font-size: 0.78rem; font-weight: 600; color: var(--text-secondary); }
.pp-streak-line b { color: var(--text-primary); font-variant-numeric: tabular-nums; }

/* Stat tiles */
.pp-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.pp-tile { background: rgba(255,255,255,0.04); border-radius: 10px; padding: 11px 13px; }
.pp-tile-num { font-size: 1.35rem; font-weight: 800; color: var(--text-primary); font-variant-numeric: tabular-nums; line-height: 1; }
.pp-tile-label { font-size: 0.66rem; letter-spacing: 0.05em; text-transform: uppercase; color: var(--text-secondary); margin-top: 5px; }
.pp-tiles--loading .pp-tile-num { color: var(--text-secondary); }

/* Profile-tab card only: the stat tiles tuck up beside the name, much smaller
   than the desktop right-panel grid. */
/* Header column stretches to the tile column's height; the name sits on the
   top tile row's line and Member/badge on the bottom row's line. */
.profile-card--menu .pp-menu-top { display: flex; align-items: stretch; gap: 12px; }
.profile-card--menu .pp-menu-top .pp-head { flex: 1 1 auto; min-width: 0; align-items: stretch; }
/* Two lines distributed so the name row centres on the top tile row and the
   Member/badge row centres on the bottom tile row. */
.profile-card--menu .pp-menu-top .pp-head-meta { display: flex; flex-direction: column; justify-content: center; gap: 2px; }
.profile-card--menu .pp-tiles {
    flex: 0 0 auto;
    grid-template-columns: repeat(2, 58px);
    gap: 5px;
}
.profile-card--menu .pp-tile { padding: 5px 8px; border-radius: 8px; text-align: center; }
.profile-card--menu .pp-tile-num { font-size: 1rem; }
.profile-card--menu .pp-tile-label { font-size: 0.5rem; margin-top: 1px; letter-spacing: 0.02em; }

/* Quests */
.pp-quest { display: flex; gap: 11px; align-items: center; padding: 9px 0; border-top: 1px solid rgba(255,255,255,0.05); }
.pp-quest:first-of-type { border-top: none; padding-top: 2px; }
.pp-quest-emoji { font-size: 1.3rem; width: 26px; text-align: center; flex-shrink: 0; }
.pp-quest.locked { opacity: 0.5; }
.pp-quest.locked .pp-quest-emoji { filter: grayscale(1); }
.pp-quest-body { min-width: 0; flex: 1; }
.pp-quest-label { font-size: 0.82rem; font-weight: 600; color: var(--text-primary); display: flex; align-items: center; gap: 5px; }
.pp-quest-tick { color: #44d07b; font-weight: 800; }
.pp-quest-bar { height: 5px; border-radius: 4px; background: rgba(255,255,255,0.08); overflow: hidden; margin-top: 6px; }
.pp-quest-bar > span { display: block; height: 100%; background: linear-gradient(90deg, var(--primary), #7c5cff); }
.pp-quest-sub { font-size: 0.68rem; color: var(--text-secondary); margin-top: 4px; }

/* Signed-out teaser */
.pp-signedout { text-align: center; padding: 32px 12px; color: var(--text-secondary); }
.pp-signedout-emoji { font-size: 2rem; margin-bottom: 10px; }
.pp-signedout p { font-size: 0.85rem; margin-bottom: 15px; line-height: 1.4; }
.pp-signin { background: var(--primary); color: #04222b; border: none; border-radius: 8px; padding: 8px 16px; font-weight: 700; cursor: pointer; }
.pp-signin:hover { filter: brightness(1.08); }

@media (max-width: 980px) {
    .panel-right { display: none; }
}

/* ═══════════════════════════════════════════════════════════════════
   Centre column — global chat (top) + DMs dock (below).
   The dock is rendered by js/dmdock.js. Shown on desktop in the
   "Chat + DMs" layout; hidden in "Chat only" and ≤800px (DMs → drawer).
   ═══════════════════════════════════════════════════════════════════ */
.center-col { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.center-col .chat-area { flex: 1 1 auto; min-height: 0; }

.dm-dock {
    flex: 0 0 38%;
    min-height: 160px;
    max-height: 360px;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    background: #0b0d14;
    border-top: 1px solid rgba(255,255,255,0.08);
}
.dm-head { display: flex; align-items: center; gap: 8px; padding: 9px 13px; background: rgba(255,255,255,0.035); border-bottom: 1px solid rgba(255,255,255,0.06); flex-shrink: 0; user-select: none; -webkit-user-select: none; }
.dm-title { font-size: 0.8rem; font-weight: 700; letter-spacing: 0.03em; color: var(--text-primary); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-title-back { cursor: pointer; }
.dm-title-back:hover { color: #fff; }
.dm-back { background: none; border: none; color: var(--text-secondary); font-size: 1.35rem; line-height: 1; cursor: pointer; padding: 0 2px; flex-shrink: 0; position: relative; top: -1px; }
.dm-back:hover { color: var(--text-primary); }
.dm-badge { background: var(--primary); color: #04222b; font-size: 0.62rem; font-weight: 800; border-radius: 9px; padding: 1px 6px; min-width: 16px; text-align: center; flex-shrink: 0; }
.dm-body { flex: 1; overflow-y: auto; scrollbar-width: thin; }
.dm-empty { color: var(--text-secondary); font-size: 0.8rem; text-align: center; padding: 26px 16px; line-height: 1.4; }

.dm-list { display: flex; flex-direction: column; }
.dm-thread { display: flex; align-items: center; gap: 10px; padding: 9px 12px; background: none; border: none; border-bottom: 1px solid rgba(255,255,255,0.04); cursor: pointer; text-align: left; width: 100%; font: inherit; }
.dm-thread:hover { background: rgba(255,255,255,0.04); }
.dm-av { display: inline-flex; width: 34px; height: 34px; border-radius: 50%; overflow: hidden; background: #161a26; flex-shrink: 0; }
.dm-av svg { width: 100%; height: 100%; display: block; }
.dm-thread-main { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.dm-thread-name { font-size: 0.82rem; font-weight: 600; color: var(--text-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-thread-last { font-size: 0.74rem; color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dm-thread.unread .dm-thread-last { color: var(--text-primary); }
.dm-thread-meta { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; font-size: 0.66rem; color: var(--text-secondary); flex-shrink: 0; }

.dm-msgs { display: flex; flex-direction: column; gap: 5px; padding: 10px 12px; }
.dm-msg { display: flex; }
/* Own DMs: flat text on the right with a faint deep-blue band; partner DMs are
   flat text. Matches the global + user chat treatment. */
.dm-msg.me { justify-content: flex-end; background: linear-gradient(to left, rgba(28, 72, 112, 0.3), transparent); padding: 1px 5px 4px 0; }
/* Roomier line-height + bottom padding so tall emoji glyphs sit inside the
   bubble (and the own-message gradient) rather than poking out the bottom. */
.dm-bubble { max-width: 82%; padding: 3px 5px 4px; font-size: 0.82rem; line-height: 1.45; word-break: break-word; }
.dm-msg.them .dm-bubble { background: none; color: var(--text-primary); }
.dm-msg.me .dm-bubble { background: none; color: var(--text-primary); text-align: right; }

/* Stack the bubble above its reaction chips, aligned per sender. */
.dm-msg { flex-direction: column; }
.dm-msg.me   { align-items: flex-end; }
.dm-msg.them { align-items: flex-start; }

/* Per-thread delete (trash at the end of each row in the list). The row is a
   <button>, so this is a role=button span; it reveals on row hover. */
.dm-thread { position: relative; }
.dm-thread-del {
  flex: 0 0 auto; display: inline-flex; align-items: center; margin-left: 4px;
  padding: 3px 4px; border-radius: 6px; opacity: 0; font-size: 0.95rem; line-height: 1;
  cursor: pointer; transition: opacity 0.12s, transform 0.12s, background 0.12s;
}
.dm-thread:hover .dm-thread-del { opacity: 0.7; }
.dm-thread-del:hover { opacity: 1; transform: scale(1.12); background: rgba(255, 255, 255, 0.06); }
@media (hover: none) { .dm-thread-del { opacity: 0.6; } }   /* touch has no hover */

/* Unread/request badge on the Friends tab in the menu (mirrors the hamburger). */
.drawer-tab-badge {
  position: absolute; top: 1px; right: 1px;
  min-width: 15px; height: 15px; padding: 0 4px; box-sizing: border-box;
  background: #e15454; color: #fff; font-size: 0.6rem; font-weight: 700;
  line-height: 15px; text-align: center; border-radius: 8px;
  box-shadow: 0 0 0 2px #0d0f14; pointer-events: none;
}
.drawer-tab-badge.hidden { display: none; }

/* Reaction chips under a bubble. */
.dm-reacts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.dm-react-chip {
  display: inline-flex; align-items: center; gap: 3px; padding: 1px 6px;
  border-radius: 11px; border: 1px solid var(--dark-border);
  background: rgba(255, 255, 255, 0.05); color: var(--text-primary);
  font-size: 0.82rem; line-height: 1.5; cursor: pointer;
}
.dm-react-chip.mine { border-color: var(--primary); background: rgba(var(--primary-rgb), 0.18); }
.dm-react-n { font-size: 0.7rem; color: var(--text-secondary); }
/* The right-click / long-press reaction picker reuses global chat's
   .reaction-picker styling (chat.css) so the bin + ＋ grid look identical. */

/* Compose emoji picker (the smiley button) — floats above the input. */
#dm-compose { position: relative; }
.dm-emoji-pop {
  position: absolute; bottom: calc(100% + 6px); right: 6px;
  width: 244px; max-height: 196px; overflow-y: auto;
  display: flex; flex-wrap: wrap; gap: 1px; padding: 8px;
  border-radius: 10px; background: #1c2030; border: 1px solid var(--dark-border);
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.45); z-index: 6000;
}
.dm-emoji-pop.hidden { display: none; }
.dm-emoji-pop .emoji-item {
  border: none; background: none; cursor: pointer; font-size: 1.2rem;
  line-height: 1; padding: 3px; border-radius: 6px;
}
.dm-emoji-pop .emoji-item:hover { background: rgba(255, 255, 255, 0.08); }

/* ── Shared DM conversation component (DMThread) ──────────────────────────
   Fills its host (the dock's #dm-thread-host or the friends-drawer body) as a
   flex column: scrolling messages above, compose pinned below. */
.dmt-host { flex: 1 1 auto; min-height: 0; display: flex; }
.dmt { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; height: 100%; }
.dmt-scroll { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
.dmt-compose { flex: 0 0 auto; position: relative; }
.friends-drawer .side-drawer-body > .dmt { flex: 1; min-height: 0; }

/* The whole friend row is click-to-DM. */
.friend-row:not(.pending) { cursor: pointer; }

/* System "XES" welcome thread (client-only, shown to newcomers). */
.dm-thread-system .dm-thread-name { color: var(--primary); }
.dm-intro-bubble { max-width: 100%; white-space: pre-wrap; }
.dm-intro-note {
    margin-top: 10px;
    font-size: 0.7rem;
    color: var(--text-secondary);
    text-align: center;
    opacity: 0.8;
}

/* DM thread compose reuses the global chat strip (.chat-strip / .chat-text-input
   / .chat-icon-btn / .chat-emoji-btn / .chat-send-btn in chat.css) so the two
   inputs stay identical — no DM-specific compose rules here. */

/* Unified-box header (DM | User | Global). Shown wherever the dock IS the chat:
   quiet, social, and chat. In 'centred' the dock is just the DM list, so the
   tabs stay hidden there. */
.dm-tabs { display: none; align-items: center; gap: 2px; }
.dm-controls { display: none; align-items: center; gap: 2px; margin-left: auto; flex-shrink: 0; }
.app-layout[data-layout="quiet"]  .dm-tabs,
.app-layout[data-layout="social"] .dm-tabs,
.app-layout[data-layout="quiet"]  .dm-controls,
.app-layout[data-layout="social"] .dm-controls { display: flex; }
/* The collapse chevron folds the box into its header — only meaningful in
   Quiet (the other layouts let the box fill its column). */
.dm-ctl[data-act="collapse"] { display: none; }
.app-layout[data-layout="quiet"] .dm-ctl[data-act="collapse"] { display: flex; }
.dm-ctl { background: none; border: none; color: var(--text-secondary); cursor: pointer; padding: 2px 7px; display: flex; align-items: center; border-radius: 6px; line-height: 0; }
.dm-ctl svg { width: 18px; height: 18px; }
.dm-ctl:hover { color: var(--text-primary); background: rgba(255,255,255,0.08); }
.dm-ctl[data-act="collapse"] svg { transition: transform 0.15s ease; }
.app-layout[data-layout="quiet"] .dm-dock:not(.collapsed) .dm-ctl[data-act="collapse"] svg { transform: rotate(180deg); }
/* Tab buttons: DM + Call text pills. */
.dm-tab {
    background: none; border: none; cursor: pointer; border-radius: 6px; padding: 3px 8px;
    font-size: 0.73rem; font-family: "Exo 2", sans-serif; font-weight: 500;
    color: var(--text-secondary); line-height: 1;
    transition: background 0.12s, color 0.12s;
}
.dm-tab:hover { background: rgba(255,255,255,0.07); color: var(--text-primary); }
.dm-tab.active { background: var(--deep-blue); color: #fff; }
/* Dedicated DM box (centred layout): a plain "Messages" title instead of the
   tab switcher. Shown in every layout via JS (controls() returns it when the
   dock isn't the unified box). */
.dm-head-title { font-size: 0.73rem; font-weight: 500; font-family: "Exo 2", sans-serif; color: var(--text-secondary); letter-spacing: normal; line-height: 1; padding: 3px 0; }   /* match the left chat header (.chat-tab): same font, size + vertical footprint so the two header bars line up */
/* Collapsed (Quiet only) → just the header bar. The #dm-dock id is needed to
   outweigh the quiet sizing rule (which also uses the id + min-height). */
/* Open/close slides — the whole box unfolds from / folds back into its header bar
   (max-height on the dock so the inner chat keeps a real height to fill). */
.app-layout[data-layout="quiet"] .panel-left #dm-dock.collapsed { max-height: 40px; }
/* Mobile hides the dock by default (DMs live in the Friends drawer there) —
   but Dashboard uses the dock as the unified chat, so keep it there. */
@media (max-width: 800px) { .dm-dock { display: none; } }
@media (max-width: 800px) {
    .app-layout[data-layout="social"] .dm-dock { display: flex; }
}

/* Dashboard (social): the dock IS the chat — fill the centre column and hide
   the now-redundant standalone chat-area (it lives inside the dock when hosted;
   when the dock shows the DM list, the chat-area is parked in the centre
   column and must stay hidden so the dock reads as the single chat box). */
.app-layout[data-layout="social"] .center-col #dm-dock {
    flex: 1 1 auto; max-height: none; min-height: 0;
    border: 1px solid rgba(255,255,255,0.07);
    border-radius: 0;   /* square top + bottom — no rounded corners here */
}
.app-layout[data-layout="social"] .center-col > #chat-area { display: none; }

/* ── "Call + DMs" layout (desktop) ───────────────────────────────────
   global chat left · call box centre · DMs right · no profile card. Equal-width
   flanks + a centred row keep the call box dead centre; the layout selector stays
   in the right column (above the DMs) so you can switch back. Mobile keeps the
   call box on top (this is desktop-only). */
@media (min-width: 801px) {
    .app-layout[data-layout="centred"] .center-col { order: -1; flex: 1 1 0; }
    .app-layout[data-layout="centred"] .panel-left { flex: 0 0 420px; }
    .app-layout[data-layout="centred"] .panel-right { flex: 1 1 0; width: auto; min-width: 0; padding: 0; gap: 0; }   /* equal flank + let the DM dock fill the panel edge-to-edge (no box-in-box) */
    .app-layout[data-layout="centred"] .profile-card { display: none; }
    .app-layout[data-layout="centred"] .panel-right #dm-dock {
        flex: 1 1 auto; max-height: none; min-height: 0;
        border: none;       /* fills the whole panel — no inner box outline */
        border-radius: 0;
    }
    /* The left chat header's globe icon inflates its bar to ~42px; the
       Messages header is shorter. Pin it to the same height so the two line up. */
    .app-layout[data-layout="centred"] .panel-right .dm-head { min-height: 42px; }
}

/* ── "Quiet" layout — just the call box + DMs (no global chat, no profile) ──
   One centred column: call box on top, DMs below, layout selector at the foot so
   you can switch back. The chat + profile columns are dropped at all widths; the
   centring + column width are desktop-only. */
.app-layout[data-layout="quiet"] .center-col,
.app-layout[data-layout="quiet"] .panel-right { display: none; }
.app-layout[data-layout="quiet"] .panel-left #dm-dock {
    flex: 1 1 auto; width: 100%; min-height: 0; max-height: 50vh; overflow: hidden;
    border: 1px solid rgba(255,255,255,0.07); border-radius: 10px;
    transition: max-height 0.34s cubic-bezier(0.4, 0, 0.2, 1);
}
@media (min-width: 801px) {
    .app-layout[data-layout="quiet"] { justify-content: center; }
    .app-layout[data-layout="quiet"] .panel-left { flex: 0 0 420px; border-right: none; }
}
/* Quiet is the default, so it has to read the same on mobile: show the DMs (which
   are otherwise hidden ≤800px) and let the call box + DMs fill the screen. */
@media (max-width: 800px) {
    .app-layout[data-layout="quiet"] .panel-left { flex: 1; min-height: 0; }
    .app-layout[data-layout="quiet"] .panel-left #dm-dock { display: flex; }
}

/* ── Shared FIXED tab header for the menu panels (Filters / Friends / Video room).
   It sits above the drawers and stays put; only the panel below it slides. ──── */
.drawer-tabs {
    position: fixed; top: 0; right: 0; width: 440px; max-width: 92vw; z-index: 1201;
    display: flex; gap: 4px; padding: 10px 10px;
    background: #0a0c14;
    border-left: 1px solid rgba(255,255,255,0.06);
    border-bottom: 1px solid rgba(255,255,255,0.07);
    transform: translateX(100%);
    transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.drawer-tabs.show { transform: translateX(0); }
/* Menu panels leave room for the fixed bar overhead. */
.menu-drawer { padding-top: 62px; }
.drawer-tab {
    flex: 1; min-width: 0; display: flex; align-items: center; justify-content: center;
    height: 40px; border-radius: 9px; cursor: pointer;
    background: rgba(255,255,255,0.04); border: 1px solid transparent; color: var(--text-secondary);
    transition: background 0.14s, color 0.14s, border-color 0.14s;
}
.drawer-tab svg { width: 20px; height: 20px; }
.drawer-tab:hover { background: rgba(255,255,255,0.09); color: var(--text-primary); }
.drawer-tab.active { background: var(--deep-blue); color: #fff; border-color: rgba(255,255,255,0.16); }
/* Exit sits at the end as the single close affordance now the per-panel X
   has been retired. A small left-margin separates it from the tab cluster. */
.drawer-tab-exit { margin-left: 4px; flex: 0 0 40px; color: var(--text-secondary); }
.drawer-tab-exit:hover { background: rgba(255,90,90,0.18); color: #ff9b9b; border-color: rgba(255,90,90,0.28); }

/* Staff tabs — hidden until refreshStaffTabs() confirms the role. */
.drawer-tab.staff-tab-hidden { display: none; }

/* Mod tab — red shield palette */
.drawer-tab[data-tab="mod"] { color: #fca5a5; }
.drawer-tab[data-tab="mod"]:hover { background: rgba(156,86,86,0.28); color: #fca5a5; border-color: rgba(196,124,124,0.35); }
.drawer-tab[data-tab="mod"].active { background: #9c5656; border-color: #c47c7c; color: #fca5a5; }

/* Admin tab — gold star palette */
.drawer-tab[data-tab="admin"] { color: #e0b347; }
.drawer-tab[data-tab="admin"]:hover { background: rgba(183,121,31,0.28); color: #f0c44f; border-color: rgba(224,179,71,0.35); }
.drawer-tab[data-tab="admin"].active { background: #b7791f; border-color: #e0b347; color: #fff; }


/* Mobile: match the bar to the full-width drawer. This MUST sit after the base
   .drawer-tabs rule above, or its 440px width wins on source order. */
@media (max-width: 600px) {
    .drawer-tabs { width: 100%; max-width: 100%; }
}

/* Create-room panel (host setup; Join → loading → room.html). */
.cr-panel { padding: 0 0 26px; }
.cr-blurb { font-size: 0.88rem; color: var(--text-secondary); line-height: 1.55; margin: 0 0 16px; }
/* Premium note — same treatment as the gender-filter "earned" note. */
.cr-note {
    margin: 0 0 20px; padding: 10px 12px;
    font-size: 0.82rem; line-height: 1.45;
    color: #fde68a; background: rgba(252, 211, 77, 0.1);
    border: 1px solid rgba(252, 211, 77, 0.25); border-radius: 9px;
}
.cr-field { margin-bottom: 16px; }
.cr-field label { display: block; font-size: 0.78rem; color: var(--text-secondary); margin-bottom: 6px; }
.cr-field input, .cr-field select {
    width: 100%; box-sizing: border-box;
    background: rgba(255,255,255,0.05); border: 1px solid rgba(255,255,255,0.1); border-radius: 9px;
    padding: 10px 12px; color: var(--text-primary); font-size: 0.9rem; outline: none;
}
.cr-field input:focus, .cr-field select:focus { border-color: var(--primary); }
.cr-check { display: flex; align-items: center; gap: 9px; font-size: 0.86rem; color: var(--text-secondary); margin: 4px 0 22px; cursor: pointer; }
.cr-check input { width: 16px; height: 16px; flex-shrink: 0; }
.cr-join { width: 100%; background: var(--primary); color: #04222b; border: none; border-radius: 10px; padding: 13px; font-weight: 700; font-size: 0.95rem; cursor: pointer; }
.cr-join:hover { filter: brightness(1.07); }

/* ── Room loading cover — create video room → room.html ─────────────── */
.room-loading {
    position: fixed; inset: 0; z-index: 2000;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 18px;
    background: radial-gradient(ellipse at center, #0e1430 0%, #06070d 70%);
    color: var(--text-primary); opacity: 0; pointer-events: none;
    transition: opacity 0.2s ease;
}
.room-loading.show { opacity: 1; pointer-events: auto; }
.room-loading p { font-size: 0.95rem; color: var(--text-secondary); letter-spacing: 0.02em; }
.room-loading-spinner {
    width: 46px; height: 46px; border-radius: 50%;
    border: 3px solid rgba(255,255,255,0.14); border-top-color: var(--primary);
    animation: room-spin 0.8s linear infinite;
}
@keyframes room-spin { to { transform: rotate(360deg); } }
