/* === Repartee Web Base Styles === */

/* Nerd Font for terminal (powerline glyphs, icons) */
@font-face {
    font-family: 'FiraCode Nerd Font Mono';
    src: url('/fonts/FiraCodeNerdFontMono-Regular.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
    font-display: block;
}

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body {
    /* Stable layout-viewport height. Using `100dvh` here caused the page
       to animate frame-by-frame as iOS Safari and Chrome Android
       expanded/collapsed their URL bars and virtual keyboard, which
       triggered our resize handlers on every frame and produced visible
       scroll drift. The lounge uses `100%` for the same reason — the
       chat scroll container fills whatever the layout viewport happens
       to be at startup and stays there. The virtual keyboard then
       either overlays (iOS Safari) or resizes the container (Android
       Chrome with `interactive-widget=resizes-content`, which we
       removed because it added more state changes than it solved). */
    height: 100%;
    background: var(--bg);
    color: var(--fg);
    font-family: 'FiraCode Nerd Font Mono', 'JetBrains Mono', 'Fira Code', 'SF Mono', 'Cascadia Code', monospace;
    font-size: 13px;
    line-height: var(--line-height, 1.35);
    overflow: hidden;
    overscroll-behavior: none;
    /* Disables pull-to-refresh and pinch-zoom on touch. Without this,
       a slow swipe inside `.chat-messages` could reach the top and
       turn into a Chrome refresh gesture, which fires synthetic scroll
       events that desync our `is_at_bottom` flag. */
    touch-action: none;
}

/* === Layout === */

.app {
    display: flex;
    flex-direction: column;
    height: 100%;
    overflow: hidden;
}

.desktop-only {
    display: flex;
    flex-direction: column;
    flex: 1;
    overflow: hidden;
}

.topic-bar {
    background: var(--bg-alt);
    padding: 2px 8px;
    height: 20px;
    display: flex;
    align-items: center;
    overflow: hidden;
    white-space: nowrap;
    border-bottom: 1px solid var(--border);
}

.main-area {
    display: flex;
    flex: 1;
    overflow: hidden;
}

/* === Buffer List (left panel) === */

.buffer-list {
    width: 170px;
    background: var(--bg);
    border-right: 1px solid var(--border);
    overflow-y: auto;
    flex-shrink: 0;
    padding: 1px 0;
}

.buffer-list .buffer-item {
    padding: 0 6px;
    line-height: 1.4;
    cursor: pointer;
}

.buffer-list .buffer-item:hover { background: rgba(255,255,255,0.03); }

.buffer-list .buffer-item.active {
    background: rgba(122, 162, 247, 0.1);
    border-left: 2px solid var(--accent);
}

.buffer-item .num { color: var(--fg-muted); }
.buffer-item .name { color: var(--fg-dim); }
.buffer-item.type-server { margin-top: 4px; border-top: 1px solid var(--border); padding-top: 2px; }
.buffer-item.type-server:first-child { margin-top: 0; border-top: none; padding-top: 0; }
.buffer-item.type-server .num { color: var(--accent); }
.buffer-item.type-server .name { color: var(--accent); font-weight: bold; }
.buffer-item.type-query .name { color: var(--cyan); }
.buffer-item.type-dcc .name { color: var(--yellow); }
.buffer-item.active .num { color: var(--yellow); }
.buffer-item.active .name { color: var(--bright); font-weight: bold; }
.buffer-item.activity-1 .name { color: var(--green); }
.buffer-item.activity-2 .name { color: var(--red); }
.buffer-item.activity-3 .name { color: var(--yellow); }
.buffer-item.activity-4 .name { color: var(--purple); }

/* === Chat View (center) === */

.chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.chat-messages {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 2px 0;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    /* The pin in chat_view.rs is the only thing that decides where the
       viewport sits. Browser scroll-anchoring would otherwise fight us
       whenever an image preview decoded or a wrapped line re-measured. */
    overflow-anchor: none;
}

.chat-messages-outer {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
}

/* Wrapper for the `<For>` children inside .chat-messages. Kept as a
   single flex column so message rows behave predictably during
   programmatic scroll pins. */
.chat-messages-inner {
    display: flex;
    flex-direction: column;
}

.scroll-bottom-btn {
    position: absolute;
    bottom: 8px;
    right: 12px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--bg-alt);
    border: 1px solid var(--border);
    color: var(--fg-muted);
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 5;
    opacity: 0.85;
    transition: opacity 0.15s;
    -webkit-tap-highlight-color: transparent;
}

.scroll-bottom-btn:hover { opacity: 1; }
.scroll-bottom-btn.hidden { display: none; }

/* Chat line — flex row, all items on same baseline.
   No `content-visibility` here: while it skips layout for off-screen
   lines, the deferred measurement makes scrollHeight grow whenever a
   line crosses into the viewport, which fights the scroll pin and was
   visible as up-then-down jitter on mobile. We can afford the full
   1000-row layout cost on every modern browser; thelounge does the
   same. If real-world perf ever justifies it, swap in a windowed
   renderer rather than re-introducing CSS virtualization. */
.chat-line {
    padding: 0 8px;
    display: flex;
    align-items: baseline;
    line-height: var(--line-height, 1.35);
    max-width: 100%;
    overflow: hidden;
}

.chat-line .ts {
    width: 70px;
    flex-shrink: 0;
    color: var(--fg-dim);
}
.chat-line .nick {
    flex-shrink: 0;
    text-align: right;
    white-space: nowrap;
}
.chat-line .nick .mode { color: var(--fg-muted); }
.chat-line .nick .name { color: var(--accent); font-weight: bold; }
.chat-line .nick .sep { color: var(--accent); margin-left: 2px; }
.chat-line .text {
    padding-left: 4px;
    flex: 1;
    min-width: 0;
    white-space: pre-wrap;
    overflow-wrap: break-word;
}

/* Own message nick = green */
.chat-line.own .nick .name { color: var(--green); }
.chat-line.own .text { color: var(--bright); }

/* Mention/highlight background */
.chat-line.mention { background: var(--mention-bg); }
.chat-line.mention .text { color: var(--purple); }
.chat-line.highlight { background: var(--highlight-bg); }
.chat-line.highlight .text { color: var(--red); }

/* Mention log: pre-formatted line (mentions buffer) — no timestamp/nick column */
.chat-line.mention-log { background: var(--mention-bg); }
.chat-line.mention-log .mention-log-text { color: var(--purple); }

/* Date/backlog separator: centered, dimmed, no timestamp */
.chat-line.date-separator {
    justify-content: center;
    color: var(--fg-dim);
    padding: 4px 8px;
    opacity: 0.7;
}
.chat-line.date-separator .separator-text {
    text-align: center;
    letter-spacing: 0.5px;
}

/* Events: no nick column — text follows timestamp inline */

.chat-line .join-arrow { color: var(--green); }
.chat-line .part-arrow { color: var(--yellow); }
.chat-line .quit-arrow { color: var(--red); }
.chat-line .nick-arrow { color: var(--purple); }
.chat-line .kick-arrow { color: var(--red); }
.chat-line .kicked-arrow { color: var(--red); }
.chat-line .topic-arrow { color: var(--cyan); }
.chat-line .mode-arrow { color: var(--fg-muted); }
.chat-line .connect-arrow { color: var(--green); }
.chat-line .disconnect-arrow { color: var(--red); }
.chat-line .chghost-arrow { color: var(--purple); }
.chat-line .account-arrow { color: var(--fg-muted); }

/* Event-key-specific text coloring */
.chat-line.join-event { color: var(--green); }
.chat-line.part-event { color: var(--yellow); }
.chat-line.kick-event { color: var(--yellow); }
.chat-line.kicked-event { color: var(--red); font-weight: bold; }
.chat-line.nick-event { color: var(--purple); }
.chat-line.topic-event { color: var(--cyan); }
.chat-line.mode-event { color: var(--fg-muted); }

/* Action: * nick action text */
.chat-line.action { color: var(--yellow); }

/* Notice: -nick- text */
.chat-line.notice { color: var(--cyan); }
.chat-line .notice-body { color: var(--fg-muted); }
.chat-line .notice-nick { color: var(--cyan); }

/* === Nick List (right panel) === */

.nick-list {
    width: 150px;
    background: var(--bg);
    border-left: 1px solid var(--border);
    overflow-y: auto;
    flex-shrink: 0;
    padding: 1px 0;
}

.nick-list .mode-group {
    padding: 0 6px;
    color: var(--fg-muted);
    font-size: 9px;
    text-transform: uppercase;
    letter-spacing: 1px;
    line-height: 1.6;
    margin-top: 3px;
}

.nick-list .mode-group:first-child { margin-top: 0; }

.nick-list .nick-entry {
    padding: 0 6px;
    line-height: 1.4;
    cursor: pointer;
}

.nick-entry .prefix-op { color: var(--green); }
.nick-entry .prefix-voice { color: var(--cyan); }
.nick-entry .prefix-normal { color: var(--fg-muted); }
.nick-entry.away { opacity: 0.4; }

/* === Bottom: Status + Input === */

.bottom-bar {
    background: var(--bg-alt);
    border-top: 1px solid var(--border);
    padding-bottom: env(safe-area-inset-bottom);
    /* Plain flex item — `flex: 0 0 auto` so the bar takes only its
       intrinsic height and the sibling `.chat-messages` (flex: 1)
       fills everything else. No `position: sticky`: sticky inside a
       flex column intermittently detached during the iOS Safari URL-
       bar collapse animation and on Android keyboard open. */
    flex: 0 0 auto;
}

.status-line {
    padding: 1px 8px;
    height: 17px;
    display: flex;
    align-items: center;
    white-space: nowrap;
    font-size: 12px;
}

.status-line .bracket { color: var(--fg-dim); }
.status-line .sep { color: var(--fg-dim); }
.status-line .nick { color: var(--accent); }
.status-line .muted { color: var(--fg-muted); }
.status-line .act-green { color: var(--green); }
.status-line .act-yellow { color: var(--yellow); }
.status-line .act-red { color: var(--red); }
.status-line .act-purple { color: var(--purple); }

.input-line {
    padding: 2px 8px;
    display: flex;
    align-items: center;
    gap: 6px;
}

.input-line .prompt { color: var(--accent); }

.input-line textarea {
    flex: 1;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--fg);
    padding: 4px 8px;
    border-radius: 3px;
    outline: none;
    font-family: inherit;
    font-size: 13px;
    line-height: var(--line-height, 1.35);
    resize: none;
    overflow: hidden;
    min-height: 0;
}

.input-line textarea:focus { border-color: var(--accent); }

.input-line .send-btn {
    background: var(--accent);
    color: var(--bg);
    border: none;
    padding: 4px;
    border-radius: 3px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 28px;
    min-height: 28px;
    flex-shrink: 0;
    -webkit-tap-highlight-color: transparent;
}

/* === Login === */

.login-page {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
    gap: 16px;
}

.login-box {
    background: var(--bg-alt);
    border: 1px solid var(--border);
    border-radius: 8px;
    padding: 24px;
    min-width: 300px;
    text-align: center;
}

.login-box input {
    width: 100%;
    background: var(--bg);
    border: 1px solid var(--border);
    color: var(--fg);
    padding: 8px 12px;
    border-radius: 4px;
    outline: none;
    font-family: inherit;
    font-size: 14px;
    margin-bottom: 12px;
}

.login-box button {
    width: 100%;
    background: var(--accent);
    color: var(--bg);
    border: none;
    padding: 8px 16px;
    border-radius: 4px;
    cursor: pointer;
    font-family: inherit;
    font-size: 14px;
}

.login-box .error { color: var(--red); font-size: 12px; margin-top: 8px; }

/* === Mentions Badge === */

.mention-badge {
    color: var(--purple);
    font-size: 10px;
    background: rgba(187, 154, 247, 0.2);
    padding: 0 5px;
    border-radius: 8px;
    cursor: pointer;
}

/* === Mobile === */

/* Desktop: hide mobile elements */
@media (min-width: 768px) {
    .mobile-only { display: none !important; }
}

/* Mobile: hide desktop, show mobile */
@media (max-width: 767px) {
    .desktop-only { display: none !important; }
    .mobile-only {
        display: flex;
        flex-direction: column;
        height: 100%;
        overflow: hidden;
        /* Re-enable pan-y inside the mobile container so vertical
           scroll works in `.chat-messages`. The body-level
           `touch-action: none` blocks pull-to-refresh; we narrow it
           back to pan-y here so the chat list itself remains
           scrollable. Horizontal swipe is still handled by JS. */
        touch-action: pan-y;
        overscroll-behavior: none;
    }

    .buffer-list, .nick-list {
        display: none; /* hidden by default, shown inside slide-out panels */
    }

    /* Chat area — vertical scroll only, no horizontal */
    .chat-area {
        overflow: hidden;
        min-width: 0;
    }
    .chat-messages {
        touch-action: pan-y;
    }

    /* Inline chat layout — no nick column */
    .chat-line {
        display: block;
        padding: 0 6px;
        overflow: hidden;
        overflow-wrap: anywhere;
    }
    .chat-line .ts {
        display: inline;
        width: auto;
        margin-right: 4px;
    }
    .chat-line .nick {
        display: inline;
        width: auto;
        text-align: left;
    }
    .chat-line .text {
        display: inline;
        padding-left: 0;
        overflow-wrap: anywhere;
    }

    /* Mobile top bar */
    .mobile-topbar {
        display: flex;
        background: var(--bg-alt);
        padding: 4px 8px;
        align-items: center;
        border-bottom: 1px solid var(--border);
        min-height: 28px;
        flex-shrink: 0;
        touch-action: pan-y;
    }
    .mobile-topbar .hamburger,
    .mobile-topbar .nicklist-btn {
        color: var(--fg-muted);
        cursor: pointer;
        font-size: 16px;
        padding: 2px 4px;
        -webkit-tap-highlight-color: transparent;
    }
    .mobile-topbar-center {
        flex: 1;
        text-align: center;
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        padding: 0 8px;
    }
    .mobile-topbar .mobile-chan {
        color: var(--accent);
        font-weight: bold;
        font-size: 13px;
    }
    .mobile-topbar .mobile-topic {
        color: var(--fg-muted);
        font-size: 11px;
    }
    .mobile-topbar-right {
        display: flex;
        gap: 6px;
        align-items: center;
        flex-shrink: 0;
    }

    /* Slide-out overlay — always in DOM, toggled via .visible */
    .slide-overlay {
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.5);
        z-index: 10;
        opacity: 0;
        pointer-events: none;
        transition: opacity 0.2s ease;
    }
    .slide-overlay.visible {
        opacity: 1;
        pointer-events: auto;
    }

    .slide-panel-left {
        position: fixed;
        left: 0; top: 0; bottom: 0;
        width: 220px;
        background: var(--bg-alt);
        border-right: 1px solid var(--border);
        z-index: 11;
        overflow-y: auto;
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        display: flex;
        flex-direction: column;
        touch-action: pan-y;
        will-change: transform;
    }
    .slide-panel-left.open { transform: translateX(0); }

    .slide-panel-right {
        position: fixed;
        right: 0; top: 0; bottom: 0;
        width: 180px;
        background: var(--bg-alt);
        border-left: 1px solid var(--border);
        z-index: 11;
        overflow-y: auto;
        transform: translateX(100%);
        transition: transform 0.2s ease;
        display: flex;
        flex-direction: column;
        touch-action: pan-y;
        will-change: transform;
    }
    .slide-panel-right.open { transform: translateX(0); }

    .slide-panel-header {
        padding: 8px 10px;
        border-bottom: 1px solid var(--border);
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex-shrink: 0;
    }

    /* Override desktop buffer-list/nick-list styles inside panels */
    .slide-panel-left .buffer-list,
    .slide-panel-right .nick-list {
        display: block;
        width: auto;
        border: none;
    }

    /* Compact status bar on mobile */
    .status-line { font-size: 11px; }

    /* Touch-friendly input — 16px prevents iOS Safari auto-zoom on focus */
    .input-line textarea {
        font-size: 16px;
        padding: 6px 8px;
    }
}

/* === Theme switcher === */

.theme-picker {
    display: flex;
    gap: 4px;
    padding: 2px 8px;
    justify-content: center;
    background: var(--bg-alt);
}

.theme-swatch {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    cursor: pointer;
    border: 1px solid transparent;
}

.theme-swatch.active { border-color: var(--accent); }
.theme-swatch:hover { border-color: var(--fg-muted); }

/* === Shell terminal view (beamterm WebGL2 canvas) === */

.shell-terminal {
    flex: 1 1 0;
    display: block;
    width: 100%;
    min-height: 0;
    background: #000;
    outline: none;
}

.shell-terminal:focus {
    box-shadow: inset 0 0 0 1px var(--accent);
}

/* === Clickable links === */

.msg-link {
    color: var(--link, #87cefa);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    cursor: pointer;
    word-break: break-all;
}

.msg-link:hover {
    text-decoration-thickness: 2px;
}

/* === Inline built-in emotes (:name:) === */
.emote {
    height: 1.4em;
    width: auto;
    vertical-align: middle;
    margin: 0 1px;
    /* Preserve animated GIF crispness for small pixel-art emotes. */
    image-rendering: auto;
}

/* Visually-hidden ":name:" kept in the DOM so copy/paste and screen readers
   still surface the shortcode for an emote rendered as an <img>. */
.emote-code {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* === Link image previews === */

.msg-previews {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 4px 0 2px 56px; /* indent under the message text column */
}

.msg-preview-card {
    position: relative;
    /* Hidden by default. The card is only revealed (`.loaded` added by
       the image's onload handler) when the thumbnail actually loads,
       so previews whose fetch fails — x.com tweets blocking og:image,
       dead imgur links, /api/preview returning 502 — never flash a
       placeholder box on screen, and never trigger the
       reserve-then-collapse reflow that caused the visible jitter.
       Trade-off: `loading="lazy"` is incompatible with display:none
       (IntersectionObserver doesn't fire on hidden subtrees), so all
       preview images for messages currently in the For are fetched
       eagerly. The server-side thumbnail cache + browser HTTP cache
       absorb the cost; per-message preview count is capped by
       `web.image_previews_max_per_msg`. */
    display: none;
}
.msg-preview-card.loaded {
    display: inline-block;
    /* No `content-visibility`: same jitter source as on `.chat-line` —
       re-measuring when the card crossed the viewport boundary grew
       scrollHeight and fought the pin. The fixed thumb dimensions
       below already reserve layout space synchronously. */
}

.msg-preview-thumb {
    display: block;
    /* Fixed box reserves layout space BEFORE the image loads, so async
       loads don't reflow the chat (which is anchored to bottom — every
       reflow visibly jumps the scroll position). `object-fit: contain`
       letterboxes images smaller than the box. */
    width: 320px;
    height: 200px;
    border: 1px solid var(--border, rgba(128, 128, 128, 0.25));
    border-radius: 4px;
    background: var(--bg-alt, #111);
    object-fit: contain;
}

.msg-preview-dismiss {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 18px;
    height: 18px;
    border: none;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 14px;
    line-height: 16px;
    text-align: center;
    cursor: pointer;
    padding: 0;
    opacity: 0;
    transition: opacity 0.15s ease;
}

.msg-preview-card:hover .msg-preview-dismiss {
    opacity: 1;
}

@media (max-width: 720px) {
    .msg-previews { margin-left: 0; }
    .msg-preview-thumb {
        /* Full-width on mobile; `aspect-ratio` reserves vertical space
           proportionally so the layout doesn't jump when the image loads. */
        width: 100%;
        height: auto;
        aspect-ratio: 16 / 10;
    }
    .msg-preview-dismiss { opacity: 1; } /* always visible on touch */
}

/* ===== Add-server wizard modal ===== */
.wizard-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 40;
}
.wizard-modal {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: min(460px, 92vw);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    background: var(--bg-alt);
    border: 1px solid var(--border);
    border-radius: 10px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
    z-index: 41;
}
.wizard-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border);
}
.wizard-head h3 { margin: 0; font-size: 15px; color: var(--fg); }
.wizard-x { cursor: pointer; color: var(--fg-muted); font-size: 16px; }
.wizard-x:hover { color: var(--fg); }
.wizard-tabs { display: flex; gap: 4px; padding: 10px 16px 0; }
.wizard-tab {
    padding: 6px 14px;
    border: none;
    background: transparent;
    color: var(--fg-muted);
    cursor: pointer;
    border-radius: 7px 7px 0 0;
    font-size: 13px;
}
.wizard-tab.active { background: var(--bg); color: var(--fg); }
.wizard-body {
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    overflow-y: auto;
}
.wizard-row { display: flex; flex-direction: column; gap: 4px; }
.wizard-row label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--fg-muted);
}
.wizard-row input,
.wizard-row select {
    background: var(--bg);
    border: 1px solid var(--border);
    border-radius: 6px;
    padding: 7px 9px;
    color: var(--fg);
    font-size: 13px;
}
.wizard-row input:focus,
.wizard-row select:focus { outline: none; border-color: var(--accent); }
.wizard-check {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 13px;
    color: var(--fg);
}
.wizard-error { color: #e06c75; font-size: 12px; margin: 0 16px; }
.wizard-foot {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 16px;
    border-top: 1px solid var(--border);
}
.wizard-btn {
    padding: 7px 16px;
    border-radius: 7px;
    border: none;
    cursor: pointer;
    font-size: 13px;
}
.wizard-btn.p { background: var(--accent); color: var(--bg); font-weight: 600; }
.wizard-btn.s { background: var(--border); color: var(--fg); }
.add-network-btn {
    width: calc(100% - 8px);
    margin: 4px;
    border: 1px dashed var(--border);
    background: transparent;
    color: var(--fg-muted);
    border-radius: 6px;
    padding: 5px;
    cursor: pointer;
    font-size: 12px;
}
.add-network-btn:hover { color: var(--accent); border-color: var(--accent); }
.error-toast {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: min(560px, 92vw);
    padding: 10px 14px;
    background: var(--bg-alt);
    border: 1px solid var(--red);
    border-radius: 8px;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    z-index: 60;
}
.error-toast-msg { color: var(--red); font-size: 13px; }
.error-toast-x { cursor: pointer; color: var(--fg-muted); font-size: 14px; }
.error-toast-x:hover { color: var(--fg); }

/* === Emote / emoji pickers === */
.emote-picker-modal,
.emoji-picker-modal {
    position: fixed;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    z-index: 41;
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px;
    background: var(--bg-alt);
    border: 1px solid var(--fg-muted);
    border-radius: 8px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
}
.emote-picker-modal { width: min(560px, 92vw); max-height: 70vh; }
.emoji-picker-modal { width: min(420px, 92vw); max-height: 70vh; }

.emote-picker-filter {
    font-family: inherit;
    font-size: 13px;
    padding: 6px 8px;
    background: var(--bg);
    color: var(--fg);
    border: 1px solid var(--fg-muted);
    border-radius: 4px;
}
.emote-picker-filter:focus { outline: none; border-color: var(--accent); }

.emote-picker-grid {
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    gap: 6px;
}
.emote-picker-cell {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 6px;
    cursor: pointer;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--fg);
}
.emote-picker-cell:hover { border-color: var(--accent); background: var(--bg); }
.emote-picker-cell img { width: 32px; height: 32px; object-fit: contain; }
.emote-picker-name {
    font-size: 11px;
    color: var(--fg-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 68px;
    white-space: nowrap;
}

.emoji-picker-tabs { display: flex; gap: 4px; flex-wrap: wrap; }
.emoji-tab {
    cursor: pointer;
    background: var(--bg);
    border: 1px solid var(--fg-muted);
    border-radius: 4px;
    color: var(--fg-muted);
    padding: 2px 8px;
    font-size: 12px;
}
.emoji-tab:hover { color: var(--fg); border-color: var(--accent); }
.emoji-picker-grid {
    overflow-y: auto;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(34px, 1fr));
    gap: 4px;
}
.emoji-cell {
    cursor: pointer;
    background: transparent;
    border: none;
    font-size: 22px;
    line-height: 1;
    padding: 4px;
    border-radius: 4px;
}
.emoji-cell:hover { background: var(--bg); }

/* Input-line picker buttons */
.input-emote-btn {
    font-family: inherit;
    font-size: 13px;
    padding: 0 8px;
    margin-right: 4px;
    cursor: pointer;
    background: transparent;
    border: 1px solid var(--fg-muted);
    border-radius: 4px;
    color: var(--fg-muted);
}
.input-emote-btn:hover { color: var(--fg); border-color: var(--accent); }

/* UTF-8 emoji button is desktop-only — phones provide a system emoji keyboard. */
@media (max-width: 767px) {
    .input-emote-btn.emoji { display: none; }
}

/* ── Scrollbars ──────────────────────────────────────────────────────────
   Safari/macOS draws thin, auto-hiding overlay scrollbars natively, so the UI
   looked clean there; every other browser fell back to wide, opaque OS
   scrollbars that eat layout width and clash with the theme. Style them to be
   thin, theme-coloured, and reveal only while the pointer is over the scrolling
   area — matching Safari across Chrome, Edge and Firefox. The thumb uses the
   per-theme --fg-muted / --fg-dim tokens, so it adapts to every theme. */

/* Firefox — inherits to every scrollable descendant. It cannot hide the thumb
   on hover, so it shows a permanently-thin themed bar (still far subtler than
   the default).

   Gated behind `@supports not selector(::-webkit-scrollbar)` so ONLY Firefox
   applies it: Chrome/Edge 121+ now support `scrollbar-color`, and when it is set
   they ignore the `::-webkit-scrollbar-*` pseudo-elements entirely — which would
   kill the reveal-on-hover thumb below and leave a permanently-visible bar. The
   feature query keeps WebKit browsers on the pseudo-element path. */
@supports not selector(::-webkit-scrollbar) {
    html {
        scrollbar-width: thin;
        scrollbar-color: var(--fg-muted) transparent;
    }
}

/* WebKit (Chrome, Edge, Safari) — thin track, no arrow buttons, rounded thumb. */
*::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}
*::-webkit-scrollbar-track,
*::-webkit-scrollbar-corner {
    background: transparent;
}
*::-webkit-scrollbar-thumb {
    /* Transparent (invisible) by default. The 2px transparent border plus
       background-clip:padding-box insets it into a slim rounded pill when shown. */
    background-color: transparent;
    border: 2px solid transparent;
    border-radius: 8px;
    background-clip: padding-box;
}
/* Reveal while the pointer is over the scrolling area; brighten while dragging. */
*:hover::-webkit-scrollbar-thumb {
    background-color: var(--fg-muted);
}
*::-webkit-scrollbar-thumb:hover,
*::-webkit-scrollbar-thumb:active {
    background-color: var(--fg-dim);
}
