/* ============================================================
   SLEEK GS — Design System
   All styles for the application live here.
   No element.style.cssText or inline style= attributes anywhere in JS.

   Structure:
   1. Reset + base
   2. Design tokens (:root + [data-theme="dark"])
   3. Map container
   4. Panel (sidebar)
   5. Layer tree — groups + rows
   6. Symbology legend
   7. Filter panel
   8. Query panel
   9. Popup
   10. Controls (dark mode toggle, MapLibre overrides)
   11. Measure tool
   12. Utilities
   13. Responsive
   ============================================================ */


/* ============================================================
   1. RESET + BASE
   ============================================================ */

*, *::before, *::after {
    box-sizing: border-box;
}

/* Global slim scrollbars */
* {
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border, #ccc) transparent;
}
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--sgs-border, #ccc); border-radius: 3px; }

html, body {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
    font-size: 13px;
    line-height: 1.4;
    /* The ONE app-wide text color (P6): unstyled text used to fall back to the UA
       default (black) and read dark-on-dark all over dark mode. Every surface now
       inherits the themed color unless it deliberately overrides. */
    color: var(--sgs-text);
    -webkit-font-smoothing: antialiased;
}

button {
    font: inherit;
    cursor: pointer;
    border: none;
    background: none;
    padding: 0;
}

input[type="text"],
input[type="search"],
textarea {
    font: inherit;
}


/* ============================================================
   2. DESIGN TOKENS
   ============================================================ */

:root {
    /* — Colors — */
    --sgs-bg:              #ffffff;
    --sgs-layer-canvas:    #f3f3f3;  /* panel body canvas — cards sit on top of this */
    /* Layer/group card fills, split out so dark mode can restack the layer-list depth order
       independently of the global surface tokens. Light mode keeps the historical values:
       off cards = --sgs-surface-hover, on cards = --sgs-bg (see the dark block for the swap). */
    --sgs-layer-card:      var(--sgs-surface-hover);  /* unselected (off) layer/group card */
    --sgs-layer-card-on:   var(--sgs-bg);             /* selected (on) layer/group card */
    /* Top-right map control hover — ONE shared patch + icon(outline) colour so every button in
       the stack (zoom/compass/geolocate, measure, dark toggle, person) responds identically.
       Light: patch darkens, glyph darkens. The dark block mirrors it (patch + glyph lighten). */
    --sgs-ctrl-hover-bg:      var(--sgs-surface-hover);  /* button patch on hover */
    --sgs-ctrl-hover-outline: var(--sgs-text);           /* SVG stroke / icon colour on hover */
    --sgs-surface:         #f5f5f5;
    --sgs-surface-mid:     var(--_surface-mid);
    --sgs-surface-2:       #efefef;
    --sgs-surface-hover:   var(--_surface-hover);
    --sgs-border:          var(--_border);
    --sgs-border-light:    var(--_border-light);
    /* Contrast anchors — these are the single source of truth for the four
       tokens that vary between low/medium/high contrast. Update only here;
       contrast variants derive automatically via color-mix() in @supports below. */
    --_border:             #c0c0c0;
    --_border-light:       #d0d0d0;
    --_surface-hover:      #e8e8e8;
    --_surface-mid:        #f9f9f9;
    --sgs-text:            #1a1d23;
    --sgs-text-off:        #8c9baa;
    --sgs-text-muted:      #535a67;
    --sgs-text-micro:      #9ca3af;
    --sgs-accent:          #2563eb;
    /* Same shade/lightness as the accent but with saturation knocked down to a
       barely-there sliver (~12% of the original) — near-gray, just the tiniest
       hint of blue. Resolved at use site, so it tracks whatever --sgs-accent is
       in scope (light/dark). De-emphasizes an expanded on-group's own checkbox. */
    --sgs-accent-faint:    hsl(from var(--sgs-accent) h calc(s * 0.12) l);
    --sgs-accent-hover:    #1d4ed8;
    --sgs-accent-light:    #5a9be8;  /* lighter accent — gradient start on circle checkboxes */
    --sgs-accent-light-faint: hsl(from var(--sgs-accent-light) h calc(s * 0.12) l);  /* faint twin (circle gradient) */
    --sgs-accent-subtle:   #dbeafe;
    --sgs-danger:          #dc2626;
    --sgs-danger-subtle:   #fdf0ef;  /* tinted danger bg — danger buttons, hover tints */
    --sgs-warn:            #e67e22;  /* amber warning — filter-active badge, search status */
    --sgs-publish-green:   #2e8b57;  /* GeoParquet / publish identity — featured radar, "where we're heading", publish-done */
    --sgs-publish-green-faint: color-mix(in srgb, var(--sgs-publish-green) 5%, transparent);  /* faint tint over the panel — featured card bg, both themes (softened 2026-07-07) */
    --sgs-vt-indigo:       #4356e0;  /* Vector Tiles identity (n9) — nudged toward the radar blue (owner 2026-07-07); VT card accent/outline/radar */
    --sgs-vt-indigo-faint: color-mix(in srgb, var(--sgs-vt-indigo) 5%, transparent);  /* faint blue-indigo tint — VT card bg, both themes */
    --sgs-shadow-sm:       0 1px 3px rgba(0, 0, 0, 0.10), 0 1px 2px rgba(0, 0, 0, 0.06);
    --sgs-shadow:          0 4px 12px rgba(0, 0, 0, 0.12), 0 2px 4px rgba(0, 0, 0, 0.07);
    --sgs-shadow-lg:       0 8px 24px rgba(0, 0, 0, 0.14), 0 4px 8px rgba(0, 0, 0, 0.08);
    --sgs-card-bevel-top:    rgba(255,255,255,0.05);
    --sgs-card-bevel-bottom: rgba(0,0,0,0.05);
    --sgs-card-border-color: var(--sgs-border-light);
    --sgs-card-shadow:       inset 0 1px 0 var(--sgs-card-bevel-top), inset 0 -1px 0 var(--sgs-card-bevel-bottom);

    /* — Spacing (4px grid) — */
    --sgs-gap-xs:  4px;
    --sgs-gap-sm:  8px;
    --sgs-gap-md:  12px;
    --sgs-gap-lg:  16px;

    /* Map-control geometry (n2 2026-07-11): every top-right control button is one
       square size, and the stack's spacing is the same shared small gap the panels
       and docks inset with — adjust these two knobs to retune the whole chrome.
       Both ride --sgs-ui-scale so Readable mode (n3 2026-07-12) grows the
       right-edge controls with everything else. */
    --sgs-ctrl-size:  calc(24px * var(--sgs-ui-scale));
    /* Glyph 16 in a 24 box: the 4px margins and the glyph itself land on WHOLE
       device pixels at every common zoom (1, 1.25, 1.5, 2). 18px put a 22.5
       device-pixel glyph in the box at 125% and every icon drifted a fraction
       of a pixel off-centre (n13 2026-07-11). */
    --sgs-ctrl-glyph: calc(16px * var(--sgs-ui-scale));
    --sgs-gap-xl:  24px;
    --sgs-gap-2xl: 32px;
    /* — Shape — */
    --sgs-radius-sm:   3px;
    --sgs-radius-md:   6px;
    --sgs-radius-lg:   10px;
    --sgs-radius-pill: 999px;
    /* ONE grip pill for every drag handle (panel edge, dock top, widget strip,
       popup) — resize affordances are the same feature everywhere (n3/n18
       2026-07-12), so their geometry is two knobs, not per-surface literals. */
    --sgs-grip-len:   34px;
    --sgs-grip-thick: 3px;

    /* — Motion — */
    --sgs-transition:      0.15s ease;
    --sgs-transition-slow: 0.25s ease;

    /* — Typography (n3 2026-07-12) —
       ONE scaled ladder: every size is `raw × --sgs-ui-scale`, so the two-mode
       UI-size toggle (Sleek / Readable) grows all token-driven text at once
       instead of chasing literals. Sleek = the historical sizes (scale 1);
       Readable bumps the scale in the [data-ui-size="readable"] block below.
       (micro/md/lg formalized here — they were used before they existed.) */
    --sgs-ui-scale:   1;
    --sgs-font-micro: calc(10px * var(--sgs-ui-scale));
    --sgs-font-xs:    calc(11px * var(--sgs-ui-scale));
    --sgs-font-sm:    calc(12px * var(--sgs-ui-scale));
    --sgs-font-base:  calc(13px * var(--sgs-ui-scale));
    --sgs-font-md:    calc(14px * var(--sgs-ui-scale));
    --sgs-font-lg:    calc(16px * var(--sgs-ui-scale));

    /* — Panel dimensions — */
    --sgs-panel-width: 280px;

    /* — Compose-mode icon dimensions (spacers derive from these) — */
    --sgs-row-gap:   4px;  /* flex gap shared by .sgs-layer-row and .sgs-group-header */
    --sgs-drag-w:    8px;  /* drag handle width */
    --sgs-drag-total: calc(var(--sgs-drag-w) + var(--sgs-row-gap)); /* 12px budget across 4 slots */
    --sgs-drag-gap-1: calc(var(--sgs-drag-total) * 0.20); /* left of chevron       */
    --sgs-drag-gap-2: calc(var(--sgs-drag-total) * 0.40); /* chevron → checkbox    */
    --sgs-drag-gap-3: calc(var(--sgs-drag-total) * 0.20); /* checkbox → pill       */
    --sgs-drag-gap-4: calc(var(--sgs-drag-total) * 0.20); /* pill → name           */
    --sgs-gear-w:  18px;
    --sgs-trash-w: 18px;
}

[data-theme="dark"] {
    /* Lighter-gray dark palette (R2, 2026-07-07): the old near-black stack read as
       "too dark" everywhere except the layer list. One step lighter across the whole
       surface family, applied ONLY here at the token layer — per-surface CSS must
       never hand-pick dark hexes. */
    --sgs-bg:              #2a2d34;
    /* Dark layer-list depth order (lightest → darkest): selected card ▸ canvas ▸ unselected
       card ▸ header/toolbar (--sgs-bg). Canvas sits a step above the solid-dark header so the
       cards can read either side of it — off cards a hair darker, on cards clearly lifted. */
    --sgs-layer-canvas:    #41454c;  /* panel canvas — lighter than the solid-dark header */
    --sgs-layer-card:      #33363d;  /* unselected card — darker than the canvas */
    --sgs-layer-card-on:   #7a7c88;  /* selected card — clearly lifted above the canvas */
    /* Control hover, dark mirror: surface-hover is LIGHTER than the dark chrome so the patch
       lifts (not darkens), and text is near-white so the glyph reads as a light outline. */
    --sgs-ctrl-hover-bg:      var(--sgs-surface-hover);
    --sgs-ctrl-hover-outline: var(--sgs-text);
    --sgs-surface:         #31343c;
    --sgs-surface-2:       #42454f;
    /* Dark contrast anchors — overrides :root anchors; public tokens resolve automatically */
    --_border:             #63656f;
    --_border-light:       #3a3b45;
    --_surface-hover:      #3d4150;
    --_surface-mid:        #383b46;
    --sgs-text:            #e8eaf0;
    --sgs-text-off:        #717a97;
    --sgs-text-muted:      #949ab0;
    --sgs-text-micro:      #6b7188;
    --sgs-accent:          #3b82f6;
    --sgs-accent-hover:    #60a5fa;
    --sgs-accent-light:    #93c5fd;
    --sgs-accent-subtle:   #1e3a5f;
    --sgs-danger:          #f87171;
    --sgs-danger-subtle:   #3a1a18;
    --sgs-warn:            #f5a623;
    --sgs-publish-green:   #46b277;  /* brighter on dark so the featured identity reads on a dark panel */
    --sgs-vt-indigo:       #7d9bf5;  /* brighter blue-indigo on dark so the VT identity reads on a dark panel */
    --sgs-shadow-sm:       0 1px 3px rgba(0, 0, 0, 0.40), 0 1px 2px rgba(0, 0, 0, 0.30);
    --sgs-shadow:          0 4px 12px rgba(0, 0, 0, 0.45), 0 2px 4px rgba(0, 0, 0, 0.30);
    --sgs-shadow-lg:       0 8px 24px rgba(0, 0, 0, 0.55), 0 4px 8px rgba(0, 0, 0, 0.35);
    /* Off-card default bevel — kept muted so turned-off cards read quieter than the lifted,
       more-defined on-cards (see the [data-on] override). */
    --sgs-card-shadow:     inset 0 1px 0 rgba(255,255,255,0.05), inset 0 -1px 0 rgba(0,0,0,0.20);
}
[data-theme="dark"] .sgs-panel {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* UI size (n3 2026-07-12) — Sleek is the :root default (scale 1), no block
   needed. Readable bumps ONE knob and the whole scaled ladder (fonts + the
   right-edge control geometry) grows with it. Deliberately two modes only,
   no slider — a coarse accessibility choice, not fine typography. JS sets
   data-ui-size on <html> (personal-prefs.applyUiSize). */
[data-ui-size="readable"] { --sgs-ui-scale: 1.16; }

/* Contrast levels — medium is the :root default, no block needed.
   JS sets data-contrast on <html>.
   Structure: static fallbacks first (all browsers), then @supports block overrides
   with DRY color-mix() derivation from the --_* anchors (modern browsers only).
   To adjust the contrast scale: edit only the --_* anchors in :root / [data-theme="dark"]. */

/* ── Static fallbacks (browsers without color-mix support) ── */
[data-contrast="low"] {
    --sgs-border:        #d0d0d0;
    --sgs-border-light:  #e2e2e2;
    --sgs-surface-hover: #efefef;
    --sgs-surface-mid:   #fbfbfb;
}
[data-contrast="high"] {
    --sgs-border:        #a8a8a8;
    --sgs-border-light:  #bfbfbf;
    --sgs-surface-hover: #d0d0d0;
    --sgs-surface-mid:   #f5f5f5;
}
[data-theme="dark"][data-contrast="low"] {
    --sgs-border:        #4b4d59;
    --sgs-border-light:  #34353e;
    --sgs-surface-mid:   #34363f;
    --sgs-surface-hover: #383b46;
}
[data-theme="dark"][data-contrast="high"] {
    --sgs-border:        #767987;
    --sgs-border-light:  #4a4c58;
    --sgs-surface-mid:   #3d4049;
    --sgs-surface-hover: #474b58;
}

/* ── DRY derivation for modern browsers (overrides static fallbacks above) ── */
@supports (color: color-mix(in srgb, red, blue)) {
    [data-contrast="low"] {
        --sgs-border:        color-mix(in srgb, var(--_border), white 25%);
        --sgs-border-light:  color-mix(in srgb, var(--_border-light), white 40%);
        --sgs-surface-hover: color-mix(in srgb, var(--_surface-hover), white 30%);
        --sgs-surface-mid:   color-mix(in srgb, var(--_surface-mid), white 30%);
    }
    [data-contrast="high"] {
        --sgs-border:        color-mix(in srgb, var(--_border), black 13%);
        --sgs-border-light:  color-mix(in srgb, var(--_border-light), black 8%);
        --sgs-surface-hover: color-mix(in srgb, var(--_surface-hover), black 12%);
        --sgs-surface-mid:   color-mix(in srgb, var(--_surface-mid), black 3%);
    }
    /* Dark mode: low = push toward canvas (black), high = push away (white) */
    [data-theme="dark"][data-contrast="low"] {
        --sgs-border:        color-mix(in srgb, var(--_border), black 18%);
        --sgs-border-light:  color-mix(in srgb, var(--_border-light), black 15%);
        --sgs-surface-hover: color-mix(in srgb, var(--_surface-hover), black 10%);
        --sgs-surface-mid:   color-mix(in srgb, var(--_surface-mid), black 8%);
    }
    [data-theme="dark"][data-contrast="high"] {
        --sgs-border:        color-mix(in srgb, var(--_border), white 18%);
        --sgs-border-light:  color-mix(in srgb, var(--_border-light), white 15%);
        --sgs-surface-hover: color-mix(in srgb, var(--_surface-hover), white 10%);
        --sgs-surface-mid:   color-mix(in srgb, var(--_surface-mid), white 8%);
    }
}


/* ============================================================
   3. MAP CONTAINER
   ============================================================ */

#map {
    position: absolute;
    inset: 0;
    /* When no basemap is on, MapLibre clears the GL canvas to transparent and this shows
       through — so the empty map void tracks the theme (dark backdrop in dark mode) instead
       of a stark white flash. */
    background: var(--sgs-bg);
}


/* ============================================================
   4. PANEL (sidebar)
   ============================================================ */

.sgs-panel {
    position: absolute;
    top: var(--sgs-gap-sm);
    left: var(--sgs-gap-sm);
    bottom: var(--sgs-gap-sm);
    z-index: 400;
    width: fit-content;
    min-width: 200px;
    max-width: 33vw;
    /* The panel canvas, NOT --sgs-bg (n10 2026-07-12): the toolbar paints its
       own --sgs-bg header on top, so only the very top bar reads white/dark;
       the heading, list, strip, AND any slack between the list and a bottom-
       anchored block strip all share the one canvas gray instead of exposing a
       white band. Both themes: dark's canvas is the lighter body tone. */
    background: var(--sgs-layer-canvas);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow);
    color: var(--sgs-text);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    transition: background var(--sgs-transition), border-color var(--sgs-transition);
    scrollbar-width: none;
}

.sgs-panel-body {
    flex: 1;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0px;
    background: var(--sgs-layer-canvas);
}
.sgs-panel-body::-webkit-scrollbar {
    width: 6px;
}
.sgs-panel-body::-webkit-scrollbar-track {
    background: transparent;
}
.sgs-panel-body::-webkit-scrollbar-thumb {
    background: var(--sgs-border);
    border-radius: var(--sgs-radius-pill);
}

.sgs-separator {
    border: none;
    border-top: 1px solid var(--sgs-border-light);
    margin: var(--sgs-gap-sm) 0 var(--sgs-gap-xs);
}

/* Minimap inset (issue #51): a fixed-aspect card between the heading and the
   list. Non-interactive overview; the extent box is drawn by minimap.js. */
.sgs-minimap-card {
    flex: 0 0 auto;
    height: 116px;
    margin: 2px var(--sgs-gap-sm) var(--sgs-gap-sm);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    overflow: hidden;
    background: var(--sgs-surface-2);
}
.sgs-minimap-card .maplibregl-ctrl-attrib { display: none; } /* the inset stays chrome-free */
.sgs-minimap-card canvas { cursor: default; }

/* ── Panel frame: manual width + unpinned float (issue #18) ──────────────
   panel-frame.js writes these classes; geometry itself rides --sgs-panel-w
   and inline left/top so ONE applier owns every posture. */
.sgs-panel--manual {
    width: var(--sgs-panel-w, 280px);
    max-width: none;
}
/* Pinned height (n5 2026-07-12): the bottom grip releases the bottom anchor
   and pins --sgs-panel-h, the vertical twin of the width posture. */
.sgs-panel--manual-h,
.sgs-perf-dock-open .sgs-panel--manual-h {
    bottom: auto;
    height: var(--sgs-panel-h, 60vh);
    max-height: calc(100vh - var(--sgs-gap-sm) * 2);
}
/* Unpinned: hug the content height (tight to the bottom layer, n10) and stop
   pinning to the left edge. The paired dock-open selector outweighs the
   .sgs-perf-dock-open .sgs-panel bottom offset without resorting to !important. */
.sgs-panel--float,
.sgs-perf-dock-open .sgs-panel--float {
    bottom: auto;
    height: auto;
    max-height: calc(100vh - var(--sgs-gap-sm) * 2);
}
.sgs-panel--float .sgs-toolbar { cursor: grab; }
.sgs-panel--float.sgs-panel-dragging .sgs-toolbar { cursor: grabbing; }
.sgs-panel--float.sgs-panel-dragging { transition: none; }
/* Right-edge width grip — same idiom as the bottom dock's top grip. */
.sgs-panel-resize {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 7px;
    z-index: 6;
    cursor: ew-resize;
}
.sgs-panel-resize::before {
    content: '';
    position: absolute;
    top: 50%;
    right: 2px;
    width: var(--sgs-grip-thick);
    height: var(--sgs-grip-len);
    margin-top: calc(var(--sgs-grip-len) / -2);
    border-radius: 2px;
    background: transparent;
}
.sgs-panel-resize:hover::before { background: var(--sgs-text-muted); }
.sgs-panel-resizing { user-select: none; cursor: ew-resize; }
/* Bottom-edge height grip (n5) — the side grip's vertical twin, same pill. */
.sgs-panel-resize-h {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 7px;
    z-index: 6;
    cursor: ns-resize;
}
.sgs-panel-resize-h::before {
    content: '';
    position: absolute;
    left: 50%;
    bottom: 2px;
    width: var(--sgs-grip-len);
    height: var(--sgs-grip-thick);
    margin-left: calc(var(--sgs-grip-len) / -2);
    border-radius: 2px;
    background: transparent;
}
.sgs-panel-resize-h:hover::before { background: var(--sgs-text-muted); }
/* A float hugs its content — the bottom grip has nothing honest to pin. */
.sgs-panel--float .sgs-panel-resize-h { display: none; }
/* A MINIMIZED block strip is exactly this band: its grab bar (and the
   bring-back button) must win the bottom edge, or the height grip steals
   their clicks (r21 regression, R29). */
.sgs-panel:has(#sgs-widget-strip.sgs-widget-strip--min) .sgs-panel-resize-h { display: none; }
/* The pin lights its glyph, not a background chip (n4). */
.sgs-toolbar-btn--frame-pin.sgs-toolbar-btn--active {
    background: transparent;
    color: var(--sgs-accent);
}


/* ============================================================
   4b. TOOLBAR (layer list header bar)
   ============================================================ */

.sgs-toolbar {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    padding: var(--sgs-gap-xs) var(--sgs-gap-xs) var(--sgs-gap-xs) var(--sgs-gap-sm);
    flex-shrink: 0;
    overflow: visible;
    background: var(--sgs-bg);
    border-radius: var(--sgs-radius-lg) var(--sgs-radius-lg) 0 0;
    border-bottom: 1px solid var(--sgs-border-light);
}

.sgs-toolbar-spacer {
    flex: 1;
}

.sgs-toolbar-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
    /* Clicking must never text-/drag-select the inner SVG glyph (the "selection
       overlay over the globe" glitch). Clicks land on the button, not the paths. */
    user-select: none;
}
.sgs-toolbar-btn svg { pointer-events: none; }

.sgs-toolbar-btn:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}

.sgs-toolbar-btn--active {
    color: var(--sgs-accent);
    background: var(--sgs-accent-subtle);
}

.sgs-toolbar-btn--edit.sgs-toolbar-btn--active {
    background: transparent;
    color: var(--sgs-accent);
}

.sgs-checkbox-style-group .sgs-toolbar-btn:not(.sgs-toolbar-btn--active) {
    background: none;
    color: var(--sgs-text-muted);
}

.sgs-checkbox-style-group .sgs-toolbar-btn--active {
    background: none;
    outline: none;
    font-weight: 600;
}

.sgs-theme-group .sgs-toolbar-btn {
    background: none;
}
.sgs-theme-group .sgs-toolbar-btn:hover {
    background: none;
}
.sgs-theme-group .sgs-toolbar-btn--active {
    background: none;
}

.sgs-toolbar-btn svg {
    display: block;
}

/* Canvas heading row (name + dirty hub, below toolbar) */
.sgs-config-heading {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    background: var(--sgs-layer-canvas);
    padding: var(--sgs-gap-sm) var(--sgs-gap-xs) 2px var(--sgs-gap-sm);
    user-select: none;
    overflow: visible;
    flex-shrink: 0;
    /* The heading and the panel body below it are both --sgs-layer-canvas, but as separate flex
       children a sub-pixel boundary can leave a faint hairline seam between them. Bleed the same
       canvas color 1px down to paint over the seam (no layout shift). */
    box-shadow: 0 1px 0 var(--sgs-layer-canvas);
}
.sgs-config-heading-title {
    flex: 1;
    min-width: 0;
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    /* Legible at rest so the active canvas name doesn't fade into the heading; hover still lifts
       it the rest of the way to full --sgs-text + bold. Light mode leans darker for contrast on the
       light heading; dark mode keeps the softer mix below (near-white text needs less). */
    color: var(--sgs-text-muted);
    color: color-mix(in srgb, var(--sgs-text) 62%, var(--sgs-text-muted));
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    border-radius: var(--sgs-radius-sm);
    padding-left: var(--sgs-gap-xs);
    transition: color var(--sgs-transition), font-weight var(--sgs-transition);
}
/* Dark mode already had a well-tuned softer rest color — keep it (light mode's darker mix above
   is the change; here we restore the previous 40% blend against the near-white dark text). */
[data-theme="dark"] .sgs-config-heading-title {
    color: color-mix(in srgb, var(--sgs-text) 40%, var(--sgs-text-muted));
}
.sgs-config-heading-title--clickable { cursor: pointer; }
/* The whole row is the switcher handle: it spans the full layer-list width and, on hover,
   lifts a subtle surface and bolds the canvas name so the affordance reads at a glance. */
.sgs-config-heading--clickable { cursor: pointer; }
.sgs-config-heading--clickable:hover { background: var(--sgs-surface); }
/* Dark mode: --sgs-surface reads as a distinct darkening against the canvas, which looks like
   a state change on this static heading. Keep the canvas fill on hover (as light mode already
   effectively does) — the title bolding below is the only hover affordance. */
[data-theme="dark"] .sgs-config-heading--clickable:hover { background: var(--sgs-layer-canvas); }
.sgs-config-heading--clickable:hover .sgs-config-heading-title { color: var(--sgs-text); font-weight: 700; }
/* Switcher open: the dropdown anchors a few px below the title, and the layer body behind it is
   now blurred — so that gap would flash the dimmed canvas as a floating gray band. Lift the heading
   above the blurred body (z-index) and bleed its own fill down over the gap, so the region reads as
   the heading extending down to meet the dropdown rather than a band of its own. */
.sgs-switcher-open .sgs-config-heading {
    position: relative;
    z-index: 2;
    box-shadow: 0 9px 0 var(--sgs-layer-canvas);
}

/* Dirty hub — the edit-management cluster at the right of the name row. Order: dot · redo · undo ·
   discard (super-undo) · save. Each icon appears only when it would do something (undo needs
   history, redo needs an undo, dot/discard/save need a dirty canvas); the hub hides when none do. */
.sgs-dirty-hub {
    display: flex;
    align-items: center;
    gap: 2px;
    margin-left: auto;
}
.sgs-dirty-dot {
    color: var(--sgs-accent);
    font-size: 9px;
    line-height: 1;
    padding: 0 2px;
    cursor: default;
}
.sgs-dirty-redo,
.sgs-dirty-undo,
.sgs-dirty-save,
.sgs-dirty-discard {
    width: 20px;
    height: 20px;
}
.sgs-dirty-redo:hover,
.sgs-dirty-undo:hover,
.sgs-dirty-save:hover { color: var(--sgs-accent); }

/* ── Canvas switcher (dropdown on the canvas name) ──────────────────────────────
   Deliberately NOT a layer card: a flat, full-width navigation list. Rows echo the
   canvas-name heading (small, upper, letter-spaced); the active row is highlighted
   the way an active layer/basemap is (no checkmark — the highlight is the signal).
   Width + left are set inline to span the layer panel (mountSwitcherPanel). */
.sgs-canvas-switcher-panel {
    z-index: 9000;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-top: none;
    border-radius: 0 0 var(--sgs-radius-lg) var(--sgs-radius-lg);
    box-shadow: 0 10px 28px rgba(0,0,0,.22);   /* lifted a touch vs resting cards — reads as elevated */
    padding: 4px;
}

/* ── Switcher "rack focus" ───────────────────────────────────────────────────────
   While the switcher is open, the current canvas's downstream artifacts recede
   (they're contingent on the choice being reconsidered). The heading it grows from
   and the dropdown itself stay sharp/lit — they're the live decision surface.
   Classes toggled in mountSwitcherPanel: `.sgs-switcher-open` on the layer panel,
   `.sgs-switcher-active` on <body>. Reversible; both transition in/out. */
.sgs-panel-body,
#sgs-widget-strip {
    transition: filter 180ms ease, opacity 180ms ease;
}
.sgs-switcher-open .sgs-panel-body,
.sgs-switcher-open #sgs-widget-strip {
    filter: blur(2.5px) saturate(0.85);
    opacity: 0.5;
    pointer-events: none;   /* a click here falls through to the outside-close handler, not a card */
}
/* Light veil over the map — it changes with the canvas too, but a full GL blur is costly/janky,
   so it just dims. A FIXED dark scrim (not --sgs-bg) so it reads in both themes: fading toward the
   light app bg was invisible over pale basemap tiles in light mode. Dims the map toward the now-
   focused dark dropdown, saying "provisional" without the modal weight of a heavy scrim. */
#map::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 5;
    background: #14161c;
    opacity: 0;
    pointer-events: none;
    transition: opacity 200ms ease;
}
.sgs-switcher-active #map::after { opacity: 0.24; }

.sgs-canvas-switcher-list { display: flex; flex-direction: column; }
.sgs-canvas-switcher-row {
    display: flex;
    align-items: center;
    border-radius: var(--sgs-radius-sm);
}
.sgs-canvas-switcher-row:hover { background: var(--sgs-surface-2); }
.sgs-canvas-switcher-row--active { background: var(--sgs-surface-2); }
.sgs-canvas-switcher-open {
    flex: 1;
    display: flex;
    align-items: center;
    gap: 6px;
    min-width: 0;
    padding: 5px var(--sgs-gap-sm);
    background: none;
    border: none;
    text-align: left;
    cursor: pointer;
    /* echo the canvas-name heading */
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--sgs-text-muted);          /* unselected = darker/muted */
}
.sgs-canvas-switcher-row:hover .sgs-canvas-switcher-open { color: var(--sgs-text); }
.sgs-canvas-switcher-row--active .sgs-canvas-switcher-open { color: var(--sgs-text); }
.sgs-canvas-switcher-name {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-canvas-switcher-dirty { color: var(--sgs-accent); font-size: 9px; flex-shrink: 0; }

/* Row actions — quiet until you hover (or the row is active), to keep the list clean */
.sgs-canvas-switcher-actions {
    display: flex;
    gap: 1px;
    padding-right: 4px;
    opacity: 0;
    transition: opacity var(--sgs-transition);
}
.sgs-canvas-switcher-row:hover .sgs-canvas-switcher-actions,
.sgs-canvas-switcher-row--active .sgs-canvas-switcher-actions { opacity: 1; }
.sgs-canvas-switcher-action {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 22px;
    height: 22px;
    padding: 0 4px;
    background: none;
    border: none;
    border-radius: 4px;
    font-size: 12px;
    color: var(--sgs-text-muted);
    cursor: pointer;
}
.sgs-canvas-switcher-action:hover { background: var(--sgs-surface-hover); color: var(--sgs-text); }
.sgs-canvas-switcher-action--danger:hover { color: var(--sgs-danger); }
.sgs-canvas-switcher-action--armed {
    color: #fff;
    background: var(--sgs-danger);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.3px;
}
.sgs-canvas-switcher-input {
    flex: 1;
    min-width: 0;
    width: 100%;
    font: inherit;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-accent);
    border-radius: 4px;
    padding: 4px var(--sgs-gap-sm);
    margin: 1px 0;
}

/* ＋ New canvas — same row rhythm, accent-tinted */
.sgs-canvas-switcher-newbtn {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 5px var(--sgs-gap-sm);
    background: none;
    border: none;
    border-radius: var(--sgs-radius-sm);
    text-align: left;
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--sgs-accent);
    cursor: pointer;
}
.sgs-canvas-switcher-newbtn:hover { background: var(--sgs-surface-2); }
.sgs-canvas-switcher-plus { font-size: 13px; line-height: 1; }

/* Demo-maps section header (with all-or-nothing hide) + the collapsed "show" row */
.sgs-canvas-switcher-demohdr {
    display: flex;
    align-items: center;
    margin-top: 4px;
    padding: 4px var(--sgs-gap-sm) 2px;
    border-top: 1px solid var(--sgs-border-light);
}
.sgs-canvas-switcher-demolabel {
    flex: 1;
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--sgs-text-micro);
}
.sgs-canvas-switcher-demohdr .sgs-canvas-switcher-action { opacity: 0.55; }
.sgs-canvas-switcher-demohdr:hover .sgs-canvas-switcher-action { opacity: 1; }
.sgs-canvas-switcher-showdemos {
    margin-top: 4px;
    border-top: 1px solid var(--sgs-border-light);
    padding-top: 4px;
}
.sgs-canvas-switcher-showdemos-btn {
    width: 100%;
    padding: 5px var(--sgs-gap-sm);
    background: none;
    border: none;
    border-radius: var(--sgs-radius-sm);
    text-align: left;
    font-size: 9px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--sgs-text-micro);
    cursor: pointer;
}
.sgs-canvas-switcher-showdemos-btn:hover { background: var(--sgs-surface-2); color: var(--sgs-text-muted); }


/* ============================================================
   5. LAYER TREE — groups + rows
   ============================================================ */

/* Group container — outlined box wrapping header + children */
.sgs-group-wrap {
    border: 1px solid var(--sgs-card-border-color);
    border-radius: 5px;
    margin: 6px var(--sgs-gap-sm);
    background: var(--sgs-layer-card);
    box-shadow: var(--sgs-card-shadow);
    transition: background var(--sgs-transition);
}
[data-theme="dark"] .sgs-group-name,
[data-theme="dark"] .sgs-layer-name {
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}
/* Checked + expanded: step back to off-white to frame the children */
.sgs-group-wrap:has(.sgs-group-triangle--open)[data-on] {
    background: var(--sgs-surface-2);
    transition: background var(--sgs-transition);
}
/* …and de-emphasize the group's OWN checkbox: knock the accent down to a near-gray
   faint blue so focus shifts to the turned-on child layers. Redefining --sgs-accent
   on the input cascades to every checkbox-style variant, which all read it. Scoped
   with `>` to the header so child-layer checkboxes stay full blue. The basemap card
   (#group-wrap-basemap) is excluded: it behaves like a single layer, so its checkbox
   stays fully blue whether the swatch list is open or closed. */
.sgs-group-wrap:has(.sgs-group-triangle--open)[data-on]:not(#group-wrap-basemap) > .sgs-group-header input[type="checkbox"] {
    --sgs-accent: var(--sgs-accent-faint);
    --sgs-accent-light: var(--sgs-accent-light-faint);
}
.sgs-group-header {
    display: flex;
    align-items: center;
    gap: var(--sgs-row-gap);
    padding: 5px var(--sgs-gap-sm) 5px var(--sgs-gap-xs);
    min-height: 28px;
    user-select: none;
    cursor: pointer;
    border-radius: var(--sgs-radius-sm);
    transition: background var(--sgs-transition);
}
.sgs-group-header:hover {
    background: none;
}

.sgs-group-triangle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--sgs-text-off);
    flex-shrink: 0;
    cursor: pointer;
    border-radius: var(--sgs-radius-sm);
    transition: color var(--sgs-transition), background var(--sgs-transition);
    position: relative;
    top: -0.06em;
}
.sgs-group-triangle svg {
    transition: transform var(--sgs-transition);
}
.sgs-group-triangle--open svg {
    transform: rotate(90deg);
}
.sgs-group-triangle:hover {
    color: var(--sgs-text);
    background: var(--sgs-surface-2);
}

.sgs-group-name {
    font-weight: 400;
    font-size: var(--sgs-font-base);
    color: var(--sgs-text);
    transition: color var(--sgs-transition);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: 18px;
    margin-top: -3px;
}

.sgs-group-children {
    padding: 0 6px 0 6px;
    overflow: hidden;
    transition: max-height var(--sgs-transition-slow);
    border-radius: 0 0 5px 5px;
}
.sgs-group-children > .sgs-layer-wrap {
    margin-left: 0;
    margin-right: 0;
}

/* Layer wrapper — uniform outlined box (matches group container) */
.sgs-layer-wrap {
    border: 1px solid var(--sgs-card-border-color);
    border-radius: 5px;
    margin: 6px var(--sgs-gap-sm);
    background: var(--sgs-layer-card);
    cursor: pointer;
    box-shadow: var(--sgs-card-shadow);
    transition: background var(--sgs-transition);
}

/* On: lift background + strengthen border (border-color direct, not via custom property — doesn't inherit to children) */
.sgs-layer-wrap[data-on],
.sgs-group-wrap[data-on] {
    background: var(--sgs-layer-card-on);
    border-color: var(--sgs-border);
}
/* On-state raised bevel — layer cards and collapsed on-groups only.
   Expanded groups excluded so children get visual emphasis instead.
   --sgs-card-shadow set here, NOT on group-wrap broadly, to prevent inheritance by child layer-wraps. */
.sgs-layer-wrap[data-on],
.sgs-group-wrap[data-on]:not(:has(.sgs-group-triangle--open)) {
    --sgs-card-shadow: inset 0 1px 0 rgba(255,255,255,0.80), inset 0 -1px 0 rgba(0,0,0,0.18);
}
/* The 0.80 white top bevel is tuned for light mode's near-white on-cards; on a dark lifted
   card that's a hot white glow — keep just a little top light accent, and a soft bottom shade
   (both stronger/more defined than the muted off-card default, so on-cards read as lifted). */
[data-theme="dark"] .sgs-layer-wrap[data-on],
[data-theme="dark"] .sgs-group-wrap[data-on]:not(:has(.sgs-group-triangle--open)) {
    --sgs-card-shadow: inset 0 1px 0 rgba(255,255,255,0.16), inset 0 -1px 0 rgba(0,0,0,0.16);
}
/* Layers inside a turned-off group (or off dynamic MapServer, which is also a group-wrap) stay
   fully gray: not just the off background, but the muted off border too — the prominent on-state
   --sgs-border would otherwise make a suppressed layer read as active when nothing is rendered. */
.sgs-group-wrap:not([data-on]) .sgs-layer-wrap[data-on] {
    background: var(--sgs-layer-card);
    border-color: var(--sgs-card-border-color);
}
/* …and their checkboxes drop to the same faint accent: the parent group is off so
   nothing is visible — no reason for a child layer's blue dot to draw attention.
   Same mechanism as the expanded-group header checkbox. */
.sgs-group-wrap:not([data-on]) .sgs-group-children input[type="checkbox"] {
    --sgs-accent: var(--sgs-accent-faint);
    --sgs-accent-light: var(--sgs-accent-light-faint);
}
/* On + collapsed + no active children: visually indistinguishable from off.
   Excludes the basemap card (#group-wrap-basemap): its children are swatches, not
   checkbox layers, so "no checked children" is always true — it must stay lit-when-on. */
.sgs-group-wrap[data-on]:not(#group-wrap-basemap):has(.sgs-group-children):not(:has(.sgs-group-triangle--open)):not(:has(.sgs-group-children input:checked)) {
    background: var(--sgs-layer-card);
}
.sgs-group-wrap[data-on]:not(#group-wrap-basemap):has(.sgs-group-children):not(:has(.sgs-group-triangle--open)):not(:has(.sgs-group-children input:checked))
    :is(.sgs-group-name, .sgs-group-icon, .sgs-group-triangle) {
    color: var(--sgs-text-off);
}
/* Hover highlights only on off-state cards; on-state (white) cards stay white.
   Group rules guard against child .sgs-layer-wrap hover bleeding up to the group background.
   Uses --sgs-surface-2 (one step from the resting --sgs-surface-hover) so the hover shift
   is subtle, matching the short basemap-swatch hover step. */
.sgs-layer-wrap:not([data-on]):hover,
.sgs-group-wrap:not([data-on]):hover:not(:has(.sgs-layer-wrap:hover)) {
    background: var(--sgs-surface-2);
}
/* Expanded on-group: no hover lift — it stays the plain expanded gray
   (--sgs-surface-2) so hovering doesn't pull focus back to the group itself. */
/* Child layer-wraps inside a group: only highlight when off */
.sgs-group-children .sgs-layer-wrap:not([data-on]):hover {
    background: var(--sgs-surface-2);
}

/* Leaf layer row — cursor:default so individual elements control their own cursor */
.sgs-layer-row,
.sgs-legend,
.sgs-filter-body {
    cursor: default;
}

/* ── Local performance instrument strip (ADR #42) ───────────────────────────
   Thin numeric readout at the bottom of an expanded vector-layer card; only
   present when the local perf toggle is on and the layer was measured. */
/* Performance is its own third section between symbology and fields. The container gives a
   small left/right inset (a touch tighter than the fields panel, so the strip reads a hair
   wider) and little padding below. It collapses to nothing when the monitor is off (no strip
   inside), so an off card shows no empty gap. */
.sgs-perf-container {
    /* Bottom padding matches the left/right inset (6px) so when Fields are collapsed the perf
       strip has the same breathing room below as on its sides. The strip's own bottom margin is
       removed (below) so the gap to Fields, when present, stays where it already looked right. */
    padding: 0 6px 6px;
}
.sgs-perf-container:empty {
    display: none;
    padding: 0;
}
.sgs-perf-strip {
    margin: 2px 0 0;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    border-radius: var(--sgs-radius-sm);
    background: rgba(0,0,0,0.035);
    font-size: 11px;
    cursor: default;
}
[data-theme="dark"] .sgs-perf-strip {
    background: rgba(255,255,255,0.05);
}

/* ── Unified performance table docked across the bottom (perf-table.js) ──────────
   The foundation for the app's attribute-table surface. Styled to match the layer list,
   as a horizontal panel across the bottom; when open it raises the layer list above it. */
.sgs-perf-dock {
    position: fixed;
    /* Floating like the layer list: inset with a gap on every side + rounded card + full border. */
    left: var(--sgs-gap-sm);
    right: var(--sgs-gap-sm);
    bottom: var(--sgs-gap-sm);
    height: var(--sgs-perf-dock-h, 250px);
    z-index: 450;
    display: flex;
    flex-direction: column;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    box-shadow: 0 -6px 20px rgba(0,0,0,0.14);
    color: var(--sgs-text);
    overflow: hidden;
}
/* Raise the floating layer list (and any bottom-anchored panels) above the dock, keeping the
   dock's own bottom inset plus a separating gap. */
.sgs-perf-dock-open .sgs-panel {
    bottom: calc(var(--sgs-perf-dock-h, 250px) + var(--sgs-gap-sm) * 2);
}
/* Top-edge drag handle: a thin grabbable strip with a centered grip pill. Overlaid absolutely on
   the top edge (not a flow child) so it adds ZERO height to the header — the pill floats over the
   empty top-centre of the header between the title (left) and the buttons (right). */
.sgs-perf-dock-resize {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 8px;
    z-index: 2;
    cursor: ns-resize;
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
}
.sgs-perf-dock-resize::before {
    content: '';
    width: var(--sgs-grip-len);
    height: var(--sgs-grip-thick);
    border-radius: 2px;
    background: var(--sgs-border);
}
.sgs-perf-dock-resize:hover::before { background: var(--sgs-text-muted); }
/* While dragging, kill text selection + pointer noise across the app. */
.sgs-perf-dock-resizing { user-select: none; cursor: ns-resize; }
.sgs-perf-dock-head {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    /* Slim header (matches the layer-list header height). Reserved for future table controls
       (filters, attribute-column pickers) — the space is intentional headroom, not padding. */
    padding: 3px var(--sgs-gap-md);
    border-bottom: 1px solid var(--sgs-border-light);
    background: var(--sgs-layer-canvas);
    flex-shrink: 0;
}
.sgs-perf-dock-title {
    font-size: 12.5px;
    font-weight: 700;
    color: var(--sgs-text);
}
.sgs-perf-dock-count {
    font-size: 11px;
    color: var(--sgs-text-muted);
    /* Absorbs the free space so everything after it (reload, ✕) floats to the right edge. */
    margin-right: auto;
}
.sgs-perf-dock-reload {
    font-size: 11px;
    padding: 2px 8px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-perf-dock-reload:hover { background: var(--sgs-surface-2); color: var(--sgs-text); }
.sgs-perf-dock-reload:disabled { opacity: 0.6; cursor: default; }
/* Head buttons (chevron · fullscreen · ✕): ONE cluster — flex-centered so all
   three glyphs sit on the same optical middle (n20 2026-07-12), 4px apart
   instead of the head's 8px gap, with the ✕ tucked toward the edge so its
   glyph sits about as far from the right edge as the title from the left
   (n21). */
.sgs-perf-dock-close,
.sgs-perf-dock-hide,
.sgs-perf-dock-max {
    width: 22px;
    height: 22px;
    border-radius: var(--sgs-radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-perf-dock-close { font-size: 16px; line-height: 1; margin-right: -5px; }
.sgs-perf-dock-hide,
.sgs-perf-dock-max { margin-right: calc(var(--sgs-gap-xs) - var(--sgs-gap-sm)); }
.sgs-perf-dock-close:hover,
.sgs-perf-dock-hide:hover,
.sgs-perf-dock-max:hover { background: var(--sgs-surface-2); color: var(--sgs-text); }
.sgs-perf-dock--max .sgs-perf-dock-max { color: var(--sgs-accent); }
/* Collapsed to the slim bar: the whole header is the re-expand target, and the
   chevron points up. */
.sgs-perf-dock--min .sgs-perf-dock-head { cursor: pointer; }
.sgs-perf-dock--min .sgs-perf-dock-hide svg { transform: rotate(180deg); }
.sgs-perf-dock-body {
    flex: 1;
    overflow: auto;
    padding: 0;
}
/* A config BLOCK holding the bottom dock (placement: dock-bottom, R38): the dock
   chrome is the same, but a block's own body wants the panel's breathing room
   rather than a table's edge-to-edge rows. */
.sgs-dock-block-body {
    padding: var(--sgs-gap-sm) var(--sgs-gap-md) var(--sgs-gap-md);
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
}
/* Block chrome (the ⓘ, the zoom-follow latch) sits in the dock head too, so a
   block reads the same wherever it is placed. */
.sgs-perf-dock-head .sgs-widget-zoom,
.sgs-perf-dock-head .sgs-basemap-info-btn { margin-left: 2px; }
.sgs-perf-dock-empty {
    padding: var(--sgs-gap-lg);
    font-size: 12px;
    color: var(--sgs-text-muted);
}
.sgs-perf-dock-empty-icon svg { vertical-align: -2px; }

/* ── The attribute table's always-there bottom sliver (n3) ──────────────────────
   A tiny centered tab on the bottom edge; hidden while either bottom dock is open
   (the shared .sgs-perf-dock-open layout class covers both). */
.sgs-dock-sliver {
    position: fixed;
    left: 50%;
    transform: translateX(-50%);
    bottom: 0;
    z-index: 440;
    width: 56px;
    height: 13px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-bottom: none;
    border-radius: var(--sgs-radius-md) var(--sgs-radius-md) 0 0;
    color: var(--sgs-text-muted);
    cursor: pointer;
    opacity: 0.75;
    transition: opacity var(--sgs-transition), color var(--sgs-transition);
}
.sgs-dock-sliver:hover { opacity: 1; color: var(--sgs-text); }
.sgs-perf-dock-open .sgs-dock-sliver { display: none; }
.sgs-pt-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 11.5px;
    /* Fixed layout so the Type + Layer columns take a set width and the metric columns share the
       rest evenly, instead of the Layer name ballooning to soak up all the slack. */
    table-layout: fixed;
}
/* Type pill column: just wide enough for the pillbox. Layer name: deliberately narrow (was
   soaking up all the free width), truncated with an ellipsis. Metric columns split the rest. */
/* Perf-table column plan only — the attribute table's columns are data-driven and
   user-resizable, so these fixed widths must not leak onto it. */
#sgs-perf-dock .sgs-pt-table th:nth-child(1), #sgs-perf-dock .sgs-pt-table td:nth-child(1) { width: 70px; }
#sgs-perf-dock .sgs-pt-table th:nth-child(2), #sgs-perf-dock .sgs-pt-table td:nth-child(2) { width: 22%; }
.sgs-pt-th {
    position: sticky;
    top: 0;
    z-index: 1;
    text-align: left;
    padding: 6px var(--sgs-gap-md);
    background: var(--sgs-layer-canvas);
    border-bottom: 1px solid var(--sgs-border);
    color: var(--sgs-text-muted);
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
}
.sgs-pt-th--num { text-align: right; }
.sgs-pt-th--active { color: var(--sgs-accent); }
.sgs-pt-th:hover { color: var(--sgs-text); }
.sgs-pt-td {
    padding: 5px var(--sgs-gap-md);
    border-bottom: 1px solid var(--sgs-border-light);
    white-space: nowrap;
    color: var(--sgs-text);
}
/* Vertical separators between columns (drop the trailing one on the last column). */
.sgs-pt-th, .sgs-pt-td { border-right: 1px solid var(--sgs-border-light); }
.sgs-pt-th:last-child, .sgs-pt-td:last-child { border-right: none; }
.sgs-pt-td--num { text-align: right; font-variant-numeric: tabular-nums; }
.sgs-pt-td--type { white-space: nowrap; }
.sgs-pt-td--name { font-weight: 500; overflow: hidden; text-overflow: ellipsis; }

/* ── Attribute-table variant: every cell ellipsizes inside its (resizable) column ── */
.sgs-pt-table--attr .sgs-pt-td,
.sgs-pt-table--attr .sgs-pt-th { overflow: hidden; text-overflow: ellipsis; }
/* Zebra striping + a distinct header gray (n19 2026-07-12): three grays, three
   jobs — header (surface-mid) ▸ even rows (a whisper of text) ▸ odd rows (bg). */
.sgs-pt-table--attr .sgs-pt-th { background: var(--sgs-surface-mid); }
.sgs-pt-table--attr tbody .sgs-pt-row:nth-child(even) { background: color-mix(in srgb, var(--sgs-text) 4%, transparent); }
/* The whole row zooms (n19): advertise it, and let hover out-rank the stripe. */
.sgs-pt-row--zoomable { cursor: pointer; }
.sgs-pt-table--attr tbody .sgs-pt-row--zoomable:hover { background: var(--sgs-surface-hover); }
/* Right-edge grip inside each header cell: drag to resize that column. */
.sgs-pt-table--attr .sgs-pt-th { padding-right: 14px; }
.sgs-pt-col-grip {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    width: 9px;
    cursor: col-resize;
}
.sgs-pt-col-grip:hover { background: color-mix(in srgb, var(--sgs-accent) 18%, transparent); }
.sgs-pt-col-resizing { user-select: none; cursor: col-resize; }
/* Zoom-to-feature handle on each row (quiet until hovered, like the layer-row actions). */
.sgs-pt-th--zoom, .sgs-pt-td--zoom { padding: 0; text-align: center; }
.sgs-pt-zoom {
    border: none;
    background: none;
    font: inherit;
    font-size: 13px;
    line-height: 1;
    padding: 2px 6px;
    cursor: pointer;
    color: var(--sgs-text-muted);
    opacity: 0.45;
    transition: opacity var(--sgs-transition), color var(--sgs-transition);
}
.sgs-pt-row:hover .sgs-pt-zoom { opacity: 1; }
.sgs-pt-zoom:hover { color: var(--sgs-accent); }
.sgs-pt-zoom svg { display: block; }
/* Shared-SVG rename/delete buttons (canvas switcher, cloud maps, Geogs header):
   center the icon like their former text glyphs. */
.sgs-canvas-switcher-action svg,
.sgs-cloudmap-action svg,
.sgs-savant-conv-btn svg { display: block; margin: 0 auto; }

/* The $/mo cell: bold, colored by its rate class (n11); conversion on hover (n9).
   Feature storage is the pricey class (amber); file / other is cheap (green). */
.sgs-ot-td--cost { font-weight: 600; white-space: nowrap; }
.sgs-rate--feature { color: #c9761b; }
.sgs-rate--file { color: #3a9d5d; }
.sgs-rate--none { color: var(--sgs-text-muted); font-weight: 400; }
[data-theme="dark"] .sgs-rate--feature { color: #e6a24c; }
[data-theme="dark"] .sgs-rate--file { color: #5cc281; }
/* Value on top, faint session mean stacked underneath (like the per-card strip). */
.sgs-pt-val { display: block; }
.sgs-pt-mean {
    display: block;
    font-size: 0.82em;
    opacity: 0.5;
    font-variant-numeric: tabular-nums;
}
.sgs-pt-row:hover { background: var(--sgs-surface); }
/* Placeholder rows for layers that were never drawn: de-emphasized so the all-— row doesn't read
   as real data. (You can't measure a layer that was never turned on and loaded.) */
.sgs-pt-row--unmeasured { opacity: 0.5; }
.sgs-perf-dock-foot {
    margin: 0;
    padding: 6px var(--sgs-gap-md) 8px;
    font-size: 11px;
    color: var(--sgs-text-muted);
}

.sgs-perf-head {
    display: flex;
    justify-content: space-between;
    /* center (not baseline) so the table button + ⓘ badge line up vertically with the
       feature count instead of riding above the text baseline. */
    align-items: center;
    margin-bottom: 4px;
}
.sgs-perf-title {
    font-weight: 600;
    letter-spacing: 0.02em;
    opacity: 0.85;
}
.sgs-perf-fc {
    opacity: 0.6;
    font-variant-numeric: tabular-nums;
    margin-left: auto;
}
/* Circular "i" badge drawn in CSS — crisper than the ⓘ glyph, which renders unevenly. */
.sgs-perf-info {
    flex: 0 0 auto;
    margin-left: 4px;
    padding: 0;
    /* Sized to match the table button (they sit side by side); the bordered circle reads
       heavier than an outline glyph, so it is kept a touch smaller than the table icon. */
    width: 12px;
    height: 12px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: 1px solid currentColor;
    background: transparent;
    color: var(--sgs-text-muted);
    font-size: 8px;
    font-weight: 700;
    /* Upright (not italic): an italic serif "i" leans right and read as off-centre inside the
       tiny circle; upright centres cleanly via flex. */
    font-style: normal;
    font-family: Georgia, 'Times New Roman', serif;
    line-height: 1;
    cursor: pointer;
    opacity: 0.6;
    transition: color var(--sgs-transition), border-color var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-perf-info:hover {
    opacity: 1;
    color: var(--sgs-accent);
}
.sgs-perf-tablebtn {
    flex: 0 0 auto;
    margin-left: 6px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 14px;
    height: 14px;
    border: none;
    background: transparent;
    color: var(--sgs-text-muted);
    cursor: pointer;
    opacity: 0.6;
    transition: color var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-perf-tablebtn:hover { opacity: 1; color: var(--sgs-accent); }
.sgs-perf-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 3px var(--sgs-gap-sm);
}
/* Load-phase breakdown: a thin stacked bar (to-first-draw vs settle) under the metric grid. */
.sgs-perf-loadbar {
    display: flex;
    height: 5px;
    margin-top: 6px;
    border-radius: 3px;
    overflow: hidden;
    background: var(--sgs-border-light);
}
.sgs-perf-loadseg { display: block; min-width: 2px; }
.sgs-perf-loadseg--draw { background: var(--sgs-accent); }
/* Network transfer (measured) is the darkest; parse/first-draw is the accent; settle is faint. */
.sgs-perf-loadseg--transfer { background: color-mix(in srgb, var(--sgs-accent) 70%, #111); }
.sgs-perf-loadseg--process { background: var(--sgs-accent); }
.sgs-perf-loadseg--settle { background: color-mix(in srgb, var(--sgs-accent) 35%, transparent); }
.sgs-perf-metric {
    display: flex;
    align-items: baseline;
    /* Wrap so the session mean drops to its own line UNDER the value (label left, value right on
       row 1; ~mean right-aligned on row 2). The mean span is only appended when there is a mean,
       so metrics without one never reserve a second line. */
    flex-wrap: wrap;
    gap: 2px 4px;
    min-width: 0;
}
.sgs-perf-metric--headline {
    font-weight: 600;
}
.sgs-perf-label {
    opacity: 0.6;
    flex: 0 0 auto;
}
.sgs-perf-val {
    font-variant-numeric: tabular-nums;
    margin-left: auto;
}
.sgs-perf-mean {
    opacity: 0.45;
    font-variant-numeric: tabular-nums;
    /* Full row so it sits below the value, right-aligned under it. */
    flex: 0 0 100%;
    text-align: right;
    font-size: 0.9em;
}
.sgs-perf-prov {
    margin-top: 6px;
    padding-top: 5px;
    border-top: 1px solid var(--sgs-border, rgba(0, 0, 0, 0.08));
    display: grid;
    gap: 2px;
}
.sgs-perf-prov-row {
    display: flex;
    align-items: baseline;
    gap: var(--sgs-gap-sm);
    min-width: 0;
}
.sgs-perf-prov-k {
    flex: 0 0 auto;
    opacity: 0.55;
}
.sgs-perf-prov-v {
    margin-left: auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}
.sgs-perf-prov-link {
    color: var(--sgs-accent);
    text-decoration: none;
}
.sgs-perf-prov-link:hover {
    text-decoration: underline;
}
.sgs-perf-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sgs-gap-sm);
    margin-top: 6px;
    padding-top: 5px;
    border-top: 1px solid var(--sgs-border, rgba(0, 0, 0, 0.08));
}
.sgs-perf-hint {
    opacity: 0.55;
    font-size: 11px;
    line-height: 1.3;
}
.sgs-perf-btn {
    flex: 0 0 auto;
    padding: 2px 12px;
    font-size: 11px;
    font-weight: 600;
    cursor: pointer;
    border: 1px solid var(--sgs-border, rgba(0, 0, 0, 0.2));
    border-radius: var(--sgs-radius-sm, 4px);
    background: transparent;
    color: inherit;
}
.sgs-perf-btn:hover:not(:disabled) {
    background: var(--sgs-accent);
    border-color: var(--sgs-accent);
    color: #fff;
}
.sgs-perf-btn:disabled {
    opacity: 0.5;
    cursor: default;
}

/* ── "Data sources" tab (editorial format explainer + radars, ADR #42) ──────── */
.sgs-ds-tab .sgs-ds-note {
    font-size: 12px;
    opacity: 0.6;
    margin: var(--sgs-gap-sm) 0;
}
.sgs-ds-learn {
    margin-top: var(--sgs-gap-md);
}
.sgs-ds-learn-summary {
    cursor: pointer;
    font-weight: 600;
    padding: var(--sgs-gap-xs) 0;
}
.sgs-ds-cards {
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-sm);
    margin-top: var(--sgs-gap-sm);
}
.sgs-ds-card {
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    /* ~1.5x the prior 8/12 so the heading + blurb get more breathing room from the card edge. */
    padding: var(--sgs-gap-md) 18px;
    background: rgba(0,0,0,0.02);
    /* Anchor the card's text to the theme color — otherwise the name/blurb inherit a
       non-themed color and render dark-on-dark in dark mode (the default theme). */
    color: var(--sgs-text);
}
[data-theme="dark"] .sgs-ds-card {
    background: rgba(255,255,255,0.03);
}
/* The two house formats keep an identity tint but FAINT (owner 2026-07-07): the
   border mixes the identity color into the standard light border at the standard
   1px, so they read "a little more interesting", not louder. */
.sgs-ds-card--featured {
    border-color: color-mix(in srgb, var(--sgs-publish-green) 40%, var(--sgs-border-light));
    background: var(--sgs-publish-green-faint);
}
.sgs-ds-card[data-format-id="vectortiles"] {
    border-color: color-mix(in srgb, var(--sgs-vt-indigo) 40%, var(--sgs-border-light));
    background: var(--sgs-vt-indigo-faint);
}
.sgs-ds-card-summary {
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    font-weight: 600;
}
/* The name is a fixed column so the "Read more..." hints line up down the stack
   (owner 2026-07-07); the mini radar's margin-left:auto eats the slack, keeping
   mini radar + vscore + badge together at the right edge. */
.sgs-ds-card-name { flex: 0 0 auto; min-width: 235px; }
/* Indicative "versatility" mean (n8): quiet, light-gray, in a fixed slot just left of the badge.
   Its content is a constant-width label + an "x.x/5" value (tabular-nums), and the badge beside it
   is equal-width across cards, so the numbers line up in a vertical column down the stack (n18). */
.sgs-ds-card-vscore {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    flex: 0 0 auto;
    font-size: 11px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
    color: var(--sgs-text-off, #8c9baa);
    cursor: help;
    white-space: nowrap;
}
/* Small "versatility" caption so a bare number doesn't read like a version string (n18). */
.sgs-ds-card-vscore-label {
    font-size: 9.5px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.7;
}
.sgs-ds-card-vscore-val { font-weight: 600; }
.sgs-ds-card-badge {
    flex: 0 0 auto;
    /* Equal-width pills (fits the longest label, "DISPLAY FORMAT"), centered, so the vscore slot to
       their left keeps a constant right boundary and the numbers stay column-aligned (n18). */
    min-width: 100px;
    text-align: center;
    box-sizing: border-box;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    padding: 1px 6px;
    border-radius: 999px;
    /* Neutral role pill by default (Read format); the two house formats wear their identity color. */
    background: var(--sgs-fill-muted, rgba(0, 0, 0, 0.06));
    color: var(--sgs-text-off, #8c9baa);
}
.sgs-ds-card-badge--featured {
    background: var(--sgs-publish-green);
    color: #fff;
}
/* Vector Tiles "Display format" pill wears the indigo identity, mirroring the featured green pill. */
.sgs-ds-card[data-format-id="vectortiles"] .sgs-ds-card-badge {
    background: var(--sgs-vt-indigo);
    color: #fff;
}
/* ── Per-axis explainer (replaced the "Scores" dropdown, owner 2026-07-07) ──────
   Clicking a radar axis label bolds-and-holds it and fills this panel below the
   blurb+radar row with the score, the format's justification, and the axis ⓘ. */
.sgs-ds-axis-detail {
    margin-top: var(--sgs-gap-sm);
    border-top: 1px solid var(--sgs-border-light);
    padding-top: var(--sgs-gap-xs);
}
.sgs-ds-axis-detail-head {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}
.sgs-ds-axis-detail-name { font-weight: 600; font-size: var(--sgs-font-sm); }
.sgs-ds-score-info { align-self: center; }
.sgs-ds-score-info .sgs-basemap-info-btn { opacity: 0.5; width: 18px; height: 18px; }
.sgs-ds-axis-detail-head:hover .sgs-ds-score-info .sgs-basemap-info-btn,
.sgs-ds-score-info .sgs-basemap-info-btn:focus-visible { opacity: 1; }
.sgs-ds-score-val {
    margin-left: auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    font-size: 12px;
    padding: 0 6px;
    border-radius: 999px;
    background: var(--sgs-fill-muted, rgba(0, 0, 0, 0.06));
    color: var(--sgs-text, #1a1d23);
}
.sgs-ds-axis-detail-why {
    margin: 4px 0 0;
    font-size: 12px;
    line-height: 1.45;
    opacity: 0.8;
}
.sgs-ds-axis-detail-note {
    margin: 4px 0 0;
    font-size: 11px;
    font-style: italic;
    opacity: 0.6;
}
/* Clickable axis labels: pointer + bold-and-hold when active. */
.sgs-ds-radar-label--clickable { cursor: pointer; }
.sgs-ds-radar-label--clickable:hover { opacity: 1; }
.sgs-ds-radar-label--active { font-weight: 700; opacity: 1; }
/* "Read more..." hint: faint gray italic in a fixed column right of the name so the
   hints align down the closed stack; gone once the card is open. */
.sgs-ds-card-readmore {
    flex: 0 0 auto;
    font-size: 11px;
    font-style: italic;
    font-weight: 400;
    color: var(--sgs-text-micro);
}
.sgs-ds-card[open] .sgs-ds-card-readmore { visibility: hidden; }
/* Tiny label-free radar on the collapsed summary line, left of the versatility slot. */
.sgs-ds-radar-mini {
    flex: 0 0 auto;
    width: 22px;
    height: 22px;
    margin-left: auto; /* pushes itself + vscore + badge to the right edge */
}
.sgs-ds-card[open] .sgs-ds-radar-mini { visibility: hidden; }
/* Two halves: the narrative blurb on the LEFT (the wider half), the chart on the RIGHT, with no
   divider. Both top-aligned so the text sits right under the title and the radar floats to the top;
   wraps to stacked only when the card gets too narrow for both to breathe. */
.sgs-ds-card-body {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    /* Stretch so the radar slot spans the card's full height and can vertically center the chart
       (rather than pinning it to the top, which read as "sitting low" next to a tall blurb). */
    align-items: stretch;
    gap: var(--sgs-gap-md);
    margin-top: 4px;   /* text hugs the title */
}
.sgs-ds-card-blurb {
    /* The wider half (~two thirds); the radar takes the remaining third to its right. */
    flex: 1 1 300px;
    max-width: 60%;
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    opacity: 0.85;
}
/* Trailing source link inside the blurb (project page / how-to). Reads as part of the copy. */
.sgs-ds-card-link {
    color: var(--sgs-publish-green);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
}
.sgs-ds-card-link::after { content: ' \2192'; }  /* → */
.sgs-ds-card-link:hover { text-decoration: underline; }
/* Vector Tiles source links wear the indigo identity, not the default publish-green (n9). */
.sgs-ds-card[data-format-id="vectortiles"] .sgs-ds-card-link { color: var(--sgs-vt-indigo); }
/* The right third: an invisible box the radar is centered inside, both ways. More padding on the
   LEFT insulates the chart from the blurb; the tighter right keeps it off a wide empty gutter. */
.sgs-ds-radar-slot {
    flex: 1 1 210px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2px 4px 2px var(--sgs-gap-lg);
}
.sgs-ds-radar {
    /* Height matches the cropped 200x158 viewBox aspect (196 * 158/200 ≈ 155) so the box holds no
       letterbox padding — the chart fills it. The slot handles placement now. */
    flex: 0 0 auto;
    width: 196px;
    height: 155px;
    overflow: visible;   /* axis labels may sit just outside the viewBox — don't clip them */
}
.sgs-ds-radar-ring {
    fill: none;
    stroke: currentColor;
    opacity: 0.12;
}
.sgs-ds-radar-spoke {
    stroke: currentColor;
    opacity: 0.12;
}
/* Default data area tracks the app accent — no more stray third blue. */
.sgs-ds-radar-area {
    fill: var(--sgs-accent);
    fill-opacity: 0.22;
    stroke: var(--sgs-accent);
    stroke-width: 1.5;
    stroke-linejoin: round;
}
/* The featured (GeoParquet) radar wears the publish-green identity + a quiet draw-in. */
.sgs-ds-radar--featured .sgs-ds-radar-area {
    fill: var(--sgs-publish-green);
    fill-opacity: 0.28;
    stroke: var(--sgs-publish-green);
    transform-box: view-box;
    transform-origin: 100px 96px;
    animation: sgs-ds-radar-draw 0.45s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
/* Vector Tiles radar wears the indigo identity, matching its card tint + badge (n9). */
.sgs-ds-card[data-format-id="vectortiles"] .sgs-ds-radar-area {
    fill: var(--sgs-vt-indigo);
    fill-opacity: 0.22;
    stroke: var(--sgs-vt-indigo);
}
@keyframes sgs-ds-radar-draw {
    from { opacity: 0; transform: scale(0.4); }
    to   { opacity: 1; transform: scale(1); }
}
.sgs-ds-radar-label {
    font-size: 9px;
    fill: currentColor;
    opacity: 0.72;
}
.sgs-ds-measure {
    margin-top: var(--sgs-gap-lg);
    padding-top: var(--sgs-gap-md);
    border-top: 1px solid var(--sgs-border-light);
}
.sgs-ds-toggle {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    cursor: pointer;
    margin: var(--sgs-gap-sm) 0;
    font-weight: 500;
}
.sgs-ds-batch {
    display: flex;
    gap: var(--sgs-gap-sm);
    margin: var(--sgs-gap-sm) 0;
}
.sgs-ds-batch-btn,
.sgs-ds-viewtable {
    padding: 4px 14px;
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    cursor: pointer;
    border: 1px solid var(--sgs-border, rgba(0, 0, 0, 0.2));
    border-radius: var(--sgs-radius-sm, 4px);
    background: transparent;
    color: inherit;
}
.sgs-ds-batch-btn:hover:not(:disabled),
.sgs-ds-viewtable:hover:not(:disabled) {
    background: var(--sgs-accent);
    border-color: var(--sgs-accent);
    color: #fff;
}
.sgs-ds-batch-btn:disabled,
.sgs-ds-viewtable:disabled { opacity: 0.4; cursor: default; }
.sgs-ds-xlink {
    display: inline-block;
    margin-top: var(--sgs-gap-sm);
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-accent);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.sgs-ds-xlink:hover { text-decoration: underline; }
.sgs-ds-xlink:disabled { opacity: 0.4; cursor: default; text-decoration: none; }
/* Signed-out cost CTA above the format explainer (n16): same link treatment as .sgs-ds-xlink.
   Tight below it (n18) so it hugs the "Our vector data formats" disclosure that follows. */
.sgs-ds-costcta {
    display: inline-block;
    margin: var(--sgs-gap-xs) 0 var(--sgs-gap-xs);
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-accent);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.sgs-ds-costcta:hover { text-decoration: underline; }

/* In-text format links in the convergence intro (n20): bold + black, open their card on click. */
.sgs-ds-formatlink {
    display: inline;
    padding: 0;
    border: none;
    background: none;
    font: inherit;
    font-weight: 700;
    color: var(--sgs-text, #1a1d23);
    cursor: pointer;
}
.sgs-ds-formatlink:hover { text-decoration: underline; }

/* ── Publish-to-ArcGIS dialog (the LayerStyle→drawingInfo payoff, ADR #41) ──────
   A consequential moment: a "flight plan" stepper previews exactly what will happen,
   then animates as each stage lands. Cohesive with --sgs-* tokens; the only accent
   indulgence is a publish-green that ties back to the format identity. */
.sgs-pub-window { width: min(460px, 92vw); }
.sgs-pub {
    --sgs-pub-ok: var(--sgs-publish-green);
    padding: var(--sgs-gap-md) var(--sgs-gap-lg) var(--sgs-gap-lg);
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-md);
}
.sgs-pub-summary {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-accent-faint);
}
.sgs-pub-swatch {
    width: 26px; height: 26px;
    flex: 0 0 auto;
    border-radius: 6px;
    background: var(--sgs-pub-color, var(--sgs-accent));
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.25);
}
.sgs-pub-dest { font-weight: 600; font-size: 13px; }
.sgs-pub-facts {
    font-size: 12px;
    opacity: 0.7;
    font-variant-numeric: tabular-nums;
    margin-top: 1px;
}
.sgs-pub-lede {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    opacity: 0.78;
}

/* The flight plan */
.sgs-pub-plan {
    list-style: none;
    margin: 0;
    padding: 0;
}
.sgs-pub-stage {
    position: relative;
    display: flex;
    gap: var(--sgs-gap-sm);
    padding: 7px 0;
}
.sgs-pub-node {
    position: relative;
    flex: 0 0 auto;
    width: 26px; height: 26px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--sgs-border);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    transition: background var(--sgs-transition), transform var(--sgs-transition);
}
/* Connector line between nodes — anchored to the list item so it spans node-to-node
   regardless of how tall the stage text wraps. Fills when this stage is done. */
.sgs-pub-stage:not(:last-child)::after {
    content: "";
    position: absolute;
    left: 13px;                 /* node center (node is 26px wide, first flex child) */
    transform: translateX(-50%);
    top: 33px;                  /* 7px top padding + 26px node */
    bottom: -7px;               /* reach into the next stage's top padding */
    width: 2px;
    background: var(--sgs-border);
    transition: background var(--sgs-transition);
}
.sgs-pub-num { transition: opacity var(--sgs-transition); }
.sgs-pub-node-icon { position: absolute; display: grid; place-items: center; }

.sgs-pub-stage-text { padding-top: 2px; }
.sgs-pub-stage-label { font-weight: 600; font-size: 13px; }
.sgs-pub-stage-sub { font-size: 12px; opacity: 0.62; margin-top: 1px; }

/* Stage states */
.sgs-pub-stage[data-state="running"] .sgs-pub-node {
    background: var(--sgs-accent);
    animation: sgs-pub-pulse 1.1s ease-in-out infinite;
}
.sgs-pub-stage[data-state="done"] .sgs-pub-node { background: var(--sgs-pub-ok); }
.sgs-pub-stage[data-state="warn"] .sgs-pub-node { background: var(--sgs-warn); }
.sgs-pub-stage[data-state="error"] .sgs-pub-node { background: var(--sgs-danger); }
.sgs-pub-stage[data-state="done"] .sgs-pub-num,
.sgs-pub-stage[data-state="warn"] .sgs-pub-num,
.sgs-pub-stage[data-state="error"] .sgs-pub-num { opacity: 0; }
.sgs-pub-stage[data-state="done"]::after { background: var(--sgs-pub-ok); }
.sgs-pub-stage[data-state="idle"] .sgs-pub-stage-text { opacity: 0.55; }

@keyframes sgs-pub-pulse {
    0%, 100% { box-shadow: 0 0 0 0 var(--sgs-accent-faint); }
    50% { box-shadow: 0 0 0 5px var(--sgs-accent-faint); }
}

/* Result — the receipt. Reveals with a quiet rise so the final beat lands. */
.sgs-pub-result {
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    border-radius: var(--sgs-radius-sm);
    border-left: 3px solid var(--sgs-pub-ok);
    background: color-mix(in srgb, var(--sgs-publish-green) 9%, transparent);
    animation: sgs-pub-result-in var(--sgs-transition-slow) ease both;
}
@keyframes sgs-pub-result-in {
    from { opacity: 0; transform: translateY(5px); }
    to   { opacity: 1; transform: none; }
}
/* Respect users who ask for less motion: keep the meaning (state colors, the receipt),
   drop the movement. */
@media (prefers-reduced-motion: reduce) {
    .sgs-ds-radar--featured .sgs-ds-radar-area,
    .sgs-pub-result,
    .sgs-pub-stage[data-state="running"] .sgs-pub-node {
        animation: none;
    }
}
.sgs-pub-result[data-kind="warn"] { border-left-color: var(--sgs-warn); background: rgba(230,126,34,0.08); }
.sgs-pub-result[data-kind="error"] { border-left-color: var(--sgs-danger); background: rgba(220,38,38,0.08); }
.sgs-pub-result-title { font-weight: 700; font-size: 13px; }
.sgs-pub-result-note { font-size: 12px; line-height: 1.5; opacity: 0.8; margin: 4px 0 6px; }
.sgs-pub-link {
    font-weight: 600;
    font-size: 13px;
    color: var(--sgs-accent);
    text-decoration: none;
}
.sgs-pub-link:hover { text-decoration: underline; }

/* Actions */
.sgs-pub-actions {
    display: flex;
    justify-content: flex-end;
    gap: var(--sgs-gap-sm);
    margin-top: 2px;
}
.sgs-pub-btn {
    padding: 7px 16px;
    border-radius: var(--sgs-radius-sm);
    font: inherit;
    font-weight: 600;
    font-size: 13px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-pub-btn--primary { background: var(--sgs-accent); color: #fff; }
.sgs-pub-btn--primary:hover:not(:disabled) { filter: brightness(1.07); }
.sgs-pub-btn--ghost { background: transparent; border-color: var(--sgs-border); color: var(--sgs-text); }
.sgs-pub-btn--ghost:hover:not(:disabled) { background: var(--sgs-accent-faint); }
.sgs-pub-btn:disabled { opacity: 0.55; cursor: default; }

/* ── Convert-to-GeoParquet dialog (lighter sibling of the publish flight-plan) ── */
.sgs-conv-window { width: min(440px, 92vw); }
.sgs-conv {
    padding: var(--sgs-gap-md) var(--sgs-gap-lg) var(--sgs-gap-lg);
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-md);
}
.sgs-conv-summary {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    border-radius: var(--sgs-radius-sm);
    /* accent-subtle, not accent-faint: faint keeps the accent's mid lightness, which
       reads as a dark slab when used as a fill (notebear 2026-07-07 n1) */
    background: var(--sgs-accent-subtle);
}
.sgs-conv-swatch {
    width: 26px; height: 26px;
    flex: 0 0 auto;
    border-radius: 6px;
    background: var(--sgs-conv-color, var(--sgs-accent));
    box-shadow: inset 0 0 0 1px rgba(0,0,0,0.18), 0 1px 3px rgba(0,0,0,0.25);
}
.sgs-conv-dest { font-weight: 600; font-size: 13px; }
.sgs-conv-facts { font-size: 12px; opacity: 0.7; font-variant-numeric: tabular-nums; margin-top: 1px; }
.sgs-conv-lede { margin: 0; font-size: 13px; line-height: 1.5; opacity: 0.78; }
.sgs-conv-esri-note { margin: 4px 0 0; font-size: 12px; line-height: 1.45; opacity: 0.72; }
.sgs-conv-esri-link { font-size: 12px; }

.sgs-conv-progress {
    font-size: 12px;
    opacity: 0.8;
    font-variant-numeric: tabular-nums;
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-accent-subtle);
}

.sgs-conv-result {
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    border-radius: var(--sgs-radius-sm);
    border-left: 3px solid var(--sgs-publish-green);
    background: color-mix(in srgb, var(--sgs-publish-green) 9%, transparent);
}
.sgs-conv-result[data-kind="warn"] { border-left-color: var(--sgs-warn); background: rgba(230,126,34,0.08); }
.sgs-conv-result[data-kind="error"] { border-left-color: var(--sgs-danger); background: rgba(220,38,38,0.08); }
.sgs-conv-result-title { font-weight: 700; font-size: 13px; }
.sgs-conv-result-note { font-size: 12px; line-height: 1.5; opacity: 0.8; margin: 4px 0 6px; }
.sgs-conv-link { font-weight: 600; font-size: 13px; color: var(--sgs-accent); text-decoration: none; }
.sgs-conv-link:hover { text-decoration: underline; }

.sgs-conv-actions { display: flex; justify-content: flex-end; gap: var(--sgs-gap-sm); margin-top: 2px; }
.sgs-conv-btn {
    padding: 7px 16px;
    border-radius: var(--sgs-radius-sm);
    font: inherit; font-weight: 600; font-size: 13px;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-conv-btn--primary { background: var(--sgs-accent); color: #fff; }
.sgs-conv-btn--primary:hover:not(:disabled) { filter: brightness(1.07); }
.sgs-conv-btn--ghost { background: transparent; border-color: var(--sgs-border); color: var(--sgs-text); }
.sgs-conv-btn--ghost:hover:not(:disabled) { background: var(--sgs-accent-faint); }
.sgs-conv-btn:disabled { opacity: 0.55; cursor: default; }

/* The per-layer "Convert to GeoParquet" entry button, inside the field-edit panel. */
.sgs-convert { margin-top: var(--sgs-gap-sm); }
.sgs-convert-btn {
    width: 100%;
    padding: 6px 10px;
    border-radius: var(--sgs-radius-sm);
    border: 1px solid var(--sgs-border);
    background: transparent;
    color: var(--sgs-text);
    font: inherit; font-weight: 600; font-size: 12px;
    cursor: pointer;
    transition: background var(--sgs-transition), border-color var(--sgs-transition);
}
.sgs-convert-btn:hover { background: var(--sgs-accent-faint); border-color: var(--sgs-accent); }

.sgs-layer-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--sgs-row-gap);
    padding: 5px var(--sgs-gap-sm) 5px var(--sgs-gap-xs);
    min-height: 28px; /* pre-sized to compose-mode height (18px icons + 10px padding) so rows don't jump */
    user-select: none;
    border-radius: var(--sgs-radius-sm);
    box-shadow: 0 1px 0 rgba(0,0,0,0.07);
    transition: background var(--sgs-transition);
}
[data-theme="dark"] .sgs-layer-row {
    box-shadow: 0 1px 0 rgba(0,0,0,0.45), inset 0 1px 0 rgba(255,255,255,0.05);
}
/* When the card is open (legend visible below the row), suppress the bottom hairline so it
   doesn't show as an interior divider. Dark mode keeps the top inset highlight. */
.sgs-layer-wrap:has(.sgs-legend:not(.sgs-hidden)) .sgs-layer-row,
.sgs-layer-wrap:has(.sgs-filter-body:not(.sgs-hidden)) .sgs-layer-row {
    box-shadow: none;
}
[data-theme="dark"] .sgs-layer-wrap:has(.sgs-legend:not(.sgs-hidden)) .sgs-layer-row,
[data-theme="dark"] .sgs-layer-wrap:has(.sgs-filter-body:not(.sgs-hidden)) .sgs-layer-row {
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.05);
}
/* guide for centering layer card elements, in dev */
/*
.sgs-layer-row::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 50%;
    height: 1px;
    background: rgba(255, 0, 0, 0.35);
    pointer-events: none;
}
*/

.sgs-layer-row input[type="checkbox"],
.sgs-group-header input[type="checkbox"] {
    flex-shrink: 0;
    position: relative;
    top: -0.07em;
    /* A little breathing room to the right of the checkbox circle before the type pill / name,
       so the row isn't cramped (pairs with the roomier legend swatch spacing). */
    margin-right: 2px;
}
.sgs-layer-row:hover {
    background: none;
}

.sgs-layer-row--loading {
    opacity: 0.5;
}
.sgs-layer-row--loading .sgs-layer-name {
    font-style: italic;
}

.sgs-layer-spinner {
    display: inline-block;
    width: 12px;
    height: 12px;
    border: 2px solid var(--sgs-border);
    border-top-color: var(--sgs-accent);
    border-radius: 50%;
    animation: sgs-spin 0.8s linear infinite;
    flex-shrink: 0;
}
@keyframes sgs-spin {
    to { transform: rotate(360deg); }
}

.sgs-layer-name {
    font-size: var(--sgs-font-base);
    font-weight: 400;
    color: var(--sgs-text-off);
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    cursor: pointer;
    line-height: 18px;
    margin-top: -3px;
    transition: color var(--sgs-transition);
}
/* Layer name brightens when on */
.sgs-layer-wrap[data-on] .sgs-layer-name {
    color: var(--sgs-text);
}
/* Children of a turned-off group stay faded */
.sgs-group-wrap:not([data-on]) .sgs-layer-name {
    color: var(--sgs-text-off);
}
/* Group name fades when off */
.sgs-group-wrap:not([data-on]) .sgs-group-name {
    color: var(--sgs-text-off);
}
/* Chevrons follow: bright when on, muted when off */
.sgs-layer-wrap[data-on] .sgs-icon-btn:not(.sgs-icon-btn--lit) {
    color: var(--sgs-text);
}
.sgs-group-wrap:not([data-on]) .sgs-icon-btn:not(.sgs-icon-btn--lit) {
    color: var(--sgs-text-off);
}
.sgs-group-wrap[data-on] .sgs-group-triangle {
    color: var(--sgs-text);
}

/* Row action buttons (labels toggle, savant, gear, trash) */
.sgs-row-actions {
    display: flex;
    align-items: center;
    gap: 0;
    flex-shrink: 0;
    min-width: calc(var(--sgs-gear-w) + var(--sgs-trash-w));
    justify-content: flex-end; /* visible icons always float to the right edge */
}
.sgs-row-actions--trash-only {
    min-width: var(--sgs-trash-w);
}

/* Spacers hold compose-mode icon space when edit is off; vanish when it's on */
.sgs-drag-spacer,
.sgs-trash-spacer {
    flex-shrink: 0;
    pointer-events: none;
}
.sgs-drag-spacer  { width: var(--sgs-drag-w); }
.sgs-trash-spacer { width: var(--sgs-trash-w); }
.sgs-edit-active .sgs-drag-spacer,
.sgs-edit-active .sgs-trash-spacer { display: none; }

/* Distributed drag gap — pre-reserves drag-handle width as breathing room before the layer name.
   Split 4-ways: left of chevron, chevron→cb, cb→pill, pill→name. Collapses atomically (no
   transition) when edit mode activates so the drag handle fills the exact same space in one
   frame — zero net displacement for the layer name or group name. */
.sgs-layer-row > .sgs-icon-btn:first-child,
.sgs-group-header > .sgs-group-triangle {
    margin-left: var(--sgs-drag-gap-1);
    margin-right: var(--sgs-drag-gap-2);
}
.sgs-layer-row > input[type="checkbox"],
.sgs-group-header > input[type="checkbox"] {
    margin-right: var(--sgs-drag-gap-3);
}
.sgs-layer-row > .sgs-pill-slot,
.sgs-group-header > .sgs-group-icon {
    margin-right: var(--sgs-drag-gap-4);
}
.sgs-edit-active .sgs-layer-row > .sgs-icon-btn:first-child,
.sgs-edit-active .sgs-group-header > .sgs-group-triangle {
    margin-left: 0;
    margin-right: 0;
}
.sgs-edit-active .sgs-layer-row > input[type="checkbox"],
.sgs-edit-active .sgs-layer-row > .sgs-pill-slot,
.sgs-edit-active .sgs-group-header > input[type="checkbox"],
.sgs-edit-active .sgs-group-header > .sgs-group-icon {
    margin-right: 0;
}
/* Sublayers can't be reordered — keep their distributed gap intact in edit mode */
.sgs-edit-active .sgs-layer-wrap--sublayer .sgs-layer-row > .sgs-icon-btn:first-child {
    margin-left: var(--sgs-drag-gap-1);
    margin-right: var(--sgs-drag-gap-2);
}
.sgs-edit-active .sgs-layer-wrap--sublayer .sgs-layer-row > input[type="checkbox"] {
    margin-right: var(--sgs-drag-gap-3);
}
.sgs-edit-active .sgs-layer-wrap--sublayer .sgs-layer-row > .sgs-pill-slot {
    margin-right: var(--sgs-drag-gap-4);
}

.sgs-group-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 16px;
    flex-shrink: 0;
    color: var(--sgs-text-off);
    transition: color var(--sgs-transition);
}
.sgs-group-wrap[data-on] .sgs-group-icon {
    color: var(--sgs-text);
}
.sgs-group-icon svg {
    width: 12px;
    height: 12px;
    stroke-width: 1;
}

.sgs-pill-slot {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    flex-shrink: 0;
    position: relative;
    top: -0.05em;
}

.sgs-source-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;
    font-weight: 600;
    line-height: 1;
    padding: 2px 2px;
    border-radius: 3px;
    opacity: 0.8;
    transition: color var(--sgs-transition), background var(--sgs-transition);
    white-space: nowrap;
    letter-spacing: 0.02em;
}
/* Hydrated fundamentals: the pill glows subtly + becomes a click target for the
   report. Metadata affordance (like layer type) — no map glow, no separate dot. */
.sgs-source-pill[data-savant] {
    opacity: 1;
    cursor: pointer;
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--sgs-savant-start, #8b5cf6) 45%, transparent),
                0 0 6px color-mix(in srgb, var(--sgs-savant-glow, rgba(139,92,246,0.35)) 90%, transparent);
}
.sgs-source-pill[data-savant="ai"] {
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--sgs-savant-start, #8b5cf6) 65%, transparent),
                0 0 9px color-mix(in srgb, var(--sgs-savant-glow, rgba(139,92,246,0.5)) 100%, transparent);
}
.sgs-source-pill[data-savant]:hover {
    filter: brightness(1.06);
}
.sgs-source-pill-spacer {
    display: inline-block;
    width: 32px;
    flex-shrink: 0;
}
.sgs-source-pill--vtl  { color: #7c3aed; background: #ede9fe; }
.sgs-source-pill--wms  { color: #0d9488; background: #ccfbf1; }
.sgs-source-pill--ms   { color: #d97706; background: #fef3c7; }
.sgs-source-pill--fs   { color: #2563eb; background: #dbeafe; }
.sgs-source-pill--json { color: #16a34a; background: #dcfce7; }
.sgs-source-pill--xyz  { color: #b91c1c; background: #fee2e2; }
.sgs-source-pill--csv  { color: #16a34a; background: #dcfce7; }
.sgs-source-pill--pqt  { color: #7c3aed; background: #f3e8ff; }
.sgs-source-pill--other { color: #475569; background: #e2e8f0; }

[data-theme="dark"] .sgs-source-pill--vtl  { color: #c4b5fd; background: #2e1065; }
[data-theme="dark"] .sgs-source-pill--wms  { color: #5eead4; background: #042f2e; }
[data-theme="dark"] .sgs-source-pill--ms   { color: #fcd34d; background: #451a03; }
[data-theme="dark"] .sgs-source-pill--fs   { color: #93c5fd; background: #172554; }
[data-theme="dark"] .sgs-source-pill--json { color: #86efac; background: #052e16; }
[data-theme="dark"] .sgs-source-pill--xyz  { color: #fca5a5; background: #450a0a; }
[data-theme="dark"] .sgs-source-pill--csv  { color: #86efac; background: #052e16; }
[data-theme="dark"] .sgs-source-pill--pqt  { color: #d8b4fe; background: #3b0764; }
[data-theme="dark"] .sgs-source-pill--other { color: #cbd5e1; background: #1e293b; }

/* Pill grays when layer is off; real color only when on */
.sgs-layer-wrap:not([data-on]) .sgs-source-pill,
.sgs-group-wrap:not([data-on]) .sgs-source-pill {
    color: var(--sgs-text-off);
    background: var(--sgs-surface-2);
}

.sgs-icon-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text-off);
    transition: background var(--sgs-transition), color var(--sgs-transition);
    flex-shrink: 0;
    cursor: pointer;
    position: relative;
    top: -0.06em;
}
.sgs-icon-btn svg {
    transition: transform var(--sgs-transition);
}
.sgs-icon-btn--open svg {
    transform: rotate(90deg);
}
.sgs-icon-btn:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}
.sgs-icon-btn--active {
    color: var(--sgs-text-muted);
    opacity: 0.5;
}

/* Badges: Q and Q! on layer / group rows */
.sgs-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    border-radius: var(--sgs-radius-pill);
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    line-height: 1;
    background: var(--sgs-accent);
    color: #ffffff;
    flex-shrink: 0;
    margin-top: 2px;
}
.sgs-badge--inverted {
    background: transparent;
    color: var(--sgs-accent);
    border: 1px solid var(--sgs-accent);
}

/* Checkboxes */
input[type="checkbox"] {
    flex-shrink: 0;
    cursor: pointer;
    accent-color: var(--sgs-accent);
    width: 13px;
    height: 13px;
    margin: 0;
    margin-top: 2px;
}

/* ── Checkbox style variants (applied via class on .sgs-panel) ──── */

/* Default/square variant — only when no other style is active */
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-layer-row input[type="checkbox"],
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-group-header input[type="checkbox"],
html:not([data-checkbox-style]) .sgs-settings-check input[type="checkbox"],
html[data-checkbox-style="default"] .sgs-layer-row input[type="checkbox"],
html[data-checkbox-style="default"] .sgs-group-header input[type="checkbox"],
html[data-checkbox-style="default"] .sgs-settings-check input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 12px;
    height: 12px;
    border-radius: 2px;
    border: none;
    box-shadow: inset 0 0 0 1.2px var(--sgs-text-off);
    background: rgba(128,128,128,0.08);
    position: relative;
    transition: box-shadow var(--sgs-transition), background var(--sgs-transition);
}
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-layer-row input[type="checkbox"]:checked,
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-group-header input[type="checkbox"]:checked,
html:not([data-checkbox-style]) .sgs-settings-check input[type="checkbox"]:checked,
html[data-checkbox-style="default"] .sgs-layer-row input[type="checkbox"]:checked,
html[data-checkbox-style="default"] .sgs-group-header input[type="checkbox"]:checked,
html[data-checkbox-style="default"] .sgs-settings-check input[type="checkbox"]:checked {
    background: var(--sgs-accent);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.25), inset 0 -1px 0 rgba(0,0,0,0.1);
}
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-layer-row input[type="checkbox"]:checked::after,
html:not([data-checkbox-style]) .sgs-panel:not([class*="sgs-check--"]) .sgs-group-header input[type="checkbox"]:checked::after,
html:not([data-checkbox-style]) .sgs-settings-check input[type="checkbox"]:checked::after,
html[data-checkbox-style="default"] .sgs-layer-row input[type="checkbox"]:checked::after,
html[data-checkbox-style="default"] .sgs-group-header input[type="checkbox"]:checked::after,
html[data-checkbox-style="default"] .sgs-settings-check input[type="checkbox"]:checked::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 3.5px;
    height: 6px;
    border: solid #fff;
    border-width: 0 1.2px 1.2px 0;
    /* A rotated checkmark's optical centre sits left of its geometric centre, so the glyph read
       as shifted left. Pull it back toward centre on X (and settle it vertically). */
    transform: translate(-38%, -60%) rotate(45deg);
}

/* Eye icon variant (class-based for panel, attribute-based for early paint) */
.sgs-check--eye input[type="checkbox"],
html[data-checkbox-style="eye"] input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 14px;
    height: 14px;
    margin-top: 0;
    position: relative;
    border: none;
    background: none;
}
.sgs-check--eye input[type="checkbox"]::before,
html[data-checkbox-style="eye"] input[type="checkbox"]::before {
    content: '';
    display: block;
    width: 14px;
    height: 14px;
    background: currentColor;
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E") center/contain no-repeat;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'/%3E%3Ccircle cx='12' cy='12' r='3'/%3E%3C/svg%3E") center/contain no-repeat;
    color: var(--sgs-accent);
    opacity: 1;
    transition: opacity var(--sgs-transition);
}
.sgs-check--eye input[type="checkbox"]:not(:checked)::before,
html[data-checkbox-style="eye"] input[type="checkbox"]:not(:checked)::before {
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24'/%3E%3Cline x1='4' y1='4' x2='20' y2='20' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
    -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24'/%3E%3Cline x1='4' y1='4' x2='20' y2='20' stroke-linecap='round'/%3E%3C/svg%3E") center/contain no-repeat;
    color: var(--sgs-text-muted);
    opacity: 0.5;
}

/* Toggle/pill variant (class-based for panel, attribute-based for early paint) */
.sgs-check--toggle input[type="checkbox"],
html[data-checkbox-style="toggle"] input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    width: 22px;
    height: 12px;
    border-radius: var(--sgs-radius-pill);
    background: var(--sgs-border);
    position: relative;
    transition: background var(--sgs-transition);
}
.sgs-check--toggle input[type="checkbox"]::before,
html[data-checkbox-style="toggle"] input[type="checkbox"]::before {
    content: '';
    position: absolute;
    top: 2px;
    left: 2px;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #fff;
    transition: transform var(--sgs-transition);
}
.sgs-check--toggle input[type="checkbox"]:checked,
html[data-checkbox-style="toggle"] input[type="checkbox"]:checked {
    background: var(--sgs-accent);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.2), inset 0 -1px 0 rgba(0,0,0,0.1);
}
.sgs-check--toggle input[type="checkbox"]:checked::before,
html[data-checkbox-style="toggle"] input[type="checkbox"]:checked::before {
    transform: translateX(10px);
}

/* Circle variant (class-based for panel, attribute-based for early paint) */
.sgs-check--circle input[type="checkbox"],
html[data-checkbox-style="circle"] input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    /* Even integer size so border-radius:50% rasterizes to a true circle even after the
       layer-list scale transform (an odd/too-small box made the corners read squarish). */
    width: 12px;
    height: 12px;
    margin-top: 1px;
    border-radius: 50%;
    border: none;
    box-shadow: inset 0 0 0 1.2px var(--sgs-text-off);
    background: transparent;
    transition: box-shadow var(--sgs-transition), background var(--sgs-transition);
}
.sgs-check--circle input[type="checkbox"]:checked,
html[data-checkbox-style="circle"] input[type="checkbox"]:checked {
    background:
        radial-gradient(circle at 35% 30%, rgba(255,255,255,0.28) 0%, rgba(255,255,255,0) 65%),
        linear-gradient(150deg, var(--sgs-accent-light) 0%, var(--sgs-accent) 100%);
    box-shadow: none;
}

/* Shrink every layer on/off toggle (square/eye/pill/circle) uniformly, but only ~10% (last
   sprint's 0.78 went too far and, at that fractional pixel size, made the CIRCLE variant's
   border-radius rasterize squarish). 0.9 walks ~2/3 of the way back toward full size while
   staying on the smaller side. Scaling the input keeps each variant's exact look and internal
   proportions; it does not change the reserved slot, so row layout is unaffected. */
.sgs-layer-row input[type="checkbox"],
.sgs-group-header input[type="checkbox"] {
    transform: scale(0.9);
}

/* Filter VALUE checkboxes are subordinate to the layer's main toggle (n12): the
   same variant look (square/eye/pill/circle all scale with their proportions
   intact), visibly smaller, and optically centered on their label line. */
.sgs-filter-body label input[type="checkbox"] {
    transform: scale(0.75);
    transform-origin: center;
    margin-top: 0;
    align-self: center;
}

/* Error row */
.sgs-layer-error {
    font-size: var(--sgs-font-sm);
    color: var(--sgs-danger);
    padding: 2px 0 2px var(--sgs-gap-xl);
}

/* Loading placeholder pulse */
.sgs-layer-placeholder {
    height: 22px;
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    animation: sgs-pulse 1.4s ease-in-out infinite;
    margin: 2px 0;
}
@keyframes sgs-pulse {
    0%, 100% { opacity: 1; }
    50%       { opacity: 0.45; }
}

/* ============================================================
   6. SYMBOLOGY LEGEND
   ============================================================ */

.sgs-legend {
    padding: 1px 0 var(--sgs-gap-sm) 18px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.sgs-sym-row {
    display: flex;
    align-items: center;
    /* Breathing room on either side of the swatch line: a touch of left pad before it and a
       wider gap after it, so the symbol patch isn't crammed against the label. */
    gap: 8px;
    padding-left: 2px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    min-height: 16px;
    padding: 1px 0;
}
/* On an active (highlighted, lifted) card the legend text steps up to full contrast — the
   layer is live, so its symbology reads clearly. Off cards keep the muted, quieter treatment. */
.sgs-layer-wrap[data-on] .sgs-sym-row {
    color: var(--sgs-text);
}

.sgs-swatch {
    flex-shrink: 0;
    border-radius: 2px;
}
.sgs-swatch--fill {
    display: inline-block;
    width: 14px;
    height: 14px;
    min-width: 14px;
    border-radius: 2px;
    background: var(--sgs-swatch-color, #ccc);
    border: 2px solid var(--sgs-swatch-border, rgba(0,0,0,0.15));
}
.sgs-swatch--line {
    display: inline-block;
    width: 22px;
    height: 3px;
    min-width: 22px;
    border-radius: 1px;
    background: var(--sgs-swatch-color, #888);
}
.sgs-swatch--line.sgs-swatch--dashed {
    background: repeating-linear-gradient(
        90deg,
        var(--sgs-swatch-color, #888) 0,
        var(--sgs-swatch-color, #888) 4px,
        transparent 4px,
        transparent 8px
    );
}
.sgs-swatch--symbol {
    display: inline-block;
    width: 14px;
    height: 14px;
    min-width: 14px;
    border-radius: 50%;
    background: var(--sgs-swatch-color, #888);
}
.sgs-swatch--circle {
    display: inline-block;
    width: 10px;
    height: 10px;
    min-width: 10px;
    border-radius: 50%;
    background: var(--sgs-swatch-color, #888);
}
[data-theme="dark"] .sgs-swatch--fill {
    border-color: var(--sgs-swatch-border, rgba(255,255,255,0.10));
}
[data-theme="dark"] img.sgs-swatch,
[data-theme="dark"] .sgs-swatch-canvas {
    filter: drop-shadow(0 0 1px rgba(255,255,255,0.25));
}

.sgs-swatch-canvas {
    flex-shrink: 0;
    border-radius: 2px;
    width: 14px;
    height: 14px;
    min-width: 14px;
}


/* ============================================================
   MEASURE TOOL
   ============================================================ */

.sgs-measure-btn {
    font-size: 15px;
    line-height: 29px;
    width: 29px;
    height: 29px;
    display: block;
    text-align: center;
    cursor: pointer;
}
.sgs-measure-btn.sgs-measure-active {
    background-color: #ffe0c0;
}
[data-theme="dark"] .sgs-measure-btn.sgs-measure-active {
    background-color: #7a3800;
}

.sgs-measure-label {
    position: absolute;
    z-index: 10;
    pointer-events: auto;
    border: 1px solid #e05800;  /* intentional measure-tool orange */
    border-radius: 4px;
    padding: 5px 24px 5px 8px;
    font: 11px/1.6 Arial, sans-serif;
    white-space: nowrap;
    box-shadow: 0 1px 4px rgba(0,0,0,0.2);
    background: var(--sgs-bg);
    color: var(--sgs-text);
}
[data-theme="dark"] .sgs-measure-label {
    border-color: #ff8833;  /* intentional measure-tool orange, brighter in dark mode */
}

.sgs-measure-close {
    position: absolute;
    top: 3px;
    right: 4px;
    background: none;
    border: none;
    cursor: pointer;
    color: #e05800;
    font: bold 14px Arial;
    line-height: 1;
    padding: 0;
}


/* ============================================================
   6b. SUBLAYER TREE (ArcGIS MapServer)
   ============================================================ */

.sgs-sublayer-check {
    width: 13px;
    height: 13px;
    margin: 0;
    cursor: pointer;
    accent-color: var(--sgs-accent);
}

.sgs-sublayer-swatch {
    flex-shrink: 0;
    border-radius: 2px;
}

.sgs-sublayer-group {
    cursor: pointer;
    user-select: none;
}

.sgs-sublayer-arrow {
    font-size: 10px;
    width: 12px;
    text-align: center;
    color: var(--sgs-text-muted);
    cursor: pointer;
}

.sgs-sublayer-group-name {
    font-weight: 500;
    color: var(--sgs-text);
}

/* nested children container */
/*.sgs-sublayer-children { 
}*/


/* ============================================================
   7. FILTER PANEL
   ============================================================ */

.sgs-filter-body {
    padding: 2px var(--sgs-gap-sm) var(--sgs-gap-sm);
}

.sgs-filter-section {
    border: 1px solid rgba(0,0,0,0.07);
    border-radius: 5px;
    margin-bottom: 2px;
    overflow: hidden;
    background: var(--sgs-surface);
    transition: border-color var(--sgs-transition);
}
.sgs-filter-section:last-child {
    margin-bottom: 0;
}
[data-theme="dark"] .sgs-filter-section {
    border-color: rgba(255,255,255,0.07);
}

.sgs-filter-section-header {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 3px var(--sgs-gap-sm) 3px 4px;
    background: var(--sgs-surface);
    cursor: pointer;
    user-select: none;
    font-size: var(--sgs-font-xs);
    font-weight: 500;
    color: var(--sgs-text);
    transition: background var(--sgs-transition);
}
.sgs-filter-section-header:hover {
    background: var(--sgs-surface-2);
}

/* Chevron for filter sections (rotates on expand) */
.sgs-filter-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 12px;
    height: 12px;
    flex-shrink: 0;
    color: var(--sgs-text-micro);
    transition: transform var(--sgs-transition);
    transform: rotate(-90deg);
}
.sgs-filter-chevron--open {
    transform: rotate(0deg);
}

/* ── Shared field-row vocabulary (issue #20) ─────────────────────────────────
   ONE type badge + field name family, used by the compose fields editor, the
   filter panel's field sections, AND the popup's type column. Was three
   near-identical CSS copies; the color scale now lives exactly once. */
.sgs-field-badge {
    display: inline-block;
    font-size: 9px;
    font-weight: 400;
    font-family: monospace;
    min-width: 20px;
    text-align: center;
    padding: 1px 3px;
    border-radius: var(--sgs-radius-sm);
    background: rgba(0,0,0,0.04);
    color: var(--sgs-text-micro);
    user-select: none;
    flex-shrink: 0;
    line-height: 12px;
    /* Legible, not decorative: the type colors are fixed hexes shared by both
       themes, so opacity is the only dimmer — keep it near-full (n6). */
    opacity: 0.95;
}
[data-theme="dark"] .sgs-field-badge {
    background: rgba(255,255,255,0.05);
}
.sgs-field-badge[data-type="string"] { color: #c9a227; }
.sgs-field-badge[data-type="integer"] { color: #4caf50; }
.sgs-field-badge[data-type="float"] { color: #5c9bd4; }
.sgs-field-badge[data-type="datetime"] { color: #ab7bd4; }
.sgs-field-badge[data-type="boolean"] { color: #e08050; }
.sgs-field-badge[data-type="null"] { color: var(--sgs-text-micro); }

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

/* Surface-specific spacing rides on the surface, not the shared family. */
.sgs-edit-popover-field .sgs-field-badge { margin-left: 6px; opacity: 0.7; }
.sgs-edit-popover-field .sgs-field-name { margin-left: 5px; }
.sgs-popup-type-col .sgs-field-badge { vertical-align: middle; cursor: default; }

.sgs-filter-section-count {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
    flex-shrink: 0;
}

.sgs-filter-section-values {
    padding: 2px var(--sgs-gap-sm);
    display: flex;
    flex-direction: column;
    gap: 1px;
    max-height: 200px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
}

.sgs-filter-search {
    width: 100%;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    border: none;
    border-bottom: 1px solid var(--sgs-border-light);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    font-size: var(--sgs-font-sm);
    outline: none;
    transition: background var(--sgs-transition);
}
.sgs-filter-search::placeholder {
    color: var(--sgs-text-micro);
}
.sgs-filter-search:focus {
    border-bottom-color: var(--sgs-accent);
}

.sgs-filter-value {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 2px var(--sgs-gap-xs);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    user-select: none;
    transition: background var(--sgs-transition);
}
/* Clearly smaller than the layer row's on/off checkbox, so a value toggle can't be
   mistaken for the layer toggle (notebear 2026-07-07 n10) */
.sgs-filter-value input[type="checkbox"] {
    width: 10px;
    height: 10px;
    margin-top: 1px;
}
.sgs-filter-value:hover {
    background: var(--sgs-surface);
}

.sgs-filter-value-label {
    flex: 1;
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sgs-filter-value-count {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
    flex-shrink: 0;
    font-variant-numeric: tabular-nums;
}

.sgs-filter-disabled {
    opacity: 0.5;
    pointer-events: none;
}

/* Unique-value discovery list (n27, issue #21): the windowed value catalog
   under a searchable field's search box. Rows reuse .sgs-filter-value. */
.sgs-filter-discoverlist {
    max-height: 210px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
    padding-top: 2px;
}
.sgs-filter-discover-empty {
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
}
.sgs-filter-discover-more {
    display: block;
    width: 100%;
    padding: 3px var(--sgs-gap-sm);
    margin-top: 2px;
    border: none;
    background: none;
    color: var(--sgs-accent);
    font-size: var(--sgs-font-xs);
    text-align: left;
    cursor: pointer;
    border-radius: var(--sgs-radius-sm);
}
.sgs-filter-discover-more:hover {
    background: var(--sgs-surface);
}

/* Zoom-to-features link */
.sgs-zoom-link {
    display: inline-flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-accent);
    cursor: pointer;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    text-decoration: none;
    transition: color var(--sgs-transition);
}
.sgs-zoom-link:hover {
    color: var(--sgs-accent-hover);
}


/* ============================================================
   8. QUERY PANEL
   ============================================================ */

.sgs-query-panel {
    position: fixed;
    z-index: 420;
    background: var(--sgs-bg);
    border-radius: 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.28);
    width: fit-content;
    min-width: 260px;
    max-width: calc(100vw - 32px);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: var(--sgs-text);
    font-size: 12px;
    cursor: grab;
    user-select: none;
    transition: background var(--sgs-transition);
}

/* Neutral header like every other floating surface (dock, popup) — the solid
   accent bar was the app's one loud blue div (n16 2026-07-12); accent stays
   reserved for state, and for Geogs' AI chrome. */
.sgs-query-titlebar {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    background: var(--sgs-layer-canvas);
    border-bottom: 1px solid var(--sgs-border-light);
    border-radius: 8px 8px 0 0;
    color: var(--sgs-text);
    cursor: move;
    user-select: none;
    font-weight: 600;
    font-size: 13px;
}

.sgs-query-titlebar-icon {
    font-size: 14px;
    flex-shrink: 0;
}

/* Dark mode: query panel interior overrides */
[data-theme="dark"] .sgs-query-surface {
    background: var(--sgs-surface);
    border-color: var(--sgs-border);
}
[data-theme="dark"] .sgs-query-surface .sgs-query-surface {
    background: var(--sgs-bg);
    border-color: var(--sgs-border);
}
[data-theme="dark"] .sgs-query-search,
[data-theme="dark"] .sgs-query-select,
[data-theme="dark"] .sgs-query-where,
[data-theme="dark"] .sgs-query-radio-label select {
    background: var(--sgs-bg);
    color: var(--sgs-text);
    border-color: var(--sgs-border);
}
[data-theme="dark"] .sgs-query-footer {
    border-top-color: var(--sgs-border);
}

.sgs-query-titlebar-text {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 600;
    font-size: 13px;
}

.sgs-query-close {
    background: none;
    border: none;
    color: var(--sgs-text-muted);
    font-size: 18px;
    cursor: pointer;
    padding: 0;
    line-height: 1;
    flex-shrink: 0;
}
.sgs-query-close:hover {
    color: var(--sgs-text);
}

.sgs-query-body {
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
    overflow-y: auto;
    max-height: 80vh;
}

/* Section label — "Fields", "Operator", "Values", "WHERE", "Apply to:" */
.sgs-query-section-label {
    font-weight: 600;
    font-size: 11px;
    color: var(--sgs-text-muted);
    margin-bottom: 3px;
}

/* Scope / field-value surface panels */
.sgs-query-surface {
    border: 1px solid var(--sgs-border-light);
    border-radius: 5px;
    padding: 7px 9px;
    background: var(--sgs-surface);
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-xs);
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
}

/* Radio labels in scope row */
.sgs-query-radio-label {
    display: flex;
    align-items: center;
    gap: 3px;
    cursor: pointer;
    user-select: none;
    font-size: 12px;
}

/* Field / value list items */
.sgs-query-item {
    padding: 3px 6px;
    border-radius: var(--sgs-radius-sm);
    font-size: 12px;
    color: var(--sgs-text);
    cursor: pointer;
    user-select: none;
    transition: background var(--sgs-transition);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    flex-shrink: 0;
    min-height: 20px;
    line-height: 1.2;
}
.sgs-query-item:hover {
    background: var(--sgs-surface-2);
}
.sgs-query-item.is-selected {
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-weight: 500;
}

/* Inner list containers (fields list, values list) — white bg inside surface */
.sgs-query-surface .sgs-query-surface {
    background: var(--sgs-bg);
    border-color: var(--sgs-border);
    border-radius: 3px;
    padding: 0;
    max-height: 160px;
    overflow-y: auto;
}

/* Search input inside query columns */
.sgs-query-search {
    font-size: 11px;
    padding: 3px 5px;
    border: 1px solid var(--sgs-border);
    border-radius: 3px;
    width: 100%;
    box-sizing: border-box;
    background: var(--sgs-bg);
    color: var(--sgs-text);
    outline: none;
    transition: border-color var(--sgs-transition);
}
.sgs-query-search:focus {
    border-color: var(--sgs-accent);
}
.sgs-query-search::placeholder {
    color: var(--sgs-text-micro);
}

/* Operator select */
.sgs-query-select {
    font-size: 11px;
    padding: 3px 4px;
    border: 1px solid var(--sgs-border);
    border-radius: 3px;
    background: var(--sgs-bg);
    color: var(--sgs-text);
    outline: none;
}

/* Group select inside scope row */
.sgs-query-radio-label select {
    font-size: 11px;
    padding: 2px 4px;
    border: 1px solid var(--sgs-border);
    border-radius: 3px;
    max-width: 200px;
    background: var(--sgs-bg);
    color: var(--sgs-text);
}

/* WHERE textarea */
.sgs-query-where {
    width: 100%;
    padding: 6px 8px;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: 4px;
    color: var(--sgs-text);
    font-family: monospace;
    font-size: 12px;
    resize: vertical;
    min-height: 60px;
    max-height: 160px;
    outline: none;
    box-sizing: border-box;
    transition: border-color var(--sgs-transition);
}
.sgs-query-where:focus {
    border-color: var(--sgs-accent);
}

/* Hint text (muted, non-error) */
.sgs-query-hint {
    font-size: 11px;
    color: var(--sgs-text-muted);
}

/* Error text */
.sgs-query-error {
    font-size: 11px;
    color: var(--sgs-danger);
}

.sgs-query-footer {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 12px;
    border-top: 1px solid var(--sgs-border-light);
    flex-wrap: wrap;
}

/* Buttons */
.sgs-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--sgs-gap-xs);
    padding: 5px var(--sgs-gap-md);
    border-radius: var(--sgs-radius-md);
    font-size: var(--sgs-font-sm);
    font-weight: 500;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background var(--sgs-transition), color var(--sgs-transition),
                border-color var(--sgs-transition), opacity var(--sgs-transition);
    user-select: none;
    white-space: nowrap;
}

.sgs-btn--primary {
    background: var(--sgs-accent);
    color: #ffffff;
    border-color: var(--sgs-accent);
}
.sgs-btn--primary:hover {
    background: var(--sgs-accent-hover);
    border-color: var(--sgs-accent-hover);
}

.sgs-btn--ghost {
    background: var(--sgs-surface);
    color: var(--sgs-text);
    border-color: var(--sgs-border);
}
.sgs-btn--ghost:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}

/* Outlined accent button — "Add to Expression" style */
.sgs-btn--outline {
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    border-color: var(--sgs-accent);
    font-weight: 600;
}
.sgs-btn--outline:hover {
    background: color-mix(in srgb, var(--sgs-accent-subtle), var(--sgs-accent) 15%);
}

/* Danger outline button — "Clear" style */
.sgs-btn--danger {
    background: var(--sgs-danger-subtle);
    color: var(--sgs-danger);
    border-color: var(--sgs-danger);
}
.sgs-btn--danger:hover {
    background: color-mix(in srgb, var(--sgs-danger-subtle), var(--sgs-danger) 15%);
}

/* Labels toggle button — uses sgs-icon-btn base; lit = labels visible */
.sgs-icon-btn--lit {
    color: var(--sgs-accent);
}
/* Dark mode: the lit blue is a touch brighter so the "T" reads clearly on the dark card. */
[data-theme="dark"] .sgs-icon-btn--lit {
    color: var(--sgs-accent-hover);
}
/* Label button grays when layer is off or group-suppressed */
.sgs-layer-wrap:not([data-on]) .sgs-icon-btn--lit,
.sgs-group-wrap:not([data-on]) .sgs-icon-btn--lit {
    color: var(--sgs-text-off);
}
/* …and when off it's INERT: no white hover/press feedback, since toggling labels on a hidden
   layer does nothing. It stays its muted grey until the layer is turned on. */
.sgs-layer-wrap:not([data-on]) .sgs-icon-btn--lit:hover,
.sgs-group-wrap:not([data-on]) .sgs-icon-btn--lit:hover,
.sgs-layer-wrap:not([data-on]) .sgs-icon-btn--lit:active,
.sgs-group-wrap:not([data-on]) .sgs-icon-btn--lit:active {
    background: none;
    color: var(--sgs-text-off);
    cursor: default;
}

.sgs-btn:disabled {
    opacity: 0.4;
    pointer-events: none;
}


/* ============================================================
   9. POPUP
   ============================================================ */

/* SVG overlay for anchor lines — sits above the map, passes through pointer events */
.sgs-popup-svg-overlay {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 401;
}

.sgs-popup {
    position: fixed;
    z-index: 410;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow-lg);
    min-width: 160px;
    max-width: 380px;
    overflow: hidden;
    color: var(--sgs-text);
    display: flex;
    flex-direction: column;
    cursor: grab;
    resize: vertical;
    transition: background var(--sgs-transition), border-color var(--sgs-transition);
}

.sgs-popup [data-no-drag] {
    cursor: text;
    user-select: text;
}

/* Scrollable body inside popup (table grows here, title bar stays fixed) */
.sgs-popup-body {
    overflow-y: auto;
    flex: 1;
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
}

.sgs-popup-titlebar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    background: var(--sgs-surface);
    border-bottom: 1px solid var(--sgs-border-light);
    cursor: move;
    user-select: none;
    gap: var(--sgs-gap-sm);
}

.sgs-popup-title {
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text-muted);
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}

.sgs-popup-title-swatch {
    flex-shrink: 0;
    width: 14px !important;
    height: 14px !important;
    min-width: 14px !important;
}
.sgs-popup-title-swatch.sgs-swatch--line {
    width: 18px !important;
    height: 3px !important;
    min-width: 18px !important;
    align-self: center;
}

.sgs-popup-query-btn {
    font-size: 11px;
    color: var(--sgs-text-muted);
    opacity: 0.6;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    flex-shrink: 0;
    cursor: pointer;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-popup-query-btn:hover {
    background: var(--sgs-surface-2);
    opacity: 1;
}

.sgs-popup-edit-btn {
    font-size: 11px;
    color: var(--sgs-text-muted);
    opacity: 0.6;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    flex-shrink: 0;
    cursor: pointer;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-popup-edit-btn:hover {
    background: var(--sgs-surface-2);
    opacity: 1;
}

/* Attribute-table launcher in the popup title bar — same treatment as the funnel (n15). */
.sgs-popup-table-btn {
    font-size: 11px;
    color: var(--sgs-text-muted);
    opacity: 0.6;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    flex-shrink: 0;
    cursor: pointer;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-popup-table-btn:hover {
    background: var(--sgs-surface-2);
    opacity: 1;
}

/* Source-type pill riding in the popup title bar (n14): same pill, popup-scale. */
.sgs-popup-titlebar .sgs-source-pill {
    flex-shrink: 0;
    align-self: center;
}

.sgs-popup-close {
    font-size: 14px;
    color: var(--sgs-text-muted);
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    flex-shrink: 0;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-popup-close:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}

.sgs-popup-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--sgs-font-sm);
}

.sgs-popup-table tr {
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-popup-table tr:last-child {
    border-bottom: none;
}

.sgs-popup-table th,
.sgs-popup-table td {
    padding: 6px var(--sgs-gap-sm);
    vertical-align: top;
    color: var(--sgs-text);
    word-break: break-word;
}

.sgs-popup-table th {
    font-weight: 600;
    color: var(--sgs-text-muted);
    background: var(--sgs-surface);
    white-space: nowrap;
    border-right: 1px solid var(--sgs-border-light);
    width: 1%;
    max-width: 140px;
    text-align: left;
}

/* Data type column in popup table */
.sgs-popup-type-col {
    padding: 6px 4px 6px var(--sgs-gap-sm);
    vertical-align: top;
    width: 1%;
    white-space: nowrap;
    border-right: 1px solid var(--sgs-border-light);
    background: var(--sgs-bg);
}

/* Popup's data-type column uses the shared .sgs-field-badge (issue #20). */

/* Anchor line from popup to feature point */
.sgs-anchor-line {
    stroke: var(--sgs-accent);
    stroke-width: 1.5;
    stroke-dasharray: 4 3;
    opacity: 0.6;
}

.sgs-anchor-dot {
    fill: var(--sgs-accent);
    opacity: 0.8;
}


/* ============================================================
   10. CONTROLS
   ============================================================ */

/* Collapse margins on hidden map controls so no gap remains */
.maplibregl-ctrl-top-right > *[style*="display: none"],
.maplibregl-ctrl-top-right > *[style*="display:none"] {
    margin: 0 !important;
}

/* One square size for every control button, one shared gap for the stack (n2).
   !important beats MapLibre's own 29px button rule and 10px ctrl margin regardless
   of bundle order (the classic "edits did nothing" trap in this section). */
.maplibregl-ctrl-group button {
    width: var(--sgs-ctrl-size) !important;
    height: var(--sgs-ctrl-size) !important;
}
.maplibregl-ctrl-top-right > .maplibregl-ctrl {
    margin: var(--sgs-gap-sm) var(--sgs-gap-sm) 0 0 !important;
}

/* The maplibre-gl-vector control is driven headlessly (vector-source.js): sleek's
   own layer list + popups are the UI, so its 29×29 toggle button stays hidden. */
.sgs-vector-control-hidden {
    display: none !important;
}

/* Dark mode toggle + app settings gear — sit in MapLibre control groups */
.sgs-dark-ctrl-wrap,
.sgs-settings-ctrl-wrap {
    width: var(--sgs-ctrl-size);
    height: var(--sgs-ctrl-size);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    user-select: none;
    font-size: 0; /* collapse any residual whitespace text nodes */
    /* Button owns the resting glyph colour (muted, not full-bright — the sun read too hot on
       --sgs-text); the icons inherit it, so the unified control-hover rule recolours them for
       free by setting `color` on the button. */
    color: var(--sgs-text-muted);
    transition: color var(--sgs-transition), background-color var(--sgs-transition);
}
.sgs-settings-ctrl-wrap svg {
    pointer-events: none;
    display: block;
    margin: auto;
    color: inherit;
    /* 15 optical (n2), scaled with the stack in Readable mode (n3). CSS wins
       over the SVG's 15px width/height attributes. */
    width: calc(15px * var(--sgs-ui-scale));
    height: calc(15px * var(--sgs-ui-scale));
}

/* ── Quick settings popover (n1) — the gear's small disclosure ──────────────────
   Theme / redshift / shortcut hints: the surface a shipped app exposes. */
.sgs-quick-settings {
    position: fixed;
    z-index: 900;
    width: 264px;
    max-height: calc(100vh - 80px);
    overflow: auto;
    padding: var(--sgs-gap-md);
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    box-shadow: 0 8px 28px rgba(0,0,0,0.18);
    color: var(--sgs-text);
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-sm);
}
.sgs-quick-settings-shortcuts {
    border-top: 1px solid var(--sgs-border-light);
    padding-top: var(--sgs-gap-sm);
    font-size: 11px;
}
/* Minimal sign-in disclosure (sign-in-popover.js) — shares the quick-settings
   shell; only its inner rows are its own. */
.sgs-signin-pop { width: 248px; }
.sgs-signin-pop-why {
    margin: 0;
    font-size: 12px;
    color: var(--sgs-text-muted);
}
.sgs-signin-pop-identity {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}
.sgs-signin-pop-logo { display: flex; width: 18px; }
.sgs-signin-pop-logo svg { width: 18px; height: 18px; }
.sgs-signin-pop-who { display: flex; flex-direction: column; min-width: 0; }
.sgs-signin-pop-name {
    font-size: 13px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-signin-pop-sub { font-size: 11px; color: var(--sgs-text-muted); }
.sgs-signin-pop-out { align-self: flex-start; }

/* "All settings" reads as its own quiet band: ruled above and below (n4),
   matching the rule that opens the shortcuts block. */
/* One divider ABOVE the link, none below (n7 2026-07-12): with the bottom line
   gone the link settles toward the panel's bottom edge. Shared by the quick
   settings and the sign-in popover. */
.sgs-quick-settings-link {
    align-self: stretch;
    text-align: right;
    border: none;
    border-top: 1px solid var(--sgs-border-light);
    background: none;
    padding: 6px 0 0;
    font-size: 11.5px;
    color: var(--sgs-accent);
    cursor: pointer;
}
.sgs-quick-settings-link:hover { text-decoration: underline; }
.sgs-dark-icon-moon,
.sgs-dark-icon-sun {
    pointer-events: none;
    display: block;
    margin: auto;
    color: inherit;
}
.sgs-dark-icon-sun { display: none; }

[data-theme="dark"] .sgs-dark-icon-moon { display: none; }
[data-theme="dark"] .sgs-dark-icon-sun { display: block; }

/* Dark mode: style the native control chrome explicitly. We deliberately do NOT
   invert anymore — invert ties the icon's dark-mode colour to its light-mode colour,
   making a clean shared colour impossible. Icons below are masked + coloured with
   var(--sgs-text-muted), so they track the theme like the person/moon icons. */
[data-theme="dark"] .maplibregl-ctrl-group:not(.sgs-custom-ctrl) {
    background: var(--sgs-bg);
    box-shadow: 0 0 0 1px var(--sgs-border);
}
[data-theme="dark"] .maplibregl-ctrl-group:not(.sgs-custom-ctrl) button + button {
    border-top-color: var(--sgs-border);
}
/* ── Unified control hover (see DESIGN TOKENS --sgs-ctrl-hover-*) ─────────────────
   Native group buttons (zoom ±, compass, geolocate): the PATCH. Theme-agnostic + !important
   so it overrides MapLibre's own light-mode hover (#f2f2f2) as well as our dark chrome. */
.maplibregl-ctrl-group:not(.sgs-custom-ctrl) button {
    transition: background-color var(--sgs-transition);
}
.maplibregl-ctrl-group:not(.sgs-custom-ctrl) button:not(:disabled):hover {
    background-color: var(--sgs-ctrl-hover-bg) !important;
}
/* Masked native ICONS (zoom/compass) recolour to the shared outline var on hover. !important
   because MapLibre's icon rule out-specifies us (the classic "edits did nothing" trap). */
.maplibregl-ctrl-zoom-in:not(:disabled):hover .maplibregl-ctrl-icon,
.maplibregl-ctrl-zoom-out:not(:disabled):hover .maplibregl-ctrl-icon,
.maplibregl-ctrl-compass:not(:disabled):hover .maplibregl-ctrl-icon {
    background-color: var(--sgs-ctrl-hover-outline) !important;
}
/* Geolocate now uses the same MASK + var mechanism as zoom/compass (its glyph is a thin
   outline wheel — see below), so hover just recolours the mask to the shared outline var.
   Guarded so the blue/red tracking states (-waiting/-active/-background/-*-error) are untouched. */
.maplibregl-ctrl-geolocate:not(.maplibregl-ctrl-geolocate-waiting):not(.maplibregl-ctrl-geolocate-active):not(.maplibregl-ctrl-geolocate-active-error):not(.maplibregl-ctrl-geolocate-background):not(.maplibregl-ctrl-geolocate-background-error):hover .maplibregl-ctrl-icon {
    background-color: var(--sgs-ctrl-hover-outline) !important;
}
/* Custom controls (measure tools, dark toggle, person): PATCH + glyph together. currentColor
   SVGs follow `color`. Excludes the amber measure-active state + the signed-in avatar ring. */
.sgs-custom-ctrl .sgs-measure-btn:not(.sgs-measure-active):not(:disabled):hover,
.sgs-custom-ctrl .sgs-dark-ctrl-wrap:not(:disabled):hover,
.sgs-custom-ctrl .sgs-settings-ctrl-wrap:not(:disabled):hover,
.sgs-custom-ctrl .sgs-auth-btn:not(.sgs-auth-btn--signed-in):not(:disabled):hover {
    background-color: var(--sgs-ctrl-hover-bg);
    color: var(--sgs-ctrl-hover-outline);
}

/* Sleek thin-line glyphs for the native controls (zoom +/−, compass).
   Implemented as a CSS MASK + `background-color: var(--sgs-text-muted)` — NOT a
   coloured background-image — so the colour is the *exact same var* the person/moon/
   measure icons use (DRY, theme-aware, identical in both modes). A data-URI can't
   reference a CSS var; a mask can.
   This works because these are THIN-STROKE glyphs: filling their alpha with a solid
   colour yields a hairline that reads at the same weight as the var-coloured strokes.
   The geolocate icon is masked too but kept in its OWN block below — it's a separate
   control with a multi-state machine (waiting/active/background/error) that swaps colour
   and the mask shape (hub in/out), so it can't share these single-state rules.
   !important on background-image/-color because MapLibre's icon rule
   (`.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon`, 0,3,1)
   out-specifies ours — that was the bug where earlier edits "did nothing". */
.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon,
.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon,
.maplibregl-ctrl-compass .maplibregl-ctrl-icon {
    background-image: none !important;
    background-color: var(--sgs-text-muted) !important;
    transition: background-color var(--sgs-transition);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    /* All control buttons share --sgs-ctrl-size now, so no cross-button nudge. */
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: var(--sgs-ctrl-glyph);
    mask-size: var(--sgs-ctrl-glyph);
}
/* Per-icon mask shapes. stroke-width 1.5 (≈1.4px effective at 22px) matches the
   person/moon weight; the stroke colour in the mask is irrelevant (only its alpha
   is used). */
.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cline x1='12' y1='6.5' x2='12' y2='17.5'/%3E%3Cline x1='6.5' y1='12' x2='17.5' y2='12'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cline x1='12' y1='6.5' x2='12' y2='17.5'/%3E%3Cline x1='6.5' y1='12' x2='17.5' y2='12'/%3E%3C/svg%3E");
}
.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cline x1='6.5' y1='12' x2='17.5' y2='12'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round'%3E%3Cline x1='6.5' y1='12' x2='17.5' y2='12'/%3E%3C/svg%3E");
}
.maplibregl-ctrl-compass .maplibregl-ctrl-icon {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4 L15.5 15.5 L12 13 L8.5 15.5 Z'/%3E%3C/svg%3E");
    mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4 L15.5 15.5 L12 13 L8.5 15.5 Z'/%3E%3C/svg%3E");
}
/* ── Geolocate icon — sleek outline "ship's wheel" (MASK + var) ──────────────────
   MapLibre ships the geolocate glyph as a FILLED locator background-image with the colour
   baked per state (grey resting / blue active / red error). We replace it with our own
   THIN-STROKE helm wheel used as a CSS MASK, painted via background-color — so it is the
   same DRY, theme-aware var the zoom/compass/person glyphs use (no baked hexes, no
   brightness-filter hover hack). The wheel is radially symmetric, so it spins seamlessly
   in the -waiting state (MapLibre's own `animation: maplibregl-spin` still applies to the
   masked element). The hub circle is the "bubble" in the centre.

   State machine (all driven by MapLibre's own classes, NO JS):
     resting                   ->  --sgs-text-muted, hub present
     -waiting  (acquiring)     ->  --sgs-accent + spin, hub present  [blue while the perm prompt is up]
     -active   (centred)       ->  --sgs-accent, hub present
     -background (panned away) ->  --sgs-accent, hub REMOVED         [the centre bubble disappears]
     -*-error                  ->  danger red (background-error also drops the hub)

   !important + selector order because MapLibre's own icon rule
   (`.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon`, spec 0,3,1)
   out-specifies a naive selector — the classic "edits did nothing" trap (see zoom/compass).
   Retune geometry in scripts/preview/geolocate-wheel.html (6 knobs, floating hub r=2,
   rim r=6, stroke 1.5) and regenerate both masks (hub-in / hub-out). */
.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon {
    background-image: none !important;
    background-color: var(--sgs-text-muted) !important;
    transition: background-color var(--sgs-transition);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    /* All buttons share --sgs-ctrl-size, so the mask centres cleanly; transform-origin is
       pinned to the same point so the -waiting spin rotates about the glyph centre. */
    -webkit-mask-position: center;
    mask-position: center;
    transform-origin: center;
    /* 18px, not the 16px glyph token: the wheel's ink (rim r=6, spokes to ~8.3
       of the 24 viewBox) carries more internal padding than its siblings — at
       16 it reads a step SMALLER than the person/gear (n2 2026-07-12). Rides
       --sgs-ui-scale so it grows with the stack in Readable mode (n3). */
    -webkit-mask-size: calc(18px * var(--sgs-ui-scale));
    mask-size: calc(18px * var(--sgs-ui-scale));
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='6'/%3E%3Cline x1='18.00' y1='12.00' x2='20.30' y2='12.00'/%3E%3Cline x1='15.00' y1='17.20' x2='16.15' y2='19.19'/%3E%3Cline x1='9.00' y1='17.20' x2='7.85' y2='19.19'/%3E%3Cline x1='6.00' y1='12.00' x2='3.70' y2='12.00'/%3E%3Cline x1='9.00' y1='6.80' x2='7.85' y2='4.81'/%3E%3Cline x1='15.00' y1='6.80' x2='16.15' y2='4.81'/%3E%3Ccircle cx='12' cy='12' r='2'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='6'/%3E%3Cline x1='18.00' y1='12.00' x2='20.30' y2='12.00'/%3E%3Cline x1='15.00' y1='17.20' x2='16.15' y2='19.19'/%3E%3Cline x1='9.00' y1='17.20' x2='7.85' y2='19.19'/%3E%3Cline x1='6.00' y1='12.00' x2='3.70' y2='12.00'/%3E%3Cline x1='9.00' y1='6.80' x2='7.85' y2='4.81'/%3E%3Cline x1='15.00' y1='6.80' x2='16.15' y2='4.81'/%3E%3Ccircle cx='12' cy='12' r='2'/%3E%3C/svg%3E");
}
/* Blue while acquiring (waiting), centred (active), and background-tracking. */
.maplibregl-ctrl-geolocate-waiting .maplibregl-ctrl-icon,
.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon,
.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon {
    background-color: var(--sgs-accent) !important;
}
/* Panned away (background): SAME wheel, hub removed -> the centre bubble disappears. */
.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon,
.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon {
    -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='6'/%3E%3Cline x1='18.00' y1='12.00' x2='20.30' y2='12.00'/%3E%3Cline x1='15.00' y1='17.20' x2='16.15' y2='19.19'/%3E%3Cline x1='9.00' y1='17.20' x2='7.85' y2='19.19'/%3E%3Cline x1='6.00' y1='12.00' x2='3.70' y2='12.00'/%3E%3Cline x1='9.00' y1='6.80' x2='7.85' y2='4.81'/%3E%3Cline x1='15.00' y1='6.80' x2='16.15' y2='4.81'/%3E%3C/svg%3E");
            mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='6'/%3E%3Cline x1='18.00' y1='12.00' x2='20.30' y2='12.00'/%3E%3Cline x1='15.00' y1='17.20' x2='16.15' y2='19.19'/%3E%3Cline x1='9.00' y1='17.20' x2='7.85' y2='19.19'/%3E%3Cline x1='6.00' y1='12.00' x2='3.70' y2='12.00'/%3E%3Cline x1='9.00' y1='6.80' x2='7.85' y2='4.81'/%3E%3Cline x1='15.00' y1='6.80' x2='16.15' y2='4.81'/%3E%3C/svg%3E");
}
/* Error states: red outline. */
.maplibregl-ctrl-geolocate-active-error .maplibregl-ctrl-icon,
.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon {
    background-color: #e54e33 !important;
}

[data-theme="dark"] .sgs-custom-ctrl {
    background: var(--sgs-bg);
    box-shadow: 0 0 0 1px var(--sgs-border);
}

/* Attribution */
/* Open by default (OSMF compliance, owner call 2026-07-11) and styled to recede.
   FLOATS just inside the corner as a rounded pill instead of sitting flush on
   the edge, with the text dim-but-legible at rest in BOTH themes (n6/n8
   2026-07-12); hover only sharpens it. The compact toggle only exists under
   640px (MapLibre's responsive default). */
.maplibregl-ctrl.maplibregl-ctrl-attrib {
    margin: 0 var(--sgs-gap-sm) var(--sgs-gap-sm) 0;
    background: color-mix(in srgb, var(--sgs-bg) 62%, transparent);
    color: var(--sgs-text-micro);
    font-size: 10px;
    line-height: 1.6;
    padding: 1px 8px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-pill);
    transition: background 0.15s ease, color 0.15s ease;
}
/* Dark map + dim token was near-invisible (n8): one shade up at rest. */
[data-theme="dark"] .maplibregl-ctrl.maplibregl-ctrl-attrib {
    color: var(--sgs-text-muted);
}
.maplibregl-ctrl.maplibregl-ctrl-attrib:hover {
    background: var(--sgs-bg);
    color: var(--sgs-text-muted);
}
.maplibregl-ctrl-attrib a {
    color: inherit;
}
.maplibregl-ctrl-attrib a:hover {
    color: var(--sgs-accent-hover);
}
/* Scale bar (n12): MapLibre's ScaleControl in sleek clothes — same translucent
   recede as the attribution pill it rides above. */
.maplibregl-ctrl.maplibregl-ctrl-scale {
    margin: 0 var(--sgs-gap-sm) 4px 0;
    background: color-mix(in srgb, var(--sgs-bg) 62%, transparent);
    color: var(--sgs-text-micro);
    font-size: 9.5px;
    line-height: 1.5;
    border: 1px solid var(--sgs-border);
    border-top: none;
    border-radius: 0 0 3px 3px;
}
[data-theme="dark"] .maplibregl-ctrl.maplibregl-ctrl-scale {
    color: var(--sgs-text-muted);
}
body.sgs-no-scalebar .maplibregl-ctrl-scale { display: none; }
/* Soften the stark black/white "i" toggle into a muted gray — but keep the
   closed-state glyph clearly legible (n3 2026-07-11: "inner gray a bit lighter").
   The button only renders in the compact (small-screen) control. */
.maplibregl-ctrl-attrib-button {
    opacity: 0.68;
}
[data-theme="dark"] .maplibregl-ctrl-attrib-button {
    filter: invert(0.95);
}


/* ============================================================
   11. MEASURE TOOL (overrides / additions to section above)
   ============================================================ */

.sgs-measure-ctrl {
    background: var(--sgs-bg);
    box-shadow: 0 0 0 1px var(--sgs-border);
}

/* SVG glyphs use currentColor → muted gray in both themes (the control is a
   .sgs-custom-ctrl, so it's excluded from the native dark-mode invert).
   Scoped under .sgs-custom-ctrl so display:flex beats MapLibre's
   `.maplibregl-ctrl-group button { display:block }` (which was pinning the SVGs
   to the left of each button). */
.sgs-custom-ctrl .sgs-measure-btn {
    color: var(--sgs-text-muted);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color var(--sgs-transition), color var(--sgs-transition);
}
.sgs-measure-btn svg { display: block; }

.sgs-measure-active {
    background: #fff3e0 !important;
    color: #e65100 !important;
}
[data-theme="dark"] .sgs-measure-active {
    background: #2d1a00 !important;
    color: #ffb74d !important;
}
/* Round only the end buttons' highlight to follow the control group's corners;
   the middle button stays square (it's flush between two others). */
.sgs-custom-ctrl .sgs-measure-btn.sgs-measure-active:first-child { border-radius: 5px 5px 0 0; }
.sgs-custom-ctrl .sgs-measure-btn.sgs-measure-active:last-child  { border-radius: 0 0 5px 5px; }


/* ============================================================
   12. UTILITIES
   ============================================================ */

/* Visually hidden (accessible) */
.sgs-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Truncate text */
.sgs-truncate {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Display toggle — replaces inline style.display manipulation */
.sgs-hidden { display: none !important; }

/* Filter panel loading state — dims content while scanning */
.sgs-filter--busy { opacity: 0.5; pointer-events: none; }

/* Query builder selected item highlight */
.sgs-query-surface--selected { background: var(--sgs-accent-subtle); }

/* Badge modifiers */
.sgs-badge--query {
    color: var(--sgs-accent);
    border-color: var(--sgs-accent);
    cursor: pointer;
    user-select: none;
}

.sgs-badge--error {
    color: var(--sgs-danger);
    border-color: var(--sgs-danger);
    cursor: pointer;
    user-select: none;
}

.sgs-badge--warn {
    color: var(--sgs-danger);
    border-color: var(--sgs-danger);
}

.sgs-badge--filter {
    background: transparent;
    color: var(--sgs-warn);
    border: 1px solid var(--sgs-warn);
    font-size: 9px;
    min-width: 14px;
    height: 14px;
    cursor: default;
}

/* Filter value off-state (unchecked) */
.sgs-filter-value--off {
    color: var(--sgs-danger);
}
.sgs-filter-value--off .sgs-filter-value-count {
    color: var(--sgs-danger);
}

/* Active filter section title */
.sgs-filter-section-title--active {
    color: var(--sgs-danger);
}

/* (removed duplicate .sgs-icon-btn--active — base rule at section 5 includes opacity) */

/* Button active state */
.sgs-btn--active {
    text-decoration: line-through;
    color: var(--sgs-text-muted);
}

/* Filter search status states */
.sgs-filter-search-status--active { color: var(--sgs-accent); }
.sgs-filter-search-status--warn   { color: var(--sgs-warn); }
.sgs-filter-search-status--error  { color: var(--sgs-danger); }

.sgs-filter-search-row {
    display: flex;
    gap: var(--sgs-gap-xs);
    align-items: center;
    padding: var(--sgs-gap-xs);
}

.sgs-filter-search-status {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    padding: 0 var(--sgs-gap-xs);
    min-height: 16px;
}


/* ============================================================
   13. RESPONSIVE
   ============================================================ */

@media (max-width: 600px) {
    .sgs-panel {
        top: auto;
        left: var(--sgs-gap-xs);
        right: var(--sgs-gap-xs);
        bottom: var(--sgs-gap-xs);
        width: auto;
        max-height: 40vh;
        border-radius: var(--sgs-radius-lg) var(--sgs-radius-lg) var(--sgs-radius-md) var(--sgs-radius-md);
    }

    .sgs-query-panel {
        width: calc(100vw - 32px);
    }

    .sgs-popup {
        max-width: calc(100vw - 32px);
    }
}


/* ============================================================
   14. POLISH & TACTILE ENHANCEMENTS
   ============================================================ */

/* Subtle depth on panel when hovered — feels more like a physical card */
.sgs-panel:hover {
    box-shadow: var(--sgs-shadow-lg);
}

/* Checkbox hover glow for discoverability */
.sgs-panel:not([class*="sgs-check--"]) .sgs-layer-row input[type="checkbox"]:hover:not(:checked),
.sgs-panel:not([class*="sgs-check--"]) .sgs-group-header input[type="checkbox"]:hover:not(:checked) {
    box-shadow: inset 0 0 0 1.2px var(--sgs-text-off), 0 0 0 3px var(--sgs-accent-subtle);
    border-radius: 2px;
}
.sgs-panel:not([class*="sgs-check--"]) .sgs-layer-row input[type="checkbox"]:hover:checked,
.sgs-panel:not([class*="sgs-check--"]) .sgs-group-header input[type="checkbox"]:hover:checked {
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.25), inset 0 -1px 0 rgba(0,0,0,0.1), 0 0 0 3px var(--sgs-accent-subtle);
    border-radius: 2px;
}
.sgs-check--toggle .sgs-layer-row input[type="checkbox"]:hover,
.sgs-check--toggle .sgs-group-header input[type="checkbox"]:hover {
    box-shadow: 0 0 0 2px var(--sgs-accent-subtle);
}
.sgs-check--circle .sgs-layer-row input[type="checkbox"]:hover:not(:checked),
.sgs-check--circle .sgs-group-header input[type="checkbox"]:hover:not(:checked) {
    box-shadow: inset 0 0 0 1.5px var(--sgs-text-off);
}
.sgs-check--eye .sgs-layer-row input[type="checkbox"]:hover,
.sgs-check--eye .sgs-group-header input[type="checkbox"]:hover {
    box-shadow: none;
    opacity: 0.8;
}

/* Layer row active press feedback — suppressed when the card is already on (white); no gray flash */
.sgs-layer-row:active {
    background: var(--sgs-surface-2);
    transform: scale(0.995);
}
.sgs-layer-wrap[data-on] .sgs-layer-row:active {
    background: transparent;
    transform: none;
}

/* Group header press feedback — suppressed when on */
.sgs-group-header:active {
    background: var(--sgs-surface-2);
    transform: scale(0.997);
}
.sgs-group-wrap[data-on] .sgs-group-header:active {
    background: transparent;
    transform: none;
}

/* Smooth open/close for filter sections */
.sgs-filter-section {
    transition: border-color var(--sgs-transition), box-shadow var(--sgs-transition);
}
.sgs-filter-section:hover {
    border-color: var(--sgs-border);
}

/* Popup entrance — subtle scale-in */
.sgs-popup {
    animation: sgs-popup-in 0.15s ease-out;
}
@keyframes sgs-popup-in {
    from { opacity: 0; transform: scale(0.96) translateY(4px); }
    to   { opacity: 1; transform: scale(1) translateY(0); }
}

/* Query panel entrance */
.sgs-query-panel {
    animation: sgs-panel-in 0.18s ease-out;
}
@keyframes sgs-panel-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Button press states — tactile depth */
.sgs-btn:active {
    transform: scale(0.96);
}
.sgs-btn--primary:active {
    background: var(--sgs-accent);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
}

/* Smooth focus rings for keyboard nav (accessibility) */
.sgs-btn:focus-visible,
.sgs-query-where:focus-visible,
.sgs-filter-search:focus-visible {
    outline: 2px solid var(--sgs-accent);
    outline-offset: 2px;
}

/* (removed duplicate .sgs-icon-btn:hover — base rule at section 5 is sufficient) */

/* Popup close button — color transition on hover */
.sgs-popup-close:active {
    transform: scale(0.9);
}
.sgs-query-close:active {
    transform: scale(0.9);
}

/* Badge pulse for active queries — draws attention without being distracting */
.sgs-badge--query {
    animation: sgs-badge-pulse 2s ease-in-out 1;
}
@keyframes sgs-badge-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.6; }
}

/* Symbology legend swatch hover — slight pop on the swatch itself only */
.sgs-swatch:hover,
.sgs-swatch-canvas:hover {
    transform: scale(1.15);
    transition: transform 0.1s ease;
}

/* ── Basemap card mount ───────────────────────────────────────────────────────
   Dedicated, stable container pinned below the (scrolling) layer list, outside
   the region reloadConfig/skeleton rebuilds wipe — so it never reflows or jumps
   on auth-change / config re-render. Empty when there's no card → no border. */
/* ── Basemap card (last item in layer list) ──────────────────────────────────── */
.sgs-basemap-wrapper {
    /* Flows naturally in the layer list with normal spacing — no separator */
}

/* ── Basemap picker (in the Basemap card) ─────────────────────────────────── */
.sgs-basemap-list {
    /* Horizontal inset matches the feature-layer field panel (.sgs-filter-body) and
       group sublayers (.sgs-layer-wrap margin) — var(--sgs-gap-sm) — so the swatch
       rows aren't flush against the card edge. */
    padding: 4px var(--sgs-gap-sm) 6px;
    display: flex;
    flex-direction: column;
}
.sgs-basemap-search-input {
    width: 100%;
    box-sizing: border-box;
    margin: 2px 0 6px;
    padding: 4px 8px;
    font-size: 12px;
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border);
    border-radius: 6px;
}
.sgs-basemap-section {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.sgs-basemap-heading {
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sgs-text-micro);
    padding: 6px 6px 2px;
    cursor: default;
}
.sgs-basemap-swatch {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 4px 6px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--sgs-text);
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}
/* Hover lightens (like sublayer cards in light mode), rather than darkening. */
.sgs-basemap-swatch:hover {
    background: var(--sgs-surface-mid);
}
/* Selected basemap mirrors an on sublayer inside an expanded, on group: outlined
   and lifted to white (light mode) — not accent-blue. Specificity (0,3,0) keeps it
   from flipping gray under the :hover rule above. */
.sgs-group-wrap[data-on] .sgs-basemap-swatch--active {
    border-color: var(--sgs-border);
    background: var(--sgs-layer-card-on);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.80), inset 0 -1px 0 rgba(0,0,0,0.18);
}
[data-theme="dark"] .sgs-group-wrap[data-on] .sgs-basemap-swatch--active {
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16), inset 0 -1px 0 rgba(0,0,0,0.16);
}
/* Basemap card off (basemap hidden): selection stays obvious but goes gray, like a
   layer inside a turned-off group. */
.sgs-group-wrap:not([data-on]) .sgs-basemap-swatch--active {
    border-color: var(--sgs-border);
    background: var(--sgs-layer-card);
}
.sgs-basemap-swatch-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-basemap-thumb {
    position: relative;
    flex-shrink: 0;
    width: 34px;
    height: 24px;
    border-radius: 4px;
    border: 1px solid var(--sgs-border);
    background-size: cover;
    background-position: center;
    /* default / generic look */
    background-image: linear-gradient(135deg, var(--sgs-surface-2), var(--sgs-surface));
}
/* Non-selected previews are muted by a light-gray wash so the active basemap's
   thumbnail reads clearly. The wash lifts on hover (when the basemap card is on),
   revealing the true image. */
.sgs-basemap-swatch:not(.sgs-basemap-swatch--active) .sgs-basemap-thumb::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: color-mix(in srgb, var(--sgs-surface-hover) 30%, transparent);
    opacity: 1;
    transition: opacity var(--sgs-transition);
}
.sgs-group-wrap[data-on] .sgs-basemap-swatch:hover .sgs-basemap-thumb::after {
    opacity: 0;
}
.sgs-basemap-thumb[data-thumb="open"]        { background-image: linear-gradient(135deg, #e8f0e0, #cfe0c0); }
.sgs-basemap-thumb[data-thumb="imagery"]     { background-image: linear-gradient(135deg, #2b3a27, #1c2b3a 60%, #4a5b3a); }
.sgs-basemap-thumb[data-thumb="topographic"] { background-image: linear-gradient(135deg, #e7e2d4, #cdd6b8); }
.sgs-basemap-thumb[data-thumb="light-gray"]  { background-image: linear-gradient(135deg, #f2f2f2, #d8d8d8); }
.sgs-basemap-thumb[data-thumb="dark-gray"]   { background-image: linear-gradient(135deg, #3a3a3a, #1f1f1f); }
.sgs-basemap-thumb[data-thumb="account"]     { background-image: linear-gradient(135deg, var(--sgs-accent-light), var(--sgs-accent)); }
.sgs-basemap-thumb[data-thumb="living-atlas"] { background-image: linear-gradient(135deg, #f0e8d8, #e8dcc8); }

/* ── Configure mode (the pin manager) ─────────────────────────────────────────
   Shown when compose/edit mode is active. The pinned set is drag-reorderable
   (mirrors the layer-list drag idiom); each catalog card is pin/unpin-able. */
.sgs-basemap-pinlist {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
/* A row wraps a swatch with its pin affordances. The swatch keeps flex:1 so the
   label/thumb layout is unchanged; the drag handle / pin button flank it. */
.sgs-basemap-pinrow {
    position: relative;
    display: flex;
    align-items: center;
    gap: 2px;
    border-radius: 6px;
}
.sgs-basemap-pinrow .sgs-basemap-swatch {
    flex: 1;
    min-width: 0;
}
/* Overlay the ± / ⓘ inside the row (on the right edge) instead of letting them take
   flex slots — so the swatch runs the full width of the card, matching use mode. The
   drag handle stays in-flow on the left. */
.sgs-basemap-pinrow .sgs-basemap-pin-btn {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
}
.sgs-basemap-pinrow .sgs-basemap-info {
    position: absolute;
    right: 26px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
}
.sgs-basemap-pinrow .sgs-basemap-swatch-label {
    padding-right: 46px;
}
/* The pin drag handle is always visible in configure mode (the card is only
   built in that mode), unlike the layer-list handle gated by .sgs-edit-active. */
.sgs-basemap-drag {
    display: flex;
}
/* Minimal, borderless ±: a small ghost icon (like the ⓘ), not a chunky button. */
.sgs-basemap-pin-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    border-radius: var(--sgs-radius-sm);
    background: none;
    color: var(--sgs-text-micro);
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-basemap-pin-btn:hover { background: var(--sgs-surface-mid); }
.sgs-basemap-pin-btn--add:hover { color: var(--sgs-accent); }
.sgs-basemap-pin-btn--remove:hover { color: #d93025; }
.sgs-basemap-pin-btn svg { display: block; }

/* Per-basemap text-labels toggle (the T glyph on each swatch row). Off reads as
   muted; --on lifts it to the accent so each basemap's label state is legible at a
   glance. Overlaid at the row's right edge (left of the ⓘ when present). */
.sgs-basemap-labels-btn {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    border-radius: var(--sgs-radius-sm);
    background: none;
    color: var(--sgs-text-micro);
    /* Labels-off resting: kept clearly visible (a mid shade between the card and the panel bg),
       just quieter than the neutral labels-on state — not the near-ghost it used to be. */
    opacity: 0.7;
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-basemap-labels-btn:hover { background: var(--sgs-surface-mid); opacity: 1; }
/* Labels-on, but this basemap is NOT the active one: the "T" is visible yet NEUTRAL (a plain
   grey, "sort of white" — never blue). Blue is reserved for the basemap actually in use, so it
   doesn't look like these labels are live on the map. Applies in both themes. */
.sgs-basemap-labels-btn--on { color: var(--sgs-text-muted); opacity: 1; }
/* Only the ACTIVE basemap's labels-on "T" goes blue (brighter in dark, matching the layer "T"). */
.sgs-basemap-row:has(.sgs-basemap-swatch--active) .sgs-basemap-labels-btn--on {
    color: var(--sgs-accent);
}
[data-theme="dark"] .sgs-basemap-row:has(.sgs-basemap-swatch--active) .sgs-basemap-labels-btn--on {
    color: var(--sgs-accent-hover);
}
.sgs-basemap-labels-btn svg { display: block; }

/* Row placement: the T sits at the right edge; the ⓘ (when present) shifts left of
   it. The swatch label reserves room so it never runs under either icon. */
.sgs-basemap-row .sgs-basemap-labels-ctrl {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
}
.sgs-basemap-row:has(.sgs-basemap-labels-ctrl) .sgs-basemap-info { right: 26px; }
.sgs-basemap-row:has(.sgs-basemap-labels-ctrl) .sgs-basemap-swatch-label { padding-right: 24px; }
.sgs-basemap-row:has(.sgs-basemap-labels-ctrl):has(.sgs-basemap-info) .sgs-basemap-swatch-label { padding-right: 46px; }
.sgs-basemap-empty {
    font-size: 11px;
    color: var(--sgs-text-micro);
    padding: 4px 6px 6px;
}
/* "Load more" for the server-paged Living Atlas results. */
.sgs-basemap-loadmore {
    align-self: flex-start;
    margin: 4px 6px 2px;
    padding: 3px 10px;
    font-size: 11px;
    color: var(--sgs-text-muted);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-pill);
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-basemap-loadmore:hover:not(:disabled) { color: var(--sgs-text); background: var(--sgs-surface-mid); }
.sgs-basemap-loadmore:disabled { opacity: 0.6; cursor: default; }

/* A row wraps a swatch with its inline affordances (ⓘ in use mode; ⓘ + pin in
   configure mode). The swatch keeps flex:1 so its label/thumb layout is unchanged. */
.sgs-basemap-row {
    position: relative;
    display: flex;
    align-items: center;
    gap: 2px;
    border-radius: 6px;
}
.sgs-basemap-row .sgs-basemap-swatch,
.sgs-basemap-pinrow .sgs-basemap-swatch {
    flex: 1;
    min-width: 0;
}
/* In use mode the ⓘ is overlaid on the right edge rather than taking a flex slot,
   so the swatch (and its hover highlight) runs the full width of the card again —
   as it did before the ⓘ was introduced. The label reserves room so it never runs
   under the icon. */
.sgs-basemap-row .sgs-basemap-info {
    position: absolute;
    right: 4px;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
}
.sgs-basemap-row:has(.sgs-basemap-info) .sgs-basemap-swatch-label {
    padding-right: 18px;
}

/* ── Per-basemap info (ⓘ) ──────────────────────────────────────────────────────
   A small button that toggles a popover (description + source link). The ⓘ stays
   subtle until the row is hovered, so use mode keeps its clean look. */
.sgs-basemap-info {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
}
.sgs-basemap-info-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    opacity: 0;
    transition: opacity var(--sgs-transition), color var(--sgs-transition);
}
.sgs-basemap-row:hover .sgs-basemap-info-btn,
.sgs-basemap-pinrow:hover .sgs-basemap-info-btn,
.sgs-basemap-info-btn:focus-visible { opacity: 1; }
.sgs-basemap-info-btn:hover { color: var(--sgs-text); }
/* On the ACTIVE (in-use) basemap the ⓘ is always visible and clearly legible — a shade lighter
   than the labels "T" (--sgs-text-muted), still short of the full-text brightness it reaches on
   hover. Theme-aware via the mix; hover below still lifts it the rest of the way. */
.sgs-basemap-row:has(.sgs-basemap-swatch--active) .sgs-basemap-info-btn {
    opacity: 1;
    color: color-mix(in srgb, var(--sgs-text) 35%, var(--sgs-text-muted));
}
.sgs-basemap-row:has(.sgs-basemap-swatch--active) .sgs-basemap-info-btn:hover {
    color: var(--sgs-text);
}
.sgs-basemap-info-btn svg { display: block; }
/* The ⓘ popover. Position:fixed (coords set in JS from the button rect) so it opens
   to the right of the click and escapes the panel's overflow clip — it's never cut
   off at the panel edge or near the top of the list. Flips left only if the viewport
   has no room on the right. */
.sgs-basemap-info-pop {
    position: fixed;
    z-index: 500;
    width: 200px;
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    box-shadow: var(--sgs-shadow-lg);
}
.sgs-basemap-info-close {
    position: absolute;
    top: 3px;
    right: 3px;
    width: 16px;
    height: 16px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    font-size: 15px;
    line-height: 1;
    cursor: pointer;
    border-radius: var(--sgs-radius-sm);
}
.sgs-basemap-info-close:hover { color: var(--sgs-text); }
.sgs-basemap-info-desc {
    font-size: 11px;
    line-height: 1.4;
    color: var(--sgs-text);
    padding-right: 14px; /* clear the ✕ on the first line */
    white-space: pre-line; /* authored blank lines (widget about:) become paragraphs */
}
.sgs-basemap-info-link {
    display: inline-block;
    margin-top: 4px;
    font-size: 11px;
    color: var(--sgs-accent);
    text-decoration: none;
}
.sgs-basemap-info-link:hover { text-decoration: underline; }
/* Layer data-origin popover rows (issue #38): provider heading, snippet, and a
   muted meta line (org / vintage / views). Reuse the popover's 11px rhythm. */
.sgs-layer-info-provider {
    font-weight: 600;
    padding-right: 14px; /* clear the ✕ */
}
.sgs-layer-info-snippet {
    font-size: 11px;
    line-height: 1.4;
    color: var(--sgs-text);
    font-style: italic;
    margin-top: 2px;
}
.sgs-layer-info-meta {
    font-size: 10px;
    line-height: 1.4;
    color: var(--sgs-text-muted);
    margin-top: 3px;
}

/* Panel scrollbar — appears only on hover for cleaner look */
.sgs-panel {
    scrollbar-gutter: stable;
}
.sgs-panel:not(:hover)::-webkit-scrollbar-thumb {
    background: transparent;
}

/* Dark mode: slightly brighter accent for better contrast on dark surfaces */
[data-theme="dark"] .sgs-badge--query {
    background: var(--sgs-accent);
}

/* Selection color matches brand */
::selection {
    background: var(--sgs-accent-subtle);
    color: var(--sgs-text);
}


/* ============================================================
   14. AUTH INDICATOR
   ============================================================ */

.sgs-auth-ctrl {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sgs-auth-ctrl .sgs-auth-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--sgs-ctrl-size);
    height: var(--sgs-ctrl-size);
    padding: 0;
    border: none;
    background: none;
    border-radius: 4px;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}

.sgs-auth-btn svg {
    display: block;
    flex-shrink: 0;
}

/* Resting/hover for the (signed-out) person icon is handled by the unified control-hover rule
   in §10 (--sgs-ctrl-hover-*), so it matches the rest of the stack. The signed-in avatar keeps
   its own accent ring hover below. */
.sgs-auth-btn--signed-in {
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: -0.3px;
    border-radius: 50%;
    overflow: hidden;
}

.sgs-auth-btn--signed-in:hover {
    box-shadow: 0 0 0 2px var(--sgs-accent);
}

.sgs-auth-avatar {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: 50%;
}

/* ── Dropdown ─────────────────────────────────────────────────── */

.sgs-auth-dropdown {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    width: 220px;
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    box-shadow: var(--sgs-shadow);
    padding: var(--sgs-gap-sm) 0;
    z-index: 1000;
}

.sgs-auth-dropdown-header {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    padding: var(--sgs-gap-xs) var(--sgs-gap-md);
}

.sgs-auth-dropdown-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
}

.sgs-auth-dropdown-initials {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-size: 12px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.sgs-auth-dropdown-info {
    min-width: 0;
}

.sgs-auth-dropdown-name {
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sgs-auth-dropdown-user {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sgs-auth-dropdown-divider {
    height: 1px;
    background: var(--sgs-border);
    margin: var(--sgs-gap-xs) 0;
}

.sgs-auth-dropdown-conn {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    padding: var(--sgs-gap-xs) var(--sgs-gap-md);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
}

.sgs-auth-conn-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: #34d399;
    flex-shrink: 0;
}

.sgs-auth-dropdown-signout {
    display: block;
    width: calc(100% - var(--sgs-gap-md) * 2);
    margin: var(--sgs-gap-xs) var(--sgs-gap-md) 0;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    text-align: left;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}

.sgs-auth-dropdown-signout:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}

[data-theme="dark"] .sgs-auth-dropdown {
    box-shadow: var(--sgs-shadow-lg);
}


/* ============================================================
   15. AGOL BROWSER MODAL
   ============================================================ */

/* The AGOL browser renders inline inside the Add Data window's ArcGIS Online tab
   (it is no longer a standalone modal). The host tab content (.sgs-adddata-content)
   provides the outer padding/scroll; these rules style the inline browser within it. */
.sgs-agol-inline {
    display: flex;
    flex-direction: column;
}

.sgs-agol-signin {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sgs-gap-sm);
}

.sgs-agol-search {
    padding: 0 0 var(--sgs-gap-sm);
}

.sgs-agol-search-input {
    width: 100%;
    padding: var(--sgs-gap-xs) var(--sgs-gap-sm);
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text);
    /* --sgs-bg (not surface) so the field reads as a field in light mode (n6) */
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
}

.sgs-agol-search-input:focus {
    outline: 1px solid var(--sgs-accent);
    outline-offset: -1px;
}

.sgs-agol-search-input::placeholder {
    color: var(--sgs-text-muted);
}

/* Filter strip (n6/n7): scope · type · owner */
.sgs-agol-filters {
    display: flex;
    gap: var(--sgs-gap-xs);
    padding: var(--sgs-gap-xs) 0;
}
.sgs-agol-filter-select {
    flex: 1;
    min-width: 0;
    padding: 2px 4px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: color var(--sgs-transition), border-color var(--sgs-transition);
}
.sgs-agol-filter-select:hover {
    color: var(--sgs-text);
    border-color: var(--sgs-border);
}

/* The results viewport's height + overflow are set in JS (_applyViewport): in paged mode
   it's locked to a full page's *measured* height so every page is the same height (no jump)
   and a full page never needs a scrollbar; in "show all" mode it's a fixed scroll window.
   `box-sizing: border-box` makes the measured scrollHeight (content + padding) map 1:1 onto
   the height we set, so the lock is pixel-exact. min-height is just a pre-measure fallback. */
.sgs-agol-results {
    box-sizing: border-box;
    overflow-y: auto;
    min-height: calc(8 * 52px);
    padding: var(--sgs-gap-xs) 0;
}

/* Cross-link back to the storage analyzer, right-aligned above the search box. */
/* (.sgs-agol-xrow removed — the storage-cost link floats in the tab strip now, n3) */
.sgs-adddata-analyze {
    margin-left: auto;
    align-self: center;
    font-size: var(--sgs-font-xs);
}

.sgs-agol-item {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    /* Fixed row height keeps the reserved-height math exact (no per-row variance). */
    min-height: 52px;
    box-sizing: border-box;
    padding: var(--sgs-gap-xs) var(--sgs-gap-xs) var(--sgs-gap-xs) 0;
    cursor: pointer; /* the card opens to its detail (n6) */
    transition: background var(--sgs-transition);
}

/* Disclosure chevron + detail (n6) */
.sgs-agol-item-chevron {
    display: flex;
    align-items: center;
    color: var(--sgs-text-micro);
    transition: transform var(--sgs-transition), color var(--sgs-transition);
}
.sgs-agol-item:hover .sgs-agol-item-chevron { color: var(--sgs-text-muted); }
.sgs-agol-item-wrap--open .sgs-agol-item-chevron { transform: rotate(90deg); }
.sgs-agol-item-detail {
    padding: 0 var(--sgs-gap-sm) var(--sgs-gap-sm) var(--sgs-gap-sm);
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-xs);
    font-size: var(--sgs-font-xs);
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-agol-item-snippet { color: var(--sgs-text); }
.sgs-agol-item-desc {
    color: var(--sgs-text-muted);
    max-height: 96px;
    overflow-y: auto;
    white-space: pre-line;
}
.sgs-agol-item-fund { color: var(--sgs-savant-text, var(--sgs-accent)); font-weight: 600; }
.sgs-agol-item-link { color: var(--sgs-accent); text-decoration: none; }
.sgs-agol-item-link:hover { text-decoration: underline; }
/* Org name in the detail foot (lazy-resolved), quiet, left of the ArcGIS link. */
.sgs-agol-item-detail-foot { display: flex; align-items: baseline; gap: var(--sgs-gap-sm); }
.sgs-agol-item-org { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--sgs-text-micro); font-size: 11px; }

.sgs-agol-item:hover {
    background: var(--sgs-surface);
}

/* Thumbnail — the item's ArcGIS preview picture, or a type glyph when it has none. */
.sgs-agol-item-thumb {
    flex-shrink: 0;
    width: 42px;
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-accent);
    font-size: 16px;
}
.sgs-agol-item-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.sgs-agol-item-info {
    flex: 1;
    min-width: 0;
}

.sgs-agol-item-name {
    font-size: var(--sgs-font-sm);
    font-weight: 500;
    color: var(--sgs-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Meta row: type pillbox + owner · date · size. */
.sgs-agol-item-meta {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    margin-top: 2px;
    min-width: 0;
}
.sgs-agol-item-metatext {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}

/* Actions cluster: ⓘ (reveals on row hover, like the basemap cards) + add-to-map. */
.sgs-agol-item-actions {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    gap: 2px;
}
.sgs-agol-item:hover .sgs-agol-item-actions .sgs-basemap-info-btn,
.sgs-agol-item-actions .sgs-basemap-info-btn:focus-visible {
    opacity: 1;
}

.sgs-agol-item-add {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 16px;
    font-weight: 600;
    color: var(--sgs-accent);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: background var(--sgs-transition);
}

.sgs-agol-item-add:hover {
    background: var(--sgs-accent-subtle);
}

/* Footer holds the mode toggle (left), page controls (center, paged mode), and the
   total-count readout (right). Constant height so it doesn't shift between pages. */
.sgs-agol-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sgs-gap-sm);
    padding: var(--sgs-gap-sm) 0 0;
    border-top: 1px solid var(--sgs-border-light);
}

.sgs-agol-mode-toggle {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-accent);
    cursor: pointer;
    white-space: nowrap;
}
.sgs-agol-mode-toggle:hover { text-decoration: underline; }

.sgs-agol-count {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    white-space: nowrap;
}

.sgs-agol-pager {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}

.sgs-agol-pager-btn {
    padding: 2px 8px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
}

.sgs-agol-pager-btn:hover:not(:disabled) {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}

.sgs-agol-pager-btn:disabled {
    opacity: 0.3;
    cursor: default;
}

.sgs-agol-pager-info {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
}

.sgs-agol-loading,
.sgs-agol-empty,
.sgs-agol-error {
    padding: var(--sgs-gap-lg) var(--sgs-gap-md);
    text-align: center;
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
}

.sgs-agol-error {
    color: var(--sgs-danger);
}


/* ============================================================
   15b. ADD DATA MODAL
   ============================================================ */

/* Add Data is a floating window like popups / the query panel (positioned next to
   the layer list in JS), not a centered backdropped modal. Same z-index band as the
   query panel so it shares their stacking behavior. */
.sgs-adddata-panel {
    position: fixed;
    z-index: 420;
    width: 440px;
    max-width: calc(100vw - 32px);
    max-height: 80vh;
    background: var(--sgs-surface);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow-lg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.sgs-adddata-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sgs-gap-md);
    border-bottom: 1px solid var(--sgs-border-light);
}

.sgs-adddata-title {
    font-weight: 600;
    font-size: var(--sgs-font-md);
    color: var(--sgs-text);
}

.sgs-adddata-close {
    font-size: 18px;
    color: var(--sgs-text-muted);
    line-height: 1;
}
.sgs-adddata-close:hover { color: var(--sgs-text); }

.sgs-adddata-tabs {
    display: flex;
    border-bottom: 1px solid var(--sgs-border-light);
    padding: 0 var(--sgs-gap-md);
    gap: 2px;
}

.sgs-adddata-tab {
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 0.15s, border-color 0.15s;
}
.sgs-adddata-tab:hover { color: var(--sgs-text); }
.sgs-adddata-tab--active {
    color: var(--sgs-accent);
    border-bottom-color: var(--sgs-accent);
}

.sgs-adddata-content {
    padding: var(--sgs-gap-md);
    overflow-y: auto;
    flex: 1;
}

/* Composition footer — quiet, below the source tabs */
.sgs-adddata-foot {
    padding: var(--sgs-gap-xs) var(--sgs-gap-md);
    border-top: 1px solid var(--sgs-border-light);
}
.sgs-adddata-newgroup {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    transition: color var(--sgs-transition);
}
.sgs-adddata-newgroup:hover {
    color: var(--sgs-text);
}

.sgs-adddata-desc {
    margin: 0 0 var(--sgs-gap-md);
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
}

.sgs-adddata-url-row {
    display: flex;
    gap: var(--sgs-gap-sm);
}

.sgs-adddata-url-input {
    flex: 1;
    padding: 6px 10px;
    font-size: var(--sgs-font-sm);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-bg);
    color: var(--sgs-text);
}
.sgs-adddata-url-input:focus {
    outline: none;
    border-color: var(--sgs-accent);
}

.sgs-adddata-url-btn {
    padding: 6px 14px;
    font-size: var(--sgs-font-sm);
    background: var(--sgs-accent);
    color: #fff;
    border-radius: var(--sgs-radius-md);
    font-weight: 500;
}
.sgs-adddata-url-btn:hover { opacity: 0.9; }

.sgs-adddata-status {
    margin-top: var(--sgs-gap-sm);
    font-size: var(--sgs-font-xs);
}
/* No reserved blank line while there is nothing to say (notebear 2026-07-07 n11). */
.sgs-adddata-status:empty { display: none; }
.sgs-adddata-status--error { color: var(--sgs-danger); }
.sgs-adddata-status--success { color: var(--sgs-success, #27ae60); }
.sgs-adddata-status--loading { color: var(--sgs-text-muted); }
.sgs-adddata-save-agol {
    display: block;
    margin-top: 8px;
    padding: 5px 10px;
    font-size: 12px;
    border: 1px solid var(--sgs-accent);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    color: var(--sgs-accent);
    cursor: pointer;
}
.sgs-adddata-save-agol:hover:not(:disabled) { background: var(--sgs-accent); color: #fff; }
.sgs-adddata-save-agol:disabled { opacity: 0.7; cursor: default; }
.sgs-adddata-publish-note {
    margin-top: 6px;
    font-size: 11px;
    color: var(--sgs-text-muted);
    line-height: 1.4;
}

.sgs-adddata-dropzone {
    border: 2px dashed var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    padding: var(--sgs-gap-lg) var(--sgs-gap-md);
    text-align: center;
    color: var(--sgs-text-muted);
    font-size: var(--sgs-font-sm);
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}
.sgs-adddata-dropzone:hover,
.sgs-adddata-dropzone--active {
    border-color: var(--sgs-accent);
    background: color-mix(in srgb, var(--sgs-accent) 5%, transparent);
}

.sgs-adddata-file-input {
    display: none;
}

.sgs-adddata-agol-btn {
    padding: 8px 16px;
    font-size: var(--sgs-font-sm);
    background: var(--sgs-accent);
    color: #fff;
    border-radius: var(--sgs-radius-md);
    font-weight: 500;
}
.sgs-adddata-agol-btn:hover { opacity: 0.9; }

.sgs-hidden { display: none !important; }


/* ============================================================
   16. EDIT MODE
   ============================================================ */

/* Drag handle: inline flex child prepended to the row.
   Hidden by default; appears when compose mode is active. */
.sgs-edit-drag {
    display: none;
    flex-shrink: 0;
    width: var(--sgs-drag-w);
    height: var(--sgs-gear-w);
    align-items: center;
    justify-content: center;
    font-size: 10px;
    color: var(--sgs-text-micro);
    cursor: grab;
    user-select: none;
    letter-spacing: 0;
    position: relative;
    top: -0.1em;
}
.sgs-edit-active .sgs-edit-drag {
    display: flex;
}
.sgs-edit-drag:active {
    cursor: grabbing;
}
.sgs-edit-drag--ghost {
    opacity: 0;
    pointer-events: none;
    cursor: default;
}

/* Zoom-to + attribute-table: use-mode row actions, revealed on row hover and
   hidden in compose (gear/trash own the action slot there). Same footprint and
   state treatment as the gear so the row reads as one system.
   visibility (not display) so every row RESERVES its icons' width at rest —
   hovering must never widen the row or the fit-content panel (n2 2026-07-11). */
.sgs-row-zoom,
.sgs-row-query,
.sgs-row-attrs,
.sgs-row-info-wrap {
    display: inline-flex;
    visibility: hidden;
    align-items: center;
    justify-content: center;
    width: var(--sgs-gear-w);
    height: var(--sgs-gear-w);
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-muted);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: color var(--sgs-transition);
}
/* The data-origin ⓘ (issue #38) rides the shared popover control, so reset its
   basemap-card chrome to the row-action footprint. Leftmost of the actions. */
.sgs-row-info-wrap { order: 6; margin: 0; }
.sgs-row-info-wrap .sgs-basemap-info-btn {
    width: var(--sgs-gear-w);
    height: var(--sgs-gear-w);
    padding: 0;
    color: inherit;
}
.sgs-layer-row:hover .sgs-row-info-wrap { visibility: visible; }
.sgs-row-info-wrap:hover { color: var(--sgs-text); }
.sgs-edit-active .sgs-layer-row:hover .sgs-row-info-wrap,
.sgs-edit-active .sgs-row-info-wrap { display: none; }
/* Table first, zoom next, funnel LAST — the funnel sits just left of the
   labels T so its query-active accent reads as the row's rightmost state
   (n2 2026-07-12; owner call, reversing the old popup-bar order). */
.sgs-row-attrs { order: 7; }
.sgs-row-zoom { order: 8; }
.sgs-row-query { order: 9; }
/* The labels "T" is visible AT REST, so it owns the far-right slot permanently:
   hover/compose icons (orders 7-11) materialize to its LEFT, never displacing it. */
.sgs-row-actions .sgs-row-labels { order: 20; }
.sgs-layer-row:hover .sgs-row-zoom,
.sgs-layer-row:hover .sgs-row-query,
.sgs-layer-row:hover .sgs-row-attrs,
.sgs-group-header:hover .sgs-row-query { visibility: visible; }
/* After the hover rule on purpose: compose wins even on a hovered row. */
.sgs-edit-active .sgs-layer-row:hover .sgs-row-zoom,
.sgs-edit-active .sgs-layer-row:hover .sgs-row-query,
.sgs-edit-active .sgs-layer-row:hover .sgs-row-attrs,
.sgs-edit-active .sgs-group-header:hover .sgs-row-query,
.sgs-edit-active .sgs-row-zoom,
.sgs-edit-active .sgs-row-query,
.sgs-edit-active .sgs-row-attrs { display: none; }
.sgs-row-zoom:hover,
.sgs-row-query:hover,
.sgs-row-attrs:hover { color: var(--sgs-text); }
.sgs-row-zoom svg,
.sgs-row-query svg,
.sgs-row-attrs svg { display: block; }
/* A layer with a query applied wears it on the funnel itself: accent, visible
   at rest (replaces the "Q" chip, n2 2026-07-12). After the hover rules so the
   accent survives hovering. */
.sgs-layer-row .sgs-row-query--active,
.sgs-group-header .sgs-row-query--active {
    visibility: visible;
    color: var(--sgs-accent);
}

/* Gear: hidden by default; min-width on .sgs-row-actions reserves its space */
.sgs-edit-gear {
    display: none;
    align-items: center;
    justify-content: center;
    width: var(--sgs-gear-w);
    height: var(--sgs-gear-w);
    padding: 0;
    order: 10;
    color: var(--sgs-text-muted);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: color var(--sgs-transition);
}
.sgs-edit-active .sgs-edit-gear {
    display: flex;
}

.sgs-edit-gear:hover {
    color: var(--sgs-text);
}

.sgs-edit-gear--active {
    color: var(--sgs-accent, #1a73e8);
}

.sgs-edit-remove {
    display: none;
    align-items: center;
    justify-content: center;
    width: var(--sgs-trash-w);
    height: var(--sgs-trash-w);
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-muted);
    border-radius: 3px;
    cursor: pointer;
    order: 11;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}

.sgs-edit-active .sgs-edit-remove {
    display: inline-flex;
}

.sgs-edit-remove:hover {
    color: #d93025;
}

.sgs-edit-remove svg,
.sgs-edit-gear svg {
    display: block;
}

/* Rename: pencil-on-hover beside the name, compose only (created/destroyed with
   the other edit affordances). The inline editor swaps the label for an input. */
/* Drop-into-group affordances (n12): a header lights up while a dragged layer can be
   filed into it; an empty group body grows a visible drop zone for the drag's duration. */
.sgs-group-header.sgs-edit-drop-into {
    background: color-mix(in srgb, var(--sgs-accent) 12%, transparent);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--sgs-accent) 45%, transparent);
    border-radius: var(--sgs-radius-sm);
}
body.sgs-edit-drag-live .sgs-group-children:empty {
    display: block;
    min-height: 22px;
    margin: 2px 4px 2px 18px;
    border: 1px dashed var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
}

/* In compose the name itself is the rename editor: a text cursor + a dashed underline
   on hover say "this text is editable" without a second pencil on the row (the gear is
   already a pencil). */
.sgs-edit-active .sgs-edit-renameable {
    cursor: text;
    /* The click-to-rename target hugs the text (n16): the name stops stretching
       across the row's free space, so clicking beside it is not a rename.
       margin-right:auto keeps the actions pushed to the right edge. */
    flex: 0 1 auto;
    margin-right: auto;
    min-width: 0;
}
.sgs-edit-active .sgs-edit-renameable:hover {
    text-decoration: underline dashed var(--sgs-text-muted);
    text-underline-offset: 3px;
}
.sgs-rename-input {
    width: 100%;
    min-width: 60px;
    padding: 0 3px;
    border: 1px solid var(--sgs-accent);
    border-radius: 3px;
    background: var(--sgs-bg, #fff);
    color: var(--sgs-text);
    font: inherit;
    outline: none;
}

/* Drag state */
.sgs-edit-dragging {
    opacity: 0.4;
}

.sgs-edit-drop-above {
    border-top: 2px solid var(--sgs-accent);
}

.sgs-edit-drop-below {
    border-bottom: 2px solid var(--sgs-accent);
}

/* Empty group drop zone in edit mode — min-height only; no padding-bottom to avoid extra gap below last item */
.sgs-edit-active .sgs-group-children {
    min-height: 20px;
}

/* Per-layer config popover */
.sgs-edit-popover {
    background: #fafbfc;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    margin: var(--sgs-gap-xs) 0;
    box-shadow: var(--sgs-shadow-sm);
}
/* When symbology hidden and filter hidden, popover bottom aligns with layer-wrap */
.sgs-layer-wrap:has(.sgs-filter-body.sgs-hidden):not(:has(.sgs-legend:not(.sgs-hidden))) .sgs-edit-popover {
    margin-bottom: 0;
}
[data-theme="dark"] .sgs-edit-popover {
    background: #2a2e38;
    border-color: var(--sgs-border);
}

.sgs-edit-popover-heading {
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text);
    margin-bottom: var(--sgs-gap-sm);
}

.sgs-edit-popover-section {
    margin-bottom: var(--sgs-gap-sm);
}

.sgs-edit-popover-label {
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    color: var(--sgs-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    margin-bottom: var(--sgs-gap-xs);
}

.sgs-edit-popover-row {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    margin-bottom: var(--sgs-gap-xs);
}

.sgs-edit-popover-color {
    width: 28px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
}

/* ── Layer style: the quiet card row + the floating symbology editor ──────────
   The card's compose view shows ONE summary row (patch dots · label · opacity %);
   the instruments (jewel swatch, sliders, per-patch overrides) live in the
   floating .sgs-symed editor it opens (issue #17, disclosure-first). The jewel
   swatch + accent slider primitives below are shared by both. */
.sgs-stylerow {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    width: 100%;
    padding: 4px 6px;
    margin-bottom: var(--sgs-gap-sm);
    background: transparent;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text);
    font-size: var(--sgs-font-xs);
    cursor: pointer;
    text-align: left;
    transition: border-color 0.12s ease, background 0.12s ease;
}
.sgs-stylerow:hover {
    border-color: var(--sgs-accent);
    background: var(--sgs-accent-subtle);
}
.sgs-stylerow-preview {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}
/* Patch dots shingle slightly so four classes still read as one compact mark. */
.sgs-stylerow-dot {
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background: var(--sgs-dot, #888);
    box-shadow: 0 0 0 1px var(--sgs-border);
}
.sgs-stylerow-dot + .sgs-stylerow-dot { margin-left: -4px; }
.sgs-stylerow-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-stylerow-pct {
    font-variant-numeric: tabular-nums;
    color: var(--sgs-text-muted);
}

/* The floating editor: quick-settings' panel shape, instrument-panel contents. */
.sgs-symed {
    position: fixed;
    z-index: 900;
    width: 232px;
    max-height: calc(100vh - 40px);
    overflow: auto;
    padding: var(--sgs-gap-md);
    background: var(--sgs-bg);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    box-shadow: 0 8px 28px rgba(0,0,0,0.18);
    color: var(--sgs-text);
}
.sgs-symed-head {
    display: flex;
    align-items: baseline;
    gap: var(--sgs-gap-sm);
    margin-bottom: var(--sgs-gap-sm);
}
.sgs-symed-title {
    font-size: var(--sgs-font-xs);
    font-weight: 600;
}
.sgs-symed-name {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--sgs-font-micro);
    color: var(--sgs-text-muted);
}
.sgs-symed-close {
    flex-shrink: 0;
    padding: 0 2px;
    background: none;
    border: none;
    font-size: 14px;
    line-height: 1;
    color: var(--sgs-text-muted);
    cursor: pointer;
}
.sgs-symed-close:hover { color: var(--sgs-text); }
.sgs-symed-label {
    margin: var(--sgs-gap-sm) 0 4px;
    font-size: var(--sgs-font-micro);
    font-weight: 600;
    letter-spacing: 0.4px;
    text-transform: uppercase;
    color: var(--sgs-text-muted);
}
.sgs-symed-colorrow {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    margin-bottom: var(--sgs-gap-sm);
}
.sgs-symed-orow {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}
.sgs-symed-orow .sgs-style-slider { flex: 1; min-width: 0; }
.sgs-symed-orow .sgs-style-value { flex-shrink: 0; min-width: 32px; text-align: right; }
.sgs-symed-patches {
    max-height: 240px;
    overflow-y: auto;
}
.sgs-symed-patch { margin-bottom: var(--sgs-gap-sm); }
.sgs-symed-patch-head {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    margin-bottom: 2px;
}
.sgs-style-swatch--sm { width: 16px; height: 16px; }
.sgs-symed-patch-label {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--sgs-font-xs);
}
.sgs-symed-patch-clear {
    flex-shrink: 0;
    padding: 0 3px;
    background: none;
    border: none;
    font-size: 12px;
    line-height: 1;
    color: var(--sgs-text-muted);
    cursor: pointer;
}
.sgs-symed-patch-clear:hover { color: var(--sgs-text); }
/* A patch slider that INHERITS the layer opacity shows a muted fill until touched. */
.sgs-style-slider--inherit {
    --sgs-track: color-mix(in srgb, var(--sgs-border) 85%, transparent);
    opacity: 0.55;
}
.sgs-symed-reset {
    width: 100%;
    margin-top: var(--sgs-gap-sm);
    padding: 4px 8px;
    background: transparent;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text);
    cursor: pointer;
    transition: border-color 0.12s ease, color 0.12s ease;
}
.sgs-symed-reset:hover { border-color: var(--sgs-accent); color: var(--sgs-accent); }

/* ── Shared style primitives: jewel swatch + accent slider ─────────────────── */
/* Circular swatch: the chosen color sits inside a thin ring with a panel-colored
   gap, so it reads like a set stone rather than a default <input type=color>. */
.sgs-style-swatch {
    width: 26px;
    height: 26px;
    flex-shrink: 0;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: none;
    cursor: pointer;
    box-shadow: 0 0 0 1px var(--sgs-border), inset 0 0 0 2px var(--sgs-swatch-gap, #fff);
    transition: box-shadow 0.12s ease, transform 0.12s ease;
}
.sgs-style-swatch:hover {
    transform: scale(1.06);
    box-shadow: 0 0 0 1px var(--sgs-accent), inset 0 0 0 2px var(--sgs-swatch-gap, #fff);
}
.sgs-style-swatch::-webkit-color-swatch-wrapper { padding: 0; }
.sgs-style-swatch::-webkit-color-swatch { border: none; border-radius: 50%; }
.sgs-style-swatch::-moz-color-swatch { border: none; border-radius: 50%; }
.sgs-style-hex {
    font-size: var(--sgs-font-xs);
    font-variant-numeric: tabular-nums;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    color: var(--sgs-text-muted);
}

.sgs-style-value {
    font-size: var(--sgs-font-xs);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--sgs-text-muted);
    transition: color 0.12s ease;
}
.sgs-style-value--live { color: var(--sgs-accent); }

/* Accent-filled range. The track fill follows --val (0..1), updated live by JS. */
.sgs-style-slider {
    --val: 1;
    --sgs-track: color-mix(in srgb, var(--sgs-border) 85%, transparent);
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 16px;
    margin: 0;
    background: none;
    cursor: pointer;
}
.sgs-style-slider:focus-visible { outline: none; }
.sgs-style-slider::-webkit-slider-runnable-track {
    height: 4px;
    border-radius: 999px;
    background: linear-gradient(to right,
        var(--sgs-accent) calc(var(--val) * 100%),
        var(--sgs-track) calc(var(--val) * 100%));
}
.sgs-style-slider::-moz-range-track {
    height: 4px;
    border-radius: 999px;
    background: var(--sgs-track);
}
.sgs-style-slider::-moz-range-progress {
    height: 4px;
    border-radius: 999px;
    background: var(--sgs-accent);
}
.sgs-style-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 13px;
    height: 13px;
    margin-top: -4.5px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--sgs-accent);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.22);
    transition: transform 0.1s ease, box-shadow 0.1s ease;
}
.sgs-style-slider::-moz-range-thumb {
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid var(--sgs-accent);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.22);
}
.sgs-style-slider:active::-webkit-slider-thumb {
    transform: scale(1.18);
    box-shadow: 0 0 0 4px var(--sgs-accent-subtle);
}
.sgs-style-slider:active::-moz-range-thumb {
    box-shadow: 0 0 0 4px var(--sgs-accent-subtle);
}
/* (--sgs-panel-2 never existed; the fallback hex was an off-palette near-black) */
[data-theme="dark"] .sgs-symed { --sgs-swatch-gap: var(--sgs-surface-2); }
[data-theme="dark"] .sgs-style-slider::-webkit-slider-thumb { background: var(--sgs-text); }
[data-theme="dark"] .sgs-style-slider::-moz-range-thumb { background: var(--sgs-text); }

.sgs-edit-popover-field {
    display: flex;
    align-items: center;
    gap: 0;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text);
    padding: 3px 5px;
    cursor: pointer;
    border-radius: 3px;
    border: 1px solid rgba(0,0,0,0.08);
    margin-bottom: 1px;
    background: rgba(255,255,255,0.6);
    transition: background 0.1s, border-color 0.1s;
}
/* Dark: give each field its own defined grey chip (like a turned-off card) that sits a clear
   step ABOVE the popover instead of the near-invisible 0.035 wash — mirrors how the light-mode
   chip reads a touch lighter than its popover, so the fields contrast against the light card. */
[data-theme="dark"] .sgs-edit-popover-field {
    border-color: var(--sgs-border);
    background: var(--sgs-surface-2);
}
.sgs-edit-popover-field:hover {
    background: rgba(255,255,255,0.9);
    border-color: rgba(0,0,0,0.14);
}
[data-theme="dark"] .sgs-edit-popover-field:hover {
    background: color-mix(in srgb, var(--sgs-surface-2), #fff 9%);
    border-color: var(--sgs-border);
}
/* Rows where both P and F are off */
.sgs-edit-popover-field--inactive {
    background: rgba(0,0,0,0.025);
    opacity: 0.6;
}
[data-theme="dark"] .sgs-edit-popover-field--inactive {
    background: rgba(0,0,0,0.15);
    opacity: 0.55;
}
.sgs-edit-popover-field[draggable="true"] {
    cursor: grab;
}
.sgs-edit-field-drag {
    color: var(--sgs-text-micro);
    font-size: 10px;
    cursor: grab;
    user-select: none;
    opacity: 0.4;
    min-width: 8px;
    margin-right: 6px;
}
.sgs-edit-field-dragging {
    opacity: 0.4;
    background: var(--sgs-accent, #e65100) !important;
    border-color: var(--sgs-accent, #e65100) !important;
    border-radius: 3px;
}

/* ── Unified P/F field header ── */
.sgs-edit-field-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
}
.sgs-edit-field-modes {
    display: flex;
    align-items: center;
    gap: 2px;
}
.sgs-edit-field-mode {
    font-size: 9px;
    font-weight: 700;
    font-family: var(--sgs-font);
    width: 18px;
    height: 16px;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: 3px;
    background: transparent;
    color: var(--sgs-text-micro);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.12s, color 0.12s, border-color 0.12s;
    padding: 0;
}
.sgs-edit-field-mode:hover {
    background: rgba(0,0,0,0.06);
}
.sgs-edit-field-mode--active {
    background: var(--sgs-accent, #e65100);
    color: #fff;
    border-color: var(--sgs-accent, #e65100);
}
.sgs-edit-field-mode--active:hover {
    background: var(--sgs-accent, #e65100);
}
.sgs-edit-field-mode--coupled {
    background: var(--sgs-accent);
    color: #fff;
    border-color: var(--sgs-accent);
    opacity: 0.7;
}
.sgs-edit-field-mode--coupled:hover {
    opacity: 0.85;
}
[data-theme="dark"] .sgs-edit-field-mode--coupled {
    background: var(--sgs-accent);
    color: #fff;
    border-color: var(--sgs-accent);
    opacity: 0.7;
}
[data-theme="dark"] .sgs-edit-field-mode {
    border-color: rgba(255,255,255,0.2);
}
[data-theme="dark"] .sgs-edit-field-mode:hover {
    background: rgba(255,255,255,0.08);
}
.sgs-edit-field-link {
    width: 16px;
    height: 16px;
    border: none;
    background: transparent;
    color: var(--sgs-text-micro);
    opacity: 0.4;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 3px;
    padding: 0;
    margin-left: 2px;
    transition: opacity 0.12s, color 0.12s;
}
.sgs-edit-field-link:hover {
    opacity: 0.8;
}
.sgs-edit-field-link--active {
    opacity: 1;
    color: var(--sgs-accent, #e65100);
}

/* ── P/F per-field indicators ── */
.sgs-edit-field-ind {
    font-size: 8.5px;
    font-weight: 800;
    font-family: var(--sgs-font);
    width: 15px;
    height: 14px;
    border-radius: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    user-select: none;
    color: var(--sgs-text-micro);
    background: rgba(0,0,0,0.04);
    border: 1px solid rgba(0,0,0,0.1);
    transition: background 0.1s, color 0.1s, border-color 0.1s, box-shadow 0.1s;
    flex-shrink: 0;
    margin-right: 2px;
}
.sgs-edit-field-ind:hover {
    background: rgba(0,0,0,0.08);
    border-color: rgba(0,0,0,0.2);
}
/* "On" is a faint accent tint, not a solid accent slab — the solid blue read as too
   bold at this size (notebear 2026-07-07 n4/n5) */
.sgs-edit-field-ind--on {
    background: color-mix(in srgb, var(--sgs-accent) 14%, transparent);
    color: var(--sgs-accent);
    border-color: color-mix(in srgb, var(--sgs-accent) 45%, transparent);
    font-weight: 900;
}
.sgs-edit-field-ind--on:hover {
    background: color-mix(in srgb, var(--sgs-accent) 22%, transparent);
}
[data-theme="dark"] .sgs-edit-field-ind {
    background: rgba(255,255,255,0.06);
    border-color: rgba(255,255,255,0.15);
    color: rgba(255,255,255,0.35);
}
[data-theme="dark"] .sgs-edit-field-ind:hover {
    background: rgba(255,255,255,0.1);
}
[data-theme="dark"] .sgs-edit-field-ind--on {
    background: color-mix(in srgb, var(--sgs-accent) 20%, transparent);
    color: color-mix(in srgb, var(--sgs-accent) 70%, #fff);
    border-color: color-mix(in srgb, var(--sgs-accent) 55%, transparent);
    box-shadow: none;
}
.sgs-edit-field-ind--disabled {
    opacity: 0.25;
    pointer-events: none;
    cursor: default;
}
/* Compose field rows use the shared .sgs-field-badge/.sgs-field-name (issue #20). */

.sgs-edit-popover-field-list {
    max-height: 180px;
    overflow-y: auto;
    padding-right: 4px;
}

.sgs-edit-popover-note {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
    font-style: italic;
}

.sgs-edit-popover-close {
    display: block;
    width: 100%;
    margin-top: var(--sgs-gap-sm);
    padding: var(--sgs-gap-xs) 0;
    font-size: var(--sgs-font-xs);
    font-weight: 500;
    color: var(--sgs-accent);
    text-align: center;
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: background var(--sgs-transition);
}

.sgs-edit-popover-close:hover {
    background: var(--sgs-accent-subtle);
}

/* ── Unified fields panel — field-edit mode ──────────────────────────────── */

.sgs-filter-body.sgs-fields-panel--editing {
    background: #fafbfc;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md) var(--sgs-radius-md) 4px 4px;
    padding: var(--sgs-gap-sm) var(--sgs-gap-md);
    margin: var(--sgs-gap-xs) 0 0;
    box-shadow: var(--sgs-shadow-sm);
}
[data-theme="dark"] .sgs-filter-body.sgs-fields-panel--editing {
    background: #2a2e38;
    border-color: var(--sgs-border);
}
/* Hide read-mode content while in edit mode */
.sgs-fields-panel--editing .sgs-filter-section-values {
    display: none !important;
}
/* Gray chevrons in edit mode (not interactive) */
.sgs-fields-panel--editing .sgs-filter-chevron {
    opacity: 0.22;
    pointer-events: none;
}
/* Cap field list height and scroll beyond that */
.sgs-fields-panel--editing .sgs-edit-popover-field-list {
    max-height: 220px;
    overflow-y: auto;
    padding-right: 0;
}

/* Segmented control pill (F | 🔗 | P) */
.sgs-field-seg {
    display: flex;
    align-items: center;
    background: rgba(0,0,0,0.07);
    border-radius: 4px;
    padding: 2px;
    gap: 1px;
}
[data-theme="dark"] .sgs-field-seg {
    background: rgba(255,255,255,0.09);
}
.sgs-field-seg-opt {
    font-size: 9px;
    font-weight: 700;
    font-family: var(--sgs-font);
    padding: 2px 6px;
    border: none;
    background: transparent;
    color: var(--sgs-text-micro);
    cursor: pointer;
    border-radius: 3px;
    line-height: 1.3;
    transition: background 0.12s, color 0.12s;
    white-space: nowrap;
}
.sgs-field-seg-opt:hover {
    background: rgba(0,0,0,0.07);
    color: var(--sgs-text-secondary);
}
[data-theme="dark"] .sgs-field-seg-opt:hover {
    background: rgba(255,255,255,0.1);
}
.sgs-field-seg-opt--active {
    background: color-mix(in srgb, var(--sgs-accent) 16%, transparent);
    color: var(--sgs-accent);
}
.sgs-field-seg-opt--active:hover {
    background: color-mix(in srgb, var(--sgs-accent) 16%, transparent);
    color: var(--sgs-accent);
}
[data-theme="dark"] .sgs-field-seg-opt--active,
[data-theme="dark"] .sgs-field-seg-opt--active:hover {
    background: color-mix(in srgb, var(--sgs-accent) 24%, transparent);
    color: color-mix(in srgb, var(--sgs-accent) 70%, #fff);
}

/* Exclusion indicator in field-edit header */
.sgs-field-excl-ind {
    font-size: 9px;
    color: var(--sgs-text-micro);
    cursor: pointer;
    text-decoration: underline;
    text-decoration-style: dotted;
    text-underline-offset: 2px;
}
.sgs-field-excl-ind:hover {
    color: var(--sgs-text-secondary);
}



/* ============================================================
   14. SAVANT — AI features design system
   Water/liquid visual identity: blue-purple gradient shimmer.
   Distinguishes Savant UI from the existing blue accent (query-panel).
   ============================================================ */

/* ── Tokens ──────────────────────────────────────────────────── */
:root {
    --sgs-savant-start:    #6366f1;
    --sgs-savant-end:      #8b5cf6;
    --sgs-savant-glow:     rgba(99, 102, 241, 0.12);
    --sgs-savant-surface:  #f5f3ff;
    --sgs-savant-border:   rgba(99, 102, 241, 0.25);
    --sgs-savant-text:     #4338ca;
}
[data-theme="dark"] {
    --sgs-savant-start:    #818cf8;
    --sgs-savant-end:      #a78bfa;
    --sgs-savant-glow:     rgba(129, 140, 248, 0.10);
    --sgs-savant-surface:  #1e1b4b;
    --sgs-savant-border:   rgba(129, 140, 248, 0.20);
    --sgs-savant-text:     #c4b5fd;
}

/* ── Shimmer animation ───────────────────────────────────────── */
@keyframes sgs-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

@keyframes sgs-pulse-dot {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.5; }
}

/* ── Savant toolbar toggle ────────────────────────────────────── */
/* When active, tint only the SVG outline (like the Compose toggle) — the button patch
   keeps its normal background rather than filling blue. */
.sgs-toolbar-btn--savant.sgs-toolbar-btn--active {
    color: var(--sgs-savant-start);
    background: transparent;
}
.sgs-toolbar-btn--savant.sgs-toolbar-btn--active:hover {
    background: var(--sgs-surface-2);
}

/* ── Geogs mascot avatar + conversation switcher (Ask panel) ──── */
.sgs-savant-avatar {
    display: inline-flex;
    align-items: center;
    margin-right: 6px;
    flex-shrink: 0;
}
.sgs-savant-conv-bar {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 6px 12px;
    border-bottom: 1px solid var(--sgs-border-light);
    flex-shrink: 0;
}
.sgs-savant-conv-select {
    flex: 1;
    min-width: 0;
    font-size: 12px;
    padding: 3px 6px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    color: var(--sgs-text);
}
.sgs-savant-conv-btn {
    flex-shrink: 0;
    width: 24px;
    height: 24px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    color: var(--sgs-text-muted);
    cursor: pointer;
    font-size: 13px;
    line-height: 1;
}
.sgs-savant-conv-btn:hover { color: var(--sgs-text); border-color: var(--sgs-savant-start); }
.sgs-savant-conv-btn:disabled { opacity: 0.4; cursor: default; }
.sgs-savant-conv-btn--danger:hover:not(:disabled) { color: var(--sgs-danger); border-color: var(--sgs-danger); }

/* Active "Add layers" / "Find data" toggle state */
.sgs-savant-context-toggle--active {
    background: var(--sgs-savant-start);
    color: #fff;
    border-color: var(--sgs-savant-start);
}

/* Find-data view (AGOL search) — swaps in over the chat body */
.sgs-savant-find {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
    overflow: hidden;
}
.sgs-savant-find-head {
    flex-shrink: 0;
    padding: 6px 12px;
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-savant-find-back {
    background: none;
    border: none;
    color: var(--sgs-savant-start);
    cursor: pointer;
    font-size: 12px;
    padding: 0;
}
.sgs-savant-find-host {
    flex: 1;
    min-height: 0;
    overflow: auto;
    padding: 6px 12px;
}

/* Layer rows in pick mode: clickable to include in the Geogs conversation */
#layer-control.sgs-picking .sgs-layer-wrap { cursor: copy; }
#layer-control.sgs-picking .sgs-layer-row { outline: 1px dashed transparent; }
.sgs-layer-picked > .sgs-layer-row,
.sgs-layer-picked.sgs-layer-row {
    box-shadow: inset 3px 0 0 var(--sgs-savant-start);
}

/* ── Layer context chips (Ask panel) ─────────────────────────── */
.sgs-savant-context-area {
    padding: 6px 12px;
    border-bottom: 1px solid var(--sgs-border-light);
    flex-shrink: 0;
}
.sgs-savant-context-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
}
.sgs-savant-context-label {
    font-size: 11px;
    font-weight: 600;
    color: var(--sgs-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.sgs-savant-context-toggle {
    background: none;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    font-size: 11px;
    padding: 2px 6px;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: color var(--sgs-transition), border-color var(--sgs-transition);
}
.sgs-savant-context-toggle:hover {
    color: var(--sgs-savant-start);
    border-color: var(--sgs-savant-start);
}
.sgs-savant-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    min-height: 24px;
    align-items: center;
}
.sgs-savant-chips-placeholder {
    font-size: 11px;
    color: var(--sgs-text-muted);
    opacity: 0.7;
    font-style: italic;
}
.sgs-savant-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    background: var(--sgs-surface-2);
    border: 1px solid var(--sgs-border);
    border-radius: 12px;
    padding: 2px 8px;
    font-size: 11px;
    color: var(--sgs-text);
    max-width: 140px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-savant-chip--has-data {
    border-color: var(--sgs-savant-start);
    background: var(--sgs-savant-glow);
}
.sgs-savant-chip--stale {
    border-color: #d97706;
    background: rgba(217, 119, 6, 0.08);
    animation: sgs-pulse-stale 2s ease infinite;
}
.sgs-savant-chip--refreshing {
    opacity: 0.5;
    pointer-events: none;
}
.sgs-savant-chip-refresh {
    cursor: pointer;
    font-size: 12px;
    opacity: 0.7;
    flex-shrink: 0;
    margin-left: 2px;
}
.sgs-savant-chip-refresh:hover {
    opacity: 1;
    color: #d97706;
}
.sgs-savant-chip-remove {
    cursor: pointer;
    font-weight: bold;
    opacity: 0.5;
    font-size: 13px;
    flex-shrink: 0;
}
.sgs-savant-chip-remove:hover {
    opacity: 1;
    color: var(--sgs-error, #ef4444);
}

/* ── Savant panel base ───────────────────────────────────────── */
.sgs-savant-panel {
    position: fixed;
    z-index: 430;
    background: var(--sgs-bg);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow-lg);
    border: 1px solid var(--sgs-savant-border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    color: var(--sgs-text);
    font-size: var(--sgs-font-sm);
    cursor: grab;
    user-select: none;
    max-height: calc(100vh - 40px);
    min-width: 320px;
    max-width: calc(100vw - 32px);
    transition: border-color var(--sgs-transition-slow);
}
.sgs-savant-panel--ai {
    border-color: var(--sgs-savant-start);
    box-shadow: var(--sgs-shadow-lg), 0 0 20px var(--sgs-savant-glow);
}

/* ── Savant title bar ────────────────────────────────────────── */
.sgs-savant-titlebar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 12px;
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    color: #ffffff;
    cursor: move;
    user-select: none;
    font-weight: 600;
    font-size: 13px;
    flex-shrink: 0;
}
.sgs-savant-titlebar--basic {
    background: linear-gradient(135deg, var(--sgs-savant-start), color-mix(in srgb, var(--sgs-savant-end) 60%, #64748b));
    opacity: 0.85;
}
/* Geogs titlebar: the shimmer is a status light, not a permanent effect.
   It plays once when the window opens, then only while Geogs is responding
   (the --busy class, toggled around each turn). */
.sgs-savant-titlebar--ai {
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    background-size: 200% 200%;
    animation: sgs-shimmer 3s ease 1;
}
.sgs-savant-titlebar--busy {
    animation: sgs-shimmer 2.5s ease infinite;
}

.sgs-savant-titlebar-label {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.sgs-savant-close {
    color: rgba(255, 255, 255, 0.7);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    transition: color var(--sgs-transition);
    flex-shrink: 0;
}
.sgs-savant-close:hover {
    color: #ffffff;
}

/* Collapsible setup stack (conversation switcher + tier switch + layer context):
   hidden by default behind the title-bar pill so the chat + message box breathe. */
.sgs-savant-setup {
    flex-shrink: 0;
}
.sgs-savant-setup-toggle {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 8px;
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.12);
    color: rgba(255, 255, 255, 0.9);
    font-size: 11px;
    font-weight: 600;
    line-height: 1.4;
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-savant-setup-toggle:hover {
    background: rgba(255, 255, 255, 0.22);
    color: #ffffff;
}

/* ── Capability-tier switch (replaces persona tabs; ADR #33 / §3d) ───────────── */
.sgs-savant-tier-switch {
    display: flex;
    gap: 3px;
    padding: 6px 8px;
    /* --sgs-panel-bg was never defined (the fallback made this transparent);
       the panel canvas is the token this always meant. */
    background: var(--sgs-layer-canvas);
    border-bottom: 1px solid var(--sgs-border-light);
    flex-shrink: 0;
}

.sgs-savant-tier-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 26px;
    padding: 0 10px;
    border-radius: 999px;
    border: 1px solid var(--sgs-border-light);
    background: transparent;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    font-size: var(--sgs-font-xs, 11px);
    font-weight: 600;
    letter-spacing: 0.02em;
    user-select: none;
}
.sgs-savant-tier-btn svg { flex-shrink: 0; opacity: 0.85; pointer-events: none; }

.sgs-savant-tier-btn:hover {
    background: var(--sgs-hover-bg);
    color: var(--sgs-text-primary);
    border-color: var(--sgs-border);
}

/* Read-only tier active = calm Savant accent. */
.sgs-savant-tier-btn--active {
    background: var(--sgs-savant-glow, rgba(139, 92, 246, 0.15));
    color: var(--sgs-savant-start, #8b5cf6);
    border-color: color-mix(in srgb, var(--sgs-savant-start, #8b5cf6) 40%, transparent);
}
/* Document (writes to org) active = publish-green, to signal it can touch the org. */
.sgs-savant-tier-btn--write.sgs-savant-tier-btn--active {
    background: color-mix(in srgb, var(--sgs-publish-green, #16a34a) 14%, transparent);
    color: var(--sgs-publish-green, #16a34a);
    border-color: color-mix(in srgb, var(--sgs-publish-green, #16a34a) 45%, transparent);
}

/* ── Panel body / content area ───────────────────────────────── */
.sgs-savant-body {
    padding: 12px;
    overflow-y: auto;
    flex: 1;
    cursor: default;
    user-select: text;
}

/* ── Action buttons (Run Fundamentals / Run w/ AI) ───────────── */
.sgs-savant-actions {
    display: flex;
    gap: 8px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--sgs-border-light);
    flex-shrink: 0;
}

.sgs-savant-btn {
    padding: 5px 12px;
    border-radius: var(--sgs-radius-md);
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--sgs-transition), opacity var(--sgs-transition);
    border: 1px solid transparent;
}
.sgs-savant-btn--basic {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
    border-color: var(--sgs-border);
}
.sgs-savant-btn--basic:hover {
    background: var(--sgs-surface);
}
.sgs-savant-btn--ai {
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    color: #ffffff;
    border: none;
}
.sgs-savant-btn--ai:hover {
    opacity: 0.88;
}
.sgs-savant-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ── Summary cards row ───────────────────────────────────────── */
.sgs-savant-cards {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.sgs-savant-card {
    background: var(--sgs-surface);
    border-radius: var(--sgs-radius-md);
    padding: 8px 12px;
    min-width: 80px;
    text-align: center;
    border: 1px solid var(--sgs-border-light);
}
.sgs-savant-card-val {
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--sgs-savant-start);
}
.sgs-savant-card-lbl {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    margin-top: 2px;
}

/* ── Table summary (AI) ──────────────────────────────────────── */
.sgs-savant-table-summary {
    background: var(--sgs-savant-surface);
    border-left: 3px solid var(--sgs-savant-start);
    border-radius: var(--sgs-radius-md);
    padding: 10px 14px;
    margin-bottom: 12px;
    font-size: var(--sgs-font-sm);
    line-height: 1.6;
    color: var(--sgs-text);
    font-style: italic;
}

/* ── Column detail table ─────────────────────────────────────── */
.sgs-savant-table-wrap {
    border-radius: var(--sgs-radius-md);
    overflow: hidden;
    border: 1px solid var(--sgs-border-light);
}
.sgs-savant-table {
    border-collapse: collapse;
    width: 100%;
    font-size: var(--sgs-font-xs);
}
.sgs-savant-table th {
    background: var(--sgs-surface-2);
    color: var(--sgs-text-muted);
    padding: 6px 10px;
    text-align: left;
    font-weight: 600;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    position: sticky;
    top: 0;
    z-index: 1;
    border-bottom: 1px solid var(--sgs-border);
}
.sgs-savant-table td {
    padding: 5px 10px;
    border-bottom: 1px solid var(--sgs-border-light);
    vertical-align: top;
    word-break: break-word;
}
.sgs-savant-table tr:last-child td {
    border-bottom: none;
}
.sgs-savant-table tr:hover td {
    background: var(--sgs-savant-glow);
}

/* Flag row highlights */
.sgs-savant-table tr.sgs-row-unique td { border-left: 3px solid var(--sgs-savant-start); }
.sgs-savant-table tr.sgs-row-empty td  { border-left: 3px solid var(--sgs-danger); background: rgba(220,38,38,0.04); }
.sgs-savant-table tr.sgs-row-dupe td   { border-left: 3px solid #d97706; background: rgba(217,119,6,0.04); }

/* ── Dtype chips ─────────────────────────────────────────────── */
.sgs-dtype-chip {
    display: inline-block;
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.03em;
    font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
    min-width: 22px;
    text-align: center;
    margin-right: 4px;
    vertical-align: middle;
    cursor: default;
}
.sgs-dtype-chip.type-str   { background: #e0e7ff; color: #3730a3; }
.sgs-dtype-chip.type-int   { background: #d1fae5; color: #065f46; }
.sgs-dtype-chip.type-float { background: #cffafe; color: #155e75; }
.sgs-dtype-chip.type-date  { background: #ede9fe; color: #5b21b6; }
.sgs-dtype-chip.type-bool  { background: #fef3c7; color: #92400e; }
.sgs-dtype-chip.type-uid   { background: #f1f5f9; color: #475569; }
.sgs-dtype-chip.type-geom  { background: #dcfce7; color: #14532d; }
.sgs-dtype-chip.type-bin   { background: #fce7f3; color: #9d174d; }
.sgs-dtype-chip.type-unk   { background: #f8fafc; color: #94a3b8; }

/* Dark mode dtype overrides */
[data-theme="dark"] .sgs-dtype-chip.type-str   { background: #312e81; color: #c7d2fe; }
[data-theme="dark"] .sgs-dtype-chip.type-int   { background: #064e3b; color: #a7f3d0; }
[data-theme="dark"] .sgs-dtype-chip.type-float { background: #164e63; color: #a5f3fc; }


/* ============================================================
   14. SETTINGS PAGE (game-settings overlay)
   ============================================================ */

/* Shared overlay window (Settings, Welcome, future Account Pane) — see ui/overlay-window.js */
.sgs-window-overlay {
    position: fixed;
    inset: 0;
    z-index: 9999;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
}

.sgs-window {
    background: var(--sgs-bg);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow-lg);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}


.sgs-window-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--sgs-gap-xs) var(--sgs-gap-lg);
    border-bottom: 1px solid var(--sgs-border-light);
    gap: var(--sgs-gap-sm);
}
.sgs-window-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--sgs-text);
    flex: 1;
}

.sgs-window-close {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text-muted);
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-window-close:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}
.sgs-settings-dark-btn {
    font-size: 16px;
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-settings-dark-btn:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}
.sgs-settings-lock-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    border-radius: var(--sgs-radius-sm);
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-settings-lock-btn:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}
.sgs-settings-lock-btn--locked {
    color: var(--sgs-accent);
}
.sgs-settings-dark-icon {
    display: inline-block;
    transition: transform var(--sgs-transition);
}
.sgs-settings-dark-icon--moon {
    transform: rotate(30deg);
}

.sgs-settings-sep {
    height: 1px;
    background: var(--sgs-border-light);
    border-radius: 1px;
    margin: var(--sgs-gap-xs) 0;
}

/* Settings content lives inside the unified pane (ui/welcome.js Settings
   tab) — the pane provides scroll and outer padding */
.sgs-settings-content {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0 0;
}
@media (max-width: 600px) {
    .sgs-settings-content {
        grid-template-columns: 1fr;
    }
}

.sgs-settings-left {
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-lg);
    padding-right: var(--sgs-gap-lg);
}

.sgs-settings-left > .sgs-settings-section + .sgs-settings-section {
    padding-top: var(--sgs-gap-md);
    border-top: 1px solid var(--sgs-border-light);
}

.sgs-settings-right {
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-lg);
    padding-left: var(--sgs-gap-lg);
    border-left: 1px solid var(--sgs-border-light);
}

.sgs-settings-right > .sgs-settings-section + .sgs-settings-section {
    padding-top: var(--sgs-gap-md);
    border-top: 1px solid var(--sgs-border-light);
}

.sgs-settings-section {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.sgs-settings-section-title {
    margin: 0 0 var(--sgs-gap-sm) 0;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sgs-text-muted);
}

.sgs-settings-section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: var(--sgs-gap-sm);
}
.sgs-settings-section-header .sgs-settings-section-title {
    margin-bottom: 0;
}

.sgs-settings-toggle-all {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    cursor: pointer;
    padding: 0;
    border: none;
    background: none;
    opacity: 0.7;
    transition: opacity var(--sgs-transition), color var(--sgs-transition);
}
.sgs-settings-toggle-all:hover {
    opacity: 1;
    color: var(--sgs-text);
}

.sgs-toggle--sm {
    width: 30px;
    height: 16px;
}
.sgs-toggle--sm .sgs-toggle-slider::before {
    width: 12px;
    height: 12px;
}
.sgs-toggle--sm input:checked + .sgs-toggle-slider::before {
    transform: translateX(14px);
}

.sgs-settings-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sgs-gap-sm);
    padding: 4px 0;
    transition: background var(--sgs-transition);
}
.sgs-settings-row:hover {
    background: var(--sgs-surface);
    border-radius: var(--sgs-radius-sm);
    padding: 4px var(--sgs-gap-xs);
    margin: 0 calc(-1 * var(--sgs-gap-xs));
}

/* Locked by the active config (share recipient) — "set by this map" (ADR #25). */
.sgs-settings-row--locked {
    opacity: 0.55;
    cursor: not-allowed;
}
.sgs-settings-row--locked .sgs-settings-check {
    cursor: not-allowed;
}

/* Settings toggles use the app's selected checkbox style (see the checkbox-style variants),
   which is smaller than the old pill switch, so the rows read tighter. */
.sgs-settings-check {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    cursor: pointer;
    width: 22px;
    height: 18px;
}
.sgs-settings-check input[type="checkbox"] { margin: 0; cursor: pointer; }

.sgs-settings-row-label {
    font-size: var(--sgs-font-sm);
    font-weight: 500;
    color: var(--sgs-text);
}

/* Settings control clusters (theme, contrast, checkbox style, redshift) —
   replaced per-element cssText (R9 CSS-unity pass): one group + two button
   sizes across every row. */
.sgs-settings-btn-group {
    display: flex;
    gap: 6px;
    align-items: center;
}
.sgs-settings-iconbtn {
    width: 28px;
    height: 24px;
}
.sgs-settings-lvlbtn {
    padding: 2px 8px;
    font-size: 11px;
    min-width: 36px;
    line-height: 1;
}

.sgs-settings-select {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    padding: 2px 6px;
    cursor: pointer;
}
.sgs-settings-select:focus {
    outline: 1px solid var(--sgs-accent);
    outline-offset: -1px;
}

.sgs-settings-note {
    margin: calc(-1 * var(--sgs-gap-xs)) 0 var(--sgs-gap-sm) 0;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    font-style: italic;
    padding: 0;
}

/* ── Toggle switch ─────────────────────────────────────────── */

.sgs-toggle {
    position: relative;
    display: inline-block;
    width: 36px;
    height: 20px;
    flex-shrink: 0;
}

.sgs-toggle input {
    opacity: 0;
    width: 0;
    height: 0;
    position: absolute;
}

.sgs-toggle-slider {
    position: absolute;
    inset: 0;
    background: var(--sgs-border);
    border-radius: var(--sgs-radius-pill);
    transition: background var(--sgs-transition);
    cursor: pointer;
}

.sgs-toggle-slider::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 2px;
    width: 16px;
    height: 16px;
    background: white;
    border-radius: 50%;
    transition: transform var(--sgs-transition);
    box-shadow: var(--sgs-shadow-sm);
}

.sgs-toggle input:checked + .sgs-toggle-slider {
    background: var(--sgs-accent);
}

.sgs-toggle input:checked + .sgs-toggle-slider::before {
    transform: translateX(16px);
}

.sgs-toggle input:focus-visible + .sgs-toggle-slider {
    outline: 2px solid var(--sgs-accent);
    outline-offset: 2px;
}

/* ── Shortcuts ─────────────────────────────────────────────── */

.sgs-settings-shortcuts {
    display: flex;
    flex-direction: column;
    gap: 0;
    margin-top: var(--sgs-gap-xs);
}

.sgs-settings-shortcut-row {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    padding: 3px 0;
}

.sgs-settings-shortcut-row kbd {
    font-family: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
    font-size: 10px;
    background: var(--sgs-surface-2);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    padding: 1px 5px;
    min-width: 80px;
    text-align: center;
    color: var(--sgs-text);
}

.sgs-settings-shortcut-row span {
    font-size: 11px;
    color: var(--sgs-text-muted);
}

/* (.sgs-settings-shortcut-edit removed — no JS referenced it; per-row shortcut
   editing was never built and the table moved to the ? cheat sheet, n15) */

/* (.sgs-settings-shortcuts-link and .sgs-shortcuts-panel removed — the standalone
   cheat-sheet window retired, n5 2026-07-11: quick settings + the inline Settings
   table are the two shortcut surfaces now) */

/* ── Field exclusion pattern list ──────────────────────────── */

.sgs-settings-pattern-list {
    display: flex;
    flex-direction: column;
    gap: 0;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    padding: var(--sgs-gap-xs);
    max-height: 18vh;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
    background: color-mix(in srgb, var(--sgs-surface) 40%, transparent);
}

.sgs-settings-pattern-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 4px var(--sgs-gap-sm);
    border-radius: var(--sgs-radius-sm);
    transition: background var(--sgs-transition);
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-settings-pattern-row:last-child {
    border-bottom: none;
}
.sgs-settings-pattern-row:hover {
    background: var(--sgs-surface);
}

.sgs-settings-pattern-name {
    font-family: 'SF Mono', 'Cascadia Code', 'Consolas', monospace;
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text);
}

.sgs-settings-pattern-remove {
    font-size: 14px;
    color: var(--sgs-text-muted);
    cursor: pointer;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-settings-pattern-remove:hover {
    background: var(--sgs-danger-bg, #fef2f2);
    color: var(--sgs-danger, #dc2626);
}

.sgs-settings-pattern-add {
    display: flex;
    gap: var(--sgs-gap-sm);
    margin-top: var(--sgs-gap-sm);
}

.sgs-settings-pattern-input {
    flex: 1;
    font-size: var(--sgs-font-sm);
    padding: 4px 8px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    background: color-mix(in srgb, var(--sgs-surface) 40%, transparent);
    color: var(--sgs-text);
    text-transform: uppercase;
}
.sgs-settings-pattern-input::placeholder { color: var(--sgs-text-muted); }

.sgs-settings-pattern-add-btn {
    font-size: var(--sgs-font-sm);
    padding: 4px 10px;
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-accent);
    color: white;
    cursor: pointer;
    transition: opacity var(--sgs-transition);
}
.sgs-settings-pattern-add-btn:hover { opacity: 0.85; }

.sgs-settings-pattern-actions {
    display: flex;
    gap: var(--sgs-gap-md);
    margin-top: var(--sgs-gap-xs);
}

.sgs-settings-pattern-reset {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    cursor: pointer;
    padding: 2px 0;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.sgs-settings-pattern-reset:hover { color: var(--sgs-text); }
[data-theme="dark"] .sgs-dtype-chip.type-date  { background: #4c1d95; color: #ddd6fe; }
[data-theme="dark"] .sgs-dtype-chip.type-bool  { background: #78350f; color: #fde68a; }
[data-theme="dark"] .sgs-dtype-chip.type-uid   { background: #334155; color: #94a3b8; }
[data-theme="dark"] .sgs-dtype-chip.type-geom  { background: #14532d; color: #86efac; }
[data-theme="dark"] .sgs-dtype-chip.type-bin   { background: #831843; color: #fbcfe8; }

/* ── AI overview column ──────────────────────────────────────── */
.sgs-savant-ai-col {
    font-style: italic;
    color: var(--sgs-text-muted);
    font-size: 11px;
    line-height: 1.5;
}
.sgs-savant-ai-col ul {
    margin: 0;
    padding-left: 14px;
}
.sgs-savant-ai-col li {
    margin-bottom: 2px;
}
.sgs-savant-enum-values {
    font-style: normal;
    font-size: 11px;
    color: var(--sgs-text-muted);
    background: var(--sgs-savant-surface);
    border-radius: 3px;
    padding: 2px 6px;
    margin-top: 3px;
    display: block;
    line-height: 1.35;
    word-break: break-word;
}
.sgs-savant-enum-lead {
    font-weight: 700;
    font-style: italic;
    color: var(--sgs-text-muted);
    opacity: 0.75;
    margin-right: 2px;
}
.sgs-savant-enum-more {
    color: var(--sgs-text-muted);
    opacity: 0.6;
    font-size: 10px;
}

/* Field column discipline — keep FIELD from ballooning to fit example values;
   pin Nulls/Unique to compact fixed widths so the table reads cleanly. */
.sgs-savant-table td:first-child,
.sgs-savant-table th:first-child { width: auto; max-width: 240px; }
.sgs-savant-table td:nth-child(2),
.sgs-savant-table th:nth-child(2),
.sgs-savant-table td:nth-child(3),
.sgs-savant-table th:nth-child(3) { width: 64px; white-space: nowrap; }

/* ── Savant badge on layer rows ──────────────────────────────── */
.sgs-badge--savant {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    display: inline-block;
    margin-right: 4px;
    vertical-align: middle;
    cursor: pointer;
    transition: background var(--sgs-transition), box-shadow var(--sgs-transition);
}
.sgs-badge--savant[data-state="basic"] {
    background: var(--sgs-savant-start);
}
.sgs-badge--savant[data-state="ai"] {
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    box-shadow: 0 0 6px var(--sgs-savant-glow);
    animation: sgs-pulse-dot 2s ease-in-out infinite;
}

/* ── Skeleton loading ────────────────────────────────────────── */
.sgs-savant-skeleton {
    background: linear-gradient(90deg, var(--sgs-surface) 25%, var(--sgs-surface-2) 50%, var(--sgs-surface) 75%);
    background-size: 200% 100%;
    animation: sgs-shimmer 1.5s ease infinite;
    border-radius: var(--sgs-radius-sm);
    height: 14px;
    margin-bottom: 6px;
}
.sgs-savant-skeleton--wide  { width: 80%; }
.sgs-savant-skeleton--med   { width: 55%; }
.sgs-savant-skeleton--short { width: 30%; }

/* ── Feature count warning ───────────────────────────────────── */
.sgs-savant-warning {
    background: #fef3c7;
    border: 1px solid #f59e0b;
    border-radius: var(--sgs-radius-md);
    padding: 8px 12px;
    font-size: var(--sgs-font-xs);
    color: #92400e;
    margin-bottom: 10px;
}
[data-theme="dark"] .sgs-savant-warning {
    background: #451a03;
    border-color: #d97706;
    color: #fde68a;
}

/* ── PII consent banner ──────────────────────────────────────── */
.sgs-savant-pii-banner {
    background: var(--sgs-savant-surface);
    border: 1px solid var(--sgs-savant-border);
    border-radius: var(--sgs-radius-md);
    padding: 8px 12px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-savant-text);
    margin-bottom: 10px;
    display: flex;
    align-items: center;
    gap: 8px;
}
.sgs-savant-pii-banner button {
    padding: 3px 10px;
    border-radius: var(--sgs-radius-sm);
    font-size: 10px;
    font-weight: 600;
    background: var(--sgs-savant-start);
    color: #fff;
    cursor: pointer;
    flex-shrink: 0;
}

/* ── Ask panel (chat) ────────────────────────────────────────── */
.sgs-savant-chat {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 8px 0;
    max-height: 400px;
    overflow-y: auto;
}
.sgs-savant-msg {
    padding: 6px 10px;
    border-radius: var(--sgs-radius-md);
    font-size: var(--sgs-font-sm);
    line-height: 1.5;
    max-width: 85%;
    word-break: break-word;
}
.sgs-savant-msg--user {
    align-self: flex-end;
    background: var(--sgs-savant-start);
    color: #fff;
    border-bottom-right-radius: 2px;
}
.sgs-savant-msg--ai {
    align-self: flex-start;
    background: var(--sgs-savant-surface);
    color: var(--sgs-text);
    border-bottom-left-radius: 2px;
    border: 1px solid var(--sgs-savant-border);
}
.sgs-savant-msg--typing {
    opacity: 0.5;
    animation: sgs-pulse-dot 1.2s infinite;
}

.sgs-savant-input-row {
    display: flex;
    gap: 6px;
    padding: 8px 12px;
    border-top: 1px solid var(--sgs-border-light);
    flex-shrink: 0;
}
.sgs-savant-input {
    flex: 1;
    padding: 6px 10px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    font-size: var(--sgs-font-sm);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    outline: none;
    transition: border-color var(--sgs-transition);
}
.sgs-savant-input:focus {
    border-color: var(--sgs-savant-start);
}
.sgs-savant-send {
    padding: 6px 12px;
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    color: #fff;
    border-radius: var(--sgs-radius-md);
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    cursor: pointer;
}
.sgs-savant-send:hover {
    opacity: 0.88;
}

/* ── Error state ─────────────────────────────────────────────── */
.sgs-savant-error {
    background: rgba(220, 38, 38, 0.06);
    border: 1px solid var(--sgs-danger);
    border-radius: var(--sgs-radius-md);
    padding: 8px 12px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-danger);
}
.sgs-savant-error button {
    margin-top: 6px;
    padding: 3px 10px;
    border-radius: var(--sgs-radius-sm);
    font-size: 10px;
    font-weight: 600;
    background: var(--sgs-danger);
    color: #fff;
    cursor: pointer;
}

/* ── Info bar (token estimate) ───────────────────────────────── */
.sgs-savant-info-bar {
    font-size: 10px;
    color: var(--sgs-text-muted);
    padding: 4px 10px 2px;
    min-height: 14px;
    user-select: none;
}
.sgs-savant-info-bar--warn {
    color: #d97706;
    font-weight: 500;
}

/* ── Stale context pulse ─────────────────────────────────────── */
@keyframes sgs-pulse-stale {
    0%, 100% { border-color: #d97706; }
    50% { border-color: rgba(217, 119, 6, 0.4); }
}

/* ── Markdown in AI messages ─────────────────────────────────── */
.sgs-savant-msg--ai ul,
.sgs-savant-msg--ai ol {
    margin: 4px 0;
    padding-left: 18px;
}
.sgs-savant-msg--ai li {
    margin-bottom: 2px;
}
.sgs-savant-msg--ai p {
    margin: 4px 0;
}
.sgs-savant-msg--ai code {
    background: rgba(0, 0, 0, 0.06);
    padding: 1px 4px;
    border-radius: 3px;
    font-size: 11px;
    font-family: 'Cascadia Code', 'Fira Code', monospace;
}
[data-theme="dark"] .sgs-savant-msg--ai code {
    background: rgba(255, 255, 255, 0.08);
}
.sgs-savant-msg--ai pre {
    background: rgba(0, 0, 0, 0.04);
    border-radius: var(--sgs-radius-sm);
    padding: 8px 10px;
    overflow-x: auto;
    font-size: 11px;
    margin: 6px 0;
}
[data-theme="dark"] .sgs-savant-msg--ai pre {
    background: rgba(255, 255, 255, 0.05);
}
.sgs-savant-msg--ai strong {
    font-weight: 600;
}
.sgs-savant-msg--ai table {
    border-collapse: collapse;
    font-size: 10px;
    margin: 6px 0;
    width: 100%;
}
.sgs-savant-msg--ai th,
.sgs-savant-msg--ai td {
    border: 1px solid var(--sgs-border-light);
    padding: 3px 6px;
    text-align: left;
}
.sgs-savant-msg--ai th {
    background: rgba(0, 0, 0, 0.03);
    font-weight: 600;
}
[data-theme="dark"] .sgs-savant-msg--ai th {
    background: rgba(255, 255, 255, 0.04);
}

/* ── Savant filter action cards ──────────────────────────────── */
.sgs-savant-filter-action {
    margin: 8px 12px;
    padding: 8px 10px;
    border-radius: var(--sgs-radius-md);
    border: 1px solid var(--sgs-savant-start);
    background: var(--sgs-savant-glow);
    font-size: 11px;
}
.sgs-savant-filter-action--applied {
    opacity: 0.6;
    border-color: var(--sgs-success, #22c55e);
}
.sgs-savant-filter-action-label {
    font-family: 'Cascadia Code', 'Fira Code', monospace;
    font-size: 11px;
    margin-bottom: 4px;
    word-break: break-all;
}
.sgs-savant-filter-action-count {
    font-size: 10px;
    color: var(--sgs-text-muted);
    margin-bottom: 6px;
}
.sgs-savant-filter-action-buttons {
    display: flex;
    gap: 6px;
}
.sgs-savant-filter-apply {
    padding: 3px 10px;
    border-radius: var(--sgs-radius-sm);
    font-size: 10px;
    font-weight: 600;
    background: linear-gradient(135deg, var(--sgs-savant-start), var(--sgs-savant-end));
    color: #fff;
    cursor: pointer;
}
.sgs-savant-filter-apply:hover {
    opacity: 0.88;
}
.sgs-savant-filter-apply:disabled {
    opacity: 0.5;
    cursor: default;
}
.sgs-savant-filter-dismiss {
    padding: 3px 10px;
    border-radius: var(--sgs-radius-sm);
    font-size: 10px;
    background: transparent;
    border: 1px solid var(--sgs-border);
    color: var(--sgs-text-muted);
    cursor: pointer;
}
.sgs-savant-filter-dismiss:hover {
    border-color: var(--sgs-text);
    color: var(--sgs-text);
}

/* ==============================================================
   15. TOAST NOTIFICATIONS
   ============================================================== */

.sgs-toast {
    position: fixed;
    bottom: 24px;
    left: 50%;
    transform: translateX(-50%) translateY(20px);
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-md);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    border: 1px solid var(--sgs-border);
    border-radius: 8px;
    padding: 10px 20px;
    font-size: var(--sgs-font-base);
    box-shadow: var(--sgs-shadow);
    opacity: 0;
    transition: opacity 0.3s, transform 0.3s;
    z-index: 10000;
    pointer-events: none; /* a passing note never blocks the map */
}
.sgs-toast--visible {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}
/* ── Tooltip (tooltip.js) — the one hover bubble, both themes ──────────────
   Theme-matched surface (NOT inverted: a black bubble read as a dark-mode
   element inside the light theme, owner 2026-07-07). A bordered raised card,
   like the rest of the chrome; tokens keep it correct in both themes. */
.sgs-tooltip {
    position: fixed;
    z-index: 11000;
    max-width: 280px;
    padding: 5px 9px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface);
    color: var(--sgs-text);
    font-size: var(--sgs-font-xs);
    line-height: 1.45;
    box-shadow: var(--sgs-shadow-lg, var(--sgs-shadow));
    opacity: 0;
    pointer-events: none;
    transform: translateY(2px);
    transition: opacity 0.12s ease, transform 0.12s ease;
    white-space: pre-line;
}
.sgs-tooltip--visible {
    opacity: 1;
    transform: none;
}

/* Actionable variant: a real button (pointer cursor, hit target) — the plain
   toast stays click-through, only this variant accepts the pointer. */
.sgs-toast--action {
    pointer-events: auto;
    cursor: default;
}
.sgs-toast-btn {
    flex-shrink: 0;
    padding: 3px 10px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    color: var(--sgs-accent);
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--sgs-transition), border-color var(--sgs-transition);
}
.sgs-toast-btn:hover {
    background: var(--sgs-surface-hover);
    border-color: var(--sgs-accent);
}

/* ── Password Gate Overlay ─────────────────────────────────────────────────── */

.sgs-auth-overlay {
    position: fixed;
    inset: 0;
    z-index: 10001;
    background: var(--sgs-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.sgs-auth-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 40px;
    max-width: 360px;
    width: 90vw;
}

.sgs-auth-title {
    font-size: 16px;
    font-weight: 600;
    color: var(--sgs-text);
    margin: 0;
    text-align: center;
}

.sgs-auth-input {
    width: 100%;
    padding: 10px 14px;
    font-size: 14px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    outline: none;
    transition: border-color 0.15s;
}
.sgs-auth-input:focus {
    border-color: var(--sgs-accent);
}

.sgs-auth-error {
    font-size: 12px;
    color: var(--sgs-danger, #e53935);
    text-align: center;
}

.sgs-auth-btn {
    width: 100%;
    padding: 10px 0;
    font-size: 14px;
    font-weight: 600;
    border: none;
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-accent);
    color: white;
    cursor: pointer;
    transition: opacity 0.15s;
}
.sgs-auth-btn:hover { opacity: 0.9; }
.sgs-auth-btn:disabled { opacity: 0.5; cursor: not-allowed; }

@keyframes sgs-auth-shake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-6px); }
    40%, 80% { transform: translateX(6px); }
}
.sgs-auth-shake {
    animation: sgs-auth-shake 0.4s ease;
}

/* ── Share Dialog ──────────────────────────────────────────────────────────── */

.sgs-share-overlay {
    position: fixed;
    inset: 0;
    z-index: 9998;
    background: rgba(0, 0, 0, 0.6);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(2px);
}
/* Quick-reference sheets (shortcuts) summoned from inside another window stack
   above the window overlays (9999) but below the tooltip (11000). */
.sgs-share-overlay--top { z-index: 10500; }

.sgs-share-panel {
    background: var(--sgs-bg);
    border-radius: var(--sgs-radius-lg);
    box-shadow: var(--sgs-shadow-lg);
    width: min(560px, 92vw);
    max-height: 88vh;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.sgs-share-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 16px;
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-share-title {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-share-close {
    background: none;
    border: none;
    font-size: 20px;
    color: var(--sgs-text-muted);
    cursor: pointer;
    line-height: 1;
}
.sgs-share-close:hover { color: var(--sgs-text); }

.sgs-share-body {
    flex: 1;
    overflow-y: auto;
    padding: 12px 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* ── Share window (ADR #26): unified .sgs-window chrome + these variant bits ── */
/* Narrower than the old 560px — the window kept reading wider than its content
   (n24/n25 2026-07-11). */
.sgs-share { width: min(480px, 92vw); }
.sgs-share-intro {
    margin: 0;
    padding: 8px 10px;
    background: var(--sgs-surface);
    border-radius: var(--sgs-radius-md);
    font-size: 12px;
    color: var(--sgs-text-muted);
    line-height: 1.4;
}
.sgs-share-mode {
    padding: 12px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
}
.sgs-share-restricted-form {
    display: flex;
    flex-direction: column;
    gap: 14px;
    margin-top: 10px;
}
.sgs-share-advanced {
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    padding: 8px 10px;
}
.sgs-share-advanced > summary {
    cursor: pointer;
    font-size: 12px;
    font-weight: 600;
    color: var(--sgs-text);
}

/* ── Save dialog (three-section save) ──────────────────────────────────── */
.sgs-save-panel { max-width: 420px; }
/* First-save required sections read as grayed-out givens, not choices (n30). */
.sgs-save-row--forced { opacity: 0.55; }
.sgs-save-row--forced input[type="checkbox"] { cursor: default; }
/* Inline affordance icons inside hint copy (n21/n22) sit on the text baseline. */
.sgs-fieldhint-icon svg { vertical-align: -2px; }
.sgs-save-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 12px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius, 8px);
    cursor: pointer;
}
.sgs-save-row input[type="checkbox"] { margin-top: 2px; flex: none; }
.sgs-save-row input:disabled { cursor: not-allowed; }
.sgs-save-row-text { display: flex; flex-direction: column; gap: 2px; }
.sgs-save-row-label { font-size: 13px; font-weight: 600; }
.sgs-save-row-desc { font-size: 11px; color: var(--sgs-text-muted, #6b7280); }

/* App-row disclosure: exactly what the app: block would write */
.sgs-save-app-detail summary {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-accent);
    cursor: pointer;
    user-select: none;
    width: fit-content;
}
.sgs-save-app-list {
    margin-top: 4px;
    max-height: 120px;
    overflow-y: auto;
    padding: 6px 8px;
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface);
    font-size: var(--sgs-font-xs);
    font-family: ui-monospace, 'Cascadia Mono', Consolas, monospace;
    color: var(--sgs-text-muted);
}
/* Long values (excludedFieldPatterns and friends) wrap instead of overrunning the dialog. */
.sgs-save-app-list div {
    overflow-wrap: anywhere;
}
/* A page's own icon inline in prose, in parentheses: "the Settings (gear) page". */
.sgs-desc-icon svg {
    width: 11px;
    height: 11px;
    vertical-align: -1.5px;
    margin: 0 1px;
}
.sgs-save-hint {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
}

/* First-add field-config hint (n23) — a small real window, not a toast */
.sgs-fieldhint-panel { max-width: 380px; }
.sgs-fieldhint-text {
    margin: 0;
    font-size: var(--sgs-font-base);
    color: var(--sgs-text);
    line-height: 1.5;
}
.sgs-fieldhint-dont {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: var(--sgs-gap-sm);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    cursor: pointer;
    user-select: none;
}

/* ── Cloud-cap prompt (contextual, at the save that hits the tier limit) ── */
.sgs-cloudcap-panel { max-width: 440px; }
.sgs-cloudcap-lead {
    margin: 0;
    font-size: 13px;
    line-height: 1.5;
    color: var(--sgs-text, #1f2937);
}

.sgs-share-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sgs-share-section-title {
    margin: 0;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--sgs-text-muted);
}

.sgs-share-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    font-size: 13px;
    color: var(--sgs-text);
    min-height: 28px;
}
.sgs-share-row--col {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}

.sgs-share-input {
    padding: 5px 8px;
    font-size: 12px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    outline: none;
    width: 100%;
}
.sgs-share-input:focus { border-color: var(--sgs-accent); }
.sgs-share-input--sm { width: auto; min-width: 84px; }

/* Selects share the input treatment plus a real affordance (n17): no OS chrome,
   our own chevron, pointer cursor, themed in both modes. */
select.sgs-share-input {
    appearance: none;
    -webkit-appearance: none;
    padding-right: 22px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='10' height='10' fill='none' stroke='%23888' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'><path d='M4 6l4 4 4-4'/></svg>");
    background-repeat: no-repeat;
    background-position: right 7px center;
    cursor: pointer;
    transition: border-color var(--sgs-transition);
}
select.sgs-share-input:hover { border-color: var(--sgs-accent); }

.sgs-share-btn-sm {
    font-size: 11px;
    padding: 3px 8px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    cursor: pointer;
}
.sgs-share-btn-sm:hover { border-color: var(--sgs-accent); }

.sgs-share-bbox-display {
    font-size: 11px;
    color: var(--sgs-text-muted);
}

/* "Your restricted shares" — the local ledger of links this device published */
.sgs-share-mine {
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-xs);
}
.sgs-share-mine-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sgs-gap-sm);
    padding: 6px 8px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-surface-mid);
}
.sgs-share-mine-text {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.sgs-share-mine-name {
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-share-mine-meta {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
}
.sgs-share-mine-actions {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    flex-shrink: 0;
}
.sgs-share-mine-forget {
    color: var(--sgs-text-muted);
}
.sgs-share-mine-forget:hover {
    color: var(--sgs-danger);
    border-color: var(--sgs-danger);
}

.sgs-share-layer-block {
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sgs-share-layer-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 13px;
    font-weight: 500;
    color: var(--sgs-text);
}
/* (.sgs-share-type-badge removed — the share panel reuses the layer list's
   .sgs-source-pill vocabulary now, n21) */
.sgs-share-field-label {
    font-size: 11px;
    color: var(--sgs-text-muted);
    min-width: 100px;
}
.sgs-share-note {
    font-size: 10px;
    color: var(--sgs-text-muted);
    font-style: italic;
    line-height: 1.3;
}

.sgs-share-footer {
    padding: 10px 16px;
    border-top: 1px solid var(--sgs-border-light);
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
}
.sgs-share-error {
    font-size: 12px;
    color: var(--sgs-danger, #e53935);
    flex: 1;
}
.sgs-share-create-btn {
    padding: 8px 16px;
    font-size: 13px;
    font-weight: 600;
    border: none;
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-accent);
    color: white;
    cursor: pointer;
    transition: opacity 0.15s;
}
.sgs-share-create-btn:hover { opacity: 0.9; }
.sgs-share-create-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── Redshift Overlay ──────────────────────────────────────────────────────── */

.sgs-redshift-overlay {
    position: fixed;
    inset: 0;
    pointer-events: none;
    z-index: 99999;
}

.sgs-redshift-slider {
    -webkit-appearance: none;
    appearance: none;
    width: 110px;
    height: 4px;
    border-radius: 2px;
    background: var(--sgs-border);
    outline: none;
    cursor: pointer;
}
.sgs-redshift-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background: var(--sgs-accent);
    cursor: pointer;
}
.sgs-redshift-slider::-moz-range-thumb {
    width: 14px;
    height: 14px;
    border-radius: 50%;
    border: none;
    background: var(--sgs-accent);
    cursor: pointer;
}

.sgs-redshift-value {
    min-width: 32px;
    text-align: right;
    font-size: 11px;
    color: var(--sgs-text-muted);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Welcome window & onboarding — ui/welcome.js, ui/onboarding-callouts.js
   ═══════════════════════════════════════════════════════════════════════════ */

/* Overlay: heavier blur than Settings — the live map is the backdrop */
.sgs-welcome-overlay {
    background: rgba(15, 18, 28, 0.45);
    backdrop-filter: blur(6px);
    animation: sgs-welcome-overlay-in 0.35s ease-out;
}
.sgs-welcome-overlay--closing {
    transition: background 0.38s ease, backdrop-filter 0.38s ease;
    background: rgba(15, 18, 28, 0);
    backdrop-filter: blur(0px);
}
@keyframes sgs-welcome-overlay-in {
    from { background: rgba(15, 18, 28, 0); backdrop-filter: blur(0px); }
}

.sgs-welcome {
    width: min(900px, 94vw);
    height: min(620px, 88vh);
    animation: sgs-welcome-enter 0.45s cubic-bezier(0.16, 1, 0.3, 1);
}
@keyframes sgs-welcome-enter {
    from { opacity: 0; transform: translateY(16px) scale(0.96); }
    to   { opacity: 1; transform: none; }
}

.sgs-welcome-brand {
    font-size: 15px;
    font-weight: 700;
    letter-spacing: 0.01em;
}
.sgs-welcome-brand-dot { color: var(--sgs-accent); }

/* ── Body: nav rail + content ── */
.sgs-welcome-body {
    flex: 1;
    min-height: 0;
    display: flex;
}

.sgs-welcome-nav {
    width: 148px;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: var(--sgs-gap-md) var(--sgs-gap-sm);
    border-right: 1px solid var(--sgs-border-light);
}
.sgs-welcome-nav-btn {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 10px;
    border-radius: var(--sgs-radius-sm);
    font-size: 12.5px;
    color: var(--sgs-text-muted);
    text-align: left;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-welcome-nav-btn:hover {
    background: var(--sgs-surface-2);
    color: var(--sgs-text);
}
.sgs-welcome-nav-btn--active {
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-weight: 600;
}
.sgs-welcome-nav-icon {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.sgs-welcome-content {
    flex: 1;
    min-width: 0;
    overflow-y: auto;
    padding: var(--sgs-gap-xl);
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
    /* Positioning context for the account "expand to fill" mode, so a fullscreened section fills
       the content area only and never covers the left nav. */
    position: relative;
}

/* ── Footer CTA bar (every tab) ── */
.sgs-welcome-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--sgs-gap-md);
    padding: var(--sgs-gap-sm) var(--sgs-gap-lg);
    border-top: 1px solid var(--sgs-border-light);
}
.sgs-welcome-footer-hint {
    font-size: 11.5px;
    color: var(--sgs-text-muted);
}
.sgs-welcome-cta {
    flex-shrink: 0;
    padding: 9px 20px;
    border-radius: var(--sgs-radius-pill);
    background: var(--sgs-accent);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    box-shadow: var(--sgs-shadow-sm);
    transition: background var(--sgs-transition), transform var(--sgs-transition);
}
.sgs-welcome-cta:hover {
    background: var(--sgs-accent-hover);
    transform: translateY(-1px);
}

/* ── Tab shells ── */
.sgs-welcome-tab-title {
    margin: 0 0 var(--sgs-gap-sm);
    font-size: 18px;
    font-weight: 700;
    color: var(--sgs-text);
    letter-spacing: -0.01em;
}
.sgs-welcome-copy {
    margin: 0 0 var(--sgs-gap-sm);
    font-size: 13px;
    line-height: 1.55;
    color: var(--sgs-text);
    max-width: 56ch;
}
.sgs-welcome-copy--muted { color: var(--sgs-text-muted); font-size: 12px; }
/* The Data-sources tab has no narrow marketing column, so its copy may run the full width. */
.sgs-ds-tab .sgs-welcome-copy { max-width: none; }
/* Exception: the monitor's intro sentence reads better narrow and contained, like body copy. */
.sgs-ds-measure .sgs-welcome-copy { max-width: 56ch; }
.sgs-welcome-copy a { color: var(--sgs-accent); text-decoration: none; }
.sgs-welcome-copy a:hover { text-decoration: underline; }

/* ── Sign In tab ── */
.sgs-welcome-signin-error {
    margin: 0 0 var(--sgs-gap-sm);
    font-size: 12px;
    color: var(--sgs-danger);
}
.sgs-welcome-acct-guide {
    margin: var(--sgs-gap-md) 0;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    overflow: hidden;
    max-width: 480px;
}
.sgs-welcome-acct-row {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 10px 12px;
}
.sgs-welcome-acct-row + .sgs-welcome-acct-row {
    border-top: 1px solid var(--sgs-border-light);
}
.sgs-welcome-acct-row strong { font-size: 12.5px; color: var(--sgs-text); }
.sgs-welcome-acct-row span { font-size: 12px; color: var(--sgs-text-muted); }
.sgs-welcome-acct-row a {
    font-size: 12px;
    color: var(--sgs-accent);
    text-decoration: none;
    width: fit-content;
}
.sgs-welcome-acct-row a:hover { text-decoration: underline; }
.sgs-welcome-acct-row .sgs-acct-row-paid { font-style: italic; }

/* Signed-out provider picker: equal-weight peers (identity-first). All three establish the
   same Sleek account; ArcGIS carries a data sublabel + a subtle accent, not a bigger button. */
.sgs-signin-providers {
    display: flex;
    flex-direction: column;
    gap: var(--sgs-gap-sm);
    margin: var(--sgs-gap-md) 0 var(--sgs-gap-sm);
    max-width: 360px;
}
.sgs-signin-provider {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 10px 14px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface);
    color: var(--sgs-text);
    text-align: left;
    transition: border-color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-signin-provider:hover { border-color: var(--sgs-accent); background: var(--sgs-accent-subtle); }
.sgs-signin-provider:disabled { opacity: 0.6; cursor: wait; }
.sgs-signin-provider-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.sgs-signin-provider-logo { display: flex; align-items: center; flex: 0 0 auto; line-height: 0; }
.sgs-signin-provider-label { font-size: 13.5px; font-weight: 600; }
.sgs-signin-provider-sub { font-size: 11.5px; font-weight: 400; color: var(--sgs-text-muted); }

/* "Learn more about ArcGIS…" — progressive disclosure, ArcGIS-path help only. */
.sgs-signin-guide { margin: var(--sgs-gap-sm) 0; max-width: 480px; }
.sgs-signin-guide > .sgs-welcome-copy { margin-top: var(--sgs-gap-xs); }
.sgs-signin-guide > summary {
    cursor: pointer;
    list-style: none;
    padding: 4px 0;
    font-size: 12.5px;
    font-style: italic;
    color: var(--sgs-text-muted);
    user-select: none;
}
.sgs-signin-guide > summary::-webkit-details-marker { display: none; }
.sgs-signin-guide > summary::before { content: '\25b8\00a0'; }
.sgs-signin-guide[open] > summary::before { content: '\25be\00a0'; }
.sgs-signin-guide > summary:hover { color: var(--sgs-text); }
.sgs-signin-guide .sgs-welcome-acct-guide { margin-top: var(--sgs-gap-xs); }
.sgs-signin-guide-create { margin-top: var(--sgs-gap-sm); font-size: 12.5px; }

/* ── Pricing tab ── */
.sgs-price-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: var(--sgs-gap-md);
    margin-top: var(--sgs-gap-md);
}
.sgs-price-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--sgs-gap-md);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-lg);
    background: var(--sgs-surface);
    /* Shorter floor since detail collapsed behind a disclosure (n14); the flex:1
       bullets list absorbs the slack and keeps the CTA pinned low. */
    min-height: 300px;
}
.sgs-price-card--featured {
    border-color: var(--sgs-accent);
    box-shadow: var(--sgs-shadow);
}
.sgs-price-card--soon {
    border-style: dashed;
    opacity: 0.72;
}
.sgs-price-flag {
    position: absolute;
    top: -9px;
    left: 12px;
    padding: 1px 8px;
    border-radius: var(--sgs-radius-pill);
    background: var(--sgs-accent);
    color: #fff;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
}
.sgs-price-name {
    font-size: 13px;
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-price-amount {
    font-size: 22px;
    font-weight: 700;
    color: var(--sgs-text);
    margin: 2px 0;
}
.sgs-price-amount small {
    font-size: 11px;
    font-weight: 400;
    color: var(--sgs-text-muted);
}
.sgs-price-card--soon .sgs-price-amount { font-size: 15px; }
.sgs-price-tagline {
    font-size: 11.5px;
    color: var(--sgs-text-muted);
    margin-bottom: var(--sgs-gap-sm);
}
.sgs-price-bullets {
    flex: 1;
    margin: 0 0 var(--sgs-gap-md);
    padding-left: 16px;
    font-size: 12px;
    line-height: 1.55;
    color: var(--sgs-text);
}
/* Collapsed per-tier detail (n14): short face, one gesture to the rest */
.sgs-price-more {
    margin: 0 0 var(--sgs-gap-sm);
}
.sgs-price-more summary {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-accent);
    cursor: pointer;
    user-select: none;
    width: fit-content;
}
.sgs-price-bullets--detail {
    flex: none;
    margin: var(--sgs-gap-xs) 0 0;
    color: var(--sgs-text-muted);
}
.sgs-price-foot {
    margin: var(--sgs-gap-sm) 0 0;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
}
.sgs-price-foot-link {
    padding: 0;
    border: none;
    background: none;
    font-size: inherit;
    color: var(--sgs-text-muted);
    text-decoration: underline;
    cursor: pointer;
}
.sgs-price-foot-link:hover { color: var(--sgs-accent); }

/* Pricing glossary: one details per concept the cards name (Geogs AI, cloud
   share, secure sharing), nested where a term lives inside another. */
.sgs-price-explain {
    margin-top: var(--sgs-gap-lg);
    border-top: 1px solid var(--sgs-border-light);
    padding-top: var(--sgs-gap-sm);
}
.sgs-price-explain-item > summary {
    cursor: pointer;
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    padding: var(--sgs-gap-xs) 0;
    color: var(--sgs-text);
}
.sgs-price-explain-body {
    padding: 0 0 var(--sgs-gap-sm) var(--sgs-gap-md);
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
    line-height: 1.55;
}
.sgs-price-explain-body p { margin: 0 0 var(--sgs-gap-xs); }
.sgs-price-explain-item--nested { margin-top: var(--sgs-gap-xs); }
.sgs-price-explain-item--nested > summary { font-weight: 500; }

/* ── Terms of Service window (terms.js) ─────────────────────────── */
.sgs-terms {
    width: min(560px, 92vw);
    max-height: 80vh;
    display: flex;
    flex-direction: column;
}
.sgs-terms-body {
    overflow-y: auto;
    padding: 0 var(--sgs-gap-lg) var(--sgs-gap-lg);
}
.sgs-terms-effective {
    margin: 0 0 var(--sgs-gap-md);
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
}
.sgs-terms-h {
    margin: var(--sgs-gap-md) 0 var(--sgs-gap-xs);
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-terms-p {
    margin: 0;
    font-size: var(--sgs-font-sm);
    line-height: 1.55;
    color: var(--sgs-text-muted);
}

/* ── Welcome (home) tab: hero + chips + mission + sustainability ── */
.sgs-home-hero { margin-bottom: var(--sgs-gap-md); }
.sgs-home-tagline {
    margin: 0 0 2px;
    font-size: 19px;
    font-weight: 650;
    line-height: 1.3;
    color: var(--sgs-text);
}
.sgs-home-brand {
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    letter-spacing: 0.4px;
    color: var(--sgs-text-micro);
    text-transform: uppercase;
}
.sgs-home-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--sgs-gap-sm);
    margin: var(--sgs-gap-md) 0;
}
.sgs-home-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border: 1px solid var(--sgs-border);
    border-radius: 999px;
    background: var(--sgs-surface);
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    color: var(--sgs-text-muted);
}
button.sgs-home-chip { cursor: pointer; }
button.sgs-home-chip:hover { color: var(--sgs-text); border-color: var(--sgs-text-muted); }
.sgs-home-chip--green { color: #3a9d5d; border-color: color-mix(in srgb, #3a9d5d 45%, var(--sgs-border)); }
button.sgs-home-chip--green:hover { color: #2f8a4e; border-color: #3a9d5d; }
[data-theme="dark"] .sgs-home-chip--green { color: #5cc281; }
[data-theme="dark"] button.sgs-home-chip--green:hover { color: #74d495; border-color: #5cc281; }
.sgs-home-mission { max-width: 560px; }
.sgs-home-sustain { margin-top: var(--sgs-gap-md); max-width: 560px; }
.sgs-home-sustain > summary {
    cursor: pointer;
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    padding: var(--sgs-gap-xs) 0;
}

.sgs-price-cta {
    padding: 7px 12px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    font-size: 12px;
    font-weight: 600;
    color: var(--sgs-text);
    background: transparent;
    transition: background var(--sgs-transition), border-color var(--sgs-transition);
}
.sgs-price-cta:hover:not(:disabled) {
    border-color: var(--sgs-accent);
    color: var(--sgs-accent);
}
.sgs-price-card--featured .sgs-price-cta { border-color: var(--sgs-accent); color: var(--sgs-accent); }
.sgs-price-cta:disabled { opacity: 0.55; cursor: default; }

/* ── Geogs character idle animations ── */
.sgs-geogs { overflow: visible; }
.sgs-geogs-eye {
    transform-box: fill-box;
    transform-origin: center;
    animation: sgs-geogs-blink 5.4s infinite;
}
@keyframes sgs-geogs-blink {
    0%, 92%, 100% { transform: scaleY(1); }
    95%, 97%      { transform: scaleY(0.08); }
}
.sgs-geogs-cloud {
    transform-box: fill-box;
    transform-origin: center;
    animation: sgs-geogs-drift 7s ease-in-out infinite;
}
.sgs-geogs-cloud--small {
    animation-duration: 9s;
    animation-delay: 1.2s;
}
@keyframes sgs-geogs-drift {
    0%, 100% { transform: translateX(0); }
    50%      { transform: translateX(3px); }
}

/* ── Onboarding hint callouts ── */
.sgs-callout {
    position: fixed;
    z-index: 9500;
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: 250px;
    padding: 8px 10px 8px 13px;
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-accent);
    color: #fff;
    font-size: 12px;
    line-height: 1.4;
    box-shadow: var(--sgs-shadow);
    opacity: 0;
    transform: translateY(-50%) translateX(-6px);
    transition: opacity 0.25s ease-out, transform 0.25s ease-out;
}
.sgs-callout--visible {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}
.sgs-callout--leaving {
    opacity: 0;
    transform: translateY(-50%) translateX(-6px);
}
.sgs-callout-arrow {
    position: absolute;
    left: -5px;
    top: 50%;
    transform: translateY(-50%) rotate(45deg);
    width: 10px;
    height: 10px;
    background: var(--sgs-accent);
    border-radius: 2px;
}
.sgs-callout-close {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    color: rgba(255, 255, 255, 0.85);
    font-size: 14px;
    line-height: 1;
    transition: background var(--sgs-transition);
}
.sgs-callout-close:hover {
    background: rgba(255, 255, 255, 0.2);
    color: #fff;
}

/* ── Nav rail: Settings anchors the bottom ── */
.sgs-welcome-nav-spacer {
    flex: 1;
    min-height: var(--sgs-gap-md);
}
/* Settings still anchors the bottom via the spacer, but without a divider line above it
   (no other nav entry has one). */
.sgs-welcome-nav .sgs-welcome-nav-spacer + .sgs-welcome-nav-btn {
    border-radius: 0 0 var(--sgs-radius-sm) var(--sgs-radius-sm);
}

/* ── Footer: "Don't show at startup" ── */
.sgs-welcome-hide-opt {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 11.5px;
    color: var(--sgs-text-muted);
    cursor: pointer;
    flex-shrink: 0;
    user-select: none;
}
.sgs-welcome-hide-opt input {
    accent-color: var(--sgs-accent);
    margin: 0;
}

/* ── Settings tab (migrated settings page) ── */
.sgs-welcome-settings-titlerow {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    margin-bottom: var(--sgs-gap-md);
}
.sgs-welcome-settings-titlerow .sgs-welcome-tab-title {
    margin: 0;
}

/* ── Account tab ── */
.sgs-account-card {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-md);
    padding: var(--sgs-gap-md);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-lg);
    background: var(--sgs-surface);
    /* Narrow and contained, matching the About-page body copy width (56ch) rather than running
       the full window. The AGOL table below has its own fullscreen expand when it needs room. */
    max-width: 56ch;
    margin-bottom: var(--sgs-gap-md);
}
/* Federated signed-in card: pinned to the 360px Connect-ArcGIS column below it (notebear n10). */
.sgs-account-card--narrow { max-width: 360px; }
/* Provider brand mark on the "Signed in with X" connection line. */
.sgs-account-conn-badge {
    display: inline-flex;
    align-items: center;
    line-height: 0;
    margin-right: 5px;
}
.sgs-account-conn-badge img,
.sgs-account-conn-badge svg { width: 13px; height: 13px; border-radius: 2px; }
.sgs-account-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-size: 16px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    flex-shrink: 0;
}
.sgs-account-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.sgs-account-info { flex: 1; min-width: 0; }
.sgs-account-name {
    font-size: 14px;
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-account-user {
    font-size: 12px;
    color: var(--sgs-text-muted);
}
.sgs-account-conn {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 4px;
    font-size: 11.5px;
    color: var(--sgs-text-muted);
}
/* The account pane has no right-hand pricing rail (unlike the home tab), so it may use the
   full content width instead of the narrow marketing column. */
.sgs-welcome-tab--account { max-width: 820px; }
.sgs-account-section {
    margin-bottom: var(--sgs-gap-lg);
    max-width: 820px;
}
/* Expand-to-fill toggle sits at the far right of the table's controls row (in line with Scope). */
.sgs-ot-expand {
    margin-left: auto;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--sgs-radius-sm);
    font-size: 15px;
    line-height: 1;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-ot-expand:hover { background: var(--sgs-surface-2); color: var(--sgs-text); }
/* Fullscreen: JUST the table + its Group by / Scope controls fill the content area (never the
   left nav, whose offset parent is .sgs-welcome-content). Scrolls internally. */
.sgs-orgtable--fs {
    position: absolute;
    inset: 0;
    z-index: 6;
    margin: 0;
    max-width: none;
    padding: var(--sgs-gap-xl);
    background: var(--sgs-bg);
    overflow: auto;
    display: flex;
    flex-direction: column;
}
.sgs-orgtable--fs .sgs-ot-wrap { max-height: none; flex: 1; }
/* Privacy line + quick-action links under the identity card. */
.sgs-account-actions {
    display: flex;
    /* One link per line with uniform spacing (they read unevenly side by side because the
       two labels differ in length and wrap to different heights). */
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sgs-gap-sm);
    margin-bottom: var(--sgs-gap-lg);
}
/* Uniform vertical rhythm: the flex gap spaces the links, so drop their own margins. */
.sgs-account-actions .sgs-ds-xlink,
.sgs-account-actions .sgs-account-xlink-top {
    margin-top: 0;
    margin-bottom: 0;
}
/* Inert "sign back in" hints — previous identities, not active sessions. */
.sgs-account-known--inert .sgs-account-known-chip { opacity: 0.72; font-style: italic; }
.sgs-account-known--inert .sgs-account-known-chip:hover { opacity: 1; font-style: normal; }
.sgs-account-section-title {
    margin: 0 0 var(--sgs-gap-sm);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--sgs-text-muted);
}
/* Promoted cost+speed cross-link at the top of the account pane. */
.sgs-account-xlink-top {
    margin-bottom: var(--sgs-gap-lg);
}
/* "Your AGOL data" collapsed-by-default section — a quiet inline disclosure (same idea as the
   "Learn more about each data format" summary), not a big framed button. Just a caret + label. */
.sgs-account-agol-summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: var(--sgs-gap-xs) 0;
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: 0;
    text-transform: none;
    color: var(--sgs-text);
    transition: color var(--sgs-transition);
}
.sgs-account-agol-summary:hover { color: var(--sgs-accent); }
.sgs-account-agol-summary::-webkit-details-marker { display: none; }
.sgs-account-agol-summary::before {
    content: '▸';
    font-size: 11px;
    color: var(--sgs-text-muted);
    transition: transform 0.15s ease;
}
.sgs-account-agol[open] > .sgs-account-agol-summary { margin-bottom: var(--sgs-gap-md); }
.sgs-account-agol[open] > .sgs-account-agol-summary::before { transform: rotate(90deg); }
.sgs-account-stub-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    font-size: 12.5px;
    color: var(--sgs-text-muted);
    margin-bottom: 6px;
}

/* "Your AGOL data storage" — scan loader (thin determinate bar + live count), shown while
   fetchOrgUsage runs. Matches the perf load-bar sensibility: slim, rounded, accent fill. */
.sgs-orgdash-loading {
    padding: var(--sgs-gap-sm) 0 var(--sgs-gap-md);
}
.sgs-orgdash-loading-label {
    font-size: 12.5px;
    color: var(--sgs-text-muted);
    margin-bottom: 8px;
}
.sgs-orgdash-loadbar {
    height: 5px;
    border-radius: 3px;
    overflow: hidden;
    background: var(--sgs-border-light);
}
.sgs-orgdash-loadbar-fill {
    height: 100%;
    width: 6%;
    border-radius: 3px;
    /* Accent fill with a soft moving sheen so slow scans still feel alive. */
    background: linear-gradient(90deg,
        var(--sgs-accent),
        color-mix(in srgb, var(--sgs-accent) 55%, #fff) 50%,
        var(--sgs-accent));
    background-size: 200% 100%;
    animation: sgs-shimmer 1.4s linear infinite;
    transition: width 0.35s ease;
}
.sgs-orgdash-loading-count {
    margin-top: 7px;
    font-size: 11px;
    color: var(--sgs-text-muted);
    font-variant-numeric: tabular-nums;
    min-height: 14px; /* reserve the line so the layout doesn't jump on the first tick */
}

/* "Your AGOL data" — storage dashboard (account pane).
   The stat cards became the segmented usage charts (n12): three thin 100%-stacked
   bars (items / storage / $ per mo), one entity→color map, 2px surface gaps,
   click-to-filter, legend chips as the identity channel. */
.sgs-orgchart {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin-bottom: 10px;
}
.sgs-orgchart-head {
    display: flex;
    justify-content: flex-end;
}
.sgs-orgchart-row {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}
.sgs-orgchart-rowhead {
    flex: 0 0 132px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 6px;
}
.sgs-orgchart-label {
    font-size: 10.5px;
    color: var(--sgs-text-muted);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.sgs-orgchart-total {
    font-size: var(--sgs-font-sm);
    font-weight: 700;
    color: var(--sgs-text);
    font-variant-numeric: tabular-nums;
}
.sgs-orgchart-track {
    flex: 1;
    display: flex;
    gap: 2px; /* the surface gap does the separating; no strokes */
    height: 14px;
    border-radius: 4px;
    overflow: hidden;
}
.sgs-orgchart-seg {
    min-width: 3px;
    padding: 0;
    border: none;
    cursor: pointer;
    transition: opacity var(--sgs-transition);
}
.sgs-orgchart-seg--dim { opacity: 0.3; }
.sgs-orgchart-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 10px;
}
.sgs-orgchart-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 1px 2px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: color var(--sgs-transition), opacity var(--sgs-transition);
}
.sgs-orgchart-chip:hover { color: var(--sgs-text); }
.sgs-orgchart-swatch {
    width: 8px;
    height: 8px;
    border-radius: 2px;
    flex-shrink: 0;
}
.sgs-orgchart-credits {
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
    font-variant-numeric: tabular-nums;
}
.sgs-orgdash-note {
    font-size: 11px;
    color: var(--sgs-text-muted);
    margin: 0 0 10px;
    line-height: 1.4;
}
.sgs-orgdash-note-link { color: var(--sgs-accent); text-decoration: none; }
.sgs-orgdash-note-link:hover { text-decoration: underline; }
/* ── Unified, pivotable usage table (org-table.js) ─────────────────────────── */
.sgs-ot-controls {
    display: flex;
    gap: var(--sgs-gap-md);
    align-items: center;
    margin-bottom: 8px;
}
.sgs-ot-control {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 11px;
    color: var(--sgs-text-muted);
}
.sgs-ot-select {
    font-size: 12px;
    padding: 2px 6px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm, 4px);
    background: var(--sgs-surface-1, transparent);
    color: var(--sgs-text);
}
/* Partial-text search — leftmost control, sized to grow a little without crowding the pivots. */
.sgs-ot-search {
    width: 150px;
    max-width: 40vw;
    font-size: 12px;
    padding: 2px 6px;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm, 4px);
    background: var(--sgs-surface-1, transparent);
    color: var(--sgs-text);
}
.sgs-ot-search:focus { outline: 1px solid var(--sgs-accent); outline-offset: -1px; }
.sgs-ot-search::placeholder { color: var(--sgs-text-muted); }
.sgs-ot-empty {
    padding: 14px 10px;
    text-align: center;
    color: var(--sgs-text-muted);
    font-size: 12px;
}
.sgs-ot-wrap { max-height: 340px; overflow: auto; border: 1px solid var(--sgs-border-light); border-radius: var(--sgs-radius-sm, 4px); }
.sgs-ot-table { width: 100%; border-collapse: collapse; font-size: 12px; }
.sgs-ot-th {
    position: sticky;
    top: 0;
    z-index: 1;
    text-align: left;
    padding: 6px 8px;
    font-weight: 600;
    color: var(--sgs-text-muted);
    background: var(--sgs-surface-2, #f4f5f7);
    border-bottom: 1px solid var(--sgs-border);
    cursor: pointer;
    white-space: nowrap;
}
.sgs-ot-th--num { text-align: right; }
.sgs-ot-th--active { color: var(--sgs-text); }
.sgs-ot-td {
    padding: 4px 8px;
    border-bottom: 1px solid var(--sgs-border-light);
    color: var(--sgs-text);
    white-space: nowrap;
}
.sgs-ot-td--num { text-align: right; font-variant-numeric: tabular-nums; }
.sgs-ot-td--title { max-width: 220px; overflow: hidden; text-overflow: ellipsis; }
.sgs-ot-link { color: var(--sgs-accent); text-decoration: none; }
.sgs-ot-link:hover { text-decoration: underline; }
.sgs-ot-row:hover > .sgs-ot-td { background: var(--sgs-surface-2, rgba(0,0,0,0.03)); }
.sgs-ot-group > td {
    padding: 5px 8px;
    font-weight: 600;
    background: var(--sgs-surface-2, #eef0f3);
    border-bottom: 1px solid var(--sgs-border);
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.sgs-ot-group-name::before {
    content: '▾';
    display: inline-block;
    margin-right: 5px;
    font-size: 9px;
    transition: transform 0.12s ease;
}
.sgs-ot-group--collapsed .sgs-ot-group-name::before { transform: rotate(-90deg); }

/* "Your maps" — saved-config list (account pane) */
.sgs-cloudmaps { display: flex; flex-direction: column; gap: 6px; }
.sgs-cloudmap-row {
    display: flex;
    align-items: stretch;
    gap: 4px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    overflow: hidden;
    transition: border-color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-cloudmap-row:hover { border-color: var(--sgs-border); background: var(--sgs-surface-mid); }
.sgs-cloudmap-row--active { border-color: var(--sgs-accent); }
.sgs-cloudmap-open {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 8px 12px;
    border: none;
    background: none;
    text-align: left;
    cursor: pointer;
    color: var(--sgs-text);
}
.sgs-cloudmap-name {
    font-size: 13px;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-cloudmap-dirty { margin-left: 6px; color: var(--sgs-accent); font-size: 10px; vertical-align: middle; }
.sgs-cloudmap-meta { font-size: 11px; color: var(--sgs-text-micro); }
.sgs-cloudmap-action {
    flex-shrink: 0;
    width: 34px;
    border: none;
    background: none;
    color: var(--sgs-text-muted);
    cursor: pointer;
    font-size: 13px;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-cloudmap-action:hover { background: var(--sgs-surface-hover); color: var(--sgs-text); }
.sgs-cloudmap-action--danger:hover { color: #d93025; }
/* Two-click armed delete (canvas-switcher idiom): the first click turns the trash hot. */
.sgs-cloudmap-action--armed,
.sgs-cloudmap-action--armed:hover { color: #fff; background: #d93025; }
/* Inline rename input — sits exactly where the name was (the name IS the editor). */
.sgs-cloudmap-rename {
    font-size: 13px;
    font-weight: 600;
    font-family: inherit;
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-accent);
    border-radius: var(--sgs-radius-sm);
    padding: 1px 6px;
    min-width: 0;
    width: 100%;
}

/* ── Account page (R5): identity, connections, provider strip, quota, organization ── */

/* Display name: click-to-rename (compose idiom) — a quiet affordance on hover only. */
.sgs-account-name--editable { cursor: text; border-radius: var(--sgs-radius-sm); }
.sgs-account-name--editable:hover { background: var(--sgs-surface-hover); box-shadow: 0 0 0 3px var(--sgs-surface-hover); }
.sgs-account-name-input {
    font-size: 15px;
    font-weight: 600;
    font-family: inherit;
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-accent);
    border-radius: var(--sgs-radius-sm);
    padding: 1px 6px;
    width: min(240px, 100%);
}

/* The Primary tag: which provider OWNS the account (ADR #27/#28 made legible). */
.sgs-account-primary-tag,
.sgs-account-conn-tag {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 7px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.02em;
    border-radius: 999px;
    color: var(--sgs-accent);
    background: var(--sgs-accent-subtle);
    vertical-align: middle;
}
.sgs-account-conn-tag--data { color: var(--sgs-text-muted); background: var(--sgs-surface-2); }

/* Connections: list-shaped rows (multi-connection renders as more rows, not new UI). */
.sgs-account-conn-list { display: flex; flex-direction: column; gap: 6px; width: min(360px, 100%); }
.sgs-account-conn-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 12px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface);
}
.sgs-account-conn-row .sgs-account-conn-badge { width: 20px; height: 20px; }
.sgs-account-conn-label { font-size: 13px; font-weight: 600; color: var(--sgs-text); }
.sgs-account-conn-sub {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    color: var(--sgs-text-muted);
}
.sgs-account-conn-row .sgs-account-conn-tag { margin-left: auto; }

/* Provider strip (SPEC-sleek-storage §4): one dashboard shell, one provider at a time. */
.sgs-provider-strip {
    display: inline-flex;
    gap: 0;
    margin: 8px 0 10px;
    border: 1px solid var(--sgs-border-light);
    border-radius: 999px;
    overflow: hidden;
    background: var(--sgs-surface-2);
}
.sgs-provider-strip-btn {
    padding: 5px 14px;
    border: none;
    background: none;
    font-size: 12px;
    font-weight: 600;
    color: var(--sgs-text-muted);
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-provider-strip-btn:hover { color: var(--sgs-text); }
.sgs-provider-strip-btn--active {
    color: var(--sgs-accent);
    background: var(--sgs-surface);
    box-shadow: inset 0 0 0 1px var(--sgs-border-light);
    border-radius: 999px;
}

/* Quota meter: used / limit with the same bar sensibility as the usage tracks. */
.sgs-quota { margin: 4px 0 10px; }
.sgs-quota-label { font-size: 12px; font-weight: 600; color: var(--sgs-text); margin-bottom: 4px; }
.sgs-quota-track {
    height: 8px;
    border-radius: 999px;
    background: var(--sgs-surface-2);
    overflow: hidden;
}
.sgs-quota-fill {
    height: 100%;
    border-radius: 999px;
    background: var(--sgs-accent);
    transition: width 0.3s ease;
}
.sgs-quota-fill--warn { background: #d16a10; }

/* Per-row delete in the storage table (deletes-before-quotas). */
.sgs-ot-th--action, .sgs-ot-td--action { width: 30px; text-align: center; }
.sgs-ot-rowdelete {
    border: none;
    background: none;
    color: var(--sgs-text-muted);
    cursor: pointer;
    padding: 2px 5px;
    border-radius: var(--sgs-radius-sm);
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-ot-rowdelete:hover { color: #d93025; background: var(--sgs-surface-hover); }
.sgs-ot-rowdelete--armed,
.sgs-ot-rowdelete--armed:hover { color: #fff; background: #d93025; }

/* Organization: the ArcGIS org you have + the Sleek org-tier preview. */
.sgs-org-section { margin-top: var(--sgs-gap-md); }
.sgs-org-current { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.sgs-org-current-name { font-size: 13px; font-weight: 600; color: var(--sgs-text); }
.sgs-org-role-pill {
    padding: 1px 7px;
    font-size: 10px;
    font-weight: 600;
    border-radius: 999px;
    color: var(--sgs-text-muted);
    background: var(--sgs-surface-2);
}
.sgs-org-preview {
    width: min(520px, 100%);
    padding: 12px 14px;
    border: 1px dashed var(--sgs-border);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface);
}
.sgs-org-preview-head { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; }
.sgs-org-preview-title { font-size: 13px; font-weight: 700; color: var(--sgs-text); }
.sgs-org-soon-pill {
    padding: 1px 8px;
    font-size: 10px;
    font-weight: 600;
    border-radius: 999px;
    color: var(--sgs-accent);
    background: var(--sgs-accent-subtle);
}
.sgs-org-preview-lead { margin: 2px 0 10px; }
.sgs-org-preview-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 8px;
    margin-bottom: 12px;
}
.sgs-org-preview-item {
    padding: 8px 10px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface-mid);
}
.sgs-org-preview-item-title { font-size: 12px; font-weight: 600; color: var(--sgs-text); margin-bottom: 2px; }
.sgs-org-preview-item-blurb { font-size: 11.5px; color: var(--sgs-text-muted); line-height: 1.45; }
.sgs-org-preview-cta[disabled] { opacity: 0.55; cursor: not-allowed; }

/* Account-page section rhythm: every section shares the h3 treatment. */
.sgs-account-section { margin-top: var(--sgs-gap-md); }
.sgs-account-maps-host { width: min(520px, 100%); }

/* Owner's in-place item editor (AGOL browser detail). */
.sgs-agol-item-editbtn {
    border: none;
    background: none;
    padding: 0;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--sgs-accent);
    cursor: pointer;
}
.sgs-agol-item-editbtn:hover { text-decoration: underline; }
.sgs-agol-item-editor { display: flex; flex-direction: column; gap: 8px; }
.sgs-agol-item-editor-label {
    display: flex;
    flex-direction: column;
    gap: 3px;
    font-size: 11px;
    font-weight: 600;
    color: var(--sgs-text-muted);
}
.sgs-agol-item-editor-snippet,
.sgs-agol-item-editor-desc {
    font-size: 12px;
    font-family: inherit;
    color: var(--sgs-text);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-sm);
    padding: 5px 8px;
    width: 100%;
}
.sgs-agol-item-editor-desc { resize: vertical; font-family: var(--sgs-mono, monospace); font-size: 11.5px; }
.sgs-agol-item-editor-note { font-size: 11px; color: var(--sgs-text-muted); font-style: italic; }
.sgs-agol-item-editor-error { font-size: 11.5px; color: #d93025; }
.sgs-agol-item-editor-error:empty { display: none; }
.sgs-agol-item-editor-btns { display: flex; gap: 8px; }

/* "Welcome back" identity hints */
.sgs-account-known {
    margin-bottom: var(--sgs-gap-md);
}
/* Each remembered account is ONE full-width pill (notebear n9): the row carries the border
   and runs the full 360px; the chip (click to sign back in) fills it, and the ✕ (forget)
   sits inside at the right, just past "Signed out". Chip + ✕ stay separate <button>s (no
   nested buttons) so their click targets don't collide. */
.sgs-account-known-row {
    display: flex;
    align-items: center;
    gap: 2px;
    width: min(360px, 100%);
    margin-bottom: 6px;
    padding-right: 8px;
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius-md);
    background: var(--sgs-surface);
    transition: border-color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-account-known-row:hover { border-color: var(--sgs-accent); background: var(--sgs-accent-subtle); }
.sgs-account-known-chip {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    padding: 8px 4px 8px 12px;
    border: 0;
    background: transparent;
    text-align: left;
}
.sgs-account-known-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 28px;
    height: 28px;
    flex-shrink: 0;
    line-height: 0;
}
.sgs-account-known-badge img,
.sgs-account-known-badge svg { width: 20px; height: 20px; border-radius: 3px; }
.sgs-account-known-forget {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    font-size: 11px;
    line-height: 1;
    color: var(--sgs-text-muted);
    opacity: 0.55;
    transition: opacity var(--sgs-transition), background var(--sgs-transition), color var(--sgs-transition);
}
.sgs-account-known-forget:hover {
    opacity: 1;
    color: var(--sgs-text);
    background: var(--sgs-surface-2, var(--sgs-accent-subtle));
}
/* Hover feedback now lives on the row pill (above); the chip itself stays transparent. */
.sgs-account-known-chip:disabled { opacity: 0.6; cursor: wait; }
.sgs-account-known-initials {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--sgs-accent-subtle);
    color: var(--sgs-accent);
    font-size: 11px;
    font-weight: 700;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.sgs-account-known-name {
    font-size: 12.5px;
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-account-known-user {
    font-size: 11.5px;
    color: var(--sgs-text-muted);
}
/* Per-chip signed-out tag (replaces the old standalone "Signed out" row). */
.sgs-account-known-status {
    margin-left: auto;
    font-size: 10.5px;
    font-style: italic;
    color: var(--sgs-text-muted);
    opacity: 0.8;
    flex-shrink: 0;
}

/* ── Person-icon pulse after welcome recedes ── */
.sgs-auth-btn--pulse {
    animation: sgs-auth-pulse 0.8s ease-out 3;
}
@keyframes sgs-auth-pulse {
    0%   { box-shadow: 0 0 0 0 rgba(90, 155, 232, 0.55); }
    100% { box-shadow: 0 0 0 10px rgba(90, 155, 232, 0); }
}

/* ── Responsive: compact welcome window ── */
@media (max-width: 720px) {
    .sgs-welcome { height: min(680px, 92vh); }
    .sgs-welcome-nav { width: 44px; }
    .sgs-welcome-nav-btn span:not(.sgs-welcome-nav-icon) { display: none; }
    .sgs-welcome-nav-btn { justify-content: center; padding: 8px 0; }
    .sgs-welcome-footer-hint { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .sgs-welcome,
    .sgs-welcome-overlay,
    .sgs-geogs,
    .sgs-geogs-eye,
    .sgs-geogs-cloud,
    .sgs-auth-btn--pulse {
        animation: none;
    }
}


/* ============================================================
   17. WIDGET STRIP (app-engine A1/A2 — widget-panel.js)
   Config-declared widgets at the bottom of the layer panel. Sections borrow the
   group-header grammar (chevron + name, hover-lift) so a plugged-in widget reads
   as core UI; bodies stay on panel tokens only — widget modules never bring
   their own palette.
   ============================================================ */

/* The strip is BOTTOM-ANCHORED (n1 2026-07-12): margin-top auto absorbs any
   slack the layer list leaves, so resizing moves the strip's TOP edge while
   its bottom stays glued to the panel's bottom (the VS Code bottom-panel
   feel). When the panel is tight it gives space back first (shrink 6 vs the
   list's 1) — the list keeps priority. */
#sgs-widget-strip {
    position: relative;
    flex: 0 6 auto;
    min-height: 0;
    margin-top: auto;
    border-top: 1px solid var(--sgs-border);
    background: var(--sgs-layer-canvas);
    overflow-y: auto;
}
/* Only a widget-bearing panel frees the list from stretching (the empty band
   below a short list belongs to the gap above the blocks, not the list), and
   the list keeps breathing room above the strip: its 6px bottom padding plus
   the last card's 6px margin = twice the card-to-card gap (n1 2026-07-12).
   :not() keeps this rule out of the maximize state — the ID inside :has()
   would otherwise out-specify the .sgs-panel--widgets-max rules below. */
.sgs-panel:has(#sgs-widget-strip):not(.sgs-panel--widgets-max) .sgs-panel-body {
    flex: 0 1 auto;
    padding-bottom: 6px;
}
/* Manual height: the grip pins it; double-click restores automatic. */
#sgs-widget-strip.sgs-widget-strip--manual {
    flex: 0 0 var(--sgs-widget-strip-h, 220px);
}
/* Minimized: only the grab bar survives, like the dock's sliver — the blocks
   tuck away without unmounting (n1 2026-07-12). */
#sgs-widget-strip.sgs-widget-strip--min {
    flex: 0 0 auto;
}
#sgs-widget-strip.sgs-widget-strip--min .sgs-widget-section { display: none; }
/* Maximize: the blocks fill the panel under the heading; the list collapses
   but the map name / toolbar never do. */
.sgs-panel--widgets-max #sgs-widget-strip {
    flex: 1 1 auto;
    /* The map name keeps the same breathing room above the strip as it gets
       above the first layer card (n17 2026-07-12). */
    margin-top: 6px;
}
.sgs-panel--widgets-max .sgs-panel-body {
    flex: 0 1 0%;
    min-height: 0;
    overflow: hidden;
}
/* Sticky grab bar across the strip's top: drag to resize, double-click to
   restore; carries the minimize + maximize toggles at its right edge. 14px
   tall so the pill and buttons sit clear of the strip's top edge (n3). */
.sgs-widget-resize {
    position: sticky;
    top: 0;
    z-index: 3;
    height: 14px;
    cursor: ns-resize;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--sgs-layer-canvas);
}
.sgs-widget-resize::before {
    content: '';
    width: var(--sgs-grip-len);
    height: var(--sgs-grip-thick);
    border-radius: 2px;
    background: var(--sgs-border);
}
.sgs-widget-resize:hover::before { background: var(--sgs-text-muted); }
.sgs-widget-max,
.sgs-widget-min {
    position: absolute;
    top: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 14px;
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    cursor: pointer;
}
.sgs-widget-max { right: 2px; }
.sgs-widget-min { right: 20px; }
.sgs-widget-max:hover,
.sgs-widget-min:hover { color: var(--sgs-text); }
.sgs-widget-min svg { transition: transform var(--sgs-transition); }
#sgs-widget-strip.sgs-widget-strip--min .sgs-widget-min svg { transform: rotate(180deg); }
.sgs-widget-section + .sgs-widget-section {
    border-top: 1px solid var(--sgs-border);
}
.sgs-widget-head {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    /* Right pad trimmed so the head's LAST icon (zoom-to) centers on the same
       column as the grab bar's min/max buttons (n11 2026-07-12). */
    padding: 5px 4px 5px var(--sgs-gap-sm);
    min-height: 26px;
    user-select: none;
    cursor: pointer;
}
.sgs-widget-chevron {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--sgs-text-off);
    flex-shrink: 0;
    transition: transform var(--sgs-transition), color var(--sgs-transition);
}
.sgs-widget-section--open .sgs-widget-chevron {
    transform: rotate(90deg);
}
.sgs-widget-head:hover .sgs-widget-chevron { color: var(--sgs-text); }
.sgs-widget-name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.sgs-widget-section--open .sgs-widget-name { color: var(--sgs-text); }
/* Head zoom-to (n13 2026-07-12): the layer row's target glyph, far right. */
.sgs-widget-zoom {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    cursor: pointer;
    flex-shrink: 0;
}
.sgs-widget-zoom:hover { color: var(--sgs-accent); }
/* The zoom LATCH (n12): lit while block filters keep re-zooming the map. */
.sgs-widget-zoom--on { color: var(--sgs-accent); }
.sgs-widget-body {
    padding: 2px var(--sgs-gap-sm) 8px;
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text-muted);
}
.sgs-widget-error { color: var(--sgs-text-micro); }

/* ── placement: map-overlay (R39) ────────────────────────────────────────────
   A block floating over the map: the layer panel's own card look, draggable by
   its head, collapsible to that head. It rises with the bottom dock so it can
   never end up hidden behind it. Bottom-right is the free corner (the panel owns
   the left, the controls the top-right); a drag moves it anywhere. */
.sgs-map-block {
    position: fixed;
    right: var(--sgs-gap-md);
    bottom: calc(var(--sgs-gap-md) + 28px); /* clears the scale bar + attribution */
    z-index: 5;
    width: var(--sgs-map-block-w, 300px);
    max-width: calc(100vw - 2 * var(--sgs-gap-md));
    border: 1px solid var(--sgs-border-light);
    border-radius: var(--sgs-radius);
    background: var(--sgs-layer-canvas);
    box-shadow: var(--sgs-shadow-lg);
    overflow: hidden;
}
html.sgs-perf-dock-open .sgs-map-block {
    /* The fallback is load-bearing: the var is only WRITTEN once the dock is
       resized, so without it the calc is invalid and the card falls to the top. */
    bottom: calc(var(--sgs-perf-dock-h, 250px) + var(--sgs-gap-md));
}
.sgs-map-block .sgs-widget-body { max-height: 46vh; overflow: auto; }
.sgs-map-block-head { background: var(--sgs-layer-canvas); }

/* ── placement: welcome-tab (R39) ────────────────────────────────────────────
   A config's own tab in the app window. The head matches the built-in tab
   headings; the block renders beneath it. */
.sgs-welcome-tab--block .sgs-welcome-tab-head {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
}

/* Sandboxed (cross-origin) block iframe: fills the section, no border of its own
   (the section chrome frames it), height driven by the block's reported content. */
.sgs-block-frame {
    display: block;
    width: 100%;
    min-height: 24px;
    border: none;
    background: transparent;
    color-scheme: light dark;
}
/* ── Block trust signals (issue #52, R40) ────────────────────────────────────
   The review badge on the consent card, and the banner a block wears when its
   code drifted from the bytes sleek reviewed. Truthful, quiet, never alarmist:
   the sandbox is what protects the user, the badge is what informs them. */
.sgs-block-badge {
    align-self: flex-start;
    padding: 1px 6px;
    border-radius: var(--sgs-radius-sm);
    border: 1px solid var(--sgs-border);
    background: var(--sgs-bg);
    color: var(--sgs-text-muted);
    font-size: var(--sgs-font-micro);
    font-weight: 600;
}
/* Reviewed states carry the accent (there is no green in the palette, and inventing
   one for a badge is not worth a new token); unreviewed stays deliberately quiet. */
.sgs-block-badge--featured,
.sgs-block-badge--reviewed {
    border-color: var(--sgs-accent);
    color: var(--sgs-accent);
}
.sgs-block-badge--unknown { color: var(--sgs-text-micro); }
/* Reviewed once, edited since: the one place a block is allowed to look alarming. */
.sgs-block-warn {
    margin: 0 0 6px;
    padding: 4px 8px;
    border-left: 2px solid var(--sgs-danger);
    background: var(--sgs-danger-subtle);
    color: var(--sgs-text-muted);
    font-size: var(--sgs-font-xs);
}

/* Cross-origin custom blocks wait behind this in-section disclosure (R18). */
.sgs-widget-consent {
    display: flex;
    flex-direction: column;
    gap: 6px;
    align-items: flex-start;
    padding: 6px 8px;
    border: 1px dashed var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    /* --sgs-bg-subtle was never defined, so this card had no fill at all. The panel
       surface token is the one it always meant. */
    background: var(--sgs-surface);
}
.sgs-widget-consent-msg {
    margin: 0;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-muted);
}
.sgs-widget-consent-btn {
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
    background: var(--sgs-bg);
    color: var(--sgs-text);
    font-size: var(--sgs-font-xs);
    padding: 3px 10px;
    cursor: pointer;
}
.sgs-widget-consent-btn:hover {
    border-color: var(--sgs-accent);
    color: var(--sgs-accent);
}
/* ── Legend mode (issue #37): the panel as a pure legend ──
   A body class is the whole mechanism: hide every control surface and what
   remains is layer names + symbology patches. Consumption, not control. */
.sgs-legend-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    padding: 2px 3px;
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
}
.sgs-legend-toggle:hover { color: var(--sgs-text); background: var(--sgs-surface-hover); }
.sgs-legend-toggle--on { color: var(--sgs-accent); }
/* The in-view filter button: same chrome, but it only exists INSIDE legend mode
   (n7 2026-07-12) — sits immediately left of the legend toggle. */
.sgs-legend-inview-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    padding: 2px 3px;
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
}
body.sgs-legend-mode .sgs-legend-inview-toggle { display: inline-flex; }
.sgs-legend-inview-toggle:hover { color: var(--sgs-text); background: var(--sgs-surface-hover); }
.sgs-legend-inview-toggle--on { color: var(--sgs-accent); }
/* Hide the control chrome. !important: one deliberate mode veto that must beat
   each surface's own display/hover rules (and .sgs-hidden interplay) without
   chasing their individual specificities. */
body.sgs-legend-mode .sgs-toolbar,
body.sgs-legend-mode #sgs-widget-strip,
body.sgs-legend-mode .sgs-dirty-hub,
body.sgs-legend-mode .sgs-layer-row .sgs-icon-btn,
body.sgs-legend-mode .sgs-layer-row input[type="checkbox"],
body.sgs-legend-mode .sgs-layer-row .sgs-pill-slot,
body.sgs-legend-mode .sgs-layer-row .sgs-row-actions,
body.sgs-legend-mode .sgs-perf-container,
body.sgs-legend-mode .sgs-filter-body,
body.sgs-legend-mode .sgs-group-header input[type="checkbox"],
body.sgs-legend-mode .sgs-group-header .sgs-edit-drag,
body.sgs-legend-mode .sgs-group-header .sgs-group-triangle,
body.sgs-legend-mode .sgs-group-header .sgs-group-icon,
body.sgs-legend-mode #group-wrap-basemap {
    display: none !important;
}
/* The point of the mode: every ON layer's patches show, even where the legend
   was collapsed or the group folded (must out-specify .sgs-hidden's !important). */
body.sgs-legend-mode #layer-list .sgs-legend { display: block !important; }
body.sgs-legend-mode .sgs-group-children { display: block !important; }
/* A legend describes what the map draws: layers toggled OFF drop out entirely —
   and so do whole OFF groups (n9 2026-07-12). */
body.sgs-legend-mode .sgs-layer-wrap:not([data-on]) { display: none; }
body.sgs-legend-mode .sgs-group-wrap:not([data-on]) { display: none; }
/* Tighter rhythm (n8): less layer-to-layer air, and a name always sits closer to
   ITS patches below than to the previous layer's patches above. */
body.sgs-legend-mode .sgs-layer-wrap,
body.sgs-legend-mode .sgs-group-wrap { margin-top: 2px; margin-bottom: 2px; }
body.sgs-legend-mode #layer-list .sgs-legend { padding-bottom: 4px; }
/* The in-view filter (n7): with the sub-mode on, only layers actually DRAWN in
   the visible viewport (data-inview, legend-mode.js) keep their legend entry. */
body.sgs-legend-mode.sgs-legend-inview .sgs-layer-wrap:not([data-inview]),
body.sgs-legend-mode.sgs-legend-inview .sgs-group-wrap:not([data-inview]) { display: none; }
/* Legend mode hides the strip, so a widgets-maximized panel must hand the
   space back to the list or the legend renders blank (n1 2026-07-12). */
body.sgs-legend-mode .sgs-panel--widgets-max .sgs-panel-body {
    flex: 1 1 auto;
    overflow-y: auto;
}
/* No toggling in this mode: rows and group headers go inert (the heading's own
   legend button stays live — it is outside the list). */
body.sgs-legend-mode .sgs-layer-row,
body.sgs-legend-mode .sgs-group-header { pointer-events: none; }
/* Cards flatten to a quiet list. */
body.sgs-legend-mode .sgs-group-wrap,
body.sgs-legend-mode .sgs-layer-wrap {
    border-color: transparent;
    box-shadow: none;
    background: transparent;
}

/* The reference stats block (configs/blocks/stats-block.js): a compact label/value grid. */
.sgs-stats-block {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 2px 12px;
    margin: 2px 0;
}
.sgs-stats-block dt {
    color: var(--sgs-text-micro);
    font-size: var(--sgs-font-xs);
}
.sgs-stats-block dd {
    margin: 0;
    text-align: right;
    font-variant-numeric: tabular-nums;
    color: var(--sgs-text);
    font-size: var(--sgs-font-xs);
}

/* ── Chart widget ── */
.sgs-chart {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.sgs-chart-row {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-xs);
    width: 100%;
    padding: 2px 4px;
    border: none;
    background: none;
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    text-align: left;
    transition: background var(--sgs-transition);
}
.sgs-chart-row:hover { background: var(--sgs-surface-mid); }
.sgs-chart-row--active { background: var(--sgs-surface-2); }
/* A map feature click lights its bar — same accent language as active rows. */
.sgs-chart-row--hit .sgs-chart-label { color: var(--sgs-accent); font-weight: 600; }
.sgs-chart-row--other { cursor: default; }
.sgs-chart-row--other:hover { background: none; }
.sgs-chart-label {
    flex: 0 0 34%;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--sgs-font-sm);
    color: var(--sgs-text);
}
.sgs-chart-track {
    flex: 1;
    height: 10px;
    border-radius: 2px;
    background: var(--sgs-surface-mid);
    overflow: hidden;
}
.sgs-chart-bar {
    display: block;
    height: 100%;
    border-radius: 2px;
    transition: width var(--sgs-transition);
}
.sgs-chart-count {
    flex: 0 0 auto;
    min-width: 3ch;
    text-align: right;
    font-size: 10.5px;
    color: var(--sgs-text-micro);
    font-variant-numeric: tabular-nums;
}
/* Canvas kinds (Chart.js, vendored + lazy): keep the plot compact in the strip. */
.sgs-chart-canvas-wrap {
    position: relative;
    max-height: 220px;
    padding: 4px 2px 0;
}
/* Chart segments filter the map on click — the canvas advertises it (n9). */
.sgs-chart-canvas-wrap canvas { max-height: 212px; cursor: pointer; }

.sgs-chart-foot {
    display: flex;
    align-items: center;
    gap: var(--sgs-gap-sm);
    margin-top: 6px;
    font-size: 10.5px;
    color: var(--sgs-text-micro);
}
/* The note flexes so the actions (paint, Show all) cluster at the right edge
   instead of floating mid-row (n13 2026-07-12). */
.sgs-chart-total {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* A FOREIGN filter is on the layer (n16): the chart's counts describe the full
   dataset while the map shows someone else's subset — dim, don't lie. */
.sgs-chart-foreign .sgs-chart,
.sgs-chart-foreign canvas { opacity: 0.55; }
.sgs-chart-clear {
    padding: 1px 8px;
    font-size: 10.5px;
    color: var(--sgs-text-muted);
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-pill);
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-chart-clear:hover { color: var(--sgs-text); background: var(--sgs-surface-mid); }
/* Paint toggle (n11): push the chart's palette onto the map as unique-value
   symbology. Accent when the map is wearing this chart's colors. */
.sgs-chart-paint {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 18px;
    padding: 0;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    border-radius: var(--sgs-radius-sm);
    cursor: pointer;
    transition: color var(--sgs-transition);
}
.sgs-chart-paint:hover { color: var(--sgs-text); }
.sgs-chart-paint--on { color: var(--sgs-accent); }

/* ── Discover widget ── */
.sgs-discover {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.sgs-discover-card {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 6px 8px;
    background: var(--sgs-surface);
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-sm);
}
.sgs-discover-top {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--sgs-gap-sm);
}
.sgs-discover-title {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--sgs-font-sm);
    font-weight: 600;
    color: var(--sgs-text);
}
.sgs-discover-kind {
    flex-shrink: 0;
    font-size: 10px;
    color: var(--sgs-text-micro);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.sgs-discover-snippet {
    font-size: 10.5px;
    color: var(--sgs-text-muted);
    line-height: 1.35;
}
.sgs-discover-add {
    align-self: flex-start;
    margin-top: 2px;
    padding: 1px 8px;
    font-size: 10.5px;
    color: var(--sgs-text-muted);
    background: none;
    border: 1px solid var(--sgs-border);
    border-radius: var(--sgs-radius-pill);
    cursor: pointer;
    transition: color var(--sgs-transition), background var(--sgs-transition);
}
.sgs-discover-add:hover:not(:disabled) { color: var(--sgs-accent); background: var(--sgs-surface-mid); }
.sgs-discover-add:disabled { opacity: 0.7; cursor: default; }

/* Table widget (issue #12): a compact attribute table in the widget strip.
   No inner height cap (n10 2026-07-12): the section opens to its windowed
   rows ("Show more" pages them) and the STRIP is the one scroll/resize
   surface — two nested scrollbars read as a bug. */
.sgs-tablew {
    overflow-x: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--sgs-border) transparent;
}
.sgs-tablew-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--sgs-font-xs);
}
.sgs-tablew-th {
    position: sticky;
    top: 0;
    background: var(--sgs-layer-canvas);
    text-align: left;
    padding: 0;
    border-bottom: 1px solid var(--sgs-border-light);
}
.sgs-tablew-sort {
    display: block;
    width: 100%;
    padding: 3px 6px;
    border: none;
    background: none;
    color: var(--sgs-text-micro);
    font-size: var(--sgs-font-xs);
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sgs-tablew-sort:hover { color: var(--sgs-text); }
.sgs-tablew-sort[data-dir="asc"]::after { content: ' ↑'; }
.sgs-tablew-sort[data-dir="desc"]::after { content: ' ↓'; }
.sgs-tablew-row { cursor: pointer; transition: background var(--sgs-transition); }
.sgs-tablew-row:hover { background: var(--sgs-surface-mid); }
.sgs-tablew-row--active { background: var(--sgs-surface-2); }
.sgs-tablew-row--hit .sgs-tablew-td:first-child { color: var(--sgs-accent); font-weight: 600; }
.sgs-tablew-td {
    padding: 2px 6px;
    color: var(--sgs-text);
    border-bottom: 1px solid var(--sgs-border-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 110px;
    font-variant-numeric: tabular-nums;
}
.sgs-tablew-more {
    display: block;
    width: 100%;
    padding: 3px 6px;
    border: none;
    background: none;
    color: var(--sgs-accent);
    font-size: var(--sgs-font-xs);
    text-align: left;
    cursor: pointer;
}
.sgs-tablew-more:hover { background: var(--sgs-surface); }
/* Pager row (n18): grow left, collapse right. */
.sgs-tablew-pager { display: flex; align-items: center; }
.sgs-tablew-pager .sgs-tablew-more { flex: 1 1 auto; width: auto; }
.sgs-tablew-fewer { flex: 0 0 auto; text-align: right; color: var(--sgs-text-muted); }
.sgs-tablew-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 3px 6px 1px;
    font-size: var(--sgs-font-xs);
    color: var(--sgs-text-micro);
}
.sgs-tablew-clear {
    border: 1px solid var(--sgs-border);
    background: var(--sgs-surface);
    color: var(--sgs-text);
    font-size: var(--sgs-font-xs);
    padding: 1px 8px;
    border-radius: var(--sgs-radius-pill);
    cursor: pointer;
}
.sgs-tablew-clear:hover { border-color: var(--sgs-accent); color: var(--sgs-accent); }
/* Bar column (n7): value drawn as a bar tinted by the layer's categorized
   color, number right-aligned beside it — chart-in-a-table. The td class lifts
   the base cell's ellipsis cap so numbers never truncate. */
.sgs-tablew-tdbar {
    max-width: none;
    min-width: 130px;
    overflow: visible;
}
.sgs-tablew-td--bar {
    display: flex;
    align-items: center;
    gap: 6px;
}
.sgs-tablew-bartrack {
    flex: 1;
    min-width: 36px;
    height: 8px;
    border-radius: 2px;
    background: var(--sgs-surface);
    overflow: hidden;
}
.sgs-tablew-barfill {
    display: block;
    height: 100%;
    border-radius: 2px;
}
.sgs-tablew-barnum {
    flex-shrink: 0;
    min-width: 62px;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
