:root {
    /* ── Design tokens (R49/F1) — single source of truth, document-wide.
       Values are unchanged from the prior palette so this is pixel-identical;
       the inline-style de-inline (F2) migrates onto these. ── */

    /* Surfaces */
    --bg-primary: #1a1a2e;
    --bg-secondary: #16213e;
    --bg-accent: #0f3460;
    /* Text */
    --text-primary: #e1e1e1;
    --text-secondary: #94a3b8;
    /* Brand accent — darkened from #e94560 so white button text meets WCAG
       4.5:1 (was 3.8:1). See scripts/contrast_audit.mjs. */
    --accent: #d61f52;
    --accent-hover: #ec4468;
    /* Accent used as TEXT on dark surfaces (links) — lightened so it clears
       WCAG 4.5:1; the button accent (#d61f52) is tuned for white text ON it and
       is too dark to BE text. (scripts/contrast_audit.mjs) */
    --accent-text: #f06a8a;
    --border: #0f3460;

    /* Status */
    --color-success: #22c55e;
    --color-success-soft: #4ade80;
    --color-danger: #ef4444;
    --color-danger-soft: #f87171;
    --color-warning-bg: #92400e;
    --color-warning-text: #fef3c7;

    /* Motion (R51/F4) — consistent transition timings; honour reduced-motion. */
    --transition-fast: 0.15s ease;
    --transition-base: 0.2s ease;

    /* Neutral slate scale — the palette the legacy inline styles draw from */
    --slate-50: #f1f5f9;
    --slate-300: #cbd5e1;
    --slate-400: #94a3b8;
    /* --slate-500 lightened from #64748b — used as small body text that failed
       contrast on the dark surfaces. (contrast_audit.mjs) */
    --slate-500: #8598ae;
    /* --slate-600 lightened from #475569: it was used for subtle TEXT that
       failed WCAG contrast on the dark surfaces. Borders that use it just get
       marginally lighter. (contrast_audit.mjs) */
    --slate-600: #8091a7;
    --slate-700: #334155;
    --slate-800: #1e293b;
    --slate-900: #0f172a;
}

* { box-sizing: border-box; }
/* Column layout so top-level banners (NAT warning) sit ABOVE the app in normal
   flow and push it down, instead of position:fixed overlaying the sidebar
   header. #app is the sidebar+chat row and takes the remaining height. */
body {
    margin: 0;
    padding: 0;
    font-family: system-ui, -apple-system, sans-serif;
    background: var(--bg-primary);
    color: var(--text-primary);
    height: 100vh;
    display: flex;
    flex-direction: column;
}

/* ── Desktop chrome polish ──
   Windows' default wide light scrollbars are the loudest "unstyled app" tell in
   a dark theme; use thin dark ones everywhere. */
* { scrollbar-width: thin; scrollbar-color: var(--slate-700) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--slate-700);
    border-radius: 5px;
    border: 2px solid transparent;
    background-clip: padding-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--slate-600); background-clip: padding-box; }

/* Keyboard-visible focus: one consistent accent ring app-wide (mouse clicks
   don't trigger :focus-visible, so pointer UX is unchanged). */
:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
}

#app {
    display: flex;
    width: 100%;
    flex: 1;
    min-height: 0;
}

#sidebar {
    width: 260px;
    background: var(--bg-secondary);
    border-inline-end: 1px solid var(--border);
    display: flex;
    flex-direction: column;
}

#sidebar header {
    padding: 20px;
    border-bottom: 1px solid var(--border);
}

#self-presence {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.9em;
    color: var(--text-secondary);
}

.dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
}
.dot.online { background: var(--color-success); box-shadow: 0 0 8px var(--color-success); }
.dot.offline { background: var(--slate-500); }

nav {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
}

/* Sidebar brand: h1 for a valid single top-level heading; sized to match the
   previous h2 exactly so the visual is unchanged. */
.app-title { font-size: 1.5em; font-weight: 700; margin: 0.83em 0; }

/* Sidebar section titles (Rooms / DMs / …) are h2s for a clean heading order
   (h1 brand → h2 sections → h2 chat title). Styling unchanged from the old h3. */
nav h2 {
    text-transform: uppercase;
    font-size: 0.75em;
    color: var(--text-secondary);
    margin: 20px 0 10px 10px;
}

nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
}

nav li {
    padding: 10px;
    border-radius: 4px;
    cursor: pointer;
    margin-bottom: 2px;
    transition: background var(--transition-base);
}

nav li:hover { background: rgba(255,255,255,0.05); }
nav li.active { background: var(--bg-accent); color: var(--text-primary); }

/* Sidebar conversation rows: the last-message preview clamps to ONE line with an
   ellipsis (it used to hard-wrap onto multiple lines, cut mid-word). */
.room-item-body, .dm-item-body { flex: 1; min-width: 0; overflow: hidden; }
.room-item-preview, .dm-item-preview {
    font-size: 0.8em;
    color: var(--text-secondary);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-top: 2px;
}

#chat-area {
    flex: 1;
    display: flex;
    flex-direction: column;
    background: var(--bg-accent);
}

#chat-header {
    padding: 15px 25px;
    /* Clear the notch/status bar in standalone PWA mode (0 on non-notch/desktop). */
    padding-top: calc(15px + env(safe-area-inset-top, 0px));
    background: var(--bg-primary);
    border-bottom: 1px solid var(--bg-secondary);
}

#message-feed {
    flex: 1;
    overflow-y: auto;
    padding: 20px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Discord-style message row: avatar column beside body column */
.message {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    padding: 2px 16px;
    border-radius: 4px;
    background: transparent;
    max-width: none;
    align-self: stretch;
    position: relative;
}
.message:hover { background: rgba(255,255,255,0.025); }
/* Optimistic send: dim until the server echo confirms, then fade to full opacity. */
.message { transition: opacity var(--transition-base); }
.message.msg-pending { opacity: 0.5; }
/* R66: send-failure state — a message that never confirmed */
.message.msg-failed { opacity: 1; }
.msg-fail-note {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 4px; font-size: 0.78em; color: var(--color-danger-soft, #f87171);
}
.msg-fail-note::before { content: "\26A0"; }   /* ⚠ */
.msg-retry-btn {
    background: transparent; border: 1px solid var(--color-danger-soft, #f87171);
    color: var(--color-danger-soft, #f87171); border-radius: 4px;
    padding: 1px 8px; cursor: pointer; font-size: 0.95em;
}
.msg-retry-btn:hover, .msg-retry-btn:focus-visible { background: rgba(248, 113, 113, 0.12); }
/* D2: pod write-through failure. The message DID deliver to room members; it is
   just not durable in the pod yet. Softer than delivery failure (amber, not red)
   and a different glyph, so the two states are not confused. */
.msg-pod-note {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 4px; font-size: 0.78em; color: #f59e0b;
}
.msg-pod-note::before { content: "\2601"; }   /* ☁ */
.msg-pod-note .msg-retry-btn { border-color: #f59e0b; color: #f59e0b; }
.msg-pod-note .msg-retry-btn:hover,
.msg-pod-note .msg-retry-btn:focus-visible { background: rgba(245, 158, 11, 0.12); }
/* Voice speaking indicator (Phase J): green ring on the active speaker's pill. */
#voice-channel-participants span { transition: box-shadow var(--transition-fast); }
#voice-channel-participants span.vc-speaking { box-shadow: 0 0 0 2px var(--color-success-soft); }
/* Tall-modal safety (esp. mobile): cap a dialog's inner container to the viewport
   and let it scroll, so a tall modal (e.g. expanded settings) never pushes its top/
   bottom — including the action buttons — off-screen with no way to reach them. */
[role="dialog"] > div { max-height: 90vh; overflow-y: auto; }
.message:not(.msg-grouped) { padding-top: 16px; }

/* Avatar column: 40 px wide, fixed */
.msg-avatar-col {
    flex-shrink: 0;
    width: 40px;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-top: 1px;
}
/* Compact timestamp shown in avatar column for grouped messages */
.msg-compact-ts {
    font-size: 0.65em;
    color: transparent;
    user-select: none;
    display: block;
    text-align: center;
    line-height: 1.6;
    width: 40px;
    white-space: nowrap;
}
.message:hover .msg-compact-ts { color: var(--text-secondary, #94a3b8); }

/* Body column: grows, wraps long words */
.msg-body { flex: 1; min-width: 0; }

/* Name + timestamp on the first message in each group */
.msg-header {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 3px;
}
.msg-sender { font-weight: 600; font-size: 0.95em; }
.msg-ts-header { font-size: 0.72em; color: var(--text-secondary, #94a3b8); }

/* Message text */
.msg-content {
    color: var(--text-primary, #e1e1e1);
    font-size: 0.95em;
    line-height: 1.5;
    word-break: break-word;
    overflow-wrap: break-word;
}

/* Hover action bar (react / reply / edit / delete / pin) */
.msg-actions {
    display: none;
    position: absolute;
    inset-inline-end: 12px;
    top: -14px;
    background: var(--bg-secondary, #16213e);
    border: 1px solid var(--border, #0f3460);
    border-radius: 6px;
    padding: 2px;
    z-index: 10;
    gap: 2px;
}
.message:hover .msg-actions { display: flex; }

/* Icon buttons inside the action bar — override the global red accent */
.icon-btn {
    background: transparent !important;
    border: none;
    color: var(--text-secondary, #94a3b8);
    cursor: pointer;
    padding: 4px;
    border-radius: 4px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: color var(--transition-fast), background var(--transition-fast);
}
.icon-btn:hover {
    background: rgba(255,255,255,0.1) !important;
    color: var(--text-primary, #e1e1e1);
}

.time {
    font-size: 0.75em;
    color: var(--text-secondary);
    margin-inline-end: 8px;
}

.system-msg {
    text-align: center;
    font-size: 0.85em;
    color: var(--text-secondary);
    margin: 10px 0;
}

#message-form {
    padding: 8px 10px;
    /* Clear the home indicator in standalone PWA mode (0 on non-notch/desktop). */
    padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    display: flex;
    gap: 4px;
    align-items: center;
    background: var(--bg-primary);
}

.paperclip {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 4px;
    cursor: pointer;
    color: var(--text-secondary);
    line-height: 0;
    transition: color var(--transition-fast), background var(--transition-fast);
}
.paperclip:hover {
    color: var(--text-primary);
    background: rgba(255,255,255,0.06);
}

.voice-record-btn,
.schedule-btn {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: transparent;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    color: var(--text-secondary);
    padding: 0;
    line-height: 0;
    font-weight: normal;
    transition: color var(--transition-fast), background var(--transition-fast);
}
.voice-record-btn:hover,
.schedule-btn:hover {
    background: rgba(255,255,255,0.06) !important;
    color: var(--text-primary);
}

@media (min-width: 769px) {
    #message-form { padding: 12px 20px; gap: 8px; }
}

#message-input {
    flex: 1;
    background: var(--bg-secondary);
    border: 1px solid var(--border);
    padding: 12px 15px;
    border-radius: 4px;
    color: var(--text-primary);
    outline: none;
}

button {
    background: var(--accent);
    color: white;
    border: none;
    padding: 0 25px;
    border-radius: 4px;
    cursor: pointer;
    font-weight: bold;
}

button:hover { background: var(--accent-hover); }

/* Mobile Responsive */
@media (max-width: 768px) {
    #sidebar {
        position: absolute;
        z-index: 100;
        height: 100%;
        width: 80%;
        inset-inline-start: 0;
        transition: transform var(--transition-base);
        transform: translateX(-100%);
    }
    /* RTL: the sidebar is anchored to the (flipped) inline-start, so it must
       hide toward the opposite side — transforms aren't direction-aware. The
       open rule is repeated under the same selector prefix so it keeps winning
       on specificity over the RTL hide rule. */
    :root[dir="rtl"] #sidebar { transform: translateX(100%); }
    #sidebar.active,
    :root[dir="rtl"] #sidebar.active { transform: translateX(0); }
    /* Members panel becomes a right-side off-canvas drawer on mobile. The desktop
       show/hide path sets inline display:block/none, so the drawer needs
       display:block !important to beat a lingering inline display:none — its
       visibility is driven by the .mobile-open class toggleMembersPanel sets.
       Without this rule the panel never opened on phones (the class had no CSS). */
    /* The off-canvas members drawer parks at translateX(100%) — off the right
       edge — which otherwise contributes to the document scroll width and breaks
       WCAG 1.4.10 reflow (a horizontal scrollbar at ≤320px). Make #app the
       drawer's containing block and clip its overflow, so the parked drawer is
       hidden and animates in from the clip region on .mobile-open. */
    #app { position: relative; overflow-x: hidden; }
    #members-panel {
        display: block !important;
        position: absolute;
        top: 0;
        inset-inline-end: 0;
        height: 100%;
        width: 80%;
        max-width: 320px;
        z-index: 100;
        transform: translateX(100%);
        transition: transform var(--transition-base);
    }
    /* RTL: anchored to the flipped inline-end, so hide toward the other side.
       Repeat the open rule under the RTL prefix so it wins on specificity. */
    :root[dir="rtl"] #members-panel { transform: translateX(-100%); }
    #members-panel.mobile-open,
    :root[dir="rtl"] #members-panel.mobile-open { transform: translateX(0); }
    /* Phone composer: the message input was squeezed to ~37% width by four buttons.
       Reclaim room for the primary input by dropping the secondary schedule action
       (still available on desktop) and tightening the Send button. */
    #schedule-btn { display: none; }
    #message-form > button[type="submit"] { padding-inline-start: 14px; padding-inline-end: 14px; }
    /* Phone chat header: the room title wrapped onto two lines and the Leave/
       Delete/Call text buttons overflowed the row. Icons only on mobile (each
       keeps its title tooltip + aria-label); the title truncates with an
       ellipsis instead of wrapping. */
    #chat-header {
        flex-wrap: nowrap;
        /* Desktop's 25px side padding is too rich when every action icon is
           showing — reclaim it for the action row. */
        padding-inline-start: 12px;
        padding-inline-end: 12px;
    }
    #chat-header .btn-label { display: none; }
    /* If a view still shows more action icons than fit (owner room + voice),
       the action strip scrolls sideways instead of clipping or wrapping.
       flex-shrink/min-width override the inline flex-shrink:0 so the strip
       yields to the title's floor and scrolls internally. */
    #chat-header-actions {
        overflow-x: auto;
        scrollbar-width: none;
        flex-shrink: 1 !important;
        min-width: 0;
    }
    #chat-header-actions::-webkit-scrollbar { display: none; }
    #chat-header-name {
        /* flex:1 (inline) has flex-basis 0, so with a full row of action icons
           the title collapsed to nothing — keep a readable floor and ellipsize. */
        min-width: 72px;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 1.1em;
    }
    .mobile-overlay {
        display: none;
        position: absolute;
        inset: 0;
        background: rgba(0,0,0,0.5);
        z-index: 90;
    }
    .mobile-overlay.active {
        display: block;
    }
    #message-feed {
        padding: 10px;
    }
    .message {
        padding: 2px 10px;
    }
    .message:not(.msg-grouped) { padding-top: 12px; }
    #menu-toggle {
        display: block !important;
    }
    /* Modal boxes carry inline min-width (e.g. onboarding's 380px) that overflows
       a 375px phone. Cap every dialog's inner box to the viewport with a small
       gutter; !important is required to beat the inline min-width. Lightbox is
       excluded (it's a full-bleed image viewer, not a card). */
    [role="dialog"]:not(#lightbox) > div,
    [id$="-modal"]:not(#lightbox) > div {
        min-width: 0 !important;
        max-width: calc(100vw - 24px) !important;
    }
}

#menu-toggle {
    display: none;
    background: transparent;
    font-size: 1.5rem;
    padding: 0 15px 0 0;
    color: var(--text-primary);
}

.vw-sharing { color: var(--accent) !important; }

.vw-controls {
    display: flex;
    gap: 4px;
}
.vw-controls button {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.07);
    border: none;
    border-radius: 4px;
    color: var(--text-secondary);
    cursor: pointer;
    padding: 7px 6px;
    line-height: 0;
    transition: background var(--transition-fast), color var(--transition-fast);
}
.vw-controls button:hover {
    background: rgba(255,255,255,0.13);
    color: var(--slate-50);
}
#end-call {
    color: var(--color-danger);
}
#end-call:hover {
    background: rgba(239,68,68,0.15) !important;
    color: var(--color-danger);
}
.vw-muted {
    color: var(--color-danger) !important;
}

.relay-pending-badge { margin-inline-start: 4px; font-size: 0.75em; opacity: 0.7; vertical-align: middle; }
.relay-pending-badge.relay-failed { color: var(--danger, #c0392b); opacity: 0.9; cursor: help; }

/* ── R13: Round 13 additions ── */

/* 13.10: Accessibility utilities */
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0;
    margin: -1px; overflow: hidden; clip: rect(0,0,0,0);
    white-space: nowrap; border: 0;
}
.skip-nav {
    position: absolute; top: -40px; inset-inline-start: 0;
    background: var(--accent, #e94560); color: #fff;
    padding: 8px 16px; z-index: 9999; text-decoration: none;
    border-radius: 0 0 4px 0;
}
.skip-nav:focus { top: 0; }
*:focus-visible { outline: 2px solid var(--accent, #e94560); outline-offset: 2px; }

/* 13.6: Backup nudge banner */
#backup-nudge {
    display: none; background: var(--color-warning-bg); color: var(--color-warning-text);
    padding: 7px 16px; font-size: 0.85em; align-items: center;
    gap: 12px; flex-shrink: 0;
}
#backup-nudge.visible { display: flex !important; }

/* 13.7: Inline image preview */
.msg-image-preview {
    display: block; max-width: 320px; max-height: 240px;
    border-radius: 6px; margin-top: 6px; cursor: pointer;
    border: 1px solid var(--border, #334155);
    object-fit: cover;
}
.msg-image-preview:hover { opacity: 0.9; }
/* R59A: inline media players — same footprint discipline as image previews */
.msg-video-preview {
    display: block; max-width: min(420px, 100%); max-height: 320px;
    border-radius: 6px; margin-top: 6px;
    border: 1px solid var(--border, #334155);
    background: #000;
}
.msg-audio-preview { display: block; max-width: min(420px, 100%); margin-top: 6px; }
/* R59G: custom room emoji — inline in message text and in lists */
.custom-emoji {
    height: 1.4em;
    width: auto;
    max-width: 3em;
    vertical-align: -0.3em;
    object-fit: contain;
}
/* R59F: poll card — structured render of the plain-text poll format */
.poll-card {
    border: 1px solid var(--slate-600);
    border-inline-start: 3px solid var(--accent);
    border-radius: 6px;
    padding: 8px 12px;
    margin-top: 4px;
    max-width: min(420px, 100%);
}
.poll-q { font-weight: 600; margin-bottom: 6px; }
.poll-opt { padding: 2px 0; }
.poll-hint { margin-top: 6px; font-size: 0.78em; color: var(--text-secondary); }
/* R60C: media spoiler — blurred image under a reveal cover, one-way */
.media-spoiler { position: relative; display: inline-block; cursor: pointer; }
.media-spoiler:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
.media-spoiler:not(.revealed) .msg-image-preview { filter: blur(28px); }
.media-spoiler:not(.revealed) { overflow: hidden; border-radius: 6px; }
.media-spoiler-label {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 0.8em; font-weight: 600; letter-spacing: 0.04em;
    text-shadow: 0 1px 4px rgba(0,0,0,.8); pointer-events: none;
}
.media-spoiler.revealed .media-spoiler-label { display: none; }
.media-spoiler.revealed { cursor: auto; }
/* R59D: ||spoiler|| — text hidden until activated, one-way reveal */
.spoiler {
    background: var(--slate-700);
    color: transparent;
    border-radius: 3px;
    padding: 0 3px;
    cursor: pointer;
    user-select: none;
}
.spoiler:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.spoiler.revealed {
    background: rgba(255, 255, 255, 0.08);
    color: inherit;
    cursor: auto;
    user-select: auto;
}
#lightbox { display: none; }
#lightbox.visible {
    display: flex !important;
}

/* 13.11: Edit history */
.edited-badge {
    font-size: 0.75em; color: var(--text-secondary);
    text-decoration: underline dotted; cursor: pointer;
    margin-inline-start: 4px; vertical-align: middle;
}
.edited-badge:hover { color: var(--slate-300); }
.edit-history-popover {
    position: absolute; z-index: 500; background: var(--bg-secondary, #1e293b);
    border: 1px solid var(--border, #334155); border-radius: 6px;
    padding: 10px 14px; font-size: 0.82em; color: var(--text-primary, #f1f5f9);
    max-width: 340px; max-height: 200px; overflow-y: auto;
    box-shadow: 0 4px 16px rgba(0,0,0,.5);
}
.edit-history-entry { border-bottom: 1px solid var(--slate-700); padding: 5px 0; }
.edit-history-entry:last-child { border-bottom: none; }
.edit-history-meta { font-size: 0.8em; color: var(--text-secondary); margin-bottom: 2px; }

/* 13.12: Room unread count badge */
.unread-count-badge {
    background: var(--accent, #e94560); color: #fff;
    border-radius: 10px; padding: 1px 7px; font-size: 0.75em;
    margin-inline-start: auto; flex-shrink: 0;
}

/* 13.14: Contact search dropdown */
.contact-search-dropdown {
    position: absolute; z-index: 600; width: 100%;
    background: var(--bg-secondary, #1e293b);
    border: 1px solid var(--border, #334155); border-radius: 6px;
    max-height: 200px; overflow-y: auto;
    box-shadow: 0 4px 12px rgba(0,0,0,.4);
    top: 100%; inset-inline-start: 0;
}
.contact-search-item {
    padding: 8px 12px; cursor: pointer; display: flex;
    flex-direction: column; gap: 2px;
}
.contact-search-item:hover { background: rgba(255,255,255,0.06); }
.contact-search-name { font-size: 0.9em; color: var(--text-primary, #f1f5f9); }
.contact-search-did { font-size: 0.75em; color: var(--text-secondary); font-family: monospace; }

/* ── PLAN_ROUND_56 D2/D3: high-contrast & forced-colors support ── */

/* D2 — users who ask for more contrast get promoted secondary text, stronger
   borders, and a thicker focus ring. */
@media (prefers-contrast: more) {
    :root {
        --text-secondary: #cbd5e1;
        --slate-500: #cbd5e1;
        --slate-600: #cbd5e1;
        --border: #3b5a8a;
    }
    :focus-visible { outline-width: 3px; outline-offset: 2px; }
    .msg-actions, nav li.active { border: 1px solid var(--border); }
}

/* D3 — Windows High Contrast / forced-colors strips custom colors. Keep focus
   visible (outline survives), and don't let presence/status be color-only:
   preserve the dots as shapes and lean on the system palette elsewhere. */
@media (forced-colors: active) {
    :focus-visible { outline: 2px solid CanvasText; }
    .dot, .avatar-presence { forced-color-adjust: none; }
    .skip-nav { forced-color-adjust: none; }
    /* Ensure interactive rows have a perceivable active state without relying on
       a custom background the UA may drop. */
    nav li.active { outline: 2px solid Highlight; outline-offset: -2px; }
}

/* R81 Q: call video — fullscreen layout, active-speaker ring, responsive */
#vw-video-area:fullscreen,
#voice-channel-videos:fullscreen {
  background: #000;
  width: 100vw; height: 100vh;
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 10px; padding: 16px; box-sizing: border-box;
}
#vw-video-area:fullscreen #vw-remote-video {
  width: auto; height: 100%; max-height: 100vh; max-width: 100vw; border-radius: 0;
}
#vw-video-area:fullscreen #vw-local-video {
  position: fixed; right: 24px; bottom: 24px; width: 220px; max-height: 160px;
}
#voice-channel-videos:fullscreen .vc-video-tile,
#voice-channel-videos:fullscreen #vc-local-video {
  width: 42%; max-height: 46vh; height: auto;
}
.vc-video-tile.vc-speaking,
#vw-remote-video.vc-speaking {
  outline: 3px solid var(--color-success, #4ade80);
  outline-offset: -3px;
}
@media (max-width: 768px) {
  #vw-remote-video { max-height: 40vh; }
  .vc-video-tile, #vc-local-video { width: 44vw !important; max-height: 30vh; }
}

/* R83: spotlight the active speaker's video tile in a larger group call */
#voice-channel-videos .vc-video-tile.vc-speaking {
  width: 280px;
  max-height: 210px;
  order: -1;   /* float the active speaker to the front of the grid */
}
@media (max-width: 768px) {
  #voice-channel-videos .vc-video-tile.vc-speaking { width: 70vw; max-height: 42vh; }
}


/* ── Merged from the former inline <style> block in index.html (R95/F2a).
   Kept at the end so the cascade order (style.css then this block) is unchanged. ── */
        #voice-banner {
            display: none;
            background: var(--accent);
            color: white;
            padding: 10px 20px;
            position: sticky;
            top: 0;
            z-index: 100;
            align-items: center;
            justify-content: center;
            gap: 12px;
        }
        #voice-banner button {
            background: white;
            color: var(--accent);
            margin: 0 10px;
            padding: 5px 15px;
            border-radius: 4px;
            border: none;
            cursor: pointer;
            font-weight: bold;
        }
        .attachment {
            display: inline-block;
            background: #1a1a2e;
            padding: 5px 10px;
            border-radius: 4px;
            margin-top: 5px;
            font-size: 0.9em;
        }
        #file-input { display: none; }
        .paperclip {
            cursor: pointer;
            font-size: 1.2em;
            margin-right: 10px;
            color: var(--text-secondary);
        }
        #search-box {
            padding: 10px;
            border-bottom: 1px solid #1a1a2e;
        }
        #search-input {
            width: 100%;
            padding: 8px;
            background: #1a1a2e;
            border: 1px solid #1a1a2e;
            color: white;
            border-radius: 4px;
        }
        .search-match {
            background: #1a2a4a;
            border-left: 4px solid var(--accent);
        }
        .search-match b { color: var(--accent); }
        .voice-channel { color: var(--color-success-soft); cursor: pointer; padding: 5px 0; }
        .voice-channel:hover { text-decoration: underline; }
        .avatar {
            width: 24px;
            height: 24px;
            border-radius: 50%;
            vertical-align: middle;
            margin-right: 8px;
            display: inline-block;
            position: relative;
        }
        .avatar.placeholder {
            background: var(--accent);
            color: white;
            text-align: center;
            line-height: 24px;
            font-size: 12px;
            font-weight: bold;
        }
        .avatar-presence {
            position: absolute;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            bottom: -1px;
            right: -1px;
            border: 2px solid var(--slate-900);
            background: var(--slate-500);  /* offline (grey) */
        }
        .avatar-presence.online {
            background: var(--color-success);  /* online (green) */
        }
        .avatar-presence.away {
            background: #eab308;  /* away (yellow) */
        }
        .avatar-presence.busy {
            background: var(--color-danger);  /* busy (red) */
        }
        .reactions {
            display: flex;
            gap: 5px;
            margin-top: 5px;
            flex-wrap: wrap;
        }
        .reaction {
            background: rgba(255,255,255,0.1);
            padding: 2px 6px;
            border-radius: 10px;
            font-size: 0.8em;
            cursor: pointer;
            border: 1px solid transparent;
        }
        .reaction.active {
            border-color: var(--accent);
            background: rgba(233, 69, 96, 0.2);
        }
        /* D3: pop a reaction pill when it is added */
        @keyframes reaction-pop {
            0%   { transform: scale(0.6); }
            55%  { transform: scale(1.3); }
            100% { transform: scale(1); }
        }
        .reaction.reaction-anim {
            animation: reaction-pop 0.28s cubic-bezier(0.2, 0.7, 0.3, 1.35);
        }
        /* F4: honour reduced-motion globally — covers the reaction pop, skeleton
           shimmer, popover fade, recording pulse, every token transition, and
           smooth scrolling, not just the one reaction rule it replaced. */
        @media (prefers-reduced-motion: reduce) {
            *, *::before, *::after {
                animation-duration: 0.001ms !important;
                animation-iteration-count: 1 !important;
                transition-duration: 0.001ms !important;
                scroll-behavior: auto !important;
            }
        }
        .emoji-picker {
            display: none;
            position: absolute;
            background: #16213e;
            border: 1px solid #0f3460;
            padding: 8px;
            border-radius: 8px;
            z-index: 1000;
            grid-template-columns: repeat(4, 1fr);
            gap: 5px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.5);
        }
        .emoji-picker button {
            cursor: pointer;
            font-size: 1.2em;
            padding: 4px;
            border-radius: 4px;
            background: transparent;
            border: none;
            color: inherit;
            line-height: 1;
        }
        .emoji-picker button:hover,
        .emoji-picker button:focus-visible { background: rgba(255,255,255,0.1); }
        /* R58: GIF tray — composer popover of starred images */
        .gif-tray-btn {
            background: transparent; border: 1px solid var(--slate-600);
            color: var(--text-secondary); border-radius: 4px; cursor: pointer;
            font-size: 0.68rem; font-weight: 700; letter-spacing: 0.03em;
            padding: 4px 6px; min-width: 36px; min-height: 28px; flex-shrink: 0;
        }
        .gif-tray-btn:hover, .gif-tray-btn:focus-visible { color: var(--slate-50); border-color: var(--slate-500); }
        #gif-tray {
            position: absolute; bottom: 62px; left: 8px; right: 8px;
            max-width: 420px; max-height: 300px; overflow-y: auto;
            background: var(--slate-800); border: 1px solid var(--slate-600);
            border-radius: 8px; padding: 10px; z-index: 1000;
            box-shadow: 0 4px 15px rgba(0,0,0,0.5);
        }
        .gif-tray-title {
            margin: 0 0 8px; font-size: 0.72em; color: var(--text-secondary);
            text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600;
        }
        .gif-tray-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(92px, 1fr)); gap: 6px; }
        .gif-tray-empty { margin: 4px 0; font-size: 0.85em; color: var(--text-secondary); grid-column: 1 / -1; }
        .gif-cell { position: relative; }
        .gif-send {
            display: block; width: 100%; padding: 0; border: 1px solid var(--slate-700);
            border-radius: 6px; background: var(--slate-900); cursor: pointer; overflow: hidden;
        }
        .gif-send img { display: block; width: 100%; height: 76px; object-fit: cover; }
        .gif-send:hover, .gif-send:focus-visible { border-color: var(--accent); }
        .gif-remove {
            position: absolute; top: 2px; inset-inline-end: 2px; min-width: 22px; min-height: 22px;
            border: none; border-radius: 4px; background: rgba(0,0,0,0.65);
            color: var(--slate-50); cursor: pointer; font-size: 0.9em; line-height: 1;
        }
        .gif-remove:hover, .gif-remove:focus-visible { background: var(--color-danger, #b91c1c); }
        /* R58: drag-drop target highlight */
        .drop-active { outline: 2px dashed var(--accent); outline-offset: -6px; }
        /* R59C: composer emoji insert-panel */
        .composer-emoji-panel {
            position: absolute; bottom: 62px; left: 8px; right: 8px;
            max-width: 420px; max-height: 260px; overflow-y: auto;
            background: var(--slate-800); border: 1px solid var(--slate-600);
            border-radius: 8px; padding: 8px; z-index: 1000;
            grid-template-columns: repeat(auto-fill, minmax(36px, 1fr)); gap: 2px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.5);
        }
        .composer-emoji-panel button {
            background: transparent; border: none; cursor: pointer;
            font-size: 1.25em; padding: 4px; border-radius: 4px; line-height: 1;
            min-width: 32px; min-height: 32px;
        }
        .composer-emoji-panel button:hover,
        .composer-emoji-panel button:focus-visible { background: rgba(255,255,255,0.1); }
        .mention { background: rgba(88,101,242,0.3); border-radius: 3px; padding: 0 2px; }
        .link-preview {
            border-left: 3px solid var(--accent);
            background: rgba(0,0,0,0.1);
            padding: 10px;
            margin-top: 8px;
            border-radius: 0 4px 4px 0;
            font-size: 0.9em;
        }
        .preview-title { font-weight: bold; margin-bottom: 4px; }
        .preview-desc { color: var(--text-secondary); margin-bottom: 4px; }
        .preview-url { font-size: 0.8em; color: #5865f2; }
        
        #reply-bar {
            display: none;
            background: var(--bg-secondary);
            padding: 8px 20px;
            border-top: 1px solid var(--border);
            border-bottom: 1px solid var(--border);
            justify-content: space-between;
            align-items: center;
            font-size: 0.9em;
        }
        .reply-preview { color: var(--text-secondary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
        .cancel-reply { cursor: pointer; color: var(--accent); font-weight: bold; }
        
        .quoted-context {
            font-size: 0.85em;
            color: var(--text-secondary);
            border-left: 2px solid var(--border);
            padding-left: 8px;
            margin-bottom: 4px;
            cursor: pointer;
        }
        .quoted-context:hover { color: var(--text-primary); }
        
        /* Link Previews */
        .link-preview {
            margin-top: 10px;
            background: var(--bg-primary);
            border: 1px solid var(--border);
            border-radius: 8px;
            overflow: hidden;
            display: flex;
            max-width: 500px;
            font-size: 0.9em;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .link-preview img {
            width: 120px;
            height: 100%;
            min-height: 100px;
            object-fit: cover;
            border-right: 1px solid var(--border);
        }
        .preview-info {
            padding: 12px;
            display: flex;
            flex-direction: column;
            gap: 4px;
        }
        .preview-title { font-weight: bold; color: var(--accent); }
        .preview-title a { color: inherit; text-decoration: none; }
        .preview-title a:hover { text-decoration: underline; }
        .preview-desc { color: var(--text-secondary); font-size: 0.85em; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
        .preview-url { font-size: 0.75em; color: var(--text-secondary); opacity: 0.7; }

        /* â"€â"€ Round 31: Messaging Fundamentals â"€â"€ */

        /* Message grouping */
        .message.msg-grouped { margin-top: 0; padding-top: 2px; }

        /* Date divider */
        .date-divider {
            text-align: center; margin: 12px 0 8px; position: relative;
            color: var(--text-secondary, #94a3b8); font-size: 0.78em; user-select: none;
        }
        .date-divider::before, .date-divider::after {
            content: ''; position: absolute; top: 50%;
            width: 38%; height: 1px; background: var(--slate-700);
        }
        .date-divider::before { left: 0; }
        .date-divider::after { right: 0; }

        /* Unread divider */
        .unread-divider {
            text-align: center; margin: 8px 0; color: var(--accent); font-size: 0.78em;
            user-select: none; border-top: 1px solid var(--accent); padding-top: 6px;
        }

        /* Markdown */
        .code-block { background: var(--slate-900); border-radius: 4px; padding: 8px 12px;
            margin: 4px 0; overflow-x: auto; font-family: monospace;
            font-size: 0.85em; white-space: pre; display: block; }
        .inline-code { background: var(--slate-800); border-radius: 3px; padding: 1px 4px;
            font-family: monospace; font-size: 0.9em; }

        /* Scroll-to-bottom button */
        #scroll-bottom-btn {
            display: none; position: absolute; bottom: 80px; right: 20px;
            background: var(--accent, #e94560); color: #fff; border: none;
            border-radius: 20px; padding: 6px 14px; cursor: pointer;
            font-size: 0.85em; z-index: 10; box-shadow: 0 2px 8px rgba(0,0,0,.4);
        }

        /* Timestamp tooltip */
        .msg-time { cursor: default; color: var(--text-secondary, #94a3b8); font-size: 0.75em; }
        .msg-time:hover { text-decoration: underline dotted; }

        /* Loading skeleton */
        .skeleton-msg {
            height: 38px; background: linear-gradient(90deg,var(--slate-800) 25%,#2d3f55 50%,var(--slate-800) 75%);
            background-size: 200% 100%; animation: shimmer 1.4s infinite;
            border-radius: 6px; margin: 8px 12px;
        }
        .skeleton-msg.short { width: 55%; }
        @keyframes shimmer { 0%{background-position:200% 0} 100%{background-position:-200% 0} }

        /* Empty state */
        .empty-state { text-align: center; color: var(--text-secondary); padding: 48px 24px; line-height: 1.8; }
        .empty-state-icon { opacity: 0.3; }
        .empty-state-hint { font-size: 0.85em; color: var(--slate-500); margin-top: 4px; }
        /* F3: consistent inline empty/loading/error notice for lists & popovers */
        .state-msg { color: var(--text-secondary); text-align: center; padding: 12px 8px; font-size: 0.9em; margin: 0; }
        .state-msg.state-error { color: var(--color-danger-soft); }
        /* Solid conversations (cross-app shared chats) */
        #solidchat-list { list-style: none; margin: 0; padding: 0; }
        .solidchat-item { display: flex; align-items: center; justify-content: space-between; gap: 8px;
            width: 100%; text-align: left; background: transparent; border: none; color: inherit;
            cursor: pointer; padding: 6px 8px; border-radius: 4px; font: inherit; }
        .solidchat-item:hover, .solidchat-item:focus-visible { background: var(--slate-800, #1e293b); }
        .solidchat-item-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .solidchat-item-role { font-size: 0.68em; color: var(--text-secondary, #94a3b8); flex-shrink: 0; }
        .solidchat-empty { list-style: none; padding: 6px 8px; font-size: 0.8em; color: var(--text-secondary, #94a3b8); }
        .solidchat-badge { font-size: 0.66em; text-transform: uppercase; letter-spacing: 0.04em;
            background: var(--slate-700, #334155); color: var(--slate-200, #e2e8f0);
            padding: 2px 7px; border-radius: 10px; flex-shrink: 0; }
        .solidchat-msg { display: flex; flex-direction: column; gap: 2px; margin-bottom: 12px; max-width: 78%; }
        .solidchat-msg.mine { margin-left: auto; align-items: flex-end; }
        .solidchat-author { font-size: 0.72em; color: var(--text-secondary, #94a3b8); }
        .solidchat-body { background: var(--slate-800, #1e293b); padding: 7px 11px; border-radius: 10px;
            white-space: pre-wrap; word-break: break-word; }
        .solidchat-msg.mine .solidchat-body { background: var(--accent, #d61f52); color: #fff; }

        /* G3/G4: actionable empty-state CTA in the sidebar lists */
        .sidebar-empty { list-style: none; padding: 8px 4px 12px; text-align: center; }
        .sidebar-empty .state-msg { padding: 4px 8px; }
        .state-cta { background: var(--slate-700); border: none; color: var(--slate-50);
            padding: 6px 12px; border-radius: 4px; cursor: pointer; font-size: 0.85em;
            transition: background var(--transition-fast); }
        .state-cta:hover { background: var(--slate-600); }

        /* Connection banner */
        #conn-banner {
            display: none; background: var(--color-warning-bg); color: var(--color-warning-text); text-align: center;
            padding: 5px 12px; font-size: 0.82em; z-index: 5; flex-shrink: 0;
        }

        /* Profile card popover (B2) */
        .profile-popover {
            display: none;
            position: fixed;
            background: var(--bg-secondary, #1a1f35);
            border: 1px solid var(--border, #334155);
            border-radius: 12px;
            padding: 16px;
            min-width: 280px;
            z-index: 1001;
            box-shadow: 0 10px 40px rgba(0,0,0,0.5);
            animation: popoverFadeIn 0.15s ease-out;
        }
        @keyframes popoverFadeIn {
            from { opacity: 0; transform: scale(0.95); }
            to { opacity: 1; transform: scale(1); }
        }
        .profile-popover.show { display: block; }
        .profile-header {
            display: flex;
            align-items: center;
            gap: 12px;
            margin-bottom: 12px;
        }
        .profile-avatar {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            font-size: 16px;
            color: white;
            position: relative;
        }
        .profile-info {
            flex: 1;
        }
        .profile-name {
            font-weight: bold;
            font-size: 1em;
            color: var(--text-primary, #f8fafc);
            margin-bottom: 4px;
        }
        .profile-webid {
            font-family: monospace;
            font-size: 0.8em;
            color: var(--text-secondary, #94a3b8);
            word-break: break-all;
        }
        .profile-status {
            display: flex;
            align-items: center;
            gap: 6px;
            margin: 10px 0;
            font-size: 0.85em;
            color: var(--text-secondary, #94a3b8);
        }
        .profile-status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: var(--slate-500);
        }
        .profile-status-dot.online { background: var(--color-success); }
        .profile-status-dot.away { background: #eab308; }
        .profile-status-dot.busy { background: var(--color-danger); }
        .profile-custom-status {
            font-size: 0.8em;
            color: var(--text-secondary, #94a3b8);
            font-style: italic;
            margin: 8px 0;
            padding: 6px 0;
            border-top: 1px solid var(--border, #334155);
            border-bottom: 1px solid var(--border, #334155);
            min-height: 16px;
        }
        .profile-divider {
            height: 1px;
            background: var(--border, #334155);
            margin: 10px 0;
        }
        .profile-actions {
            display: flex;
            gap: 8px;
        }
        .profile-btn {
            flex: 1;
            background: var(--accent, #e94560);
            color: white;
            border: none;
            padding: 8px 12px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 0.85em;
            font-weight: 500;
            transition: all var(--transition-base);
        }
        .profile-btn:hover {
            background: #d63550;
            transform: translateY(-1px);
            box-shadow: 0 4px 12px rgba(233, 69, 96, 0.3);
        }
        .profile-btn:active { transform: translateY(0); }
        /* R65: block/unblock action in the profile card */
        .profile-btn-danger { background: var(--slate-700); color: var(--color-danger-soft, #f87171); }
        .profile-btn-danger:hover { background: var(--slate-600); box-shadow: none; }

        /* msg-meta wrapper (avatar + name on first in group) */
        .msg-meta { display: inline; }

        /* Round 60: Read Receipts */
        /* Delivery tick: inline at the end of the message's last text line
           (rendering.js places it inside .msg-content), WhatsApp-style — close
           to the content instead of floating at the feed's far edge, and never
           costing its own line. */
        .read-receipt { margin-left: 6px; font-size: 0.68em; color: var(--slate-600); user-select: none; }
        .read-receipt.read { color: var(--color-success-soft); }

        /* Round 62: Voice Messages */
        .voice-record-btn { background: transparent; border: none; color: var(--text-secondary); font-size: 1.3em; cursor: pointer; padding: 0 8px; flex-shrink: 0; }
        .voice-record-btn.recording { color: var(--accent); }
        .voice-recording-bar { display: none; align-items: center; gap: 10px; padding: 8px 16px; background: var(--bg-secondary,var(--slate-800)); flex: 1; color: var(--text-primary,var(--slate-50)); }
        .voice-recording-bar.active { display: flex; }
        .recording-dot { color: var(--accent); font-size: 1.1em; animation: pulse 0.8s infinite; }
        @keyframes pulse { 0%,100%{opacity:1} 50%{opacity:0.3} }
        .audio-message { margin-top: 4px; }
        .audio-message audio { max-width: 280px; height: 36px; }
        .audio-duration { font-size: 0.78em; color: var(--text-secondary); margin-left: 6px; }

        /* Round 47: Message context menu + sidebar context menu */
        .ctx-menu { position: fixed; background: var(--slate-800); border: 1px solid var(--slate-700); border-radius: 6px; z-index: 1300; overflow: hidden; box-shadow: 0 4px 16px rgba(0,0,0,.5); min-width: 160px; }
        .ctx-menu button { display: block; width: 100%; background: none; border: none; color: var(--slate-50); padding: 9px 16px; cursor: pointer; text-align: left; font-size: 0.9em; white-space: nowrap; }
        .ctx-menu button:hover { background: var(--slate-700); }
        .ctx-menu button.danger { color: var(--color-danger); }
        .ctx-menu hr { border: none; border-top: 1px solid var(--slate-700); margin: 2px 0; }

        /* Round 63: Delete submenu */
        .delete-submenu { position: fixed; background: var(--slate-800); border: 1px solid var(--slate-700); border-radius: 6px; z-index: 1200; overflow: hidden; box-shadow: 0 4px 16px rgba(0,0,0,.4); }
        .delete-submenu button { display: block; width: 100%; background: none; border: none; color: var(--slate-50); padding: 9px 18px; cursor: pointer; text-align: left; font-size: 0.9em; }
        .delete-submenu button:hover { background: var(--slate-700); }
        .delete-submenu button.danger { color: var(--color-danger); }

        /* Round 64: Role badges */
        .role-badge { font-size: 0.65rem; font-weight: 700; border-radius: 3px; padding: 1px 5px; margin-left: 4px; letter-spacing: 0.04em; vertical-align: middle; }
        .role-badge.role-admin { background: #7c3aed; color: white; }
        .role-badge.role-mod { background: #0891b2; color: white; }
        .member-context-menu { position: fixed; background: var(--slate-800); border: 1px solid var(--slate-700); border-radius: 6px; z-index: 1200; overflow: hidden; box-shadow: 0 4px 16px rgba(0,0,0,.4); }
        .member-context-menu button { display: block; width: 100%; background: none; border: none; color: var(--slate-50); padding: 9px 18px; cursor: pointer; text-align: left; font-size: 0.9em; }
        .member-context-menu button:hover { background: var(--slate-700); }
        .member-context-menu hr { border: none; border-top: 1px solid var(--slate-700); margin: 2px 0; }
        .member-context-menu button.danger { color: var(--color-danger); }

        /* Round 65: Disappearing messages */
        .disappear-banner { background: var(--slate-800); color: var(--text-secondary); font-size: 0.8em; text-align: center; padding: 4px 12px; border-bottom: 1px solid var(--slate-700); align-items: center; justify-content: center; gap: 6px; display: none; }
        .disappear-banner.active { display: flex; }
        .disappear-timer-row { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; font-size: 0.9em; }
        .disappear-timer-row select { background: var(--slate-900); border: 1px solid var(--slate-700); color: var(--slate-50); padding: 4px 8px; border-radius: 4px; cursor: pointer; }

        /* Round 66: Session management */
        .session-item { display: flex; align-items: center; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid var(--slate-700); font-size: 0.85em; gap: 8px; }
        .session-info { display: flex; flex-direction: column; gap: 2px; flex: 1; }
        .session-ip { font-family: monospace; font-size: 0.9em; color: var(--text-secondary); }
        .session-time { font-size: 0.8em; color: var(--slate-500); }
        .session-current { color: var(--color-success-soft); font-size: 0.8em; font-weight: 600; }
        .session-revoke-btn { background: #7f1d1d; border: none; color: #fca5a5; padding: 4px 10px; border-radius: 4px; cursor: pointer; font-size: 0.8em; }

        /* Round 68: Forward messages */
        .forwarded-banner { font-size: 0.8em; color: var(--text-secondary); margin-bottom: 3px; font-style: italic; }

        /* Round 69: Schedule picker */
        .schedule-picker { position: absolute; bottom: 64px; right: 12px; background: var(--slate-800); border: 1px solid var(--slate-700); border-radius: 8px; padding: 14px; z-index: 200; display: flex; flex-direction: column; gap: 10px; min-width: 240px; box-shadow: 0 4px 20px rgba(0,0,0,.5); }
        .schedule-picker input[type="datetime-local"] { background: var(--slate-900); border: 1px solid var(--slate-700); color: var(--slate-50); padding: 6px 8px; border-radius: 4px; font-size: 0.9em; width: 100%; box-sizing: border-box; }
        .schedule-picker label { font-size: 0.85em; color: var(--text-secondary); }
        .schedule-btn { background: transparent; border: none; color: var(--text-secondary); font-size: 1.2em; cursor: pointer; padding: 0 6px; flex-shrink: 0; }

        /* Round 70: Bot/Webhook */
        .bot-badge { font-size: 0.65rem; font-weight: 700; background: var(--accent,var(--accent)); color: white; border-radius: 3px; padding: 1px 5px; margin-left: 6px; vertical-align: middle; letter-spacing: 0.05em; }
        .copyable-code { display: block; background: var(--slate-900); padding: 10px; border-radius: 6px; font-size: 0.85rem; word-break: break-all; margin: 8px 0; user-select: all; font-family: monospace; border: 1px solid var(--slate-700); }
        .room-integrations-btn { background: transparent; border: none; color: var(--text-secondary); font-size: 1em; cursor: pointer; padding: 0 4px; }

/* ── Component classes (R95/F2b): de-inlined from the repeated style= clusters
   in index.html. Declarations match the former inline values exactly, so this
   is pixel-preserving; it just gives each repeated pattern one home. Size
   modifiers come after the base so they win on equal specificity. ── */
.btn { border: none; border-radius: 4px; cursor: pointer; padding: 7px 16px; }
.btn--accent { background: var(--accent); color: #fff; }
.btn--slate  { background: var(--slate-700); color: var(--slate-50); }
.btn--lg { padding: 8px 16px; }
.btn--sm { padding: 4px 10px; font-size: 0.8em; flex-shrink: 0; }
.btn-row { display: flex; gap: 8px; justify-content: flex-end; }
.field-divider { border-color: var(--slate-700); margin: 16px 0 12px; }
.section-label { margin: 0 0 8px; font-size: 0.8em; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
