:root {
    color-scheme: dark;
    --bg: #0f1115;
    --panel: #181b22;
    --panel-2: #1f232c;
    --border: #2a2f3a;
    --text: #e6e8ec;
    --muted: #9aa3b2;
    --accent: #5b8cff;
    --accent-2: #3a6df0;
    --accent-text: #ffffff;     /* text/icon color on accent-filled buttons; user-customizable */
    --danger: #e5484d;
    --ok: #30a46c;
    --warn: #f5a524;
    --displayed: #21331f;       /* green tint for already-displayed chats */
    --displayed-border: #3f8f4a;
    --live-color: #5b8cff;      /* overlay "live chat" highlight; user-customizable */
    /* Alert / badge / tag / chip text+background colors — split into
       variables (rather than hardcoded hex) so the light theme (Settings →
       Appearance → Theme) can swap them for readable equivalents; see
       light_theme_css_vars() in includes/functions.php. */
    --banner-danger-text: #ffd7d9;
    --alert-error-bg: #3a1d1f;
    --alert-error-text: #ffb3b5;
    --alert-ok-bg: #16301f;
    --alert-ok-text: #9be3b8;
    --alert-info-bg: #1a2540;
    --alert-info-text: #b7c8ff;
    --badge-ok-text: #9be3b8;
    --badge-warn-text: #ffd591;
    --badge-danger-text: #ffb3b5;
    --tag-superchat: #ffd591;
    --tag-membership: #9be3b8;
    --chip-mod-text: #b7c8ff;
    --chip-owner-text: #ffd591;
    --chip-member-text: #9be3b8;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg);
    color: var(--text);
    font-size: 14px;
    /* Sticky footer: fill at least the viewport, let <main> grow, so the footer
       sits at the actual bottom of the page instead of floating up under short
       content. (Floating widgets are position:fixed and stay out of this flow.) */
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

.topbar {
    display: flex; align-items: center; gap: 10px 20px;
    flex-wrap: wrap;
    padding: 10px 18px;
    background: var(--panel);
    border-bottom: 1px solid var(--border);
}
.header-avatar {
    width: 64px; height: 64px; border-radius: 50%; overflow: hidden;
    background: var(--panel-2); border: 2px solid var(--border);
    display: flex; align-items: center; justify-content: center;
    font-size: 24px; font-weight: 700; color: var(--muted); flex-shrink: 0;
}
.header-avatar img { width: 100%; height: 100%; object-fit: cover; }
/* On narrow screens the toolbar reads: site name + Menu together on the
   left, then every button (Deploy/Migrate, role badge, Logout, avatar)
   grouped and pushed to the right. Stacking each button pair vertically
   (Deploy above Migrate, badge above Logout) keeps each cluster's own
   horizontal footprint down to one button's width, so the whole row fits
   without needing to wrap onto a second line. flex-wrap stays on as a
   fallback for extreme widths, but the design targets a single row. */
@media (max-width: 640px) {
    .topbar { padding: 8px 10px; gap: 6px 10px; flex-wrap: wrap; align-items: center; }
    /* The site name always stays readable: it may wrap to two lines
       ("Streamers" / "Chat") but never ellipsizes away. The BUTTONS are what
       shrink to make the row fit. */
    .brand { flex-shrink: 1; min-width: 74px; }
    .brand a { display: block; line-height: 1.15; }
    /* Menu sits right after the brand, inline on row 1 — not its own row. */
    .navwrap { order: 1; margin-right: 0; flex-shrink: 0; }
    /* Deploy/Migrate is the first "pushed right" item: margin-left:auto here
       shoves it AND everything after it (the role badge/Logout/avatar) over
       to the right edge as one grouped cluster next to the profile picture. */
    .admin-quick-actions { order: 2; margin-left: auto; flex-direction: column; align-items: stretch !important; margin-right: 0 !important; gap: 3px !important; flex-shrink: 0; }
    .userbox { order: 3; flex-wrap: nowrap; gap: 5px; flex-shrink: 0; }
    .uname { display: none; }
    .header-avatar { width: 32px; height: 32px; font-size: 14px; }
    /* Skinny header buttons so row 1 fits with the full site name. The admin
       Deploy/Migrate quick actions didn't exist when this row was designed —
       unshrunk, they overflowed the viewport. */
    .navtoggle { padding: 4px 8px; font-size: 11px; gap: 4px; }
    .userbox .btn,
    .admin-quick-actions .btn { padding: 3px 6px; font-size: 10px; }
    /* Stack the button pairs vertically so each cluster trades width for
       height: Deploy sits above Migrate, and the role badge sits above
       Logout. The !importants beat the elements' inline flex styles (set in
       header.php). */
    .admin-quick-actions .btn { text-align: center; }
    .user-actions { flex-direction: column; align-items: stretch; gap: 3px; }
    .user-actions .btn { text-align: center; }
    .ulevel { font-size: 10px; padding: 1px 4px; text-align: center; }
}
@media (max-width: 420px) {
    .brand a { font-size: 12px; }
    /* The badge used to be hidden here to fit; stacked above Logout it costs
       no extra width, so it stays visible — just a touch smaller. */
    .ulevel { font-size: 9px; }
    .header-avatar { width: 28px; height: 28px; font-size: 12px; }
    .userbox { gap: 4px; }
    /* Tighter still: icon-only Menu button (the ☰ glyph keeps its size via
       .navtoggle-icon), skinnier action buttons — the name stays. */
    .navtoggle { font-size: 0; padding: 5px 7px; gap: 0; }
    .navtoggle-icon { font-size: 15px; }
    .topbar { gap: 5px; }
    .userbox .btn,
    .admin-quick-actions .btn { padding: 2px 5px; font-size: 9.5px; }
}
.brand a { font-weight: 700; font-size: 16px; color: var(--text); }

/* Collapsible nav: a "Menu" button that opens the links as a dropdown panel,
   instead of the links filling the whole top bar. */
.navwrap { position: relative; margin-right: auto; }
.navtoggle {
    cursor: pointer;
    background: var(--panel-2); color: var(--text);
    border: 1px solid var(--border); border-radius: 7px;
    padding: 7px 14px; font-size: 13px; font-weight: 600; line-height: 1.2;
    display: inline-flex; align-items: center; gap: 8px;
}
.navtoggle:hover { background: var(--border); }
.navtoggle-icon { font-size: 15px; line-height: 1; }
.mainnav {
    display: none;
    position: absolute; top: calc(100% + 6px); left: 0;
    flex-direction: column; gap: 2px;
    min-width: 210px; padding: 8px;
    background: var(--panel); border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 8px 26px rgba(0, 0, 0, 0.45);
    z-index: 100;
}
.mainnav.open { display: flex; }
.mainnav a { color: var(--text); padding: 8px 12px; border-radius: 7px; }
.mainnav a:hover { background: var(--panel-2); text-decoration: none; }
.userbox { display: flex; align-items: center; gap: 10px; }
/* Role badge + Logout live in one wrapper so narrow screens can stack them
   vertically (see the 640px media query above). Full width: a normal row. */
.user-actions { display: flex; align-items: center; gap: 10px; }
.uname { font-weight: 600; }
.ulevel { color: var(--muted); font-size: 12px; border: 1px solid var(--border); padding: 1px 6px; border-radius: 10px; }

/* Reusable site-wide message banner: a larger translucent-red frame spanning the
   top of the page content. Hidden by default; shown for the bio prompt, errors
   and notices via $pageBanner or window.showBanner(). */
.site-banner {
    background: rgba(229, 72, 77, 0.16);
    border: 1px solid rgba(229, 72, 77, 0.55);
    border-radius: 10px;
    color: var(--banner-danger-text);
    padding: 16px 20px;
    margin: 18px auto 0;
    max-width: 1200px;
    font-size: 15px;
}
.site-banner-inner { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.site-banner-actions { display: flex; gap: 10px; flex-shrink: 0; }
.site-banner-actions:empty { display: none; }

.container { max-width: 1200px; margin: 0 auto; padding: 20px 18px 60px; width: 100%; flex: 1 0 auto; }
/* Opt-in full-width container (Live Data) so layout columns use the whole screen. */
.container.container-wide { max-width: none; }
.bottombar { text-align: center; color: var(--muted); padding: 16px; font-size: 12px; flex-shrink: 0; }

h1 { font-size: 22px; margin: 0 0 16px; }
h2 { font-size: 17px; margin: 24px 0 12px; }

/* Hard clamp: no panel — whatever its content does — can ever grow past its
   grid column and bleed past the page's left/right padding. This is the one
   shared backstop for every panel (~15+), not something each one has to get
   right on its own. */
.panel { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 16px; margin-bottom: 18px; box-sizing: border-box; max-width: 100%; overflow-x: hidden; }
/* Admin-restricted panel, hidden from a viewer whose account level isn't
   permitted. !important so the user's own "customize sections" show/hide
   toggle (a plain inline style.display set from JS) can never reveal it. */
.sc-panel-denied { display: none !important; }

/* Buttons */
.btn {
    display: inline-block; cursor: pointer;
    background: var(--accent-2); color: var(--accent-text, #fff); border: none;
    padding: 8px 14px; border-radius: 7px; font-size: 13px; font-weight: 600;
    text-decoration: none; line-height: 1.2;
}
.btn:hover { background: var(--accent); text-decoration: none; }
.btn-small { padding: 5px 10px; font-size: 12px; }
.btn-secondary { background: var(--panel-2); border: 1px solid var(--border); color: var(--text); }
.btn-danger { background: var(--danger); }
.btn-ok { background: var(--ok); }

/* Forms */
.form { max-width: 420px; }
.form label { display: block; margin: 12px 0 4px; color: var(--muted); font-size: 13px; }
.form input, .form select, .form textarea {
    width: 100%; padding: 9px 11px; background: var(--panel-2);
    border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-size: 14px;
}
.form .btn { margin-top: 16px; width: 100%; }
.formrow { display: flex; gap: 10px; align-items: flex-end; }
.formrow > div { flex: 1; }
.formrow > div input, .formrow > div select, .formrow > div textarea {
    width: 100%; padding: 9px 11px; background: var(--panel-2);
    border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-size: 14px;
}
/* Every .formrow across the site (Settings, Groups, Connections, Overlays, …)
   is the same "row of fields + a button" shape. On narrow screens stack each
   field/button onto its own full-width line instead of squeezing them all
   into one row. !important beats the inline flex:1/min-width some fields set
   for their WIDE-screen row layout — those don't apply once stacked. */
@media (max-width: 640px) {
    .formrow { flex-direction: column; align-items: stretch; }
    .formrow > input, .formrow > select, .formrow > textarea,
    .formrow > button, .formrow > label, .formrow > div, .formrow > span {
        width: 100% !important;
        flex: none !important;
        box-sizing: border-box;
    }
}

.auth-wrap { max-width: 380px; margin: 8vh auto; }
.auth-wrap .panel { padding: 24px; }
.auth-links { margin-top: 14px; font-size: 13px; display: flex; justify-content: space-between; }
.auth-divider { display: flex; align-items: center; gap: 10px; margin: 18px 0; color: var(--muted); font-size: 12px; }
.auth-divider::before, .auth-divider::after { content: ''; flex: 1; height: 1px; background: var(--border); }
.auth-social { display: block; width: 100%; text-align: center; margin-top: 8px; box-sizing: border-box; }

.alert { padding: 10px 14px; border-radius: 8px; margin-bottom: 14px; font-size: 13px; }
.alert-error { background: var(--alert-error-bg); border: 1px solid var(--danger); color: var(--alert-error-text); }
.alert-ok { background: var(--alert-ok-bg); border: 1px solid var(--ok); color: var(--alert-ok-text); }
.alert-info { background: var(--alert-info-bg); border: 1px solid var(--accent-2); color: var(--alert-info-text); }

/* Tables */
table.data { width: 100%; border-collapse: collapse; }
table.data th, table.data td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; vertical-align: middle; }
table.data th { color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: .03em; }
table.data tr:hover { background: var(--panel-2); }

/* Narrow, fixed-width tables (e.g. settings tiers): wrap header text instead
   of forcing the column wide enough to fit it on one line, and shrink the
   font slightly on narrow viewports so it keeps fitting. */
table.data.sc-tiers th {
    white-space: normal;
    word-break: break-word;
    font-size: clamp(10px, 2.6vw, 12px);
}
table.data.sc-tiers td input[type="number"],
table.data.sc-tiers td input[type="color"] {
    width: 100%;
    box-sizing: border-box;
}

/* Stacked table on narrow / portrait screens: each row becomes a card and each
   cell stacks vertically with its column name (from data-label) shown above it,
   instead of scrolling a wide horizontal grid. Opt-in via .responsive-stack. */
@media (max-width: 640px) {
    table.data.responsive-stack,
    table.data.responsive-stack tbody,
    table.data.responsive-stack tr,
    table.data.responsive-stack td {
        display: block;
        width: 100%;
    }
    table.data.responsive-stack thead { display: none; }
    table.data.responsive-stack tr {
        border: 1px solid var(--border);
        border-radius: 9px;
        background: var(--panel);
        margin-bottom: 12px;
        padding: 2px 0;
    }
    table.data.responsive-stack tr:hover { background: var(--panel); }
    table.data.responsive-stack td {
        border-bottom: 1px solid var(--border);
        padding: 8px 12px;
        white-space: normal;
        text-align: left;
    }
    table.data.responsive-stack tr td:last-child { border-bottom: none; }
    table.data.responsive-stack td::before {
        content: attr(data-label);
        display: block;
        margin-bottom: 4px;
        color: var(--muted);
        font-size: 11px;
        text-transform: uppercase;
        letter-spacing: .03em;
    }
    table.data.responsive-stack td:not([data-label])::before { display: none; }
}

.badge { font-size: 11px; padding: 2px 7px; border-radius: 10px; border: 1px solid var(--border); color: var(--muted); }
.badge-ok { color: var(--badge-ok-text); border-color: var(--ok); }
.badge-warn { color: var(--badge-warn-text); border-color: var(--warn); }
.badge-danger { color: var(--badge-danger-text); border-color: var(--danger); }

.avatar { width: 32px; height: 32px; border-radius: 50%; object-fit: cover; background: var(--panel-2); }

.muted { color: var(--muted); }
.right { text-align: right; }
.nowrap { white-space: nowrap; }
.flex { display: flex; gap: 10px; align-items: center; }
.spread { display: flex; justify-content: space-between; align-items: center; gap: 12px; }

/* Stream cards */
.stream-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 14px; }
.stream-card { background: var(--panel); border: 1px solid var(--border); border-radius: 10px; padding: 14px; }
.stream-card h3 { margin: 0 0 6px; font-size: 15px; }
.stream-card .vid { color: var(--muted); font-size: 12px; word-break: break-all; }
.stream-card .stats { margin: 10px 0; color: var(--muted); font-size: 12px; }

/* Chat manager rows */
/* Float the avatar left and the action buttons right so the message text uses
   the full width of the row and wraps beneath the buttons once it runs past
   them, instead of being boxed into a narrow middle column. */
.chat-row { display: block; padding: 10px; border: 1px solid var(--border); border-radius: 9px; margin-bottom: 8px; background: var(--panel); cursor: pointer; }
.chat-row::after { content: ""; display: table; clear: both; } /* contain the floated avatar/actions */
.chat-row .actions { cursor: default; }
.chat-row.displayed { background: var(--displayed); border-color: var(--displayed-border); }
/* The one chat currently live on the overlay: a neon gradient ring + pulsing
   glow + a clickable "ON OVERLAY" tab. Clicking the tab opens the highlight
   color picker; clicking elsewhere on the row clears the overlay. The glow
   color is var(--live-color), saved per-user and customizable. */
.chat-row.live {
    position: relative;
    border-color: var(--live-color, var(--accent));
    box-shadow:
        0 0 0 2px var(--live-color, var(--accent)),
        0 0 14px 2px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent),
        0 0 30px 5px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent);
    animation: liveGlowPulse 1.8s ease-in-out infinite;
}
/* Gradient neon border ring (drawn with the border-mask trick so the row's
   own background shows through the middle). */
.chat-row.live::before {
    content: "";
    position: absolute;
    inset: -2px;
    border-radius: 11px;
    padding: 2px;
    background: linear-gradient(135deg,
        var(--live-color, var(--accent)),
        rgba(255, 255, 255, .85) 35%,
        var(--live-color, var(--accent)) 65%,
        rgba(255, 255, 255, .7));
    -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
            mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
            mask-composite: exclude;
    pointer-events: none;
    filter: drop-shadow(0 0 4px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent));
    z-index: 0;
}
/* Keep row content above the gradient ring pseudo-element. */
.chat-row.live > .body,
.chat-row.live > .avatar,
.chat-row.live > .actions { position: relative; z-index: 1; }
@keyframes liveGlowPulse {
    0%, 100% { box-shadow: 0 0 0 2px var(--live-color, var(--accent)), 0 0 12px 2px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent), 0 0 24px 3px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent); }
    50%      { box-shadow: 0 0 0 2px var(--live-color, var(--accent)), 0 0 20px 3px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent), 0 0 40px 8px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent); }
}
/* Clickable "ON OVERLAY" tab (a bit bigger than before). */
.live-tab {
    position: absolute;
    top: -11px;
    right: 12px;
    z-index: 2;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .7px;
    color: #fff;
    border: none;
    cursor: pointer;
    padding: 3px 12px;
    border-radius: 9px;
    background-color: var(--live-color, var(--accent));
    background: linear-gradient(135deg,
        var(--live-color, var(--accent)),
        color-mix(in srgb, var(--live-color, var(--accent)) 45%, #ffffff));
    box-shadow: 0 1px 5px rgba(0, 0, 0, .45), 0 0 10px color-mix(in srgb, var(--live-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent);
    text-shadow: 0 1px 2px rgba(0, 0, 0, .4);
}
.live-tab:hover { filter: brightness(1.08); }
.chat-row .avatar { float: left; margin-right: 10px; }
.chat-row .body { min-width: 0; }
.chat-row .author { font-weight: 600; }
.chat-row .text { color: var(--text); word-wrap: break-word; }
.chat-row .text img.emoji { height: 1.2em; vertical-align: -0.2em; }
.chat-row .meta { color: var(--muted); font-size: 11px; margin-top: 3px; }
.chat-row .actions { float: right; margin-left: 10px; display: flex; flex-direction: column; gap: 6px; }
.tag-superchat { color: var(--tag-superchat); }
.tag-membership { color: var(--tag-membership); }
.chip { font-size: 10px; padding: 1px 6px; border-radius: 8px; border: 1px solid var(--border); color: var(--muted); }
.chip-mod { color: var(--chip-mod-text); border-color: var(--accent-2); }
.chip-owner { color: var(--chip-owner-text); border-color: var(--warn); }
.chip-member { color: var(--chip-member-text); border-color: var(--ok); }
.badge-img { width: 18px; height: 18px; border-radius: 50%; vertical-align: middle; object-fit: cover; }
/* Overlay/projector button on section headers */
.panel-overlay-btn { /* styles inherited from .metric-gear-btn (both classes applied) */ }

/* Gear button on section headers (metrics, group chat, …) */
.metric-gear-btn, .gc-gear-btn {
    background: none; border: none; color: var(--text); cursor: pointer;
    padding: 6px 8px; display: inline-flex; align-items: center; border-radius: 6px; line-height: 0;
    touch-action: manipulation; -webkit-tap-highlight-color: transparent;
}
.metric-gear-btn:hover, .gc-gear-btn:hover { background: var(--panel-2); }

.toolbar { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; margin-bottom: 14px; }
.toolbar select, .toolbar input { padding: 7px 10px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 7px; color: var(--text); }
/* Chat Filters: give each labelled dropdown / date / search its own full-width
   row so the label text sits on the left edge and the control stretches to the
   right edge — every control then shares the same right edge. (Checkboxes and
   buttons keep their inline grouping.) */
.chat-filters .toolbar > label.muted:has(> select),
.chat-filters .toolbar > label.muted:has(> input[type="date"]) { flex: 1 1 100%; display: flex; align-items: center; gap: 10px; }
.chat-filters .toolbar > label.muted:has(> select) > select,
.chat-filters .toolbar > label.muted:has(> input[type="date"]) > input { flex: 1 1 auto; min-width: 0; }
.chat-filters .toolbar > input[type="text"] { flex: 1 1 100%; }
.pager { display: flex; gap: 8px; margin-top: 14px; align-items: center; }

/* Two-column split chat view */
.chat-columns { display: block; }
.col-label { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 4px; }

/* Analytics charts */
.chart-wrap {
    position: relative;
    margin-top: 6px;
    padding: 10px 6px 4px;
    border: 1px solid var(--border);
    border-radius: 12px;
    background:
        radial-gradient(120% 140% at 0% 0%, rgba(91,140,255,0.07), transparent 55%),
        linear-gradient(180deg, var(--panel-2), var(--panel));
}
.chart-legend {
    display: flex; flex-wrap: wrap; gap: 6px 14px;
    margin: 6px 0 2px; font-size: 12px;
}
.chart-legend .lg {
    display: inline-flex; align-items: center; gap: 6px;
    color: var(--muted);
}
.chart-legend .lg .sw {
    width: 12px; height: 3px; border-radius: 2px; display: inline-block;
}
/* Clickable stat cards behave like buttons */
.metric-card { transition: border-color .12s ease, transform .12s ease, box-shadow .12s ease; }
.metric-card:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0,0,0,0.28); }
.metric-card.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset, 0 4px 16px rgba(91,140,255,0.25); }
.btn-small.active { background: var(--accent); color: var(--accent-text, #fff); border-color: var(--accent); }

/* Sliding toggle switch (e.g. Days/Years on Manage Streams). */
.toggle-switch {
    position: relative;
    display: inline-block;
    width: 44px;
    height: 24px;
    flex: 0 0 auto;
    vertical-align: middle;
}
.toggle-switch input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}
.toggle-slider {
    position: absolute;
    cursor: pointer;
    inset: 0;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 24px;
    transition: background .18s ease, border-color .18s ease;
}
.toggle-slider::before {
    content: "";
    position: absolute;
    height: 18px;
    width: 18px;
    left: 2px;
    top: 50%;
    transform: translateY(-50%);
    background: var(--muted, #9aa4b2);
    border-radius: 50%;
    transition: transform .18s ease, background .18s ease;
}
.toggle-switch input:checked + .toggle-slider {
    background: var(--accent-2);
    border-color: var(--accent);
}
.toggle-switch input:checked + .toggle-slider::before {
    transform: translate(20px, -50%);
    background: #fff;
}
.toggle-switch input:focus-visible + .toggle-slider {
    box-shadow: 0 0 0 2px var(--accent);
}

/* Floating group-chat widget (footer-injected on every page). */
.sc-chat { position: fixed; right: 18px; bottom: 18px; z-index: 1000; }
.sc-chat-toggle {
    width: 52px; height: 52px; border-radius: 50%; border: 2px solid var(--chat-color, var(--accent)); cursor: pointer;
    background: rgba(15, 17, 21, 0.95); color: var(--chat-color, var(--accent)); font-size: 22px; line-height: 1;
    display: flex; align-items: center; justify-content: center; padding: 0;
    box-shadow:
        0 0 14px var(--sc-chat-glow-1, rgba(91, 140, 255, 0.55)),
        0 0 28px var(--sc-chat-glow-2, rgba(91, 140, 255, 0.32)),
        inset 0 0 10px var(--sc-chat-glow-3, rgba(91, 140, 255, 0.16)),
        0 6px 20px rgba(0, 0, 0, 0.45);
    transition: all 0.3s ease;
}
.sc-chat-toggle:hover {
    border-color: var(--chat-color, var(--accent));
    box-shadow:
        0 0 20px var(--sc-chat-glow-1-hover, rgba(91, 140, 255, 0.75)),
        0 0 40px var(--sc-chat-glow-2-hover, rgba(91, 140, 255, 0.45)),
        inset 0 0 10px var(--sc-chat-glow-3-hover, rgba(91, 140, 255, 0.22)),
        0 6px 20px rgba(0, 0, 0, 0.45);
    transform: scale(1.05);
}
/* Blink: slow opacity pulse when there are unread messages. Never goes fully invisible. */
@keyframes sc-blink {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.3; }
}
/* Vibrate: "ringing phone" rotation shake for overdue unread messages. */
@keyframes sc-vibrate {
    0%, 100% { transform: rotate(0deg); }
    15% { transform: rotate(-12deg); }
    30% { transform: rotate(12deg); }
    45% { transform: rotate(-10deg); }
    60% { transform: rotate(10deg); }
    75% { transform: rotate(-6deg); }
    90% { transform: rotate(6deg); }
}
.sc-chat-toggle.sc-blink  { animation: sc-blink   1.8s ease-in-out infinite; }
.sc-chat-toggle.sc-vibrate { animation: sc-vibrate 0.6s  ease-in-out infinite; }
.sc-chat-icon {
    width: 28px; height: 28px; stroke-width: 2.5; flex-shrink: 0;
}
.sc-chat-badge {
    position: absolute; top: -2px; right: -2px; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 9px; background: var(--danger); color: #fff;
    font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; display: none;
}
.sc-chat-panel {
    position: absolute; right: 0; bottom: 64px;
    width: 340px; max-width: calc(100vw - 36px);
    height: 460px; max-height: calc(100vh - 110px);
    display: flex; flex-direction: column;
    background: var(--panel); border: 1px solid var(--border); border-radius: 12px;
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.5); overflow: hidden;
}
.sc-chat-head { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border); }
.sc-chat-head select { flex: 1; min-width: 0; padding: 6px 8px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 7px; color: var(--text); }
.sc-chat-head .sc-iconbtn {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 7px; cursor: pointer;
    background: var(--panel-2); border: 1px solid var(--border); color: var(--text); font-size: 15px; line-height: 1;
}
.sc-chat-head .sc-iconbtn:hover { background: var(--border); }
.sc-chat-people { padding: 10px; border-bottom: 1px solid var(--border); background: var(--panel-2); font-size: 13px; overflow-y: auto; max-height: 260px; }
.sc-chat-people label { display: block; color: var(--muted); font-size: 11px; margin: 8px 0 3px; }
.sc-chat-people .flex { display: flex; gap: 6px; }
.sc-chat-people input, .sc-chat-people select { flex: 1; min-width: 0; padding: 6px 8px; background: var(--panel); border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-size: 13px; }
.sc-chat-people .sc-status { margin-top: 8px; min-height: 16px; font-size: 12px; }
.sc-chat-msgs { flex: 1; overflow-y: auto; padding: 10px; display: flex; flex-direction: column; gap: 5px; }
.sc-chat-msg { padding: 4px 8px; border-radius: 7px; max-width: 85%; word-break: break-word; font-size: 13px; }
.sc-chat-msg.mine { align-self: flex-end; background: var(--gc-mine-bg, var(--accent-2)); color: var(--gc-mine-color, #fff); font-family: var(--gc-mine-font, inherit); }
/* The group chat panel docked into the page's "Group Chat" section. */
.sc-chat-panel.sc-chat-docked {
    position: static; right: auto; bottom: auto;
    width: 100%; max-width: none; height: 440px; max-height: none; box-shadow: none;
}
.sc-chat-msg.theirs { align-self: flex-start; background: var(--panel-2); }
.sc-chat-msg .who { font-weight: 600; font-size: 11px; }
.sc-chat-msg .when { opacity: .6; font-size: 10px; }
/* Markdown/link styling inside group-chat messages (floating widget + dashboard
   panel). Links underline on the accent color; code spans get a mono chip. */
.sc-chat-msg a, #gcMessages a { color: var(--accent); text-decoration: underline; word-break: break-all; }
.sc-chat-msg.mine a { color: #fff; }
.sc-chat-msg code, #gcMessages code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: .92em; padding: 1px 4px; border-radius: 4px;
    background: rgba(127, 127, 127, 0.22);
}
.sc-chat-msg strong, #gcMessages strong { font-weight: 700; }
.sc-chat-msg em, #gcMessages em { font-style: italic; }
.sc-chat-input { display: flex; gap: 6px; padding: 8px 10px; border-top: 1px solid var(--border); align-items: center; }
/* font-size must be >= 16px so iOS Safari doesn't auto-zoom the page when the
   field is focused to type. */
.sc-chat-input input { flex: 1; min-width: 0; padding: 7px 9px; background: var(--panel-2); border: 1px solid var(--border); border-radius: 7px; color: var(--text); font-size: 16px; }
.sc-chat-attach { display: flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 7px; cursor: pointer; color: var(--muted); flex-shrink: 0; transition: color .15s, background .15s; }
.sc-chat-attach:hover { color: var(--text); background: var(--panel-2); }
.sc-chat-ctx { display: flex; flex-wrap: wrap; gap: 3px; margin: 2px 0 1px; font-size: 10px; }
.sc-chat-grp { background: var(--accent-2,#3a4faa); color: var(--accent-text, #fff); border-radius: 4px; padding: 1px 5px; opacity: .85; }
.sc-chat-ctx.sc-chat-ctx-conx { opacity: .6; }
.sc-chat-msg.mine .sc-chat-grp { background: rgba(255,255,255,.25); }
.sc-chat-img { margin-top: 4px; }
.sc-chat-img img { max-width: 100%; max-height: 200px; border-radius: 6px; cursor: pointer; display: block; }
.sc-chat-file { margin-top: 4px; font-size: 12px; }
.sc-chat-file a { word-break: break-all; }
.sc-chat-empty { color: var(--muted); font-size: 12px; }
@media (max-width: 640px) {
    .sc-chat { right: 12px; bottom: 12px; }
    .sc-chat-panel { width: calc(100vw - 24px); }
}

/* Prevent iOS/Android auto-zoom on input focus. Mobile browsers zoom in when
   a focused field's font-size is below 16px; this overrides it on touch devices
   without affecting desktop appearance. */
@media (hover: none) and (pointer: coarse) {
    input, select, textarea { font-size: 16px; }
}

/* View-session gate overlay */
.sc-view-gate {
    position: fixed; inset: 0; z-index: 200;
    background: rgba(0,0,0,0.78); display: flex;
    align-items: center; justify-content: center;
}
.sc-view-gate-box {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 14px; padding: 32px 36px; max-width: 420px; width: 90%;
    box-shadow: 0 16px 48px rgba(0,0,0,0.55); text-align: center;
}
.sc-view-gate-box h2 { margin: 0 0 10px; }
.sc-view-gate-box > p { color: var(--muted); margin: 0 0 18px; }
.sc-gate-spinner {
    width: 36px; height: 36px; border: 3px solid var(--border);
    border-top-color: var(--accent); border-radius: 50%;
    animation: sc-spin 0.8s linear infinite; margin: 14px auto 0;
}
@keyframes sc-spin { to { transform: rotate(360deg); } }
.sc-view-gate-box .flex { justify-content: center; gap: 6px; margin-top: 10px; }
.sc-view-gate-box input[type="text"] {
    flex: 1; padding: 8px 10px; background: var(--panel-2);
    border: 1px solid var(--border); border-radius: 7px; color: var(--text);
}

/* Session access-request cards in the chat widget */
.sc-access-req {
    background: var(--panel); border: 1px solid var(--border);
    border-radius: 9px; padding: 9px 11px; margin-bottom: 7px;
    font-size: 13px;
}
.sc-access-req .sc-req-name { font-weight: 600; }
.sc-access-req .sc-req-type { font-size: 11px; color: var(--muted); margin-left: 5px; }
.sc-access-req .sc-req-actions { display: flex; gap: 6px; margin-top: 7px; }
.sc-session-reqs-area { padding: 8px 10px; border-bottom: 1px solid var(--border); }
.sc-session-reqs-area h4 {
    margin: 0 0 7px; font-size: 11px; color: var(--muted);
    text-transform: uppercase; letter-spacing: .05em;
}

/* ----------------------------------------------------------------
   Soundboard widget (bottom-left floating widget)
   ---------------------------------------------------------------- */
.sc-sb {
    position: fixed;
    bottom: 18px;
    left: 18px;
    z-index: 1200;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
}
/* When the soundboard is docked into the page's Soundboard section it sheds its
   floating-card styling and fills the section width — the configured columns
   stretch to span the column (via --sb-track) and the tiles fill their cells. */
.sc-sb-panel.sc-sb-docked {
    position: static; width: 100%; max-width: 100%; box-sizing: border-box;
    border: none; border-radius: 0; box-shadow: none; margin: 0;
    /* Horizontal was "visible" — that undid the grid's own overflow clamp below
       by letting an oversized child (e.g. a long "Send to" option) bleed
       straight through this wrapper instead of being contained by it. Vertical
       stays visible/uncapped so the grid can still grow tall with no inner
       scrollbar — the page scrolls instead. */
    overflow-x: hidden; overflow-y: visible;
}
.sc-sb-panel.sc-sb-docked .sc-sb-grid {
    --sb-track: minmax(0, 1fr);
    /* max-width stays 100% (not "none") so a wide/many-column grid never bleeds
       past the section's right edge on a narrow screen — it scrolls
       horizontally instead. Height still grows freely (no cap, no clipping) so
       the page scrolls rather than an inner scrollbar appearing. */
    width: 100%; max-width: 100%; max-height: none; overflow-x: auto; overflow-y: visible;
}
.sc-sb-panel.sc-sb-docked .sc-sb-cell { width: 100%; }
/* The two plain wrapper divs between the panel and the docked widget
   (index.php: #soundboardPanel-body, #soundboardDock) had no width/overflow
   rules of their own — an unconstrained ancestor is enough to let an oversized
   descendant bleed past the section regardless of the clamps above it. */
#soundboardPanel-body, #soundboardDock { max-width: 100%; box-sizing: border-box; overflow-x: hidden; }
/* The section header already says "Soundboard" — drop the panel's own title. */
.sc-sb-panel.sc-sb-docked .sc-sb-title { display: none; }
.sc-sb-toggle {
    width: 52px; height: 52px; border-radius: 50%;
    background: rgba(15, 17, 21, 0.95); border: 2px solid var(--mx-color, var(--accent));
    color: var(--mx-color, var(--accent)); cursor: pointer;
    display: flex; align-items: center; justify-content: center; padding: 0;
    box-shadow:
        0 0 14px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 55%), transparent),
        0 0 28px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 32%), transparent),
        inset 0 0 10px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 16%), transparent),
        0 6px 20px rgba(0, 0, 0, 0.45);
    transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
    order: 2;
}
.sc-sb-toggle:hover {
    border-color: var(--mx-color, var(--accent));
    box-shadow:
        0 0 20px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 75%), transparent),
        0 0 40px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 45%), transparent),
        inset 0 0 10px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 22%), transparent),
        0 6px 20px rgba(0, 0, 0, 0.45);
    transform: scale(1.05);
}
.sc-sb-icon { width: 28px; height: 28px; stroke-width: 2.5; flex-shrink: 0; }
.sc-sb-panel {
    order: 1;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    box-shadow: 0 4px 20px rgba(0,0,0,.6);
    /* Hug the grid: the panel's intrinsic width comes from the tile grid alone
       (the head/controls rows below set width:0 + min-width:100% so they match
       the panel instead of stretching it). The container grows/shrinks with the
       column count; the tiles themselves stay a fixed square size (--sb-tile). */
    width: max-content;
    max-width: calc(100vw - 36px);
    overflow: hidden;
    margin-bottom: 10px;
}
/* Keep the toggle aligned with the chat button (which drops to 12px at 640px). */
@media (max-width: 640px) {
    .sc-sb { left: 12px; bottom: 12px; }
}
@media (max-width: 420px) {
    .sc-sb-panel { max-width: calc(100vw - 20px); }
}
/* ── Combined audio widget (mixer + soundboard share one floating panel) ──── */
/* Keep a sensible minimum so the mixer is usable even when the soundboard
   section is disabled (the soundboard grid would otherwise set the width).
   :not(.sc-sb-docked) is critical — this 300px floor is for the FLOATING
   corner widget only. When the same node is docked into the Soundboard
   dashboard panel, a 300px floor is wider than a narrow phone column and,
   because min-width beats the docked rule's max-width:100%, the widget
   spills past the panel's right edge. The docked override below drops it. */
.sc-sb-panel.sc-has-mixer:not(.sc-sb-docked) { min-width: 300px; }
.sc-sb-panel.sc-sb-docked { min-width: 0; }
/* The mixer's grid (mixer.js sets its columns to minmax(80px,1fr) — a hard
   80px-per-channel floor) can be wider than a narrow phone column; cap it and
   let the mixer body scroll it horizontally inside the panel rather than
   widening the panel. NOTE: this deliberately does NOT touch #scMixerSection /
   #scSbSection — those size themselves with the `width:0; min-width:100%` trick
   (and #scSbSection is display:contents), so forcing min-width:0 on them
   collapses the section to zero width and the whole widget renders blank. */
.sc-sb-panel.sc-sb-docked #mixerPanel-body,
.sc-sb-panel.sc-sb-docked .mx-root {
    max-width: 100%;
    min-width: 0;
    box-sizing: border-box;
}
.sc-sb-panel.sc-sb-docked #mixerPanel-body { overflow-x: auto; }
/* Section tabs (enable/disable each half). Match panel width without stretching. */
.sc-audio-tabs {
    display: flex; gap: 6px; width: 0; min-width: 100%; box-sizing: border-box;
    padding: 8px 10px; border-bottom: 1px solid var(--border); background: var(--panel-2);
    /* The mixer's Save/profile toolbar joins this row (mixer.js appends it
       here); wrap so tabs + toolbar stack only when genuinely too narrow. */
    flex-wrap: wrap; align-items: center;
}
.sc-audio-tab {
    /* Compact pills (they used to stretch 50/50 across their own row) so the
       profile toolbar fits beside them on one line. */
    flex: 0 1 auto; min-width: 90px; font-size: 12px; padding: 5px 14px; cursor: pointer;
    background: var(--panel); color: var(--muted);
    border: 1px solid var(--border); border-radius: 6px;
}
.sc-audio-tab.sc-audio-tab-on {
    color: var(--text); border-color: var(--accent, #5b8cff);
    box-shadow: inset 0 0 0 1px var(--accent, #5b8cff);
}
/* The mixer section matches the panel width (set by the soundboard grid) and
   scrolls internally; its body is overflow-x:auto. */
#scMixerSection { width: 0; min-width: 100%; box-sizing: border-box; padding: 8px 10px 6px; border-bottom: 1px solid var(--border); }
/* The soundboard wrapper is display:contents so its grid/head/controls remain
   direct panel children — preserving the panel's "hug the grid" width logic.
   Toggling display:none still hides the whole soundboard half. */
#scSbSection { display: contents; }

.sc-sb-head {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    /* Match the panel width (set by the grid) without contributing to it. */
    width: 0; min-width: 100%;
    padding: 9px 10px;
    border-bottom: 1px solid var(--border);
    background: var(--panel-2);
}
.sc-sb-head .sc-sb-title {
    font-weight: 600; font-size: 13px; flex: 1;
}
.sc-sb-head button, .sc-sb-controls button {
    background: var(--panel); border: 1px solid var(--border);
    color: var(--text); border-radius: 6px; cursor: pointer;
    padding: 4px 9px; font-size: 12px;
    transition: background .12s;
}
.sc-sb-head button:hover, .sc-sb-controls button:hover { background: var(--panel-2); border-color: var(--accent); }
.sc-sb-head button.active, .sc-sb-controls button.active { background: var(--accent); border-color: var(--accent); color: var(--accent-text, #fff); }
.sc-sb-controls {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    /* Match the panel width (set by the grid) without contributing to it. */
    width: 0; min-width: 100%;
    padding: 7px 10px;
    border-bottom: 1px solid var(--border);
    font-size: 12px; color: var(--muted);
}
/* Flex children default to min-width:auto, which lets a select with a long
   option (e.g. a Mixer bus name) force this row — and the panel around it —
   wider than 100%. flex-wrap already lets these rows wrap, so shrinking is
   always safe. */
.sc-sb-controls > select, .sc-sb-controls > input { min-width: 0; }
/* Combined toolbar sub-groups (Board / Rows-Cols / Send-to): each group stays
   together as a unit on the single row and wraps as a unit when the panel is
   too narrow to fit them side by side. The selects inside can shrink. */
.sc-sb-tb-group {
    display: inline-flex; align-items: center; gap: 6px;
    flex: 1 1 auto; min-width: 0;
}
.sc-sb-tb-group > select { flex: 1 1 90px; min-width: 70px; }
.sc-sb-controls input[type="number"] {
    width: 48px; padding: 3px 6px;
    background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 5px; color: var(--text); font-size: 12px; text-align: center;
}
/* Fixed square tiles. The grid lays out fixed-size --sb-tile tracks (set on the
   columns by soundboard.js) and matching square rows here, so adding or removing
   buttons changes the grid's overall size, never the size of an individual tile.
   Scrolls within the capped area when there are more tiles than fit. */
.sc-sb-grid {
    --sb-tile: 64px;
    display: grid;
    grid-auto-rows: var(--sb-tile);
    gap: 8px;
    padding: 10px;
    max-height: 340px;
    max-width: calc(100vw - 36px);
    overflow: auto;
}
.sc-sb-cell {
    box-sizing: border-box;
    width: var(--sb-tile);
    height: var(--sb-tile);
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 8px;
    cursor: pointer;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    padding: 6px 4px;
    transition: background .12s, border-color .12s;
    text-align: center;
    overflow: hidden;
    position: relative;
}
.sc-sb-cell:hover { background: var(--panel); border-color: var(--accent); }
.sc-sb-cell.has-sound { border-color: var(--accent-2); }
.sc-sb-cell img { width: 36px; height: 36px; object-fit: cover; border-radius: 6px; }
.sc-sb-cell .sb-emoji { font-size: 28px; line-height: 1; }
.sc-sb-cell .sb-title {
    display: var(--sb-title-display, block);
    font-size: var(--sb-title-size, 11px);
    color: var(--sb-title-color, var(--muted));
    font-family: var(--sb-title-font, inherit);
    margin-top: 3px; word-break: break-word; max-width: 100%;
}
/* Image tiles: stretch the image to fill the full tile, title as bottom overlay */
.sc-sb-cell.has-img { padding: 0; }
.sc-sb-cell.has-img img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover; border-radius: 7px;
}
.sc-sb-cell.has-img .sb-title {
    display: var(--sb-title-display, block);
    position: absolute; bottom: 0; left: 0; right: 0; z-index: 1;
    margin-top: 0;
    padding: 2px 4px;
    font-size: var(--sb-title-size, 11px);
    font-family: var(--sb-title-font, inherit);
    color: #fff;
    text-shadow: 0 1px 3px rgba(0,0,0,.9);
    background: rgba(0,0,0,.45);
    border-radius: 0 0 7px 7px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sc-sb-cell .sb-empty { font-size: 24px; color: var(--border); }

/* Soundboard modal */
.sc-sb-modal-backdrop {
    position: fixed; inset: 0; background: rgba(0,0,0,.55);
    z-index: 1300; display: flex; align-items: center; justify-content: center;
    padding: 16px;
}
.sc-sb-modal {
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: 12px;
    width: 340px; max-width: 100%;
    padding: 18px 18px 14px;
    box-shadow: 0 8px 32px rgba(0,0,0,.7);
}
.sc-sb-modal h3 { margin: 0 0 14px; font-size: 15px; }
.sc-sb-modal label { font-size: 12px; color: var(--muted); display: block; margin-bottom: 4px; }
.sc-sb-modal input[type="text"],
.sc-sb-modal input[type="url"],
.sc-sb-modal input[type="file"] {
    width: 100%; padding: 8px 10px;
    background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 7px; color: var(--text); font-size: 13px;
    margin-bottom: 12px;
}
.sc-sb-modal input[type="file"] { padding: 6px 8px; }
.sc-sb-modal .sc-sb-modal-row { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.sc-sb-modal .sc-sb-modal-row input { margin-bottom: 0; }
.sc-sb-modal .sc-sb-modal-icon-preview {
    width: 40px; height: 40px; border-radius: 6px; object-fit: cover; flex-shrink: 0;
    border: 1px solid var(--border);
}
.sc-sb-modal-actions { display: flex; gap: 8px; margin-top: 4px; align-items: center; }
.sc-sb-modal-status { font-size: 12px; color: var(--danger); margin-top: 8px; min-height: 18px; }

/* Play ring SVG overlay on cells */
.sb-play-ring {
    position: absolute; top: 0; left: 0;
    pointer-events: none; z-index: 10;
    border-radius: 8px; overflow: hidden;
}

/* Share button overlay inside a cell (edit mode) */
.sb-share-btn {
    position: absolute; top: 2px; right: 2px;
    width: 17px; height: 17px;
    border-radius: 4px; border: 1px solid var(--border);
    background: var(--panel-2); color: var(--muted);
    cursor: pointer; font-size: 9px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    z-index: 5; transition: background .12s;
}
.sb-share-btn:hover { background: var(--accent); color: var(--accent-text, #fff); border-color: var(--accent); }

/* Group sounds bar at bottom of panel */
.sc-sb-group-bar {
    width: 0; min-width: 100%;
    border-top: 1px solid var(--border);
}
.sc-sb-group-toggle {
    display: flex; align-items: center; gap: 5px;
    width: 100%; padding: 7px 10px;
    background: none; border: none; cursor: pointer;
    font-size: 12px; color: var(--muted); text-align: left;
}
.sc-sb-group-toggle:hover { color: var(--text); }
.sc-sb-badge {
    background: var(--accent); color: var(--accent-text, #fff);
    font-size: 10px; border-radius: 8px;
    padding: 1px 5px; min-width: 16px; text-align: center;
    display: none;
}
.sc-sb-badge:not(:empty) { display: inline-block; }
.sc-sb-chev { margin-left: auto; font-size: 10px; transition: transform .15s; }
.sc-sb-chev.open { transform: rotate(180deg); }
.sc-sb-group-list { max-height: 200px; overflow-y: auto; }
.sc-sb-group-item {
    display: flex; align-items: center; gap: 6px;
    padding: 6px 10px; font-size: 12px;
    border-top: 1px solid var(--border);
}
.sc-sb-group-item:first-child { border-top: none; }
.sc-sb-group-item-info { flex: 1; min-width: 0; }
.sc-sb-group-item-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-sb-group-item-meta { font-size: 11px; color: var(--muted); }
.sc-sb-group-item button {
    flex-shrink: 0; background: var(--panel-2); border: 1px solid var(--border);
    color: var(--text); border-radius: 5px; cursor: pointer;
    padding: 3px 7px; font-size: 11px; transition: background .12s;
}
.sc-sb-group-item button:hover { background: var(--accent); color: var(--accent-text, #fff); border-color: var(--accent); }
.sc-sb-group-item button.danger:hover { background: var(--danger); border-color: var(--danger); }
.sc-sb-group-empty { padding: 10px; font-size: 12px; color: var(--muted); text-align: center; }

/* Share modal group buttons */
.sc-sb-share-group-btn {
    display: block; width: 100%; text-align: left;
    background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 7px; padding: 9px 12px; margin-bottom: 7px;
    color: var(--text); font-size: 13px; cursor: pointer;
    transition: background .12s;
}
.sc-sb-share-group-btn:hover { background: var(--accent); color: var(--accent-text, #fff); border-color: var(--accent); }

/* Gear button in panel head */
.sc-sb-gear-btn { display: flex; align-items: center; justify-content: center; padding: 4px 7px; }
.sc-sb-gear-btn svg { display: block; }

/* Settings modal */
.sc-sb-settings-modal label { font-size: 13px; color: var(--text); margin-bottom: 8px; }
.sc-sb-slider {
    -webkit-appearance: none; appearance: none;
    width: 100%; height: 6px;
    border-radius: 3px; background: var(--border);
    outline: none; margin-bottom: 14px; cursor: pointer;
}
.sc-sb-slider::-webkit-slider-thumb {
    -webkit-appearance: none; appearance: none;
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--accent); cursor: pointer;
    box-shadow: 0 0 6px rgba(91,140,255,.5);
}
.sc-sb-slider::-moz-range-thumb {
    width: 20px; height: 20px; border-radius: 50%;
    background: var(--accent); cursor: pointer; border: none;
}
.sc-sb-tile-preview-wrap {
    display: flex; align-items: center; justify-content: center;
    min-height: 80px; margin-bottom: 14px;
}
.sc-sb-tile-preview {
    background: var(--panel-2); border: 1px solid var(--accent);
    border-radius: 8px; display: flex; align-items: center; justify-content: center;
    font-size: 28px; transition: width .1s, height .1s;
    overflow: hidden; min-width: 16px; min-height: 16px;
}

/* Tile-text styling controls in the soundboard settings modal */
.sc-sb-title-block { display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px; border-top: 1px solid var(--border); padding-top: 12px; }
.sc-sb-title-block label { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: 13px; color: var(--text); }
.sc-sb-title-block input[type="color"] { flex-shrink: 0; }
/* Output/destination picker — on the main soundboard toolbar (.sc-sb-dest-row). */
.sc-sb-output-select {
    padding: 4px 8px; background: var(--panel-2);
    border: 1px solid var(--border); border-radius: 6px; color: var(--text); font-size: 12px;
}
.sc-sb-output-note { font-size: 11px; margin: 0 0 6px; color: var(--muted); }

/* Trim modal */
.sc-sb-trim-modal { width: 460px; }
.sc-sb-trim-hint { font-size: 12px; color: var(--muted); margin: -8px 0 10px; }
.sc-sb-waveform-wrap {
    width: 100%; border-radius: 8px; overflow: hidden;
    border: 1px solid var(--border); margin-bottom: 8px;
    cursor: col-resize; background: #1a1d24;
}
.sc-sb-trim-canvas { display: block; width: 100%; height: 80px; }
.sc-sb-trim-times {
    display: flex; justify-content: space-between; align-items: center;
    font-size: 12px; color: var(--muted); margin-bottom: 12px;
}
.sc-sb-trim-times span:first-child { color: #5b8cff; }
.sc-sb-trim-times span:last-child { color: #ff7b5b; }

/* ── Appearance / theme settings ─────────────────────────────────── */
.theme-settings { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
.theme-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.theme-row label { min-width: 190px; font-size: 13px; color: var(--text); }
.theme-color-wrap { display: flex; align-items: center; gap: 8px; }
.theme-swatch {
    width: 34px; height: 34px; border-radius: 8px; border: 2px solid var(--border);
    cursor: pointer; padding: 0; flex-shrink: 0;
    transition: border-color .15s, transform .1s;
}
.theme-swatch:hover { border-color: var(--accent); transform: scale(1.08); }
.theme-hex {
    width: 90px; background: var(--panel-2); border: 1px solid var(--border);
    border-radius: 6px; color: var(--text); font-size: 13px; padding: 5px 8px;
    font-family: monospace; letter-spacing: .5px;
}
.theme-hex:focus { outline: none; border-color: var(--accent); }
.theme-slider {
    width: 100%; max-width: 280px;
    -webkit-appearance: none; appearance: none;
    height: 5px; border-radius: 3px;
    background: var(--border); cursor: pointer; accent-color: var(--accent);
}

/* ── Audio Mixer Panel ───────────────────────────────────────────── */

/* CSS Grid root — columns set via inline style by mixer.js. A console with
   several mixes can be wider than the panel's 320px design width, so the body
   scrolls horizontally inside the panel rather than overflowing into (and being
   clipped against) neighbouring columns. */
#mixerPanel-body { overflow-x: auto; overflow-y: visible; }
.mx-root { display: grid; }

/* display:contents lets each row's cells participate directly in the
   parent grid, keeping columns perfectly aligned across all rows. */
.mx-row { display: contents; }

/* Shared cell base */
.mx-input-cell,
.mx-mix-cell,
.mx-btn-cell {
    padding: 3px 6px;
    border-bottom: 1px solid var(--border);
    min-width: 0;
}

/* Column separators */
.mx-input-cell { border-right: 2px solid var(--border); }
.mx-mix-cell   { border-right: 1px solid var(--border); }

/* Header cells: thicker bottom border + slightly different bg */
.mx-hdr-label,
.mx-hdr-cell,
.mx-btn-cell.mx-hdr-btn {
    background: var(--panel-2);
    border-bottom: 2px solid var(--border);
}

.mx-hdr-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    display: flex;
    align-items: center;
}

.mx-hdr-cell {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Add-mix button cell */
.mx-btn-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    border-right: none;
}

/* Full-width spanning cell (add channel row, driver notice) */
.mx-span-cell {
    grid-column: 1 / -1;
    padding: 4px 6px;
    border-bottom: none;
}

/* Editable name inputs */
.mx-name-input {
    flex: 1;
    min-width: 0;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: clamp(10px, 2.5vw, 11px);
    padding: 2px 5px;
}
.mx-name-input:focus { outline: none; border-color: var(--accent); }

/* Device dropdowns */
.mx-device-sel {
    width: 100%;
    min-width: 0;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 4px;
    color: var(--text);
    font-size: clamp(9px, 2vw, 10px);
    padding: 2px 4px;
    box-sizing: border-box;
}
.mx-device-sel:focus { outline: none; border-color: var(--accent); }

/* Channel strip */
.mx-strip { background: var(--panel-2); }

.mx-strip-top {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 2px;
}

.mx-ch-rm-btn { flex-shrink: 0; }

/* Fader row */
.mx-fader-row {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 2px;
}

/* Glowing-orb fader: the filled (left) portion of the track glows in the accent
   colour up to the thumb; the right side is a plain dim rail with no glow. The
   thumb is a solid, luminous orb. The fill point is driven by --pct (set from JS
   as the value changes; defaults to the far right). */
.mx-fader {
    flex: 1;
    min-width: 0;
    height: 14px;                 /* just enough for the 14px orb thumb */
    -webkit-appearance: none;
    appearance: none;
    background: transparent;
    cursor: pointer;
    --pct: 100%;
}
.mx-fader::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: 999px;
    /* left of the thumb: glowing accent; right of the thumb: dim rail */
    background:
        linear-gradient(to right,
            var(--mx-color, var(--accent)) 0%,
            var(--mx-color, var(--accent)) var(--pct),
            rgba(255,255,255,0.10) var(--pct),
            rgba(255,255,255,0.10) 100%);
}
.mx-fader::-moz-range-track {
    height: 6px;
    border-radius: 999px;
    background: rgba(255,255,255,0.10);
}
/* Firefox: colour + glow the filled (left) portion only. */
.mx-fader::-moz-range-progress {
    height: 6px;
    border-radius: 999px;
    background: var(--mx-color, var(--accent));
    box-shadow: 0 0 6px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 60%), transparent),
                0 0 12px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 32%), transparent);
}
.mx-fader::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    margin-top: -4px;             /* centre the 14px thumb on the 6px track */
    border-radius: 50%;
    /* solid, luminous orb: bright core fading to the accent colour */
    background: radial-gradient(circle at 50% 38%,
                #fff 0%,
                color-mix(in srgb, var(--mx-color, var(--accent)) 85%, #fff) 30%,
                var(--mx-color, var(--accent)) 100%);
    box-shadow: 0 0 6px 1px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent),
                0 0 13px 2px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 55%), transparent);
}
.mx-fader::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border: none;
    border-radius: 50%;
    background: radial-gradient(circle at 50% 38%,
                #fff 0%,
                color-mix(in srgb, var(--mx-color, var(--accent)) 85%, #fff) 30%,
                var(--mx-color, var(--accent)) 100%);
    box-shadow: 0 0 6px 1px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent),
                0 0 13px 2px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 55%), transparent);
}

/* Circular icon buttons */
.mx-mute-btn,
.mx-icon-btn {
    border-radius: 50%;
    padding: 0;
    line-height: 0;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255,255,255,0.05);
    cursor: pointer;
    transition: border-color .15s, background .15s, color .15s, box-shadow .15s;
}

/* Mute button: highlight color + glow matching chat ring */
.mx-mute-btn {
    width: 19px;
    height: 19px;
    border: 1.5px solid var(--mx-color, var(--accent));
    color: var(--mx-color, var(--accent));
    box-shadow: 0 0 6px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent);
}
.mx-mute-btn svg { width: 11px; height: 11px; }
/* Per-channel FX gear (sits left of the mute button in the fader row).
   Lights up when any effect is active — replaces the old "● FX" text link. */
/* FX panel must stay inside its (narrow) input column — clip anything that
   would spill past the column border (e.g. a range input's intrinsic width). */
.mx-fx-body { min-width: 0; max-width: 100%; overflow: hidden; }
.mx-fx-body input[type="range"] { min-width: 0; }
.mx-fx-btn { color: var(--muted); border-color: var(--border); }
.mx-fx-btn.mx-fx-on {
    color: var(--mx-color, var(--accent));
    border-color: var(--mx-color, var(--accent));
    background: color-mix(in srgb, var(--mx-color, var(--accent)) 18%, transparent);
}
.mx-mute-btn:hover {
    background: rgba(255,255,255,0.10);
    box-shadow: 0 0 10px color-mix(in srgb, var(--mx-color, var(--accent)) calc(var(--accent-glow, 1) * 100%), transparent);
}

/* Icon buttons (remove ×, add +): neutral grayscale */
.mx-icon-btn {
    width: 20px;
    height: 20px;
    border: 1.5px solid rgba(255,255,255,0.14);
    color: var(--muted);
    font-size: 13px;
    font-weight: 600;
}
.mx-icon-btn svg { width: 10px; height: 10px; }
.mx-icon-btn:hover {
    background: rgba(255,255,255,0.10);
    border-color: rgba(255,255,255,0.28);
    color: var(--text);
}
/* Destructive hover for remove buttons */
.mx-remove-btn:hover,
.mx-ch-rm-btn:hover {
    border-color: rgba(229,72,77,0.55);
    color: var(--danger);
    background: rgba(229,72,77,0.08);
}
/* Add-mix button non-destructive hover */
.mx-add-mix-btn { font-size: 16px; }
.mx-add-mix-btn:hover { border-color: rgba(255,255,255,0.35); color: var(--text); background: rgba(255,255,255,0.08); }

.mx-muted { opacity: 0.35; }

/* VU meter */
.mx-vu-wrap {
    width: 100%;
    height: 4px;
    margin-top: 2px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 3px;
    overflow: hidden;
}
.mx-vu-bar {
    height: 100%;
    width: 0;
    background: var(--ok);
    border-radius: 3px;
    transition: width 0.04s linear;
}
.mx-vu-bar.mx-vu-warn { background: var(--warn); }
.mx-vu-bar.mx-vu-clip { background: var(--danger); }

/* Per-mix cell body */
.mx-body-cell {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
}

/* Per-cell: mute button + live send meter side by side */
.mx-cell-top {
    display: flex;
    align-items: center;
    gap: 6px;
}
.mx-cell-vu-wrap {
    flex: 1;
    min-width: 0;
    height: 8px;
    background: var(--panel-2);
    border: 1px solid var(--border);
    border-radius: 3px;
    overflow: hidden;
}
.mx-cell-vu-bar {
    height: 100%;
    width: 0;
    background: var(--ok);
    border-radius: 3px;
    transition: width 0.04s linear;
}
.mx-cell-vu-bar.mx-vu-warn { background: var(--warn); }
.mx-cell-vu-bar.mx-vu-clip { background: var(--danger); }

/* Add-channel row spans full width via mx-span-cell */

.mx-driver-notice { margin-top: 10px; }

/* Ultra-tight padding on very narrow viewports */
@media (max-width: 400px) {
    .mx-input-cell,
    .mx-mix-cell,
    .mx-btn-cell { padding: 3px 4px; }
}

/* ── Share modal ──────────────────────────────────────────────────── */
.sc-sb-share-modal { max-width: 340px; }
.sc-sb-share-hint  { font-size: 12px; color: var(--muted); margin: -6px 0 10px; }
.sc-sb-share-grid  { display: flex; flex-wrap: wrap; gap: 8px; max-height: 220px; overflow-y: auto; margin-bottom: 10px; }
.sc-sb-share-sound-item {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    width: 64px; height: 64px; border-radius: 8px; border: 2px solid var(--border, #444);
    cursor: pointer; font-size: 22px; gap: 2px; padding: 4px; text-align: center;
    transition: border-color .15s, background .15s;
}
.sc-sb-share-sound-item:hover   { border-color: var(--accent, #5b8cff); }
.sc-sb-share-sound-item.selected { border-color: var(--accent, #5b8cff); background: rgba(91,140,255,.15); }
.sc-sb-share-sound-item img     { width: 32px; height: 32px; object-fit: cover; border-radius: 4px; }
.sc-sb-share-sound-label        { font-size: 10px; color: var(--text); overflow: hidden; max-width: 60px; text-overflow: ellipsis; white-space: nowrap; }
.sc-sb-share-section-label      { font-size: 11px; font-weight: 600; color: var(--muted); text-transform: uppercase; letter-spacing: .05em; margin: 8px 0 4px; }
.sc-sb-share-recipient          { display: flex; align-items: center; gap: 6px; font-size: 13px; padding: 4px 0; cursor: pointer; }
.sc-sb-share-recipient input    { cursor: pointer; }
.sc-sb-share-empty              { font-size: 12px; color: var(--muted); margin: 2px 0 6px; }
.sc-sb-share-all-btn            { background: none; border: none; cursor: pointer; padding: 2px 5px; font-size: 15px; color: var(--text); opacity: .75; }
.sc-sb-share-all-btn:hover      { opacity: 1; }
