  /* ============================================================
     Page chrome
     ============================================================ */
  /* overscroll-behavior:none — app-shell, not a document: the chrome is sticky/in-flow and
     the drill-in detail panels are position:fixed over an otherwise non-scrolling body. On iOS a
     finger-drag on a fixed panel (whose content fits, so it can't scroll) rubber-bands the whole
     page — the in-flow chrome bounces while the fixed panel stays put, exposing the view behind.
     Containing overscroll at the root kills that bounce for every mobile panel at once (also
     disables pull-to-refresh, which we want in an app shell). */
  html, body { background: #07100C; margin: 0; padding: 0; min-height: 100vh; overscroll-behavior: none; color: #E8F1ED; font-family: var(--font-ui); }
  [data-theme="blue"], [data-theme="blue"] body { background: #060B14; }
  #root { min-height: 100vh; background: var(--bg-0); }

  /* App-level container */
  .isg-app { position: relative; min-height: 100vh; isolation: isolate; }

  /* (Removed full-page accent wash — was washing chrome to gray) */

  /* App shell — normal content stacking context */
  .isg-shell { position: relative; z-index: var(--z-base); }

  /* ============================================================
     Container primitives — Module & Panel
     ============================================================
     Every content container in the app is one of two primitives:

     MODULE — floating rounded card (activity feed, trend charts,
            legend, stat tiles, coming-soon placeholders).
            PHP-rendered modules use module_open()/module_close()
            (templates/_module.php). Hand-built modules follow:
              <div class="isg-module isg-module--<name>">
                <div class="isg-spot" …></div>   ← isg_spot() in PHP
                <div class="isg-module-inner"> content </div>
              </div>

     PANEL — edge-docked, full-height, squared-off container
            (zones panel). Same structure with isg-panel / isg-panel-inner.

     Both carry the spotlight: a faint radial glow at a random
     per-render angle (--spot-angle, injected inline by PHP or Alpine).

     New containers MUST start from one of these primitives and
     diverge only in an isg-module-- or isg-panel-- modifier below.
     (Exception: map overlay controls — heat sliders, corner chips —
     are translucent map furniture, not Modules.) */

  /* ── Module primitive ── */
  .isg-module {
    --module-pad: 20px;
    position: relative;
    background: var(--bg-1);
    border-radius: var(--r-lg);
    isolation: isolate;
    box-shadow: var(--elev-2);
    overflow: hidden;
    padding: var(--module-pad);
  }
  /* Static rim — slightly lighter than surface */
  .isg-module::before {
    content: ''; position: absolute; inset: 0;
    border-radius: inherit;
    border: 1px solid var(--border-0);
    pointer-events: none;
    z-index: var(--z-decor);
  }
  .isg-module-inner { position: relative; z-index: var(--z-content); }
  /* Standard module header row — title left, meta right */
  .isg-module-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
  /* Header action buttons (e.g. hover tools) flow inline with the title text — size them
     to the text so revealing them never grows the header row. Reused by any Module header. */
  .isg-module-head .isg-icon-btn {
    width: auto; height: auto; padding: 0; line-height: 0;
    border: none; background: transparent;
  }
  .isg-module-head .isg-icon-btn svg { width: 0.85rem; height: 0.85rem; display: block; }

  /* ── Panel primitive ── */
  .isg-panel {
    position: relative;
    display: flex; flex-direction: column;
    background: var(--bg-1);
    isolation: isolate;
    overflow: hidden;
  }
  /* Inner wrapper scrolls so the spotlight stays fixed to the panel */
  .isg-panel-inner {
    position: relative; z-index: var(--z-content);
    flex: 1; min-height: 0;
    display: flex; flex-direction: column;
    overflow-y: auto;
  }

  /* ── Spotlight — shared by Module & Panel ── */
  /* Spotlight gradient. Kept inline (not a token) because a custom property that references
     --spot-angle bakes the angle at its declaration scope; the gradient must live where
     --spot-angle is in scope to vary per instance. Mirrored on .isg-supp-card::after. */
  .isg-spot {
    position: absolute; inset: 0;
    border-radius: inherit;
    pointer-events: none;
    z-index: var(--z-base);
    background:
      radial-gradient(
        80% 60% at calc(50% + cos(var(--spot-angle, 0deg)) * 40%) calc(50% + sin(var(--spot-angle, 0deg)) * 40%),
        var(--spotlight-color),
        transparent 65%
      );
  }

  /* ── Module children — every Module in the app, one modifier each ── */
  /* Activity feed module — right side of Map & Area Studies (templates/_activity-panel.php) */
  .isg-module--activity { --module-pad: 0; flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .isg-module--activity > .isg-module-inner { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  /* Legend module — pin-colors key below the Activity module (templates/_severity-legend.php) */
  .isg-module--legend { --module-pad: 0; flex-shrink: 0; }
  /* Stat tile module — dashboard grid cells (templates/_stats-dashboard.php); grid + size variants in the Statistics section */
  .isg-module--stat { --module-pad: 14px; min-width: 0; }
  .isg-module--stat > .isg-module-inner { display: flex; flex-direction: column; height: 100%; }
  /* Query Library entry module — saved-query cards (templates/_stats-library.php) */
  .isg-module--libentry > .isg-module-inner { display: flex; justify-content: space-between; align-items: center; gap: 12px; }

  /* ── Panel children ── */
  /* Zones panel — left side of Area Studies (templates/_area-studies.php) */
  .isg-panel--zones {
    position: absolute;
    left: 0; top: 0; bottom: 0;
    width: 200px;
    z-index: var(--z-popover);
    border-right: 1px solid var(--border-0);
  }

  /* ============================================================
     Layout shell
     ============================================================ */
  .isg-shell { display: flex; height: 100vh; }
  .isg-main { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
  .isg-content { flex: 1; min-height: 0; padding: 16px; overflow-y: auto; }
  .isg-content--map { padding: 0; min-height: 0; overflow: hidden; display: flex; }
  .isg-map-view { flex: 1; min-width: 0; display: flex; }

  /* Scroll-down cue — floats bottom-center of the content area when there's more below.
     Gentle bob draws the eye; click scrolls the content down a screenful. */
  .isg-scroll-cue {
    position: absolute; bottom: 14px; left: 50%; transform: translateX(-50%);
    z-index: var(--z-popover);
    display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0;
    border: none; border-radius: 50%;
    background: color-mix(in srgb, var(--bg-2) 82%, transparent);
    color: var(--fg-2); cursor: pointer;
    box-shadow: var(--elev-2);
    -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px);
    animation: isg-scroll-bob 1.6s ease-in-out infinite;
    transition: color 0.15s ease;
  }
  .isg-scroll-cue:hover { color: var(--fg-0); }
  .isg-scroll-cue svg { width: 26px; height: 26px; display: block; }
  @keyframes isg-scroll-bob {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%      { transform: translateX(-50%) translateY(4px); }
  }
  @media (prefers-reduced-motion: reduce) { .isg-scroll-cue { animation: none; } }

  /* ============================================================
     Sidebar
     ============================================================ */
  .isg-sidebar {
    width: 76px; flex-shrink: 0; border-right: 1px solid var(--border-0);
    display: flex; flex-direction: column;
    background: var(--bg-1);
    transition: width var(--d-med) var(--ease);
    padding: 12px 8px;
    gap: 8px;
  }
  .isg-sidebar.is-expanded { width: 232px; }
  .isg-sidebar-head { position: relative; display: flex; align-items: center; justify-content: space-between; padding: 4px; min-height: 40px; }
  .isg-logo { display: flex; align-items: center; gap: 10px; color: var(--accent); }
  .isg-logo-mark { height: 48px; width: auto; flex-shrink: 0; }
  .isg-logo-word { font: var(--t-h3); color: #fff; white-space: nowrap; opacity: 0; transition: opacity var(--d-med) var(--ease); letter-spacing: 0.04em; }
  .isg-sidebar.is-expanded .isg-logo-word { opacity: 1; }
  .isg-sidebar-toggle {
    width: 28px; height: 28px; border-radius: 8px; background: var(--bg-2);
    border: 1px solid var(--border-0); color: var(--fg-1);
    display: grid; place-items: center; cursor: pointer;
    transition: background var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
  }
  /* When collapsed: shield stays centered with the nav icons; toggle floats at the right edge */
  .isg-sidebar:not(.is-expanded) .isg-sidebar-head { justify-content: center; }
  .isg-sidebar:not(.is-expanded) .isg-logo-word { display: none; }
  .isg-sidebar:not(.is-expanded) .isg-sidebar-toggle {
    position: absolute; top: 50%; right: -4px; transform: translateY(-50%);
    width: 18px; height: 18px;
    background: transparent; border-color: transparent;
  }
  .isg-sidebar-toggle:hover { color: var(--fg-0); border-color: var(--border-1); }
  .isg-sidebar-toggle i, .isg-sidebar-toggle svg { width: 14px; height: 14px; display: block; }

  .isg-nav { display: flex; flex-direction: column; gap: 2px; margin-top: 8px; }
  .isg-sidebar-foot { margin-top: auto; display: flex; flex-direction: column; gap: 2px; padding-top: 12px; border-top: 1px solid var(--border-0); }
  .isg-nav-item {
    display: flex; align-items: center; gap: 12px;
    height: 44px; padding: 0 12px;
    border-radius: var(--r-md);
    background: transparent; border: 0;
    color: var(--fg-1); font: 500 var(--fs-16)/var(--lh-16) var(--font-ui);
    cursor: pointer; text-align: left; width: 100%;
    transition: background var(--d-fast) var(--ease), color var(--d-fast) var(--ease);
    white-space: nowrap;
  }
  .isg-nav-item i, .isg-nav-item svg { width: 20px; height: 20px; flex-shrink: 0; display: block; }
  .isg-nav-item span { opacity: 0; transition: opacity var(--d-fast) var(--ease); }
  .isg-sidebar.is-expanded .isg-nav-item span { opacity: 1; }
  .isg-sidebar:not(.is-expanded) .isg-nav-item { justify-content: center; padding: 0; }
  .isg-sidebar:not(.is-expanded) .isg-nav-item span { display: none; }
  .isg-nav-item:hover { background: var(--bg-2); color: var(--fg-0); }
  .isg-nav-item.is-active {
    background: var(--accent-soft); color: var(--fg-0);
    box-shadow: inset 0 0 0 1px var(--border-1);
  }
  .isg-nav-logout { margin-top: 4px; }
  .isg-nav-logout:hover { background: rgba(220, 60, 60, 0.12); color: #e05555; }

  /* Public showcase (Plan 9): locked nav + banner + embed */
  .isg-nav-item:disabled { opacity: 0.35; cursor: not-allowed; }
  .isg-nav-item:disabled:hover { background: transparent; color: inherit; }
  /* The statement band: the first thing a visitor reads, so full-size type on a raised strip with an accent edge */
  .isg-kiosk-banner {
    display: flex; flex-direction: column; align-items: center; gap: 4px;
    padding: 12px 20px; background: var(--bg-2); color: var(--fg-0); text-align: center;
    border-top: 3px solid var(--accent); border-bottom: 1px solid var(--border-1);
  }
  .isg-kiosk-banner-lead { margin: 0; max-width: 1080px; font-size: 15px; line-height: 1.45; }
  .isg-kiosk-banner strong { font-weight: 700; }
  .isg-kiosk-banner a { color: var(--accent); font-weight: 600; text-decoration: none; }
  .isg-kiosk-banner a:hover, .isg-kiosk-banner a:focus-visible { text-decoration: underline; }
  .isg-kiosk-banner-asof { color: var(--fg-2); font-family: var(--font-mono); font-size: 12px; }
  @media (max-width: 720px) {
    .isg-kiosk-banner { padding: 10px 14px; }
    .isg-kiosk-banner-lead { font-size: 14px; line-height: 1.4; }
  }
  .isg-app.is-embed { pointer-events: none; }
  .isg-app.is-embed .isg-sidebar, .isg-app.is-embed .isg-topbar, .isg-app.is-embed .isg-msubhead,
  .isg-app.is-embed .isg-incident-panel, .isg-app.is-embed .isg-mactivity-bar,
  .isg-app.is-embed .isg-heat-controls, .isg-app.is-embed .mapboxgl-ctrl-group { display: none !important; }
  .isg-app.is-embed .isg-main { width: 100%; }
  /* Kiosk root is a column (banner above shell) so banner + shell together fill exactly one viewport */
  .isg-app.is-kiosk { display: flex; flex-direction: column; height: 100vh; min-height: 0; }
  .isg-app.is-kiosk .isg-kiosk-banner { flex-shrink: 0; }
  .isg-app.is-kiosk .isg-shell { flex: 1; min-height: 0; height: auto; }
  /* Showcase 403/404/500 (sites/crime-stats/{403,404,500}.html) — replaces IONOS's parking page */
  .isg-errorpage { min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 24px; box-sizing: border-box; background: var(--bg-0); }
  .isg-errorpage-card { max-width: 440px; text-align: center; }
  .isg-errorpage-code { color: var(--fg-3); font-family: var(--font-mono); font-size: 12px; }
  .isg-errorpage h1 { margin: 8px 0 12px; font-size: 20px; color: var(--fg-0); }
  .isg-errorpage p { margin: 0 0 16px; font-size: 14px; color: var(--fg-1); }
  .isg-errorpage a { color: var(--accent); text-decoration: none; }

  /* ============================================================
     Topbar
     ============================================================ */
  .isg-topbar {
    min-height: 44px; border-bottom: 1px solid var(--border-0);
    display: flex; align-items: center; padding: 6px 16px; gap: 16px;
    background: var(--bg-1);
  }
  .isg-topbar-l { display: flex; align-items: center; gap: 16px; }
  .isg-topbar-c { flex: 1; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
  .isg-topbar-r { display: flex; align-items: center; gap: 8px; }
  .isg-crumb { display: flex; flex-direction: column; align-items: flex-start; gap: 0; line-height: 1.2; white-space: nowrap; color: var(--fg-2); font: var(--t-caption); }
  .isg-crumb strong { color: var(--fg-0); font: var(--t-body-md); font-weight: 600; }

  /* Alpine x-if needs a single root element; this wrapper stays out of layout */
  .isg-contents { display: contents; }

  /* Segment */
  .isg-segment {
    display: inline-flex; padding: 3px; border-radius: var(--r-md);
    background: var(--bg-1); border: 1px solid var(--border-0);
  }
  .isg-segment button {
    height: 28px; padding: 0 10px; border: 0; background: transparent;
    color: var(--fg-1); font: var(--t-caption); border-radius: 7px; cursor: pointer; white-space: nowrap;
    display: inline-flex; align-items: center; gap: 6px;
  }
  .isg-segment button.is-active { background: var(--accent-soft); color: var(--fg-0); }
  .isg-segment button:not(.is-active):hover { color: var(--fg-0); }
  .isg-segment-sm button { padding: 0 10px; }

  /* Dropdown */
  .isg-drop { position: relative; }
  .isg-drop-btn {
    display: inline-flex; align-items: center; gap: 5px;
    height: 32px; padding: 0 10px; border-radius: var(--r-md);
    background: var(--bg-1); border: 1px solid var(--border-0);
    color: var(--fg-1); font: var(--t-caption); cursor: pointer;
  }
  .isg-drop-btn:hover { color: var(--fg-0); border-color: var(--border-1); }
  .isg-drop-btn i { width: 13px; height: 13px; }
  .isg-drop-menu {
    position: absolute; top: calc(100% + 4px); left: 0; min-width: 180px;
    background: var(--bg-1); border: 1px solid var(--border-1); border-radius: var(--r-md);
    box-shadow: var(--elev-pop); z-index: var(--z-menu); padding: 4px;
  }
  .isg-drop-menu button {
    display: block; width: 100%; text-align: left;
    height: 32px; padding: 0 12px; border-radius: 6px;
    background: transparent; border: 0; color: var(--fg-1);
    font: var(--t-body); cursor: pointer;
  }
  .isg-drop-menu button:hover { background: var(--bg-2); color: var(--fg-0); }
  .isg-drop-menu button.is-active { color: var(--accent); }
  /* Inline filter row at the foot of a drop menu (zones name filter) */
  .isg-drop-filter { padding: 4px; border-top: 1px solid var(--border-0); margin-top: 4px; }
  .isg-drop-filter .isg-input { width: 100%; height: 28px; padding: 0 10px; font-size: 12px; }

  .isg-icon-btn {
    width: 36px; height: 36px; display: grid; place-items: center;
    border-radius: var(--r-md); border: 1px solid var(--border-0);
    background: var(--bg-1); color: var(--fg-1); cursor: pointer; position: relative;
  }
  .isg-icon-btn:hover { color: var(--fg-0); border-color: var(--border-1); }
  .isg-icon-btn i { width: 16px; height: 16px; }
  .isg-icon-btn .isg-dot { position: absolute; top: 8px; right: 8px; width: 6px; height: 6px; border-radius: 50%; background: var(--sev-violent); box-shadow: 0 0 8px var(--sev-violent); }
  /* Inline variant — flows with text (sidebar nav label) instead of pinning to a corner */
  .isg-dot-inline { position: relative; top: -1px; margin-left: 4px; display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px var(--accent); }

  .isg-refresh-btn { border-radius: 50%; }
  .isg-refresh-btn i { transition: transform 0.6s ease; }
  .isg-refresh-btn.is-spinning i { animation: spin 0.7s linear infinite; }

  /* ============================================================
     Map view
     ============================================================ */
  .isg-map-grid {
    display: grid;
    grid-template-columns: 1fr 360px;
    gap: 16px; height: calc(100vh - 56px - 56px - 32px);
    min-height: 560px;
  }
  .isg-map-mod { height: 100%; }
  .isg-map { position: relative; width: 100%; height: 100%; border-radius: var(--r-lg); overflow: hidden; }
  .isg-map-svg { width: 100%; height: 100%; display: block; }

  .isg-map-tl, .isg-map-br {
    position: absolute; padding: 10px 14px; border-radius: var(--r-md);
    background: rgba(7,16,12,0.7); backdrop-filter: blur(8px);
    border: 1px solid var(--border-0);
    font: var(--t-caption); display: flex; align-items: center; gap: 8px;
    z-index: var(--z-controls);
  }
  .isg-map-tl { top: 16px; left: 16px; }
  .isg-map-br { bottom: 16px; right: 16px; flex-direction: column; align-items: flex-start; gap: 4px; padding: 10px 12px; }
  .isg-map-tl strong { color: var(--fg-0); font-size: 14px; }

  .isg-legend { display: flex; flex-direction: column; gap: 4px; }
  .isg-legend-row { display: flex; align-items: center; gap: 8px; color: var(--fg-1); font-size: 11px; }
  .isg-sev-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }

  /* Map pin pulse */
  @keyframes isg-pulse { 0% { r: 6; opacity: .8; } 100% { r: 18; opacity: 0; } }
  .isg-pulse { animation: isg-pulse 2s ease-out infinite; }

  /* Map popover */
  .isg-mappop {
    position: absolute; transform: translate(-50%, calc(-100% - 14px));
    background: var(--bg-1); border: 1px solid var(--border-1);
    border-radius: var(--r-md); padding: 10px 12px; min-width: 220px;
    box-shadow: var(--elev-pop); z-index: var(--z-popover); pointer-events: none;
  }
  .isg-mappop-head { display: flex; align-items: center; gap: 8px; }
  .isg-mappop-head strong { font-size: 14px; }
  .isg-mappop-meta { font-size: 11px; color: var(--fg-2); margin-top: 4px; }

  /* ============================================================
     Incident list
     ============================================================ */
  .isg-list-mod { display: flex; flex-direction: column; height: 100%; }
  .isg-list-head { padding: 16px 20px 12px; display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid var(--border-0); }
  .isg-list-head h3 { font: var(--t-h3); }
  .isg-list { flex: 1; overflow-y: auto; padding: 8px; display: flex; flex-direction: column; gap: 2px; }

  .isg-row {
    position: relative; display: grid; grid-template-columns: 4px 1fr auto; gap: 12px; align-items: center;
    padding: 10px 12px; padding-left: 14px;
    background: transparent; border: 0; border-radius: var(--r-md);
    text-align: left; cursor: pointer; color: var(--fg-1);
    transition: background var(--d-fast) var(--ease);
  }
  .isg-row:hover { background: var(--bg-2); color: var(--fg-0); }
  .isg-row.is-selected { background: var(--bg-3); color: var(--fg-0); }
  .isg-row.is-selected::after { content: ''; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--border-1); pointer-events: none; }
  .isg-row:not(.is-live) { opacity: .82; }
  .isg-row-bar { width: 3px; align-self: stretch; border-radius: 3px; min-height: 28px; }
  .isg-row-main { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
  .isg-row-title { display: flex; align-items: center; gap: 8px; font: var(--t-body-md); }
  .isg-row-title strong { color: var(--fg-0); font-weight: 600; font-size: 13px; }
  .isg-zonechip { color: var(--accent); font-size: 9px; }
  .isg-row-meta { font-size: 11px; color: var(--fg-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .isg-row-time { font: var(--t-mono-sm); color: var(--fg-2); display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
  .isg-livedot { width: 6px; height: 6px; border-radius: 50%; background: var(--rec-live); box-shadow: 0 0 8px var(--rec-live); animation: isg-blink 1.6s ease-in-out infinite; }
  @keyframes isg-blink { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

  /* ============================================================
     Detail slide-over
     ============================================================ */
  .isg-detail {
    position: absolute; top: 0; right: 0; width: 420px; height: 100%;
    padding: 16px; z-index: var(--z-panel); pointer-events: none;
  }
  .isg-detail-inner { width: 100%; height: 100%; display: flex; flex-direction: column; pointer-events: auto; animation: isg-slide-in var(--d-med) var(--ease); }
  @keyframes isg-slide-in { from { transform: translateX(20px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
  .isg-detail-head { display: flex; justify-content: space-between; align-items: flex-start; padding: 24px 24px 16px; }
  .isg-detail-head h2 { margin-top: 4px; }

  .isg-eyebrow { font: var(--t-caption); color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.08em; font-size: 11px; }

  .isg-kv { display: grid; grid-template-columns: 1fr 1fr; gap: 16px 24px; padding: 0 24px; margin: 0; }
  .isg-kv > div { display: flex; flex-direction: column; gap: 4px; }
  .isg-kv dt { font: var(--t-caption); color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.06em; font-size: 10.5px; }
  .isg-kv dd { margin: 0; font: var(--t-body-md); color: var(--fg-0); }

  .isg-detail-section { padding: 20px 24px; border-top: 1px solid var(--border-0); margin-top: 20px; }
  .isg-detail-section p { color: var(--fg-1); }
  .isg-detail-actions { padding: 16px 24px 24px; display: flex; gap: 8px; margin-top: auto; border-top: 1px solid var(--border-0); }

  /* Buttons.
     Height is the app-wide control height (32px) shared with the form-control family
     (.isg-input / .isg-picker-btn / .isg-pill) so buttons and fields line up wherever they
     sit in the same row (notably the builder). Explicit height is required — Safari won't
     infer it from padding/line-height on a flex control. */
  .isg-btn {
    display: inline-flex; align-items: center; gap: 8px; padding: 0 14px; height: 32px;
    background: var(--accent); color: #061410;
    border: 0; border-radius: var(--r-md); font: var(--t-body-md); font-weight: 600; font-size: 13px; cursor: pointer;
    transition: filter var(--d-fast) var(--ease);
  }
  .isg-btn:hover:not(:disabled) { filter: brightness(1.1); }
  .isg-btn:disabled { opacity: 0.4; cursor: not-allowed; }
  .isg-btn i { width: 14px; height: 14px; }
  .isg-btn-ghost { background: var(--bg-2); color: var(--fg-1); box-shadow: inset 0 0 0 1px var(--border-1); }
  .isg-btn-ghost:hover { background: var(--bg-3); color: var(--fg-0); }
  .isg-btn-ghost:disabled { opacity: 0.38; cursor: default; }
  .isg-btn-sm { height: 28px; padding: 0 10px; font-size: 12px; }

  /* ============================================================
     Stats view
     ============================================================ */
  .isg-stats-grid {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px;
  }
  .isg-stats-grid > .isg-module:nth-child(1),
  .isg-stats-grid > .isg-module:nth-child(2),
  .isg-stats-grid > .isg-module:nth-child(3) { grid-column: span 1; }
  .isg-stats-grid > .isg-module:nth-child(4) { grid-column: span 2; }
  .isg-stats-grid > .isg-module:nth-child(5) { grid-column: span 2; }
  .isg-stats-grid > .isg-module:nth-child(6) { grid-column: span 2; }
  .isg-stats-grid > .isg-module:nth-child(7) { grid-column: span 2; }

  .isg-data-lg { font: var(--t-data-lg); margin-top: 6px; letter-spacing: -0.02em; }
  .isg-data-md { font: 600 18px/22px var(--font-mono); }
  .isg-caption { font: var(--t-caption); }
  .isg-mono { font-family: var(--font-mono); }
  .isg-fg2 { color: var(--fg-2); }
  .isg-delta { display: inline-flex; align-items: center; gap: 4px; font: var(--t-caption); margin-top: 8px; }
  .isg-delta.is-up { color: var(--sev-traffic); }
  .isg-delta.is-down { color: var(--sev-violent); }
  .isg-delta i { width: 12px; height: 12px; }

  .isg-trend { width: 100%; height: auto; }

  .isg-bars { display: flex; flex-direction: column; gap: 8px; margin-top: 8px; }
  .isg-bar { display: grid; grid-template-columns: 88px 1fr 36px; gap: 10px; align-items: center; font: var(--t-caption); }
  .isg-bar-l { color: var(--fg-1); }
  .isg-bar-track { height: 6px; background: var(--bg-2); border-radius: var(--r-pill); overflow: hidden; }
  .isg-bar-fill { display: block; height: 100%; border-radius: var(--r-pill); }
  .isg-bar-v { color: var(--fg-0); text-align: right; }

  .isg-watches { display: flex; gap: 16px; align-items: flex-end; height: 140px; padding: 8px 0; }
  .isg-watch-col { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 6px; height: 100%; justify-content: flex-end; }
  .isg-watch-bar { width: 28px; flex: 1; background: var(--bg-2); border-radius: 6px; overflow: hidden; display: flex; align-items: flex-end; }
  .isg-watch-bar > span { width: 100%; background: linear-gradient(180deg, var(--accent), var(--accent-deep)); border-radius: 6px; }

  .isg-table { width: 100%; border-collapse: collapse; }
  .isg-table thead th {
    text-align: left; font: var(--t-caption); color: var(--fg-2); text-transform: uppercase; letter-spacing: 0.06em;
    padding: 8px 16px; font-size: 10.5px; border-bottom: 1px solid var(--border-0);
  }
  .isg-table tbody td { padding: 12px 16px; border-bottom: 1px solid var(--border-0); font-size: 13px; color: var(--fg-1); }
  .isg-table tbody tr:last-child td { border-bottom: 0; }
  .isg-mini-bar { width: 80px; height: 4px; background: var(--bg-2); border-radius: 2px; overflow: hidden; }
  .isg-mini-bar > span { display: block; height: 100%; background: var(--accent); border-radius: 2px; }

  /* ============================================================
     Area Studies view
     ============================================================ */
  .isg-areas-grid { display: grid; grid-template-columns: 320px 1fr; gap: 16px; min-height: 600px; }
  .isg-areas-list { display: flex; flex-direction: column; }
  .isg-areas-detail { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-content: start; }
  .isg-areas-detail > .isg-module:first-child { grid-column: 1 / -1; }
  .isg-areas-mini { grid-column: 1 / -1; height: 280px; overflow: hidden; }
  .isg-areas-mini .isg-map-svg { width: 100%; height: 100%; }

  .isg-zonecard {
    display: flex; justify-content: space-between; align-items: center;
    padding: 12px 16px; margin: 4px 8px;
    background: transparent; border: 0; border-radius: var(--r-md);
    text-align: left; cursor: pointer; color: var(--fg-1);
    transition: background var(--d-fast) var(--ease);
  }
  .isg-zonecard:hover { background: var(--bg-2); color: var(--fg-0); }
  .isg-zonecard.is-selected { background: var(--accent-soft); color: var(--fg-0); box-shadow: inset 0 0 0 1px var(--border-1); }
  .isg-zonecard h3 { font: var(--t-body-md); font-weight: 600; font-size: 14px; }
  .isg-zonecard-r { display: flex; flex-direction: column; align-items: flex-end; gap: 2px; }

  /* ============================================================
     Direction overrides
     ============================================================ */

  /* Direction A — the brief, faithful. (default; nothing extra) */

  /* Direction B — Tactical */
  [data-direction="B"] {
    --r-lg: 6px;
    --r-md: 4px;
    --bg-0: #050907;
    --bg-1: #0A100D;
  }
  [data-direction="B"] h1, [data-direction="B"] h2, [data-direction="B"] h3 {
    font-family: var(--font-mono); letter-spacing: 0.02em; text-transform: uppercase; font-weight: 600;
  }
  [data-direction="B"] .isg-data-lg { letter-spacing: 0; }
  [data-direction="B"] .isg-module {
    background-image: linear-gradient(90deg, var(--bg-1) 95%, transparent), repeating-linear-gradient(0deg, transparent 0 39px, rgba(255,255,255,0.012) 39px 40px);
  }
  [data-direction="B"] .isg-row-bar { width: 6px; }
  [data-direction="B"] .isg-sidebar { background: linear-gradient(180deg, rgba(0,0,0,0.4), rgba(0,0,0,0.1)); }
  [data-direction="B"] .isg-nav-item { font-family: var(--font-mono); text-transform: uppercase; font-size: 11px; letter-spacing: 0.08em; }

  /* Direction C — Stealth Blue (handled by data-theme="blue" already). Just lighter touch */
  [data-direction="C"] .isg-app::before {
    background:
      radial-gradient(60% 50% at 50% -10%, var(--accent-soft), transparent 70%),
      radial-gradient(40% 40% at 0% 0%, var(--accent-soft), transparent 70%);
  }

  /* Direction D — Intel Brief: cleaner, less ambient motion, bigger headlines */
  [data-direction="D"] {
    --r-lg: 20px;
  }
  [data-direction="D"] .isg-module::before { border-color: rgba(255,255,255,0.06); }
  [data-direction="D"] .isg-spot { opacity: .6; }
  [data-direction="D"] .isg-app::before { opacity: .35; }
  [data-direction="D"] h1 { font: var(--t-display); letter-spacing: -0.02em; }
  [data-direction="D"] h2 { font-size: 26px; line-height: 30px; letter-spacing: -0.02em; }
  [data-direction="D"] .isg-data-lg { font-family: var(--font-ui); font-weight: 700; font-size: 36px; }

/* ── View containers ── */
.isg-view {
  display: grid;
  place-items: center;
  min-height: 400px;
}

/* ── Zone polygon: solid glowing line (replaces prototype dashed stroke) ── */
.isg-zone-polygon {
  stroke-dasharray: none !important;
  filter: drop-shadow(0 0 6px var(--accent));
}

/* ── Alpine: hide elements before Alpine activates ── */
[x-cloak] { display: none !important; }

/* ============================================================
   Map view — full-bleed layout
   ============================================================ */

/* Override the default .isg-content padding for the map view.
   The map div fills the entire content area edge-to-edge. */
.isg-map-wrap {
  position: relative;
  display: flex;
  flex: 1;
  min-width: 0;
  overflow: hidden;
}

/* The Mapbox canvas container */
#isg-map-canvas {
  flex: 1;
  min-width: 0;
}

/* ── Incident list panel (right side) ── */
.isg-incident-panel {
  width: 300px;
  position: absolute;
  top: 16px;
  right: 0;
  bottom: 0;
  padding-right: 16px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding-bottom: 16px;
  z-index: var(--z-popover);
}

/* (Activity module container is .isg-module--activity — see Container primitives) */

.isg-incident-panel-head {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-0);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
}

/* Universal panel header (left zones panel + right activity panel, map + areas) */
.isg-incident-panel-head h3,
.isg-zones-head h3 {
  font: var(--t-panel-head);
  color: var(--text-0);
  margin: 0;
  text-transform: uppercase;
  letter-spacing: .06em;
}

.isg-incident-count {
  font: var(--t-label-sm);
  color: var(--text-3);
}

/* Activity filter box (map + areas) — sits under the panel head, above the feed */
.isg-activity-search {
  display: flex; align-items: center; gap: 7px; flex-shrink: 0;
  margin: 10px 16px 4px;
  padding: 6px 9px; border: 1px solid var(--border-0); border-radius: 7px; background: var(--bg-2);
  transition: border-color var(--d-fast);
}
.isg-activity-search:focus-within { border-color: var(--border-1); }
.isg-activity-search-icon { width: 14px; height: 14px; color: var(--text-3); flex-shrink: 0; }
.isg-activity-search-input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  color: var(--fg-0); font: var(--t-body);
}
.isg-activity-search-input::placeholder { color: var(--text-3); }
.isg-activity-search-clear {
  flex-shrink: 0; border: none; background: none; cursor: pointer;
  color: var(--text-2); font-size: 17px; line-height: 1; padding: 0 4px;
  transition: color var(--d-fast);
}
.isg-activity-search-clear:hover { color: var(--fg-0); }

.isg-incident-list {
  flex: 1;
  overflow-y: auto;
  overflow-x: hidden;
}

/* Empty state */
.isg-incident-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 200px;
  color: var(--text-3);
  font: var(--t-body-sm);
  text-align: center;
  padding: 24px;
}

/* Each incident row */
.isg-incident-row {
  display: flex;
  align-items: stretch;
  cursor: pointer;
  border-bottom: 1px solid var(--border-0);
  transition: background var(--d-fast);
  min-height: 44px;
}

.isg-incident-row:hover {
  background: var(--bg-2);
}

.isg-incident-row.is-hovered {
  background: var(--bg-2);
  box-shadow: inset 0 0 0 1px rgba(61, 220, 151, 0.22);
}

.isg-incident-row.is-selected {
  background: var(--bg-2);
}

/* Severity color bar (left edge) */
.isg-sev-bar {
  width: 4px;
  flex-shrink: 0;
  border-radius: 2px 0 0 2px;
}

.isg-sev-bar[data-pc="8"] { background: var(--pc-8); }
.isg-sev-bar[data-pc="7"] { background: var(--pc-7); }
.isg-sev-bar[data-pc="6"] { background: var(--pc-6); }
.isg-sev-bar[data-pc="5"] { background: var(--pc-5); }
.isg-sev-bar[data-pc="4"] { background: var(--pc-4); }
.isg-sev-bar[data-pc="3"] { background: var(--pc-3); }
.isg-sev-bar[data-pc="2"] { background: var(--pc-2); }
.isg-sev-bar[data-pc="1"] { background: var(--pc-1); }
.isg-sev-bar[data-pc="0"] { background: var(--pc-0); }

.isg-sev-bar[data-pri="1"] { background: var(--pri-1); }
.isg-sev-bar[data-pri="2"] { background: var(--pri-2); }
.isg-sev-bar[data-pri="3"] { background: var(--pri-3); }
.isg-sev-bar[data-pri="4"] { background: var(--pri-4); }
.isg-sev-bar[data-pri="0"] { background: var(--pc-0); } /* 0 = unknown priority; borrows --pc-0 neutral gray (no --pri-0 token — priority is a real 1–4 domain) */

.isg-incident-row-body {
  flex: 1;
  min-width: 0;
  padding: 6px 12px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Activity tiles run hundreds deep — sized down from the original 14/12 + 60px row to a
   denser ~47px tile (title 13, meta 11), keeping the title↔meta ratio so it reads the same,
   just smaller. Shared by every activity-panel-type list (map, areas, search, tracked tiles). */
.isg-incident-type {
  font: 500 var(--fs-13)/var(--lh-13) var(--font-ui);
  color: var(--fg-0);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.isg-incident-meta {
  font: 500 11px/15px var(--font-ui);
  color: var(--fg-2);
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 6px;
}

.isg-incident-meta-addr {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.isg-incident-meta-r {
  flex-shrink: 0;
  white-space: nowrap;
  color: var(--fg-3);
}

/* ── Incident detail panel (slides in from right, over the list) ── */
.isg-incident-detail {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  /* bg-0 (page) so the bg-1 cards read as raised Module surfaces — mirrors Module-on-page. */
  background: var(--bg-0);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transform: translateX(100%);
  transition: transform var(--d-med) var(--ease);
  z-index: var(--z-panel);
}

.isg-incident-detail.is-open {
  transform: translateX(0);
}

/* Header — full-width, three regions (offense + narrative · badges · track + reference) */
.isg-detail-head {
  padding: 12px 16px 12px 0;
  border-bottom: 1px solid var(--border-0);
  display: flex;
  align-items: flex-start;
  gap: 10px;
  flex-shrink: 0;
  position: relative;
  min-height: 56px;
}

.isg-detail-sev-bar {
  width: 4px;
  align-self: stretch;
  flex-shrink: 0;
  border-radius: 0 2px 2px 0;
}
.isg-detail-sev-bar[data-pc="8"] { background: var(--pc-8); }
.isg-detail-sev-bar[data-pc="7"] { background: var(--pc-7); }
.isg-detail-sev-bar[data-pc="6"] { background: var(--pc-6); }
.isg-detail-sev-bar[data-pc="5"] { background: var(--pc-5); }
.isg-detail-sev-bar[data-pc="4"] { background: var(--pc-4); }
.isg-detail-sev-bar[data-pc="3"] { background: var(--pc-3); }
.isg-detail-sev-bar[data-pc="2"] { background: var(--pc-2); }
.isg-detail-sev-bar[data-pc="1"] { background: var(--pc-1); }
.isg-detail-sev-bar[data-pc="0"] { background: var(--pc-0); }

.isg-detail-sev-bar[data-pri="1"] { background: var(--pri-1); }
.isg-detail-sev-bar[data-pri="2"] { background: var(--pri-2); }
.isg-detail-sev-bar[data-pri="3"] { background: var(--pri-3); }
.isg-detail-sev-bar[data-pri="4"] { background: var(--pri-4); }
.isg-detail-sev-bar[data-pri="0"] { background: var(--pc-0); }

.isg-detail-back {
  background: none;
  border: none;
  color: var(--fg-2);
  cursor: pointer;
  display: flex;
  align-items: center;
  padding: 4px;
  border-radius: var(--r-sm);
  transition: color var(--d-fast), background var(--d-fast);
  flex-shrink: 0;
}
.isg-detail-back:hover {
  color: var(--fg-0);
  background: var(--bg-2);
}

/* Header left region — offense title + de-emphasized narrative copy */
.isg-detail-head-main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding-top: 2px;
}
.isg-detail-headline {
  font: var(--t-h3);
  font-weight: 600;
  color: var(--fg-0);
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.isg-detail-subnarr {
  font: var(--t-caption);
  color: var(--fg-2);
  line-height: 1.4;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Chip row under the call-panel headline (priority + Live) */
.isg-detail-head-chips {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
}

/* Header center region — enforcement count badges */
.isg-detail-head-badges {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
  align-self: center;
}
.isg-detail-cbadge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font: var(--t-caption);
  font-weight: 600;
  letter-spacing: .03em;
  white-space: nowrap;
}
.isg-detail-cbadge--arrest { background: rgba(168, 15, 15, 0.15); color: var(--sev-violent); }
/* Charges are enforcement (red), not suspect (yellow) — keep them out of the suspect palette. */
.isg-detail-cbadge--charge { background: rgba(168, 15, 15, 0.15); color: var(--sev-violent); }

/* Header right region — Track This, with the incident reference set beneath it */
.isg-detail-head-side {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
  flex-shrink: 0;
}
.isg-detail-ref { display: flex; flex-direction: column; align-items: flex-end; }
.isg-detail-ref-num { font: var(--t-mono-sm); color: var(--fg-2); }

/* Body */
.isg-detail-body {
  flex: 1;
  overflow-y: auto;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* Category + severity row */
.isg-detail-meta-row {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  flex-wrap: wrap;
}

.isg-detail-cat-badge {
  display: inline-flex;
  align-items: center;
  padding: 3px 9px;
  border-radius: var(--r-pill);
  font: var(--t-caption);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}
.isg-detail-cat-badge[data-cat="violent"]     { background: rgba(232,89,89,0.15);   color: var(--sev-violent); }
.isg-detail-cat-badge[data-cat="property"]    { background: rgba(240,140,58,0.15);  color: var(--sev-property); }
.isg-detail-cat-badge[data-cat="disturbance"] { background: rgba(232,197,71,0.15);  color: var(--sev-disturb); }
.isg-detail-cat-badge[data-cat="suspicious"]  { background: rgba(91,168,255,0.15);  color: var(--sev-suspicious); }
.isg-detail-cat-badge[data-cat="traffic"]     { background: rgba(61,220,151,0.15);  color: var(--sev-traffic); }
.isg-detail-cat-badge[data-cat="other"]       { background: rgba(138,149,145,0.15); color: var(--sev-other); }

.isg-detail-sev-display {
  display: flex;
  align-items: center;
  gap: 6px;
  font: var(--t-body-sm);
  color: var(--fg-1);
}

.isg-detail-live-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  background: rgba(61, 220, 151, 0.08);
  border: 1px solid rgba(61, 220, 151, 0.2);
  font: var(--t-caption);
  color: var(--accent);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* Dispatch-priority chip (1 = highest urgency → hot; 3/4 → neutral/faded) */
.isg-detail-pri-chip {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: var(--r-pill);
  font: var(--t-caption);
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  white-space: nowrap;
}
.isg-detail-pri-chip[data-pri="1"] { background: rgba(232,89,89,0.15);  color: var(--sev-violent); }
.isg-detail-pri-chip[data-pri="2"] { background: rgba(240,140,58,0.15); color: var(--sev-property); }
.isg-detail-pri-chip[data-pri="3"] { background: var(--bg-2); border: 1px solid var(--border-0); color: var(--fg-1); }
.isg-detail-pri-chip[data-pri="4"] { background: var(--bg-2); border: 1px solid var(--border-0); color: var(--fg-2); }

/* Label / value fields */
.isg-detail-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.isg-detail-field-end { justify-content: flex-end; }

.isg-detail-label {
  font: var(--t-caption);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.isg-detail-value {
  font: var(--t-body);
  color: var(--fg-0);
}

.isg-detail-mono {
  font: var(--t-mono);
  color: var(--fg-1);
}

/* Two fields side by side */
.isg-detail-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
}

/* Unit chips */
.isg-detail-units {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin-top: 2px;
}
.isg-detail-unit-chip {
  font: var(--t-mono-sm);
  color: var(--fg-1);
  background: var(--bg-2);
  border: 1px solid var(--border-0);
  border-radius: var(--r-sm);
  padding: 2px 7px;
}

/* Narrative */
.isg-detail-narrative {
  font: var(--t-small);
  color: var(--fg-1);
  line-height: 1.65;
  white-space: pre-wrap;
}

/* Footer — stacks Center-on-Map + Add-to-report (Plan 7 Task 4.3) full-width. */
.isg-detail-foot {
  padding: 12px 16px;
  border-top: 1px solid var(--border-0);
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Zone tooltip (Mapbox popup override) */
.mapboxgl-popup-content {
  background: var(--bg-1) !important;
  border: 1px solid var(--border-0) !important;
  color: var(--text-0) !important;
  border-radius: var(--r-md) !important;
  padding: 12px 14px !important;
  font: var(--t-body-sm) !important;
  box-shadow: var(--elev-2) !important;
}

.mapboxgl-popup-tip {
  display: none !important;
}

.mapboxgl-ctrl-logo {
  opacity: 0.25 !important;
}

.mapboxgl-ctrl-attrib {
  opacity: 0.25 !important;
}

.mapboxgl-ctrl-group {
  background: #3a3a3a !important;
  border: 1px solid #555 !important;
  box-shadow: none !important;
}

.mapboxgl-ctrl-group button {
  background-color: transparent !important;
}

.mapboxgl-ctrl-group button .mapboxgl-ctrl-icon {
  filter: brightness(0.6) !important;
}

.mapboxgl-ctrl-group button:hover .mapboxgl-ctrl-icon {
  filter: brightness(0.85) !important;
}

.mapboxgl-ctrl-group button + button {
  border-top: 1px solid #555 !important;
}

.isg-zone-popup-name {
  font: var(--t-body-md);
  color: var(--text-0);
  margin-bottom: 4px;
}

.isg-zone-popup-count {
  font: var(--t-label-sm);
  color: var(--text-2);
}

/* Activity panel legend */
/* (Legend module container is .isg-module--legend — see Container primitives) */

.isg-legend-header {
  background: var(--bg-2);
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-0);
}

.isg-legend-title {
  font: var(--t-label-sm);
  color: var(--fg-1);
  text-transform: uppercase;
  letter-spacing: .06em;
}

.isg-legend-section-label {
  font-size: 11px;
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: .06em;
  padding: 8px 16px 0;
}

.isg-legend-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 8px 12px;
}

.isg-legend-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  padding: 7px 8px;
  border-radius: var(--r-sm);
  text-align: left;
  transition: background var(--d-fast), opacity var(--d-fast);
}

.isg-legend-item:hover {
  background: var(--bg-2);
}

.isg-legend-item.is-active {
  background: var(--bg-3);
}

.isg-legend-item.is-dimmed {
  opacity: 0.3;
}

.isg-legend-item.is-dimmed:hover {
  opacity: 0.7;
}

.isg-legend-pin {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  flex-shrink: 0;
}

.isg-legend-label {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.isg-legend-sev-num {
  font-size: 13px;
  color: var(--fg-1);
  line-height: 1;
}

.isg-legend-examples {
  font-size: 11px;
  color: var(--fg-2);
  line-height: 1;
}

/* Pin colors match penal-class/priority ramps in map.js */
.isg-legend-pin[data-pc="8"] { background: var(--pc-8); }
.isg-legend-pin[data-pc="7"] { background: var(--pc-7); }
.isg-legend-pin[data-pc="6"] { background: var(--pc-6); }
.isg-legend-pin[data-pc="5"] { background: var(--pc-5); }
.isg-legend-pin[data-pc="4"] { background: var(--pc-4); }
.isg-legend-pin[data-pc="3"] { background: var(--pc-3); }
.isg-legend-pin[data-pc="2"] { background: var(--pc-2); }
.isg-legend-pin[data-pc="1"] { background: var(--pc-1); }
.isg-legend-pin[data-pc="0"] { background: var(--pc-0); }

.isg-legend-pin[data-pri="1"] { background: var(--pri-1); }
.isg-legend-pin[data-pri="2"] { background: var(--pri-2); }
.isg-legend-pin[data-pri="3"] { background: var(--pri-3); }
.isg-legend-pin[data-pri="4"] { background: var(--pri-4); }

/* Pin hover tooltip */
.isg-map-tip .mapboxgl-popup-content {
  padding: 5px 10px !important;
  font: var(--t-label-sm) !important;
  color: var(--fg-0) !important;
  max-width: 220px !important;
  border-radius: 6px !important;
  line-height: 1.4 !important;
}

/* Coincident-pin stack list — hover popup listing every pin on one plotted point */
.isg-map-stack .mapboxgl-popup-content {
  padding: 6px !important;
  min-width: 180px !important;
  max-width: 280px !important;
}
.isg-stack-list { display: flex; flex-direction: column; gap: 1px; max-height: 320px; overflow-y: auto; }
.isg-stack-head {
  font: var(--t-label-sm);
  color: var(--text-2);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 2px 6px 5px;
}
.isg-stack-row {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 5px 6px;
  background: transparent;
  border: 0;
  border-radius: var(--r-sm);
  color: var(--text-0);
  font: var(--t-body-sm);
  text-align: left;
  cursor: pointer;
}
.isg-stack-row:hover { background: var(--bg-2); }
.isg-stack-dot {
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border-radius: 50%;
}
.isg-stack-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Colors match penal-class/priority ramps in tokens.css */
.isg-stack-dot[data-pc="8"] { background: var(--pc-8); }
.isg-stack-dot[data-pc="7"] { background: var(--pc-7); }
.isg-stack-dot[data-pc="6"] { background: var(--pc-6); }
.isg-stack-dot[data-pc="5"] { background: var(--pc-5); }
.isg-stack-dot[data-pc="4"] { background: var(--pc-4); }
.isg-stack-dot[data-pc="3"] { background: var(--pc-3); }
.isg-stack-dot[data-pc="2"] { background: var(--pc-2); }
.isg-stack-dot[data-pc="1"] { background: var(--pc-1); }
.isg-stack-dot[data-pc="0"] { background: var(--pc-0); }

.isg-stack-dot[data-pri="1"] { background: var(--pri-1); }
.isg-stack-dot[data-pri="2"] { background: var(--pri-2); }
.isg-stack-dot[data-pri="3"] { background: var(--pri-3); }
.isg-stack-dot[data-pri="4"] { background: var(--pri-4); }
.isg-stack-dot[data-pri="0"] { background: var(--pc-0); }

/* Map no-token message */
.isg-map-no-token {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 12px;
  color: var(--text-2);
  font: var(--t-body-md);
  text-align: center;
  padding: 40px;
  background: var(--bg-0);
}

.isg-map-no-token code {
  font-family: var(--font-mono);
  background: var(--bg-2);
  padding: 2px 6px;
  border-radius: var(--r-sm);
  font-size: .85em;
}

/* Incident detail styles */
.isg-detail-icon-sm { width: 16px; height: 16px; }
.isg-detail-icon-xs { width: 14px; height: 14px; margin-right: 6px; }
.isg-detail-center-btn { width: 100%; justify-content: center; }

/* Add-to-report action + picker (Plan 7 Task 4.3); the foot flex layout lives with .isg-detail-foot above. */
.isg-detail-addrep { position: relative; width: 100%; }
/* Picker popover — opens upward from the foot, above the panel content. */
.isg-detail-addrep-menu {
  position: absolute; bottom: calc(100% + 6px); left: 0; right: 0; z-index: var(--z-menu);
  padding: 12px; border: 1px solid var(--border-0); border-radius: var(--r-sm);
  background: var(--bg-2); box-shadow: var(--elev-2);
  display: flex; flex-direction: column; gap: 12px; max-height: 340px; overflow-y: auto;
}
.isg-detail-addrep-new { width: 100%; justify-content: flex-start; }
.isg-detail-addrep-new svg { width: 14px; height: 14px; margin-right: 5px; }
.isg-detail-addrep-sub { display: flex; flex-direction: column; gap: 6px; padding-top: 12px; border-top: 1px solid var(--border-0); }
.isg-detail-addrep-list { display: flex; flex-direction: column; gap: 4px; max-height: 200px; overflow-y: auto; }
.isg-detail-addrep-hit { justify-content: flex-start; text-align: left; }
.isg-detail-addrep-err { margin-top: 2px; }

/* ── Heat mode: panel collapse ── */
.isg-incident-panel {
  transition: width 0.3s ease, padding 0.3s ease, gap 0.3s ease;
}
.isg-incident-panel.is-heat-collapsed {
  width: 18px;
  padding: 0;
  gap: 0;
}

/* ── Panel collapse tab ── */
.isg-panel-collapse-tab {
  position: absolute;
  top: 50%;
  left: 0;
  transform: translateY(-50%);
  width: 18px;
  height: 56px;
  background: var(--bg-1);
  border: 1px solid var(--border-0);
  border-right: none;
  border-radius: 6px 0 0 6px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--fg-2);
  transition: color var(--d-fast) var(--ease), background var(--d-fast) var(--ease);
  padding: 0;
}
.isg-panel-collapse-tab:hover {
  color: var(--accent);
  background: var(--bg-2);
}
.isg-panel-collapse-tab svg {
  width: 12px;
  height: 12px;
}

/* ── Heatmap controls floating card ── */
.isg-heat-controls {
  position: absolute;
  bottom: 36px;
  right: 34px;
  width: 180px;
  background: rgba(7, 16, 12, 0.94);
  border: 1px solid var(--border-0);
  border-radius: 10px;
  padding: 14px 16px;
  z-index: var(--z-popover);
  display: flex;
  flex-direction: column;
  gap: 14px;
  backdrop-filter: blur(8px);
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.5);
}

.isg-heat-controls-title {
  font: var(--t-label-sm);
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--border-0);
  margin-bottom: -2px;
}

.isg-heat-slider-row {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.isg-heat-slider-label {
  display: flex;
  justify-content: space-between;
  font-size: 11px;
  color: var(--fg-2);
}

.isg-heat-slider-val {
  color: var(--accent);
  opacity: 0.7;
}

/* Range input — custom styling for dark ops theme */
.isg-heat-range {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  background: var(--border-0);
  border-radius: 2px;
  outline: none;
  cursor: pointer;
}
.isg-heat-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-0);
  cursor: pointer;
  margin-top: -4.5px;
}
.isg-heat-range::-moz-range-thumb {
  width: 13px;
  height: 13px;
  border-radius: 50%;
  background: var(--accent);
  border: 2px solid var(--bg-0);
  cursor: pointer;
}
.isg-heat-range::-webkit-slider-runnable-track {
  background: var(--border-0);
  height: 4px;
  border-radius: 2px;
}

/* ── Active calls — panel section header ──────────────────────── */
.isg-panel-section-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px 6px;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-2);
  border-top: 1px solid var(--border-0);
}
.isg-panel-section-head:first-child { border-top: none; }

/* ── Pulsing live indicator dot ───────────────────────────────── */
.isg-live-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
  animation: isg-pulse 1.8s ease-in-out infinite;
}
@keyframes isg-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.35; }
}
.isg-live-dot-sm { width: 6px; height: 6px; }

/* ── Call detail footer status line ──────────────────────────── */
.isg-live-status-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 0.75rem;
  color: var(--fg-2);
  padding: 14px 16px;
}

/* ── Icon size utilities ── */
.isg-icon-xs    { width: 11px; height: 11px; }
.isg-icon-empty { width: 32px; height: 32px; opacity: .4; }
.isg-text-hint  { font-size: .8em; opacity: .7; }

/* ── Placeholder views ── */
.isg-coming-soon h2           { margin-bottom: 8px; }
.isg-coming-soon .isg-eyebrow { margin-top: 12px; }

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

/* ── Supplemental data sections (incident detail) ── */
.isg-supp-divider {
  height: 1px;
  background: var(--border-0);
  margin: 6px 0 0;
}

.isg-supp-loading {
  font: var(--t-caption);
  color: var(--fg-3);
  padding: 14px 0 0;
  text-align: center;
}

.isg-supp-section {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding-top: 14px;
}

.isg-supp-label {
  font: var(--t-caption);
  color: var(--fg-1);
  text-transform: uppercase;
  letter-spacing: .07em;
}

/* Module-styled card box — the reusable box language shared by the incident detail-panel cards
   and (coming) the Call / Call-History detail panels. Same look as .isg-module (bg-1 surface,
   faint rim, spotlight glow) but sized for a dense card, and BOX-ONLY: layout/padding lives on
   the consumer, and content is never wrapped, so existing arrangements are untouched. New card
   surfaces should reach for .isg-module-card. */
.isg-module-card,
.isg-supp-card {
  position: relative;
  isolation: isolate;
  background: var(--bg-1);
  border-radius: var(--r-sm);
}
.isg-module-card::before,
.isg-supp-card::before {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit;
  border: 1px solid var(--border-0);
  pointer-events: none;
}
/* Spotlight — the same gradient as .isg-spot, painted on a pseudo so no child element or content
   wrapper is needed; z-index:-1 under isolate keeps it behind the text. Inline (not a token)
   because a root custom property would bake --spot-angle at declaration scope — keep in sync with
   .isg-spot. */
.isg-module-card::after,
.isg-supp-card::after {
  content: ''; position: absolute; inset: 0;
  border-radius: inherit;
  pointer-events: none;
  z-index: -1;
  background:
    radial-gradient(
      80% 60% at calc(50% + cos(var(--spot-angle, 0deg)) * 40%) calc(50% + sin(var(--spot-angle, 0deg)) * 40%),
      var(--spotlight-color),
      transparent 65%
    );
}
/* Vary the spotlight angle by position so cards don't all glow the same corner (modules randomize
   theirs per-instance; a positional cycle gives the same effect with no per-card markup). */
.isg-module-card:nth-child(6n+1), .isg-supp-card:nth-child(6n+1) { --spot-angle: 25deg; }
.isg-module-card:nth-child(6n+2), .isg-supp-card:nth-child(6n+2) { --spot-angle: 145deg; }
.isg-module-card:nth-child(6n+3), .isg-supp-card:nth-child(6n+3) { --spot-angle: 235deg; }
.isg-module-card:nth-child(6n+4), .isg-supp-card:nth-child(6n+4) { --spot-angle: 310deg; }
.isg-module-card:nth-child(6n+5), .isg-supp-card:nth-child(6n+5) { --spot-angle: 85deg; }
.isg-module-card:nth-child(6n),   .isg-supp-card:nth-child(6n)   { --spot-angle: 195deg; }

.isg-supp-card {
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.isg-supp-card-head {
  display: flex;
  align-items: center;
  gap: 7px;
  flex-wrap: wrap;
}

.isg-supp-card-name {
  font: var(--t-body-md);
  color: var(--fg-0);
}

.isg-supp-badge {
  font: var(--t-caption);
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 3px;
  background: var(--bg-3);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: .05em;
  flex-shrink: 0;
}

.isg-supp-badge--suspect {
  background: rgba(232, 197, 71, 0.12);
  color: var(--sev-disturb);
}

.isg-supp-badge--arrest {
  background: rgba(168, 15, 15, 0.15);
  color: var(--sev-violent);
}

.isg-supp-meta {
  font: var(--t-caption);
  color: var(--fg-2);
  line-height: 1.45;
}

.isg-supp-field {
  display: flex;
  align-items: baseline;
  gap: 6px;
}

.isg-supp-field-label {
  font: var(--t-caption);
  font-size: 10px;
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: .05em;
  flex-shrink: 0;
  width: 58px;
}

.isg-supp-field-value {
  font: var(--t-caption);
  color: var(--fg-1);
}

.isg-supp-narrative {
  font: var(--t-small);
  color: var(--fg-2);
  line-height: 1.55;
  white-space: pre-wrap;
  margin-top: 2px;
}

/* Green victim badge — completes the escalation gradient (green → gray → yellow → red) */
.isg-supp-badge--victim { background: rgba(61, 220, 151, 0.14); color: var(--sev-traffic); }

/* Role tint — a subtle left accent on each card, so the "good guys left / bad guys right"
   split reads at a glance. Inset shadow (not a border) avoids shifting the card's padding. */
.isg-supp-card--victim  { box-shadow: inset 3px 0 0 var(--sev-traffic); }
.isg-supp-card--suspect { box-shadow: inset 3px 0 0 var(--sev-disturb); }
.isg-supp-card--arrest  { box-shadow: inset 3px 0 0 var(--sev-violent); }

/* Arrest/charge cards carry a lot of detail — fade the body text back to fg-2 so the
   arrestee/charge name (kept white) anchors the card. Labels keep their own fg-3. */
.isg-supp-card--arrest .isg-supp-field-value,
.isg-supp-card--arrest .isg-detail-mono { color: var(--fg-2); }

/* ── Detail-panel redesign: two-column layout + group-cards ── */

/* Container query context so the grid collapses to one column when the panel is genuinely
   narrow (a safety fallback — the expected mounts are all ~740px+). */
.isg-detail-body { container-type: inline-size; }

.isg-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  align-items: start;
}
.isg-detail-col {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}
@container (max-width: 560px) {
  .isg-detail-grid { grid-template-columns: 1fr; }
}

/* Group-card — a supp-card carrying a titled set of label/value rows (the core incident
   fields, converged onto the supplemental-card visual language). */
.isg-gcard { gap: 6px; }
.isg-gcard-title {
  display: inline-block;
  align-self: flex-start;          /* hug content width in the column-flex card */
  font: var(--t-caption);
  font-weight: 700;
  font-size: 13px;
  color: var(--fg-1);
  text-transform: uppercase;
  letter-spacing: .06em;
  background: var(--bg-3);
  border: 1px solid var(--border-0);
  border-radius: var(--r-sm);
  padding: 4px 10px;
  margin-bottom: 8px;
}
.isg-gcard-field { display: flex; gap: 8px; align-items: baseline; }
/* Label column sized to the widest label in use ("Call received", ~75px) plus a hair of
   margin — no narrower, or that one clips. */
.isg-gcard-label {
  flex: 0 0 78px;
  font: var(--t-caption);
  color: var(--fg-3);
}
.isg-gcard-value {
  flex: 1;
  min-width: 0;
  font: var(--t-body-sm);
  color: var(--fg-0);
  word-break: break-word;
}
/* De-emphasized value inside a normal (non-faded) card — the lesser meta gray, for secondary
   values that sit beside a headline one kept white (e.g. Fed card: Crime stays white; Category/
   NIBRS/Against fade). */
.isg-gcard-value--muted { color: var(--fg-2); }
/* Two short label/value fields paired on one row (e.g. Officers' Reporting + Assisting).
   Labels keep the standard 78px width so they align with the full-width rows above. */
.isg-gcard-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* A field row that also carries a right-justified calculated value (Timeline's Dispatch/Clearance
   times sit to the right of the timestamp they end on). The calc rides the value's line when it
   fits; when it can't (e.g. a multi-value "Against PERSON, PROPERTY, SOCIETY"), the row wraps and
   the calc drops to its own line — where it can wrap internally rather than overflow. */
.isg-gcard-field--split { flex-wrap: wrap; }
.isg-gcard-field--split .isg-gcard-value { flex: 0 0 auto; white-space: nowrap; }
.isg-gcard-calc { margin-left: auto; font: var(--t-body-sm); color: var(--fg-0); }
.isg-gcard-calc-lbl { color: var(--fg-3); margin-right: 5px; }

/* De-emphasized card: body values fade back (fg-2). Title chip and the title-row label/value keep
   their weight — except --faded-title, which also fades the title-row value (labels stay fg-3). */
.isg-gcard--faded .isg-gcard-value,
.isg-gcard--faded .isg-gcard-calc { color: var(--fg-2); }
.isg-gcard--faded-title .isg-gcard-head-val { color: var(--fg-2); }
/* Opt a single value back to full white inside a faded card (e.g. Timeline's Received). */
.isg-gcard--faded .isg-gcard-value.isg-gcard-value--strong { color: var(--fg-0); }
/* Title row that can carry a right-justified value (e.g. Geography's Division, a Flags hit),
   putting the card's one headline datum on the same line as the title to save a row. */
.isg-gcard-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 8px;
}
.isg-gcard-head .isg-gcard-title { align-self: center; margin-bottom: 0; }
.isg-gcard-head-val {
  font: var(--t-body-sm);
  color: var(--fg-0);
  text-align: right;
  min-width: 0;
  word-break: break-word;
}
/* Label portion of a title-row value stays gray (like the field-row labels); the value white. */
.isg-gcard-head-lbl { color: var(--fg-3); }
.isg-gcard-head-sep { margin: 0 6px; color: var(--fg-3); }
/* Zone badges on the Geography title row — user zones containing the record's point.
   Filled accent pill (dark text on green) so a zone hit reads at a glance. */
.isg-gcard-zones { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
.isg-supp-badge--zone {
  background: var(--accent);
  color: var(--bg-0);
  font-size: 11px;
  font-weight: 700;
  padding: 3px 10px;
  border-radius: var(--r-pill);
}
/* Multi-row Method-of-Entry cards get a divider between entries */
.isg-gcard-mo + .isg-gcard-mo {
  margin-top: 6px;
  padding-top: 6px;
  border-top: 1px solid var(--border-0);
}

.isg-detail-empty-note {
  font: var(--t-caption);
  color: var(--fg-3);
  font-style: italic;
  padding: 6px 2px;
}

/* ── Mount-width wiring ──
   The panel is position:absolute; width:100% of its host. Two hosts are narrow (the Map /
   Area-Studies activity column ~300px and the Explorer list column ~330px); widen the panel to
   the ~740px two-column design and right-anchor it so it slides over the adjacent map. Search
   (~742px) and Module-expand (≤1100px) already provide the width. Off-state (translateX(100%))
   is clipped by each host's own overflow ancestor, so no new horizontal scrollbar. */
.isg-incident-panel .isg-incident-detail,
.isg-areas-activity .isg-incident-detail,
.isg-xp-list .isg-incident-detail {
  /* ~740px design width, but never wider than the content area (viewport minus the ~249px
     sidebar + margin), so the left edge can't slip under the sidebar / get clipped. */
  width: min(740px, calc(100vw - 265px));
  left: auto;
  right: 0;
}
/* The call panel is single-column and its data is thin — cap it at ~440px in every mount
   (right-anchored slide-over, same behavior). Doubled class outranks the three host rules
   above; placed after them so the tie also breaks this way. */
.isg-incident-detail.isg-incident-detail--call {
  width: min(440px, calc(100vw - 265px));
  left: auto;
  right: 0;
}

/* Let the Explorer list column stop clipping so its widened panel can cover the map; the grid
   clips the off-screen (closed) panel instead, so no scrollbar. Higher specificity than the
   shared `.isg-explorer > div { overflow: hidden }`. */
.isg-explorer { overflow: hidden; }
.isg-explorer > .isg-xp-list { overflow: visible; }

/* ============================================================
   Area Studies — full-bleed three-column layout
   (reuses .isg-content--map; mirrors the Map view flex chain)
   ============================================================ */

/* Fills the flex content area, like .isg-map-view */
.isg-areas-view {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
}

.isg-areas-wrap {
  flex: 1;
  min-width: 0;
  min-height: 0;
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* Stage: holds the map + the floating zone/activity overlays. Flexes down to sit
   above the docked Zone Stats panel; the overlays anchor to it, so they stop at the
   panel's top automatically. */
.isg-areas-stage {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  overflow: hidden;
}

/* (Zones panel container is .isg-panel--zones — see Container primitives) */

.isg-zones-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-0);
}
/* Zone name filter — one state drives the list, the Area Studies map, and the Map view's
   zone overlay (setZoneNameFilter). Sized to sit between the panel title and sort icons. */
.isg-zone-filter { flex: 1; min-width: 0; height: 28px; padding: 0 10px; font-size: 12px; }

/* (panel-head h3 styling is shared with .isg-incident-panel-head h3 above) */

/* Center: map fills the entire wrap behind all floating panels */
.isg-areas-center {
  position: absolute;
  inset: 0;
}

/* The Mapbox canvas fills the entire wrap */
.isg-areas-map {
  position: absolute;
  inset: 0;
}

/* Right: zone-scoped Activity slot — same floating-card layout as the Map view's
   .isg-incident-panel (the .isg-module--activity + legend Modules carry their own styling). */
.isg-areas-activity {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: 300px;
  z-index: var(--z-popover);
  display: flex;
  flex-direction: column;
  gap: 16px;
  padding: 16px;
}

/* Shared Activity Panel host — transparent so the activity + legend Modules + detail
   slide-ins participate directly in the outer wrapper's flex layout. */
.isg-activity-host { display: contents; }

/* ── Area Studies — components (Stage 6) ─────────────────────────── */

/* Zone list */
.isg-zone-sort { display: flex; gap: 6px; }
.isg-zone-sort button { background: transparent; border: none; padding: 2px; color: var(--text-3); cursor: pointer; line-height: 0; }
.isg-zone-sort button:hover { color: var(--text-2); }
.isg-zone-sort button.is-active { color: var(--accent); }
.isg-zone-sort button svg { width: 15px; height: 15px; stroke-width: 1.5; }
.isg-zone-tiles { display: flex; flex-direction: column; }
/* Borderless rows on the panel bg with a 1px divider, like the incident feed. */
.isg-zone-tile { display: flex; flex-direction: row; align-items: stretch; gap: 10px; padding: 10px 12px; background: transparent; border: none; border-bottom: 1px solid var(--border-0); cursor: pointer; text-align: left; transition: background var(--d-fast); }
.isg-zone-tile:hover { background: var(--bg-2); }
.isg-zone-badge { display: inline-flex; align-items: center; justify-content: center; min-width: 24px; height: 24px; padding: 0 4px; border-radius: var(--r-sm); font-weight: 700; font-size: 9px; color: #04140d; flex-shrink: 0; }
.isg-zone-tile > .isg-zone-badge { align-self: stretch; width: 28px; min-width: 28px; height: auto; }
.isg-zone-tile-body { display: flex; flex-direction: column; justify-content: center; gap: 6px; flex: 1; min-width: 0; }
.isg-zone-tile-name { min-width: 0; font: var(--t-body-md); color: var(--fg-0); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.isg-zone-deltas { display: flex; justify-content: space-between; gap: 16px; }
.isg-zone-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; color: var(--fg-1); }
.isg-zone-delta-label { font-size: 10px; letter-spacing: 0.04em; }
.isg-zone-delta.is-up   { color: #ff6b6b; }
.isg-zone-delta.is-down { color: var(--pc-3); }
.isg-zone-delta.is-flat { color: var(--fg-2); }
.isg-zone-add { display: flex; align-items: center; justify-content: center; gap: 6px; margin: 12px; padding: 12px; border: 1px solid var(--border-1); border-radius: var(--r-md); background: transparent; color: var(--fg-1); cursor: pointer; }
.isg-zone-add:hover:not(:disabled) { border-color: var(--accent); }
.isg-zone-add:disabled { opacity: 0.4; cursor: not-allowed; }
.isg-zone-add i { width: 16px; height: 16px; }
.isg-zone-empty { padding: 20px; text-align: center; color: var(--fg-2); }

/* Zone detail */
.isg-zone-detail, .isg-zone-form { padding: 14px 16px; }
.isg-zone-detail-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.isg-zone-detail-actions { display: flex; gap: 8px; }
/* Small bare icon buttons (back / edit / delete) — same light treatment as the sort icons. */
.isg-icon-btn-sm { background: transparent; border: none; padding: 4px; color: var(--text-3); cursor: pointer; line-height: 0; display: inline-flex; align-items: center; }
.isg-icon-btn-sm:hover { color: var(--text-2); }
.isg-icon-btn-sm.is-danger:hover { color: #ff6b6b; }
.isg-icon-btn-sm svg { width: 16px; height: 16px; stroke-width: 1.5; }
/* Read-only field value in the detail view — mirrors the form's fields, a step larger. */
.isg-field-value { font-size: var(--fs-16); line-height: var(--lh-16); font-weight: 500; color: var(--fg-0); word-break: break-word; }
.isg-zone-section { padding: 12px 0; border-top: 1px solid var(--border-0); }
.isg-zone-section-title { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); margin-bottom: 8px; }
.isg-zone-section-empty { color: var(--fg-2); font-size: 13px; }
.isg-chip-group { margin-bottom: 12px; }
.isg-chip-label { display: block; font-size: 11px; color: var(--fg-3); letter-spacing: .04em; margin-bottom: 6px; }
/* Chips wrap on their own rows below the label; min-width keeps same-length
   items (beat/sector numbers) in clean, uniform columns. */
.isg-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.isg-chip { min-width: 32px; text-align: center; padding: 2px 8px; border-radius: var(--r-pill); background: var(--accent-soft); border: 1px solid var(--border-1); color: var(--fg-1); font-size: 12px; }
/* Zone detail — two columns above Divisions: Name|Abbreviation, Color|Boundary method,
   and Beats|Sectors. Divisions/Districts stay full-width (too wide). Field labels are
   deemphasized to match the Overlapping Areas chip labels; Beats/Sectors values stack. */
.isg-zone-detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; align-items: start; margin-bottom: 12px; }
.isg-zone-detail-grid .isg-field, .isg-zone-detail-grid .isg-chip-group { margin-bottom: 0; }
/* Identity badge row — abbreviation+color in one token, sized to match the Area Studies list tile. */
.isg-zone-detail-grid--badge { grid-template-columns: auto 1fr; align-items: center; }
.isg-zone-badge--detail { height: 40px; min-width: 28px; }
.isg-zone-detail .isg-field > span { font-size: 11px; color: var(--fg-3); letter-spacing: .04em; }
.isg-chip-group--stacked .isg-chips { flex-direction: column; align-items: flex-start; }
/* Zone-detail "reference section" links (Alerts rules now, Reports in Plan 7) — small, wrapping,
   link-styled buttons stacked above the section's Create button. */
.isg-zone-ref-list { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; margin-bottom: 10px; }
.isg-zone-ref-link { text-align: left; background: none; border: none; padding: 0; cursor: pointer;
  color: var(--accent); font-size: 12px; line-height: 1.35; word-break: break-word; }
.isg-zone-ref-link:hover { text-decoration: underline; }
/* Kind badge on a zone ref item (Plan 7: distinguishes a Ledger from a Report in one list). */
.isg-zone-ref-badge { margin-left: 6px; color: var(--fg-2); vertical-align: middle; }

/* Outlined small buttons inside the zones panel (the global .isg-btn-sm is a
   size-modifier for .isg-btn; here it is used standalone). */
.isg-panel--zones .isg-btn-sm { display: inline-flex; align-items: center; gap: 5px; height: auto; padding: 5px 10px; border-radius: var(--r-sm); border: 1px solid var(--border-1); background: transparent; color: var(--fg-1); font-size: 12px; cursor: pointer; }
.isg-panel--zones .isg-btn-sm:hover:not(:disabled) { border-color: var(--accent-soft); color: var(--fg-0); }
.isg-panel--zones .isg-btn-sm:disabled { opacity: 0.4; cursor: not-allowed; }
.isg-panel--zones .isg-btn-sm.is-danger { border-color: rgba(168,15,15,0.4); color: #ff6b6b; }
.isg-panel--zones .isg-btn-sm i { width: 14px; height: 14px; }
.isg-btn-primary { padding: 8px 16px; border-radius: var(--r-sm); border: none; background: var(--accent); color: #04140d; font-weight: 700; cursor: pointer; }
.isg-btn-primary:disabled { opacity: 0.5; cursor: not-allowed; }

/* Zone form */
.isg-zone-form-head { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; }
.isg-field { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; min-width: 0; }
.isg-field > span { font-size: 12px; color: var(--fg-1); }
.isg-field > .isg-zone-badge { color: #04140d; } /* badge preview keeps badge text color, not the field-label color */
/* box-sizing: border-box + width:100% keep inputs inside their field — the app
   shell doesn't load main.css's global reset, so inputs default to content-box. */
.isg-field input[type=text], .isg-field input[type=number], .isg-field input[type=email], .isg-field input[type=password], .isg-field select { box-sizing: border-box; width: 100%; min-width: 0; background: var(--bg-0); border: 1px solid var(--border-1); border-radius: var(--r-sm); padding: 8px; color: var(--fg-0); font-family: inherit; }
.isg-field input:focus, .isg-field select:focus { outline: none; border-color: var(--accent); }
/* Safari ignores padding on <select> and collapses it to its intrinsic height — give it an
   explicit height so it matches the sibling inputs (which render ~34px from padding+border). */
.isg-field select { height: 34px; }
.isg-field-row { display: flex; gap: 12px; align-items: flex-end; }
.isg-field-row .isg-field:first-child { flex: 1; }
.isg-color-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.isg-color-row input[type=color] { width: 36px; height: 28px; border: none; background: none; padding: 0; cursor: pointer; }
.isg-swatch { width: 24px; height: 24px; border-radius: 5px; border: 1px solid var(--border-1); cursor: pointer; }
.isg-method-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.isg-method-btn { padding: 8px; border-radius: var(--r-sm); border: 1px solid var(--border-1); background: transparent; color: var(--fg-1); font-size: 12px; cursor: pointer; }
.isg-method-btn:hover { border-color: var(--accent-soft); }
.isg-method-btn.is-active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent); }
.isg-method-inputs { margin-top: 10px; }
.isg-inline-row { display: flex; gap: 6px; }
.isg-inline-row input { flex: 1; }
/* Cut-out zone pills (donut boundaries) — wraps under the polygon method's hint */
.isg-cutout-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.isg-form-error { color: #ff6b6b; font-size: 12px; margin: 8px 0; }
.isg-form-ok    { color: var(--accent); font-size: 12px; margin: 8px 0; }
.isg-form-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }

/* ============================================================
   Form views (UI/Forms) — full view, stacked section cards.
   Shared shell for Profile & Settings (centered column + cards).
   ============================================================ */
.isg-form-view { max-width: 560px; margin: 0 auto; display: flex; flex-direction: column; gap: 16px; }
.isg-form-view-head h1 { font: var(--t-h2); color: var(--fg-0); margin: 0 0 2px; }
.isg-form-view-sub { font: var(--t-small); color: var(--fg-2); margin: 0; }
.isg-module--form { width: 100%; }
/* Scoped under [data-isg] to outrank the base `[data-isg] h2` heading reset (which
   would otherwise force --t-h2 size + negative tracking onto this section label). */
[data-isg] .isg-form-section-title { font-size: 11px; font-weight: 600; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); margin: 0 0 14px; }

/* ── Profile-specific ── */
/* Tier is read-only — a pill, not an input. The `.isg-field >` specificity beats the
   generic `.isg-field > span` label rule (mirrors the zone-badge override). */
.isg-field > .isg-tier-badge { display: inline-block; align-self: flex-start; padding: 2px 10px; border-radius: var(--r-pill); background: var(--accent-soft); border: 1px solid var(--border-1); color: var(--fg-1); font-size: 12px; text-transform: capitalize; }
.isg-key-status { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--fg-1); margin: 0; }
.isg-key-status.is-muted { color: var(--fg-3); }
.isg-key-status i { width: 14px; height: 14px; flex-shrink: 0; }

/* ── Settings-specific — instant-apply controls ── */
/* Label / control row (notifications, regional). */
.isg-setting-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 0; }
.isg-setting-row + .isg-setting-row { border-top: 1px solid var(--border-0); }
.isg-setting-label .name { font-size: 14px; color: var(--fg-0); }
.isg-setting-label .desc { font-size: 12px; color: var(--fg-2); margin-top: 2px; }
.isg-setting-control { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
/* Transient "Saved" flash + error shown after an instant-apply write. */
.isg-setting-saved { font-size: 12px; color: var(--accent); white-space: nowrap; }
.isg-settings-error { color: #ff6b6b; font-size: 12px; margin: 8px 0 0; }
/* Segmented control (theme picker). */
.isg-segment { display: inline-flex; gap: 2px; padding: 2px; background: var(--bg-0); border: 1px solid var(--border-1); border-radius: var(--r-sm); }
.isg-segment-btn { padding: 6px 16px; border: 0; background: transparent; color: var(--fg-1); border-radius: calc(var(--r-sm) - 2px); font-size: 13px; cursor: pointer; transition: background var(--d-fast) var(--ease), color var(--d-fast) var(--ease); }
.isg-segment-btn:hover:not(.is-active) { color: var(--fg-0); }
.isg-segment-btn.is-active { background: var(--accent-soft); color: var(--accent); }
/* Toggle switch (notification booleans). */
.isg-toggle { position: relative; width: 40px; height: 22px; flex-shrink: 0; padding: 0; border: 1px solid var(--border-1); border-radius: var(--r-pill); background: var(--bg-0); cursor: pointer; transition: background var(--d-fast) var(--ease), border-color var(--d-fast) var(--ease); }
.isg-toggle.is-on { background: var(--accent); border-color: var(--accent); }
.isg-toggle-knob { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--fg-0); transition: transform var(--d-fast) var(--ease); }
.isg-toggle.is-on .isg-toggle-knob { transform: translateX(18px); background: #04140d; }
/* Timezone select sits inline in the control slot, not a full-width field. */
.isg-setting-control select { min-width: 190px; height: 34px; box-sizing: border-box; background: var(--bg-0); border: 1px solid var(--border-1); border-radius: var(--r-sm); padding: 0 8px; color: var(--fg-0); font-family: inherit; cursor: pointer; }
.isg-setting-control select:focus { outline: none; border-color: var(--accent); }
.isg-toggle:disabled { opacity: 0.4; cursor: not-allowed; }
/* Assistant memory list (read-only facts + per-fact delete). */
.isg-setting-memory { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.isg-memory-fact { display: flex; align-items: center; gap: 8px; color: var(--fg-2); font-size: 13px; }
.isg-setting-empty { color: var(--fg-3); font-size: 12px; font-style: italic; }

/* ── Admin (UI/Forms) — user management ── */
.isg-admin { display: flex; flex-direction: column; }
.isg-admin-add { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 12px; align-items: end; }
.isg-admin-add .isg-field { margin-bottom: 0; }
.isg-admin-table { width: 100%; border-collapse: collapse; }
.isg-admin-table thead th { text-align: left; font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--fg-3); font-weight: 600; padding: 0 10px 10px; }
.isg-admin-table thead th:last-child { width: 64px; }
.isg-admin-actions { display: flex; align-items: center; gap: 2px; justify-content: flex-end; }
.isg-admin-row td { padding: 10px; border-top: 1px solid var(--border-0); vertical-align: middle; font-size: 13px; color: var(--fg-1); }
.isg-admin-user { display: flex; flex-direction: column; gap: 1px; }
.isg-admin-name { color: var(--fg-0); font-weight: 500; }
.isg-admin-email { color: var(--fg-2); font-size: 12px; }
.isg-admin-tier { background: var(--bg-0); border: 1px solid var(--border-1); border-radius: var(--r-sm); padding: 6px 8px; color: var(--fg-0); font-family: inherit; font-size: 12px; cursor: pointer; }
.isg-admin-tier:focus { outline: none; border-color: var(--accent); }
.isg-admin-tier:disabled { opacity: 0.5; cursor: not-allowed; }
.isg-admin-fail { display: block; color: #ff6b6b; font-size: 11px; margin-top: 2px; }
.isg-admin-drawer td { padding: 0 10px 12px; }
.isg-admin-history { background: var(--bg-0); border: 1px solid var(--border-0); border-radius: var(--r-sm); padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.isg-admin-hist-row { display: flex; align-items: center; gap: 12px; font-size: 12px; }
.isg-admin-hist-badge { flex-shrink: 0; min-width: 56px; text-align: center; padding: 1px 8px; border-radius: var(--r-pill); font-size: 11px; }
.isg-admin-hist-badge.is-ok { background: var(--accent-soft); color: var(--accent); }
.isg-admin-hist-badge.is-fail { background: rgba(255, 107, 107, 0.14); color: #ff6b6b; }
.isg-admin-hist-time { color: var(--fg-1); }
.isg-admin-hist-ip { color: var(--fg-3); font-family: var(--font-mono); margin-left: auto; }

/* ── Admin lookup-management: tabbed page + two-column body + inline forms (plan-5.6) ── */
.isg-admin-tabbar { display: flex; gap: 2px; border-bottom: 1px solid var(--border-1); margin-bottom: 18px; }
.isg-admin-tab { display: inline-flex; align-items: center; gap: 7px; padding: 10px 18px; margin-bottom: -1px;
                 background: none; border: 0; border-bottom: 2px solid transparent; color: var(--fg-2);
                 font: inherit; font-size: 14px; font-weight: 500; cursor: pointer; }
.isg-admin-tab:hover { color: var(--fg-0); }
.isg-admin-tab.is-active { color: var(--fg-0); border-bottom-color: var(--accent); }
.isg-admin-tab .isg-chip { min-width: 0; padding: 0 7px; background: var(--accent); color: #04140d; font-weight: 700; }
.isg-admin-body { display: flex; gap: 16px; align-items: flex-start; }
.isg-admin-main { flex: 1; min-width: 0; }
.isg-admin-tabpanel { display: flex; flex-direction: column; gap: 16px; }
/* Modules here stretch to the full column width; border-box keeps their 24px padding
   inside that width instead of overflowing it (no global box-sizing reset exists). */
.isg-admin .isg-module { box-sizing: border-box; }
/* .isg-admin scope beats the base [data-isg] p margin reset. */
.isg-admin .isg-admin-intro { margin-bottom: 18px; }
/* position: relative contains the absolutely-positioned incident/call detail slide-in
   to the panel width (like the Map's .isg-incident-panel) instead of the whole page. */
.isg-admin-activity { width: 340px; flex-shrink: 0; position: relative; display: flex; flex-direction: column; gap: 16px; align-self: stretch; min-height: 480px; }
.isg-lookup-link { background: none; border: 0; padding: 0; color: var(--accent); font: inherit; cursor: pointer; }
.isg-lookup-link:hover { text-decoration: underline; }
.isg-chip--warn { min-width: 0; padding: 0 8px; background: rgba(255,107,107,0.14); color: #ff6b6b; margin-left: 6px; }
.isg-admin-form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; padding: 4px 0 8px; }
.isg-admin-form-grid .isg-field { margin-bottom: 0; }
.isg-field--wide { grid-column: 1 / -1; }
.isg-admin-tabhead { display: flex; justify-content: space-between; align-items: center; gap: 12px; margin-bottom: 14px; }
.isg-admin-tabhead .isg-form-section-title { margin: 0; }
.isg-admin-addform { background: var(--bg-0); border: 1px solid var(--border-1); border-radius: var(--r-sm); padding: 14px; margin-bottom: 16px; }

/* Docked Zone Stats panel — full-width bottom of Area Studies, zone-detail state only.
   Built from the Panel primitive; tiles reuse the dashboard grid (.isg-dash-grid) at
   full size. Height is content-driven up to a cap, then .isg-panel-inner scrolls. */
.isg-panel--zone-stats { flex-shrink: 0; max-height: 40vh; border-top: 1px solid var(--border-0); background: var(--bg-0); }
.isg-panel--zone-stats .isg-panel-inner { padding: 14px 16px; }
.isg-zone-stats-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.isg-zone-stats-title { margin: 0; font-size: 0.95rem; font-weight: 600; }
.isg-zone-stats-actions { display: flex; gap: 8px; flex-shrink: 0; }

/* Activity feed (reuses the Map view's .isg-incident-row / .isg-sev-bar styles) */
.isg-area-act-scope { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 10px 16px; font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); border-bottom: 1px solid var(--border-0); }
.isg-area-act-asof { text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; opacity: 0.75; }

/* ── Statistics (Plan 5) ─────────────────────────────────────────── */
.isg-stats-view { height: 100%; overflow-y: auto; }
.isg-stats-shell { padding: 20px; max-width: 1500px; margin: 0 auto; }
.isg-stats-header { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.isg-stats-title { font: var(--t-h2); margin: 0; }
.isg-stats-header-actions { display: flex; gap: 8px; }
.isg-btn-ghost.is-active { background: var(--bg-3); color: var(--fg-0); box-shadow: inset 0 0 0 1px var(--accent-soft); }

.isg-dash-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 14px;
  grid-auto-flow: dense;
}
.isg-module--stat.is-small  { grid-column: span 1; min-height: 90px; }
.isg-module--stat.is-medium { grid-column: span 2; min-height: 175px; }
.isg-module--stat.is-large  { grid-column: span 4; min-height: 270px; }
.isg-module--stat.is-layout { cursor: grab; outline: 1px dashed var(--pc-0); }

/* Stat tile head — the canonical .isg-module-head, centered for its single-line title + tools */
.isg-module--stat .isg-module-head { align-items: center; gap: 8px; margin-bottom: 8px; }
.isg-dash-tile-name { font-weight: 600; font-size: 0.85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.isg-dash-tile-tools { flex-shrink: 0; line-height: 0; }
.isg-dash-hover-tools { display: none; gap: 6px; }
.isg-module--stat:hover .isg-dash-hover-tools { display: inline-flex; }   /* §9.3 hover reveal */
.isg-dash-size-btns { display: inline-flex; gap: 2px; }
.isg-dash-size-btn {
  width: 22px; height: 22px; padding: 0; border-radius: var(--r-sm);
  border: 1px solid var(--border-1); background: transparent; color: var(--fg-1);
  font-size: 11px; font-weight: 600; cursor: pointer; line-height: 1;
}
.isg-dash-size-btn:hover { color: var(--fg-0); border-color: var(--accent-soft); }
.isg-dash-size-btn.is-active { background: var(--accent); color: #061410; border-color: var(--accent); }

.isg-dash-tile-body { flex: 1; min-height: 0; position: relative; }
.isg-dash-tile-body canvas { position: absolute; inset: 0; }
.isg-dash-tile-foot { margin-top: 6px; }
.isg-dash-tile-state { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; text-align: center; }
.isg-dash-tile-state--empty { color: var(--fg-2); }
.isg-dash-tile-state--error { color: var(--pc-8); }
.isg-dash-skeleton { width: 70%; height: 40%; border-radius: 8px; opacity: 0.25;
  background: linear-gradient(100deg, transparent 30%, var(--pc-0) 50%, transparent 70%);
  background-size: 200% 100%; animation: isg-dash-shimmer 1.2s infinite; }
@keyframes isg-dash-shimmer { to { background-position: -200% 0; } }

.isg-kpi { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: 6px; }
.isg-kpi-value { font-size: 2.4rem; font-weight: 700; line-height: 1.1; }
.isg-kpi-delta { font-size: 0.8rem; font-weight: 600; }
.isg-kpi-sub { font-size: 0.72rem; color: var(--text-3); }
/* Density measure: numerator under 10 — shown, never suppressed (design 2026-07-10) */
.isg-kpi-caution {
  display: inline-block;
  padding: 0 5px;
  border-radius: 3px;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--warn, #e0a83c);
  border: 1px solid currentColor;
}
.isg-trendarrow { display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100%; gap: 2px; }
.isg-trendarrow-value { font-size: 2rem; font-weight: 700; }
.isg-trendarrow-delta { font-size: 0.85rem; font-weight: 600; }
/* crime semantics (Plan 4 convention): up = red, down = green */
.isg-kpi-delta.is-up, .isg-trendarrow.is-up .isg-trendarrow-delta { color: var(--pc-8); }
.isg-kpi-delta.is-down, .isg-trendarrow.is-down .isg-trendarrow-delta { color: var(--pc-3); }
.isg-trendarrow-base { font-size: 0.72rem; opacity: 0.6; }

.isg-heatgrid { display: grid; grid-template-columns: auto repeat(var(--heat-cols), 1fr);
  gap: 2px; height: 100%; overflow-y: auto; font-size: 0.68rem; }
.isg-heatgrid-corner, .isg-heatgrid-col, .isg-heatgrid-row { opacity: 0.7; padding: 2px 4px; }
.isg-heatgrid-col { text-align: center; }
.isg-heatgrid-row { white-space: nowrap; }
.isg-heatgrid-cell { border-radius: 3px; min-height: 14px; display: flex; align-items: center; justify-content: center; }
.isg-heatgrid-cell span { opacity: 0.85; }

.isg-stats-table-wrap { height: 100%; overflow: auto; }
.isg-stats-table { width: 100%; border-collapse: collapse; font-size: 0.78rem; }
.isg-stats-table th, .isg-stats-table td { padding: 4px 8px; text-align: left; border-bottom: 1px solid color-mix(in srgb, var(--pc-0) 25%, transparent); }
.isg-stats-table th { color: var(--fg-2); font-weight: 600; }

/* Funnel lens — builder stage stack */
.isg-funnel-stage { border: 1px solid var(--border-0); border-radius: 6px; padding: 8px; margin-bottom: 8px; }
.isg-funnel-stage-head { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.isg-funnel-stage-num { font-weight: 600; font-size: 0.85rem; }
.isg-funnel-threshold { max-width: 9rem; }
.isg-funnel-stage-conds { margin-top: 6px; padding-left: 8px; }
.isg-funnel-addcond { margin-top: 4px; }

/* Funnel lens — display */
.isg-funnelviz { display: flex; flex-direction: column; gap: 8px; padding: 6px 4px; }
.isg-funnelviz-kpi { text-align: center; font-size: 1.6rem; font-weight: 700; color: var(--accent); }
.isg-funnelviz-kpi span { display: block; font-size: 0.78rem; font-weight: 400; color: var(--text-1); }
.isg-funnelviz-row { cursor: pointer; }
.isg-funnelviz-bar { height: 26px; border-radius: 3px; min-width: 4px; transition: width 0.2s; }
.isg-funnelviz-lab { font-size: 0.8rem; margin-top: 2px; }
.isg-funnelviz-sub { color: var(--text-3); }

.isg-dash-empty { text-align: center; padding: 60px 0; opacity: 0.8; display: flex; flex-direction: column; align-items: center; gap: 14px; }

/* ── Module Results Drill-Down: clickable tile + inline sample ── */
.isg-module--stat:not(.is-layout) { cursor: pointer; transition: box-shadow var(--d-fast) var(--ease); }
.isg-module--stat:not(.is-layout):hover { box-shadow: var(--elev-2), inset 0 0 0 1px rgba(255,255,255,0.28); }

.isg-tile-sample { margin-top: 8px; border-top: 1px solid var(--border-0); padding-top: 6px; overflow: hidden; }
.isg-tile-sample-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 2px; }
.isg-tile-sample-count { font-size: 10px; color: var(--text-2); }
.isg-tile-sample .isg-incident-row.is-static { cursor: default; }
.isg-tile-sample .isg-incident-row.is-static:hover { background: none; }

/* ── Query Builder (Plan 5 Stage 8a) ─────────────────────────────── */
.isg-builder { max-width: 1180px; margin: 0 auto; display: flex; flex-direction: column; gap: 0; }
.isg-builder-bar { display: flex; align-items: center; gap: 10px; }
.isg-builder-bar-spacer { flex: 1; }
.isg-builder-bar .isg-btn-ghost.is-active { background: var(--bg-3); color: var(--fg-0); box-shadow: inset 0 0 0 1.5px var(--fg-0); }

/* Top zone: controls (~60%) on the left, the live module preview (~40%) on the right.
   Display and everything below it close out of this row and run full-width. */
.isg-builder-top { display: flex; gap: 28px; align-items: flex-start; }
.isg-builder-controls { flex: 0 1 60%; min-width: 0; display: flex; flex-direction: column; }
/* start a little lower — roughly level with the Source / What-How divider — so it isn't
   pressed against the top bar; sticky still pins it at top:20px as you scroll. */
.isg-builder-live { flex: 1 1 40%; min-width: 0; position: sticky; top: 20px; margin-top: 100px; }
.isg-builder-live-label { display: block; margin-bottom: 8px; }
/* the preview card fills its pane regardless of the chosen module size — it's only a preview.
   box-sizing: border-box because there's no global reset — without it width:100% adds the
   card's padding on top of 100% and the card overflows its pane (the right-edge clipping). */
.isg-module--preview { width: 100%; box-sizing: border-box; }
/* The pane isn't a dashboard grid item, so the card has no definite height for the flex
   chain (.isg-module-inner height:100% → body flex:1 → absolute canvas) to resolve against.
   Without it the body collapses to 0 and the chart canvas overflows the card's clipped
   bottom. Give it a generous definite height — there's room, and a clipped chart is worse. */
.isg-module--preview          { height: 300px; }
.isg-module--preview.is-small { height: 200px; }
.isg-module--preview.is-large { height: 380px; }
@media (max-width: 920px) {
  .isg-builder-top { flex-direction: column; }
  .isg-builder-live { position: static; flex-basis: auto; width: 100%; margin-top: 0; }
}
.isg-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 12px;
  border-radius: 10px; background: color-mix(in srgb, var(--pc-0) 12%, transparent); font-size: 0.85rem; }
.isg-builder .isg-chips { font-size: 1.05rem; padding: 18px 20px; gap: 8px; line-height: 1.6;
  border: 1px solid color-mix(in srgb, var(--pc-2) 25%, transparent);
  background: color-mix(in srgb, var(--pc-0) 8%, transparent); margin-top: 8px; }
.isg-builder .isg-chip-word { opacity: 0.7; font-size: 1.05rem; }
.isg-builder .isg-chip { font-size: 0.92rem; padding: 4px 14px; }
.isg-builder .isg-chip-count { font-size: 1.0rem; font-weight: 700; }
/* `.isg-chip` is also the zones-panel geo badge (global rule above); scope the builder's
   clickable sentence chip so the zones panel styling is untouched (neutralize the leaked
   min-width/text-align). */
.isg-builder .isg-chip { min-width: 0; text-align: left; cursor: pointer; color: var(--fg-0);
  border: 1px solid color-mix(in srgb, var(--pc-2) 60%, transparent); border-radius: var(--r-pill);
  padding: 2px 10px; background: color-mix(in srgb, var(--pc-2) 18%, transparent); }
.isg-builder .isg-chip:hover { filter: brightness(1.15); }
.isg-builder .isg-chip--dim { display: inline-flex; gap: 4px; align-items: center;
  background: color-mix(in srgb, var(--pc-3) 18%, transparent);
  border-color: color-mix(in srgb, var(--pc-3) 60%, transparent); }
.isg-chip-word { opacity: 0.65; }
.isg-chip-count { margin-left: auto; font-weight: 600; opacity: 0.85; }
.isg-bsec { display: flex; flex-direction: column; gap: 8px; padding: 20px 0; border-top: 1px solid color-mix(in srgb, var(--fg-0) 8%, transparent); transition: opacity 0.3s ease; }
.isg-bsec:first-of-type { border-top: none; padding-top: 8px; }
.isg-bsec.is-quiet, .isg-builder .isg-chips.is-quiet { opacity: 0.35; }   /* §4.1: visible but quiet (incl. the bottom progress string) */

/* §4.1 cascade reveal: when a subject is picked, the quiet sections turn live top-to-bottom,
   one every --cascade-step. The delay only applies entering the live state, so re-dimming
   (e.g. Clear) is immediate, not staggered. Purely visual — every section is usable at once.
   The progress string (.isg-chips) shares index 6, so it brightens with the last section. */
.isg-builder { --cascade-step: 0.5s; }
#isg-bsec-measure { --i: 0; } #isg-bsec-compare { --i: 0; } #isg-bsec-time { --i: 1; } #isg-bsec-area { --i: 2; }
#isg-bsec-filters { --i: 3; } #isg-bsec-breakdowns { --i: 4; } #isg-bsec-display { --i: 5; }
#isg-bsec-name { --i: 6; } .isg-builder .isg-chips { --i: 6; transition: opacity 0.3s ease; }
.isg-bsec:not(.is-quiet), .isg-builder .isg-chips:not(.is-quiet) { transition-delay: calc(var(--i, 0) * var(--cascade-step)); }
@media (prefers-reduced-motion: reduce) { .isg-bsec, .isg-builder .isg-chips { transition: none; } }
.isg-bsec-title { font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; opacity: 0.7; }
.isg-bsec-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.isg-bsec-substack { flex: 1 0 100%; margin-top: 8px; padding-left: 12px; border-left: 2px solid var(--pc-0); display: flex; flex-direction: column; gap: 6px; }
.isg-bsec-subtitle { font-size: 0.85rem; color: var(--text-2); }
#isg-bsec-subject { margin-top: 36px; }                                    /* drop the first section below the builder bar */
.isg-bfield { display: flex; flex-direction: column; gap: 6px; }           /* labelled control: small label above its picker (own class — .isg-field is the form-field style) */
.isg-subject-row { align-items: flex-end; }                                /* controls + hint share one baseline; labels stack above */
.isg-subject-hint { align-self: flex-end; display: inline-flex; align-items: center; gap: 6px; height: 32px;
  margin-left: 10px; font: var(--t-body-md); font-weight: 600; color: var(--fg-0); }   /* matches the "New Module" bar text */
.isg-subject-hint i, .isg-subject-hint svg { width: 18px; height: 18px; display: block; }
.isg-filter-row { gap: 6px; }
/* The row's delete X is the global 36px icon-btn; shrink it to the 32px control height so it
   aligns with the field/operator/value selects beside it (other .isg-icon-btn uses unaffected).
   padding:0 clears the UA <button> padding that otherwise shrinks the content box below the
   icon width and throws place-items:center off (the icon drifts right). */
.isg-filter-row > .isg-icon-btn { width: 32px; height: 32px; padding: 0; }

/* New shared form primitives (no prior definition in app.css; existing forms style inputs
   via the `.isg-field input` wrapper — the builder's inline controls need a direct class). */
.isg-input { box-sizing: border-box; background: var(--bg-2); border: 1px solid var(--border-1);
  border-radius: var(--r-sm); padding: 6px 8px; color: var(--fg-0); font-family: inherit; font-size: 13px; }
.isg-input:focus { outline: none; border-color: var(--accent); }

/* Cross-browser control height. Safari ignores `height` on a native <select> (appearance:
   menulist) and renders it taller than the 32px styled picker buttons/pills beside it; Chromium
   respects it, so the rows only look ragged in Safari. Reset appearance, pin the height, and add
   a chevron to replace the native one. Builder-row inputs (incl. date) are pinned to match. */
select.isg-input {
  -webkit-appearance: none; appearance: none;
  height: 32px; padding-right: 26px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23ffffff' stroke-opacity='.55' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center;
}
.isg-bsec-row input.isg-input { height: 32px; }

/* Picker trigger — a field/subject selector that opens the picker overlay. Styled like the
   op/value <select>s beside it (not a solid CTA) so it reads as "choose from", with a chevron.
   The --prompt modifier keeps the empty "Pick a subject…" state loud (it's the required first step). */
.isg-picker-btn { box-sizing: border-box; display: inline-flex; align-items: center; gap: 6px;
  background-color: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--r-sm);
  height: 32px; padding: 0 26px 0 8px; color: var(--fg-0); font-family: inherit; font-size: 13px; cursor: pointer;
  /* same line chevron as select.isg-input, so the trigger reads identically to the dropdowns */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23ffffff' stroke-opacity='.55' stroke-width='1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 9px center; }
.isg-picker-btn:hover { border-color: var(--accent-soft); }
.isg-picker-btn--prompt { border-color: var(--accent); color: var(--accent); font-weight: 600; box-shadow: inset 0 0 0 1px var(--accent); }
.isg-picker-btn--prompt::after { border-top-color: var(--accent); }

/* Toggle chips (Compare / Timeframe presets / zone + multi-select pills). Rounded shape keeps
   them readable as on/off choices, but they share the 32px control height so they sit level with
   the dropdowns beside them (e.g. Timeframe presets next to the Timestamp <select>). Explicit
   height + flex centering — Safari won't size them from padding alone. */
.isg-pill { display: inline-flex; align-items: center; border: 1px solid var(--border-1);
  background: var(--bg-2); color: var(--fg-1); border-radius: var(--r-pill);
  height: 32px; padding: 0 14px; font-size: 13px; cursor: pointer; }
.isg-pill:hover:not(:disabled) { color: var(--fg-0); border-color: var(--accent-soft); }
.isg-pill:disabled { opacity: 0.4; cursor: not-allowed; }
.isg-pill.is-active { outline: 2px solid var(--pc-2); color: var(--fg-0); }

/* Dimension picker overlay (§5) */
.isg-picker-overlay { position: fixed; inset: 0; z-index: var(--z-panel); display: flex;
  align-items: flex-start; justify-content: center; padding-top: 8vh;
  background: color-mix(in srgb, black 50%, transparent); }
/* Subject picker opens ~50px lower so its "All {source}" option — the 95% choice — lands
   under the cursor that just clicked the Subject button (Fitts's law), not above it. */
.isg-picker-overlay--subject { padding-top: calc(8vh + 50px); }
.isg-picker { width: min(920px, 95vw); max-height: 72vh; display: flex; }
.isg-picker .isg-module-inner { display: flex; flex-direction: column; gap: 10px; min-height: 0; width: 100%; }
.isg-picker-cascade { display: grid; grid-template-columns: 1fr 1fr 1.25fr; min-height: 0;
  border: 1px solid var(--border-1); border-radius: var(--r-sm); overflow: hidden; }
.isg-picker-col { border-right: 1px solid var(--border-1); min-height: 300px; max-height: 56vh;
  overflow-y: auto; padding: 4px; display: flex; flex-direction: column; gap: 1px; }
.isg-picker-col:last-child { border-right: none; }
.isg-picker-col--vals { padding: 0; }
.isg-picker-row { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; text-align: left; padding: 7px 10px; border: none; border-radius: 6px;
  background: transparent; color: var(--fg-0); cursor: pointer; font: inherit; }
.isg-picker-row:hover, .isg-picker-row.is-active { background: color-mix(in srgb, var(--pc-2) 16%, transparent); }
.isg-picker-chev { opacity: 0.5; }
.isg-picker-valwrap { display: flex; flex-direction: column; min-height: 0; flex: 1; }
.isg-picker-vlist { display: flex; flex-direction: column; gap: 1px; padding: 4px; overflow-y: auto; min-height: 0; }
.isg-picker-val { text-align: left; padding: 6px 10px; border: none; border-radius: 6px;
  background: transparent; color: var(--fg-0); cursor: pointer; font: inherit; }
.isg-picker-val:hover { background: color-mix(in srgb, var(--pc-2) 16%, transparent); }
.isg-picker-val.is-active { outline: 2px solid var(--pc-2); }
.isg-picker-results { overflow-y: auto; min-height: 0; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.isg-picker-result { display: flex; align-items: baseline; gap: 10px; width: 100%; text-align: left;
  padding: 7px 10px; border: none; border-radius: 6px; background: transparent; color: var(--fg-0); cursor: pointer; font: inherit; }
.isg-picker-result:hover { background: color-mix(in srgb, var(--pc-2) 16%, transparent); }
.isg-picker-kind { margin-left: auto; font-size: 0.62rem; text-transform: uppercase; letter-spacing: 0.05em;
  opacity: 0.6; border: 1px solid var(--border-1); border-radius: 4px; padding: 0 5px; }
.isg-picker-hl { background: color-mix(in srgb, var(--pc-2) 35%, transparent); color: var(--fg-0); border-radius: 3px; }
.isg-picker-search { width: 100%; }
.isg-picker-crumb { font-size: 0.7rem; opacity: 0.5; }
/* Primary "no subject filter" choice — broken out above the cascade as a prominent, accent-framed row. */
.isg-picker-all { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  padding: 12px 16px; border-radius: var(--r-sm); color: var(--fg-0); font-size: 1.05rem; font-weight: 600;
  background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 38%, transparent);
  transition: background 0.15s ease, border-color 0.15s ease; }
.isg-picker-all:hover { background: color-mix(in srgb, var(--accent) 22%, transparent);
  border-color: color-mix(in srgb, var(--accent) 60%, transparent); }
.isg-picker-all i, .isg-picker-all svg { width: 18px; height: 18px; color: var(--accent); flex-shrink: 0; }
.isg-picker-all-sub { margin-left: auto; font-size: 0.8rem; font-weight: 400; opacity: 0.6; }
.isg-picker-text { display: flex; gap: 8px; }
.isg-picker-text .isg-input { flex: 1; }
.isg-picker-vempty { font-size: 0.8rem; opacity: 0.6; padding: 8px; }
.isg-picker-vfoot { padding-top: 8px; border-top: 1px solid color-mix(in srgb, var(--fg-0) 12%, transparent); }

/* Builder execute section (Stage 8b): display tiles, name/size, preview */
.isg-display-row { display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px; }
.isg-display-tile { border: 1px solid var(--border-1); background: var(--bg-2); color: var(--fg-1);
  border-radius: var(--r-sm); padding: 10px 12px 8px; font-size: 11px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; gap: 6px; min-width: 64px; }
.isg-display-tile svg { width: 40px; height: 28px; flex-shrink: 0; }
.isg-display-tile:hover:not(.is-locked) { color: var(--fg-0); border-color: var(--accent-soft); }
.isg-display-tile.is-active { outline: 2px solid var(--pc-2); color: var(--fg-0); background: color-mix(in srgb, var(--pc-2) 10%, var(--bg-2)); }
.isg-display-tile.is-locked { opacity: 0.3; cursor: not-allowed; }
.isg-input--wide { flex: 1; min-width: 240px; }
.isg-bsec--actions { padding-top: 32px; }
.isg-builder-error { color: var(--pc-8); font-size: 12px; }
/* Proactive hint under the action row: names what's still required while the bottom buttons
   are disabled (subject + display). Muted, not an error — it clears when the buttons go live. */
.isg-builder-hint { color: var(--fg-2); font-size: 12px; margin-top: 8px; }

/* Library (Stage 9) */
.isg-library { max-width: 880px; margin: 0 auto; display: flex; flex-direction: column; gap: 14px; }
.isg-lib-section { display: flex; flex-direction: column; gap: 8px; }
.isg-lib-section + .isg-lib-section { margin-top: 24px; }
.isg-lib-entry-name { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.isg-lib-badge { font-size: 0.65rem; text-transform: uppercase; border-radius: 4px; padding: 1px 6px;
  background: color-mix(in srgb, var(--pc-2) 25%, transparent); }
.isg-lib-badge--system { background: color-mix(in srgb, var(--pc-4) 25%, transparent); }
.isg-lib-badge--pinned { background: var(--accent-soft); color: var(--accent); border: 1px solid var(--accent); }
/* Zone-default tile badge — marks the tile as shared across every zone (design 2026-07-06).
   Sits on its own row under the title: the head row is width-starved (title + hover tools). */
.isg-zone-default-badge { display: inline-flex; align-items: center; gap: 3px; font-size: 10px; color: var(--accent);
  background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-radius: var(--r-pill); padding: 0 6px; margin: -2px 0 6px; white-space: nowrap;
  align-self: flex-start; width: fit-content; line-height: 15px; }
.isg-zone-default-badge svg { width: 9px; height: 9px; flex-shrink: 0; }
.isg-lib-entry-sentence { font-size: 0.8rem; opacity: 0.8; margin: 2px 0; }
.isg-lib-entry-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

/* ── Reports — Ledgers list (plan-7). Mirrors the Query Library list; each row is a
   clickable libentry Module. Archived rows sort last (list.php) and dim here. ── */
.isg-ledger-list { max-width: 880px; margin: 0 auto; display: flex; flex-direction: column; gap: 8px; }
.isg-ledger-row { cursor: pointer; }
.isg-ledger-row:hover::before { border-color: var(--border-1); }
.isg-ledger-row.is-archived { opacity: 0.55; }
.isg-ledger-row-meta { margin-top: 3px; }
.isg-ledger-badge--archived { opacity: 0.7; }
.isg-ledger-badge--error { display: inline-flex; align-items: center; gap: 4px; font-size: 0.65rem;
  text-transform: uppercase; border-radius: 4px; padding: 1px 6px;
  background: rgba(255, 107, 107, 0.14); color: #ff6b6b; }
.isg-ledger-badge--error svg { width: 11px; height: 11px; flex-shrink: 0; }

/* ── Ledger builder (plan-7 Task 3.3) — four-step create flow. Reuses the .isg-builder /
   .isg-bsec / .isg-pill primitives; metric editing dives into the shared Query Builder. ── */
.isg-ledger-builder { max-width: 880px; }
.isg-ledger-metrics { display: flex; flex-direction: column; gap: 8px; }
.isg-ledger-metric { display: flex; align-items: center; gap: 12px; padding: 10px 12px;
  border: 1px solid var(--border-1); border-radius: var(--r-sm); background: var(--bg-2); }
.isg-ledger-metric-reorder { display: flex; flex-direction: column; gap: 1px; flex-shrink: 0; }
.isg-ledger-metric-reorder .isg-icon-btn { width: 22px; height: 20px; padding: 0; }
.isg-ledger-metric-reorder .isg-icon-btn:disabled { opacity: 0.3; cursor: not-allowed; }
.isg-ledger-metric-main { flex: 1; min-width: 0; }
.isg-ledger-metric-label { font-weight: 600; display: flex; align-items: center; gap: 8px; }
.isg-ledger-metric-sentence { font-size: 0.8rem; opacity: 0.75; margin-top: 2px; }
.isg-ledger-metric-actions { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }

/* Fill / backfill progress panel */
.isg-ledger-fill { display: flex; flex-direction: column; gap: 12px; max-width: 620px; padding-top: 12px; }
.isg-ledger-fill-status { display: flex; align-items: center; gap: 8px; color: var(--fg-0); }
.isg-ledger-fill-status svg { width: 16px; height: 16px; opacity: 0.7; }
.isg-ledger-fill-bar { height: 6px; border-radius: var(--r-pill); background: var(--bg-3); overflow: hidden; }
.isg-ledger-fill-bar-fill { width: var(--fill-pct, 0%); height: 100%; background: var(--accent); transition: width 0.3s ease; }
.isg-ledger-fill-rows { display: flex; flex-wrap: wrap; gap: 6px; }

/* ── Ledger grid view (Plan 7 Task 3.4) — metric rows × period columns ── */
.isg-lgrid-view { max-width: 100%; }
.isg-lgrid-header { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-bottom: 14px; }
.isg-lgrid-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.isg-lgrid-name { font-size: 1.1rem; font-weight: 700; color: var(--fg-0); }
.isg-lgrid-affordance { margin-left: auto; }
.isg-lgrid-view .isg-builder-error { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.isg-lgrid-view .isg-builder-error svg { width: 14px; height: 14px; flex-shrink: 0; }

/* Full-series horizontal scroll — no capped columns. The label + corner columns pin left so the
   metric/zone/value labels stay visible while the period columns scroll. */
.isg-lgrid-scroll { overflow-x: auto; border: 1px solid var(--border-0); border-radius: 10px; }
.isg-lgrid { border-collapse: collapse; font-size: 0.8rem; white-space: nowrap; }
.isg-lgrid th, .isg-lgrid td { padding: 6px 12px; border-bottom: 1px solid color-mix(in srgb, var(--pc-0) 22%, transparent); text-align: right; }
.isg-lgrid thead th { position: sticky; top: 0; z-index: 2; background: var(--bg-2); color: var(--fg-2);
  font-weight: 600; border-bottom: 1px solid var(--border-1); }
.isg-lgrid-corner { position: sticky; left: 0; z-index: 3; text-align: left; background: var(--bg-2); }
/* Raise specificity over `.isg-lgrid thead th` (0,1,2) so the pinned corner beats the scrolling
   period headers on horizontal scroll instead of tying them (both would otherwise sit at z-index 2). */
.isg-lgrid thead th.isg-lgrid-corner { z-index: 3; }
.isg-lgrid-phead { text-align: right; }
.isg-lgrid-phead.is-backfilled .isg-lgrid-plabel { opacity: 0.85; }
.isg-lgrid-plabel { display: block; }
.isg-lgrid-chip { display: inline-block; margin-top: 2px; font-size: 0.6rem; text-transform: uppercase;
  letter-spacing: 0.05em; border-radius: 4px; padding: 0 5px; color: var(--fg-2);
  background: color-mix(in srgb, var(--pc-0) 22%, transparent); }
.isg-lgrid-chip--backfilled { background: color-mix(in srgb, var(--pc-4) 22%, transparent); }
.isg-lgrid-chip--revised { background: color-mix(in srgb, var(--accent) 22%, transparent); color: var(--accent); }

/* Sticky first column on data rows carries a solid bg so scrolled cells don't bleed under it. */
.isg-lgrid-rowlabel { position: sticky; left: 0; z-index: 1; text-align: left; background: var(--bg-1);
  color: var(--fg-1); font-weight: 500; }
.isg-lgrid-cell { font-variant-numeric: tabular-nums; color: var(--fg-0); }
.isg-lgrid-cell.is-null { color: var(--text-3); }
.isg-lgrid-cell.is-clickable { cursor: pointer; }
.isg-lgrid-cell.is-clickable:hover { background: color-mix(in srgb, var(--accent) 14%, transparent); }
.isg-lgrid-cell.is-revised { color: var(--accent); }
/* Month-over-month direction tint — crime semantics: up = worse (red), down = better (green). Faint
   background only, no text-color change, so it reads at a glance without competing with revision (accent). */
.isg-lgrid-cell.is-cell-up   { background: color-mix(in srgb, var(--pc-8) 20%, transparent); }
.isg-lgrid-cell.is-cell-down { background: color-mix(in srgb, var(--pc-3) 20%, transparent); }
.isg-lgrid-rev { color: var(--accent); font-weight: 700; margin-left: 1px; cursor: help; }

.isg-lgrid-total { text-align: right; font-weight: 600; border-left: 1px solid var(--border-1);
  font-variant-numeric: tabular-nums; }
.isg-lgrid-total-head { border-left: 1px solid var(--border-1); }

.isg-lgrid-flags, .isg-lgrid-flags-head { text-align: left; }
.isg-lgrid-flag { display: inline-block; margin: 0 4px 0 0; font-size: 0.62rem; border-radius: 4px;
  padding: 1px 6px; background: color-mix(in srgb, var(--pc-0) 18%, transparent); color: var(--fg-2); }
.isg-lgrid-flag.is-up   { background: color-mix(in srgb, var(--pc-8) 20%, transparent); color: var(--pc-8); }
.isg-lgrid-flag.is-down { background: color-mix(in srgb, var(--pc-3) 20%, transparent); color: var(--pc-3); }
.isg-lgrid-flag--rec { background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); }

/* Metric section header + zone-group label rows span the full width. */
.isg-lgrid-metric-head { position: sticky; left: 0; text-align: left; background: var(--bg-3);
  color: var(--fg-0); font-weight: 700; padding-top: 9px; padding-bottom: 9px; }
.isg-lgrid-metric-name { margin-right: 8px; }
.isg-lgrid-zone { position: sticky; left: 0; text-align: left; background: var(--bg-1);
  color: var(--fg-2); font-weight: 600; padding-left: 22px;
  text-transform: uppercase; letter-spacing: 0.04em; font-size: 0.72rem; }
.isg-lgrid-totalrow td { font-weight: 600; background: color-mix(in srgb, var(--pc-0) 8%, transparent); }
/* Keep the sticky label solid (`.isg-lgrid-totalrow td` (0,1,1) would otherwise repaint the
   rowlabel with the 8% tint and let scrolled-under cells bleed through it). */
.isg-lgrid-totalrow td.isg-lgrid-rowlabel { background: var(--bg-1); color: var(--fg-0); }

/* Ledger cell drill-down: the shared drill-down popup's viz pane, when opened from a ledger cell. */
.isg-mexp-lcell { display: flex; flex-direction: column; gap: 10px; max-width: 480px; }
.isg-mexp-lcell-metric { font-size: 1rem; font-weight: 700; color: var(--fg-0); }
.isg-mexp-lcell-meta { font-size: 0.85rem; color: var(--text-2); }
.isg-mexp-lcell-frozen { display: flex; align-items: baseline; gap: 10px; margin-top: 4px; }
.isg-mexp-lcell-num { font-size: 2.4rem; font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }
.isg-mexp-lcell-note { max-width: 420px; line-height: 1.5; }

/* Boundary layer */
.isg-bl-filter-badge { display: inline-flex; align-items: center; justify-content: center;
  min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px; font-size: 11px; font-weight: 600;
  background: var(--accent); color: #061410; margin-left: 2px; }
.isg-bl-multi-badge { display: flex; align-items: center; gap: 6px; margin-top: 8px; padding: 6px 10px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--r-sm); font-size: 0.8rem; color: var(--fg-1); }
.isg-bl-multi-badge svg { width: 13px; height: 13px; opacity: 0.7; flex-shrink: 0; }
.isg-bl-multi-badge span { flex: 1; }
.isg-icon-btn--xs { width: 20px; height: 20px; padding: 0; flex-shrink: 0; }

/* ── Reports — composer + document view (Plan 7 Task 4.2). Reuses the .isg-builder / .isg-bsec /
   .isg-ledger-metric / .isg-lgrid / module-drill-down modal primitives; the classes below add only
   what those don't cover: the draggable section card, the add-section menu, the document iframe,
   the two-column doc/send layout, and the send/snapshot modals. ── */

/* Reports-list "new period ready" chip (accent-tinted variant of .isg-lib-badge). */
.isg-rbadge--ready { background: color-mix(in srgb, var(--accent) 22%, transparent);
  color: var(--accent); border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent); }

/* Section-stack card — the .isg-ledger-metric row made draggable, with a grip + type icon. */
.isg-rsection { cursor: grab; }
.isg-rsection:active { cursor: grabbing; }
.isg-rsection-reorder { align-items: center; }
.isg-rsection-grip { display: flex; align-items: center; justify-content: center; color: var(--text-3); }
.isg-rsection-grip svg { width: 16px; height: 16px; }
.isg-rsection-icon { width: 15px; height: 15px; opacity: 0.75; }
.isg-rview-error { margin-bottom: 12px; }

/* + Add section menu — a bordered panel below the button. */
.isg-radd { margin-top: 6px; padding: 14px; border: 1px solid var(--border-0); border-radius: var(--r-sm);
  background: var(--bg-2); display: flex; flex-direction: column; gap: 14px; }
.isg-radd-grid { display: flex; flex-wrap: wrap; gap: 6px; }
.isg-radd-grid .isg-pill svg { width: 14px; height: 14px; margin-right: 5px; }
.isg-radd-sub { display: flex; flex-direction: column; gap: 6px;
  padding-top: 12px; border-top: 1px solid var(--border-0); }
.isg-radd-results { display: flex; flex-direction: column; gap: 4px; max-height: 220px; overflow-y: auto; }
.isg-radd-hit { justify-content: flex-start; text-align: left; gap: 8px; }
.isg-radd-hit .isg-eyebrow { opacity: 0.7; }

/* Document view — two-column: the rendered document (left) + send history (right). */
.isg-rview-body { display: flex; gap: 20px; align-items: flex-start; }
.isg-rview-doc { flex: 1 1 62%; min-width: 0; display: flex; flex-direction: column; gap: 14px; }
.isg-rview-side { flex: 0 0 300px; display: flex; flex-direction: column; gap: 8px; }
@media (max-width: 900px) { .isg-rview-body { flex-direction: column; } .isg-rview-side { flex-basis: auto; width: 100%; } }

/* Period picker. */
.isg-rperiod { display: flex; align-items: center; gap: 10px; }
.isg-rperiod-label { font-weight: 700; color: var(--fg-0); min-width: 120px; text-align: center; }

/* The rendered document, isolated in an iframe (the render layer emits a full self-contained doc). */
.isg-rframe { width: 100%; height: 620px; border: 1px solid var(--border-0); border-radius: var(--r-sm);
  background: #ffffff; }
.isg-rframe--tall { height: 72vh; }

.isg-rcommentary { width: 100%; resize: vertical; min-height: 92px; line-height: 1.5; padding: 10px 12px; }

/* Send confirmation banner. */
.isg-rconfirm { display: flex; align-items: center; gap: 8px; margin-bottom: 14px; padding: 10px 14px;
  border-radius: var(--r-sm); background: color-mix(in srgb, var(--accent) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); color: var(--fg-0); font-size: 0.9rem; }
.isg-rconfirm svg { width: 16px; height: 16px; color: var(--accent); flex-shrink: 0; }

/* Send-history row — a clickable library entry. */
.isg-rsend-row { cursor: pointer; }

/* Send dialog + snapshot modal (reuses the drill-down popup's overlay/head primitives). */
.isg-rsend-overlay { position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(0,0,0,.72); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 28px; }
.isg-rsend { position: relative; width: 92vw; max-width: 1100px; height: 88vh;
  background: var(--bg-1); border: 1px solid var(--border-0); border-radius: 16px;
  display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--elev-pop); }
.isg-rsend-body { display: flex; flex: 1; min-height: 0; }
/* box-sizing: this project has no global reset, so a padded width:100% column would overflow
   (esp. when stacked on mobile) — pin border-box on the padded modal panels + their inputs. */
.isg-rsend-form { flex: 0 0 340px; box-sizing: border-box; display: flex; flex-direction: column; gap: 6px;
  padding: 18px; overflow-y: auto; border-right: 1px solid var(--border-0); }
.isg-rsend-form .isg-input { box-sizing: border-box; width: 100%; }
.isg-rsend-form .isg-bsec-title { margin-top: 8px; }
.isg-rsend-form .isg-bsec-title:first-child { margin-top: 0; }
.isg-rsend-preview { flex: 1; min-width: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 8px; padding: 18px; overflow: hidden; }
.isg-rsend-preview .isg-rframe { flex: 1; height: auto; }
.isg-rsnap-body { flex: 1; min-height: 0; box-sizing: border-box; display: flex; flex-direction: column; gap: 8px; padding: 18px; overflow: hidden; }
.isg-rsnap-body .isg-rframe { flex: 1; height: auto; }
/* Mobile: the fixed 340px form column crushes the preview — stack it above a fluid preview and let
   the modal body scroll (mirrors the .isg-mexp modal's responsive treatment). */
@media (max-width: 640px) {
  .isg-rsend-overlay { padding: 0; }
  .isg-rsend { width: 100vw; height: 100vh; max-width: none; border-radius: 0; }
  .isg-rsend-body { flex-direction: column; overflow-y: auto; }
  .isg-rsend-form { flex: 0 0 auto; width: 100%; border-right: none; border-bottom: 1px solid var(--border-0); }
  .isg-rsend-preview { flex: 0 0 auto; width: 100%; min-height: 60vh; }
}

/* Typed-confirmation delete dialog (ledgers + reports, Task 6.1) — a small centered box on the
   shared .isg-rsend-overlay backdrop; reuses the .isg-mexp head primitives. The typed name gates
   the destructive button (spec §4.4). */
.isg-confirm-dialog { position: relative; width: 92vw; max-width: 440px;
  background: var(--bg-1); border: 1px solid var(--border-0); border-radius: 16px;
  display: flex; flex-direction: column; overflow: hidden; box-shadow: var(--elev-pop); }
.isg-confirm-body { box-sizing: border-box; display: flex; flex-direction: column; gap: 10px; padding: 18px; }
.isg-confirm-body .isg-input { box-sizing: border-box; width: 100%; }
.isg-confirm-warn { margin: 0; font-size: 0.9rem; line-height: 1.45; color: var(--fg-1); }
.isg-confirm-warn strong { color: var(--fg-0); }
.isg-confirm-dialog .isg-btn.is-danger { background: rgba(168,15,15,0.18); color: #ff6b6b;
  box-shadow: inset 0 0 0 1px rgba(168,15,15,0.4); }
.isg-confirm-dialog .isg-btn.is-danger:hover:not(:disabled) { background: rgba(168,15,15,0.28); filter: none; }

/* ── Module Results Drill-Down popup ── */
.isg-mexp-overlay {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(0,0,0,.72); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 32px;
}
.isg-mexp {
  position: relative;
  /* Fill the viewport (the overlay's 32px padding is the margin) — an expanded module
     should use the whole screen, and the included detail panels inherit this size. */
  width: 100%; height: 100%;
  background: var(--bg-1); border: 1px solid var(--border-0); border-radius: 16px;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: var(--elev-pop);
}
.isg-mexp-head {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px; border-bottom: 1px solid var(--border-0); flex-shrink: 0;
}
.isg-mexp-close {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: none; border-radius: 7px;
  background: rgba(255,255,255,.07); color: var(--text-1); cursor: pointer;
}
.isg-mexp-close:hover { background: rgba(255,255,255,.12); }
.isg-mexp-title { font-size: 14px; font-weight: 600; flex: 1; }
.isg-mexp-filter-pill {
  font-size: 11px; padding: 2px 8px; border-radius: 5px;
  background: color-mix(in srgb, var(--pill) 18%, transparent);
  color: var(--pill); border: 1px solid color-mix(in srgb, var(--pill) 35%, transparent);
}
.isg-mexp-count { font-size: 11px; color: var(--text-2); }
.isg-mexp-body { display: flex; flex: 1; overflow: hidden; }
.isg-mexp-viz {
  flex: 1; min-width: 0; border-right: 1px solid var(--border-0);
  padding: 18px; display: flex; flex-direction: column; gap: 10px; overflow: hidden;
}
.isg-mexp-viz > #isg-expand-viz { flex: 1; min-height: 0; }
.isg-mexp-clear { align-self: flex-start; }
.isg-mexp-records {
  flex: 0 0 300px;
  display: flex; flex-direction: column; overflow: hidden;
}
.isg-mexp-records-head { padding: 12px 16px 10px; border-bottom: 1px solid var(--border-0); flex-shrink: 0; }
.isg-mexp-records-title { font-size: 11px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--text-2); }
/* In-module search field (sits under the records title) */
.isg-mexp-search {
  display: flex; align-items: center; gap: 7px; margin-top: 9px;
  padding: 6px 9px; border: 1px solid var(--border-0); border-radius: 7px; background: var(--bg-2);
  transition: border-color var(--d-fast);
}
.isg-mexp-search:focus-within { border-color: var(--border-1); }
.isg-mexp-search-icon { width: 14px; height: 14px; color: var(--text-3); flex-shrink: 0; }
.isg-mexp-search-input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  color: var(--fg-0); font: var(--t-body);
}
.isg-mexp-search-input::placeholder { color: var(--text-3); }
.isg-mexp-search-spin { font: var(--t-caption); color: var(--text-3); flex-shrink: 0; }
.isg-mexp-search-clear {
  flex-shrink: 0; border: none; background: none; cursor: pointer;
  color: var(--text-2); font-size: 17px; line-height: 1; padding: 0 4px;
  transition: color var(--d-fast);
}
.isg-mexp-search-clear:hover { color: var(--fg-0); }
.isg-mexp-records-scroll { overflow-y: auto; flex: 1; }
.isg-mexp-pager {
  flex-shrink: 0;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  padding: 8px 12px; border-top: 1px solid var(--border-0);
}
.isg-mexp-pager-label { font-size: 11px; color: var(--text-2); }
.isg-incident-empty.isg-incident-error { color: var(--text-2); }

/* ───── Site-wide search overlay (docs/.../2026-06-25-site-wide-search-design.md) ─────
   A near-full-screen workspace: results (left) + canonical detail host (right). Result
   rows reuse .isg-incident-row / .isg-sev-bar, so severity bars match the map + drill-down. */
.isg-search-overlay {
  position: fixed; inset: 0; z-index: var(--z-modal);
  background: rgba(0,0,0,.72); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 28px;
}
.isg-search {
  position: relative;
  width: 92vw; max-width: 1280px; height: 92vh;
  background: var(--bg-1); border: 1px solid var(--border-0); border-radius: 16px;
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: var(--elev-pop);
}

/* Head — search box + close */
.isg-search-head {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px; border-bottom: 1px solid var(--border-0); flex-shrink: 0;
}
.isg-search-head-icon { width: 18px; height: 18px; color: var(--text-2); flex-shrink: 0; }
.isg-search-clear {
  flex-shrink: 0; border: none; border-radius: 5px; padding: 3px 9px;
  background: rgba(255,255,255,.06); color: var(--text-2);
  font: var(--t-caption); cursor: pointer;
  transition: background var(--d-fast), color var(--d-fast);
}
.isg-search-clear:hover { background: rgba(255,255,255,.12); color: var(--text-0); }
.isg-search-input {
  flex: 1; min-width: 0; border: none; background: none; outline: none;
  color: var(--fg-0); font: var(--t-h3); letter-spacing: -0.005em;
}
.isg-search-input::placeholder { color: var(--text-3); font-weight: 400; }
.isg-search-spin { font: var(--t-caption); color: var(--text-2); flex-shrink: 0; }
.isg-search-close {
  display: flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border: none; border-radius: 7px;
  background: rgba(255,255,255,.07); color: var(--text-1); cursor: pointer; flex-shrink: 0;
}
.isg-search-close:hover { background: rgba(255,255,255,.12); }

/* Filters row: type chips (left) + search window (right) */
.isg-search-filters {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px; border-bottom: 1px solid var(--border-0); flex-shrink: 0;
}
.isg-search-chips { display: flex; flex-wrap: wrap; gap: 6px; min-width: 0; }
.isg-search-tf { margin-left: auto; flex-shrink: 0; }
.isg-search-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px; border-radius: var(--r-pill);
  border: 1px solid var(--border-0); background: var(--bg-0);
  color: var(--text-1); font: var(--t-caption); cursor: pointer;
  transition: background var(--d-fast), border-color var(--d-fast);
}
.isg-search-chip:hover { border-color: var(--border-1); }
.isg-search-chip.is-active {
  background: var(--accent-soft); border-color: var(--accent); color: var(--fg-0);
}
.isg-search-chip-n {
  font: var(--t-mono-sm); color: var(--text-2);
  background: rgba(255,255,255,.06); padding: 0 5px; border-radius: var(--r-pill);
}
.isg-search-chip.is-active .isg-search-chip-n { color: var(--accent); }

/* Body — master-detail */
.isg-search-body { display: flex; flex: 1; overflow: hidden; }
.isg-search-results {
  flex: 1 1 42%; min-width: 0; overflow-y: auto;
  border-right: 1px solid var(--border-0);
}
.isg-search-detail { flex: 1 1 58%; position: relative; overflow: hidden; }

/* Right-host placeholder (behind the slide-in detail) */
.isg-search-detail-empty {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; color: var(--text-3); font: var(--t-small); text-align: center; padding: 24px;
}

/* Result groups */
.isg-search-group { border-bottom: 1px solid var(--border-0); }
.isg-search-group:last-child { border-bottom: none; }
.isg-search-group-head {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: 8px;
  padding: 8px 14px; background: var(--bg-2);
  border-bottom: 1px solid var(--border-0);
}
.isg-search-group-title {
  font: var(--t-label-sm); text-transform: uppercase; letter-spacing: .06em; color: var(--text-1);
}
.isg-search-group-count { font: var(--t-mono-sm); color: var(--text-2); }
.isg-search-seeall {
  margin-left: auto; display: inline-flex; align-items: center; gap: 2px;
  border: none; background: none; cursor: pointer;
  color: var(--accent); font: var(--t-caption);
}
.isg-search-seeall i { width: 14px; height: 14px; }

/* Empty / hint / error states */
.isg-search-state {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 56px 24px; text-align: center;
  color: var(--text-2); font: var(--t-small);
}
.isg-search-state.isg-search-err { color: var(--text-2); }

/* "Showing first N of M" footer — truncation is surfaced, never silent */
.isg-search-more {
  padding: 12px 14px; text-align: center;
  font: var(--t-caption); color: var(--text-2);
  border-top: 1px solid var(--border-0);
}

/* ── Tracked-record tiles ("Track This") ───────────────────────────── */
.isg-dash-tile-badge {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: .68rem; font-weight: 700; line-height: 1.5;
  background: var(--accent, #2d7d46); color: #fff; vertical-align: 1px;
}

.isg-tracked-body { display: flex; flex-direction: column; gap: 6px; overflow: hidden; }
.isg-tracked-group-head {
  display: flex; align-items: baseline; justify-content: space-between;
  padding: 2px 2px 2px 0;
}
.isg-tracked-group-n { font-size: .72rem; font-weight: 600; opacity: .6; }
.isg-tracked-foot {
  margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--hairline, rgba(128,128,128,.2));
  font-size: .8rem; font-weight: 600; color: var(--accent, #2d7d46);
}

/* Tracked-item note — 2-line preview on tiles (sits above the record groups); live editor
   in the search overlay */
.isg-tracked-note {
  margin-bottom: 6px; padding-bottom: 6px;
  border-bottom: 1px solid var(--hairline, rgba(128,128,128,.2));
}
.isg-tracked-note-label {
  display: block; font-size: .6rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; opacity: .5; margin-bottom: 2px;
}
.isg-tracked-note-text {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: .78rem; line-height: 1.3; opacity: .85;
}
.isg-search-note {
  position: sticky; bottom: 0; margin-top: 12px;
  padding: 10px 2px 4px; background: var(--bg-1);
  border-top: 1px solid var(--border-0);
}
.isg-search-note-title {
  font-size: .7rem; font-weight: 700; letter-spacing: .04em;
  text-transform: uppercase; opacity: .55; margin-bottom: 5px;
}
.isg-search-note-input {
  width: 100%; box-sizing: border-box; resize: vertical; min-height: 56px;
  padding: 8px 10px; border: 1px solid var(--hairline, rgba(128,128,128,.25));
  border-radius: 8px; background: var(--bg-0, rgba(128,128,128,.06));
  color: inherit; font: inherit; font-size: .82rem; line-height: 1.35;
}
.isg-search-note-input:focus { outline: none; border-color: var(--accent, #2d7d46); }

/* Track-This affordances */
.isg-search-track { margin-left: auto; }      /* push to the right of the filters row */
.isg-search-track:disabled { opacity: .45; cursor: default; }
.isg-detail-track {
  margin-left: auto; display: inline-flex; align-items: center; gap: 5px;
  padding: 4px 9px; border: 0; border-radius: 6px; cursor: pointer;
  background: transparent; color: var(--accent, #2d7d46); font-size: .8rem; font-weight: 600;
}
.isg-detail-track:hover { background: var(--hover, rgba(128,128,128,.12)); }

/* ── Explorer (Plan 5.7) ───────────────────────────────────────────────── */
.isg-explorer-view { flex: 1; min-width: 0; min-height: 0; height: 100%; }
.isg-explorer {
  display: grid;
  grid-template-columns: 400px 1fr 330px;
  gap: 1px;
  height: 100%;
  min-height: 0;
  background: var(--border-0);
}
.isg-explorer > div { background: var(--bg-0); min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
/* Anchor the slide-in detail panels (position:absolute) to the list column, so they cover the
   330px list like the Map view's activity panel — not the whole grid (.isg-explorer is unpositioned). */
.isg-xp-list { position: relative; }

.isg-xp-col-head { display: flex; align-items: center; justify-content: space-between;
  padding: 11px 14px; border-bottom: 1px solid var(--border-0); flex: 0 0 auto; }
.isg-xp-col-title { font-size: 11px; text-transform: uppercase; letter-spacing: 1.2px; color: var(--text-3); }
.isg-xp-col-title b { color: var(--accent); font-weight: 600; }
/* Activity-panel "Matching N" reads as a prominent live count — 2x the eyebrow size. */
.isg-xp-list .isg-xp-col-title { font-size: 22px; letter-spacing: 0.5px; }

/* Left builder */
/* Flex column with a generous inter-group gap so each label hugs its OWN control
   (the .isg-bfield internal 6px) and is clearly separated from the group above. */
.isg-xp-build-body { padding: 16px 14px; overflow-y: auto; flex: 1;
  display: flex; flex-direction: column; gap: 20px; }
.isg-xp-build-foot { flex: 0 0 auto; display: flex; gap: 8px; align-items: center;
  padding: 11px 14px; border-top: 1px solid var(--border-0); }
.isg-xp-build-foot .isg-btn { flex: 1; font-size: 12.5px; padding: 9px 10px; white-space: nowrap; }
.isg-xp-build-foot .isg-btn:last-child { flex: 1.6; }   /* "Save to Dashboard" needs more room than "Reset" */

/* Path lane selector — its own bordered section above the seed, sharing the col-head/seed
   14px inset and bottom border so its label + chips align with the rest of the column.
   Inner label→chips spacing comes from .isg-bfield (same as the Source/Mode fields). */
.isg-xp-path { flex: 0 0 auto; padding: 13px 14px 12px; border-bottom: 1px solid var(--border-0); }

/* Seed bar (Plan 5.7 Seed & Flow) — sits in front of the builder; freezes a cross-entity cohort.
   A standard text input (always editable); the Seeded badge + clear live outside it, in the label. */
.isg-xp-seed { flex: 0 0 auto; padding: 13px 14px 12px; border-bottom: 1px solid var(--border-0);
  display: flex; flex-direction: column; gap: 8px; }
.isg-xp-seed-label { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-2); }
.isg-xp-seed-opt { color: var(--text-3); text-transform: none; letter-spacing: 0; font-size: 0.72rem; }
.isg-xp-seed-status { display: inline-flex; align-items: center; gap: 5px; flex: 0 0 auto;
  text-transform: none; letter-spacing: 0; color: var(--accent); font-size: 11px; }
.isg-xp-seed-lock { width: 12px; height: 12px; color: var(--accent); flex: 0 0 auto; }
.isg-xp-seed-clear { background: transparent; border: 0; color: var(--text-2);
  font-size: 15px; line-height: 1; cursor: pointer; padding: 0 2px; }
.isg-xp-seed-clear:hover { color: var(--fg-0); }
.isg-xp-seed-entry { display: flex; align-items: center; gap: 8px; }
.isg-xp-seed-entry .isg-btn-sm { height: 32px; flex: 0 0 auto; }
.isg-xp-seed-input { flex: 1; min-width: 0; height: 32px; }
.isg-xp-cohort { font-size: 12px; color: var(--text-2); }
.isg-xp-cohort b { color: var(--accent); font-weight: 600; }
.isg-xp-hint { font-size: 11px; color: var(--text-3); }

/* Center map */
.isg-xp-map { position: relative; }
.isg-xp-canvas { position: absolute; inset: 0; }
.isg-xp-mapcount { position: absolute; right: 14px; top: 12px; z-index: 2;
  background: rgba(7,16,12,.82); border: 1px solid var(--border-0); border-radius: 18px;
  padding: 6px 13px; font-size: 12px; color: var(--text-1); }
.isg-xp-mapcount b { color: var(--accent); font-weight: 600; }

/* Within-cohort sub-searches (Plan 5.7 Seed & Flow) — chained text rows in the builder, shown
   only once seeded. Each row matches the filter-row layout (remove button + input). */
.isg-xp-subsearch-input { flex: 1; min-width: 0; height: 32px; }

/* Right list */
.isg-xp-search { margin: 10px 12px 6px; display: flex; align-items: center; gap: 8px;
  background: var(--bg-2); border: 1px solid var(--border-0); border-radius: 9px; padding: 8px 11px; }
.isg-xp-search-input { flex: 1; background: transparent; border: 0; color: var(--text-0); font-size: 12.5px; outline: none; }
.isg-xp-search-icon { width: 14px; height: 14px; color: var(--text-3); }
.isg-xp-search-clear { background: transparent; border: 0; color: var(--text-3); font-size: 16px; cursor: pointer; }
.isg-xp-records-scroll { flex: 1; overflow-y: auto; }
.isg-xp-records-placeholder { padding: 24px; text-align: center; }

/* Explorer dashboard module */
.isg-xpmod { cursor: pointer; display: flex; flex-direction: column; height: 100%; }
.isg-xpmod-split { display: grid; grid-template-columns: 1fr 1fr; gap: 11px; flex: 1; min-height: 0; }
/* Abstract spatial fingerprint — severity pins normalized into a 0–100% box (no Mapbox).
   Deliberately NOT a map: it sits on the normal module surface and carries no map chrome,
   so it reads as a stylized snapshot rather than a basemap that failed to load. */
.isg-xpmod-scatter { position: relative; border: 1px solid var(--border-0); border-radius: 9px; overflow: hidden;
  background: transparent; }
.isg-xpmod-pin { position: absolute; width: 8px; height: 8px; border-radius: 50%; transform: translate(-50%, -50%); }
.isg-xpmod-pin[data-pc="0"] { background: var(--pc-0); } .isg-xpmod-pin[data-pc="1"] { background: var(--pc-1); }
.isg-xpmod-pin[data-pc="2"] { background: var(--pc-2); } .isg-xpmod-pin[data-pc="3"] { background: var(--pc-3); }
.isg-xpmod-pin[data-pc="4"] { background: var(--pc-4); } .isg-xpmod-pin[data-pc="5"] { background: var(--pc-5); }
.isg-xpmod-pin[data-pc="6"] { background: var(--pc-6); } .isg-xpmod-pin[data-pc="7"] { background: var(--pc-7); }
.isg-xpmod-pin[data-pc="8"] { background: var(--pc-8); }
.isg-xpmod-pin[data-pri="1"] { background: var(--pri-1); } .isg-xpmod-pin[data-pri="2"] { background: var(--pri-2); }
.isg-xpmod-pin[data-pri="3"] { background: var(--pri-3); } .isg-xpmod-pin[data-pri="4"] { background: var(--pri-4); }
.isg-xpmod-pin[data-pri="0"] { background: var(--pc-0); }
.isg-xpmod-tiles { border: 1px solid var(--border-0); border-radius: 9px; background: transparent; overflow: hidden;
  display: flex; flex-direction: column; }
.isg-xpmod-th { font-size: 9.5px; text-transform: uppercase; letter-spacing: .8px; color: var(--text-3);
  padding: 7px 10px; border-bottom: 1px solid var(--border-0); }
.isg-xpmod-th b { color: var(--accent); }
.isg-xpmod-foot { margin-top: 9px; font-size: 10.5px; color: var(--text-3); display: flex; align-items: center; gap: 6px; }

/* Origin chip — marks a dashboard tile's provenance (saved tracked search / Explorer view).
   Pinned to the module's bottom-right corner (out of the title flow, so a long name can't clip
   it); shared by both special module types so they read as one consistent family. */
.isg-dash-tile-origin { position: absolute; right: 0; bottom: 0; z-index: 1; pointer-events: none;
  display: inline-flex; align-items: center; gap: 4px; font-size: 9.5px;
  text-transform: uppercase; letter-spacing: .8px; color: var(--accent); background: var(--accent-soft);
  border: 1px solid rgba(61,220,151,.3); border-radius: 11px; padding: 2px 7px; }
.isg-dash-tile-origin svg { width: 11px; height: 11px; }
/* Reserve room under the flowing content (View all foot, Note) so it stops above the
   absolutely-positioned Saved Item chip instead of running under it. Scoped to tiles that
   actually carry a chip; border-box keeps the padding inside the height:100% inner. */
.isg-module--stat > .isg-module-inner:has(> .isg-dash-tile-origin) {
  box-sizing: border-box; padding-bottom: 22px;
}

/* ══ Alerts (Plan 6) ══════════════════════════════════════════════════════
   Two modes on one view: the rule library (list) and the rule builder. The builder
   reuses the shared .isg-bfield / .isg-pill / .isg-picker-btn controls; only the
   alerts-specific layout + card styling lives here. */
.isg-alerts-view { height: 100%; overflow-y: auto; }
.isg-alerts { max-width: 1040px; margin: 0 auto; padding: 24px 28px 48px; }

/* — List mode — */
.isg-alerts-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 20px; }
.isg-alerts-title { font-size: 1.5rem; color: var(--fg-0); margin: 0; }
.isg-alerts-sub { font-size: 0.85rem; color: var(--text-2); margin: 4px 0 0; max-width: 60ch; }

/* The feed/register are the canonical .isg-module--activity; on a scrolling page (not a docked
   panel) the list grows with content and the page scrolls, so undo the panel's internal flex/scroll. */
.isg-alerts-panel { display: block; margin-bottom: 28px; }
.isg-alerts-panel > .isg-module-inner { display: block; }
.isg-alert-feed { overflow: visible; }

.isg-alerts-rules-head { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text-2); margin-bottom: 12px; }
.isg-alerts-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; color: var(--text-2); font-size: 0.9rem; padding: 40px 0; text-align: center; }
.isg-alerts-empty svg { width: 28px; height: 28px; opacity: 0.5; }

.isg-alerts-rulelist { display: flex; flex-direction: column; gap: 10px; }
/* Rule cards are Modules — bg / rim / elevation / spotlight come from .isg-module. --module-pad:0
   keeps the existing inner padding (size unchanged); the main↔actions flex moves to module-inner. */
.isg-alert-card { --module-pad: 0; }
.isg-alert-card > .isg-module-inner { display: flex; align-items: stretch; }
.isg-alert-card:hover::before { border-color: var(--border-1); }
.isg-alert-card.is-off { opacity: 0.6; }
.isg-alert-card-main { flex: 1; min-width: 0; padding: 14px 16px; cursor: pointer; }
.isg-alert-card-top { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.isg-alert-name { font-size: 0.95rem; color: var(--fg-0); font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.isg-alert-badge { flex-shrink: 0; font-size: 0.66rem; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 2px 8px; border-radius: 10px; }
.isg-alert-badge.is-notify { background: var(--accent-soft); color: var(--accent); }
.isg-alert-badge.is-log { background: var(--bg-2); color: var(--text-2); }
.isg-alert-card-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.isg-alert-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 0.72rem; color: var(--fg-1);
  background: var(--bg-2); border-radius: 8px; padding: 3px 8px; }
.isg-alert-chip svg { width: 12px; height: 12px; opacity: 0.7; }
.isg-alert-chip.is-paused { color: #ffc84b; }
.isg-alert-chip.is-off { color: #ff6b6b; }
.isg-alert-card-actions { display: flex; align-items: center; gap: 4px; padding: 0 12px; border-left: 1px solid var(--border-0); }
.isg-alert-card-actions .isg-icon-btn:hover { color: var(--fg-0); }

/* — Builder mode — */
.isg-alerts-bhead { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.isg-alerts-btitle { font-size: 1.15rem; color: var(--fg-0); }
.isg-alerts-bgrid { display: grid; grid-template-columns: 1fr; gap: 20px; align-items: start; }
.isg-ab-match, .isg-ab-settings { background: var(--bg-1); border: 1px solid var(--border-0);
  border-radius: var(--r-lg); padding: 18px 18px 22px; display: flex; flex-direction: column; gap: 16px; }
.isg-ab-sectitle { margin-bottom: 2px; }
.isg-ab-opt { color: var(--text-2); font-weight: 400; text-transform: none; letter-spacing: 0; }
.isg-ab-zonepills { margin-top: 8px; }
.isg-ab-hint { font-size: 0.75rem; color: var(--text-2); }
.isg-ab-livecount { font-size: 0.82rem; color: var(--text-2); padding-top: 6px; border-top: 1px solid var(--border-0); }
.isg-ab-livecount b { color: var(--accent); }
.isg-ab-check { display: flex; align-items: center; gap: 8px; font-size: 0.88rem; color: var(--fg-1); cursor: pointer; }
.isg-ab-check input { accent-color: var(--accent); width: 15px; height: 15px; }
.isg-input--time { max-width: 140px; }
/* Native time picker's clock glyph renders dark by default (Blink) — invert it for the dark theme
   so it reads as a light icon rather than a near-black smudge. */
.isg-input--time::-webkit-calendar-picker-indicator { filter: invert(1); opacity: 0.55; cursor: pointer; }

.isg-alerts-bfoot { display: flex; align-items: center; gap: 10px; margin-top: 20px; }
.isg-alerts-bfoot .isg-builder-error { color: #ff6b6b; font-size: 0.82rem; }

/* ── Alerts feed / register tiles (Plan 6) — the shared Activity-Panel .isg-incident-row tile,
   with an alert-only rule name right-justified in the offense row + a subtle unread accent. ── */
/* Offense row becomes offense (left, truncates) + rule name (right); overrides the base
   .isg-incident-type single-line ellipsis, which now lives on the offense span instead. */
.isg-alert-row-top { display: flex; align-items: baseline; gap: 10px; overflow: visible; white-space: normal; }
.isg-alert-row-offense { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.isg-alert-row-rule { flex-shrink: 0; display: inline-flex; align-items: center; gap: 4px;
  font: 500 11px/15px var(--font-ui); color: var(--accent); }
.isg-alert-row-rule svg { width: 11px; height: 11px; }
/* Unread: a soft left accent + brighter text, in keeping with the panel's is-selected tint. */
.isg-alert-row.is-unread { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.isg-alert-row.is-unread .isg-alert-row-offense { color: var(--fg-0); }

.isg-alert-unread { flex-shrink: 0; min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
  background: var(--accent); color: #061410; font-size: 0.7rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; }

/* ── Alert monitor-window editor (Plan 6 Stage 6) ── */
.isg-ab-winband { align-items: center; gap: 8px; }
.isg-ab-windays { gap: 5px; margin-top: 8px; flex-wrap: wrap; }
/* The explanatory hint under a window's day pills gets a little air (scoped to the day-pills
   sibling so the inline "to" separator and other hints are untouched). */
.isg-ab-windays + .isg-ab-hint { margin-top: 8px; }
.isg-pill--day { min-width: 34px; padding: 5px 0; text-align: center; justify-content: center; }
/* Notify sub-settings are nested in an x-show wrapper, so the panel's flex gap doesn't reach them —
   give the wrapper the same column rhythm so every section is spaced evenly (16px). */
.isg-ab-sub { display: flex; flex-direction: column; gap: 16px; }

/* ── Alerts dev "Run now" trigger + result flash (Plan 6, removed at go-live) ── */
.isg-alerts-head-actions { display: flex; align-items: center; gap: 8px; }
.isg-alerts-runresult { font-size: 0.82rem; color: var(--text-2); background: var(--bg-1);
  border: 1px solid var(--border-0); border-radius: var(--r-md); padding: 8px 14px; margin-bottom: 16px; }
.isg-alerts-runresult b { color: var(--accent); }

/* ── Assistant chat (Plan 8) — floating button + docked drawer, desktop only.
   Mobile full-screen treatment is a separate later task — do not add mobile rules here. ── */
.isg-chat-fab {
  position: fixed; right: 24px; bottom: 24px; z-index: var(--z-panel);
  width: 52px; height: 52px; border-radius: 50%; border: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #061410; cursor: pointer;
  box-shadow: var(--elev-pop);
  transition: filter var(--d-fast) var(--ease);
}
.isg-chat-fab:hover { filter: brightness(1.1); }
.isg-chat-fab i { width: 22px; height: 22px; }

.isg-chat {
  position: fixed; right: 24px; bottom: 24px; z-index: var(--z-modal);
  width: 420px; height: min(640px, calc(100vh - 96px));
  background: var(--bg-1); border: 1px solid var(--border-0); border-radius: var(--r-lg);
  box-shadow: var(--elev-pop);
  display: flex; flex-direction: column; overflow: hidden;
}

.isg-chat-head {
  flex-shrink: 0; display: flex; align-items: center; gap: 8px;
  padding: 10px 12px; border-bottom: 1px solid var(--border-0);
}
.isg-chat-title { font: var(--t-body-md); color: var(--fg-0); margin-right: auto; }
.isg-chat-model {
  height: 30px; padding: 0 8px; border-radius: var(--r-sm);
  background: var(--bg-2); border: 1px solid var(--border-1); color: var(--fg-1);
  font: var(--t-small); cursor: pointer;
}

.isg-chat-scroll { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 10px; }
.isg-chat-hint { font: var(--t-small); color: var(--fg-2); text-align: center; padding: 12px; }
.isg-chat-hint a { color: var(--accent); }

.isg-chat-turn { display: flex; flex-direction: column; gap: 4px; max-width: 88%; }
.isg-chat-turn.is-user { align-self: flex-end; align-items: flex-end; }
.isg-chat-turn.is-assistant { align-self: flex-start; align-items: flex-start; }
.isg-chat-bubble {
  padding: 8px 12px; border-radius: var(--r-md); font: var(--t-body); color: var(--fg-0);
  white-space: pre-wrap; word-break: break-word;
}
.isg-chat-turn.is-user .isg-chat-bubble { background: var(--bg-2); }
.isg-chat-turn.is-assistant .isg-chat-bubble { background: var(--bg-0); border: 1px solid var(--border-0); }
.isg-chat-status { display: block; margin-top: 4px; font: var(--t-caption); color: var(--fg-2); }

.isg-chat-work {
  border: 0; background: none; padding: 0; margin: 0;
  font: var(--t-caption); color: var(--fg-2); cursor: pointer; text-decoration: underline;
}
.isg-chat-work:hover { color: var(--fg-1); }
.isg-chat-worklog {
  max-width: 100%; max-height: 200px; overflow: auto;
  background: var(--bg-0); border: 1px solid var(--border-0); border-radius: var(--r-sm);
  padding: 8px; font: var(--t-mono-sm); color: var(--fg-2); white-space: pre-wrap; word-break: break-word;
}

.isg-chat-foot {
  flex-shrink: 0; display: flex; align-items: center; gap: 8px;
  padding: 14px 16px calc(14px + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--border-0);
}
.isg-chat-foot textarea {
  flex: 1; resize: none; max-height: 96px;
  background: var(--bg-2); border: 1px solid var(--border-1); border-radius: var(--r-sm);
  color: var(--fg-0); font: var(--t-body); padding: 6px 10px;
}
.isg-chat-foot textarea:disabled { opacity: 0.5; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE — Plan 6.2. Single breakpoint: max-width 768px. ALL mobile rules live
   in THIS block only. Mobile top-bar height is 48px (offsets full-screen panels).
   iPhone 17 Pro is 402×874 CSS px — verification numbers only; never hard-code them.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  /* Task 0.2 — drawer + scrim + search */

  /* Sidebar → left off-canvas drawer.
     ⚠ Selector doubled with .is-expanded on purpose: the desktop rule
     `.isg-sidebar.is-expanded { width: 232px }` (app.css ~169) is (0,2,0) and beats a
     bare `.isg-sidebar` (0,1,0) — media queries add NO specificity, so without the
     second selector the drawer opens 232px wide instead of 82vw. */
  .isg-sidebar,
  .isg-sidebar.is-expanded {
    position: fixed; top: 0; left: 0; bottom: 0;
    width: 82vw; max-width: 320px;
    /* ⚠ +2/+1, not bare --z-menu: the mobile top bar is also z --z-menu, and the
       sidebar/scrim precede .isg-main in the DOM — at EQUAL z the top bar paints on
       top and the drawer slides UNDER its 48px strip. Keep drawer > scrim > top bar. */
    z-index: calc(var(--z-menu) + 2);
    transform: translateX(-100%);
    transition: transform .22s ease;
  }
  .isg-sidebar.is-drawer-open { transform: translateX(0); }
  .isg-sidebar-toggle { display: none; }               /* no desktop collapse chevron on mobile */
  .isg-drawer-scrim {
    position: fixed; inset: 0; background: rgba(8,10,14,.5);
    z-index: calc(var(--z-menu) + 1);   /* above the top bar, below the drawer */
  }
  .isg-drawer-search { display: flex; align-items: center; gap: 8px; padding: 8px 10px; margin-bottom: 6px; }
  .isg-drawer-search-input {
    flex: 1; height: 34px; border-radius: 8px;
    background: var(--bg-1); border: 1px solid var(--border-1); color: var(--fg-0);
    padding: 0 10px;
  }

  /* Task 0.3 — contextual top bar */

  /* Hide the desktop top-bar (breadcrumb, center filters, right icons) */
  .isg-topbar-l, .isg-topbar-c, .isg-topbar-r { display: none; }
  .isg-topbar { position: sticky; top: 0; z-index: var(--z-menu); height: 48px; padding: 0; }

  .isg-mtopbar { width: 100%; height: 48px; }
  .isg-mtopbar-root { width: 100%; height: 100%; display: flex; align-items: center; gap: 8px;
    padding: 0 12px; background: var(--bg-0); border: 0; color: var(--fg-0); cursor: pointer; }
  .isg-mtopbar-logo { width: 28px; height: 28px; }
  .isg-mtopbar-word { font-weight: 700; }
  .isg-mtopbar-burger { margin-left: auto; display: inline-flex; }

  /* Mobile sub-header — back (left, when drilled) + page title. A non-scrolling flex
     row under the 48px top bar; content flows below it (total chrome = 48 + 40 = 88px).
     Replaces the old center-chevron: one back affordance, top-left, always. */
  .isg-msubhead { flex-shrink: 0; height: 40px; display: flex; align-items: center; gap: 4px;
    padding: 0 8px; background: var(--bg-0); border-bottom: 1px solid var(--border-0); }
  .isg-msubhead-back { display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; margin-left: -4px; background: none; border: 0; color: var(--fg-0); cursor: pointer; }
  .isg-msubhead-back i, .isg-msubhead-back svg { width: 22px; height: 22px; }
  .isg-msubhead-title { font-size: 16px; font-weight: 600; color: var(--fg-1); }

  /* Task 0.4 — tile grid → one column */

  /* The shared "panel of tiles" primitive → single column on a phone */
  .isg-dash-grid { grid-template-columns: 1fr; }
  .isg-module--stat.is-small,
  .isg-module--stat.is-medium,
  .isg-module--stat.is-large { grid-column: auto; }

  /* Task 1.1 — alerts root */

  /* Alerts: lead with the feed + rules; push the title/description/New button to the bottom */
  .isg-alerts-list { display: flex; flex-direction: column; }
  .isg-alerts-panel      { order: 1; }
  .isg-alerts-rules-head { order: 2; }
  .isg-alerts-empty      { order: 2; }
  .isg-alerts-rulelist   { order: 3; }
  .isg-alerts-head       { order: 9; }
  .isg-alerts-runresult  { order: 10; }
  /* order:9 drops the header (title + subtitle + New/dev buttons) below the rules, but it keeps
     the desktop space-between row — on a phone that crushes the subtitle to one word per line and
     wraps the button labels outside the 32px buttons. Stack it: full-width title + subtitle, then
     the actions on their own wrapping row with space above; keep each button label on one line.
     Inset from the edges (the feed above stays edge-to-edge). */
  .isg-alerts-head { flex-direction: column; align-items: stretch; gap: 14px; padding: 0 16px; }
  .isg-alerts-head-actions { flex-wrap: wrap; }
  .isg-alerts-head .isg-btn { white-space: nowrap; }
  /* full-bleed feed: activity module already has --module-pad:0; sev-bars sit flush by design */
  .isg-alerts, .isg-alerts-list { padding-left: 0; padding-right: 0; }

  /* Task 1.2 — full-screen detail */

  /* Drilled-in detail panels fill the screen below the 88px chrome (48 top bar +
     40 sub-header), so the sub-header's back stays reachable above them.
     ⚠ Doubled/compound selectors on purpose — they must out-rank the desktop
     mount-width rules (app.css ~1721–1739, specificity (0,2,0)) that otherwise
     pin the panel to a ~137px right-hand sliver at 402px. Both inset edges set,
     so width is auto — do not reintroduce a width value. This mobile @media block
     must remain LAST in app.css so the source-order tie-break holds. */
  .isg-incident-detail.isg-incident-detail,
  .isg-incident-detail.isg-incident-detail--call {
    position: fixed; inset: 88px 0 0 0;
    width: auto; max-width: none;
    /* ⚠ height:auto is load-bearing — the base rule sets height:100%, which (with
       position:fixed) would make the panel a full 874px TALL starting at y88, pushing
       its foot (the "Center on Map" button + live-status line) ~88px below the viewport.
       auto lets the inset top/bottom govern the height so the foot stays on-screen. */
    height: auto;
    z-index: var(--z-panel); overflow-y: auto;
  }
  /* The panel's own back arrow is redundant on mobile — the sub-header is the single
     back affordance. Keep the offense title + Track This in the panel head. */
  .isg-detail-back { display: none; }

  /* Task 2.1 — dashboard 1-up */

  /* Statistics: lead with the modules; title + toolbar drop to the bottom */
  .isg-stats-shell  { display: flex; flex-direction: column; }
  .isg-stats-header { order: 9; }

  /* Task 2.2 — module drill-down full-screen */

  /* Sit below the 88px chrome (top bar + sub-header); the base rule already
     fixes/z-indexes it. padding:0 — desktop keeps 32px padding (floating-card
     look); on a phone the card IS the screen. */
  .isg-mexp-overlay { inset: 88px 0 0 0; padding: 0; }
  .isg-mexp { border-radius: 0; }
  /* Drill-down stacks on a phone: viz on top, records below — the desktop side-by-side
     (viz + 300px rail) reads as two absurd skinny columns at 400px. The 300px flex-basis
     that was the rail's WIDTH would become its HEIGHT in a column — override to flex:1
     so the records list takes the leftover height with its own internal scroll. */
  .isg-mexp-body { flex-direction: column; }
  .isg-mexp-viz { flex: 0 0 40%; min-height: 0; border-right: 0; border-bottom: 1px solid var(--border-0); padding: 12px; }
  .isg-mexp-records { flex: 1; min-height: 0; }

  /* ⚠ Containing-block trap: .isg-mexp-overlay has backdrop-filter (app.css ~2353),
     which makes it the containing block for position:fixed DESCENDANTS. The detail
     panels included inside _module-expand.php resolve Task 1.2's `inset: 48px 0 0 0`
     against the overlay — which already starts 48px down — landing them doubly
     offset (~96px). Zero the offset for overlay-mounted panels; (0,3,0) out-ranks
     the (0,2,0) Task 1.2 rule regardless of order. */
  .isg-mexp-overlay .isg-incident-detail.isg-incident-detail,
  .isg-mexp-overlay .isg-incident-detail.isg-incident-detail--call { inset: 0; }

  /* Task 3.1 — area studies root */

  /* Area Studies: stack; the stage never shares a row on a phone */
  .is-mobile-areas .isg-areas-stage { display: block; }
  .is-mobile-areas .isg-panel--zones { width: 100%; max-width: none; }
  .is-mobile-areas .isg-areas-center,
  .is-mobile-areas .isg-areas-activity { display: none; }

  /* Task 3.2 — zone detail: map + tiles peek */

  /* Zone detail: hide the zone-info panel + activity; map on top, tiles below */
  .is-mzone-detail .isg-panel--zones { display: none; }          /* hides zone info */
  /* flex: 0 0 45vh — the desktop stage is flex:1 inside the wrap column; left alone it
     stretches to fill the space above the peek and strands the tiles ~250px below the
     45vh map. Pin the stage to the map's height so the peek sits directly under it. */
  .is-mzone-detail .isg-areas-stage  { display: flex; flex-direction: column; flex: 0 0 45vh; }
  .is-mzone-detail .isg-areas-center { display: block; height: 45vh; }
  .is-mzone-detail .isg-areas-map    { height: 100%; }
  /* All tiles stacked below the 45vh map from the moment the zone opens (2026-07-06: the old
     180px "peek" + tap-to-expand two-state showed only the first tile and ate the first tap —
     Jim: all modules should appear on load).
     ⚠ overflow-y:auto, NOT visible: the areas view sits inside .isg-content--map
     (app.css ~132) which is overflow:hidden — `visible` would just clip, and every
     tile below the fold would be unreachable. The panel itself is the scroller. */
  .is-mzone-detail .isg-panel--zone-stats { display: block; width: 100%; flex: 1; min-height: 0; overflow-y: auto; }

  /* ⚠ Deviation (verified live): map pin → detail rendered NOTHING without this.
     The areas view mounts its incident/call detail panels inside .isg-areas-activity
     (_activity-panel.php), which Task 3.1 display:none's on mobile — and
     position:fixed cannot escape a display:none ancestor. Re-show the aside only
     while a detail inside it is open (`.is-open`, toggled by detailOpen /
     callDetailOpen); the full-screen fixed panel covers everything else in the
     aside, so none of the activity rail is actually seen. */
  .is-mobile-areas .isg-areas-activity:has(.isg-incident-detail.is-open) { display: block; }

  /* Reclaim screen real estate: drop the 16px content inset on a phone so the
     alerts feed (and other plain-.isg-content views) run edge-to-edge. Map/areas/
     explorer already use .isg-content--map (padding 0); stats keeps its own shell pad. */
  .isg-content { padding: 0; }

  /* Stats: kill the sideways drift. The header (title + Edit Layout/Library/Add
     Module) is a nowrap flex row ~465px wide — on a 402px phone it overflowed and
     made .isg-stats-view (overflow-x:auto) draggable ~83px sideways. Wrap the header
     to remove the overflow at its source, and hard-lock the scroller to vertical. */
  .isg-stats-header { flex-wrap: wrap; }
  .isg-stats-view { overflow-x: hidden; }

  /* ─── Mobile readability — bump text where reading matters (plenty of vertical
     room on a phone; these are shared classes so the bump is mobile-only). ─── */
  .isg-mtopbar-word { font-size: 20px; }
  /* Activity Panel feed rows (offense/signal title + address/time) */
  .isg-incident-type { font-size: 17px; line-height: 22px; }
  .isg-incident-meta { font-size: 14px; line-height: 19px; }
  /* Detail panels (call + incident) — the fields you drill in to read. Their body is
     built from .isg-gcard-* cards, used ONLY in the two detail templates, so these
     bumps are inherently detail-panel-scoped. */
  .isg-gcard-value,
  .isg-gcard-head-val   { font-size: 18px; line-height: 24px; }   /* the data values */
  .isg-gcard-title      { font-size: 15px; }                      /* section headers */
  .isg-gcard-label      { font-size: 14px; }                      /* field labels */
  .isg-detail-narrative,
  .isg-detail-subnarr   { font-size: 16px; line-height: 1.6; }    /* incident narrative */

  /* ─── Map view (mobile): the map fills the screen; the activity panel is a bottom
     bar that raises full-screen over the map on tap. No legend. The open panel is a
     fixed overlay, so the map never resizes underneath it. ─── */
  .is-mmap .isg-module--legend { display: none; }        /* no legend on a phone */
  /* Collapsed: hide the floating activity panel — the bottom bar is the affordance. */
  .is-mmap .isg-incident-panel { display: none; }
  /* ⚠ Same trap as Area Studies: the map's detail panels mount INSIDE .isg-incident-panel.
     A map-pin tap opens a detail while collapsed — re-show the host so the fixed detail
     can render (it covers the screen; the panel's own feed sits hidden behind it). */
  .is-mmap .isg-incident-panel:has(.isg-incident-detail.is-open) { display: flex; }
  /* Raised: the panel fills the screen below the 88px chrome, over the map. */
  .is-mmap.is-mactivity-full .isg-incident-panel {
    display: flex; position: fixed; inset: 88px 0 0 0; width: auto; padding: 0;
    z-index: var(--z-panel); background: var(--bg-0); overflow-y: auto;
  }
  /* Bottom Activity bar — the collapsed affordance. */
  .isg-mactivity-bar {
    position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: 52px;
    display: flex; align-items: center; gap: 10px; padding: 0 16px;
    background: var(--bg-1); border: 0; border-top: 1px solid var(--border-0);
    color: var(--fg-0); cursor: pointer; z-index: var(--z-popover);
  }
  .is-mactivity-full .isg-mactivity-bar { display: none; }   /* hidden while raised */
  .isg-mactivity-bar-title { font-size: 16px; font-weight: 600; }
  .isg-mactivity-bar-count { color: var(--text-2); font-size: 14px; }
  .isg-mactivity-bar > i, .isg-mactivity-bar > svg { margin-left: auto; width: 20px; height: 20px; }

  /* ─── Map filter dropdowns in the sub-header (map view) — the 5 shared filters,
     icon-only. Reuses the desktop .isg-drop components; CSS hides the label + chevron. ─── */
  .isg-msubhead-tools { margin-left: auto; display: flex; align-items: center; gap: 0; }
  .isg-msubhead-tools .isg-drop-btn {
    width: 40px; height: 40px; padding: 0; justify-content: center;
    background: none; border: 0; border-radius: 8px; color: var(--fg-1);
  }
  .isg-msubhead-tools .isg-drop-btn span,          /* text label — icon-only on a phone */
  .isg-msubhead-tools .isg-drop-caret { display: none; }   /* the chevron */
  .isg-msubhead-tools .isg-drop-btn.is-open { background: var(--bg-2); color: var(--fg-0); }
  .isg-msubhead-tools .isg-drop-btn i, .isg-msubhead-tools .isg-drop-btn svg { width: 20px; height: 20px; }
  /* Menu drops below the icon, right-aligned so it can't run off the right screen edge. */
  .isg-msubhead-tools .isg-drop-menu { left: auto; right: 0; max-height: 62vh; overflow-y: auto; }

  /* ─── Assistant chat (Plan 8 Task 15): full-screen primary view on mobile
     (88px = mtopbar 48px + msubhead 40px chrome). ─── */
  .isg-chat { position: fixed; inset: 88px 0 0 0; width: auto; height: auto;
    border-radius: 0; border: none; max-width: none; }
  .isg-chat-fab { bottom: 76px; }   /* clear the mobile activity bar */
  /* ≥16px or iOS Safari auto-zooms the page on focus, hiding the Send button */
  .isg-chat-foot textarea { font-size: 16px; }
}
