/* ==========================================================================
   LIORA ALTIMA DASHBOARD — DESIGN SYSTEM
   Sections: 1. Tokens  2. Theme Overrides  3. Reset & Base  4. Layout
   5. Sidebar  6. Top Bar  7. Cards & Settings  8. Forms & Buttons
   9. Switch / Sliders  10. Channel Drawers  11. Tables  12. Status Toast
   13. Badges  14. Scrollbars  15. Animations  16. Accessibility
   17. Responsive
   ========================================================================== */

/* 1. DESIGN TOKENS ------------------------------------------------------- */
:root {
    /* Default Dark Theme (Discord-familiar base) */
    --bg-primary: #313338;
    --bg-secondary: #2b2d31;
    --bg-tertiary: #1e1f22;
    --bg-floating: #111214;
    --header-primary: #f2f3f5;
    --header-secondary: #b5bac1;
    --text-normal: #dbdee1;
    --text-muted: #949ba4;
    --text-link: #00a8fc;
    --brand-experiment: #5865f2;
    --brand-hover: #4752c4;
    --brand-active: #3c45a5;
    --button-danger-bg: #da373c;
    --button-danger-hover: #a12828;
    --button-positive-bg: #248046;
    --button-positive-hover: #1a6334;
    --interactive-normal: #b5bac1;
    --interactive-hover: #dee1e5;
    --interactive-active: #ffffff;
    --sidebar-width: 240px;
    --status-positive: #23a55a;
    --status-danger: #f23f43;
    --border-color: rgba(255, 255, 255, 0.06);
    --bg-modifier-hover: rgba(255, 255, 255, 0.06);

    /* Liora's own accent -- warm gold, distinct from the borrowed blurple */
    --liora-gold: #ffb800;
    --liora-gold-strong: #ff8008;
    --liora-gold-soft: rgba(255, 184, 0, 0.18);
    --lever-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 26'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23fff2bf'/%3E%3Cstop offset='.45' stop-color='%23ffc531'/%3E%3Cstop offset='1' stop-color='%23d98200'/%3E%3C/linearGradient%3E%3ClinearGradient id='s' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%238a5200'/%3E%3Cstop offset='.5' stop-color='%23fff2bf'/%3E%3Cstop offset='1' stop-color='%238a5200'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect x='6' y='9.5' width='2' height='15.5' rx='1' fill='url(%23s)'/%3E%3Cpath d='M3.4 1h7.2l2.6 3.4L7 11.4.8 4.4z' fill='url(%23g)' stroke='%238a5200' stroke-width='.6' stroke-linejoin='round'/%3E%3Cpath d='M.9 4.4h12.2M3.4 1l1.8 3.4L7 11.4l1.8-7L10.6 1' fill='none' stroke='%238a5200' stroke-width='.5' stroke-linejoin='round' opacity='.7'/%3E%3Cpath d='M3.7 1.5h2.4L5 3.8z' fill='%23fff' opacity='.75'/%3E%3C/svg%3E");
    --lever-base: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 10'%3E%3Cdefs%3E%3ClinearGradient id='p' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23ffc531'/%3E%3Cstop offset='1' stop-color='%238a5200'/%3E%3C/linearGradient%3E%3CradialGradient id='d' cx='.4' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23fff2bf'/%3E%3Cstop offset='.6' stop-color='%23ffc531'/%3E%3Cstop offset='1' stop-color='%23d98200'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect x='1' y='3.6' width='24' height='6' rx='3' fill='url(%23p)' stroke='%235a3600' stroke-width='.6'/%3E%3Cpath d='M3.5 5h19' stroke='%23fff2bf' stroke-width='.6' stroke-linecap='round' opacity='.6'/%3E%3Cellipse cx='13' cy='4.6' rx='5' ry='3.6' fill='url(%23d)' stroke='%235a3600' stroke-width='.6'/%3E%3Ccircle cx='13' cy='4' r='1.1' fill='%235a3600' opacity='.7'/%3E%3C/svg%3E");

    /* Spacing scale */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 32px;
    --space-8: 40px;

    /* Radius scale */
    --radius-sm: 4px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-pill: 999px;

    /* Shadow scale */
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.25);
    --shadow-lg: 0 8px 28px rgba(0, 0, 0, 0.35);

    /* Motion */
    --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
    --ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
    --duration-fast: 120ms;
    --duration-base: 200ms;
    --duration-slow: 320ms;
    --duration-slower: 520ms;
}

/* 2. THEME OVERRIDES ------------------------------------------------------ */
[data-theme="light"] {
    --bg-primary: #ffffff;
    --bg-secondary: #f2f3f5;
    --bg-tertiary: #ebedef;
    --bg-floating: #ffffff;
    --header-primary: #060607;
    --header-secondary: #4e5058;
    --text-normal: #313338;
    --text-muted: #5c5e66;
    --interactive-normal: #4e5058;
    --interactive-hover: #2e3338;
    --interactive-active: #060607;
    --border-color: rgba(6, 6, 7, 0.1);
    --bg-modifier-hover: rgba(6, 6, 7, 0.05);
    --shadow-sm: 0 1px 2px rgba(6, 6, 7, 0.08);
    --shadow-md: 0 4px 12px rgba(6, 6, 7, 0.1);
    --shadow-lg: 0 8px 28px rgba(6, 6, 7, 0.14);
}

[data-theme="midnight"] {
    --bg-primary: #000000;
    --bg-secondary: #050505;
    --bg-tertiary: #0a0a0a;
    --bg-floating: #000000;
    --header-primary: #ffffff;
    --header-secondary: #a0a0a0;
    --text-normal: #e0e0e0;
    --text-muted: #808080;
    --interactive-normal: #b0b0b0;
    --interactive-hover: #d0d0d0;
    --interactive-active: #ffffff;
    --brand-experiment: #7289da;
    --border-color: rgba(255, 255, 255, 0.08);
    --bg-modifier-hover: rgba(255, 255, 255, 0.05);
}

/* Hidden easter-egg theme: true OLED black, void-purple accent instead of gold.
   Unlocked by clicking the sidebar logo 5 times (see auth.js). */
[data-theme="abyss"] {
    --bg-primary: #000000;
    --bg-secondary: #000000;
    --bg-tertiary: #000000;
    --bg-floating: #000000;
    --header-primary: #e8e8ea;
    --header-secondary: #6a6a72;
    --text-normal: #a8a8b0;
    --text-muted: #4a4a52;
    --interactive-normal: #7a7a82;
    --interactive-hover: #c0c0c8;
    --interactive-active: #ffffff;
    --brand-experiment: #6c2bd9;
    --brand-hover: #5a22b8;
    --brand-active: #4a1c96;
    --border-color: rgba(108, 43, 217, 0.15);
    --bg-modifier-hover: rgba(108, 43, 217, 0.08);
    --liora-gold: #8b3ff5;
    --liora-gold-strong: #6c2bd9;
    --liora-gold-soft: rgba(139, 63, 245, 0.16);
    --lever-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 26'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0' y1='0' x2='1' y2='1'%3E%3Cstop offset='0' stop-color='%23efe2ff'/%3E%3Cstop offset='.45' stop-color='%23b98aff'/%3E%3Cstop offset='1' stop-color='%236c2bd9'/%3E%3C/linearGradient%3E%3ClinearGradient id='s' x1='0' x2='1'%3E%3Cstop offset='0' stop-color='%233f168a'/%3E%3Cstop offset='.5' stop-color='%23efe2ff'/%3E%3Cstop offset='1' stop-color='%233f168a'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect x='6' y='9.5' width='2' height='15.5' rx='1' fill='url(%23s)'/%3E%3Cpath d='M3.4 1h7.2l2.6 3.4L7 11.4.8 4.4z' fill='url(%23g)' stroke='%233f168a' stroke-width='.6' stroke-linejoin='round'/%3E%3Cpath d='M.9 4.4h12.2M3.4 1l1.8 3.4L7 11.4l1.8-7L10.6 1' fill='none' stroke='%233f168a' stroke-width='.5' stroke-linejoin='round' opacity='.7'/%3E%3Cpath d='M3.7 1.5h2.4L5 3.8z' fill='%23fff' opacity='.75'/%3E%3C/svg%3E");
    --lever-base: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 26 10'%3E%3Cdefs%3E%3ClinearGradient id='p' x1='0' y1='0' x2='0' y2='1'%3E%3Cstop offset='0' stop-color='%23b98aff'/%3E%3Cstop offset='1' stop-color='%233f168a'/%3E%3C/linearGradient%3E%3CradialGradient id='d' cx='.4' cy='.3' r='.8'%3E%3Cstop offset='0' stop-color='%23efe2ff'/%3E%3Cstop offset='.6' stop-color='%23b98aff'/%3E%3Cstop offset='1' stop-color='%236c2bd9'/%3E%3C/radialGradient%3E%3C/defs%3E%3Crect x='1' y='3.6' width='24' height='6' rx='3' fill='url(%23p)' stroke='%2324094f' stroke-width='.6'/%3E%3Cpath d='M3.5 5h19' stroke='%23efe2ff' stroke-width='.6' stroke-linecap='round' opacity='.6'/%3E%3Cellipse cx='13' cy='4.6' rx='5' ry='3.6' fill='url(%23d)' stroke='%2324094f' stroke-width='.6'/%3E%3Ccircle cx='13' cy='4' r='1.1' fill='%2324094f' opacity='.7'/%3E%3C/svg%3E");
}

/* Abyss exclusive: everything rests in void-purple, but touch reveals the
   real gold underneath -- the theme's whole "hidden" premise made tactile.
   Scoped to [data-theme="abyss"] only; every other theme keeps its own
   plain hover treatment for these elements. */
[data-theme="abyss"] .settings-card {
    transition: border-color var(--duration-slow) var(--ease-standard),
                box-shadow var(--duration-slow) var(--ease-standard);
}
[data-theme="abyss"] .settings-card:hover {
    border-color: rgba(255, 184, 0, 0.55);
    box-shadow: 0 0 0 1px rgba(255, 184, 0, 0.2), 0 0 22px rgba(255, 184, 0, 0.14);
}

[data-theme="abyss"] .feature-card {
    transition: transform var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-slow) var(--ease-standard),
                border-color var(--duration-slow) var(--ease-standard),
                background var(--duration-slow) var(--ease-standard);
}
[data-theme="abyss"] .feature-card:hover {
    border-color: rgba(255, 184, 0, 0.55);
    background: linear-gradient(135deg, rgba(255, 184, 0, 0.10) 0%, var(--bg-secondary) 100%);
    box-shadow: 0 0 24px rgba(255, 184, 0, 0.16), var(--shadow-md);
}
[data-theme="abyss"] .feature-card:hover .feature-card-head h3,
[data-theme="abyss"] .feature-card:hover .feature-badge {
    color: #ffd54f;
}
[data-theme="abyss"] .feature-badge {
    transition: color var(--duration-slow) var(--ease-standard),
                background var(--duration-slow) var(--ease-standard);
}
[data-theme="abyss"] .feature-card:hover .feature-badge {
    background: rgba(255, 184, 0, 0.18);
}

[data-theme="abyss"] #sidebar li a {
    transition: background-color var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard),
                border-color var(--duration-slow) var(--ease-standard);
}
[data-theme="abyss"] #sidebar li a:hover {
    border-left-color: rgba(255, 184, 0, 0.6);
}

[data-theme="abyss"] .switch-container {
    transition: border-color var(--duration-slow) var(--ease-standard);
}
[data-theme="abyss"] .switch-container:hover {
    border-color: rgba(255, 184, 0, 0.4);
}

/* Hidden theme "Liora" (2026-09-28, Bliss): black and gold, her gem glowing behind everything, gold glow that breathes
   on its own rhythm per element, and "scraping" sparks that run along edges (static/js/liora-theme.js).
   Unlocked by clicking the gem on the Meet the team page 5 times (static/js/team.js). */
[data-theme="liora"] {
    --bg-primary: #060403;
    --bg-secondary: rgba(17, 12, 7, 0.88);
    --bg-tertiary: #030201;
    --bg-floating: #0c0905;
    --header-primary: #ffe7b0;
    --header-secondary: #d2ae6a;
    --text-normal: #f3e4c6;
    --text-muted: #a88c5f;
    --text-link: #ffc94d;
    --interactive-normal: #cfb07a;
    --interactive-hover: #ffe3a1;
    --interactive-active: #fff4d8;
    --brand-experiment: #ffb800;
    --brand-hover: #ffc933;
    --brand-active: #e89a00;
    --border-color: rgba(255, 184, 0, 0.2);
    --bg-modifier-hover: rgba(255, 184, 0, 0.09);
    --liora-gold: #ffb800;
    --liora-gold-strong: #ff8a1f;
    --liora-gold-soft: rgba(255, 184, 0, 0.17);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.55);
    --shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.6);
}
/* her gem, glowing faintly behind everything, and a warm light that breathes out of step with it */
[data-theme="liora"] body::before,
[data-theme="liora"] body::after {
    content: ""; position: fixed; pointer-events: none; z-index: 0;
}
[data-theme="liora"] body::before {
    width: min(62vh, 560px); height: min(62vh, 560px);
    left: calc(var(--sidebar-width) + (100vw - var(--sidebar-width)) / 2); top: 50%;
    transform: translate(-50%, -50%);
    background: url("/static/liora_gem.png") center / contain no-repeat;
    opacity: 0.07;
    filter: drop-shadow(0 0 40px rgba(255, 170, 0, 0.6));
    animation: liora-gem-breathe 11s ease-in-out infinite;
}
[data-theme="liora"] body::after {
    inset: 0;
    background:
        radial-gradient(ellipse 55% 45% at calc(var(--sidebar-width) + (100% - var(--sidebar-width)) / 2) 50%, rgba(255, 170, 0, 0.10), transparent 70%),
        radial-gradient(ellipse 40% 30% at 100% 100%, rgba(255, 110, 20, 0.06), transparent 70%);
    animation: liora-light-breathe 14s ease-in-out -5s infinite;
}
[data-theme="liora"] .app-container { position: relative; z-index: 1; }
[data-theme="liora"] #main-content { background: transparent; }

/* gold glow that breathes: every element gets its own rhythm and starting point from liora-theme.js
   (--breathe-len / --breathe-delay), so the page never pulses all at once */
[data-theme="liora"] .settings-card,
[data-theme="liora"] .feature-card,
[data-theme="liora"] .home-card {
    border-color: rgba(255, 184, 0, 0.22);
    animation: liora-card-breathe var(--breathe-len, 8s) ease-in-out var(--breathe-delay, 0s) infinite;
}
[data-theme="liora"] #sidebar {
    background: rgba(10, 7, 4, 0.94);
    border-right: 1px solid rgba(255, 184, 0, 0.28);
    animation: liora-edge-breathe var(--breathe-len, 9s) ease-in-out var(--breathe-delay, 0s) infinite;
}
[data-theme="liora"] .sidebar-header { box-shadow: 0 1px 0 rgba(255, 184, 0, 0.22); }
[data-theme="liora"] .nav-category { border-bottom: 1px solid rgba(255, 184, 0, 0.1); }
[data-theme="liora"] .nav-category span,
[data-theme="liora"] .settings-card h3,
[data-theme="liora"] .settings-page h2 {
    color: #ffd27a;
    animation: liora-text-breathe var(--breathe-len, 9s) ease-in-out var(--breathe-delay, 0s) infinite;
}
[data-theme="liora"] .settings-card h3 { border-bottom-color: rgba(255, 184, 0, 0.18); }
[data-theme="liora"] #sidebar li a.active {
    background: linear-gradient(90deg, rgba(255, 184, 0, 0.22), rgba(255, 184, 0, 0.04));
    color: #ffe7b0;
    border-left-color: #ffb800;
    box-shadow: inset 0 0 12px rgba(255, 184, 0, 0.12);
}
[data-theme="liora"] #sidebar li a:hover { color: #ffe7b0; border-left-color: rgba(255, 184, 0, 0.6); }
/* gold buttons need dark text to stay readable */
[data-theme="liora"] button:not(.danger):not(.positive) {
    color: #2a1800; font-weight: 600;
    background-image: linear-gradient(135deg, #ffc933, #ff9a1f);
    box-shadow: 0 0 14px rgba(255, 170, 0, 0.25);
}
[data-theme="liora"] input, [data-theme="liora"] select, [data-theme="liora"] textarea {
    background-color: rgba(8, 6, 3, 0.85); border-color: rgba(255, 184, 0, 0.22); color: var(--text-normal);
}
[data-theme="liora"] input:focus, [data-theme="liora"] select:focus, [data-theme="liora"] textarea:focus {
    border-color: #ffb800; box-shadow: 0 0 0 2px rgba(255, 184, 0, 0.25);
}

/* On an open page the cards also slide in (card-in, cascading 70ms apart). Run both animations, each with its own
   delay, so the entrance cascade and the breathing glow don't overwrite each other. */
:root[data-theme="liora"] .settings-page.active .settings-card {
    animation-name: card-in, liora-card-breathe;
    animation-duration: var(--duration-slower), var(--breathe-len, 8s);
    animation-timing-function: var(--ease-standard), ease-in-out;
    animation-iteration-count: 1, infinite;
    animation-fill-mode: backwards, none;
    animation-delay: 0ms, var(--breathe-delay, 0s);
}
:root[data-theme="liora"] .settings-page.active .settings-card:nth-of-type(2) { animation-delay: 70ms, var(--breathe-delay, 0s); }
:root[data-theme="liora"] .settings-page.active .settings-card:nth-of-type(3) { animation-delay: 140ms, var(--breathe-delay, 0s); }
:root[data-theme="liora"] .settings-page.active .settings-card:nth-of-type(4) { animation-delay: 210ms, var(--breathe-delay, 0s); }
:root[data-theme="liora"] .settings-page.active .settings-card:nth-of-type(n+5) { animation-delay: 260ms, var(--breathe-delay, 0s); }

/* Feature Showcase plates (Bliss: "the gold glow is a bit too much"): in Liora's theme each plate shows its OWN colour
   (--accent-rgb / --accent-hex, set per plate) with a softer breathing glow. Hovering a plate makes it shine with a
   slight iridescence: a sheen tinted by its colour sweeps across while its hues slowly shift. The sparks stay gold. */
:root[data-theme="liora"] .settings-page.active .settings-card.feature-card {
    animation-name: card-in, liora-plate-breathe;
    border-color: rgba(var(--accent-rgb), 0.42);
    background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.16) 0%, rgba(14, 10, 6, 0.92) 58%, rgba(var(--accent-rgb), 0.07) 100%);
}
[data-theme="liora"] .feature-card { position: relative; overflow: hidden; isolation: isolate; }
[data-theme="liora"] .feature-card .feature-card-head h3 {
    color: var(--accent-hex);
    animation: liora-plate-text var(--breathe-len, 9s) ease-in-out var(--breathe-delay, 0s) infinite;
}
[data-theme="liora"] .feature-card .feature-badge { background: rgba(var(--accent-rgb), 0.2); color: var(--accent-hex); }
[data-theme="liora"] .feature-card::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none; z-index: 1;
    background: linear-gradient(112deg,
        transparent 20%,
        rgba(var(--accent-rgb), 0.22) 34%,
        rgba(255, 255, 255, 0.18) 42%,
        rgba(140, 220, 255, 0.16) 47%,
        rgba(220, 150, 255, 0.14) 52%,
        rgba(var(--accent-rgb), 0.20) 58%,
        transparent 72%);
    background-size: 260% 100%;
    background-position: 110% 0;
    mix-blend-mode: screen;
    opacity: 0;
    transition: opacity 0.5s ease;
}
[data-theme="liora"] .feature-card:hover::after {
    opacity: 1;
    animation: liora-sheen 3.2s ease-in-out infinite alternate, liora-iridesce 5s ease-in-out infinite;
}
[data-theme="liora"] .feature-card:hover { border-color: rgba(var(--accent-rgb), 0.7); }
[data-theme="liora"] .feature-card > * { position: relative; z-index: 2; }
@keyframes liora-plate-breathe {
    0%, 100% { box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.12), 0 0 8px rgba(var(--accent-rgb), 0.05), var(--shadow-sm); }
    50% { box-shadow: 0 0 0 1px rgba(var(--accent-rgb), 0.34), 0 0 18px rgba(var(--accent-rgb), 0.16), var(--shadow-sm); }
}
@keyframes liora-plate-text {
    0%, 100% { text-shadow: 0 0 0 rgba(var(--accent-rgb), 0); }
    50% { text-shadow: 0 0 10px rgba(var(--accent-rgb), 0.55); }
}
/* while hovered, the sheen drifts back and forth across the plate... */
@keyframes liora-sheen { from { background-position: 110% 0; } to { background-position: -10% 0; } }
/* ...and its colours slowly slide around the colour wheel: the iridescence */
@keyframes liora-iridesce {
    0%, 100% { filter: hue-rotate(-40deg) saturate(1.2); }
    50% { filter: hue-rotate(40deg) saturate(1.5); }
}

@keyframes liora-gem-breathe {
    0%, 100% { opacity: 0.05; transform: translate(-50%, -50%) scale(0.98); }
    50% { opacity: 0.11; transform: translate(-50%, -50%) scale(1.02); }
}
@keyframes liora-light-breathe { 0%, 100% { opacity: 0.7; } 50% { opacity: 1; } }
@keyframes liora-card-breathe {
    0%, 100% { box-shadow: 0 0 0 1px rgba(255, 184, 0, 0.06), 0 0 10px rgba(255, 170, 0, 0.05), var(--shadow-sm); }
    50% { box-shadow: 0 0 0 1px rgba(255, 184, 0, 0.26), 0 0 26px rgba(255, 170, 0, 0.17), var(--shadow-sm); }
}
@keyframes liora-edge-breathe {
    0%, 100% { box-shadow: 1px 0 6px rgba(255, 170, 0, 0.08); }
    50% { box-shadow: 1px 0 22px rgba(255, 170, 0, 0.28); }
}
@keyframes liora-text-breathe {
    0%, 100% { text-shadow: 0 0 0 rgba(255, 184, 0, 0); }
    50% { text-shadow: 0 0 12px rgba(255, 184, 0, 0.45); }
}

/* the scraping point: a white-hot bead that runs along an edge, throwing sparks behind it */
.scrape-head {
    position: fixed; top: 0; left: 0; width: 5px; height: 5px; margin: -2.5px 0 0 -2.5px;
    border-radius: 50%; pointer-events: none; z-index: 99998;
    background: radial-gradient(circle, #fffdf3 0%, #ffe08a 45%, rgba(255, 184, 0, 0) 75%);
    box-shadow: 0 0 10px 3px rgba(255, 190, 40, 0.75), 0 0 22px 6px rgba(255, 140, 0, 0.35);
    will-change: transform, opacity;
}
.scrape-spark {
    position: fixed; top: 0; left: 0; height: 1.5px; width: 5px;
    pointer-events: none; z-index: 99999; opacity: 0;
    transform-origin: 0% 50%; border-radius: 1px;
    background: linear-gradient(90deg, #fffef6 0%, #ffe07a 25%, #ffb000 60%, transparent 100%);
    filter: drop-shadow(0 0 2px rgba(255, 170, 0, 0.8));
    will-change: transform, width, opacity;
}
@media (prefers-reduced-motion: reduce) {
    [data-theme="liora"] body::before, [data-theme="liora"] body::after,
    [data-theme="liora"] .settings-card, [data-theme="liora"] .feature-card, [data-theme="liora"] .home-card,
    [data-theme="liora"] #sidebar, [data-theme="liora"] .nav-category span,
    [data-theme="liora"] .settings-card h3, [data-theme="liora"] .settings-page h2,
    :root[data-theme="liora"] .settings-page.active .settings-card { animation: none; }
    [data-theme="liora"] .feature-card::after, [data-theme="liora"] .feature-card .feature-card-head h3 { animation: none; }
    :root[data-theme="liora"] .settings-page.active .settings-card.feature-card { animation: none; }
}

/* 3. RESET & BASE ---------------------------------------------------------- */
*, *::before, *::after {
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    background: var(--bg-primary);
    color: var(--text-normal);
    margin: 0;
    overflow: hidden;
    height: 100vh;
    height: 100dvh; /* progressive enhancement: correct mobile viewport height */
    -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, p { margin: 0; }
h2 { font-size: 22px; font-weight: 700; color: var(--header-primary); }

a { color: var(--text-link); }

/* 4. LAYOUT STRUCTURE ------------------------------------------------------ */
.app-container {
    display: flex;
    height: 100vh;
    height: 100dvh;
    width: 100%;
}

/* 5. SIDEBAR NAVIGATION ----------------------------------------------------- */
#sidebar {
    width: var(--sidebar-width);
    background: var(--bg-secondary);
    display: flex;
    flex-direction: column;
    border-right: 1px solid rgba(0, 0, 0, 0.2);
    flex-shrink: 0;
    transition: width var(--duration-base) var(--ease-standard);
}

.sidebar-header {
    text-decoration: none;
    padding: 10px 16px;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
    font-weight: 700;
    color: var(--header-primary);
    font-size: 16px;
    height: 56px;
    display: flex;
    align-items: center;
}
/* her name in her own lettering, as on the home page and the Library: Fraunces, "Altima" in gold italic (Bliss, 2026-10-04) */
.sidebar-header .brand-name { font: 600 19px/1 "Fraunces", Georgia, "Times New Roman", serif; letter-spacing: 0.005em; }
.sidebar-header .brand-name em { font-style: italic; font-weight: 400; color: var(--liora-gold); }

.sidebar-scrollable {
    flex-grow: 1;
    overflow-y: auto;
    padding: 10px 8px;
}

#sidebar ul { list-style: none; padding: 0; margin: 0; }

/* Category groups collapse by default; hovering (or being the group that
   holds the current page) slides the links out from underneath the label
   with a soft fade, instead of showing every item flatly at once. */
.nav-group {
    margin-bottom: 2px;
}

.nav-category {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 12px;
    font-weight: 700;
    color: var(--text-muted);
    text-transform: uppercase;
    padding: 10px 10px 10px 8px;
    letter-spacing: 0.4px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    user-select: none;
    transition: color var(--duration-fast) var(--ease-standard),
                background-color var(--duration-fast) var(--ease-standard);
}
.nav-group:hover .nav-category,
.nav-group.expanded .nav-category,
.nav-group.pinned .nav-category {
    color: var(--header-secondary);
    background-color: var(--bg-modifier-hover);
}
/* Pinned open (clicked, not just hovered): a slightly stronger highlight so
   it reads as "held open" rather than a passing hover. */
.nav-group.pinned .nav-category {
    background-color: var(--liora-gold-soft);
}

.nav-category-arrow {
    width: 6px;
    height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: rotate(-45deg);
    opacity: 0.6;
    transition: transform var(--fold-ms) var(--fold) 60ms, opacity var(--fold-ms) var(--fold) 60ms;
    flex-shrink: 0;
}
.nav-group:hover .nav-category-arrow,
.nav-group.expanded .nav-category-arrow,
.nav-group.pinned .nav-category-arrow {
    transform: rotate(45deg);
    opacity: 0.9;
    transition: transform var(--glide-ms) var(--glide) 120ms, opacity var(--glide-ms) var(--glide) 120ms;   /* turns with the links */
}

.nav-links {
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transform: translateY(-6px);
    /* Closing (Bliss, 2026-09-28: "very aggressive"): a soft, even fold. max-height animates to the category's
       REAL height (--open-h, measured in dashboard.js) instead of a fixed 480px, so the whole animation is spent on
       what you can see rather than collapsing blank space first and then snapping shut at the end.
       2026-10-03 ("a bit smoother"): height, fade, slide and the arrow now share one motion (--fold / --glide in
       emblems.css, the same as the site notice) and start together, instead of three timings a beat apart. */
    transition: max-height var(--fold-ms) var(--fold) 60ms,
                opacity calc(var(--fold-ms) * 0.75) var(--fold) 60ms,
                transform var(--fold-ms) var(--fold) 60ms;
}
.nav-group:hover .nav-links,
.nav-group.expanded .nav-links,
.nav-group.pinned .nav-links {
    max-height: var(--open-h, 480px);
    opacity: 1;
    transform: translateY(0);
    /* Hover-intent delay: opening only begins after a brief sustained hover,
       so quickly scanning down the sidebar never pops each category open
       and shut in a flickering cascade -- only a deliberate pause reveals one.
       Then it glides out quickly and settles gently. */
    transition: max-height var(--glide-ms) var(--glide) 120ms,
                opacity calc(var(--glide-ms) * 0.8) var(--glide) 120ms,
                transform var(--glide-ms) var(--glide) 120ms;
}

#sidebar li a {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    text-decoration: none;
    color: var(--interactive-normal);
    border-radius: var(--radius-sm);
    font-weight: 500;
    margin-bottom: 2px;
    transition: background-color var(--duration-fast) var(--ease-standard),
                color var(--duration-fast) var(--ease-standard),
                border-color var(--duration-fast) var(--ease-standard);
    font-size: 15px;
    position: relative;
    border-left: 2px solid transparent;
}
#sidebar li a:hover { background-color: var(--bg-modifier-hover); color: var(--interactive-hover); }
#sidebar li a.active {
    background-color: var(--liora-gold-soft);
    color: var(--interactive-active);
    border-left: 2px solid var(--liora-gold);
}

/* 6. MAIN CONTENT / TOP BAR -------------------------------------------------- */
#main-wrapper {
    flex-grow: 1;
    display: flex;
    flex-direction: column;
    background: var(--bg-primary);
    min-width: 0;
}

.top-bar {
    height: 48px;
    flex-shrink: 0;   /* the full-height column was squashing it on long pages, cutting "All servers" and Save in half */
    padding: 0 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    box-shadow: 0 1px 0 rgba(0, 0, 0, 0.2);
    z-index: 10;
    flex-wrap: wrap;
    gap: 8px;
    row-gap: 4px;
}

.top-bar-title {
    color: var(--header-primary);
    font-weight: 600;
    font-size: 16px;
}
/* Desktop: the title sits in the true middle of the bar, in line with the page below (Bliss, 2026-10-03). Spacing the
   bar's items evenly pushed it right whenever "All servers" showed on the left with nothing on the right. A long
   server name is cut short with "…" before it can reach the buttons at either end. */
@media (min-width: 821px) {
    .top-bar { position: relative; }
    .top-bar-title {
        position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
        max-width: calc(100% - 440px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
    }
    /* the page's scrollbar takes room on the right only, which nudged everything below a few pixels left of the
       title; an equal gutter on both sides keeps the page's middle and the bar's middle the same */
    #main-content { scrollbar-gutter: stable both-edges; }
}

#main-content {
    flex-grow: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 24px;
}

/* 7. CARDS & SETTINGS -------------------------------------------------------- */
.settings-card {
    background: var(--bg-secondary);
    border-radius: var(--radius-md);
    padding: 20px;
    box-shadow: var(--shadow-sm);
    border: 1px solid var(--border-color);
    transition: box-shadow var(--duration-base) var(--ease-standard);
    /* Multi-column layout has no row-gap equivalent, and without this a card
       could be sliced in half across a column break. */
    margin-bottom: 20px;
    break-inside: avoid;
}

.settings-card h3 {
    margin-top: 0;
    color: var(--header-primary);
    font-size: 16px;
    border-bottom: 1px solid var(--border-color);
    padding-bottom: 10px;
    margin-bottom: 15px;
}

.page-desc {
    display: block;
    font-size: 15px;
    color: var(--text-muted);
    line-height: 1.5;
    margin: 4px 0 24px 0;
    max-width: 720px;
}

/* Feature showcase cards: color-coded by --accent-rgb / --accent-hex, set
   per-card via inline style. The gradient resolves against --bg-secondary
   instead of a hardcoded dark color, so these stay correct in every theme. */
.feature-card {
    background: linear-gradient(135deg, rgba(var(--accent-rgb), 0.08) 0%, var(--bg-secondary) 100%);
    border: 1px solid rgba(var(--accent-rgb), 0.25);
    border-radius: var(--radius-md);
    padding: 20px;
    transition: transform var(--duration-base) var(--ease-standard), box-shadow var(--duration-base) var(--ease-standard);
}
.feature-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-md);
}
.feature-card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 8px;
    margin-bottom: 12px;
}
.feature-card-head h3 {
    margin: 0;
    font-size: 16px;
    color: var(--accent-hex);
}
.feature-card p {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted);
    line-height: 1.5;
}
.feature-badge {
    background: rgba(var(--accent-rgb), 0.2);
    color: var(--accent-hex);
}

.setting-desc {
    display: block;
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.5;
    margin: -4px 0 16px 0;
}

/* A single labeled control: label, optional hint, then the input itself. */
.setting {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 20px;
}
.setting:last-child { margin-bottom: 0; }
.setting > label {
    font-size: 12px;
    font-weight: 700;
    color: var(--header-secondary);
    text-transform: uppercase;
    letter-spacing: 0.4px;
}
.setting-hint {
    display: block;
    font-size: 13px;
    color: var(--text-muted);
    line-height: 1.5;
}

/* Legacy alias kept for compatibility with any existing markup */
.form-group { margin-bottom: 20px; }
.form-group label {
    display: block;
    margin-bottom: 8px;
    font-size: 12px;
    font-weight: 700;
    color: var(--header-secondary);
    text-transform: uppercase;
}

/* 8. FORMS & BUTTONS ---------------------------------------------------------- */
select, input[type="text"], input[type="number"], textarea {
    width: 100%;
    padding: 10px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    color: var(--text-normal);
    border-radius: var(--radius-sm);
    box-sizing: border-box;
    font-size: 16px;
    font-family: inherit;
    transition: border-color var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard);
}
select:focus, input:focus, textarea:focus {
    outline: none;
    border-color: var(--brand-experiment);
    box-shadow: 0 0 0 3px rgba(88, 101, 242, 0.25);
}
select:disabled, input:disabled, textarea:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

button {
    background-color: var(--brand-experiment);
    color: white;
    border: none;
    cursor: pointer;
    padding: 10px 20px;
    border-radius: var(--radius-sm);
    font-weight: 500;
    font-size: 14px;
    font-family: inherit;
    transition: background-color var(--duration-base) var(--ease-standard),
                transform var(--duration-fast) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard),
                opacity var(--duration-base) var(--ease-standard);
    width: auto;
}
button:hover:not(:disabled) { background-color: var(--brand-hover); transform: translateY(-1px); box-shadow: var(--shadow-sm); }
button:active:not(:disabled) { background-color: var(--brand-active); transform: translateY(0); }
button.danger { background-color: var(--button-danger-bg); }
button.danger:hover:not(:disabled) { background-color: var(--button-danger-hover); }
button.positive { background-color: var(--button-positive-bg); }
button.positive:hover:not(:disabled) { background-color: var(--button-positive-hover); }

button:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    transform: none !important;
    box-shadow: none !important;
    filter: saturate(0.6);
}

/* Custom Switch */
.setting-grid-2 {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
    gap: 40px;
}

.switch-container {
    display: flex;
    align-items: center;
    justify-content: space-between;
    background: var(--bg-tertiary);
    padding: 12px 16px;
    border-radius: var(--radius-md);
    margin-bottom: 8px;
    border: 1px solid var(--border-color);
    transition: border-color var(--duration-base) var(--ease-standard);
}
.switch-container:hover { border-color: rgba(88, 101, 242, 0.3); }
.switch-container label { margin: 0; text-transform: none; font-size: 16px; color: var(--header-primary); font-weight: 500; }
/* The Request button by the AI switch (owners and admins; Bliss has the switch itself) */
.ai-request-btn { margin: 0 14px 0 auto; padding: 6px 16px; font-size: 14px; flex-shrink: 0; }
.ai-request-status { display: block; margin-top: 6px; font-size: 13px; font-weight: 500; color: var(--text-normal, inherit); }
.ai-request-status[hidden] { display: none; }

/* 9. ANIMATED MECHANICAL LEVER SWITCH ----------------------------------------- */
input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 62px;
    height: 32px;
    background: var(--lever-base) center 15px / 26px 10px no-repeat,   /* the lever's gold mount, fixed in the middle */
                linear-gradient(180deg, #18191c 0%, #222428 50%, #2b2d31 100%);
    border: 2px solid #3b3e45;
    border-radius: 16px;
    position: relative;
    cursor: pointer;
    transition: all 0.3s var(--ease-standard);
    flex-shrink: 0;
    outline: none;
    overflow: visible;
    box-shadow: inset 0 3px 6px rgba(0, 0, 0, 0.7), 0 2px 5px rgba(0, 0, 0, 0.3);
}

input[type="checkbox"]::after {
    content: "";
    position: absolute;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    top: 11px;
    left: 8px;
    background: #e74c3c;
    box-shadow: 0 0 6px #e74c3c;
    transition: all 0.35s var(--ease-spring);
    pointer-events: none;
    z-index: 1;
}

input[type="checkbox"]::before {
    /* The handle (Bliss, 2026-10-01: "like a minecraft lever, but gold"): pivots on the mount in the middle of the
       switch, tipped left when off and right when on. Pressing stands it upright, mid-flip. */
    content: "";
    position: absolute;
    left: calc(50% - 7px);
    top: -7px;
    width: 14px;
    height: 26px;
    background: var(--lever-img) center / contain no-repeat;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.8)) saturate(0.7) brightness(0.88);
    transform-origin: 50% 100%;
    transform: rotate(-40deg);
    transition: transform 0.35s var(--ease-spring), filter 0.3s ease;
    z-index: 2;
    pointer-events: none;
}

input[type="checkbox"]:hover::before {
    filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 0.9));
    transform: rotate(-32deg);
}

input[type="checkbox"]:checked {
    background: var(--lever-base) center 15px / 26px 10px no-repeat,
                linear-gradient(180deg, #152219 0%, #1a2f22 50%, #203e2c 100%);
    border-color: #2ecc71;
    box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.8), 0 0 12px rgba(46, 204, 113, 0.4);
}

input[type="checkbox"]:checked::after {
    left: 44px;
    background: #2ecc71;
    box-shadow: 0 0 8px #2ecc71, 0 0 12px #2ecc71;
}

input[type="checkbox"]:checked::before {
    transform: rotate(40deg);
    filter: drop-shadow(0 0 5px rgba(46, 204, 113, 0.7)) drop-shadow(0 2px 3px rgba(0, 0, 0, 0.8));
}

input[type="checkbox"]:checked:hover::before {
    transform: rotate(32deg);
}

input[type="checkbox"]:active::before {
    transform: rotate(0deg);
}

input[type="checkbox"]:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* Range Sliders */
input[type="range"] {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    width: 100%;
    height: 8px;
    background: var(--bg-tertiary);
    border-radius: var(--radius-sm);
    margin: 15px 0;
}
input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 20px;
    height: 20px;
    background: var(--interactive-active);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
    transition: transform var(--duration-fast) var(--ease-standard);
}
input[type="range"]::-webkit-slider-thumb:hover { transform: scale(1.1); }
input[type="range"]::-moz-range-thumb {
    width: 20px;
    height: 20px;
    background: var(--interactive-active);
    border-radius: 50%;
    cursor: pointer;
    border: none;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
}

/* 10. CHANNEL SELECT ROWS & DRAWERS -------------------------------------------- */
.channel-select-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    margin-bottom: 8px;
    border-radius: var(--radius-md);
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    cursor: pointer;
    user-select: none;
    transition: all 0.25s ease;
    gap: 12px;
}

.channel-select-row:hover {
    background: var(--bg-modifier-hover);
    border-color: rgba(88, 101, 242, 0.4);
}

.channel-select-row:has(input:checked) {
    background: rgba(46, 204, 113, 0.08);
    border-color: rgba(46, 204, 113, 0.35);
}

.channel-row-left {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 1;
    min-width: 0;
}

.channel-status-light {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #e74c3c;
    box-shadow: 0 0 6px rgba(231, 76, 60, 0.7);
    flex-shrink: 0;
    transition: all 0.3s ease;
    display: inline-block;
}

.channel-select-row:has(input:checked) .channel-status-light,
.channel-status-light.active {
    background: #2ecc71;
    box-shadow: 0 0 8px #2ecc71, 0 0 14px rgba(46, 204, 113, 0.5);
}

.channel-name {
    font-size: 14px;
    font-weight: 500;
    color: var(--header-primary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    letter-spacing: 0.2px;
}

.channel-drawer {
    margin-top: 8px;
    border-radius: var(--radius-md);
    border: 1px solid var(--border-color);
    background: var(--bg-tertiary);
    transition: border-color 0.25s ease, box-shadow 0.25s ease;
    overflow: hidden;
}

.channel-drawer:hover {
    border-color: rgba(88, 101, 242, 0.35);
}

.channel-drawer.open {
    border-color: var(--brand-experiment);
    box-shadow: var(--shadow-md);
}

.channel-drawer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 14px;
    background: var(--bg-secondary);
    cursor: pointer;
    user-select: none;
    transition: background 0.2s ease;
}

.channel-drawer-header:hover {
    background: var(--bg-modifier-hover);
}

.channel-drawer-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 14px;
    font-weight: 500;
    color: var(--header-primary);
}

.channel-drawer-badge {
    font-size: 12px;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius-pill);
    background: rgba(88, 101, 242, 0.15);
    color: var(--brand-experiment);
    border: 1px solid rgba(88, 101, 242, 0.3);
    transition: all 0.2s ease;
}

.channel-drawer.has-selected .channel-drawer-badge {
    background: rgba(46, 204, 113, 0.18);
    color: #2ecc71;
    border-color: rgba(46, 204, 113, 0.4);
}

.channel-drawer-arrow {
    font-size: 11px;
    color: var(--text-muted);
    transition: transform 0.25s ease;
}

.channel-drawer.open .channel-drawer-arrow {
    transform: rotate(180deg);
}

.channel-drawer-content {
    display: none;
    padding: 12px;
    border-top: 1px solid var(--border-color);
    background: var(--bg-tertiary);
}

.channel-drawer.open .channel-drawer-content {
    display: block;
    animation: drawer-open var(--duration-base) var(--ease-standard);
}

@keyframes drawer-open {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: translateY(0); }
}

.drawer-toolbar {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 10px;
}

.drawer-search-input {
    flex: 1;
    padding: 7px 12px !important;
    font-size: 13px !important;
    border-radius: 6px !important;
    border: 1px solid var(--border-color) !important;
    background: var(--bg-secondary) !important;
    color: var(--text-normal) !important;
    margin-bottom: 0 !important;
    outline: none;
}

.drawer-search-input:focus {
    border-color: var(--brand-experiment) !important;
}

.drawer-btn {
    padding: 6px 10px;
    font-size: 12px;
    font-weight: 600;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--bg-secondary);
    color: var(--text-normal);
    cursor: pointer;
    white-space: nowrap;
    transition: all 0.2s;
}

.drawer-btn:hover {
    background: var(--brand-experiment);
    color: white;
    border-color: var(--brand-experiment);
}

.drawer-btn-outline {
    background: transparent;
}

.drawer-btn-outline:hover {
    background: rgba(231, 76, 60, 0.2);
    color: #e74c3c;
    border-color: rgba(231, 76, 60, 0.4);
}

.drawer-channels-scroll {
    max-height: 220px;
    overflow-y: auto;
    padding-right: 4px;
}

/* 11. TABLES ------------------------------------------------------------------ */
.xp-table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}
.xp-table th {
    padding: 12px 8px;
    border-bottom: 1px solid var(--border-color);
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.xp-table td {
    padding: 10px 8px;
    border-bottom: 1px solid var(--border-color);
    vertical-align: middle;
}
.xp-table tbody tr {
    transition: background-color 0.15s ease;
}
.xp-table tbody tr:hover {
    background-color: var(--bg-modifier-hover);
}

/* Reaction Roles & Lists */
#reaction-roles-list { list-style: none; padding: 0; margin: 0; }
/* dashboard.js appends rendered reaction-role panels here as raw
   .settings-card divs (not inside the page grid), so they need their own
   spacing now that .settings-card no longer carries a blanket margin-bottom. */
#reaction-roles-list > .settings-card { margin-bottom: 12px; max-width: none; }
#reaction-roles-list li {
    background: var(--bg-tertiary);
    padding: 12px;
    border-radius: var(--radius-sm);
    margin-bottom: 8px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid var(--border-color);
    transition: border-color var(--duration-base) var(--ease-standard);
}
#reaction-roles-list li:hover { border-color: rgba(88, 101, 242, 0.3); }
.delete-rr-btn { background: var(--button-danger-bg); padding: 4px 10px; font-size: 12px; }

/* 12. STATUS TOAST -------------------------------------------------------------- */
.status {
    position: fixed;
    bottom: 20px;
    right: 20px;
    padding: 12px 24px;
    border-radius: var(--radius-md);
    background: var(--bg-floating);
    box-shadow: var(--shadow-lg);
    z-index: 100;
    display: none;
    border-left: 3px solid var(--brand-experiment);
    font-size: 14px;
    font-weight: 500;
    color: var(--header-primary);
    animation: toast-in var(--duration-base) var(--ease-spring);
}
.status.success { border-left-color: var(--status-positive); }
.status.error { border-left-color: var(--status-danger); }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(8px); }
    to { opacity: 1; transform: translateY(0); }
}

.settings-page { display: none; }
.settings-page.active {
    /* True masonry, not a row-locked grid: CSS Grid forces every card in the
       same row to share that row's height (the tallest card in the row sets
       it for everyone), and these cards vary a lot in content length -- that
       mismatch is exactly what read as cards "fighting" and never lining up.
       Multi-column layout packs each column independently instead, so a
       short card is immediately followed by the next one in its own column,
       regardless of how tall its neighbor column's card happens to be. */
    display: block;
    columns: 1;
    column-gap: 20px;
    max-width: 1400px;
    animation: page-in var(--duration-slow) var(--ease-standard);
}
.settings-page.active > *:not(.settings-card) {
    column-span: all;
}

@media (min-width: 1280px) {
    .settings-page.active { columns: 2; }
}
@media (min-width: 1680px) {
    .settings-page.active { columns: 3; }
}

/* ============ CARD PAGER MODE ============ */
/* Opt-in (data-card-pager="true") for pages whose cards are already large on
   their own -- XP & Leveling, for one. Instead of masonry-packing several
   already-massive cards, show exactly one at a time, filling the space, with
   a glowing control to move to the next and a dot trail for orientation. */
.settings-page.active[data-card-pager] {
    display: flex;
    flex-direction: column;
    height: 100%;
    columns: initial;
    max-width: none;
}
.settings-page[data-card-pager] > .settings-card {
    display: none;
}
.settings-page[data-card-pager] > .settings-card.pager-active {
    display: flex;
    flex-direction: column;
    /* Not flex-grow:1 -- a card should sit at its own natural height (a
       short card stays short instead of stretching into a mostly-empty box)
       and only cap + scroll internally once it's actually taller than the
       space available. */
    flex: 0 1 auto;
    min-height: 0;
    max-height: 100%;
    overflow-y: auto;
    align-self: center;
    width: 100%;
    max-width: 920px;
    margin-bottom: 0;
    animation: card-in var(--duration-slower) var(--ease-standard);
}

.card-pager-nav {
    position: fixed;
    right: 28px;
    top: 50%;
    transform: translateY(-50%);
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    z-index: 500;
}
.card-pager-nav.visible { display: flex; }
/* ...but not over the welcome screen or server picker when the last page you had open was a pager page
   (dashboard.js restores it before a server is chosen, while #dashboard-body is still hidden). */
body:has(#dashboard-body[style*="display: none"]) .card-pager-nav { display: none; }

/* A literal beam of light: a thin glowing shaft rather than a button. The
   clickable area (.card-pager-glow) stays a comfortable width for hit-testing;
   the visible beam itself (.card-pager-beam) is the slim glowing element
   inside it, brightening and thickening on hover to show it noticed the
   cursor. */
.card-pager-glow {
    width: 44px;
    height: 108px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.card-pager-beam {
    width: 4px;
    height: 100%;
    border-radius: 4px;
    background: linear-gradient(
        180deg,
        transparent 0%,
        rgba(255, 184, 0, 0.12) 15%,
        rgba(255, 213, 79, 0.75) 50%,
        rgba(255, 184, 0, 0.12) 85%,
        transparent 100%
    );
    box-shadow: 0 0 8px rgba(255, 184, 0, 0.5), 0 0 20px rgba(255, 184, 0, 0.25);
    transition: width var(--duration-base) var(--ease-standard),
                box-shadow var(--duration-base) var(--ease-standard),
                filter var(--duration-base) var(--ease-standard);
}
.card-pager-glow:hover .card-pager-beam {
    width: 6px;
    box-shadow: 0 0 14px rgba(255, 184, 0, 0.85), 0 0 34px rgba(255, 184, 0, 0.45);
    filter: brightness(1.25);
}
.card-pager-glow:active .card-pager-beam {
    width: 5px;
    filter: brightness(1.5);
}

.card-pager-dots {
    display: flex;
    flex-direction: column;
    gap: 7px;
    padding: 4px 0;
}
.card-pager-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--text-muted);
    opacity: 0.5;
    cursor: pointer;
    transition: all var(--duration-base) var(--ease-standard);
}
.card-pager-dot:hover { opacity: 0.85; }
.card-pager-dot.active {
    background: var(--liora-gold, #ffb800);
    opacity: 1;
    transform: scale(1.35);
    box-shadow: 0 0 6px rgba(255, 184, 0, 0.6);
}

@keyframes page-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}

/* 13. BADGES ---------------------------------------------------------------------- */
.badge {
    display: inline-flex;
    align-items: center;
    line-height: 1.2;
    white-space: nowrap;
    letter-spacing: 0.2px;
    border-radius: var(--radius-pill);
    font-size: 11px;
    font-weight: 700;
    padding: 3px 9px;
    background: var(--bg-tertiary);
    color: var(--text-muted);
    border: 1px solid var(--border-color);
}

/* 14. SCROLLBARS -------------------------------------------------------------------- */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--bg-tertiary) transparent;
}

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 10px; }
::-webkit-scrollbar-thumb:hover { background: #111; }

.drawer-channels-scroll::-webkit-scrollbar,
.custom-scroll::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

.drawer-channels-scroll::-webkit-scrollbar-track,
.custom-scroll::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.1);
    border-radius: 3px;
}

.drawer-channels-scroll::-webkit-scrollbar-thumb,
.custom-scroll::-webkit-scrollbar-thumb {
    background: rgba(255, 255, 255, 0.15);
    border-radius: 3px;
}

.drawer-channels-scroll::-webkit-scrollbar-thumb:hover,
.custom-scroll::-webkit-scrollbar-thumb:hover {
    background: rgba(255, 255, 255, 0.3);
}

/* 15. MICRO-ANIMATIONS & SPARKLES ----------------------------------------------------- */
#sidebar li a span {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    transition: transform 0.3s var(--ease-spring);
}
#sidebar li a:hover span {
    animation: sidebar-jiggle 0.6s ease-in-out;
    transform: scale(1.04);
}

@keyframes sidebar-jiggle {
    0% { transform: scale(1.04) rotate(0deg); }
    15% { transform: scale(1.04) rotate(-3deg); }
    30% { transform: scale(1.04) rotate(2deg); }
    45% { transform: scale(1.04) rotate(-2deg); }
    60% { transform: scale(1.04) rotate(1deg); }
    100% { transform: scale(1.04) rotate(0deg); }
}

/* A small 4-point spark drawn as a clip-path shape filled with a real gold
   gradient -- not an emoji glyph, so the color is always exactly this gold,
   on every platform, instead of whatever an emoji font happens to ship. */
/* A physics-driven spark streak, updated per-frame from JS (see
   spawnSpark/stepSparks in dashboard.js) -- not a CSS keyframe animation.
   transform-origin sits at the bright head (the spark's actual position);
   the element's width is its current streak length, and JS rotates it to
   trail directly behind the spark's real direction of travel. */
.spark-particle {
    position: fixed;
    top: 0;
    left: 0;
    height: 1.5px;
    width: 4px;
    pointer-events: none;
    z-index: 99999;
    opacity: 0;
    transform-origin: 0% 50%;
    border-radius: 1px;
    background: linear-gradient(90deg, #fff8e1 0%, #ffd54f 30%, #ffb800 65%, transparent 100%);
    filter: drop-shadow(0 0 2px rgba(255, 184, 0, 0.75));
    will-change: transform, width, opacity;
}

/* Card entrance on page load: cards slide out from the left, as if emerging
   from underneath the sidebar, cascading in one after another rather than
   all arriving at once -- echoing the same "slip out" motion as the sidebar
   category reveal, just travelling the other direction. */
.settings-page.active .settings-card {
    animation: card-in var(--duration-slower) var(--ease-standard) backwards;
}
/* :nth-of-type (not :nth-child) -- .settings-card is always a <div>, but a
   page's <h2>/.page-desc siblings come before it and would otherwise throw
   the count off by 2, so the first two real cards never matched before. */
.settings-page.active .settings-card:nth-of-type(1) { animation-delay: 0ms; }
.settings-page.active .settings-card:nth-of-type(2) { animation-delay: 70ms; }
.settings-page.active .settings-card:nth-of-type(3) { animation-delay: 140ms; }
.settings-page.active .settings-card:nth-of-type(4) { animation-delay: 210ms; }
.settings-page.active .settings-card:nth-of-type(n+5) { animation-delay: 260ms; }

@keyframes card-in {
    from { opacity: 0; transform: translateX(-44px); }
    to { opacity: 1; transform: translateX(0); }
}

/* 16. ACCESSIBILITY ------------------------------------------------------------------- */
a:focus-visible,
button:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--liora-gold);
    outline-offset: 2px;
}

#sidebar li a:focus-visible {
    outline-offset: -2px;
}

@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;
    }
}

/* 16b. HOME PAGE: the Library's golden-hour reading room, brought to the dashboard ---------- */
:root {
    --serif: "Fraunces", Georgia, "Times New Roman", serif;
    --sans-warm: "DM Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
}
.home {
    position: relative; max-width: 1040px; margin: 0 auto; padding: 8px 0 24px;
    font-family: var(--sans-warm); color: var(--text-normal); isolation: isolate;
}
.home-glow { position: absolute; border-radius: 50%; filter: blur(80px); pointer-events: none; z-index: -1; opacity: 0.5; }
.home-glow-a { width: 560px; height: 560px; top: -240px; left: 50%; transform: translateX(-50%);
    background: radial-gradient(circle, rgba(255, 184, 0, 0.32), transparent 70%); }
.home-glow-b { width: 420px; height: 420px; top: 520px; right: -180px;
    background: radial-gradient(circle, rgba(255, 120, 40, 0.16), transparent 70%); }
.home em { font-style: italic; color: var(--liora-gold); }

.home-hero { text-align: center; padding: 28px 8px 12px; }
.home-gem { position: relative; width: 132px; height: 132px; margin: 0 auto 18px; }
.home-gem img { position: relative; width: 100%; height: 100%; object-fit: contain;
    filter: drop-shadow(0 10px 30px rgba(255, 184, 0, 0.45)); animation: home-float 6s ease-in-out infinite; }
.home-halo { position: absolute; inset: -18px; border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 184, 0, 0.28), transparent 65%); animation: home-breathe 6s ease-in-out infinite; }
@keyframes home-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
@keyframes home-breathe { 0%, 100% { opacity: 0.6; transform: scale(0.96); } 50% { opacity: 1; transform: scale(1.04); } }

.home-kicker { text-transform: uppercase; letter-spacing: 0.18em; font-size: 12px; font-weight: 700; color: var(--liora-gold); margin-bottom: 6px; }
.home-title { font: 600 clamp(2.4rem, 7vw, 3.8rem)/1.05 var(--serif); color: var(--header-primary); margin: 0 0 14px; }
.home-lead { max-width: 560px; margin: 0 auto; font-size: 17px; line-height: 1.65; color: var(--header-secondary); }
.home-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 26px; }
.home-btn {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 46px; padding: 0 22px;
    border-radius: 999px; font: 700 15px var(--sans-warm); text-decoration: none; cursor: pointer;
    transition: transform var(--duration-fast) var(--ease-standard), box-shadow var(--duration-base), background var(--duration-base);
}
.home-btn:hover { transform: translateY(-2px); }
.home-btn-gold { background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong)); color: #2a1800;
    box-shadow: 0 8px 24px rgba(255, 150, 20, 0.35); }
.home-btn-gold:hover { box-shadow: 0 12px 30px rgba(255, 150, 20, 0.5); }
.home-btn-ghost { color: var(--header-primary); border: 1px solid rgba(255, 210, 150, 0.26); background: rgba(255, 232, 196, 0.04); }
.home-btn-ghost:hover { background: rgba(255, 232, 196, 0.09); border-color: rgba(255, 210, 150, 0.45); }
body.logged-in .home-login { display: none; }
.home-servers { display: none; }
body.logged-in .home-servers { display: inline-flex; }

/* --- Server picker (auth.js): choose a server on cards before the dashboard opens --- */
.server-picker { max-width: 1100px; margin: 0 auto; padding: 28px 8px 60px; animation: page-in var(--duration-slower) var(--ease-standard); }
.server-picker-head { text-align: center; margin-bottom: 28px; }
.server-picker-title { font: 600 clamp(2rem, 5.5vw, 3rem)/1.1 var(--serif); color: var(--header-primary); margin: 0 0 10px; }
.server-picker-title em { font-style: italic; color: var(--liora-gold); }
.server-picker-sub { margin: 0 auto; max-width: 560px; color: var(--text-muted); font-size: 15px; }
.server-picker-search {
    display: flex; align-items: center; gap: 10px; max-width: 420px; margin: 20px auto 0; padding: 4px 16px;
    border: 1px solid var(--border-color); border-radius: var(--radius-pill); background: var(--bg-secondary);
}
.server-picker-search[hidden] { display: none; }
/* "Get the app" (links to /app): not shown once you're in the installed app. */
.server-picker-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 16px; }
.server-picker-actions .home-btn { min-height: 0; padding: 8px 18px; font-size: 14px; }
@media (display-mode: standalone) { .app-get-link { display: none !important; } }
.server-picker-search input { border: 0; background: transparent; margin: 0; padding: 8px 0; flex: 1; color: var(--text-normal); box-shadow: none; }
.server-picker-search input:focus { outline: none; box-shadow: none; }
/* minmax(0, ...) lets a column be narrower than a long server name (the name trims with …) instead of pushing past the screen */
.server-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr)); gap: 16px; }
.server-grid-label {
    grid-column: 1 / -1; margin: 18px 0 0; font-size: 12px; font-weight: 700; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--text-muted);
}
.server-card {
    display: flex; align-items: center; gap: 14px; padding: 16px 18px; min-width: 0; max-width: 100%;
    background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 16px;
    color: var(--text-normal); text-decoration: none; position: relative;
    transition: transform var(--duration-base) var(--ease-standard), border-color var(--duration-slow) var(--ease-standard),
                box-shadow var(--duration-slow) var(--ease-standard), background var(--duration-slow) var(--ease-standard);
    animation: card-in var(--duration-slower) var(--ease-standard) backwards;
}
.server-card:hover, .server-card:focus-visible {
    transform: translateY(-3px);
    border-color: rgba(255, 184, 0, 0.55);
    box-shadow: 0 0 0 1px rgba(255, 184, 0, 0.18), 0 10px 26px rgba(0, 0, 0, 0.3), 0 0 22px rgba(255, 184, 0, 0.12);
    outline: none;
}
.server-card-icon {
    flex: none; width: 56px; height: 56px; border-radius: 18px; overflow: hidden;
    display: grid; place-items: center; font: 600 1.5rem var(--serif); color: var(--liora-gold);
    background: var(--liora-gold-soft); border: 1px solid rgba(255, 184, 0, 0.25);
}
.server-card-icon img { width: 100%; height: 100%; object-fit: cover; }
.server-card-body { flex: 1; min-width: 0; }
.server-card-name { margin: 0; font-size: 16px; font-weight: 700; color: var(--header-primary); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.server-card-meta { margin-top: 3px; font-size: 13px; color: var(--text-muted); }
.server-card-badge {
    display: inline-block; margin-top: 6px; padding: 1px 9px; border-radius: var(--radius-pill);
    font-size: 11px; font-weight: 700; color: var(--liora-gold); background: var(--liora-gold-soft);
}
.server-card-go {
    flex: none; font-size: 13px; font-weight: 700; color: var(--liora-gold); opacity: 0.85;
    transition: transform var(--duration-base) var(--ease-standard), opacity var(--duration-base);
}
.server-card:hover .server-card-go { transform: translateX(3px); opacity: 1; }
.server-card-invite { border-style: dashed; opacity: 0.85; }
.server-card-invite .server-card-icon { filter: grayscale(0.6); }
.server-card-invite:hover { opacity: 1; }
.server-picker-empty { text-align: center; color: var(--text-muted); max-width: 520px; margin: 30px auto 0; }
.server-grid .server-card:nth-child(2) { animation-delay: 50ms; }
.server-grid .server-card:nth-child(3) { animation-delay: 100ms; }
.server-grid .server-card:nth-child(4) { animation-delay: 150ms; }
.server-grid .server-card:nth-child(n+5) { animation-delay: 200ms; }

/* back to the server cards, in the top bar while a server is open */
.back-to-servers {
    display: inline-flex; align-items: center; gap: 6px; margin-right: 10px; padding: 6px 14px;
    background: transparent !important; background-image: none !important; box-shadow: none !important;
    color: var(--liora-gold) !important; border: 1px solid rgba(255, 184, 0, 0.4); border-radius: var(--radius-pill);
    font-size: 13px; font-weight: 700; white-space: nowrap;
}
.back-to-servers[hidden] { display: none; }
.back-to-servers:hover:not(:disabled) { background: var(--liora-gold-soft) !important; transform: none; }
@media (max-width: 820px) {
    .server-picker { padding: 16px 0 48px; }
    .server-grid { grid-template-columns: minmax(0, 1fr); gap: 12px; }
    .server-card { padding: 14px 14px; gap: 12px; }
    .server-card-icon { width: 48px; height: 48px; border-radius: 15px; }
    .server-card-go { font-size: 12px; }
    .back-to-servers { padding: 6px 10px; margin-right: 6px; }
    .back-to-servers .back-label { display: none; }
}
/* Liora's theme: the cards breathe too */
[data-theme="liora"] .server-card {
    border-color: rgba(255, 184, 0, 0.22);
    animation: card-in var(--duration-slower) var(--ease-standard) backwards,
               liora-card-breathe var(--breathe-len, 8s) ease-in-out var(--breathe-delay, 0s) infinite;
}

.home-section { margin-top: 56px; }
.home-h2 { font: 600 clamp(1.5rem, 4vw, 2rem) var(--serif); color: var(--header-primary); text-align: center; margin-bottom: 22px; }
.home-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 16px; }
.home-card {
    background: rgba(255, 232, 196, 0.045); border: 1px solid rgba(255, 210, 150, 0.13); border-radius: 20px; padding: 22px;
    transition: transform var(--duration-base) var(--ease-standard), border-color var(--duration-base), background var(--duration-base);
}
.home-card:hover { transform: translateY(-3px); border-color: rgba(255, 210, 150, 0.3); background: rgba(255, 232, 196, 0.07); }
.home-card h3 { font: 600 1.15rem var(--serif); color: var(--header-primary); margin: 10px 0 6px; }
.home-card p { font-size: 14.5px; line-height: 1.6; color: var(--text-muted); }
.home-icon { display: inline-grid; place-items: center; width: 44px; height: 44px; border-radius: 14px; font-size: 22px;
    background: var(--liora-gold-soft); box-shadow: inset 0 0 0 1px rgba(255, 184, 0, 0.25); }

/* Her own clips (static/media, made by tools/patreon/clips.py): the introduction, her faces, the dashboard tour.
   aspect-ratio holds the room before the picture arrives, so the page doesn't jump. */
.home-video { max-width: 860px; margin: 0 auto; }
.home-video video { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 22px; background: #0b0806;
    border: 1px solid rgba(255, 190, 60, 0.38); box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45), 0 0 50px rgba(255, 170, 30, 0.10); }
.home-video figcaption { margin-top: 12px; text-align: center; font-size: 14px; line-height: 1.55; color: var(--text-muted); }
.home-tour { margin: 30px auto 0; }
.home-faces { display: flex; align-items: center; justify-content: center; gap: 30px; flex-wrap: wrap; }
.home-faces-clip { flex: 0 0 auto; width: min(260px, 68vw); aspect-ratio: 1; border-radius: 28px; overflow: hidden; background: #0b0806;
    border: 1px solid rgba(255, 190, 60, 0.38); box-shadow: 0 0 44px rgba(255, 170, 30, 0.14); }
.home-faces-clip video { display: block; width: 100%; height: 100%; object-fit: cover; }
.home-faces-words { flex: 1 1 280px; max-width: 420px; }
.home-faces-words .home-h2 { text-align: left; margin-bottom: 10px; }
.home-faces-words p { font-size: 16px; line-height: 1.65; color: var(--header-secondary); }
@media (max-width: 640px) { .home-faces-words, .home-faces-words .home-h2 { text-align: center; } }
/* Her themes, shown where one is picked (General, Appearance) */
.theme-film { margin: 14px 0 4px; max-width: 520px; }
.theme-film video { display: block; width: 100%; aspect-ratio: 16 / 9; border-radius: 14px; background: #0b0806;
    border: 1px solid rgba(255, 190, 60, 0.35); }
/* On the showcase's "Her Own Emojis" card: just the gem, in a round window (the clip's own caption is cropped away) */
.feature-loop { float: right; width: 92px; height: 92px; margin: 0 0 8px 14px; border-radius: 50%; overflow: hidden; background: #1c1307;
    border: 1px solid rgba(255, 190, 60, 0.45); box-shadow: 0 0 18px rgba(255, 170, 30, 0.22); }
.feature-loop video { display: block; width: 160%; max-width: none; margin: -20% 0 0 -30%; }

.home-steps { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; }
.home-steps li { display: flex; gap: 14px; align-items: flex-start; padding: 18px; border-radius: 18px; border: 1px dashed rgba(255, 210, 150, 0.22); }
.home-steps li > span { flex-shrink: 0; display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
    font: 600 1.1rem var(--serif); color: #2a1800; background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong)); }
.home-steps h3 { font: 600 1.05rem var(--serif); color: var(--header-primary); margin-bottom: 2px; }
.home-steps p { font-size: 14px; color: var(--text-muted); }

/* The clock on her making (utils/dev_clock.py): days since her birthday, Bliss's estimate, hours clocked since */
.home-clock-figures { list-style: none; padding: 0; margin: 0 auto; max-width: 860px; display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
.home-clock-figures li { display: grid; gap: 3px; align-content: start; padding: 22px 16px; text-align: center; border-radius: 20px;
    background: rgba(255, 232, 196, 0.045); border: 1px solid rgba(255, 210, 150, 0.13); }
.home-clock-figures strong { font: 600 clamp(2rem, 6vw, 2.7rem)/1.1 var(--serif); color: var(--liora-gold); font-variant-numeric: tabular-nums; }
.home-clock-figures strong i { font: italic 400 0.42em var(--serif); color: var(--text-muted); }
.home-clock-figures span { font-size: 15px; color: var(--header-primary); }
.home-clock-figures small { font-size: 13px; color: var(--text-muted); }
.home-clock-note { max-width: 620px; margin: 16px auto 0; text-align: center; font-size: 14px; line-height: 1.6; color: var(--text-muted); }

.home-promise { margin-top: 56px; padding: 26px 24px; border-radius: 22px;
    background: linear-gradient(160deg, rgba(255, 184, 0, 0.1), rgba(255, 120, 40, 0.04)); border: 1px solid rgba(255, 184, 0, 0.22); }
.home-promise ul { list-style: none; padding: 0; margin: 0 auto; max-width: 640px; display: grid; gap: 12px; }
.home-promise li { font-size: 15px; line-height: 1.55; color: var(--header-secondary); }
.home-promise code { background: rgba(0, 0, 0, 0.25); padding: 1px 6px; border-radius: 6px; font-size: 13px; }

.home-foot { display: flex; align-items: center; justify-content: center; gap: 8px; margin-top: 40px;
    font: italic 400 14px var(--serif); color: var(--text-muted); flex-wrap: wrap; }
.home-foot-link { color: inherit; text-decoration: underline; text-decoration-color: rgba(255, 184, 0, 0.5); text-underline-offset: 3px; }
.home-foot-link::before { content: "·"; margin-right: 8px; color: var(--text-muted); display: inline-block; }
.home-foot-link:hover { color: #ffb800; }

[data-theme="light"] .home-card, [data-theme="light"] .home-btn-ghost, [data-theme="light"] .home-clock-figures li { background: rgba(255, 252, 245, 0.9); border-color: rgba(110, 72, 20, 0.16); }
[data-theme="light"] .home-steps li { border-color: rgba(110, 72, 20, 0.22); }
[data-theme="light"] .home-promise code { background: rgba(110, 72, 20, 0.08); }
@media (prefers-reduced-motion: reduce) { .home-gem img, .home-halo { animation: none; } }

/* 16c. FRESH START -------------------------------------------------------------------------- */
.fs-card { margin-bottom: 16px; }
.fs-note { font-size: 15px; }
.fs-h3 { font-family: var(--serif); font-weight: 600; font-size: 1.15rem; color: var(--header-primary); margin-bottom: 12px; }
.fs-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 10px; margin-bottom: 14px; }
.fs-choice { display: flex; gap: 10px; align-items: flex-start; padding: 14px; border-radius: 14px; cursor: pointer;
    border: 1px solid rgba(255, 210, 150, 0.18); background: rgba(255, 232, 196, 0.035); }
.fs-choice:has(input:checked) { border-color: var(--liora-gold); background: var(--liora-gold-soft); }
.fs-choice-danger:has(input:checked) { border-color: var(--status-danger); background: rgba(242, 63, 67, 0.12); }
.fs-choice input { margin-top: 3px; accent-color: var(--liora-gold); }
.fs-choice strong { display: block; color: var(--header-primary); }
.fs-choice small { display: block; color: var(--text-muted); font-size: 13px; margin-top: 2px; }
.fs-btn { margin-top: 14px; min-height: 44px; padding: 0 20px; border-radius: 999px; font-weight: 700; cursor: pointer; }
#fs-preview-btn { background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong)); color: #2a1800; border: 0; }
.fs-count { font: 600 1.3rem var(--serif); color: var(--header-primary); margin-bottom: 4px; }
.fs-sample { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.fs-sample span { padding: 4px 10px; border-radius: 999px; background: var(--bg-tertiary); font-size: 13px; }
.fs-sample .fs-more { background: transparent; color: var(--text-muted); }
.fs-danger { border: 1px solid rgba(242, 63, 67, 0.35); }
#fs-confirm-input { width: 100%; margin-top: 8px; }
.fs-status { min-height: 1.4em; font-size: 14px; color: var(--text-muted); }
.fs-status[data-kind="ok"] { color: var(--status-positive); }
.fs-status[data-kind="error"] { color: var(--status-danger); }
.fs-status[data-kind="info"] { color: var(--liora-gold); }

/* 17. RESPONSIVE ------------------------------------------------------------------------ */
/* Hamburger + backdrop exist only for phones. So do the Save cards at the end of each page (dashboard.js adds them);
   desktop saves from the top-bar button. */
#mobile-menu-btn { display: none; }
#sidebar-backdrop { display: none; }
.settings-card.save-card { display: none; }

/* Phones & small tablets: the menu becomes a slide-out drawer (☰ or swipe in from the left edge), the page gets
   the full width and scrolls normally, and Save is the last card on each page. */
@media (max-width: 820px) {
    body { height: 100dvh; }
    .app-container { display: block; height: 100dvh; }

    #sidebar {
        position: fixed; top: 0; bottom: 0; left: 0; z-index: 60;
        width: min(86vw, 320px);
        transform: translateX(-105%);
        transition: transform var(--duration-slow) var(--ease-standard);
        box-shadow: var(--shadow-lg);
        border-right: 1px solid var(--liora-gold-soft);
        padding-bottom: env(safe-area-inset-bottom);
    }
    body.menu-open #sidebar { transform: translateX(0); }
    #sidebar-backdrop {
        display: block; position: fixed; inset: 0; z-index: 55;
        background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(2px);
        opacity: 0; pointer-events: none; transition: opacity var(--duration-base) var(--ease-standard);
    }
    body.menu-open #sidebar-backdrop { opacity: 1; pointer-events: auto; }

    /* In the drawer every section is open: one scroll, big tap targets, no hover needed. */
    .nav-links { max-height: none !important; opacity: 1 !important; transform: none !important; }
    .nav-category-arrow { display: none; }
    .nav-category { pointer-events: none; padding-top: 14px; }
    #sidebar li a { padding: 12px 10px; font-size: 15px; }

    #main-wrapper { height: 100dvh; width: 100%; }
    .top-bar {
        height: auto; min-height: 56px; padding: 8px 12px; padding-top: max(8px, env(safe-area-inset-top));
        position: sticky; top: 0; background: var(--bg-primary);
    }
    .top-bar > div:last-child { width: 100%; order: 3; }
    .top-bar-title { flex: 1; min-width: 0; font-size: 16px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
    #server-select-container { min-width: 0 !important; flex: 1; }
    #server-select { width: 100%; font-size: 16px; padding: 10px 12px !important; }

    #mobile-menu-btn {
        display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
        width: 44px; height: 44px; padding: 0 11px; flex-shrink: 0;
        border-radius: 50%; border: 2px solid var(--liora-gold); background: var(--liora-gold-soft);
        box-shadow: 0 0 12px rgba(255, 184, 0, 0.35); cursor: pointer;
    }
    /* width: 100% because a button starts its contents at the left edge (align-items: flex-start), which shrank the three lines to nothing */
    #mobile-menu-btn span { display: block; width: 100%; height: 2px; border-radius: 2px; background: var(--liora-gold); }

    #main-content {
        padding: 16px; padding-bottom: calc(32px + env(safe-area-inset-bottom));
        height: auto; overscroll-behavior-y: contain; -webkit-overflow-scrolling: touch;
    }
    #main-content img, #main-content video, #main-content iframe { max-width: 100%; height: auto; }
    #main-content table { display: block; max-width: 100%; overflow-x: auto; }
    #main-content [style*="grid-template-columns"], .setting-grid-2 { grid-template-columns: minmax(0, 1fr) !important; }
    #main-content [style*="min-width"] { min-width: 0 !important; }
    #main-content pre, #main-content code { white-space: pre-wrap; word-break: break-word; }
    /* 16px stops phones zooming in when a field is tapped */
    input, select, textarea { font-size: 16px !important; max-width: 100%; }
    button { min-height: 40px; }

    /* XP & Leveling tables (channel level locks, staff channels, members) were wider than a phone and ran off the
       right edge. Here every row becomes a little stacked card: the channel/member on top, its controls labelled
       underneath (the labels come from each cell's data-label, since the header row is hidden). */
    #main-content .xp-table.stack-on-phone { display: block; overflow: visible; }
    .xp-table.stack-on-phone thead { display: none; }
    .xp-table.stack-on-phone tbody { display: block; }
    .xp-table.stack-on-phone tr {
        display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px 14px;       /* one control per line */
        padding: 12px 4px; border-bottom: 1px solid var(--border-color);
    }
    #xp-members-table tr { grid-template-columns: repeat(2, minmax(0, 1fr)); }  /* members: just numbers, two a line */
    .xp-table.stack-on-phone td {
        display: flex; align-items: center; justify-content: space-between; gap: 8px;
        min-width: 0; padding: 0 !important; border: 0; text-align: left !important;
    }
    .xp-table.stack-on-phone td:first-child, .xp-table.stack-on-phone td[colspan] { grid-column: 1 / -1; }
    .xp-table.stack-on-phone td:first-child { justify-content: flex-start; }
    .xp-table.stack-on-phone td:first-child > div { min-width: 0; }
    .xp-table.stack-on-phone td:first-child span { overflow-wrap: anywhere; }
    .xp-table.stack-on-phone td[data-label]::before {
        content: attr(data-label); font-size: 13px; font-weight: 600; color: var(--text-muted); white-space: nowrap;
    }
    .xp-table.stack-on-phone td > input { margin: 0 !important; flex-shrink: 0; }
    .xp-table.stack-on-phone .channel-level-cap-input { width: 90px !important; }
    #xp-members-table td.xp-edit-cell { grid-column: 1 / -1; justify-content: flex-end; }
    /* Their scroll boxes were only ~320px tall inside the card; give the lists most of the screen instead. */
    #xp-settings-page .settings-card [style*="max-height"] { max-height: 65vh !important; }
    .drawer-channels-scroll { max-height: 55vh; }

    /* Card pager (XP & Leveling) on phones: still one card at a time, but the card keeps its natural height and the
       page scrolls. Boxing the card to the screen made it a flex column that squashed the channel list at the bottom
       of Channel Level Locking into a thin black strip you couldn't read or scroll. (!important beats the height
       sizeCardPager sets inline.) */
    .settings-page.active[data-card-pager] { display: block; height: auto !important; }
    .settings-page[data-card-pager] > .settings-card.pager-active {
        display: block; max-height: none; overflow: visible; margin-bottom: 16px; scroll-margin-top: 72px;
    }
    /* The beam and dots sit in the right-hand gutter instead of over the cards' switches and buttons. */
    .card-pager-nav { right: 0; }
    .card-pager-glow { width: 24px; height: 88px; }

    /* Save: its own card at the end of the page (dashboard.js), not a button floating over the content. */
    #save-button { display: none !important; }
    .settings-page > .settings-card.save-card,
    .settings-page[data-card-pager] > .settings-card.save-card {
        display: flex; flex-direction: column; align-items: stretch; gap: 12px; margin-bottom: 0;
    }
    .save-card-note { margin: 0; font-size: 14px; color: var(--text-muted); text-align: center; }
    .save-card-btn {
        min-height: 48px; padding: 12px 22px; border: 0; border-radius: 999px; cursor: pointer;
        font-weight: 800; font-size: 16px; color: #1e1f22;
        background: linear-gradient(135deg, #ffc837 0%, #ff8008 100%);
        box-shadow: 0 4px 14px rgba(255, 184, 0, 0.35);
    }
    .save-card-btn:active { transform: scale(0.98); }
}

@media (max-width: 480px) {
    #main-content { padding: 12px; }
    .settings-card { padding: 14px; }
    h2 { font-size: 19px; }
    .top-bar-title { font-size: 14px; }
}

/* --- Golden emblems on the dashboard (colours and the base .ico rules: emblems.css) --- */
#sidebar li a .ico { width: 19px; height: 19px; transition: filter var(--duration-base) var(--ease-standard); }
#sidebar li a.active .ico,
#sidebar li a:hover .ico { filter: drop-shadow(0 0 4px var(--emblem-glow)); }
#sidebar-footer button .ico { width: 17px; height: 17px; margin-right: 6px; }
.home-btn .ico { width: 19px; height: 19px; }
.back-to-servers .ico { width: 16px; height: 16px; }
.home-icon .ico { width: 24px; height: 24px; }

/* Site notice editor on the server cards (Bliss only; see auth.js and utils/site_notice.py) */
.notice-editor {
    max-width: 720px; margin: 0 auto 28px; padding: 16px 18px; border-radius: 14px;
    background: var(--bg-secondary); border: 1px solid rgba(255, 184, 0, 0.3);
}
.notice-editor[hidden] { display: none; }
.notice-editor h2 { display: flex; align-items: center; gap: 8px; margin: 0 0 4px; font-size: 18px; }
.notice-editor textarea { width: 100%; margin-top: 10px; resize: vertical; }
.notice-editor-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 10px; }
.notice-editor-row label { display: flex; align-items: center; gap: 8px; margin: 0; text-transform: none; font-size: 14px; }
.notice-editor-row input[type="date"] { width: auto; margin: 0; }
.notice-count { margin-left: auto; font-size: 12px; color: var(--text-muted); }
.notice-status { font-size: 13px; color: var(--text-muted); }
.alt-switch .switch-container { margin: 0; background: transparent; border: 0; padding: 0; }
.alt-switch .notice-status:empty { display: none; }
/* Announcements & Messaging: the pictures, GIFs and videos picked to send as Liora (dashboard.js) */
.say-media-tile { width: 60px; height: 60px; object-fit: cover; border-radius: 6px; border: 1px solid var(--brand-experiment); background: #0b0806; }
.say-media-problem { display: block; margin-top: 8px; color: var(--liora-gold); }
.say-media-problem[hidden] { display: none; }
/* Bliss's clock on the server cards (Bliss only; see dev-clock.js and utils/dev_clock.py) */
.dev-clock .notice-editor-row label { flex-wrap: wrap; }
.dev-clock input[type="number"] { width: 92px; margin: 0; }
.dev-clock.waiting #dev-clock-ask { color: var(--liora-gold); }
.dev-clock #dev-clock-state { font-size: 15px; color: var(--header-secondary); }
.dev-clock #dev-clock-total { margin-top: 12px; }

/* AI badge beside "Feature Toggles" (Bliss only, ai-count.js): how many servers have her AI on, and which. */
#sidebar li:has(> .ai-count) { position: relative; }
#sidebar li:has(> .ai-count:not([hidden])) > a { padding-right: 52px; }
#sidebar .ai-count {
    position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
    display: inline-flex; align-items: center; gap: 4px;
    height: 24px; padding: 0 8px 0 5px; margin: 0;
    border: 1px solid rgba(255, 184, 0, 0.45); border-radius: var(--radius-pill);
    background: var(--liora-gold-soft); color: var(--liora-gold);
    font: 700 12px/1 inherit; font-variant-numeric: tabular-nums;
    cursor: pointer; box-shadow: none;
    transition: background-color var(--duration-fast) var(--ease-standard),
                border-color var(--duration-fast) var(--ease-standard),
                box-shadow var(--duration-fast) var(--ease-standard);
}
#sidebar .ai-count[hidden] { display: none; }
.ai-count .ico { width: 15px; height: 15px; }
#sidebar .ai-count:hover, #sidebar .ai-count:focus, #sidebar .ai-count:active, #sidebar .ai-count[aria-expanded="true"] {
    background: rgba(255, 184, 0, 0.28); border-color: var(--liora-gold); color: var(--liora-gold);
    box-shadow: 0 0 8px var(--emblem-glow, rgba(255, 184, 0, 0.5));
}
.ai-count:focus-visible { outline: 2px solid var(--liora-gold); outline-offset: 2px; }
.ai-count.none { filter: grayscale(0.7); opacity: 0.7; }

.ai-count-pop {
    position: fixed; z-index: 200; width: 300px; max-height: min(420px, calc(100dvh - 24px));
    display: flex; flex-direction: column;
    padding: 12px; border-radius: var(--radius-lg);
    background: var(--bg-floating); color: var(--text-normal);
    border: 1px solid rgba(255, 184, 0, 0.35); box-shadow: var(--shadow-lg);
    animation: ai-count-in var(--glide-ms, 260ms) var(--glide, ease-out);
}
.ai-count-pop[hidden] { display: none; }
@keyframes ai-count-in { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
.ai-count-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.ai-count-head h3 { margin: 0; font-size: 15px; color: var(--header-primary); }
.ai-count-close {
    width: 28px; height: 28px; padding: 0; border: 0; border-radius: var(--radius-sm);
    background: transparent; color: var(--text-muted); font-size: 20px; line-height: 1; cursor: pointer;
}
#ai-count-pop .ai-count-close:hover { background: var(--bg-modifier-hover); color: var(--header-primary); }
.ai-count-sum { margin: 2px 0 8px; font-size: 13px; color: var(--text-muted); }
.ai-count-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; }
.ai-count-server {
    display: flex; align-items: center; gap: 10px; width: 100%; padding: 6px 8px; margin: 0;
    border: 0; border-radius: var(--radius-md); background: transparent; color: inherit;
    text-align: left; cursor: pointer; box-shadow: none;
}
#ai-count-pop .ai-count-server:hover:not(:disabled) { background: var(--liora-gold-soft); color: inherit; }
.ai-count-server:disabled { cursor: default; opacity: 1; background: transparent; }
.ai-count-icon {
    flex: 0 0 32px; width: 32px; height: 32px; border-radius: 50%; overflow: hidden;
    display: grid; place-items: center; background: var(--bg-tertiary); color: var(--liora-gold); font-weight: 700;
}
.ai-count-icon img { width: 100%; height: 100%; object-fit: cover; }
.ai-count-text { display: flex; flex-direction: column; min-width: 0; }
.ai-count-name { font-weight: 600; color: var(--header-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ai-count-meta { font-size: 12px; color: var(--text-muted); }
@media (max-width: 820px) {
    .ai-count { height: 28px; padding: 0 10px 0 7px; }
    .ai-count-pop { left: 16px !important; right: 16px; top: auto !important; bottom: max(16px, env(safe-area-inset-bottom)); width: auto; z-index: 1001; }
}

/* ROLE MENUS PAGE (2026-10-11; static/js/role-menus.js) ------------------------
   A builder for one card with a button per kind of role. Liora's gold for what's hers (icons, chips, the Post button),
   plain surfaces for the form, and a strip that shows the card the way Discord's dark theme will. On phones every
   role row stacks, and every button is at least 34px tall with 44px for the ones tapped most. */
.rm-note { column-span: all; font-size: 15px; border-color: rgba(255, 184, 0, 0.35); }
.rm-h3 { font-family: var(--serif, Georgia, serif); font-weight: 600; font-size: 1.15rem; color: var(--header-primary); margin: 0 0 12px; }
.settings-card .rm-h3 { border-bottom: 0; padding-bottom: 0; margin-bottom: 0; }
.rm-h4 { font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px; color: var(--liora-gold); margin: 26px 0 8px; }
.rm-empty { color: var(--text-muted); font-size: 14px; margin: 6px 0 14px; }
.rm-muted { color: var(--text-muted); }
.rm-warn { color: var(--liora-gold); }

.rm-ghost {
    display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 0 16px;
    border-radius: 999px; background: var(--bg-tertiary); border: 1px solid var(--border-color); color: var(--text-normal);
    font-weight: 600; font-size: 14px; text-decoration: none; cursor: pointer; box-shadow: none; white-space: nowrap;
}
button.rm-ghost:hover:not(:disabled), a.rm-ghost:hover {
    background: var(--liora-gold-soft); border-color: var(--liora-gold); color: var(--header-primary); transform: none; box-shadow: none;
}
.rm-ghost[hidden], .rm-chip[hidden], .rm-check[hidden] { display: none; }
.rm-small { min-height: 34px; padding: 0 12px; font-size: 13px; }
.rm-danger { color: #ff8a8d; }
button.rm-danger:hover:not(:disabled) { background: rgba(242, 63, 67, 0.14); border-color: var(--status-danger); color: #ffb3b5; }
.rm-save {
    min-height: 46px; padding: 0 28px; border: 0; border-radius: 999px; font-weight: 700; font-size: 15px; color: #2a1800;
    background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong));
}
button.rm-save:hover:not(:disabled) { background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong)); filter: brightness(1.08); }
.rm-add { margin-top: 4px; }

.rm-list { margin-bottom: 8px; }
.rm-card { display: flex; gap: 14px; align-items: center; justify-content: space-between; flex-wrap: wrap; margin-bottom: 12px; }
.rm-card-open { border-color: var(--liora-gold); }
.rm-card-main { display: flex; flex-direction: column; gap: 4px; min-width: 0; flex: 1 1 260px; }
.rm-card-main strong { color: var(--header-primary); font-size: 16px; }
.rm-card-main small { color: var(--text-muted); font-size: 13px; }
.rm-card-icons { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; min-height: 20px; }
.rm-card-tools { display: flex; flex-wrap: wrap; gap: 8px; }

.rm-builder { margin-top: 18px; }
.rm-builder-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 16px; }
.rm-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 0 16px; }
.rm-grid .setting, .rm-grid .setting:last-child { margin-bottom: 16px; }
.rm-color { display: flex; gap: 8px; align-items: center; }
.rm-color input[type="color"], .rm-new-role input[type="color"] {
    flex: none; width: 46px; height: 40px; padding: 2px; border: 1px solid var(--border-color); border-radius: 8px;
    background: var(--bg-tertiary); cursor: pointer;
}
.rm-new-role input[type="color"]:disabled { opacity: 0.35; cursor: not-allowed; }

.rm-presets { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.rm-chip {
    display: inline-flex; align-items: center; gap: 6px; min-height: 38px; padding: 0 14px; border-radius: 999px;
    background: var(--bg-tertiary); border: 1px solid rgba(255, 184, 0, 0.35); color: var(--text-normal);
    font-weight: 600; font-size: 13px; box-shadow: none;
}
button.rm-chip:hover:not(:disabled) { background: var(--liora-gold-soft); border-color: var(--liora-gold); transform: none; box-shadow: none; }
.rm-chip:disabled { opacity: 0.4; }
.rm-chip-all { border-style: dashed; }

.rm-menu { border: 1px solid var(--border-color); border-radius: 12px; background: var(--bg-primary); margin-bottom: 10px; }
.rm-menu.rm-open { border-color: rgba(255, 184, 0, 0.45); }
.rm-menu-head { display: flex; align-items: center; gap: 10px; padding: 10px 12px; flex-wrap: wrap; }
.rm-menu-head .rm-menu-title { flex: 1 1 160px; min-width: 0; width: auto; font-weight: 600; }
.rm-count { color: var(--text-muted); font-size: 13px; white-space: nowrap; }
.rm-menu-tools { display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }
.rm-menu-body { padding: 14px 12px; border-top: 1px solid var(--border-color); }
.rm-group {
    display: flex; flex-direction: column; gap: 8px; padding: 12px; margin-bottom: 10px; border-radius: 10px;
    background: var(--bg-secondary); border: 1px solid var(--border-color);
}
.rm-group-head { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
.rm-group-head > input[type="text"] { flex: 1 1 220px; width: auto; }
.rm-check { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; color: var(--text-normal); cursor: pointer; }
.rm-group > .rm-ghost { align-self: flex-start; }
.rm-options { display: flex; flex-direction: column; gap: 6px; }
.rm-option { display: grid; grid-template-columns: 44px minmax(0, 1.1fr) minmax(0, 1fr) minmax(0, 1.3fr) 36px; gap: 6px; align-items: center; }
.rm-icon-btn {
    flex: none; width: 44px; height: 44px; padding: 0; border-radius: 10px; background: var(--bg-tertiary);
    border: 1px solid var(--border-color); display: grid; place-items: center; box-shadow: none;
}
button.rm-icon-btn:hover:not(:disabled) { background: var(--liora-gold-soft); border-color: var(--liora-gold); transform: none; box-shadow: none; }
.rm-plus { color: var(--text-muted); font-size: 20px; line-height: 1; }
.rm-uni { line-height: 1; }
.rm-role-btn {
    display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 44px; padding: 0 12px; border-radius: var(--radius-sm);
    background: var(--bg-tertiary); border: 1px solid var(--border-color); color: var(--text-normal); font-weight: 500;
    text-align: left; box-shadow: none;
}
button.rm-role-btn:hover:not(:disabled) { background: var(--liora-gold-soft); border-color: var(--liora-gold); transform: none; box-shadow: none; }
.rm-role-btn span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-role-btn em { flex: none; font-style: normal; font-size: 11px; font-weight: 700; color: #2a1800; background: var(--liora-gold); border-radius: 999px; padding: 1px 7px; }
.rm-dot { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--text-muted); }
.rm-x { width: 36px; height: 36px; padding: 0; border-radius: 50%; background: transparent; color: var(--text-muted); font-size: 20px; line-height: 1; box-shadow: none; }
button.rm-x:hover:not(:disabled) { background: rgba(242, 63, 67, 0.14); color: #ff8a8d; transform: none; box-shadow: none; }

.rm-preview { background: #313338; border-radius: 12px; padding: 16px; color: #dbdee1; font-size: 15px; overflow-x: auto; }
.rm-preview .rm-empty { color: #949ba4; margin: 10px 0 0; }
.rm-pv-embed { background: #2b2d31; border-left: 4px solid #ffb800; border-radius: 4px; padding: 12px 16px; max-width: 560px; }
.rm-pv-title { color: #fff; font-weight: 700; font-size: 16px; margin-bottom: 8px; overflow-wrap: anywhere; }
.rm-pv-desc { font-size: 14px; line-height: 1.4; margin-bottom: 10px; overflow-wrap: anywhere; }
.rm-pv-desc img, .rm-pv-fields img { vertical-align: -4px; }
.rm-pv-fields { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px 12px; }
.rm-pv-fields b { display: block; color: #fff; font-size: 13px; }
.rm-pv-fields span { font-size: 13px; overflow-wrap: anywhere; }
.rm-pv-foot { margin-top: 10px; font-size: 12px; color: #b5bac1; }
.rm-pv-btns { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
.rm-pv-row { display: flex; flex-wrap: wrap; gap: 8px; }
.rm-pv-btn { display: inline-flex; align-items: center; gap: 6px; border-radius: 8px; padding: 6px 14px; font-size: 14px; font-weight: 500; color: #fff; }
.rm-pv-grey { background: #4e5058; }
.rm-pv-blurple { background: #5865f2; }
.rm-pv-green { background: #248046; }
.rm-pv-red { background: #da373c; }

.rm-problems { margin: 16px 0 0; padding: 12px 14px; border-radius: 10px; border: 1px solid rgba(242, 63, 67, 0.4); background: rgba(242, 63, 67, 0.1); font-size: 14px; color: var(--text-normal); }
.rm-problems ul { margin: 0; padding-left: 18px; }
.rm-problems li { margin: 3px 0; }
#rm-fresh-wrap { display: flex; margin-top: 16px; }
#rm-fresh-wrap[hidden] { display: none; }
.rm-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; margin-top: 16px; }

.rm-dialog { position: fixed; inset: 0; z-index: 1300; display: grid; place-items: center; padding: 16px; background: rgba(0, 0, 0, 0.62); }
.rm-dialog[hidden] { display: none; }
.rm-dialog-box {
    width: min(560px, 100%); max-height: min(640px, calc(100vh - 32px)); max-height: min(640px, calc(100dvh - 32px));
    display: flex; flex-direction: column; gap: 10px; padding: 16px; border-radius: 16px; background: var(--bg-secondary);
    border: 1px solid rgba(255, 184, 0, 0.35); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.rm-dialog-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; color: var(--header-primary); font-size: 16px; }
.rm-dialog-quick { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.rm-inline { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--text-normal); }
.rm-inline[hidden] { display: none; }
.rm-inline input[type="text"] { width: 150px; }
.rm-picker-grid, .rm-role-list { flex: 1 1 auto; min-height: 120px; overflow-y: auto; }
.rm-picker-label { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.4px; color: var(--header-secondary); margin: 10px 0 6px; }
.rm-picker-label:first-child { margin-top: 0; }
.rm-picker-row { display: grid; grid-template-columns: repeat(auto-fill, minmax(46px, 1fr)); gap: 6px; }
.rm-picker-row button { height: 46px; padding: 0; border-radius: 10px; background: var(--bg-tertiary); display: grid; place-items: center; box-shadow: none; }
.rm-picker-row button:hover:not(:disabled) { background: var(--liora-gold-soft); transform: none; box-shadow: none; }
.rm-new-role { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; padding-bottom: 10px; border-bottom: 1px solid var(--border-color); }
.rm-new-role > input[type="text"] { flex: 1 1 180px; width: auto; }
.rm-role-row {
    display: flex; align-items: center; gap: 4px 10px; flex-wrap: wrap; width: 100%; min-height: 44px; padding: 6px 10px; margin: 0 0 4px;
    border-radius: 8px; background: transparent; color: var(--text-normal); text-align: left; font-weight: 500; box-shadow: none;
}
button.rm-role-row:hover:not(:disabled) { background: var(--liora-gold-soft); transform: none; box-shadow: none; }
.rm-role-row span { flex: 1 1 0; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rm-role-row small { flex-basis: 100%; padding-left: 22px; color: var(--text-muted); font-size: 12px; font-weight: 400; white-space: normal; }
.rm-role-row:disabled { opacity: 0.55; }

@media (max-width: 720px) {
    .rm-option {
        grid-template-columns: 44px minmax(0, 1fr) 36px; grid-template-areas: "icon role x" "label label label" "about about about";
        padding: 8px; border: 1px solid var(--border-color); border-radius: 10px;
    }
    .rm-option > :nth-child(1) { grid-area: icon; }
    .rm-option > :nth-child(2) { grid-area: role; }
    .rm-option > :nth-child(3) { grid-area: label; }
    .rm-option > :nth-child(4) { grid-area: about; }
    .rm-option > :nth-child(5) { grid-area: x; }
    .rm-menu-tools { margin-left: 0; width: 100%; }
    .rm-pv-fields { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .rm-actions .rm-save { width: 100%; }
    .rm-inline input[type="text"] { width: 120px; }
}
@media (prefers-reduced-motion: reduce) {
    .rm-ghost, .rm-chip, .rm-icon-btn, .rm-role-btn, .rm-save { transition: none; }
}

/* THE AI PAGE'S NOTE AND LOCK (2026-10-11) ------------------------------------
   Liora's AI is run and paid for by Bliss, so only Bliss or her Mother change its settings. Everyone else sees the
   page as it is, with a note saying why, and its controls locked (a disabled fieldset locks whatever is inside it,
   also the channel lists that are filled in later). */
.ai-owner-note {
    column-span: all; display: flex; gap: 12px; align-items: flex-start; margin: 0 0 20px; padding: 14px 16px;
    border-radius: var(--radius-md); background: var(--liora-gold-soft); border: 1px solid rgba(255, 184, 0, 0.4);
    color: var(--text-normal); font-size: 14px; line-height: 1.5; max-width: 820px;
}
.ai-owner-note .ico { flex: none; width: 22px; height: 22px; margin-top: 1px; }
.ai-owner-note p { margin: 0; }
.ai-owner-note strong { color: var(--header-primary); }
fieldset.ai-lock { border: 0; padding: 0; margin: 0 0 20px; min-width: 0; }
fieldset.ai-lock:last-child { margin-bottom: 0; }
fieldset.ai-lock:disabled .channel-drawer-header { cursor: default; }

/* LAYLA'S PAGE (2026-10-11) --------------------------------------------------- */
.layla-status { margin: 0 0 14px; font-size: 15px; color: var(--header-primary); }
.layla-invite {
    display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 0 22px; margin-bottom: 14px;
    border-radius: 999px; font-weight: 700; font-size: 15px; text-decoration: none; color: #2a1800;
    background: linear-gradient(135deg, var(--liora-gold), var(--liora-gold-strong));
}
.layla-invite[hidden] { display: none; }
.layla-invite:hover { filter: brightness(1.08); }
.layla-invite .ico { width: 20px; height: 20px; stroke: #2a1800; }
.layla-invite .ico .f { fill: rgba(42, 24, 0, 0.18); }
.layla-invite .ico .solid { fill: #2a1800; }
.layla-list { margin: 0; padding-left: 18px; color: var(--text-normal); font-size: 14px; line-height: 1.6; }
.layla-list li { margin-bottom: 6px; }
.layla-list code { background: var(--bg-tertiary); padding: 1px 6px; border-radius: 4px; }

/* THE HEARTHKEEPER THEME (2026-10-11) -----------------------------------------
   For supporters, the people keeping Liora running (utils/supporters.py). Her gold turns to the rose and ember of a
   fire that someone is tending: wine-dark walls, warm cream words, and the glow of a hearth breathing up from the
   bottom of the page. A look only: it changes nothing anyone can do. */
[data-theme="keeper"] {
    --bg-primary: #140b0d;
    --bg-secondary: rgba(31, 17, 20, 0.92);
    --bg-tertiary: #0c0607;
    --bg-floating: #170c0f;
    --header-primary: #ffeae2;
    --header-secondary: #e2b5a8;
    --text-normal: #f3ded7;
    --text-muted: #ad8d86;
    --text-link: #ffa27d;
    --interactive-normal: #d8a99c;
    --interactive-hover: #ffd5c7;
    --interactive-active: #fff2ec;
    --brand-experiment: #f0704f;
    --brand-hover: #ff8667;
    --brand-active: #d85a3b;
    --border-color: rgba(255, 138, 105, 0.2);
    --bg-modifier-hover: rgba(255, 138, 105, 0.09);
    --liora-gold: #ffa978;
    --liora-gold-strong: #ff6259;
    --liora-gold-soft: rgba(255, 150, 115, 0.18);
    --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.55);
    --shadow-lg: 0 8px 30px rgba(0, 0, 0, 0.6);
}
[data-theme="keeper"] body::after {
    content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
    background:
        radial-gradient(ellipse 75% 42% at calc(var(--sidebar-width) + (100% - var(--sidebar-width)) / 2) 108%, rgba(255, 112, 72, 0.20), transparent 70%),
        radial-gradient(ellipse 45% 30% at 100% 0%, rgba(255, 160, 175, 0.07), transparent 70%);
    animation: keeper-hearth 9s ease-in-out infinite;
}
@keyframes keeper-hearth { 0%, 100% { opacity: 0.75; } 50% { opacity: 1; } }
[data-theme="keeper"] .app-container { position: relative; z-index: 1; }
[data-theme="keeper"] #main-content { background: transparent; }
[data-theme="keeper"] #sidebar { background: rgba(17, 9, 11, 0.95); border-right: 1px solid rgba(255, 138, 105, 0.26); }
[data-theme="keeper"] .settings-card,
[data-theme="keeper"] .feature-card,
[data-theme="keeper"] .home-card { border-color: rgba(255, 138, 105, 0.22); }
[data-theme="keeper"] .settings-card:hover { border-color: rgba(255, 150, 115, 0.5); box-shadow: 0 0 0 1px rgba(255, 138, 105, 0.16), 0 0 26px rgba(255, 110, 80, 0.12); }
/* plain colours for the headings, not a gradient clipped to the letters: that would flatten the emojis in them */
[data-theme="keeper"] .settings-page h2 { color: #ffd9c6; }
[data-theme="keeper"] .settings-card:not(.feature-card) h3 { color: #ffb99d; border-bottom-color: rgba(255, 138, 105, 0.22); }
[data-theme="keeper"] .nav-category span { color: #ff9f86; }
[data-theme="keeper"] select:focus, [data-theme="keeper"] input:focus, [data-theme="keeper"] textarea:focus {
    border-color: #ff9d7c; box-shadow: 0 0 0 3px rgba(255, 138, 105, 0.25);
}
.keeper-thanks { display: flex; align-items: center; gap: 8px; margin-top: 8px; color: var(--liora-gold); }
.keeper-thanks[hidden] { display: none; }
.keeper-thanks .ico { flex: none; width: 18px; height: 18px; }
@media (prefers-reduced-motion: reduce) { [data-theme="keeper"] body::after { animation: none; } }
