/* ==== css/base.css ==== */
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

/* ── SVG icon system ── */
svg.oul-icon {
    display: inline-block;
    width: 1em;
    height: 1em;
    vertical-align: -0.15em;
    flex-shrink: 0;
    overflow: visible;
    fill: currentColor;
    mix-blend-mode: var(--icon-blend, normal);
}

/* Semantic icon color utilities — apply to the wrapping element */
.icon-danger  { color: var(--danger-color,  #e74c3c); }
.icon-success { color: var(--success-color, #27ae60); }
.icon-warning { color: var(--warning-color, #f39c12); }
.icon-muted   { color: var(--text-muted,    #888);    }
.icon-primary { color: var(--primary-color, #111);    }
.icon-white   { color: #fff; }

oul-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* Prevent FOUC - hide screens before custom elements upgrade */
oul-screen:not(:defined) {
    display: none !important;
}

oul-screen:not([active]) {
    display: none !important;
}

:root {
    /* Primary Colors */
    /* --primary-color: #667eea;
    --primary-dark: #5568d3;
    --primary-darker: #4455b8;
    --primary-light: #e0e7ff;
    --primary-hover: #5568d3;
    --primary-shadow: rgba(102, 126, 234, 0.4);
    --primary-shadow-light: rgba(102, 126, 234, 0.1); */
    --primary-color: #111;
    --primary-dark: #090909;
    --primary-darker: #080808;
    --primary-light: #e0e0e0;
    --primary-hover: #222;
    --primary-shadow: rgba(100, 100, 100, 0.4);
    --primary-shadow-light: rgba(102, 102, 102, 0.1);

    /* Secondary Colors */
    --secondary-color: #444;
    --secondary-dark: #333;
    --secondary-light: #e0e0e0;

    /* Success Colors */
    --success-color: #27ae60;
    --success-dark: #219a52;
    --success-darker: #1e8449;
    --success-light: #dcfce7;
    --success-text: #166534;

    /* Danger Colors */
    --danger-color: #e74c3c;
    --danger-dark: #c0392b;
    --danger-darker: #a93226;
    --danger-light: #fee2e2;
    --danger-text: #991b1b;

    /* Warning Colors */
    --warning-color: #f39c12;
    --warning-dark: #d68910;
    --warning-light: #fef3c7;
    --warning-text: #92400e;

    /* Info Colors */
    --info-color: #3b82f6;
    --info-dark: #2563eb;
    --info-light: #e8f0fe;
    --info-text: #1d4ed8;

    /* Text Colors */
    --text-color: #333;
    --text-secondary: #555;
    --text-muted: #666;
    --text-light: #888;
    --text-lighter: #999;
    --text-placeholder: #aaa;
    --text-disabled: #bbb;
    --text-inverse: #fff;

    /* Background Colors */
    --bg-light: #f8f9fa;
    --bg-secondary: #f5f5f5;
    --bg-tertiary: #f0f0f0;
    --bg-white: #fff;
    --bg-dark: rgba(0, 0, 0, 0.2);
    --bg-overlay: rgba(0, 0, 0, 0.5);

    /* Border Colors */
    --border-color: #e0e0e0;
    --border-light: #e5e5e5;
    --border-focus: var(--primary-color);

    /* Shadows */
    --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.1);
    --shadow-md: 0 4px 12px rgba(0, 0, 0, 0.1);
    --shadow-lg: 0 10px 40px rgba(0, 0, 0, 0.1);
    --shadow-focus: 0 0 0 3px var(--primary-shadow-light);

    /* Border Radius */
    --radius-sm: 6px;
    --radius-md: 8px;
    --radius-lg: 12px;
    --radius-round: 50%;

    /* Badge Colors */
    --badge-public: #4caf50;
    --badge-hyper-public: #2196f3;
    --badge-shared: #ff9800;

    /* Map Colors */
    --map-marker-bg: #3b82f6;
    --map-bg: #f0f0f0;

    /* Slider Colors */
    --slider-track: #e0e0e0;
    --slider-thumb: var(--primary-color);
    --slider-disabled: #ccc;

    /* Status Window */
    --status-window-bg: rgba(30, 30, 40, 0.95);

    /* Z-Index Scale */
    --z-base: 1;
    --z-controls: 100;
    --z-header: 1000;
    --z-overlay: 2000;
    --z-panel: 9000;
    --z-modal: 10000;
    --z-top: 10001;

    /* Typography Scale */
    --text-xs: 11px;
    --text-sm: 12px;
    --text-base: 14px;
    --text-md: 16px;
    --text-lg: 18px;
    --text-xl: 20px;
    --text-2xl: 24px;
    --text-3xl: 32px;

    /* Extra Radius */
    --radius-xs: 4px;
    --radius-pill: 20px;

    /* Spacing Scale (base-4) */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-8: 32px;
    --space-10: 40px;
    --space-12: 48px;

    /* Motion */
    --duration-fast: 0.15s;
    --duration-normal: 0.2s;
    --duration-slow: 0.3s;
    --easing-default: ease;
    --easing-smooth: cubic-bezier(0.4, 0, 0.2, 1);

    /* Typography — fill scale gaps */
    --text-sm2: 13px;
    /* between --text-sm (12px) and --text-base (14px) */
    --text-md2: 15px;
    /* between --text-base (14px) and --text-md (16px)  */
}

/* ═══════════════════════════════════════════════════════════════════════════
   BASE & LAYOUT
   ═══════════════════════════════════════════════════════════════════════════ */
body {
    font-family: var(--font-body, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif);
    /* --app-bg is set by ProjectTheme when a background preset is chosen;
       otherwise the brand gradient shows. */
    background: var(--app-bg, linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%));
    background-attachment: var(--app-bg-attach, scroll);
    background-size: var(--app-bg-size, auto);
    color: var(--text-color);
    min-height: 100vh;
    /* Top inset included too: on iOS, @capacitor/status-bar's overlaysWebView:
       false positions the webview below the status bar so this resolves to 0
       (no-op) — but Android 15+ forces edge-to-edge and ignores that plugin's
       deprecated flags, so the WebView is always edge-to-edge there and needs
       a real top inset. Other sides cover landscape notches and the home
       indicator on both platforms. */
    padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}


/* ═══ Text selection & long-press callout ═══
   This is a native-feeling app UI, not a document — accidental text selection
   on buttons, list rows, and menus (especially the long-press that also opens
   a context menu on mobile) reads as a bug. Suppress selection + the iOS
   touch-callout app-wide by default, then RE-ENABLE it only for genuinely
   selectable content below. Applied to #app (not html/body) so DevTools and
   any injected print frames are unaffected. */
#app,
oul-screen {
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

/* Opt back IN for real text: form fields the user types/edits into, anything
   explicitly marked selectable, and the admin API-key block (which relies on
   user-select: all for one-tap copy). */
input,
textarea,
[contenteditable="true"],
.selectable,
.user-select-text {
    -webkit-user-select: text;
    user-select: text;
    -webkit-touch-callout: default;
}

/* Project display font for headings & panel/dialog titles (themeable) */
h1,
h2,
h3,
h4,
.admin-panel-title,
.docs-header-title,
.sounds-explorer-title {
    font-family: var(--font-display, inherit);
}

/* Themeable edge/border on primary surfaces (radius is handled by the
   --radius-* tokens, which already cascade to all components). */
.admin-panel,
.sounds-explorer,
.dse-source-card {
    border: var(--panel-border, none);
}

body.map-active {
    overflow: hidden;
    position: fixed;
    width: 100%;
}

#app {
    min-height: 100vh;
}

/* App Title for login screen */
.app-title {
    color: var(--text-inverse);
    font-size: 32px;
    margin-bottom: 20px;
    text-align: center;
}

.logo {
    font-size: 80px;
    margin-bottom: 40px;
    text-align: center;
}

/* Login screen logo image */
.login-logo {
    display: block;
    width: min(150px, 50vw);
    height: auto;
    margin: 0 auto 10px;
    opacity: 0.9;
}

/* ═══ Context menu (right-click / long-press) ═══ */
.context-menu {
    position: fixed;
    /* Above full-screen panels/screens (e.g. the sounds explorer at --z-top
       10001) so the menu is never hidden behind them. */
    z-index: 100001;
    min-width: 180px;
    max-width: 260px;
    padding: 6px;
    background: var(--bg-white, #fff);
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-md, 8px);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.22);
    font-size: var(--text-base, 14px);
    user-select: none;
}

.context-menu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    border: none;
    background: none;
    text-align: left;
    color: var(--text-color, #111);
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
    font-size: inherit;
    line-height: 1.2;
}

.context-menu-item:hover:not(.disabled) {
    background: var(--bg-tertiary, #f0f0f0);
}

.context-menu-item.danger {
    color: var(--danger-color, #c62828);
}

.context-menu-item.danger:hover:not(.disabled) {
    background: rgba(198, 40, 40, 0.1);
}

.context-menu-item.disabled {
    opacity: 0.45;
    cursor: default;
}

.context-menu-icon {
    width: 18px;
    text-align: center;
    flex-shrink: 0;
}

.context-menu-label {
    flex: 1;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.context-menu-sep {
    height: 1px;
    margin: 5px 6px;
    background: var(--border-color, #e0e0e0);
}

/* ═══ Zone picker modal ═══ */
.zone-picker-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal, 10000);
    display: none;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    padding: 16px;
}

.zone-picker {
    background: var(--bg-white, #fff);
    width: min(480px, 100%);
    max-height: min(80vh, 640px);
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg, 12px);
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.2));
    overflow: hidden;
}

.zone-picker-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px;
    background: linear-gradient(135deg, var(--primary-color, #111) 0%, var(--secondary-color, #222) 100%);
    color: var(--text-inverse, #fff);
}

.zone-picker-title {
    margin: 0;
    font-size: var(--text-lg, 18px);
}

.zone-picker-close {
    background: rgba(255, 255, 255, 0.2);
    border: none;
    color: inherit;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-round, 50%);
    cursor: pointer;
}

.zone-picker-toolbar {
    display: flex;
    gap: 10px;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.zone-picker-search {
    flex: 1;
    padding: 8px 10px;
    border: 1px solid var(--border-color, #ddd);
    border-radius: var(--radius-sm, 6px);
    font-size: var(--text-base, 14px);
}

.zone-picker-all {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-sm, 12px);
    white-space: nowrap;
    cursor: pointer;
}

.zone-picker-list {
    flex: 1;
    overflow-y: auto;
    padding: 6px;
    -webkit-overflow-scrolling: touch;
}

.zone-picker-list.is-disabled {
    opacity: 0.4;
    pointer-events: none;
}

.zone-picker-empty {
    color: var(--text-secondary, #777);
    text-align: center;
    padding: 24px;
}

.zone-picker-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 10px;
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
}

.zone-picker-item:hover {
    background: var(--bg-tertiary, #f0f0f0);
}

.zone-picker-item.is-off {
    opacity: 0.6;
}

.zone-picker-type {
    width: 22px;
    text-align: center;
    flex-shrink: 0;
}

.zone-picker-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.zone-picker-name {
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.zone-picker-meta {
    font-size: var(--text-xs, 11px);
    color: var(--text-secondary, #777);
}

.zone-picker-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    border-top: 1px solid var(--border-color, #eee);
}

.zone-picker-count {
    font-size: var(--text-sm, 12px);
    color: var(--text-secondary, #777);
}

.zone-picker-actions {
    display: flex;
    gap: 8px;
}

.choose-zones-btn {
    margin-top: 6px;
    padding: 6px 10px;
    font-size: var(--text-sm, 12px);
    border: 1px solid var(--border-color, #ddd);
    background: var(--bg-white, #fff);
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
}

.choose-zones-btn:hover {
    background: var(--bg-tertiary, #f0f0f0);
}

/* ═══ Zone bulk grid editor ═══ */
.zbe-overlay {
    position: fixed;
    inset: 0;
    z-index: var(--z-modal, 10000);
    display: none;
    align-items: stretch;
    justify-content: center;
    background: rgba(0, 0, 0, 0.5);
    padding: 12px;
}

.zbe-panel {
    background: var(--bg-white, #fff);
    width: min(1100px, 100%);
    max-height: 100%;
    display: flex;
    flex-direction: column;
    border-radius: var(--radius-lg, 12px);
    overflow: hidden;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.2));
}

.zbe-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 12px 16px;
    background: linear-gradient(135deg, var(--primary-color, #111) 0%, var(--secondary-color, #222) 100%);
    color: var(--text-inverse, #fff);
}

.zbe-title {
    margin: 0;
    font-size: var(--text-lg, 18px);
}

.zbe-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.zbe-dirty-count {
    font-size: var(--text-sm, 12px);
    opacity: 0.9;
}

.zbe-close {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    min-width: 30px;
    padding: 0;
    line-height: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.2);
    border: none;
    color: inherit;
    border-radius: var(--radius-round, 50%);
    cursor: pointer;
}

.zbe-apply-bar {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-color, #eee);
    background: var(--bg-light, #f8f9fa);
    font-size: var(--text-sm, 12px);
}

.zbe-sel-count {
    color: var(--text-secondary, #666);
    font-weight: 500;
}

.zbe-apply-group {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.zbe-apply-field,
.zbe-apply-input {
    padding: 5px 8px;
    border: 1px solid var(--border-color, #ddd);
    border-radius: var(--radius-xs, 4px);
    font-size: var(--text-sm, 12px);
}

.zbe-apply-bool {
    display: flex;
    align-items: center;
    gap: 6px;
}

.zbe-table-wrap {
    flex: 1;
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

/* Size to content (with a floor of the container width) so the grid scrolls
   horizontally rather than squishing all columns into the window. */
.zbe-table {
    border-collapse: collapse;
    width: max-content;
    min-width: 100%;
    font-size: var(--text-sm, 12px);
}

.zbe-table th,
.zbe-table td {
    border: 1px solid var(--border-color, #eee);
    padding: 4px 6px;
    text-align: left;
    white-space: nowrap;
}

.zbe-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--bg-tertiary, #f0f0f0);
    font-weight: 600;
}

.zbe-table tbody tr:nth-child(even) {
    background: var(--bg-light, #fafafa);
}

.zbe-sel-col {
    width: 28px;
    text-align: center;
}

.zbe-in {
    box-sizing: border-box;
    padding: 3px 5px;
    border: 1px solid transparent;
    background: transparent;
    border-radius: var(--radius-xs, 4px);
    font-size: inherit;
}

.zbe-in:focus {
    border-color: var(--primary-color, #111);
    background: var(--bg-white, #fff);
    outline: none;
}

.zbe-in[type="text"] {
    min-width: 160px;
    width: 100%;
}

.zbe-table select.zbe-in {
    min-width: 130px;
}

.zbe-num {
    width: 72px;
}

.zbe-in[type="checkbox"] {
    width: auto;
}

.zbe-in.is-dirty,
.is-dirty {
    background: #fff7e0;
    border-color: #f0c040;
}

.zbe-ro {
    color: var(--text-secondary, #777);
}

/* ═══ Mobile map-header & path-list tweaks ═══ */
/* Keep map-header button labels on one line so all buttons match height (the 📡
   broadcast button was shorter than the wrapping text buttons). white-space is
   an inherited property, so it crosses into the oul-button shadow DOM. */
#map-header oul-button {
    white-space: nowrap;
}

@media (max-width: 640px) {

    /* Print is rarely used on mobile — hide it on the map screen */
    #map-header #print-map-btn {
        display: none;
    }

    /* Path list rows: hide length + date (and their separators) on mobile */
    .path-meta .pm-dist,
    .path-meta .pm-date,
    .path-meta .pm-sep {
        display: none;
    }
}

/* ═══ App loading overlay ═══ */
/* Takes over from the native launch screen (resources/splash.svg), so it
   matches it exactly: the same solid #111 and the logo at the same size and
   place. The splash is a square scaled to FILL the screen, which makes its
   logo 625/2732 of the screen's longer side, centred. The title and spinner
   hang below the logo without moving it. Not themed: the project's colours
   are applied while this is still up, and the splash has none. */
#app-loading-overlay {
    position: fixed;
    inset: 0;
    z-index: 100000;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #111111;
    transition: opacity 0.4s ease;
}

#app-loading-overlay.hidden {
    opacity: 0;
    pointer-events: none;
}

.app-loading-inner {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
}

.app-loading-logo {
    display: block;
    /* = the splash's logo; capped for desktop browsers, which have no splash */
    width: min(320px, calc(625 / 2732 * max(100vw, 100vh)));
    height: auto;
}

.app-loading-below {
    position: absolute;
    top: calc(100% + 22px);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 22px;
    white-space: nowrap;
}

.app-loading-title {
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--text-lg, 18px);
    letter-spacing: 0.5px;
}

.app-loading-spinner {
    width: 32px;
    height: 32px;
    border: 3px solid rgba(255, 255, 255, 0.25);
    border-top-color: #fff;
    border-radius: 50%;
    animation: app-loading-spin 0.8s linear infinite;
}

@keyframes app-loading-spin {
    to {
        transform: rotate(360deg);
    }
}

/* Button row helper */
.button-row {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 15px;
}

.button-row>* {
    flex: 1;
    min-width: 120px;
}

/* Section header row */
.section-header-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
}

.section-header-row h4 {
    margin: 0;
    color: var(--text-color);
}

/* Legacy screen support */
.screen {
    display: none;
    min-height: 100vh;
}

.screen.active {
    display: block;
}

.container {
    display: flex;
    flex-direction: column;
    gap: 10px;
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
}

/* Header */
.header {
    background: var(--bg-dark);
    padding: 15px 20px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    color: var(--text-inverse);
}

.header h2 {
    margin: 0;
    font-size: var(--text-2xl);
    font-weight: 700;
}

/* ═══════════════════════════════════════════════════════════════════════════
   LOGIN SCREEN
   ═══════════════════════════════════════════════════════════════════════════ */
/* Login Screen */
#login-screen {
    display: flex;
    align-items: center;
    justify-content: center;
}

#login-screen .container {
    text-align: center;
}

#login-screen h1 {
    color: var(--text-inverse);
    font-size: 32px;
    margin-bottom: 20px;
}

.logo {
    font-size: 80px;
    margin-bottom: 40px;
}

#login-form {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    padding: 30px;
    box-shadow: var(--shadow-lg);
}

/* ═══════════════════════════════════════════════════════════════════════════
   FORMS & INPUTS
   ═══════════════════════════════════════════════════════════════════════════ */
/* Form Elements */
.form-group {
    margin-bottom: 20px;
    text-align: left;
}

.form-group label {
    display: block;
    margin-bottom: 8px;
    font-weight: 600;
    color: var(--text-secondary);
}

.form-group input[type="text"],
.form-group input[type="password"],
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 12px;
    border: 2px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--text-md);
    transition: border-color var(--duration-slow) var(--easing-default);
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--primary-color);
}

.form-group.checkbox {
    display: flex;
    align-items: center;
}

.form-group.checkbox label {
    margin: 0;
    display: flex;
    align-items: center;
    cursor: pointer;
}

.form-group.checkbox input {
    width: auto;
    margin-right: 8px;
    cursor: pointer;
}

/* ═══════════════════════════════════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════════════════════════════════ */
/* ─── BUTTONS ─────────────────────────────────────────────────────────────────
 * Two button systems coexist in the app:
 *   <oul-button>   — web component; use for editors, forms, modal footers.
 *                    Supports loading state. Prefer this for new code.
 *   .btn           — plain CSS; use for legacy/inline HTML outside web
 *                    components. New code should prefer <oul-button>.
 *
 * Sizes: default (12px/24px) · .btn-sm (4px/10px, tightest) · .btn-small (6px/12px)
 * ──────────────────────────────────────────────────────────────────────────── */
.btn {
    padding: 12px 24px;
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--text-md);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--duration-slow) var(--easing-default);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    text-align: center;
}

.btn:focus-visible {
    outline: 3px solid var(--primary-color);
    outline-offset: 2px;
}

.btn:disabled {
    opacity: 0.55;
    cursor: not-allowed;
    pointer-events: none;
}

.btn-primary {
    background: var(--primary-color);
    color: var(--text-inverse);
    width: 100%;
}

.btn-primary:hover:not(:disabled),
.btn-primary:active:not(:disabled) {
    background: var(--primary-hover);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px var(--primary-shadow);
}

.btn-secondary {
    background: var(--bg-tertiary);
    color: var(--text-color);
}

.btn-secondary:hover:not(:disabled),
.btn-secondary:active:not(:disabled) {
    background: var(--border-color);
}

.btn-danger {
    background: var(--danger-color);
    color: var(--text-inverse);
}

.btn-danger:hover:not(:disabled),
.btn-danger:active:not(:disabled) {
    background: var(--danger-dark);
}

.btn-success {
    background: var(--success-color);
    color: var(--text-inverse);
}

.btn-success:hover:not(:disabled) {
    background: var(--success-dark);
}

.btn-warning {
    background: var(--warning-color);
    color: var(--text-inverse);
}

.btn-warning:hover:not(:disabled) {
    background: var(--warning-dark);
}

/* .btn-small — compact variant (6px/12px). Alias: .btn-sm is even tighter (4px/10px). */
.btn-small {
    padding: 6px 12px;
    font-size: var(--text-sm);
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-weight: 600;
    transition: background var(--duration-normal) var(--easing-default);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
}

.btn-small:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* .btn-sm — ultra-compact (4px/10px). Use inside dense list rows. */
.btn-sm {
    padding: 4px 10px;
    font-size: var(--text-sm);
}

.btn .icon {
    margin-right: 5px;
}


/* ── Captions (access provision — docs/SUBTITLES_PLAN.md) ────────────────────
   Broadcast-style: bottom-third, high-contrast box per line, max two lines
   (the engine enforces the count). Sound descriptions render italic. */
#caption-overlay {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: calc(env(safe-area-inset-bottom, 0px) + 84px);
    z-index: 1200;
    display: none;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    max-width: min(92vw, 640px);
    pointer-events: none;
}

#caption-overlay.visible { display: flex; }

.caption-line {
    background: rgba(0, 0, 0, 0.82);
    color: #fff;
    font-size: 17px;
    line-height: 1.35;
    padding: 4px 12px;
    border-radius: 4px;
    text-align: center;
    text-wrap: balance;
}

.caption-sd { font-style: italic; opacity: 0.92; }

/* Broadcast zones: slow marching-ants outline (#18 chosen vocabulary) */
@keyframes oul-march { to { stroke-dashoffset: -20; } }
.oul-march { animation: oul-march 2.8s linear infinite; }

/* ==== css/screens.css ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   MESSAGES & ALERTS
   ═══════════════════════════════════════════════════════════════════════════ */
/* Messages */
.error-message {
    color: var(--danger-color);
    margin-top: 15px;
    padding: 10px;
    border-radius: var(--radius-sm);
    background: var(--danger-light);
    display: none;
}

.error-message.show {
    display: block;
}

.success-message {
    color: var(--success-color);
    margin-top: 15px;
    padding: 10px;
    border-radius: var(--radius-sm);
    background: var(--success-light);
    display: none;
}

.success-message.show {
    display: block;
}

.status-message {
    color: var(--primary-color);
    margin-top: 15px;
    font-size: var(--text-base);
}

/* Main Screen */
#main-screen .container {
    padding-top: 0;
}

/* Scrollable content area — grows to fill space below the sticky app-bar */
#main-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior-y: contain;
}

/* Lock background scroll while any panel/form is open.
   Without this, iOS keyboard focus or accidental swipes shift the scroll
   position behind the panel, leaving the app-bar out of view on close. */
body.panel-open #main-scroll {
    overflow: hidden;
}

/* Pull-to-refresh indicator — lives in the sticky slot, hidden by default */
#ptr-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 0;
    overflow: hidden;
    background: var(--bg-surface, #f5f5f5);
    font-size: 13px;
    color: var(--text-muted, #888);
    transition: height 0.15s ease;
    pointer-events: none;
}

#ptr-indicator.ptr-pulling {
    height: 44px;
}

#ptr-indicator.ptr-ready {
    height: 44px;
    color: var(--primary-color, #4a90e2);
}

#ptr-indicator.ptr-loading {
    height: 44px;
}

.ptr-arrow {
    display: inline-block;
    transition: transform 0.2s ease;
    font-size: 16px;
}

#ptr-indicator.ptr-ready .ptr-arrow {
    transform: rotate(180deg);
}

#ptr-indicator.ptr-loading .ptr-arrow {
    display: none;
}

#ptr-indicator.ptr-loading::before {
    content: '';
    width: 16px;
    height: 16px;
    border: 2px solid var(--primary-color, #4a90e2);
    border-top-color: transparent;
    border-radius: 50%;
    animation: ptr-spin 0.6s linear infinite;
}

@keyframes ptr-spin {
    to {
        transform: rotate(360deg);
    }
}

.user-info {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    padding: 20px;
    margin-top: 20px;
    box-shadow: var(--shadow-md);
}

.user-info h3 {
    margin-bottom: 5px;
    color: var(--primary-color);
}

.user-info p {
    color: var(--text-muted);
    font-size: var(--text-base);
}

/* Sections */
.section {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    padding: 20px;
    margin-top: 20px;
    box-shadow: var(--shadow-md);
}

.section h3 {
    margin-bottom: 20px;
    color: var(--text-color);
}

/* ═══════════════════════════════════════════════════════════════════════════
   UPLOAD
   ═══════════════════════════════════════════════════════════════════════════ */
/* Upload Area */
.upload-area {
    /* display: flex; */
    display: grid;
    grid-auto-flow: column;
    justify-content: center;
    gap: 10px;
    margin-bottom: 20px;
    /* flex-wrap: nowrap; */
}

.upload-area .btn {
    flex: 1;
    min-width: 140px;
}

.sounds-action-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    margin-bottom: 16px;
    justify-items: center;
    width: min-content;
    margin: 0 auto 16px auto;
}

@media (max-width: 600px) {
    .sounds-action-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    #open-sounds-explorer {
        grid-column: span 2;
        width: 100%;

        >button {
            width: inherit;
        }
    }

}


.tab-action-grid {
    display: grid;
    grid-auto-flow: column;
    align-items: stretch;
    gap: 8px;
    margin-bottom: 12px;
    justify-content: end;
}


.new-pool-inline-btn {
    display: block;
    width: 100%;
    margin-bottom: 8px;
    text-align: center;
}

.file-info {
    background: var(--bg-light);
    padding: 15px;
    border-radius: var(--radius-md);
    margin-bottom: 20px;
}

.file-info p {
    margin: 5px 0;
    font-size: var(--text-base);
}

/* ═══════════════════════════════════════════════════════════════════════════
   BATCH UPLOAD
   ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Batch upload ───────────────────────────────────────────── */
.batch-upload-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}

.batch-file-count {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-color);
}

.batch-clear-btn {
    background: none;
    border: none;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    cursor: pointer;
    padding: 2px 6px;
    border-radius: var(--radius-xs);
}

.batch-clear-btn:hover {
    color: var(--danger-color);
    background: var(--danger-light);
}

/* File list */
.batch-file-list {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    margin-bottom: 12px;
    overflow: hidden;
}

.batch-file-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-white);
}

.batch-file-row:last-child {
    border-bottom: none;
}

.batch-file-row:nth-child(even) {
    background: var(--bg-secondary);
}

.batch-file-info {
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    flex: 0 0 160px;
}

.batch-file-icon {
    font-size: var(--text-base);
    flex-shrink: 0;
}

.batch-file-details {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.batch-file-name {
    font-size: var(--text-sm);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 120px;
}

.batch-file-size {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.batch-title-input {
    flex: 1;
    min-width: 0;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    padding: 5px 8px;
    font-size: var(--text-sm);
    background: var(--bg-white);
    color: var(--text-color);
}

.batch-title-input:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 2px var(--primary-shadow-light);
}

.batch-remove-btn {
    flex-shrink: 0;
    background: none;
    border: none;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: var(--text-sm);
    padding: 4px 6px;
    border-radius: var(--radius-xs);
    line-height: 1;
}

.batch-remove-btn:hover {
    color: var(--danger-color);
    background: var(--danger-light);
}

/* Shared options */
.batch-shared-options {
    margin-top: 4px;
}

/* Progress area */
.batch-progress-header {
    margin-bottom: 8px;
}

.batch-progress-label {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-color);
}

.batch-status-list {
    margin-top: 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.batch-status-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    font-size: var(--text-sm);
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-white);
    transition: background var(--duration-fast);
}

.batch-status-row:last-child {
    border-bottom: none;
}

.batch-status-row.batch-status-uploading {
    background: #eff6ff;
}

.batch-status-row.batch-status-done {
    background: #f0fdf4;
}

.batch-status-row.batch-status-errored {
    background: var(--danger-light);
}

.batch-status-icon {
    flex-shrink: 0;
}

.batch-status-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.batch-status-msg {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.batch-status-error {
    color: var(--danger-color);
}

@keyframes pulse {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.5;
    }
}

/* Progress */
.progress-container {
    margin-top: 20px;
}

.progress-bar {
    width: 100%;
    height: 30px;
    background: var(--border-color);
    border-radius: var(--radius-pill);
    overflow: hidden;
    margin-bottom: 10px;
}

.progress-fill {
    height: 100%;
    background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
    transition: width var(--duration-slow) var(--easing-default);
    width: 0%;
}

#progress-text {
    text-align: center;
    color: var(--text-muted);
    font-size: var(--text-base);
}

/* ═══════════════════════════════════════════════════════════════════════════
   SOUNDS LIST (legacy)
   ═══════════════════════════════════════════════════════════════════════════ */
/* Sounds List */
.sounds-list {
    max-height: 400px;
    overflow-y: auto;
}

.sound-item {
    background: var(--bg-light);
    padding: 15px;
    border-radius: var(--radius-md);
    margin-bottom: 10px;
    border-left: 4px solid var(--primary-color);
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 15px;
}

.sound-item-content {
    flex: 1;
}

.sound-item-actions {
    display: flex;
    gap: 8px;
    flex-shrink: 0;
}

.play-sound-btn.playing {
    background: var(--danger-color);
    border-color: var(--danger-color);
}

.play-sound-btn.playing:hover {
    background: var(--danger-dark);
    border-color: var(--danger-dark);
}

.play-sound-btn.downloading {
    opacity: 0.6;
    cursor: not-allowed;
}

.sound-item h4 {
    margin-bottom: 5px;
    color: var(--text-color);
}

.sound-item p {
    margin: 3px 0;
    font-size: var(--text-base);
    color: var(--text-muted);
}

.sound-item .tags {
    margin-top: 8px;
}

.tag {
    display: inline-block;
    background: var(--primary-color);
    color: var(--text-inverse);
    padding: 4px 10px;
    border-radius: var(--radius-lg);
    font-size: var(--text-sm);
    margin-right: 5px;
    margin-top: 5px;
}

.loading {
    text-align: center;
    color: var(--text-muted);
    padding: 20px;
}

/* Project Info */
.project-info {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    padding: 15px;
    margin-top: 10px;
}

.project-info p {
    margin-bottom: 10px;
}

.info-text {
    color: var(--text-muted);
    text-align: center;
}

/* Shared form field label / native select used outside oul-components */
.form-field-label {
    display: block;
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--text-color);
}

.form-field-optional {
    font-weight: 400;
    color: var(--text-secondary);
}

.form-select-native {
    width: 100%;
    padding: 8px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-white);
    color: var(--text-color);
    font-size: var(--text-sm);
    appearance: auto;
}

/* Project Statistics Cards */
.stats-summary {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}

.stat-card {
    padding: 16px;
    border-radius: var(--radius-md);
    text-align: center;
}

.stat-card--primary {
    background: var(--primary-light, #e0e7ff);
}

.stat-card--success {
    background: var(--success-light, #dcfce7);
}

.stat-card--danger {
    background: var(--danger-light, #fff5f5);
}

.stat-card-value {
    font-size: 28px;
    font-weight: 700;
    line-height: 1;
    margin-bottom: 4px;
}

.stat-card--primary .stat-card-value {
    color: var(--primary-color);
}

.stat-card--success .stat-card-value {
    color: var(--success-color, #48bb78);
}

.stat-card--danger .stat-card-value {
    color: var(--danger-color);
}

.stat-card-label {
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.stats-section-heading {
    margin: 16px 0 8px;
    font-size: var(--text-base);
    color: var(--text-color);
}

/* ═══════════════════════════════════════════════════════════════════════════
   ZONES
   ═══════════════════════════════════════════════════════════════════════════ */
/* Zones Section */
.zones-section {
    margin-top: 15px;
}

.zones-section h4 {
    margin-bottom: 10px;
    color: var(--text-color);
}

.zones-list {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    padding: 10px;
}

.zone-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px;
    background: var(--bg-light);
    border-radius: var(--radius-sm);
    margin-bottom: 8px;
    border-left: 3px solid var(--primary-color);
}

.zone-item-info {
    flex: 1;
}

.zone-item-info h5 {
    margin: 0 0 5px 0;
    color: var(--text-color);
    font-size: var(--text-base);
}

.zone-item-info p {
    margin: 0;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.zone-sound-name {
    margin-top: 5px !important;
    color: var(--primary-color) !important;
    font-weight: 500;
}

.zone-item-actions {
    display: flex;
    gap: 8px;
    align-items: center;
}

/* Modal */
.modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: var(--bg-overlay);
    z-index: var(--z-header);
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.modal-content {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    width: 100%;
    max-width: 600px;
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    border-bottom: 1px solid var(--border-color);
}

.modal-header h3 {
    margin: 0;
}

.btn-close {
    background: none;
    border: none;
    font-size: 28px;
    color: var(--text-lighter);
    cursor: pointer;
    padding: 0;
    width: 30px;
    height: 30px;
    line-height: 1;
}

.btn-close:hover {
    color: var(--text-color);
}

.modal-body {
    padding: 20px;
    overflow-y: auto;
}

/* Tabs */
.project-tabs {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
}

.tab-btn {
    flex: 1;
    padding: 10px;
    background: var(--bg-secondary);
    border: none;
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--duration-slow);
}

.tab-btn.active {
    background: var(--primary-color);
    color: var(--text-inverse);
}

.tab-content {
    display: none;
}

.tab-content.active {
    display: block;
}

/* Projects List */
.projects-list {
    max-height: 400px;
    overflow-y: auto;
}

.project-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 15px;
    background: var(--bg-light);
    border-radius: var(--radius-md);
    margin-bottom: 10px;
    transition: all var(--duration-slow);
}

.project-item:hover {
    background: var(--bg-tertiary);
}

.project-item.active {
    background: var(--info-light);
    border: 2px solid var(--primary-color);
}

.project-item-info h4 {
    margin: 0 0 5px 0;
    color: var(--text-color);
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.project-date {
    font-size: var(--text-sm);
    color: var(--text-lighter);
    margin: 0;
}

/* Badges */
.badge {
    display: inline-block;
    padding: 3px 8px;
    font-size: var(--text-xs);
    font-weight: 600;
    border-radius: var(--radius-lg);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.badge-public {
    background: var(--badge-public);
    color: var(--text-inverse);
}

.badge-hyper-public {
    background: var(--badge-hyper-public);
    color: var(--text-inverse);
}

.badge-shared {
    background: var(--badge-shared);
    color: var(--text-inverse);
}

.project-item-actions {
    display: flex;
    gap: 8px;
}

/* Button Group */
.button-group {
    display: flex;
    gap: 10px;
    margin-top: 20px;
}

.button-group .btn {
    flex: 1;
}
/* ==== css/map.css ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   MAP
   ═══════════════════════════════════════════════════════════════════════════ */
/* Map Screen */
#map-screen {
    display: flex;
    flex-direction: column;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100vh;
    overflow: hidden;
}

#map-screen .header {
    flex-shrink: 0;
    position: relative;
    z-index: var(--z-header);
}

/* Make room for floating toggle on map screen */
#map-header {
    --header-right-margin: 100px;
}

.zone-status-bar {
    display: flex;
    justify-content: space-around;
    align-items: center;
    background: rgba(0, 0, 0, 0.6);
    padding: 10px;
    color: var(--text-inverse);
    font-size: var(--text-base);
    flex-shrink: 0;
}

.zone-status-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.zone-status-label {
    font-size: var(--text-xs);
    opacity: 1;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

.zone-status-item span:last-child {
    font-size: var(--text-lg);
    font-weight: bold;
}

.zone-legend {
    display: flex;
    align-items: center;
    gap: 12px;
    background: rgba(255, 255, 255, 0.95);
    padding: 8px 12px;
    border-radius: var(--radius-md);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    font-size: var(--text-sm);
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-header);
    flex-wrap: wrap;
    justify-content: center;
}

.legend-title {
    font-weight: 600;
    margin-right: 4px;
    color: var(--text-color);
}

.legend-item {
    display: flex;
    align-items: center;
    gap: 4px;
}

.legend-color {
    width: 16px;
    height: 16px;
    border-radius: var(--radius-xs);
    border: 1px solid rgba(0, 0, 0, 0.2);
}

.legend-label {
    color: var(--text-muted);
    white-space: nowrap;
}

/* Collapsible legend — tap the title to fold it down to a compact bar */
.legend-title {
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    user-select: none;
}

.legend-collapse-chevron {
    font-size: 10px;
    color: var(--text-muted);
    transition: transform 0.15s;
}

.zone-legend.is-collapsed .legend-item {
    display: none;
}

.zone-legend.is-collapsed {
    gap: 0;
    padding: 6px 12px;
}

.zone-legend.is-collapsed .legend-collapse-chevron {
    transform: rotate(-90deg);
}

/* Playing-zones popup (tap the Playing count) */
.playing-list-popup {
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    margin-top: 6px;
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
    border: 1px solid var(--border-color);
    width: min(320px, 92vw);
    max-height: 52vh;
    overflow-y: auto;
    overflow-x: hidden;
    z-index: var(--z-overlay);
    padding: 6px;
}

.playing-list-popup-header {
    font-size: var(--text-xs);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-muted);
    padding: 6px 8px 4px;
}

/* Recent-list cards: tighter than now-playing (no chips row) */
.plz-card--recent {
    padding: 7px 10px 6px;
}

.plz-card--recent .plz-card-top {
    justify-content: space-between;
}

.plz-ago {
    font-size: var(--text-xs);
    color: var(--text-muted);
    white-space: nowrap;
    flex-shrink: 0;
}

/* Per-zone card */
.plz-card {
    padding: 10px 10px 8px;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-color);
    margin-bottom: 6px;
    background: var(--bg-light, #f9fafb);
}

.plz-card:last-child {
    margin-bottom: 0;
}

.plz-card-top {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 4px;
}

.plz-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #10b981;
    flex: 0 0 auto;
    animation: plz-pulse 2s ease-in-out infinite;
}

@keyframes plz-pulse {

    0%,
    100% {
        opacity: 1;
        box-shadow: 0 0 0 0 rgba(16, 185, 129, .4);
    }

    50% {
        opacity: .8;
        box-shadow: 0 0 0 4px rgba(16, 185, 129, 0);
    }
}

.plz-name {
    font-weight: 600;
    color: var(--text-color);
    font-size: var(--text-sm);
    word-break: break-word;
    line-height: 1.3;
}

.plz-sound {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-bottom: 7px;
    padding-left: 15px;
    word-break: break-word;
}

/* The inline sound/pool icon arrives as raw SVG — without an explicit size it
   rendered at the SVG's intrinsic size, which is what made the tiles look
   uneven. Pin it. */
.plz-sound .oul-icon,
.plz-sound svg {
    width: 13px;
    height: 13px;
    flex: 0 0 auto;
}

.plz-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    padding-left: 15px;
}

.plz-chip {
    font-size: 10px;
    font-weight: 600;
    padding: 2px 7px;
    border-radius: 99px;
    white-space: nowrap;
}

.plz-chip--mode {
    background: #dbeafe;
    color: #1d4ed8;
}

.plz-chip--vol {
    background: #d1fae5;
    color: #065f46;
}

/* A modifier is currently ducking/swelling this zone's volume. */
.plz-chip--vol-mod {
    background: #fde68a;
    color: #92400e;
    font-weight: 600;
}

.plz-chip--fade {
    background: #fef3c7;
    color: #92400e;
}

/* Which item of a sound pool this zone is currently on (#2/5). */
.plz-chip--pool {
    background: #e0e7ff;
    color: #3730a3;
    font-variant-numeric: tabular-nums;
}

.plz-chip--geo {
    background: #ede9fe;
    color: #5b21b6;
}

/* Modifiers targeting this zone — active gets the same amber treatment as
   the volume chip's active-duck state; inactive is a plain muted outline. */
.plz-chip--mod-active {
    background: #fde68a;
    color: #92400e;
    font-weight: 600;
}

.plz-chip--mod-inactive {
    background: transparent;
    border: 1px solid #d1d5db;
    color: #6b7280;
}

/* Zone click-popup reuses the plz card pieces; no dot indent inside Leaflet
   popups, slightly larger name. */
.zone-popup.plz-style {
    min-width: 170px;
}

.zone-popup.plz-style .plz-name {
    font-size: 13px;
    display: block;
    margin-bottom: 4px;
}

.zone-popup.plz-style .plz-sound,
.zone-popup.plz-style .plz-chips {
    padding-left: 0;
}

.playing-list-empty {
    padding: 10px 8px;
    color: var(--text-muted);
    font-size: var(--text-sm);
}

.zone-status-item.is-clickable {
    cursor: pointer;
    position: relative;
}

.zone-status-item.is-clickable:active {
    opacity: 0.7;
}

#map-container {
    flex: 1;
    width: 100%;
    height: 100%;
    min-height: 300px;
    background: var(--map-bg);
    overflow: hidden;
    position: relative;
    user-select: none;
    -webkit-user-select: none;
}

#map-container * {
    user-select: none;
    -webkit-user-select: none;
}

/* User compass marker on map */
.user-location-marker-container {
    background: transparent !important;
    border: none !important;
}

.user-location-marker {
    position: relative;
    width: 80px;
    height: 80px;
}

.location-cone-svg {
    position: absolute;
    top: 0;
    left: 0;
    width: 80px;
    height: 80px;
    transform-origin: 40px 40px;
    opacity: 0;
    transition: transform 0.25s ease-out, opacity 0.2s;
    pointer-events: none;
}

.location-dot {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 18px;
    height: 18px;
    background: var(--map-marker-bg, #3b82f6);
    border: 3px solid white;
    border-radius: 50%;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
    z-index: 2;
}

.zone-x-marker-container {
    background: transparent !important;
    border: none !important;
}

.zone-x-marker-svg {
    width: 20px;
    height: 20px;
    display: block;
}

/* Ensure map screen content fills space */
#map-screen .screen-content {
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* Hide New Zone button by default, show only in edit mode */
#new-zone-map-btn {
    display: none;
}

#map-screen.edit-mode #new-zone-map-btn {
    display: inline-flex;
}

/* ═══════════════════════════════════════════════════════════════════════════
   DEBUG
   ═══════════════════════════════════════════════════════════════════════════ */
/* Debug Screen */
.debug-section {
    background: var(--bg-white);
    padding: 15px;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-sm);
}

/* Toggle Switch */
.switch {
    position: relative;
    display: inline-block;
    width: 50px;
    height: 28px;
}

.switch input {
    opacity: 0;
    width: 0;
    height: 0;
}

.slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--slider-disabled);
    transition: 0.4s;
    border-radius: var(--radius-pill);
}

.slider:before {
    position: absolute;
    content: "";
    height: 20px;
    width: 20px;
    left: 4px;
    bottom: 4px;
    background-color: var(--text-inverse);
    transition: 0.4s;
    border-radius: var(--radius-round);
}

input:checked+.slider {
    background-color: var(--primary-color);
}

input:checked+.slider:before {
    transform: translateX(22px);
}

/* Responsive */
@media (max-width: 480px) {
    .upload-area .btn {
        width: 100%;
    }

    .sound-item {
        flex-direction: column;
    }

    .sound-item-actions {
        width: 100%;
    }

    .sound-item-actions .btn {
        flex: 1;
    }

    .button-group {
        flex-direction: column;
    }

    .button-group .btn {
        width: 100%;
    }

    .modal-content {
        max-height: 90vh;
    }

    .project-item {
        flex-direction: column;
        align-items: flex-start;
        gap: 10px;
    }

    .project-item .btn {
        width: 100%;
    }
}

/* Debug Screen Additional Styles */
.debug-location-container {
    font-family: -apple-system, BlinkMacSystemFont, monospace;
    font-size: var(--text-sm2);
}

.debug-history-list {
    max-height: 400px;
    overflow-y: auto;
}

.debug-history-item {
    background: var(--bg-light);
    padding: 10px;
    border-radius: var(--radius-sm);
    margin-bottom: 8px;
    border-left: 3px solid var(--text-muted);
}

.debug-history-item.current {
    background: var(--primary-light);
    border-left-color: var(--primary-color);
}

.debug-history-item p {
    margin: 3px 0;
}

.debug-distance {
    color: var(--danger-color);
}

.debug-milestone-item {
    background: var(--bg-light);
    padding: 10px;
    border-radius: var(--radius-sm);
    margin-bottom: 8px;
    border-left: 3px solid var(--text-muted);
}

.debug-milestone-item.current {
    background: var(--success-light);
    border-left-color: var(--success-color);
}

.debug-milestone-item p {
    margin: 3px 0;
    font-size: var(--text-sm2);
}

/* Background Mode Debug Styles */
.bg-log-entry {
    padding: 4px 8px;
    border-bottom: 1px solid var(--border-color);
    font-size: var(--text-sm);
    font-family: monospace;
}

.bg-log-entry:first-child {
    background: var(--primary-light);
}

.bg-log-time {
    color: var(--text-secondary);
    margin-right: 8px;
}

#bg-event-log {
    max-height: 200px;
    overflow-y: auto;
    background: var(--bg-secondary);
    border-radius: var(--radius-md);
    margin-top: 10px;
}

/* Web Component Integration */
oul-input,
oul-select,
oul-checkbox,
oul-range,
oul-button,
oul-toggle {
    display: block;
    margin-bottom: 15px;
}

/* Floating Tracking Toggle */
.floating-tracking-toggle {
    position: fixed;
    /* See app-bar.js — Android's forced edge-to-edge display means this needs
       a real top inset; a no-op on iOS. */
    top: calc(env(safe-area-inset-top, 0px) + 12px);
    right: 16px;
    z-index: var(--z-modal);
    background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
    padding: 6px 10px;
    border-radius: var(--radius-pill);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    backdrop-filter: blur(10px);
    transition: opacity var(--duration-slow) var(--easing-default), transform var(--duration-slow) var(--easing-default);
}

/* Motion-state indicator: subtle ring showing whether the motion detector
   (or the path simulator's is_moving pin) currently reads moving or still.
   Drawn as a box-shadow ring, NOT a border — a border changes the box size
   and doesn't follow the pill's rounded corners cleanly against the
   backdrop-filtered background, which looked misshapen. No ring while
   tracking is off (classes are cleared then). */
.floating-tracking-toggle.is-moving {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 0 0 2.5px rgba(52, 211, 153, 0.85); /* soft green — moving */
}
.floating-tracking-toggle.is-still {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2), 0 0 0 2.5px rgba(148, 163, 184, 0.6); /* soft slate — still */
}

.floating-tracking-toggle.hidden {
    opacity: 0;
    transform: translateY(20px);
    pointer-events: none;
}

/* While any PanelManager panel/overlay is open, hide floating chrome so it
   doesn't sit on top of the panel and obscure its close button. */
body.panel-open .floating-tracking-toggle {
    display: none !important;
}

.tracking-status-toggle {
    margin-bottom: 0;
    transform: scale(0.85);
    transform-origin: center;
}

/* GPS Status States */
.tracking-status-toggle.gps-off {
    --toggle-color: #ef4444;
    /* Red for off */
}

.tracking-status-toggle.gps-waiting {
    --toggle-color: #9ca3af;
    /* Grey for waiting */
    position: relative;
    overflow: hidden;
}

.tracking-status-toggle.gps-waiting::before {
    content: '';
    position: absolute;
    top: 0;
    left: -100%;
    width: 200%;
    height: 100%;
    background: linear-gradient(90deg,
            transparent 0%,
            rgba(255, 255, 255, 0.3) 50%,
            transparent 100%);
    animation: shimmer 2s infinite;
    pointer-events: none;
}

@keyframes shimmer {
    0% {
        left: -100%;
    }

    100% {
        left: 100%;
    }
}

.tracking-status-toggle.gps-good {
    --toggle-color: #10b981;
    /* Green for good accuracy */
}

.tracking-status-toggle.gps-poor {
    --toggle-color: #f59e0b;
    /* Amber for poor accuracy */
}

/* Responsive adjustments for floating toggle */
@media (max-width: 768px) {
    .floating-tracking-toggle {
        top: 12px;
        right: 12px;
        padding: 5px 8px;
    }

    #map-header {
        --header-right-margin: 80px;
    }
}

oul-button {
    display: inline-block;
    margin-bottom: 0;
}

oul-form-row {
    display: flex;
    gap: 15px;
}

oul-form-row>* {
    flex: 1;
}


/* Polygon Points Styling */
.polygon-point-row {
    display: flex;
    align-items: flex-end;
    gap: 10px;
    margin-bottom: 10px;
}

.polygon-point-inputs {
    display: flex;
    gap: 10px;
    flex: 1;
}

.polygon-point-inputs oul-input {
    flex: 1;
    margin-bottom: 0;
}

.remove-polygon-point {
    background: var(--danger-color);
    color: var(--text-inverse);
    border: none;
    padding: 10px 12px;
    border-radius: var(--radius-sm);
    cursor: pointer;
}

.remove-polygon-point:hover {
    background: var(--danger-dark);
}

/* Batch Operations Bar */
.batch-operations-bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 10px 15px;
    background: var(--info-light);
    border-radius: var(--radius-sm);
    margin-bottom: 10px;
    flex-wrap: wrap;
    gap: 10px;
}

.batch-select-controls {
    display: flex;
    align-items: center;
    gap: 10px;
}

.batch-count {
    font-size: var(--text-sm2);
    color: var(--text-muted);
    font-weight: 500;
}

.batch-actions {
    display: flex;
    gap: 8px;
}

.batch-toggle {
    margin-bottom: 10px;
}

/* Zone Search/Filter Bar */
.zone-search-bar {
    display: flex;
    gap: 10px;
    margin-bottom: 10px;
    flex-wrap: wrap;
}

.zone-search-input {
    flex: 1;
    min-width: 150px;
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    outline: none;
    transition: border-color var(--duration-normal);
}

.zone-search-input:focus {
    border-color: var(--primary-color);
}

.zone-filter-select {
    padding: 8px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    background: var(--bg-white);
    cursor: pointer;
    outline: none;
}

.zone-filter-select:focus {
    border-color: var(--primary-color);
}

/* Map Layer Control */
.map-layer-control {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

.map-layer-btn {
    width: 34px;
    min-height: 34px;
    border: none;
    background: none;
    cursor: pointer;
    font-size: var(--text-lg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.map-layer-btn:hover {
    background: var(--bg-secondary);
}

/* Map Labels Control */
.map-labels-control {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    margin-top: 5px;
}

.map-labels-btn {
    width: 34px;
    min-height: 34px;
    border: none;
    background: none;
    cursor: pointer;
    font-size: var(--text-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity var(--duration-normal);
}

.map-labels-btn:hover {
    background: var(--bg-secondary);
}

.map-labels-btn.active {
    background: var(--primary-light);
    color: var(--primary-color);
}

/* Map Path Control */
.map-path-control {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
    margin-top: 5px;
}

.map-path-btn {
    width: 34px;
    min-height: 34px;
    border: none;
    background: none;
    cursor: pointer;
    font-size: var(--text-lg);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity var(--duration-normal);
}

.map-path-btn:hover {
    background: var(--bg-secondary);
}

/* Location Refresh Control — bottom-left, consistent with other map buttons */
.map-location-refresh-control {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

/* ─── Path simulator player (debug) ──────────────────────────────── */
.path-sim-player {
    position: fixed;
    left: 50%;
    bottom: 18px;
    transform: translateX(-50%);
    width: min(420px, calc(100vw - 24px));
    box-sizing: border-box;
    background: var(--bg-white, #fff);
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-md, 8px);
    box-shadow: var(--shadow-lg, 0 8px 30px rgba(0, 0, 0, 0.18));
    padding: 10px 12px;
    z-index: var(--z-overlay, 2000);
    display: flex;
    flex-direction: column;
    gap: 8px;
    font-size: var(--text-sm, 12px);
}

.path-sim-player.is-playing {
    border-color: var(--primary-color, #111);
}

.path-sim-player .psp-row {
    display: flex;
    align-items: center;
    gap: 8px;
}

.path-sim-player .psp-title {
    font-weight: 600;
    color: var(--text-color, #333);
    white-space: nowrap;
}

.path-sim-player .psp-path {
    flex: 1;
    min-width: 0;
    padding: 6px 8px;
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-xs, 4px);
    background: var(--bg-white, #fff);
    font-size: var(--text-sm, 12px);
}

.path-sim-player .psp-scrub {
    width: 100%;
    accent-color: var(--primary-color, #111);
    cursor: pointer;
}

.path-sim-player .psp-controls {
    justify-content: flex-start;
}

.path-sim-player .psp-moving.active {
    background: rgba(52, 211, 153, 0.25);
    border-radius: 6px;
}

.path-sim-player .psp-btn {
    width: 36px;
    height: 32px;
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-xs, 4px);
    background: var(--bg-white, #fff);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.path-sim-player .psp-btn:hover {
    background: var(--bg-tertiary, #f0f0f0);
}

.path-sim-player .psp-time {
    font-variant-numeric: tabular-nums;
    color: var(--text-muted, #666);
    margin-left: 2px;
}

.path-sim-player .psp-speed-wrap {
    margin-left: auto;
}

.path-sim-player .psp-speed {
    padding: 5px 6px;
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-xs, 4px);
    background: var(--bg-white, #fff);
    font-size: var(--text-sm, 12px);
}

.path-sim-player .psp-loop-wrap {
    display: flex;
    align-items: center;
    gap: 3px;
    cursor: pointer;
    user-select: none;
}

.map-location-refresh-btn {
    width: 36px;
    height: 36px;
    border: none;
    background: var(--bg-white);
    cursor: pointer;
    font-size: var(--text-lg);
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-xs);
    transition: background var(--duration-fast), opacity var(--duration-normal);
}

.map-location-refresh-btn:hover {
    background: var(--bg-tertiary);
}

.map-location-refresh-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ═══════════════════════════════════════════════════════════════════════════
   PATH RECORDING
   ═══════════════════════════════════════════════════════════════════════════ */
/* Path Recording Screen */
.path-stats-bar {
    display: flex;
    justify-content: space-around;
    align-items: center;
    background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
    padding: 12px 16px;
    color: var(--text-inverse);
    flex-shrink: 0;
    z-index: var(--z-controls);
}

.path-stat-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
}

.path-stat-icon {
    font-size: var(--text-md);
    opacity: 0.9;
}

.path-stat-value {
    font-size: var(--text-xl);
    font-weight: 700;
}

.path-stat-label {
    font-size: 10px;
    opacity: 0.8;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.path-map-container {
    flex: 1;
    width: 100%;
    height: 100%;
    min-height: 300px;
    background: var(--map-bg);
    overflow: hidden;
    position: relative;
}

.path-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 12px;
    padding: 16px;
    background: var(--bg-white);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
    flex-shrink: 0;
    z-index: var(--z-controls);
}

/* Current position marker pulse animation */
.current-position-marker {
    background: transparent !important;
    border: none !important;
}

.pulse-dot {
    width: 24px;
    height: 24px;
    background: var(--primary-color);
    border: 3px solid var(--text-inverse);
    border-radius: var(--radius-round);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
    animation: pulse-ring 2s infinite;
}

@keyframes pulse-ring {
    0% {
        box-shadow: 0 0 0 0 var(--primary-shadow);
    }

    70% {
        box-shadow: 0 0 0 15px transparent;
    }

    100% {
        box-shadow: 0 0 0 0 transparent;
    }
}

/* Save Path Dialog */
.path-save-dialog {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--bg-overlay);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: var(--z-overlay);
    padding: 20px;
}

.path-save-dialog-content {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    padding: 24px;
    width: 100%;
    max-width: 400px;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
}

.path-save-dialog-content h3 {
    margin: 0 0 20px 0;
    font-size: var(--text-xl);
    color: var(--text-color);
}

.path-save-dialog-content .form-group {
    margin-bottom: 16px;
}

.path-save-dialog-content .form-group label {
    display: block;
    margin-bottom: 6px;
    font-weight: 500;
    color: var(--text-color);
}

.path-save-dialog-content .form-input {
    width: 100%;
    padding: 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    box-sizing: border-box;
}

.path-save-dialog-content .form-input:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px var(--primary-shadow-light);
}

.path-save-dialog-content textarea.form-input {
    resize: vertical;
    min-height: 80px;
}

.dialog-buttons {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
    margin-top: 20px;
}

/* Inline form group — label + checkbox on one line */
.form-group--inline {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.form-group--inline label {
    margin-bottom: 0 !important;
    cursor: pointer;
}

.form-checkbox {
    width: 18px;
    height: 18px;
    cursor: pointer;
    accent-color: var(--primary-color);
    flex-shrink: 0;
}

.form-hint {
    font-size: var(--text-sm);
    color: var(--text-muted, #6b7280);
    width: 100%;
    margin-top: -4px;
}

/* Path screen layout */
#path-screen .screen-content {
    flex: 1;
    display: flex;
    flex-direction: column;
}
/* Recentre-on-zones control (below the zoom buttons) */
.map-recentre-control a {
    font-size: 20px;
    line-height: 30px;
    text-align: center;
    text-decoration: none;
    color: #333;
}

/* ==== css/sounds.css ==== */
/* ======================================
   SOUNDS EXPLORER STYLES
====================================== */

.sounds-explorer-screen {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--bg-white);
    z-index: var(--z-top);
    flex-direction: column;
    overflow: hidden;
}

.sounds-explorer-screen.active {
    display: flex !important;
}

/* ─── Sound Optimization page ─────────────────────────────────────── */
.sound-opt-intro {
    padding: 12px 16px;
    border-bottom: 1px solid var(--border-color, #e0e0e0);
    font-size: var(--text-sm, 12px);
    color: var(--text-secondary, #555);
}

.sound-opt-intro p {
    margin: 0 0 8px;
}

.sound-opt-legend {
    margin: 0;
    padding-left: 18px;
}

.sound-opt-legend li {
    margin: 2px 0;
}

.sound-opt-warning {
    margin-top: 8px;
    padding: 8px 10px;
    background: var(--danger-light, #ffe5e5);
    color: var(--danger-color, #c0392b);
    border-radius: var(--radius-sm, 6px);
}

.sound-opt-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 16px;
    border-bottom: 1px solid var(--border-color, #e0e0e0);
    font-size: var(--text-sm, 12px);
}

.sound-opt-summary {
    margin-left: auto;
    color: var(--text-muted, #666);
}

.sound-optimizer-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.sopt-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 10px 12px;
    background: var(--bg-white, #fff);
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-sm, 6px);
}

.sopt-main {
    flex: 1;
    min-width: 0;
}

.sopt-title {
    font-weight: 600;
    color: var(--text-color, #222);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sopt-meta {
    font-size: var(--text-xs, 11px);
    color: var(--text-muted, #666);
    margin-top: 3px;
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.sopt-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}

.sopt-format {
    padding: 5px 6px;
}

.sopt-badge {
    display: inline-block;
    padding: 1px 7px;
    border-radius: var(--radius-pill, 20px);
    font-size: var(--text-xs, 11px);
    font-weight: 600;
}

.sopt-badge.ready {
    background: #e5ffe9;
    color: #1b7f3b;
}

.sopt-badge.working {
    background: #fff6e0;
    color: #9a6700;
}

.sopt-badge.failed {
    background: #ffe5e5;
    color: #c0392b;
}

.sopt-badge.none {
    background: var(--bg-tertiary, #f0f0f0);
    color: var(--text-muted, #666);
}

/* Row highlight for looped sounds that haven't been optimised yet */
.sopt-row--needs-opt {
    border-color: #fbbf24;
    background: #fffbeb;
}

/* Looping-zone usage line */
.sopt-loop-hint {
    font-size: var(--text-xs, 11px);
    color: var(--text-muted, #666);
    margin-top: 5px;
    line-height: 1.4;
}

.sopt-loop-hint--warn {
    color: #92400e;
    font-weight: 600;
}

.sopt-loop-zones {
    font-weight: 400;
    color: var(--text-muted, #666);
}

@media (max-width: 480px) {
    .sopt-row {
        flex-direction: column;
        align-items: stretch;
    }

    .sopt-actions {
        justify-content: flex-end;
    }
}

.sounds-explorer-header {
    display: flex;
    align-items: center;
    gap: 16px;
    padding: 16px;
    padding-top: calc(env(safe-area-inset-top, 0px) + 16px);
    border-bottom: 1px solid var(--border-color);
    background: var(--bg-white);
}

.sounds-explorer-back {
    background: none;
    border: none;
    font-size: var(--text-md);
    color: var(--primary-color);
    cursor: pointer;
    padding: 8px 12px;
    border-radius: var(--radius-md);
}

.sounds-explorer-back:hover {
    background: var(--bg-light);
}

.sounds-explorer-title {
    font-size: var(--text-lg);
    font-weight: 600;
    color: var(--text-color);
    margin: 0;
}

.sounds-explorer-filters {
    padding: 12px 16px;
    background: var(--bg-light);
    border-bottom: 1px solid var(--border-color);
}

.sounds-filter-tabs {
    display: flex;
    gap: 8px;
    margin-bottom: 12px;
}

.sounds-filter-tab {
    padding: 8px 16px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-pill);
    background: var(--bg-white);
    color: var(--text-secondary);
    font-size: var(--text-sm2);
    cursor: pointer;
    transition: all var(--duration-normal);
}

.sounds-filter-tab:hover {
    background: var(--bg-tertiary);
}

.sounds-filter-tab.active {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

/* ── Tag filter bar (sounds explorer) ─────────────────────────────── */
.sounds-tag-filter {
    display: flex;
    flex-wrap: nowrap;
    gap: 6px;
    overflow-x: auto;
    padding: 2px 0 4px;
    scrollbar-width: none;
    /* Firefox */
    -ms-overflow-style: none;
}

.sounds-tag-filter::-webkit-scrollbar {
    display: none;
}

.sound-tag-chip {
    flex-shrink: 0;
    padding: 4px 10px;
    border-radius: var(--radius-lg);
    font-size: var(--text-sm);
    font-weight: 500;
    cursor: pointer;
    border: 1.5px solid var(--border-color, #e0e0e0);
    background: var(--bg-light, #f5f5f5);
    color: var(--text-secondary, #555);
    transition: background var(--duration-fast), color var(--duration-fast), border-color var(--duration-fast);
    white-space: nowrap;
    user-select: none;
}

.sound-tag-chip:hover {
    border-color: var(--primary-color, #111);
    color: var(--primary-color, #111);
}

.sound-tag-chip.active {
    background: var(--primary-color, #111);
    border-color: var(--primary-color, #111);
    color: var(--text-inverse);
}

/* ── Tag chips on sound cards ──────────────────────────────────────── */
.sound-card-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 6px;
}

.sound-card-tag {
    padding: 2px 8px;
    border-radius: var(--radius-lg);
    font-size: var(--text-xs);
    font-weight: 500;
    background: var(--primary-light, #e0e7ff);
    color: var(--primary-dark, #3730a3);
    cursor: pointer;
    border: none;
    transition: background var(--duration-fast);
}

.sound-card-tag:hover {
    background: var(--primary-color, #111);
    color: var(--text-inverse);
}

.sounds-search-row {
    display: flex;
    gap: 12px;
}

.sounds-search-input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
}

.sounds-search-input:focus {
    outline: none;
    border-color: var(--primary-color);
}

.sounds-sort-select {
    padding: 10px 14px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    background: var(--bg-white);
    min-width: 120px;
}

.sounds-explorer-content {
    flex: 1;
    overflow-y: auto;
    padding: 16px;
}

.sounds-explorer-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   SOUND EXPLORER
   ═══════════════════════════════════════════════════════════════════════════ */
.sound-explorer-item {
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    transition: box-shadow var(--duration-normal);
}

.sound-explorer-item:hover {
    box-shadow: var(--shadow-md);
}

.sound-item-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
}

.sound-item-title {
    font-weight: 600;
    font-size: var(--text-md2);
    color: var(--text-color);
    margin: 0;
}

.sound-item-badges {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.sound-badge {
    padding: 3px 8px;
    border-radius: var(--radius-lg);
    font-size: var(--text-xs);
    font-weight: 500;
}

.sound-badge.public {
    background: rgba(76, 175, 80, 0.1);
    color: #2e7d32;
}

.sound-badge.mine {
    background: rgba(33, 150, 243, 0.1);
    color: #1976d2;
}

.sound-badge.in-project {
    background: rgba(156, 39, 176, 0.1);
    color: #7b1fa2;
}

.sound-badge.has-zones {
    background: rgba(255, 152, 0, 0.1);
    color: #f57c00;
}

.sound-item-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    font-size: var(--text-sm2);
    color: var(--text-muted);
}

.sound-meta-item {
    display: flex;
    align-items: center;
    gap: 4px;
}

.sound-meta-icon {
    font-size: var(--text-base);
}

.sound-item-actions {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}

.sound-action-btn {
    padding: 8px 14px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-white);
    color: var(--text-secondary);
    font-size: var(--text-sm2);
    cursor: pointer;
    transition: all var(--duration-normal);
}

.sound-action-btn:hover {
    background: var(--bg-light);
}

.sound-action-btn.primary {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

.sound-action-btn.primary:hover {
    background: var(--primary-dark);
}

.sounds-load-more {
    display: block;
    width: 100%;
    padding: 14px;
    margin-top: 16px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    background: var(--bg-white);
    color: var(--text-secondary);
    font-size: var(--text-base);
    cursor: pointer;
    transition: all var(--duration-normal);
}

.sounds-load-more:hover {
    background: var(--bg-light);
}

.sounds-empty-state {
    text-align: center;
    padding: 40px 20px;
    color: var(--text-muted);
}

.sounds-empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
}

/* Sound Picker Display (Zone Form) */
.sound-picker-display {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 12px;
    background: var(--bg-light);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
}

.sound-picker-display.has-sound {
    background: var(--bg-white);
    border-color: var(--primary-color);
}

.sound-picker-info {
    flex: 1;
    min-width: 0;
}

.sound-picker-label {
    display: block;
    font-weight: 500;
    color: var(--text-color);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sound-picker-display:not(.has-sound) .sound-picker-label {
    color: var(--text-muted);
}

.sound-picker-duration {
    display: block;
    font-size: var(--text-sm);
    color: var(--text-muted);
    margin-top: 2px;
}

.sound-picker-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

/* Select button highlight in picker mode */
.sound-action-btn.select-sound {
    background: var(--success-color);
    color: var(--text-inverse);
    border-color: var(--success-color);
}

.sound-action-btn.select-sound:hover {
    background: var(--success-dark);
}

/* =============================================
   Sound Pool Editor Styles
   ============================================= */

.pool-items-list {
    min-height: 100px;
    border: 2px dashed var(--border-color);
    border-radius: var(--radius-md);
    padding: 12px;
    margin-bottom: 12px;
    background: var(--bg-secondary);
}

.pool-items-list .empty-state {
    text-align: center;
    color: var(--text-muted);
    padding: 24px;
}

.pool-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    margin-bottom: 8px;
    cursor: move;
    transition: background var(--duration-normal);
}

.pool-item:hover {
    background: var(--bg-tertiary);
}

.pool-item.dragging {
    opacity: 0.4;
}

.drag-handle {
    font-size: var(--text-xl);
    color: var(--text-muted);
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    -webkit-touch-callout: none;
    /* Touch drags the row (soundPools.js) instead of scrolling the list. */
    touch-action: none;
    padding: var(--spacing-sm, 8px);
    margin: calc(-1 * var(--spacing-sm, 8px));
}

.drag-handle:active {
    cursor: grabbing;
}

.pool-item-info {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 12px;
}

.pool-item-info strong {
    color: var(--text-color);
}

.pool-item-info .duration {
    color: var(--text-secondary);
    font-size: 0.9em;
}

.pool-item-controls {
    display: flex;
    align-items: center;
    gap: 12px;
}

.pool-item-controls label {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.9em;
    color: var(--text-secondary);
    cursor: pointer;
}

.pool-item-controls .play-once-checkbox {
    cursor: pointer;
}

/* Pool item preview play button */
.pool-item-preview-btn {
    background: none;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    cursor: pointer;
    font-size: var(--text-sm);
    padding: 2px 8px;
    color: var(--primary-color);
    transition: background var(--duration-fast), color var(--duration-fast);
}

.pool-item-preview-btn:hover {
    background: var(--primary-color);
    color: #fff;
    border-color: var(--primary-color);
}

/* Edit sound preview row */
.edit-sound-preview {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--border-color);
    margin-bottom: 4px;
}

.edit-sound-preview-btn {
    padding: 6px 16px;
    background: var(--primary-color);
    color: #fff;
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--duration-fast);
}

.edit-sound-preview-btn:hover {
    background: var(--primary-dark);
}

.edit-sound-preview-duration {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.btn-icon {
    background: none;
    border: none;
    cursor: pointer;
    font-size: var(--text-lg);
    padding: 4px 8px;
    opacity: 0.6;
    transition: opacity var(--duration-normal);
}

.btn-icon:hover {
    opacity: 1;
}

.remove-item-btn {
    color: var(--danger-color);
}

.form-section {
    margin-top: 24px;
    padding-top: 24px;
    border-top: 1px solid var(--border-color);
}

.form-section h3 {
    margin-bottom: 12px;
    color: var(--text-color);
    font-size: 1.1em;
}

.help-text {
    font-size: 0.85em;
    color: var(--text-muted);
    margin-top: 4px;
}


/* Multi-select picker: highlight selected rows */
.sound-explorer-item.multi-selected {
    outline: 2px solid var(--primary-color, #667eea);
    outline-offset: -2px;
    border-radius: var(--radius-md, 8px);
}

/* ─── Record popover ─────────────────────────────────────────────────────── */
/* Self-contained record → describe → upload flow. Clicking the dimmed
   backdrop stops and discards; the card stays open through the upload. */
.record-popover-overlay {
    position: fixed;
    inset: 0;
    z-index: 10200;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(0, 0, 0, 0.35);
    padding: 16px;
}

.record-popover {
    width: 100%;
    max-width: 420px;
    max-height: calc(100vh - 48px);
    overflow-y: auto;
    background: var(--bg-primary, #fff);
    border: 1px solid var(--border-color, #ddd);
    border-radius: var(--radius-md, 12px);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.28);
    padding: 18px;
}

.rp-stage {
    text-align: left;
}

#rp-stage-recording {
    text-align: center;
    padding: 8px 0;
}

.rp-recording-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 10px 0;
}

#rp-timer {
    font-size: var(--text-lg, 18px);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-primary);
}

.rp-hint {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin: 0 0 14px;
}

.rp-audio {
    width: 100%;
    margin-bottom: 12px;
}

/* ==== css/map-print.css ==== */
/* =============================================
   Print Map Styles
   ============================================= */

.print-map-label {
    background: transparent !important;
    border: none !important;
}

.print-map-label .label-content {
    background: var(--bg-white);
    padding: 4px 8px;
    border-radius: var(--radius-xs);
    font-size: var(--text-sm);
    font-weight: 600;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
    white-space: nowrap;
    border: 2px solid #333;
}

.zone-label .label-content {
    background: #dbeafe;
    border-color: #3b82f6;
    color: #1e40af;
}

.path-label .label-content {
    background: #d1fae5;
    border-color: #10b981;
    color: #065f46;
}

.print-map-title {
    display: none;
}

/* Print Overlay — non-blocking bottom panel: the live map stays pannable
   behind it so the user can compose the crop shown by .print-crop-mask */
.print-overlay {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: transparent;
    pointer-events: none;
    z-index: var(--z-modal);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    padding-bottom: 12px;
}

.print-overlay-content {
    pointer-events: auto;
    background: var(--bg-white);
    border-radius: var(--radius-md);
    width: 92%;
    max-width: 420px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
    max-height: 60vh;
    overflow-y: auto;
    /* Dragged position is applied as inline left/top by PrintMap._makeDraggable */
    position: relative;
}

/* The panel sits on top of the very map area being composed, so it recedes
   until wanted: faded while idle, fully opaque on hover/focus/drag. Kept above
   a usable floor so it never becomes invisible furniture. */
.print-overlay-content {
    opacity: 0.35;
    transition: opacity var(--duration-normal, 0.2s) ease;
}

.print-overlay-content:hover,
.print-overlay-content:focus-within,
.print-overlay-content.is-dragging,
.print-overlay-content.pinned {
    opacity: 1;
}

/* Coarse pointers get no hover, so fading would strand the panel dim on
   touch devices — show it solid and let dragging move it out of the way. */
@media (hover: none) {
    .print-overlay-content { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .print-overlay-content { transition: none; }
}

.print-overlay-header {
    cursor: grab;
    touch-action: none;      /* let the drag handler own the gesture */
    user-select: none;
}

.print-overlay-content.is-dragging .print-overlay-header { cursor: grabbing; }

.print-drag-hint {
    font-size: var(--text-xs);
    color: #999;
    margin-left: auto;
    margin-right: 8px;
    letter-spacing: 0.08em;
}

/* A4 crop rectangle over the map: everything outside is dimmed by the
   oversized box-shadow; the rect itself is transparent and click-through */
.print-crop-mask {
    position: absolute;
    z-index: 800; /* above tiles/overlays, below Leaflet controls (1000) */
    pointer-events: none;
    border: 2px dashed rgba(255, 255, 255, 0.95);
    border-radius: 2px;
    box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.45);
}

.print-orient-group {
    display: inline-flex;
    background: #ececec;
    border-radius: var(--radius-xs);
    padding: 2px;
    gap: 2px;
}

.print-orient-btn {
    border: none;
    background: transparent;
    color: #555;
    padding: 5px 10px;
    border-radius: var(--radius-xs);
    font-size: var(--text-xs);
    font-weight: 600;
    cursor: pointer;
}

.print-orient-btn.active {
    background: var(--primary-color);
    color: var(--text-inverse);
}

.print-status-line {
    margin-top: 10px;
    font-size: var(--text-xs);
    color: #777;
    font-variant-numeric: tabular-nums;
    min-height: 15px;
}

.print-overlay-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    border-bottom: 1px solid #e0e0e0;
}

.print-overlay-header h3 {
    margin: 0;
    font-size: var(--text-xl);
    font-weight: 600;
}

.close-print-btn {
    background: none;
    border: none;
    font-size: var(--text-2xl);
    color: #999;
    cursor: pointer;
    padding: 0;
    width: 30px;
    height: 30px;
    border-radius: var(--radius-xs);
    transition: all var(--duration-normal);
}

.close-print-btn:hover {
    background: #f0f0f0;
    color: #333;
}

.print-overlay-body {
    padding: 20px;
}

.print-overlay-body .form-group {
    margin-bottom: 15px;
}

.print-overlay-body label {
    display: block;
    margin-bottom: 5px;
    font-weight: 500;
    color: #333;
}

.print-overlay-body input[type="checkbox"] {
    margin-right: 8px;
}

.print-title-input {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: var(--radius-xs);
    font-size: var(--text-base);
}

.print-overlay-footer {
    padding: 20px;
    border-top: 1px solid #e0e0e0;
    display: flex;
    gap: 10px;
}

.print-overlay-footer .btn {
    flex: 1;
    padding: 12px;
    border: none;
    border-radius: var(--radius-sm);
    font-size: var(--text-md);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--duration-slow);
}

.print-overlay-footer .btn-primary {
    background: var(--primary-color);
    color: var(--text-inverse);
}

.print-overlay-footer .btn-primary:hover {
    background: #222;
}

.print-overlay-footer .btn-secondary {
    background: #e0e0e0;
    color: #333;
}

.print-overlay-footer .btn-secondary:hover {
    background: #d0d0d0;
}

/* Print Title Display */
.map-print-title {
    display: none;
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--bg-white);
    padding: 15px 30px;
    border-radius: var(--radius-md);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    font-size: var(--text-2xl);
    font-weight: bold;
    z-index: var(--z-header);
}

/* Zone label tooltips (permanent Leaflet tooltips on each zone) */
.zone-label-tooltip {
    background: rgba(255, 255, 255, 0.85);
    border: 1px solid rgba(0, 0, 0, 0.25);
    border-radius: var(--radius-xs);
    padding: 3px 7px;
    font-size: var(--text-xs);
    font-weight: 600;
    line-height: 1.4;
    white-space: pre;
    /* allow \n for name + size on separate lines */
    pointer-events: none;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.2);
}

.zone-label-tooltip::before {
    display: none;
    /* remove Leaflet's default arrow */
}

/* Path labels share the zone-label-tooltip base styles but are visually lighter */
.path-label-tooltip {
    font-weight: 500;
    font-style: italic;
    background: rgba(240, 244, 255, 0.9);
    border-color: rgba(100, 126, 234, 0.35);
}

/* Data Script print — hide all app chrome, show only the generated frame */
body.script-printing > *:not(#script-print-frame) { display: none !important; }
#script-print-frame { display: block; }

/* Print-specific styles */
@media print {

    /* Preserve colours in print */
    * {
        -webkit-print-color-adjust: exact !important;
        print-color-adjust: exact !important;
    }

    /* Hide everything in body except the map screen.
       oul-screen shadow DOM visibility is handled via JS (_prepareShadowDOM)
       so we only need to hide sibling screens here. */
    oul-screen:not(#map-screen) {
        display: none !important;
    }

    /* Hide UI chrome inside the map screen */
    oul-header,
    #map-header,
    #zone-status-bar,
    #zone-legend,
    .print-overlay,
    #floating-tracking-toggle,
    .map-location-refresh-control,
    .map-rotation-control,
    .path-sim-player,
    .leaflet-control-scale {
        display: none !important;
    }

    /* Map container fills the page */
    #map-container {
        position: fixed !important;
        top: 0 !important;
        left: 0 !important;
        right: 0 !important;
        bottom: 0 !important;
        width: 100vw !important;
        height: 100vh !important;
        overflow: visible !important;
        z-index: 1 !important;
    }

    /* Zone / path labels — more transparent background for print */
    .zone-label-tooltip {
        background: rgba(255, 255, 255, 0.55) !important;
        border-color: rgba(0, 0, 0, 0.4) !important;
        box-shadow: none !important;
    }

    /* Zone shapes — lighter fill, strong outline */
    .leaflet-interactive {
        fill-opacity: 0.08 !important;
        stroke-width: 2.5 !important;
        stroke: #000 !important;
        stroke-opacity: 0.85 !important;
    }

    @page {
        size: A4 landscape;
        margin: 0;
    }
}


/* ── Compose mode ─────────────────────────────────────────────────────────────
   While the print dialog is open the map is a page being framed, not a live
   tracking view. Hide the tracking chrome that would otherwise sit over the
   crop area (and print-preview badly), and show a scale bar matching the one
   the renderer draws onto the page. */

body.print-composing #floating-tracking-toggle,
body.print-composing #map-current-status,
body.print-composing .now-playing-popover,
body.print-composing #playing-list-popup,
body.print-composing #recent-list-popup {
    display: none !important;
}

/* The compose-mode ruler is _buildRuler()'s element (same as the printed page),
   which styles itself inline; it only needs to sit above the crop mask. */
#print-ruler-preview {
    pointer-events: none;
}

/* ==== css/map-editor.css ==== */
/* ─── Map Rotation / Compass Control ───────────────────────── */

.map-rotation-control {
    background: var(--bg-white);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    overflow: hidden;
}

.map-rotation-compass-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 1px;
    width: 34px;
    min-height: 34px;
    padding: 4px 0;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--text-color);
}

.map-rotation-compass-btn:hover {
    background: var(--bg-secondary);
}

#map-compass-svg {
    transition: transform var(--duration-normal) var(--easing-default);
    display: block;
}

.map-rotation-badge {
    font-size: var(--text-xs);
    font-weight: 700;
    color: var(--danger-color);
    line-height: 1;
}

.map-rotation-panel {
    border-top: 1px solid var(--border-color);
    padding: 8px;
    width: 140px;
}

.map-rotation-slider {
    width: 100%;
    margin: 0;
}

.map-rotation-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 4px;
    font-size: var(--text-sm);
}

.map-rotation-reset-btn {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    font-size: var(--text-xs);
    font-weight: 600;
    padding: 2px 6px;
    cursor: pointer;
}

.map-rotation-reset-btn:hover {
    background: var(--bg-tertiary);
}

/* ─── Map Edit Mode Overlay ─────────────────────────────────── */

.edit-mode-instructions {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: rgba(0, 0, 0, 0.8);
    color: var(--text-inverse);
    padding: 12px 20px;
    border-radius: var(--radius-md);
    z-index: var(--z-controls);
    font-size: var(--text-sm);
    line-height: 1.5;
    pointer-events: auto;
}

.edit-mode-instructions .instructions-content {
    text-align: center;
}

.edit-mode-btn {
    background: var(--primary-color);
    color: var(--text-inverse);
    border: none;
    padding: 8px 16px;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    transition: all var(--duration-normal);
}

.edit-mode-btn:hover:not(:disabled) {
    background: var(--primary-dark);
}

.edit-mode-btn:disabled {
    background: #666;
    cursor: not-allowed;
}

/* Zone placement crosshair */
.zone-crosshair {
    background: transparent !important;
    border: none !important;
    pointer-events: none;
}

.zone-crosshair svg {
    filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.5));
    animation: crosshair-pulse 1.5s ease-in-out infinite;
}

@keyframes crosshair-pulse {

    0%,
    100% {
        opacity: 1;
        transform: scale(1);
    }

    50% {
        opacity: 0.7;
        transform: scale(1.05);
    }
}

/* ─── Path Vertex Editing ───────────────────────────────────── */

/* ═══ Map editor (draw/adjust zones & paths) ═══ */
.map-editor-toolbar {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    width: max-content;
    /* Leave room for the tracking toggle in the top-right (~100px) and a
       small margin on the left so the pill never bleeds off either edge. */
    max-width: calc(100% - 110px);
    /* Must sit above Leaflet's map panes (200–700) and controls (~1000) */
    z-index: var(--z-overlay, 2000);
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 8px;
    background: var(--bg-white, #fff);
    border-radius: var(--radius-pill, 20px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.22);
    flex-wrap: wrap;
    justify-content: center;
}

.met-btn {
    border: 1px solid var(--border-color, #e0e0e0);
    background: var(--bg-white, #fff);
    color: var(--text-color, #111);
    font-size: var(--text-base, 14px);
    line-height: 1;
    padding: 7px 10px;
    border-radius: var(--radius-sm, 6px);
    cursor: pointer;
    white-space: nowrap;
}

.met-btn.active {
    background: var(--primary-color, #111);
    color: var(--text-inverse, #fff);
    border-color: var(--primary-color, #111);
}

.met-btn.met-primary {
    background: var(--success-color, #2e7d32);
    color: #fff;
    border-color: var(--success-color, #2e7d32);
}

.met-btn.met-danger {
    background: var(--danger-color, #c62828);
    color: #fff;
    border-color: var(--danger-color, #c62828);
}

/* Collapsed visibility control: a single 👁 button opening a small dropdown. */
.met-vis-wrap {
    position: relative;
    display: inline-flex;
}

.met-vis-toggle.has-hidden {
    position: relative;
    border-color: var(--primary-color, #667eea);
}

.met-vis-toggle.has-hidden::after {
    content: '';
    position: absolute;
    top: -2px;
    right: -2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--primary-color, #667eea);
    border: 1px solid var(--bg-white, #fff);
}

.met-vis-menu {
    position: absolute;
    top: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 6px;
    background: var(--bg-white, #fff);
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-md, 8px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.22);
    z-index: 1;
}

.met-vis-menu .met-vis {
    text-align: left;
}

.met-vis-groups {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 40vh;
    overflow-y: auto;
}

.met-vis-sep {
    height: 1px;
    margin: 2px 0;
    background: var(--border-color, #e0e0e0);
}

.met-btn.met-vis-group {
    font-size: var(--text-sm, 12px);
    padding: 6px 8px;
    text-align: left;
    white-space: nowrap;
    max-width: 220px;
    overflow: hidden;
    text-overflow: ellipsis;
}

.met-group-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin-right: 4px;
    vertical-align: baseline;
}

/* Visibility toggles: smaller, and a muted "hidden" look when active (overrides
   the generic .active fill so they read as "this type is hidden", not selected). */
.met-btn.met-vis {
    font-size: var(--text-sm, 12px);
    padding: 6px 8px;
}

.met-btn.met-vis.active,
.met-btn.met-vis-group.active {
    background: var(--bg-tertiary, #eceef1);
    color: var(--text-secondary, #888);
    border-color: var(--border-color, #d6d9dd);
    text-decoration: line-through;
}

.met-sep {
    width: 1px;
    align-self: stretch;
    background: var(--border-color, #e0e0e0);
    margin: 2px 4px;
}

.met-hint {
    flex-basis: 100%;
    text-align: center;
    font-size: var(--text-xs, 11px);
    color: var(--text-secondary, #666);
    padding-top: 2px;
}

.met-group-select {
    font-size: var(--text-sm, 13px);
    padding: 5px 8px;
    border: 1px solid var(--border-color, #e0e0e0);
    border-radius: var(--radius-sm, 6px);
    background: var(--bg-white, #fff);
    color: var(--text-color, #111);
    cursor: pointer;
    max-width: 180px;
}

/* Draggable editing handles (native L.marker + divIcon) */
.map-edit-handle {
    background: var(--bg-white, #fff);
    border: 2px solid var(--primary-color, #111);
    border-radius: var(--radius-round, 50%);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
    cursor: grab;
    transition: transform 0.1s;
}

.map-edit-handle:hover {
    transform: scale(1.35);
}

.map-edit-handle.handle-radius {
    border-color: #2e7d32;
}

.map-edit-handle.handle-center {
    border-color: #ff6f00;
}

.map-edit-handle.handle-vertex {
    border-color: #1565c0;
}

.map-edit-handle.handle-vertex-selected {
    border-color: #e53935;
    background: #ffebee;
    transform: scale(1.35);
    box-shadow: 0 0 0 3px rgba(229, 57, 53, 0.3);
}

.map-edit-handle.handle-midpoint {
    border-style: dashed;
    opacity: 0.7;
    cursor: copy;
}

.map-edit-handle.handle-group {
    border-color: #8e24aa;
    width: 22px !important;
    height: 22px !important;
    margin: -3px 0 0 -3px;
    box-shadow: 0 0 0 3px rgba(142, 36, 170, 0.25);
}

/* Edit mode: the REGULAR arrow cursor everywhere — including Leaflet's
   interactive shapes (pointer finger) and drag handles (grab). Requested
   explicitly: no crosshair, no finger, no hand while editing. */
.leaflet-container.map-editing,
.leaflet-container.map-editing .leaflet-interactive,
.leaflet-container.map-editing .leaflet-marker-icon,
.leaflet-container.map-editing .map-edit-handle,
.leaflet-container.map-editing .map-edit-handle.handle-midpoint,
.leaflet-container.map-editing .path-vertex-handle,
.leaflet-container.map-editing.leaflet-grab {
    cursor: default !important;
}

.path-vertex-handle {
    background: var(--bg-white);
    border: 2px solid var(--primary-color);
    border-radius: var(--radius-round);
    cursor: grab;
    transition: transform 0.1s, border-color 0.1s;
}

.path-vertex-handle:hover {
    transform: scale(1.5);
    border-color: #4f46e5;
}

.path-vertex-delete {
    border-color: #ef4444;
    cursor: pointer;
}

.path-vertex-delete:hover {
    border-color: #b91c1c;
    transform: scale(1.5);
}

.pvt-active {
    background: rgba(255, 255, 255, 0.25) !important;
    border: 1px solid white !important;
}

/* Self-contained floating path-vertex toolbar (bottom-centre of the map) */
.path-vertex-toolbar {
    position: absolute;
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: var(--z-overlay, 2000);
    background: rgba(0, 0, 0, 0.82);
    color: #fff;
    padding: 10px 12px;
    border-radius: var(--radius-md, 8px);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
    max-width: calc(100% - 24px);
}

.path-vertex-toolbar .pvt-hint {
    font-size: var(--text-xs, 11px);
    opacity: 0.9;
    margin-bottom: 8px;
    text-align: center;
}

.path-vertex-toolbar .pvt-row {
    display: flex;
    gap: 6px;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
}

.path-vertex-toolbar .edit-mode-btn {
    flex: 0 0 auto;
    min-width: 40px;
    padding: 6px 10px;
    font-size: var(--text-base, 14px);
    white-space: nowrap;
}

.path-vertex-toolbar .pvt-done {
    font-weight: 700;
}

.pvt-counter {
    min-width: 56px;
    text-align: center;
    font-size: var(--text-sm, 12px);
    opacity: 0.9;
}

/* Selected path point — larger, highlighted, draggable */
.path-vertex-handle.path-vertex-selected {
    background: #ff6f00;
    border-color: #fff;
    box-shadow: 0 0 0 4px rgba(255, 111, 0, 0.35);
    cursor: grab;
}


/* ── Map markup (docs/MARKUP_LAYER_PLAN.md) ─────────────────────────────────*/
.met-swatch {
    display: inline-block;
    width: 14px;
    height: 14px;
    border-radius: 3px;
    background: #d33131;
    border: 1.5px solid rgba(0, 0, 0, 0.35);
    vertical-align: -2px;
}

.markup-drawing { cursor: crosshair; }

.markup-text span {
    display: inline-block;
    font: 600 13px/1.25 -apple-system, BlinkMacSystemFont, sans-serif;
    background: rgba(255, 255, 255, 0.85);
    padding: 2px 6px;
    border-radius: 4px;
    white-space: nowrap;
    text-shadow: none;
}

.markup-text.markup-selected span { outline: 2px dashed currentColor; }

/* ✥ move handle for a selected pen stroke / ellipse (labels drag themselves) */
.map-edit-handle.handle-markup-move {
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 17px;
    line-height: 1;
    color: #d33131;
    border-color: #d33131;
    box-shadow: 0 0 0 3px rgba(211, 49, 49, 0.25);
    user-select: none;
    -webkit-user-select: none;
}

/* Pen strokes are pointer events on the container. Disabling map.dragging
   drops .leaflet-touch-drag, leaving leaflet.css's
   .leaflet-container.leaflet-touch-zoom (pan-x pan-y), so the browser would
   claim a one-finger stroke as a pan and cancel it. leaflet.css loads after
   this file, so out-rank it with a third class. */
.leaflet-container.markup-drawing,
.leaflet-container.leaflet-touch-zoom.markup-drawing { touch-action: none; }

/* Outside edit mode markup is look-only: let taps fall through to the zones
   underneath instead of dying on the ink. */
.leaflet-container:not(.map-editing) .oul-markup,
.leaflet-container:not(.map-editing) .markup-text {
    pointer-events: none !important;
}

/* ==== css/admin.css ==== */
/* ─── Admin Panel ───────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   ADMIN PANEL
   ═══════════════════════════════════════════════════════════════════════════ */
.admin-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.55);
    z-index: var(--z-panel);
    display: flex;
    align-items: flex-start;
    justify-content: flex-end;
    animation: overlayBackdropIn 0.25s ease both;
}

@keyframes overlayBackdropIn {
    from { background: rgba(0, 0, 0, 0); }
    to   { background: rgba(0, 0, 0, 0.55); }
}

.admin-overlay.is-closing {
    animation: overlayBackdropOut 0.22s ease both;
    pointer-events: none;
}

@keyframes overlayBackdropOut {
    from { background: rgba(0, 0, 0, 0.55); }
    to   { background: rgba(0, 0, 0, 0); }
}

.admin-panel {
    background: var(--bg-white, #fff);
    width: min(540px, 100vw);
    height: 100vh;
    display: flex;
    flex-direction: column;
    box-shadow: -4px 0 24px rgba(0, 0, 0, 0.2);
    overflow: hidden;
    animation: panelSlideIn 0.25s cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes panelSlideIn {
    from { transform: translateX(100%); }
    to   { transform: translateX(0); }
}

.admin-overlay.is-closing .admin-panel {
    animation: panelSlideOut 0.22s cubic-bezier(0.4, 0, 0.2, 1) both;
}

@keyframes panelSlideOut {
    from { transform: translateX(0); }
    to   { transform: translateX(100%); }
}

@media (prefers-reduced-motion: reduce) {
    .admin-overlay, .admin-overlay.is-closing { animation: none; }
    .admin-panel, .admin-overlay.is-closing .admin-panel { animation: none; }
}

/* Header */
.admin-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 20px;
    padding-top: calc(env(safe-area-inset-top, 0px) + 16px);
    background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
    color: var(--text-inverse);
    flex-shrink: 0;
}

.admin-panel-title {
    margin: 0;
    font-size: var(--text-lg);
    font-weight: 700;
    letter-spacing: 0.3px;
}

.admin-close-btn {
    background: rgba(255, 255, 255, 0.2);
    border: none;
    color: var(--text-inverse);
    font-size: var(--text-md);
    width: 32px;
    height: 32px;
    border-radius: var(--radius-round);
    cursor: pointer;
    line-height: 1;
}

.admin-close-btn:hover {
    background: rgba(255, 255, 255, 0.35);
}

/* Tabs */
.admin-tabs {
    display: flex;
    border-bottom: 2px solid var(--border-color, #eee);
    flex-shrink: 0;
}

.admin-tab-btn {
    flex: 1;
    padding: 12px;
    border: none;
    background: none;
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--text-muted, #666);
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: color var(--duration-fast), border-color var(--duration-fast);
}

.admin-tab-btn.active {
    color: var(--primary-color, #111);
    border-bottom-color: var(--primary-color, #111);
}

/* Tab panels */
.admin-tab-panel {
    flex: 1;
    overflow-y: auto;
    padding: 16px 20px;
}

.admin-tab-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 14px;
}

.admin-tab-hint {
    font-size: var(--text-sm);
    color: var(--text-muted, #888);
}

/* User cards */
.admin-users-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.admin-user-card {
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.admin-user-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    background: var(--bg-light, #f9fafb);
    flex-wrap: wrap;
}

.admin-user-identity {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.admin-user-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-color, #111);
}

.admin-user-username {
    font-size: 12px;
    color: var(--text-muted, #666);
}

.admin-user-email {
    font-size: 11px;
    color: var(--text-muted, #888);
}

.admin-user-badges {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}

.admin-user-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* Keys section */
.admin-keys-section {
    padding: 10px 14px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.admin-key-row {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.admin-key-name {
    font-size: var(--text-sm);
    color: var(--text-muted, #666);
    min-width: 60px;
}

.admin-key-value {
    font-family: monospace;
    font-size: var(--text-xs);
    background: var(--bg-tertiary, #f3f4f6);
    padding: 2px 6px;
    border-radius: var(--radius-xs);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
    user-select: all;
}

.admin-no-keys {
    font-size: var(--text-sm);
    color: var(--text-muted, #aaa);
    font-style: italic;
}

/* Badges */
.admin-badge {
    font-size: var(--text-xs);
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius-lg);
    white-space: nowrap;
}

.admin-badge--green {
    background: #d1fae5;
    color: #065f46;
}

.admin-badge--grey {
    background: #f3f4f6;
    color: #6b7280;
}

.admin-badge--purple {
    background: #ede9fe;
    color: #5b21b6;
}

.admin-badge--blue {
    background: #dbeafe;
    color: #1d4ed8;
}

/* Buttons */
.admin-btn {
    padding: 5px 10px;
    font-size: var(--text-sm);
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-color, #d1d5db);
    background: var(--bg-white);
    cursor: pointer;
    white-space: nowrap;
    transition: background var(--duration-fast);
}

.admin-btn:hover {
    background: var(--bg-light, #f5f5f5);
}

.admin-btn--xs {
    padding: 3px 7px;
    font-size: 11px;
}

.admin-btn--primary {
    background: var(--primary-color, #111);
    color: var(--text-inverse);
    border-color: var(--primary-color, #111);
    padding: 9px 18px;
    font-size: var(--text-base);
    font-weight: 600;
    border-radius: var(--radius-md);
    width: 100%;
    margin-top: 4px;
}

.admin-btn--primary:hover {
    background: var(--primary-dark, #5a6fd6);
}

.admin-btn--danger {
    border-color: #fca5a5;
    color: #dc2626;
}

.admin-btn--danger:hover {
    background: #fef2f2;
}

.admin-btn--active {
    border-color: #93c5fd;
    color: #1d4ed8;
    background: #dbeafe;
}

.admin-btn--active:hover {
    background: #bfdbfe;
}

/* Create user form */
.admin-create-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.admin-field {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.admin-field label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-color, #333);
}

.admin-required {
    color: #dc2626;
}

.admin-input {
    padding: 9px 12px;
    border: 1px solid var(--border-color, #d1d5db);
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    outline: none;
    transition: border-color var(--duration-fast), box-shadow var(--duration-fast);
}

.admin-input:focus {
    border-color: var(--primary-color, #111);
    box-shadow: var(--shadow-focus);
}

.admin-field--inline {
    flex-direction: row;
    align-items: center;
    gap: 10px;
}

.admin-field--inline label {
    margin: 0;
}

.admin-checkbox {
    width: 17px;
    height: 17px;
    cursor: pointer;
    accent-color: var(--primary-color, #111);
}

/* Create result / success box */
.admin-create-result {
    margin-top: 16px;
}

.admin-create-success {
    background: #f0fdf4;
    border: 1px solid #86efac;
    border-radius: var(--radius-md);
    padding: 14px 16px;
}

.admin-create-success p {
    margin: 8px 0 6px;
    font-size: 13px;
    color: #166534;
}

.admin-new-key-display {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--bg-white);
    border: 1px solid #86efac;
    border-radius: var(--radius-sm);
    padding: 8px 10px;
    margin-top: 6px;
}

.admin-new-key-display code {
    flex: 1;
    font-size: var(--text-sm);
    word-break: break-all;
    color: #065f46;
}

/* Misc states */
.admin-loading,
.admin-empty,
.admin-error {
    padding: 32px;
    text-align: center;
    color: var(--text-muted, #888);
    font-size: var(--text-base);
}

.admin-error {
    color: #dc2626;
}

/* ─── Trigger Log Table ─────────────────────────────────────── */
.trigger-log-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.trigger-log-table th {
    text-align: left;
    padding: 6px 8px;
    border-bottom: 2px solid #e5e7eb;
    font-weight: 600;
    color: #374151;
    background: #f9fafb;
}

.trigger-log-table td {
    padding: 6px 8px;
    border-bottom: 1px solid #f3f4f6;
    vertical-align: top;
}

.trigger-log-table tr:hover td {
    background: #f9fafb;
}

/* ─── Console Log Panel ─────────────────────────────────────── */
.console-log-entry {
    padding: 1px 0;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}

.console-log-log {
    color: #e2e8f0;
}

.console-log-info {
    color: #93c5fd;
}

.console-log-debug {
    color: #94a3b8;
}

.console-log-warn {
    color: #fbbf24;
}

.console-log-error {
    color: #f87171;
}


/* ─── Site Settings Tab ─────────────────────────────────────── */
.admin-site-settings {
    padding: 8px 0;
}

.admin-settings-section {
    margin-bottom: 24px;
}

.admin-settings-section-title {
    font-size: 14px;
    font-weight: 600;
    margin: 0 0 4px;
}

.admin-settings-section-desc {
    font-size: 12px;
    color: #666;
    margin: 0 0 12px;
    line-height: 1.5;
}

.admin-condition-props-list {
    border: 1px solid #e5e7eb;
    border-radius: 6px;
    overflow: hidden;
    margin-bottom: 12px;
}

.admin-cond-category {
    border-bottom: 1px solid #e5e7eb;
}

.admin-cond-category:last-child {
    border-bottom: none;
}

.admin-cond-category-header {
    padding: 6px 10px;
    background: #f9fafb;
}

.admin-cond-cat-all {
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-size: 12px;
}

.admin-cond-props {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0;
    padding: 4px 10px 8px;
}

.admin-cond-prop-row {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 0;
    cursor: pointer;
    font-size: 12px;
    color: #374151;
}

.admin-settings-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.admin-settings-status {
    font-size: 12px;
    color: #16a34a;
}

/* ── User Profile Panel ───────────────────────────────────────────────────── */

.user-profile-overlay {
    display: none;
}

.user-profile-overlay.active {
    display: flex;
}

.user-profile-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.user-profile-header-accent {
    height: 8px;
    border-radius: var(--radius-sm, 6px) var(--radius-sm, 6px) 0 0;
    background: var(--bg-secondary, #f3f4f6);
    flex-shrink: 0;
}

.up-identity {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1;
    min-width: 0;
}

.up-display-name {
    font-size: var(--text-md, 15px);
    font-weight: 700;
    color: var(--text-color, #111);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.up-username {
    font-size: var(--text-sm, 13px);
    color: var(--text-muted, #666);
}

.up-bio {
    font-size: var(--text-sm, 13px);
    color: var(--text-secondary, #444);
    padding: 8px 16px 0;
    margin: 0;
    line-height: 1.5;
}

.user-profile-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 16px 20px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.up-stat {
    font-size: var(--text-sm, 13px);
    color: var(--text-muted, #666);
}

.up-stat-value {
    font-weight: 700;
    color: var(--text-color, #111);
    font-size: var(--text-md, 15px);
}

.up-section-title {
    font-size: var(--text-sm, 13px);
    font-weight: 700;
    color: var(--text-color, #111);
    margin-top: 4px;
}

.up-project-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.up-project-item {
    padding: 8px 10px;
    background: var(--bg-secondary, #f3f4f6);
    border-radius: var(--radius-sm, 6px);
    font-size: var(--text-sm, 13px);
    cursor: pointer;
    transition: background 0.15s;
}

.up-project-item:hover {
    background: var(--bg-hover, #e5e7eb);
}

.up-filter-sounds-btn,
.up-edit-profile-btn {
    align-self: flex-start;
}

.up-loading,
.up-error {
    font-size: var(--text-sm, 13px);
    color: var(--text-muted, #666);
    text-align: center;
    padding: 20px 0;
}

.uploader-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.uploader-filter-clear {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 11px;
    padding: 0 2px;
    color: inherit;
    opacity: 0.7;
    line-height: 1;
}

.uploader-filter-clear:hover {
    opacity: 1;
}

.sound-uploader-chip {
    cursor: pointer;
    text-decoration: underline;
    text-decoration-style: dotted;
    text-underline-offset: 2px;
}

.sound-uploader-chip:hover {
    color: var(--primary-color, #111);
}

/* ─── Session Recorder (debug panel card + summary overlay) ──────────────── */
.session-recorder-status {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin: 8px 0;
    min-height: 18px;
}

.session-recorder-status.recording {
    color: #dc2626;
    font-weight: 600;
}

.srs-session-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 1px solid var(--border-color, #eee);
}

.srs-session-meta {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.srs-session-actions {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}

.srs-badge-partial {
    font-size: var(--text-xs);
    color: #b45309;
    background: #fef3c7;
    border-radius: 8px;
    padding: 1px 7px;
}

.srs-badge-rec {
    font-size: var(--text-xs);
    color: #dc2626;
}

.srs-none {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    font-style: italic;
}

/* Summary overlay */
#session-recorder-summary-overlay {
    position: fixed;
    inset: 0;
    z-index: 10600;
    background: rgba(0, 0, 0, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 14px;
}

.srs-card {
    background: var(--bg-primary, #fff);
    border-radius: var(--radius-md, 12px);
    width: 100%;
    max-width: 560px;
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3);
}

.srs-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 14px 18px;
    border-bottom: 1px solid var(--border-color, #eee);
}

.srs-header h3 { margin: 0; }

.srs-close {
    background: none;
    border: none;
    font-size: 20px;
    color: #999;
    cursor: pointer;
}

.srs-body {
    padding: 14px 18px;
    overflow-y: auto;
}

.srs-body h4 {
    margin: 14px 0 6px;
    font-size: var(--text-sm);
}

.srs-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
}

.srs-stat {
    background: var(--bg-tertiary, #f6f6f6);
    border-radius: var(--radius-xs, 6px);
    padding: 8px 6px;
    text-align: center;
}

.srs-stat-value {
    font-weight: 700;
    font-size: var(--text-md);
}

.srs-stat-label {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.srs-anomaly {
    display: flex;
    gap: 8px;
    align-items: baseline;
    font-size: var(--text-xs);
    padding: 5px 8px;
    border-radius: var(--radius-xs, 6px);
    margin-bottom: 4px;
    background: #f8fafc;
    border-left: 3px solid #94a3b8;
}

.srs-anomaly.srs-error { background: #fef2f2; border-left-color: #dc2626; }
.srs-anomaly.srs-warn  { background: #fffbeb; border-left-color: #f59e0b; }

.srs-anomaly-rule { font-weight: 700; white-space: nowrap; }

.srs-anomaly-detail {
    flex: 1;
    word-break: break-word;
    color: var(--text-secondary);
}

.srs-anomaly-time {
    font-variant-numeric: tabular-nums;
    color: var(--text-lighter, #999);
    white-space: nowrap;
}

.srs-heard-row {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    padding: 2px 0;
}

.srs-footer {
    display: flex;
    justify-content: flex-end;
    gap: 8px;
    padding: 12px 18px;
    border-top: 1px solid var(--border-color, #eee);
}

.srs-badge-bench {
    font-size: var(--text-xs);
    color: #3730a3;
    background: #e0e7ff;
    border-radius: 8px;
    padding: 1px 7px;
}

/* ==== css/docs.css ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   DOCUMENTATION SCREEN
   ══════════════════════════════════════════════════════════════════════════ */

/* ─── Outer wrapper (fills the oul-screen) ──────────────────── */
/* ═══════════════════════════════════════════════════════════════════════════
   DOCS SCREEN
   ═══════════════════════════════════════════════════════════════════════════ */
#docs-screen {
    display: flex;
    flex-direction: column;
    background: var(--bg-white);
}

.docs-wrapper {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
    overflow: hidden;
    background: var(--bg-white);
    color: var(--text-color);
}

/* ─── Header bar ─────────────────────────────────────────────── */
.docs-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 12px;
    height: 48px;
    min-height: 48px;
    background: linear-gradient(135deg, var(--primary-color) 0%, var(--secondary-color) 100%);
    color: var(--text-inverse);
    z-index: var(--z-controls);
    flex-shrink: 0;
}

.docs-nav-toggle-btn {
    background: transparent;
    border: none;
    color: inherit;
    font-size: var(--text-lg);
    cursor: pointer;
    padding: 4px 6px;
    border-radius: var(--radius-xs);
    line-height: 1;
}

.docs-nav-toggle-btn:hover {
    background: rgba(255, 255, 255, 0.15);
}

.docs-header-title {
    flex: 1;
    font-weight: 600;
    font-size: var(--text-base);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.docs-version-badge {
    font-size: var(--text-xs);
    opacity: 0.75;
    white-space: nowrap;
}

.docs-header-btn {
    background: rgba(255, 255, 255, 0.15);
    border: 1px solid rgba(255, 255, 255, 0.3);
    color: inherit;
    font-size: var(--text-sm);
    padding: 4px 10px;
    border-radius: var(--radius-xs);
    cursor: pointer;
    white-space: nowrap;
}

.docs-header-btn:hover {
    background: rgba(255, 255, 255, 0.25);
}

.docs-close-btn {
    padding: 4px 8px;
}

/* ─── Body: nav sidebar + content area ──────────────────────── */
.docs-body {
    display: flex;
    flex: 1;
    /* Use min-height:0 so flexbox children can scroll independently on iOS */
    min-height: 0;
    overflow: hidden;
    position: relative;
    background: var(--bg-white);
}

/* ─── Sidebar nav ────────────────────────────────────────────── */
.docs-nav {
    width: 220px;
    min-width: 220px;
    background: var(--bg-secondary);
    border-right: 1px solid var(--border-color);
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    flex-shrink: 0;
    transition: width 0.25s ease, min-width 0.25s ease, transform 0.25s ease;
}

.docs-nav.docs-nav-closed {
    width: 0;
    min-width: 0;
    border-right: none;
    overflow: hidden;
}

.docs-nav-tree {
    padding: 8px 0 24px;
    /* Prevent content from being clipped during width transition */
    min-width: 220px;
}

/* Mobile backdrop (shown when nav is open on small screens) */
.docs-nav-backdrop {
    display: none;
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: calc(var(--z-overlay) - 1);
}

.docs-nav-backdrop.visible {
    display: block;
}

/* ─── Mobile layout: nav overlays content ─────────────────────
   Breakpoint matches the JS threshold in docs.js (_navOpen init)   */
@media (max-width: 640px) {
    .docs-nav {
        /* Lift out of flex flow — overlay on top of content */
        position: absolute;
        top: 0;
        left: 0;
        bottom: 0;
        z-index: var(--z-overlay);
        width: 82vw;
        max-width: 300px;
        min-width: 0;
        transform: translateX(-100%);
        /* Override desktop width-based transition */
        transition: transform 0.25s ease;
        box-shadow: 4px 0 20px rgba(0, 0, 0, 0.18);
        border-right: none;
    }

    .docs-nav.docs-nav-open {
        transform: translateX(0);
    }

    .docs-nav.docs-nav-closed {
        transform: translateX(-100%);
        width: 82vw;
        max-width: 300px;
        overflow: hidden;
    }

    .docs-nav-tree {
        min-width: 0;
    }

    /* Content always takes full width on mobile */
    .docs-content-area {
        padding: 16px 16px 40px;
    }

    /* Tighter header on narrow screens */
    .docs-version-badge {
        display: none;
    }

    /* Chapter/section items — bigger tap targets on mobile */
    .docs-chapter-heading {
        padding: 13px 14px;
    }

    .docs-section-btn {
        padding: 10px 14px 10px 30px;
    }
}

/* Chapter headings */
.docs-chapter {
    border-bottom: 1px solid var(--border-color);
}

.docs-chapter:last-child {
    border-bottom: none;
}

.docs-chapter-heading {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 10px 12px;
    background: transparent;
    border: none;
    text-align: left;
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-color);
}

.docs-chapter-heading:hover {
    background: var(--bg-tertiary);
}

.docs-chapter-icon {
    font-size: var(--text-base);
    flex-shrink: 0;
}

.docs-chapter-title {
    flex: 1;
}

.docs-chapter-chevron {
    font-size: var(--text-xs);
    opacity: 0.6;
}

/* Section list */
.docs-section-list {
    list-style: none;
    margin: 0;
    padding: 0 0 4px;
}

.docs-section-item {
    display: block;
}

.docs-section-btn {
    display: block;
    width: 100%;
    padding: 6px 12px 6px 28px;
    background: transparent;
    border: none;
    text-align: left;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    cursor: pointer;
    line-height: 1.4;
}

.docs-section-btn:hover {
    background: var(--bg-tertiary);
    color: var(--text-color);
}

.docs-section-item.active .docs-section-btn {
    background: var(--primary-color);
    color: var(--text-inverse);
    font-weight: 500;
}

/* Media status link */
.docs-media-status-link {
    font-weight: 500;
    opacity: 0.8;
}

/* ─── Content area ───────────────────────────────────────────── */
.docs-content-area {
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    padding: 24px 28px 48px;
    background: var(--bg-white);
    color: var(--text-color);
    line-height: 1.65;
    font-size: var(--text-base);
}

.docs-loading {
    color: var(--text-secondary);
    padding: 32px;
    text-align: center;
}

.docs-error {
    padding: 24px;
    background: #fef2f2;
    color: #dc2626;
    border-radius: var(--radius-md);
}

/* ─── Breadcrumb ─────────────────────────────────────────────── */
.docs-breadcrumb {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-bottom: 12px;
}

.docs-breadcrumb-sep {
    opacity: 0.5;
}

.docs-breadcrumb-section {
    color: var(--text-color);
    font-weight: 500;
}

/* ─── Staleness banner ───────────────────────────────────────── */
.docs-stale-banner {
    background: #fffbeb;
    border: 1px solid #f59e0b;
    border-radius: var(--radius-sm);
    padding: 8px 12px;
    font-size: var(--text-sm);
    color: #92400e;
    margin-bottom: 16px;
}

/* ─── Section footer ─────────────────────────────────────────── */
.docs-section-footer {
    margin-top: 32px;
    padding-top: 12px;
    border-top: 1px solid var(--border-color);
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

/* ─── Prev / Next navigation ─────────────────────────────────── */
.docs-prev-next {
    display: flex;
    justify-content: space-between;
    margin-top: 32px;
    padding-top: 16px;
    border-top: 1px solid var(--border-color);
    gap: 12px;
}

.docs-prev-btn,
.docs-next-btn {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 8px 14px;
    font-size: var(--text-sm);
    color: var(--text-color);
    cursor: pointer;
    max-width: 48%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.docs-prev-btn:hover,
.docs-next-btn:hover {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

.docs-next-btn {
    margin-left: auto;
}

/* ─── Content typography ─────────────────────────────────────── */
.docs-content-area h1 {
    font-size: var(--text-2xl);
    font-weight: 700;
    margin: 0 0 16px;
    line-height: 1.25;
}

.docs-content-area h2 {
    font-size: var(--text-xl);
    font-weight: 600;
    margin: 28px 0 12px;
}

.docs-content-area h3 {
    font-size: var(--text-lg);
    font-weight: 600;
    margin: 20px 0 8px;
}

.docs-content-area h4 {
    font-size: var(--text-base);
    font-weight: 600;
    margin: 16px 0 6px;
}

.docs-content-area p {
    margin: 0 0 12px;
}

.docs-content-area ul,
.docs-content-area ol {
    margin: 8px 0 12px 20px;
}

.docs-content-area li {
    margin-bottom: 4px;
}

.docs-content-area code {
    background: var(--bg-tertiary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    padding: 1px 5px;
    font-size: 0.9em;
    font-family: 'SF Mono', 'Fira Code', monospace;
}

.docs-content-area pre {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 12px;
    overflow-x: auto;
    font-size: var(--text-sm);
    margin: 0 0 16px;
}

.docs-content-area pre code {
    background: none;
    border: none;
    padding: 0;
}

.docs-content-area blockquote {
    border-left: 3px solid var(--primary-color);
    margin: 0 0 12px;
    padding: 6px 12px;
    color: var(--text-secondary);
    background: var(--bg-secondary);
    border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
}

.docs-content-area table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
    margin: 0 0 16px;
}

.docs-content-area th {
    background: var(--bg-tertiary);
    padding: 8px 10px;
    text-align: left;
    border-bottom: 2px solid var(--border-color);
    font-weight: 600;
}

.docs-content-area td {
    padding: 7px 10px;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}

.docs-content-area tr:hover td {
    background: var(--bg-secondary);
}

.docs-content-area a {
    color: var(--primary-color);
    text-decoration: none;
}

.docs-content-area a:hover {
    text-decoration: underline;
}

.docs-content-area strong {
    font-weight: 600;
}

.docs-content-area .tip,
.docs-content-area .note {
    background: #eff6ff;
    border: 1px solid #bfdbfe;
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    margin: 0 0 12px;
    font-size: var(--text-sm);
}

.docs-content-area .warning {
    background: #fffbeb;
    border: 1px solid #fde68a;
    border-radius: var(--radius-sm);
    padding: 10px 14px;
    margin: 0 0 12px;
    font-size: var(--text-sm);
}

.docs-content-area hr {
    border: none;
    border-top: 1px solid var(--border-color);
    margin: 24px 0;
}

.docs-section-empty {
    padding: 20px 0;
}

.docs-placeholder-text {
    color: var(--text-secondary);
    font-style: italic;
}

/* ─── Media blocks ───────────────────────────────────────────── */
.docs-media-item {
    margin: 16px 0;
    border-radius: var(--radius-sm);
    overflow: hidden;
}

.docs-media-image img.docs-img,
.docs-media-video video.docs-video {
    max-width: 100%;
    display: block;
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-color);
}

/* Screenshots are mobile UI — constrain to phone-like width and centre */
.docs-media-image.docs-media-type-screenshot {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.docs-media-image.docs-media-type-screenshot img.docs-img {
    max-width: 260px;
    width: 100%;
    max-height: 480px;
    object-fit: contain;
}

/* Illustrations (maps, diagrams) may be wider but not full-bleed */
.docs-media-image.docs-media-type-illustration img.docs-img {
    max-width: 85%;
    margin: 0 auto;
}

.docs-media-caption {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin: 4px 0 0;
    font-style: italic;
}

/* Pending review */
.docs-media-pending {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    background: #fffbeb;
    border: 1px dashed #f59e0b;
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    color: #92400e;
}

.docs-media-pending-icon {
    font-size: var(--text-lg);
}

.docs-media-pending-label {
    font-weight: 600;
}

.docs-media-pending-desc {
    color: #78350f;
    margin-left: 4px;
}

/* Needed */
.docs-media-needed {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 12px 14px;
    background: var(--bg-secondary);
    border: 1px dashed var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.docs-media-needed-icon {
    font-size: var(--text-xl);
    flex-shrink: 0;
}

.docs-media-needed-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.docs-media-needed-body strong {
    color: var(--text-color);
}

.docs-media-needed-body em {
    font-size: var(--text-xs);
    opacity: 0.7;
}

.docs-media-missing {
    color: #dc2626;
    font-size: var(--text-sm);
}

/* ─── Media status page ──────────────────────────────────────── */
.docs-media-intro {
    color: var(--text-secondary);
    margin-bottom: 16px;
}

.docs-media-summary-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
    margin-bottom: 24px;
}

.docs-media-summary-card {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 12px 16px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
}

.docs-media-summary-card strong {
    font-weight: 600;
    margin-bottom: 2px;
}

.docs-media-summary-sub {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.docs-media-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
}

.docs-media-table th {
    background: var(--bg-tertiary);
    padding: 8px 10px;
    text-align: left;
    border-bottom: 2px solid var(--border-color);
    font-weight: 600;
}

.docs-media-table td {
    padding: 6px 8px;
    border-bottom: 1px solid var(--border-color);
    vertical-align: top;
}

.docs-media-table-desc {
    max-width: 300px;
}

.docs-media-chapter-row td {
    background: var(--bg-secondary);
    padding: 8px 10px;
}

.docs-media-status-badge {
    display: inline-block;
    padding: 2px 7px;
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: 500;
    white-space: nowrap;
}

.docs-media-status-needed {
    background: #f3f4f6;
    color: #374151;
}

.docs-media-status-in-progress {
    background: #fef3c7;
    color: #92400e;
}

.docs-media-status-captured {
    background: #ffedd5;
    color: #9a3412;
}

.docs-media-status-approved {
    background: #dcfce7;
    color: #166534;
}

/* ─── Print frame (docs guide) — hidden at runtime ──────────── */
#docs-print-frame {
    display: none;
}

/* ─── Docs print styles ──────────────────────────────────────── */
@media print {

    /*
     * body.docs-printing is set by DocsManager.printGuide() before window.print().
     * Hide every app element; show only the injected #docs-print-frame.
     */
    body.docs-printing>* {
        display: none !important;
    }

    body.docs-printing #docs-print-frame {
        display: block !important;
        background: #fff !important;
        color: #222 !important;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        font-size: 11pt;
        line-height: 1.65;
        margin: 0;
        padding: 0;
    }

    @page {
        size: A4 portrait;
        margin: 20mm 18mm;

        @top-center {
            content: "One Unbroken Line — Author Guide";
            font-size: 9pt;
            color: #888;
        }

        @bottom-right {
            content: counter(page);
            font-size: 9pt;
            color: #888;
        }
    }

    /* ── Title page ─────────────────────────────────────────── */
    .dpt-title-page {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        min-height: 80vh;
        text-align: center;
        page-break-after: always;
    }

    .dpt-title-logo {
        font-size: 52pt;
        margin-bottom: 16pt;
    }

    .dpt-title {
        font-size: 28pt;
        font-weight: 700;
        margin: 0 0 8pt;
        color: #111;
    }

    .dpt-subtitle {
        font-size: 18pt;
        font-weight: 400;
        margin: 0 0 24pt;
        color: #444;
    }

    .dpt-meta {
        font-size: 11pt;
        color: #666;
        margin: 2pt 0;
    }

    .dpt-meta-date {
        font-size: 10pt;
        color: #888;
        margin-top: 8pt;
    }

    /* ── Table of contents ───────────────────────────────────── */
    .dpt-toc {
        page-break-after: always;
        padding: 0;
    }

    .dpt-toc-heading {
        font-size: 20pt;
        font-weight: 700;
        color: #111;
        margin: 0 0 16pt;
        padding-bottom: 6pt;
        border-bottom: 2px solid #111;
    }

    .dpt-toc-list {
        list-style: none;
        margin: 0;
        padding: 0;
        counter-reset: toc-chapter;
    }

    .dpt-toc-chapter {
        counter-increment: toc-chapter;
        margin: 0 0 10pt;
    }

    .dpt-toc-chapter-name {
        display: block;
        font-size: 12pt;
        font-weight: 700;
        color: #111;
        margin-bottom: 3pt;
    }

    .dpt-toc-sections {
        list-style: none;
        padding: 0 0 0 16pt;
        margin: 0;
    }

    .dpt-toc-sections li {
        font-size: 10pt;
        color: #444;
        line-height: 1.8;
    }

    .dpt-toc-sections a {
        color: #444;
        text-decoration: none;
    }

    /* ── Chapter headers ─────────────────────────────────────── */
    .dpt-chapter {
        page-break-before: always;
    }

    .dpt-chapter-header {
        display: flex;
        align-items: center;
        gap: 8pt;
        font-size: 18pt;
        font-weight: 700;
        color: #111;
        padding: 0 0 6pt;
        border-bottom: 2pt solid #111;
        margin-bottom: 16pt;
    }

    .dpt-chapter-icon {
        font-size: 20pt;
    }

    /* ── Sections ────────────────────────────────────────────── */
    .dpt-section {
        margin-bottom: 24pt;
        page-break-inside: avoid;
    }

    .dpt-section-meta {
        font-size: 8pt;
        color: #aaa;
        border-top: 0.5pt solid #ddd;
        margin-top: 10pt;
        padding-top: 4pt;
    }

    /* ── Content typography ──────────────────────────────────── */
    #docs-print-frame h1 {
        font-size: 16pt;
        font-weight: 700;
        margin: 0 0 8pt;
        color: #111;
    }

    #docs-print-frame h2 {
        font-size: 13pt;
        font-weight: 700;
        margin: 14pt 0 5pt;
        color: #222;
    }

    #docs-print-frame h3 {
        font-size: 11pt;
        font-weight: 700;
        margin: 10pt 0 4pt;
        color: #333;
    }

    #docs-print-frame h4 {
        font-size: 10pt;
        font-weight: 700;
        margin: 8pt 0 3pt;
    }

    #docs-print-frame p {
        margin: 0 0 7pt;
    }

    #docs-print-frame ul,
    #docs-print-frame ol {
        margin: 4pt 0 8pt 18pt;
    }

    #docs-print-frame li {
        margin-bottom: 2pt;
    }

    #docs-print-frame code {
        background: #f4f4f4;
        border: 0.5pt solid #ddd;
        border-radius: 2pt;
        padding: 0 3pt;
        font-family: 'SF Mono', 'Fira Code', monospace;
        font-size: 9pt;
    }

    #docs-print-frame pre {
        background: #f8f8f8;
        border: 0.5pt solid #ddd;
        border-radius: 3pt;
        padding: 8pt;
        font-size: 9pt;
        margin: 0 0 8pt;
        white-space: pre-wrap;
        word-break: break-all;
    }

    #docs-print-frame pre code {
        background: none;
        border: none;
        padding: 0;
    }

    #docs-print-frame blockquote {
        border-left: 3pt solid #aaa;
        margin: 0 0 8pt;
        padding: 4pt 8pt;
        color: #555;
    }

    #docs-print-frame table {
        width: 100%;
        border-collapse: collapse;
        font-size: 9pt;
        margin: 0 0 8pt;
    }

    #docs-print-frame th {
        background: #f0f0f0;
        padding: 5pt 8pt;
        border: 0.5pt solid #ccc;
        text-align: left;
        font-weight: 700;
    }

    #docs-print-frame td {
        padding: 4pt 8pt;
        border: 0.5pt solid #ddd;
        vertical-align: top;
    }

    #docs-print-frame .tip,
    #docs-print-frame .note {
        border: 0.5pt solid #b3d1ff;
        background: #f0f6ff;
        padding: 6pt 10pt;
        margin: 0 0 8pt;
        border-radius: 3pt;
        font-size: 10pt;
    }

    #docs-print-frame .warning {
        border: 0.5pt solid #f0c040;
        background: #fffbe6;
        padding: 6pt 10pt;
        margin: 0 0 8pt;
        border-radius: 3pt;
        font-size: 10pt;
    }

    /* Approved images print; placeholders are hidden */
    .docs-media-image img.docs-img {
        max-width: 100%;
        border: 0.5pt solid #ccc;
        display: block;
        margin: 8pt 0 4pt;
    }

    /* Screenshots: phone-sized thumbnail — never bigger than a third of the page height */
    .docs-media-image.docs-media-type-screenshot {
        display: flex;
        flex-direction: column;
        align-items: center;
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .docs-media-image.docs-media-type-screenshot img.docs-img {
        max-width: 38%;
        max-height: 200pt;
        object-fit: contain;
        border: 0.5pt solid #ccc;
        margin: 6pt auto 2pt;
    }

    /* Illustrations: can be wider but still avoid page breaks through them */
    .docs-media-image.docs-media-type-illustration {
        break-inside: avoid;
        page-break-inside: avoid;
    }

    .docs-media-image.docs-media-type-illustration img.docs-img {
        max-width: 80%;
        margin: 6pt auto 2pt;
    }

    .docs-media-caption {
        font-size: 8pt;
        color: #777;
        font-style: italic;
        margin-bottom: 8pt;
    }

    .docs-media-needed,
    .docs-media-pending,
    .docs-media-missing {
        display: none !important;
    }
}

/* ─── Mobile responsive ──────────────────────────────────────────
   NOTE: the .docs-nav drawer layout is governed by the @media(max-width:640px)
   block above (matches docs.js _isMobile()). Do NOT re-position .docs-nav here
   — an earlier `top: 48px` override added a spurious gap because the nav is
   already inside .docs-body, which sits below the 48px header. */
@media (max-width: 600px) {
    .docs-content-area {
        padding: 16px 16px 48px;
    }

    .docs-media-summary-grid {
        grid-template-columns: 1fr;
    }
}


/* ==== css/zones.css ==== */
/* ─── Zone List Redesign ─────────────────────────────────────── */

/* View mode toggle buttons (in zone section header) */
.zone-view-controls {
    display: flex;
    gap: 2px;
    align-items: center;
}

.zone-view-btn {
    width: 28px;
    height: 28px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    background: var(--bg-white);
    color: var(--text-muted);
    font-size: 14px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--duration-fast);
    line-height: 1;
}

.zone-view-btn:hover {
    background: var(--bg-light);
    color: var(--text-color);
}

.zone-view-btn.active {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

/* Filter chip bar (replaces zone-filter-select) */
.zone-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
    align-items: center;
}

.zone-filter-chip {
    padding: 4px 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-pill);
    background: var(--bg-white);
    color: var(--text-secondary);
    font-size: var(--text-sm);
    cursor: pointer;
    transition: all var(--duration-fast);
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 5px;
}

.zone-filter-chip:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.zone-filter-chip.active {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

.zone-filter-chip--hide-markers.active {
    background: var(--warning-color);
    border-color: var(--warning-color);
}

.zone-filter-divider {
    color: var(--border-color);
    font-size: var(--text-md);
    user-select: none;
}

/* Zone list wrapper — always full width */
.zone-list-wrapper {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════════
   ZONE CARDS & LIST
   ═══════════════════════════════════════════════════════════════════════════ */
.zone-card {
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 14px 16px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    transition: box-shadow var(--duration-fast);
}

.zone-card:hover {
    box-shadow: var(--shadow-md);
}

.zone-card.is-disabled {
    opacity: 0.6;
}

.zone-card-header {
    display: flex;
    align-items: center;
    gap: 10px;
}

.zone-card-dot {
    width: 10px;
    height: 10px;
    border-radius: var(--radius-round);
    flex-shrink: 0;
}

.zone-card-name {
    font-weight: 600;
    font-size: 15px;
    color: var(--text-color);
    margin: 0;
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.zone-card-badges {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    align-items: center;
}

/* Zone-specific badges */
.zone-badge {
    padding: 2px 7px;
    border-radius: var(--radius-pill);
    font-size: var(--text-xs);
    font-weight: 500;
    white-space: nowrap;
}

.zone-badge.enabled {
    background: rgba(39, 174, 96, 0.1);
    color: #1a7a43;
}

.zone-badge.disabled {
    background: rgba(200, 200, 200, 0.2);
    color: var(--text-muted);
}

.zone-badge.marker {
    background: rgba(33, 150, 243, 0.1);
    color: #1565c0;
}

.zone-badge.broadcast {
    background: rgba(156, 39, 176, 0.1);
    color: #6a1b9a;
}

.zone-badge.circle {
    background: rgba(255, 152, 0, 0.08);
    color: #e65100;
}

.zone-badge.polygon {
    background: rgba(0, 150, 136, 0.1);
    color: #00695c;
}

.zone-card-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
    font-size: var(--text-sm);
    color: var(--text-muted);
}

.zone-meta-item {
    display: flex;
    align-items: center;
    gap: 4px;
}

.zone-meta-item.no-sound {
    color: var(--text-lighter);
    font-style: italic;
}

.zone-card-actions {
    display: flex;
    gap: 6px;
    margin-top: 2px;
}

.zone-action-btn {
    padding: 6px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    background: var(--bg-white);
    color: var(--text-secondary);
    font-size: var(--text-sm);
    cursor: pointer;
    transition: all var(--duration-fast);
}

.zone-action-btn:hover {
    background: var(--bg-light);
}

.zone-action-btn.primary {
    background: var(--primary-color);
    color: var(--text-inverse);
    border-color: var(--primary-color);
}

.zone-action-btn.primary:hover {
    background: var(--primary-dark);
}

.zone-action-btn.toggle-on {
    background: rgba(39, 174, 96, 0.1);
    color: #1a7a43;
    border-color: rgba(39, 174, 96, 0.3);
}

.zone-action-btn.toggle-on:hover {
    background: rgba(39, 174, 96, 0.2);
}

.zone-action-btn.toggle-off {
    background: rgba(200, 200, 200, 0.15);
    color: var(--text-muted);
    border-color: var(--border-color);
}

.zone-action-btn.toggle-off:hover {
    background: rgba(200, 200, 200, 0.3);
}

/* ─── Zone List Rows (List view mode) ────────────────────────── */

.zone-list-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 12px;
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    transition: background 0.1s;
    min-height: 44px;
}

.zone-list-item:hover {
    background: var(--bg-light);
}

.zone-list-item.is-disabled {
    opacity: 0.55;
}

.zone-list-item.is-draggable {
    cursor: default;
}

.zone-list-item.dragging {
    opacity: 0.4;
    border-style: dashed;
}

.zone-list-item.drag-over {
    border-color: var(--primary-color);
    background: var(--bg-light);
    box-shadow: 0 0 0 2px var(--primary-light, #e0e7ff) inset;
}

.zone-drag-handle {
    font-size: 16px;
    color: var(--text-lighter);
    cursor: grab;
    flex-shrink: 0;
    padding: 0 2px;
    user-select: none;
    line-height: 1;
}

.zone-drag-handle:active {
    cursor: grabbing;
}

.zone-select-checkbox {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    cursor: pointer;
    accent-color: var(--primary-color);
}

.zone-list-dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-round);
    flex-shrink: 0;
}

.zone-list-text {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.zone-list-name {
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--text-color);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.zone-list-type {
    font-size: 18px;
    color: var(--text-lighter);
    flex-shrink: 0;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
}

.zone-list-sound {
    font-size: var(--text-xs);
    color: var(--text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    display: flex;
    align-items: center;
    gap: 5px;
}

.zone-list-props {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 4px;
    margin-top: 1px;
}

.zone-prop-icon {
    font-size: 12px;
    color: var(--text-lighter);
    opacity: 0.6;
    line-height: 1;
    display: flex;
    align-items: center;
}

.zone-prop-icon svg,
.zone-prop-icon .oul-icon {
    width: 12px;
    height: 12px;
}

/* Thin/small-geometry safety warning — full opacity + colour so it doesn't
   read as just another muted property chip. */
.zone-prop-icon--warn {
    color: var(--warning-color, #f39c12);
    opacity: 1;
}

.zone-prop-icon--danger {
    color: var(--danger-color, #e74c3c);
    opacity: 1;
}

.path-item-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.path-right {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    margin-left: auto;
}

.path-meta {
    font-size: var(--text-xs);
    color: var(--text-muted);
    white-space: nowrap;
}

.zone-list-actions {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}

.zone-list-btn {
    width: 30px;
    height: 30px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    background: var(--bg-white);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    transition: all 0.1s;
    color: var(--text-secondary);
}

.zone-list-btn:hover {
    background: var(--bg-tertiary);
}

.zone-list-btn.playing {
    background: var(--primary-color, #111);
    color: var(--text-inverse, #fff);
    border-color: var(--primary-color, #111);
}

.zone-list-btn.playing:hover {
    background: var(--primary-hover, #333);
}

/* ─── Denser list rows on phones ─────────────────────────────────
   Trim horizontal padding/gaps so zone & pool names get more room and
   don't feel cramped. Touch height is preserved (min-height 44px). */
@media (max-width: 640px) {
    .zone-list-wrapper {
        gap: 4px;
    }

    .zone-list-item {
        gap: 8px;
        padding: 8px 8px;
    }

    .zone-list-actions {
        gap: 2px;
    }

    .zone-list-btn {
        width: 30px;
        height: 30px;
    }

    .zone-controls-row {
        gap: 6px;
        margin-bottom: 6px;
    }

    /* Pool rows reuse the zone-list card classes — same treatment applies. */
}

/* ─── Zone Toggle Switch ─────────────────────────────────────── */

.zone-toggle-switch {
    position: relative;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    flex-shrink: 0;
}

.zone-toggle-switch input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.zone-toggle-track {
    width: 34px;
    height: 18px;
    background: var(--bg-tertiary);
    border-radius: var(--radius-pill);
    border: 1px solid var(--border-color);
    transition: background var(--duration-normal), border-color var(--duration-normal);
    position: relative;
}

.zone-toggle-track::after {
    content: '';
    position: absolute;
    top: 1px;
    left: 1px;
    width: 14px;
    height: 14px;
    border-radius: var(--radius-round);
    background: var(--text-lighter);
    transition: transform var(--duration-normal), background var(--duration-normal);
}

.zone-toggle-switch input:checked+.zone-toggle-track {
    background: var(--success-color);
    border-color: var(--success-color);
}

.zone-toggle-switch input:checked+.zone-toggle-track::after {
    transform: translateX(16px);
    background: white;
}

/* ─── Per-Project Theme Editor ───────────────────────────────── */

.theme-editor {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.theme-color-row {
    display: flex;
    align-items: center;
    gap: 10px;
}

.theme-color-label {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    flex: 1;
    min-width: 100px;
}

.theme-color-picker {
    width: 40px;
    height: 32px;
    padding: 2px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    cursor: pointer;
    background: var(--bg-white);
}

.theme-select {
    flex: 1 1 auto;
    min-width: 0;
    height: 34px;
    padding: 4px 8px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    background: var(--bg-white);
    color: var(--text-color);
    font-size: var(--text-sm);
    cursor: pointer;
}

.theme-file {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.theme-preview-action {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 8px;
    align-items: flex-start;
}

.theme-color-value {
    font-size: var(--text-sm);
    color: var(--text-muted);
    font-family: monospace;
    width: 60px;
}

.theme-preview-bar {
    display: flex;
    gap: 8px;
    align-items: center;
    padding: 10px;
    background: var(--bg-light);
    border-radius: var(--radius-sm);
    border: 1px solid var(--border-color);
}

.theme-preview-btn {
    padding: 6px 14px;
    border: none;
    border-radius: var(--radius-sm);
    color: white;
    font-size: var(--text-sm);
    cursor: default;
    font-weight: 500;
}

.theme-preview-badge {
    padding: 3px 8px;
    border-radius: var(--radius-pill);
    color: white;
    font-size: var(--text-xs);
    font-weight: 500;
}

.theme-preview-label {
    font-size: var(--text-xs);
    color: var(--text-muted);
    margin-left: auto;
}

/* Zone header row — houses search + view mode side-by-side */
.zone-controls-row {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-bottom: 8px;
}

.zone-controls-row .zone-search-input {
    flex: 1;
    margin-bottom: 0;
}

/* ═══════════════════════════════════════════════════════════════════
   Zone Groups
   ═══════════════════════════════════════════════════════════════════ */

.zone-group-header {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 8px;
    background: var(--bg-secondary);
    border-radius: var(--radius-sm);
    font-size: var(--text-sm);
    font-weight: 600;
    cursor: pointer;
    user-select: none;
    margin-top: 4px;
}

.zone-group-header:first-child {
    margin-top: 0;
}

.zone-group-header--ungrouped {
    cursor: default;
    font-weight: 400;
    background: transparent;
    border-top: 1px solid var(--border-subtle);
    border-radius: 0;
    margin-top: 8px;
    padding-top: 8px;
}

.group-chevron {
    background: none;
    border: none;
    padding: 2px;
    font-size: 16px;
    color: var(--text-muted);
    cursor: pointer;
    line-height: 1;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    min-height: 20px;
    transform: rotate(90deg);
    transition: transform 0.15s ease;
}

.group-chevron.collapsed {
    transform: rotate(0deg);
}

.group-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.group-count {
    color: var(--text-muted);
    font-weight: 400;
    font-size: var(--text-xs);
    flex-shrink: 0;
}

.group-actions {
    display: flex;
    gap: 2px;
    margin-left: 4px;
}

.group-action-btn {
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    font-size: 16px;
    border-radius: var(--radius-xs);
    color: var(--text-secondary);
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 24px;
    min-height: 24px;
}

.group-action-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.zone-group-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding-left: 12px;
    padding-top: 2px;
}

.zone-group-body[data-collapsed="true"] {
    display: none;
}

/* ── Groups management panel ── */
.zone-groups-panel {
    background: var(--bg-secondary);
    border-radius: var(--radius-md);
    padding: 10px 12px;
    margin-bottom: 8px;
    border: 1px solid var(--border-subtle);
}

.zone-groups-panel-header {
    display: grid;
    grid-auto-flow: column;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
}

.zone-groups-panel-title {
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text-secondary);
}

.zone-groups-list {
    display: grid;
    grid-auto-flow: row;
    gap: 4px;
}

.zone-groups-empty {
    font-size: var(--text-sm);
    color: var(--text-muted);
    text-align: center;
    padding: 8px 0;
    margin: 0;
}

.zone-group-panel-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 5px 8px;
    border-radius: var(--radius-sm);
    background: var(--bg-primary);
    font-size: var(--text-sm);
}

.zone-group-panel-row:hover .group-actions {
    opacity: 1;
}

.zone-group-panel-name {
    flex: 1;
    font-weight: 500;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* ── Batch "Move to Group" dropdown ── */
.batch-move-group-wrapper {
    position: relative;
}

.batch-group-menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    background: var(--bg-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    min-width: 140px;
    z-index: 200;
    padding: 4px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.batch-group-menu-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    background: none;
    border: none;
    border-radius: var(--radius-sm);
    cursor: pointer;
    font-size: var(--text-sm);
    color: var(--text-primary);
    text-align: left;
    width: 100%;
}

.batch-group-menu-item:hover {
    background: var(--bg-hover);
}

/* Sound Library collapsed summary strip */
.sound-library-summary {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
    padding: 6px 2px 8px;
    font-size: 12px;
    color: var(--text-secondary, #666);
}

.sound-library-summary .sl-sep {
    color: var(--text-tertiary, #aaa);
}

.sound-library-summary .sl-stat {
    font-variant-numeric: tabular-nums;
}

.sound-library-summary .sl-used {
    color: var(--success-color, #27ae60);
    font-weight: 500;
}

.sound-library-summary .sl-unused {
    color: var(--text-secondary, #888);
}

.sound-library-summary .sl-size {
    color: var(--text-secondary, #888);
}

.sound-library-summary .sl-empty {
    font-style: italic;
}
/* Sound-pool list chips. "Sticky" changes how a pool behaves per zone, so it is
   called out by name — an icon variant alone reads as decoration. */
.pool-chip {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 7px;
    border-radius: var(--radius-lg, 12px);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: middle;
    white-space: nowrap;
}

.pool-chip-sticky {
    background: var(--primary-color, #111);
    color: var(--text-inverse, #fff);
}

/* Marks the project's most recently modified zone in the list. */
.zone-chip-lastedit {
    background: transparent;
    color: var(--primary-color, #111);
    border: 1px solid currentColor;
    opacity: 0.75;
}

/* ==== css/onboarding.css ==== */
#onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

#onboarding-card {
  background: var(--bg-white, #fff);
  border-radius: 16px;
  padding: 32px 24px 24px;
  max-width: 480px;
  width: 90%;
  max-height: 90dvh;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 16px;
  position: relative;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
}

/* Step enter animation — triggered by JS adding/removing this class */
@keyframes onboarding-fadein {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
#onboarding-card.onboarding-step-enter {
  animation: onboarding-fadein 0.22s ease forwards;
}

#onboarding-skip {
  position: absolute;
  top: 14px;
  right: 14px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1;
}
#onboarding-skip:hover { color: var(--text-primary); }

#onboarding-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: 4px;
}
#onboarding-dots span {
  width: 8px;
  height: 8px;
  border-radius: 4px;
  background: var(--border-color, #e0e0e0);
  transition: background 0.2s, width 0.2s;
  display: inline-block;
}
/* Current step — wider pill */
#onboarding-dots span.active {
  background: var(--primary-color, #111);
  width: 20px;
}
/* Already-visited steps — softer fill */
#onboarding-dots span.visited {
  background: var(--text-muted, #888);
  opacity: 0.4;
}

#onboarding-asset {
  height: 200px;
  border-radius: 12px;
  background: var(--bg-secondary, #f5f5f5);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
}
#onboarding-asset img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 16px;
}

.onboarding-asset-placeholder {
  border: 2px dashed var(--border-color, #e0e0e0);
  border-radius: 10px;
  color: var(--text-muted);
  font-size: 12px;
  text-align: center;
  padding: 16px;
  width: calc(100% - 32px);
  height: calc(100% - 32px);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  line-height: 1.4;
}
.onboarding-asset-placeholder strong {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.6;
}

#onboarding-title {
  font-size: 20px;
  font-weight: 700;
  margin: 0;
  line-height: 1.2;
}

#onboarding-body {
  font-size: 15px;
  color: var(--text-secondary, #555);
  margin: 0;
  line-height: 1.55;
}

#onboarding-cta-primary {
  margin-top: 4px;
}

#onboarding-cta-secondary {
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 14px;
  cursor: pointer;
  padding: 6px;
  text-align: center;
  transition: color 0.15s;
}
#onboarding-cta-secondary:hover { color: var(--text-primary); }

/* Location step — spinner state */
#onboarding-cta-primary[data-loading] {
  opacity: 0.7;
  cursor: wait;
}

@media (max-height: 600px) {
  #onboarding-asset { height: 120px; }
  #onboarding-card { padding: 20px 20px 16px; gap: 10px; max-height: 95dvh; }
  #onboarding-title { font-size: 17px; }
  #onboarding-body { font-size: 14px; }
}

/* ==== css/contributions.css ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   CONTRIBUTION FLOW
   ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Contribution badge on zone list rows ──────────────────────── */
.zone-list-contrib-badge {
    font-size: 12px;
    flex-shrink: 0;
    opacity: 0.8;
    cursor: default;
}

/* ─── Experience-mode layout (shared by guest mode AND listener preview) ──
   Both guest mode and the editor's "Preview as listener" add
   body.experience-mode; guest mode additionally adds body.guest-mode for
   guest-only extras (sign-in banner). */
body.experience-mode #zones-paths-section,
body.experience-mode #audio-section,
body.experience-mode #sounds-section,
body.experience-mode #modifiers-section,
body.experience-mode #project-stats-section,
body.experience-mode #zone-batch-toggle,
body.experience-mode #zone-reorder-btn,
body.experience-mode #new-zone-btn,
body.experience-mode #new-zone-map-btn,
body.experience-mode #toggle-edit-mode-btn,
body.experience-mode #triggers-btn,
body.experience-mode #open-contribution-panel-btn,
body.experience-mode #edit-current-project-btn,
body.experience-mode #change-project-btn {
    display: none !important;
}

/* Minimal guest project header (name + description) */
.guest-project-header {
    padding: 14px 16px 6px;
    text-align: center;
}

.guest-project-name {
    margin: 0;
    font-size: var(--text-xl, 20px);
    font-family: var(--font-display, inherit);
    color: var(--text-color);
}

.guest-project-desc {
    margin: 6px auto 0;
    max-width: 600px;
    font-size: var(--text-base, 14px);
    color: var(--text-secondary, #555);
    line-height: 1.5;
}

.guest-header-actions {
    margin-top: 12px;
    display: flex;
    justify-content: center;
    gap: 8px;
    flex-wrap: wrap;
}

/* ─── Offline download hint popover ───────────────────────────────── */
.offline-dl-hint {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
    padding: 9px 14px 9px 12px;
    background: var(--primary-color, #111);
    color: var(--text-inverse, #fff);
    border-radius: var(--radius-md, 8px);
    font-size: var(--text-sm, 12px);
    cursor: pointer;
    animation: offline-hint-in 0.3s ease;
    max-width: 280px;
    box-shadow: 0 3px 10px rgba(0,0,0,0.25);
    user-select: none;
    -webkit-user-select: none;
}

/* upward-pointing arrow pointing at the download button above */
.offline-dl-hint::before {
    content: '';
    position: absolute;
    top: -7px;
    left: 50%;
    transform: translateX(-50%);
    border: 7px solid transparent;
    border-top: 0;
    border-bottom-color: var(--primary-color, #111);
}

.offline-dl-hint-text {
    flex: 1;
    line-height: 1.4;
}

.offline-dl-hint-close {
    background: none;
    border: none;
    color: var(--text-inverse, #fff);
    opacity: 0.55;
    cursor: pointer;
    padding: 0;
    font-size: 16px;
    line-height: 1;
    flex-shrink: 0;
}

.offline-dl-hint-close:hover { opacity: 0.9; }

@keyframes offline-hint-in {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Guests don't edit — only show this header outside the map */
body:not(.guest-mode) .guest-project-header {
    display: none;
}

/* ─── Listener-preview bar (editor previewing the experience view) ─── */
.listener-preview-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    background: var(--primary-color, #111);
    color: var(--text-inverse, #fff);
    padding: 10px 16px;
    padding-top: calc(env(safe-area-inset-top, 0px) + 10px);
    display: flex;
    align-items: center;
    gap: 12px;
    z-index: var(--z-top, 10001);
    font-size: var(--text-sm, 12px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
}

.listener-preview-bar span {
    flex: 1;
    opacity: 0.9;
}

body.listener-preview {
    /* reserve space so the bar doesn't cover the top */
}

.guest-mode-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background: var(--bg-dark, rgba(0, 0, 0, 0.8));
    color: #fff;
    /* See app-bar.js — Android's forced edge-to-edge display means this needs
       a real bottom inset; a no-op on iOS. */
    padding: 10px 16px calc(env(safe-area-inset-bottom, 0px) + 10px);
    display: flex;
    align-items: center;
    gap: 10px;
    z-index: var(--z-top, 10001);
    font-size: var(--text-sm, 12px);
}

.guest-mode-banner span {
    flex: 1;
    opacity: 0.8;
}

/* ─── Guest contribute FAB ──────────────────────────────────────── */
.guest-contribute-fab {
    position: fixed;
    bottom: 80px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--primary-color, #111);
    color: #fff;
    border: none;
    border-radius: var(--radius-pill, 20px);
    padding: 12px 24px;
    font-size: var(--text-base, 14px);
    font-weight: 600;
    cursor: pointer;
    box-shadow: var(--shadow-lg, 0 10px 40px rgba(0, 0, 0, 0.2));
    z-index: var(--z-panel, 9000);
    transition: transform var(--duration-fast), box-shadow var(--duration-fast);
}

.guest-contribute-fab:hover {
    transform: translateX(-50%) scale(1.05);
    box-shadow: 0 14px 48px rgba(0, 0, 0, 0.25);
}

/* ─── Contribution recording modal ──────────────────────────────── */
/* The contribution modal reuses .admin-overlay (top-right slide-over) but should
   be a centred dialog. */
#contribution-modal-overlay {
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.contribution-modal {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    width: 90%;
    max-width: 380px;
    overflow: hidden;
    box-shadow: var(--shadow-lg);
}

.contrib-modal-header {
    display: flex;
    align-items: center;
    padding: 16px 20px;
    border-bottom: 1px solid var(--border-color);
    gap: 12px;
}

.contrib-modal-header h3 {
    flex: 1;
    margin: 0;
    font-size: var(--text-md, 16px);
    font-weight: 600;
}

.contrib-modal-body {
    padding: 20px;
}

.contrib-step-hint {
    font-size: var(--text-sm, 12px);
    color: var(--text-muted);
    margin: 0 0 14px;
    line-height: 1.4;
}

.contrib-name-input {
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--text-base, 14px);
    color: var(--text-color);
    background: var(--bg-white);
    box-sizing: border-box;
    margin-bottom: 2px;
}

.contrib-name-input:focus {
    outline: none;
    border-color: var(--primary-color);
}

.contrib-recording-indicator {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 14px 0;
    justify-content: center;
}

.recording-dot {
    width: 12px;
    height: 12px;
    background: #ef4444;
    border-radius: 50%;
    animation: pulse 1.2s ease-in-out infinite;
}

#contrib-record-timer {
    font-size: var(--text-lg, 18px);
    font-weight: 600;
    font-variant-numeric: tabular-nums;
    color: var(--text-color);
}

.contrib-done-icon {
    font-size: 48px;
    text-align: center;
    margin-bottom: 8px;
}

.contrib-done-icon+h4 {
    text-align: center;
    margin: 0 0 8px;
    font-size: var(--text-md, 16px);
}

/* ─── Contribution moderation panel ─────────────────────────────── */
.contrib-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px 0;
    max-height: 60vh;
    overflow-y: auto;
}

.contribution-card {
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 12px 14px;
    background: var(--bg-white);
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.contrib-card-meta {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.contrib-zone-tag {
    font-size: var(--text-xs, 11px);
    background: var(--bg-tertiary);
    border-radius: var(--radius-xs);
    padding: 2px 6px;
    color: var(--text-secondary);
}

.contrib-who {
    font-size: var(--text-sm, 12px);
    font-weight: 500;
    color: var(--text-color);
}

.contrib-when {
    font-size: var(--text-xs, 11px);
    color: var(--text-lighter);
    margin-left: auto;
}

.contrib-audio {
    width: 100%;
    height: 36px;
}

.contrib-transcript {
    font-size: var(--text-sm, 12px);
    color: var(--text-muted);
    font-style: italic;
    margin: 0;
    line-height: 1.4;
}

.contrib-no-audio {
    font-size: var(--text-sm, 12px);
    color: var(--text-lighter);
    margin: 0;
    font-style: italic;
}

.contrib-actions {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

/* ─── Pending badge on contributions button ─────────────────────── */
.contrib-badge {
    background: #ef4444;
    color: #fff;
    border-radius: var(--radius-round);
    font-size: 10px;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    line-height: 16px;
    text-align: center;
    padding: 0 4px;
    display: inline-block;
    vertical-align: middle;
    margin-left: 4px;
}

/* ─── Login screen additions ────────────────────────────────────── */
.login-divider {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0;
    color: var(--text-lighter);
    font-size: var(--text-sm, 12px);
}

.login-divider::before,
.login-divider::after {
    content: '';
    flex: 1;
    border-top: 1px solid var(--border-color);
}

.login-alt-btn {
    width: 100%;
    text-align: center;
    margin-top: 2px;
}

.settings-keys-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.settings-key-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 8px 10px;
    background: var(--bg-secondary, #f8f9fa);
    border-radius: var(--radius-sm, 6px);
}

.settings-key-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.settings-key-name {
    font-size: var(--text-sm, 13px);
    font-weight: 600;
}

.settings-key-meta {
    font-size: var(--text-xs, 11px);
    color: var(--text-secondary, #888);
}

.login-code-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.login-code-actions .login-alt-btn {
    margin-top: 0;
}

.register-field-hint {
    font-size: 12px;
    margin: -6px 0 6px;
    min-height: 16px;
}

.register-field-hint--ok {
    color: var(--success-color, #2e7d32);
}

.register-field-hint--err {
    color: var(--error-color, #c62828);
}

/* Advanced API-key fallback — collapsed by default */
.login-advanced {
    margin-top: 16px;
    border-top: 1px solid var(--border-color, #e0e0e0);
    padding-top: 12px;
}

.login-advanced>summary {
    cursor: pointer;
    list-style: none;
    font-size: var(--text-sm, 12px);
    color: var(--text-secondary, #888);
    text-align: center;
    user-select: none;
}

.login-advanced>summary::-webkit-details-marker {
    display: none;
}

.login-advanced[open]>summary {
    margin-bottom: 10px;
}

/* ─── Inline project picker (no-project-view) ────────────────────── */
/* Full-screen project picker */
#no-project-view {
    position: fixed;
    inset: 0;
    z-index: 10001;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: max(env(safe-area-inset-top), 24px) 16px calc(env(safe-area-inset-bottom) + 40px);
    background: var(--app-bg, linear-gradient(135deg, var(--primary-color, #111) 0%, var(--secondary-color, #222) 100%));
    background-size: var(--app-bg-size, auto);
}

#no-project-view>* {
    max-width: 640px;
    margin-left: auto;
    margin-right: auto;
}

.picker-back-btn {
    display: block;
    background: rgba(255, 255, 255, 0.15);
    color: var(--text-inverse, #fff);
    border: 1px solid rgba(255, 255, 255, 0.3);
    padding: 8px 14px;
    border-radius: var(--radius-pill, 20px);
    cursor: pointer;
    margin-bottom: 12px;
    font-size: var(--text-sm, 12px);
}

.npv-logo {
    display: block;
    width: min(110px, 36vw);
    height: auto;
    margin: 6px auto 10px;
    opacity: 0.92;
}

.npv-header {
    text-align: center;
    padding: 8px 16px 24px;
    mix-blend-mode: exclusion;
}

.npv-title {
    margin: 0 0 8px;
    font-size: var(--text-2xl);
    font-weight: 700;
    color: var(--text-inverse, #fff);
}

.npv-subtitle {
    margin: 0;
    font-size: var(--text-base);
    color: rgba(255, 255, 255, 0.82);
}

/* Themed cards float directly on the picker background */
#no-project-view oul-list,
#no-project-view #picker-projects-list {
    background: transparent;
    box-shadow: none;
    overflow: visible;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

/* Divider between list and create form */
.npv-divider {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 28px 0 20px;
    color: var(--text-muted);
    font-size: var(--text-sm);
}

.npv-divider::before,
.npv-divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--border-color);
}

/* Create project form */
.npv-create-form {
    background: var(--bg-white);
    border-radius: var(--radius-lg);
    padding: 20px;
    box-shadow: var(--shadow-md);
}
/* ==== css/modifiers.css ==== */
/* ═══════════════════════════════════════════════════════════════════════════
   MODIFIERS & DATA SOURCES
   ═══════════════════════════════════════════════════════════════════════════ */
/* ─── Modifier inline tab header ────────────────────────────────── */
.modifier-inline-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 8px;
    min-height: 20px;
}

.modifier-list-count {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

/* ─── Modifier list items ────────────────────────────────────────── */
.modifier-list-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    padding: 12px;
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    margin-bottom: 8px;
}

.modifier-list-item.is-disabled {
    background: var(--bg-secondary, #f5f5f5);
    opacity: 0.7;
}

.modifier-li-main {
    flex: 1;
    min-width: 0;
}

.modifier-li-name {
    font-weight: 600;
    margin-bottom: 3px;
    color: var(--text-color);
}

.modifier-li-active {
    margin-left: 8px;
    font-size: var(--text-xs);
    font-weight: 600;
    color: #1b7f3b;
    background: #e5ffe9;
    padding: 1px 7px;
    border-radius: var(--radius-pill);
    vertical-align: 1px;
    animation: modActivePulse 2s ease-in-out infinite;
}

@keyframes modActivePulse {

    0%,
    100% {
        opacity: 1;
    }

    50% {
        opacity: 0.55;
    }
}

.modifier-li-summary {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    line-height: 1.4;
}

.modifier-li-meta {
    font-size: var(--text-xs);
    color: var(--text-lighter);
    margin-top: 2px;
}

.modifier-li-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 6px;
    flex-shrink: 0;
}

.modifier-li-status {
    font-size: 15px;
    font-weight: 700;
    line-height: 1;
}

.modifier-li-status.mod-status-on {
    color: var(--success-color, #22c55e);
}

.modifier-li-status.mod-status-off {
    color: var(--text-lighter);
}

.modifier-li-btns {
    display: flex;
    gap: 6px;
}

/* ─── Modifier form: condition & action cards ────────────────────── */
.cond-card,
.act-card {
    padding: 12px;
    border-radius: var(--radius-md);
    margin-bottom: 10px;
    border: 1px solid var(--border-color);
}

.cond-card {
    background: var(--bg-light, #f8fafc);
}

.act-card {
    background: var(--bg-light, #f8fafc);
}

.mod-card-head {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
}

.mod-card-title {
    font-weight: 600;
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.mod-remove-btn {
    background: var(--danger-color, #ef4444);
    color: #fff;
    border: none;
    border-radius: var(--radius-xs);
    padding: 4px 8px;
    cursor: pointer;
    font-size: var(--text-xs);
}

.mod-field {
    margin-bottom: 10px;
}

.mod-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    margin-bottom: 10px;
}

.mod-label {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    display: block;
    margin-bottom: 4px;
}

.mod-input,
.mod-select {
    width: 100%;
    padding: 8px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    box-sizing: border-box;
    background: var(--bg-white);
    font-size: var(--text-sm);
}

.mod-hint {
    font-size: var(--text-xs);
    color: var(--text-lighter);
    margin: 4px 0 0;
    font-style: italic;
}

.mod-checks {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.mod-check {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
}

/* Live condition preview pill */
.cond-preview {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 8px;
    font-size: var(--text-xs);
    padding: 3px 8px;
    border-radius: var(--radius-pill);
    background: var(--bg-tertiary, #f0f0f0);
    color: var(--text-secondary);
}

.cond-preview .dot {
    width: 8px;
    height: 8px;
    border-radius: var(--radius-round);
    background: var(--text-lighter);
}

.cond-preview.pass {
    background: #e5ffe9;
    color: #1b7f3b;
}

.cond-preview.pass .dot {
    background: #22c55e;
}

.cond-preview.fail {
    background: #fdecec;
    color: #b3261e;
}

.cond-preview.fail .dot {
    background: #ef4444;
}

.cond-preview.unknown {
    background: var(--bg-tertiary, #f0f0f0);
    color: var(--text-muted);
}

/* Zone target / chips selector */
.zone-pick {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.zp-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-height: 26px;
    align-items: center;
}

.zp-chip {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 10px;
    font-size: var(--text-xs);
    background: var(--bg-elevated, #e8e8e8);
    color: var(--text-primary);
    max-width: 180px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.zp-chip-all {
    background: var(--color-accent, #4a90e2);
    color: #fff;
}

.zp-chip-empty {
    background: transparent;
    color: var(--text-lighter);
    font-style: italic;
    padding-left: 0;
}

.zp-open-btn {
    align-self: flex-start;
    font-size: var(--text-xs);
    padding: 4px 10px;
    border-radius: var(--radius-xs);
    border: 1px solid var(--border-color);
    background: var(--bg-elevated);
    color: var(--text-secondary);
    cursor: pointer;
}

.zp-open-btn:hover {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.sound-pick-row {
    display: flex;
    gap: 6px;
    align-items: center;
}

.sound-pick-row .mod-input {
    flex: 1;
}

.mod-pick-btn {
    padding: 8px 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    background: var(--bg-white);
    cursor: pointer;
    font-size: var(--text-sm);
    white-space: nowrap;
}

/* Validation + test-now panel */
.mod-validation {
    margin: 8px 0;
    padding: 8px 10px;
    border-radius: var(--radius-sm);
    background: var(--danger-light, #ffe5e5);
    color: var(--danger-color, #c0392b);
    font-size: var(--text-xs);
}

.mod-validation ul {
    margin: 4px 0 0;
    padding-left: 18px;
}

.mod-test-result {
    margin: 8px 0;
    font-size: var(--text-sm);
}

.mod-test-line {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 2px 0;
}

/* ─── Data Source Editor Panel ───────────────────────────────────── */
.dse-panel {
    max-width: 640px;
    width: 96vw;
}

.dse-view {
    padding: 0 20px 20px;
    overflow-y: auto;
    flex: 1;
}

.dse-intro {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin: 0 0 10px;
    line-height: 1.5;
}

.dse-expression-hint {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 8px 12px;
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin-bottom: 14px;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.dse-expression-hint code {
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-xs);
    padding: 1px 6px;
    font-family: 'SF Mono', monospace;
    font-size: var(--text-xs);
    color: var(--primary-color);
}

.dse-list-toolbar {
    margin-bottom: 12px;
}

.dse-presets {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-bottom: 16px;
}

.dse-presets-label {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.dse-presets-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.dse-sources-list {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.dse-source-card {
    background: var(--bg-white);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-md);
    padding: 12px 14px;
}

.dse-source-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 10px;
}

.dse-source-info {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.dse-source-name {
    font-size: var(--text-base);
}

.dse-source-meta {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dse-source-status {
    font-size: var(--text-xs);
    color: var(--text-secondary);
}

.dse-source-error {
    font-size: var(--text-xs);
    color: var(--danger-color, #e74c3c);
    word-break: break-word;
}

.dse-source-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

.dse-outputs-preview {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--border-color);
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.dse-output-row {
    display: grid;
    grid-template-columns: 1fr 2fr auto;
    gap: 8px;
    align-items: center;
    font-size: var(--text-xs);
}

.dse-output-name {
    font-weight: 500;
}

.dse-output-expr {
    font-family: monospace;
    color: var(--text-secondary);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.dse-output-val {
    font-family: monospace;
    font-weight: 600;
    color: var(--primary-color);
    white-space: nowrap;
}

/* Form view */
.dse-form-nav {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 16px;
}

.dse-form-title {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 600;
}

.dse-field-group {
    margin-bottom: 12px;
}

.dse-field-inline {
    display: flex;
    align-items: center;
    gap: 8px;
}

.dse-label {
    display: block;
    font-size: var(--text-sm);
    font-weight: 500;
    color: var(--text-color);
    margin-bottom: 4px;
}

.dse-input {
    width: 100%;
    padding: 8px 10px;
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    font-size: var(--text-base);
    box-sizing: border-box;
}

.dse-input-sm {
    width: 80px;
    flex-shrink: 0;
}

.dse-unit {
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.dse-outputs-section {
    margin-top: 16px;
}

.dse-outputs-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.dse-outputs-title {
    margin: 0;
    font-size: var(--text-base);
    font-weight: 600;
}

.dse-outputs-hint {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin: 0 0 10px;
}

.dse-outputs-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.dse-output-form-row {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
    padding: 8px;
}

.dse-output-fields {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 2fr 80px;
    gap: 6px;
}

.dse-output-fields input {
    padding: 5px 8px;
    font-size: var(--text-sm);
}

.dse-mono {
    font-family: 'SF Mono', monospace;
}

.dse-output-row-actions {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    flex-shrink: 0;
}

.dse-test-val-badge {
    font-size: var(--text-xs);
    font-family: monospace;
    color: var(--primary-color);
    font-weight: 600;
    white-space: nowrap;
}

.dse-test-section {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--border-color);
}

.dse-test-toolbar {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 8px;
}

.dse-raw-json {
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-sm);
}

.dse-raw-summary {
    padding: 6px 10px;
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: 500;
}

.dse-raw-pre {
    padding: 10px;
    margin: 0;
    font-size: var(--text-xs);
    font-family: monospace;
    overflow-x: auto;
    max-height: 200px;
    overflow-y: auto;
    white-space: pre-wrap;
    word-break: break-all;
}

.dse-form-actions {
    display: flex;
    gap: 8px;
    margin-top: 20px;
    padding-top: 12px;
    border-top: 1px solid var(--border-color);
}

.dse-empty {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    font-style: italic;
    text-align: center;
    padding: 20px 0;
}

.dse-outputs-empty {
    text-align: left;
    padding: 8px 0;
}
/* Zone chip hover tooltip (desktop) — reuses the .plz-* map-popup styles */
.zp-tip {
    position: fixed;
    z-index: 10500;
    max-width: 280px;
    padding: 10px 12px;
    background: var(--bg-primary, #fff);
    border: 1px solid var(--border-color, #ddd);
    border-radius: var(--radius-sm, 8px);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
    pointer-events: none;
}

.zp-tip .zone-popup {
    min-width: 0;
}

.zp-tip-shape {
    display: block;
    width: 84px;
    height: 52px;
    margin-bottom: 6px;
}

.zp-tip-shape path {
    fill: var(--color-accent, #4a90e2);
    fill-opacity: 0.18;
    stroke: var(--color-accent, #4a90e2);
    stroke-width: 1.5;
    stroke-linejoin: round;
}

.zp-tip-disabled {
    margin-top: 6px;
    font-size: var(--text-xs);
    color: var(--color-danger, #d9534f);
    font-style: italic;
}

