    /* Floating launcher — tucked bottom-right, doesn't fight the agent
       chat widget which lives bottom-left. */
    .customize-fab {
        position: fixed; right: 18px; bottom: 18px; z-index: 60;
        width: 50px; height: 50px; border-radius: 50%;
        background: linear-gradient(135deg, #1a1a2e, #2c3e50);
        color: #fff; border: 0; cursor: pointer;
        font-size: 1.5rem; line-height: 50px; text-align: center;
        box-shadow: 0 6px 18px rgba(0,0,0,.25);
        transition: transform .15s, box-shadow .15s;
    }
    .customize-fab:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(0,0,0,.32); }

    /* Slide-in panel — anchored to right edge, fixed-position so it
       overlays content without pushing it. Covers ~360px wide; on
       small screens caps at viewport width minus 24px gutter. */
    .customize-panel {
        position: fixed;
        /* Anchor below the two-tier nav stack (world-nav + admin-nav)
           so navigation stays visible and interactive while the panel
           is open. --nav-stack-h is set on :root by admin-nav.jsp's
           syncHeights() and falls back to 106px (default 46+60). */
        top: var(--nav-stack-h, 106px);
        right: 0; bottom: 0;
        width: min(360px, calc(100vw - 24px));
        background: var(--card, #fff);
        color: var(--text, #1a1a2e);
        box-shadow: -8px 0 24px rgba(0,0,0,.18);
        /* z-index 95 sits below the nav stack (101/102) so the panel
           visually slides in *underneath* the bar — exactly as the
           user asked for. The backdrop drops to 94 to match. */
        z-index: 95;
        transform: translateX(110%);
        transition: transform .22s ease-out;
        overflow-y: auto;
        padding: 18px 20px 90px;
        border-left: 1px solid var(--border, #e2e8f0);
        /* CLOSED: pointer-events:none so the off-screen panel can't
           intercept clicks aimed at the Dashboard launcher / nav / page
           content on the right edge of the viewport. The previous build
           had pointer-events: auto by default which is what made the
           Dashboard popover appear "behind" — the click was actually
           landing on the invisible panel. */
        pointer-events: none;
    }
    .customize-panel.open { transform: translateX(0); pointer-events: auto; }
    /* Sticky header — title + close button stay pinned at the top of the
       panel even when the user scrolls through the long settings list.
       Bg matches the panel so content scrolls invisibly behind it. */
    .customize-panel .cp-header {
        position: sticky; top: 0; z-index: 2;
        margin: -18px -20px 8px;
        padding: 14px 20px 10px;
        background: var(--card, #fff);
        border-bottom: 1px solid var(--border, #e2e8f0);
        display: flex; align-items: flex-start; gap: 10px;
    }
    .customize-panel .cp-header-text { flex: 1; min-width: 0; }
    .customize-panel h3 {
        margin: 0 0 4px; font-size: 1.05rem; font-weight: 800;
        color: var(--text, #1a1a2e);
        display: flex; align-items: center; gap: 8px;
    }
    /* Secondary text in the panel is tied to --text (the same readable
       color the headers use), then dimmed via opacity for hierarchy.
       Using --text-muted directly was risky: when the panel sits on a
       dark mode card, --text-muted (#94a3b8) is technically light but
       can read as gray-on-gray and the user reported it as illegible.
       Opacity on --text guarantees contrast no matter which mode +
       text-color preset the user has active. */
    .customize-panel .cp-sub {
        color: var(--text, #1a1a2e); opacity: .78;
        font-size: .82rem; margin: 0 0 14px; line-height: 1.5;
    }
    .customize-panel .cp-header .cp-sub { margin: 0; }
    .customize-panel .cp-section {
        border-top: 1px solid var(--border, #e2e8f0);
        padding: 14px 0 10px;
    }
    .customize-panel .cp-section h4 {
        margin: 0 0 8px; font-size: .72rem; font-weight: 800;
        text-transform: uppercase; letter-spacing: .08em;
        color: var(--text, #1a1a2e); opacity: .85;
    }
    /* Close button is high-contrast against any mode (light: dark text on
       light pill; dark: light text on darker pill) and stays in the
       sticky header so it's always one click away. */
    .customize-panel .cp-close {
        flex-shrink: 0;
        width: 34px; height: 34px; border-radius: 50%;
        border: 1px solid var(--border, #cbd5e1);
        background: var(--soft-bg, #f8fafc);
        color: var(--text, #1a1a2e);
        cursor: pointer;
        font-size: 1.4rem; line-height: 1; padding: 0;
        display: inline-flex; align-items: center; justify-content: center;
        transition: background .15s, transform .15s, border-color .15s;
    }
    .customize-panel .cp-close:hover {
        background: var(--accent, #c8a951);
        border-color: var(--accent, #c8a951);
        color: #fff;
        transform: scale(1.05);
    }
    .customize-panel .cp-close:focus-visible {
        outline: 2px solid var(--accent, #c8a951);
        outline-offset: 2px;
    }

    /* Translucent backdrop behind the panel — clicking it closes the
       panel (mirrors the modal pattern used elsewhere on the site).
       Pointer-events:none until .open so the rest of the page stays
       interactive when the panel is closed. */
    .customize-backdrop {
        position: fixed;
        /* Backdrop ALSO starts below the nav stack so the world-nav and
           admin-nav stay visible and clickable while the panel is open
           — the user can navigate to a different page without first
           closing the panel. */
        top: var(--nav-stack-h, 106px);
        left: 0; right: 0; bottom: 0;
        background: rgba(0,0,0,.32);
        z-index: 94;
        opacity: 0;
        pointer-events: none;
        transition: opacity .22s ease-out;
    }
    .customize-backdrop.open {
        opacity: 1;
        pointer-events: auto;
    }

    /* Mode pills (Light / Dark / Auto) */
    .cp-mode-row { display: flex; gap: 6px; }
    .cp-mode-row button {
        flex: 1; padding: 8px 10px; border-radius: 8px;
        border: 1px solid var(--border, #cbd5e1); background: var(--card, #fff);
        color: var(--text, #1a1a2e); cursor: pointer; font: inherit;
        font-size: .85rem; font-weight: 700;
    }
    .cp-mode-row button.active {
        background: linear-gradient(135deg, #1a1a2e, #2c3e50); color: #fff; border-color: #1a1a2e;
    }

    /* Accent swatches — one circle per preset */
    .cp-swatches { display: flex; flex-wrap: wrap; gap: 8px; }
    .cp-swatch {
        width: 32px; height: 32px; border-radius: 50%;
        border: 2px solid transparent; cursor: pointer; padding: 0;
        box-shadow: 0 1px 3px rgba(0,0,0,.15);
        transition: transform .12s, box-shadow .12s;
    }
    .cp-swatch:hover { transform: scale(1.1); }
    .cp-swatch.active { border-color: var(--text, #1a1a2e); box-shadow: 0 0 0 2px var(--card, #fff), 0 0 0 4px var(--text, #1a1a2e); }

    .cp-cta {
        background: linear-gradient(135deg, #1a1a2e, #2c3e50);
        color: #fff; border: 0; border-radius: 8px;
        padding: 10px 14px; font: inherit; font-weight: 700;
        cursor: pointer; width: 100%; margin-top: 8px;
    }
    .cp-cta-soft {
        background: var(--card, #fff); color: var(--text, #1a1a2e);
        border: 1px solid var(--border, #cbd5e1);
        border-radius: 8px; padding: 8px 12px;
        font: inherit; font-weight: 700; cursor: pointer;
        width: 100%; margin-top: 6px; font-size: .88rem;
    }
    .cp-status { font-size: .78rem; color: var(--text-muted, #64748b); margin-top: 6px; min-height: 14px; }

    /* Theme presets — one-click "starter packs" that snap every knob
       (mode + accent + card style + card color + opacity + font + size
       + text color) to a known-good combination. Each chip previews its
       look via inline gradient + tiny accent dot. */
    .cp-preset-grid {
        display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    }
    .cp-preset {
        position: relative; cursor: pointer;
        border: 1px solid var(--border, #cbd5e1); border-radius: 10px;
        padding: 10px 12px; min-height: 64px;
        font: inherit; text-align: left; color: inherit;
        display: flex; flex-direction: column; gap: 2px;
        overflow: hidden;
        transition: transform .12s, box-shadow .12s, border-color .12s;
    }
    .cp-preset:hover { transform: translateY(-2px); box-shadow: 0 6px 16px rgba(0,0,0,.18); }
    .cp-preset.active { border-color: var(--accent, #c8a951); box-shadow: 0 0 0 2px var(--accent-soft, rgba(200,169,81,.25)); }
    .cp-preset-name { font-weight: 800; font-size: .82rem; color: inherit; position: relative; z-index: 1; }
    .cp-preset-tag  { font-size: .7rem; opacity: .75; position: relative; z-index: 1; }
    .cp-preset-dot {
        position: absolute; top: 8px; right: 10px;
        width: 10px; height: 10px; border-radius: 50%;
        box-shadow: 0 0 0 2px rgba(255,255,255,.6);
    }

    /* Text color swatches — same style as accent/card-color rows but
       slightly larger so visual contrast (which IS the property being
       picked) shows clearly through the swatch fill. */
    .cp-text-row { display: flex; flex-wrap: wrap; gap: 8px; }
    .cp-text-swatch {
        width: 38px; height: 38px; border-radius: 50%;
        border: 2px solid var(--border, #cbd5e1); cursor: pointer; padding: 0;
        font-weight: 800; font-size: .8rem;
        display: inline-flex; align-items: center; justify-content: center;
        transition: transform .12s;
    }
    .cp-text-swatch:hover { transform: scale(1.08); }
    .cp-text-swatch.active { border-color: var(--accent, #c8a951); box-shadow: 0 0 0 2px var(--accent-soft, rgba(200,169,81,.25)); }

    /* Reset / restore button is muted by default — destructive-ish but
       reversible. Lives next to Save in the footer section. */
    .cp-cta-reset {
        background: transparent; color: var(--text-muted, #64748b);
        border: 1px solid var(--border, #cbd5e1); border-radius: 8px;
        padding: 8px 12px; font: inherit; font-weight: 600; cursor: pointer;
        width: 100%; margin-top: 6px; font-size: .82rem;
    }
    .cp-cta-reset:hover { color: var(--text, #1a1a2e); border-color: var(--text-muted, #64748b); }

    /* Reorder mode: sections grow a dashed outline + grab cursor + the
       global drag-handle becomes visible. */
    body.dash-reorder-on .dash-section {
        outline: 2px dashed #c8a951;
        outline-offset: 4px;
        cursor: grab;
        position: relative;
    }
    body.dash-reorder-on .dash-section.dragging {
        opacity: .55; cursor: grabbing;
    }
    body.dash-reorder-on .dash-section::before {
        content: "⠿ drag to reorder";
        position: absolute; top: -10px; left: 8px; z-index: 4;
        background: #c8a951; color: #1a1a2e;
        font-size: .7rem; font-weight: 800; letter-spacing: .04em;
        padding: 2px 8px; border-radius: 999px;
        text-transform: uppercase;
    }
    body.dash-reorder-on .dash-section.drop-above {
        box-shadow: 0 -4px 0 0 #16a34a;
    }
    body.dash-reorder-on .dash-section.drop-below {
        box-shadow: 0 4px 0 0 #16a34a;
    }
