/* GridPulse — Energy Intelligence Platform
 * Design tokens + chrome. All class names preserved; values live in :root.
 *
 * Visual reference: gridpulse-v2 (Next.js + Tailwind) — single-region linear
 * stack, 3-tier surfaces, 4-tier neutrals, blue/orange accents, borders (not
 * shadows) define separation. See ~/.claude/plans/shell-redesign-v2.md.
 */

/* ── Typography ───────────────────────────────────────── */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Sora:wght@600;700&display=swap');

/* ── Design Tokens ────────────────────────────────────── */
:root {
    /* Surfaces — 3 tiers (was 5). Neutral, no blue cast. */
    --bg-base: #0a0a0b;       /* page background, deepest */
    --bg-raised: #111113;     /* cards, dropdowns, badges */
    --bg-hover: #18181b;      /* interactive hover state */
    /* Back-compat aliases for rules still referencing the old 5-tier system. */
    --bg-elevated: var(--bg-raised);
    --bg-overlay: rgba(10, 10, 11, 0.72);

    /* Borders — translucent white ramp; tightened to 0.06 / 0.12 / 0.18 */
    --border-subtle: rgba(255, 255, 255, 0.06);
    --border-default: rgba(255, 255, 255, 0.12);
    --border-strong: rgba(255, 255, 255, 0.18);
    --border-accent: #3b82f6;

    /* Text — neutral 4-tier ramp (warmer than the prior cool slate) */
    --text-primary: #e4e4e7;
    --text-secondary: #a1a1aa;
    --text-tertiary: #71717a;
    --text-disabled: #52525b;
    /* Back-compat alias */
    --text-muted: var(--text-disabled);

    /* Accent — v2 blue (replaces brand cyan #38D0FF) */
    --accent-base: #3b82f6;
    --accent-hover: #5b9aff;
    --accent-dim: rgba(59, 130, 246, 0.15);
    --accent-ring: rgba(59, 130, 246, 0.30);

    /* Forecast — v2 orange (new; was implicit in --warning previously) */
    --forecast: #f97316;
    --forecast-dim: rgba(249, 115, 22, 0.12);

    /* Semantic — tonal updates to match v2 palette */
    --success: #34d399;
    --success-dim: rgba(52, 211, 153, 0.12);
    --warning: #fbbf24;
    --warning-dim: rgba(251, 191, 36, 0.12);
    --danger: #f87171;
    --danger-dim: rgba(248, 113, 113, 0.12);
    --info: #60a5fa;
    --info-dim: rgba(96, 165, 250, 0.12);

    /* Typography */
    --font-sans: 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
    --font-display: 'Sora', 'Inter', sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, monospace;

    --text-xs: 11px;
    --text-sm: 12px;
    --text-base: 13px;
    --text-md: 14px;
    --text-lg: 16px;
    --text-xl: 20px;
    --text-2xl: 28px;
    --text-3xl: 36px;

    /* Fluid display size — clamps between --text-xl (20px) and --text-2xl
     * (28px), interpolated by viewport. Replaces the abrupt stepwise jump
     * at the 1440px breakpoint with a smooth scale across 1280–1920px. */
    --text-display: clamp(20px, 1.6vw + 12px, 28px);

    --leading-tight: 1.25;
    --leading-base: 1.5;
    --leading-relaxed: 1.65;

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

    /* Radii */
    --radius-sm: 4px;
    --radius-md: 6px;
    --radius-lg: 8px;
    --radius-xl: 12px;
    --radius-full: 9999px;

    /* Shadows — v2 uses borders, not drop shadows. Keep only :focus-visible.
     * Card surfaces opt into the top-edge highlight via --edge-highlight. */
    --shadow-xs: none;
    --shadow-sm: none;
    --shadow-md: none;
    --shadow-focus: 0 0 0 3px var(--accent-ring);
    --edge-highlight: inset 0 1px 0 0 rgba(255, 255, 255, 0.04);

    /* Layout — v2 dashboard uses max-w-5xl (1024px) with 24-32px gutters */
    --content-max-width: 64rem;
    --content-gutter: 1.5rem;
    --section-gap: 2rem;            /* space-y-8 between major sections */
    --card-padding: 1.25rem;        /* p-5 inside cards */
    /* Sticky-chrome offsets — must match .gp-header { height } and the
     * .nav-tabs total height (link padding × 2 + line-height + border).
     * .nav-tabs sticks DIRECTLY under the header so the tab-content
     * region scrolls under both. */
    --header-height: 56px;
    --tabs-height: 48px;

    /* Motion — durations */
    --duration-fast: 120ms;
    --duration-base: 160ms;
    --duration-slow: 240ms;

    /* Motion — easing vocabulary
     *   --ease-out-quint   default for entering states (hover-in, focus, mount)
     *   --ease-in-quint    faster exits — feels "snappy back" on hover-out
     *   --ease-spring      subtle spring; the original GridPulse motion curve
     *   --ease-emphasized  CSS linear() spring for palette/toast slide-in.
     *                      Falls back to --ease-spring where linear() is unsupported
     *                      (overridden by the @supports block below).
     *   --ease             retained as alias of --ease-spring so prior rules
     *                      keep working unchanged.
     */
    --ease-out-quint:  cubic-bezier(0.22, 1, 0.36, 1);
    --ease-in-quint:   cubic-bezier(0.64, 0, 0.78, 0);
    --ease-spring:     cubic-bezier(0.16, 1, 0.3, 1);
    --ease-emphasized: var(--ease-spring);
    --ease:            var(--ease-spring);
}

@supports (transition-timing-function: linear(0, 1)) {
    :root {
        --ease-emphasized: linear(
            0, 0.009 1.4%, 0.084 4.4%, 0.36 11.1%, 0.679 19.7%,
            0.917 28.7%, 1.061 38.4%, 1.121 49.7%, 1.097 60.7%,
            1.045 71.7%, 1.005 84.7%, 0.992 100%
        );
    }
}

/* ── Base ──────────────────────────────────────────────── */
/* Inter stylistic alternates:
 *   cv11 — single-storey 'a' (the "Linear feel")
 *   ss01 — simplified 'g'
 *   ss03 — refined 'l' with curved corner (disambiguates from 1, I)
 * font-optical-sizing lets variable Inter pick its display vs text axis. */
body {
    background-color: var(--bg-base) !important;
    color: var(--text-secondary);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-base);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    font-feature-settings: 'cv11', 'ss01', 'ss03';
    font-optical-sizing: auto;
    position: relative;
}

/* Subtle noise overlay (1.5% opacity) defeats OLED banding on large dark
 * surfaces — same pattern v2 uses (globals.css:48-56). Inline data-URI SVG,
 * fixed full-screen, mix-blend-mode overlay so it sits in front of bg only. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='200' height='200' filter='url(%23n)' opacity='0.5'/></svg>");
    opacity: 0.025;
    pointer-events: none;
    mix-blend-mode: overlay;
    z-index: 9999;
}

/* Tabular numerics — apply to KPI values, table cells, time labels.
 *   <span class="tabular">28,450</span>
 * Aligns decimal places and digit widths across rows. */
.tabular {
    font-variant-numeric: tabular-nums;
}

/* ── Inline Lucide icons (R5b) ─────────────────────────────────── */

:root {
    --icon-xs: 12px;
    --icon-sm: 14px;
    --icon-md: 16px;
    --icon-lg: 20px;
    --icon-xl: 24px;
}

.icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: -0.125em;
    flex-shrink: 0;
    line-height: 0;
    color: currentColor;
}

.icon svg {
    display: block;
    stroke: currentColor;
    fill: none;
    flex-shrink: 0;
}

.icon--xs svg { width: var(--icon-xs); height: var(--icon-xs); }
.icon--sm svg { width: var(--icon-sm); height: var(--icon-sm); }
.icon--md svg { width: var(--icon-md); height: var(--icon-md); }
.icon--lg svg { width: var(--icon-lg); height: var(--icon-lg); }
.icon--xl svg { width: var(--icon-xl); height: var(--icon-xl); }

/* dcc.Markdown wraps the SVG in a <p> — collapse that wrapping. */
.icon p {
    margin: 0;
    padding: 0;
    line-height: 0;
}

/* Severity tinting for alert-card icons */
.alert-card__icon {
    margin-right: var(--space-2);
}

.alert-card__icon--critical { color: var(--danger); }
.alert-card__icon--warning  { color: var(--warning); }
.alert-card__icon--info     { color: var(--info); }

/* Risk MetricsBar stress-breakdown rows */
.gp-stress-row {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 2px 8px;
    border-radius: var(--radius-full);
    font-size: 11px;
    font-weight: 500;
    background: var(--bg-base);
    border: 1px solid var(--border-subtle);
}

.gp-stress-row--critical { color: var(--danger); border-color: var(--danger-dim); }
.gp-stress-row--warning  { color: var(--warning); border-color: var(--warning-dim); }
.gp-stress-row--info     { color: var(--info); border-color: var(--info-dim); }
.gp-stress-row--empty    { color: var(--text-tertiary); }

.gp-stress-row__icon--critical { color: var(--danger); }
.gp-stress-row__icon--warning  { color: var(--warning); }
.gp-stress-row__icon--info     { color: var(--info); }

/* Fallback banner rows (degraded data sources) */
.gp-fallback-row {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font-size: 0.85rem;
    line-height: 1.4;
}

.gp-fallback-row__icon--critical { color: var(--danger); }
.gp-fallback-row__icon--warning  { color: var(--warning); }
.gp-fallback-row__icon--info     { color: var(--info); }

/* Confidence badge inline icon (replaces emoji glyph) */
.gp-confidence-badge__icon {
    margin-right: 4px;
    color: inherit;
}

/* Warming-state hero icon — small bounce-free pulse to suggest activity */
.gp-warming-icon {
    color: var(--info);
}

.alert-card__header {
    display: flex;
    align-items: center;
    gap: var(--space-1);
}

.alert-card__title {
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 600;
}

.alert-card__body {
    margin: var(--space-1) 0 0 0;
    font-size: 12px;
    color: var(--text-secondary);
    line-height: 1.4;
}

.alert-card__expires {
    color: var(--text-tertiary);
    font-size: 10px;
}

/* ── Micro-craft: selection / scrollbar / caret / cursor (R5b) ──── */

::selection {
    background: var(--accent-dim);
    color: var(--text-primary);
}

::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-track {
    background: var(--bg-base);
}

::-webkit-scrollbar-thumb {
    background: var(--bg-elevated);
    border-radius: var(--radius-full);
    border: 2px solid var(--bg-base);
}

::-webkit-scrollbar-thumb:hover {
    background: var(--bg-hover);
}

/* Firefox uses scrollbar-color (different model) */
* {
    scrollbar-color: var(--bg-elevated) var(--bg-base);
    scrollbar-width: thin;
}

:root {
    caret-color: var(--accent-base);
}

/* Cursor states — pointer on every truly interactive surface */
button,
[role="button"],
.nav-link,
.preset-btn,
.gp-panel-toggle,
.gp-preset-chip,
.gp-header__link,
.gp-segmented .form-check-label,
.cross-tab-link,
.overview-quick-nav-card {
    cursor: pointer;
}

button:disabled,
[role="button"][aria-disabled="true"],
input:disabled,
select:disabled,
.disabled {
    cursor: not-allowed;
    opacity: 0.6;
}

/* ── Briefing Mode (R5c — projection / meeting-ready chrome) ───── */
/*
 * Toggled via body.briefing (clientside mirror of meeting-mode-store).
 * Strips navigation, scales hero KPI + page title, hides the noise
 * overlay (reads as banding on projector LCDs), and stamps a watermark
 * in the lower-right of the header.
 */

body.briefing::before {
    display: none;
}

body.briefing .nav-tabs {
    display: none;
}

/* Hide secondary controls and toggle strips in projection */
body.briefing .gp-panel-toggles,
body.briefing .gp-controls-row,
body.briefing .gp-as-of-chip,
body.briefing .freshness-badge,
body.briefing .modebar,
body.briefing .modebar-container {
    display: none !important;
}

/* Bigger breathing room between sections in projection */
body.briefing .gp-section-stack {
    gap: var(--space-12);
}

/* Page title scales up */
body.briefing .gp-page-title__heading {
    font-size: 36px;
    letter-spacing: -0.025em;
}

body.briefing .gp-page-title__subtitle {
    font-size: var(--text-md);
}

/* Hero KPI scales dramatically so it reads from across a room */
body.briefing .gp-metric-value--hero {
    font-size: 56px;
    line-height: 1.05;
}

body.briefing .gp-metric-value {
    font-size: 24px;
}

body.briefing .gp-metric-label {
    font-size: 12px;
}

body.briefing .gp-chart-card {
    padding: var(--space-8);
}

/* Insight card reads as the meeting-room subtitle */
body.briefing .gp-insight-card__body {
    font-size: 18px;
    line-height: 1.6;
}

body.briefing .gp-insight-card__eyebrow {
    font-size: 12px;
}

/* Header — keep the brand visible, hide the persona chip, slightly
 * taller for breathing room. Region selector + Save View + Exit
 * Briefing button stay accessible. */
body.briefing .gp-header__chip {
    display: none;
}

body.briefing .gp-header {
    height: 64px;
}

body.briefing .gp-header__wordmark {
    font-size: var(--text-xl);
}

/* Watermark — soft "GridPulse" stamp in the lower-right of the header,
 * visually anchoring the projection screen even when nav is gone. */
body.briefing .dashboard-header {
    position: relative;
}

body.briefing .dashboard-header::after {
    content: "GridPulse";
    position: absolute;
    right: var(--content-gutter);
    bottom: -28px;
    color: var(--text-tertiary);
    font-family: var(--font-display);
    font-size: var(--text-sm);
    letter-spacing: 0.06em;
    opacity: 0.55;
    pointer-events: none;
}

/* Exit-briefing button — emphasize so users can find it again */
body.briefing #meeting-mode-btn.gp-header__link {
    color: var(--accent-base);
    background: var(--accent-dim);
}

body.briefing #meeting-mode-btn.gp-header__link:hover {
    color: var(--text-primary);
    background: var(--accent-base);
}

/* ── v2 Linear Stack Components (R2 of shell-redesign-v2.md) ───────────
 *
 * Mirrors gridpulse-v2's dashboard rhythm:
 *   max-w-5xl content (--content-max-width: 64rem)
 *   space-y-8 between sections (--section-gap: 32px)
 *   p-5 inside cards (--card-padding: 20px)
 *   Borders, not shadows, define separation
 *   10px UPPERCASE eyebrow / 13px body / text-2xl hero
 */

/* Page wrapper — centered, max-width 1024px, gutter 24px */
.gp-page {
    max-width: var(--content-max-width);
    margin: 0 auto;
    padding: var(--space-6) var(--content-gutter);
    position: relative;
    z-index: 1;  /* above the body::before noise overlay */
}

.gp-section-stack {
    display: flex;
    flex-direction: column;
    gap: var(--section-gap);
}

/* Page title block (region name + subtitle + optional freshness chip) */
.gp-page-title__row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin-bottom: var(--space-1);
}

.gp-page-title__heading {
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: var(--text-xl);
    font-weight: 600;
    letter-spacing: -0.02em;
    margin: 0;
}

.gp-page-title__subtitle {
    color: var(--text-tertiary);
    font-size: var(--text-base);
    margin: 0;
}

/* MetricsBar — 5-up grid with vertical dividers */
.gp-metrics-bar {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    padding: var(--space-4) 0;
}

.gp-metric-cell {
    padding: 0 var(--space-5);
    border-right: 1px solid var(--border-subtle);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.gp-metric-cell:last-child {
    border-right: 0;
}

.gp-metric-cell:first-child {
    padding-left: 0;
}

.gp-metric-label {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    line-height: 1.2;
}

.gp-metric-value-row {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    min-width: 0;
}

.gp-metric-value {
    color: var(--text-primary);
    font-size: var(--text-lg);
    font-weight: 500;
    line-height: 1.2;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.gp-metric-value--hero {
    font-size: var(--text-2xl);
    font-weight: 600;
}

.gp-metric-value--secondary {
    color: var(--text-secondary);
}

.gp-metric-value--positive {
    color: var(--success);
}

.gp-metric-value--negative {
    color: var(--danger);
}

.gp-metric-unit {
    color: var(--text-disabled);
    font-size: 10px;
    line-height: 1.2;
}

/* Chart card — single primary chart wrapper, border + p-5 */
.gp-chart-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--card-padding);
    box-shadow: var(--edge-highlight);  /* selective top-edge sheen */
}

/* Model metrics card — horizontal flex with top/bottom borders only */
.gp-model-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-5);
    border-top: 1px solid var(--border-subtle);
    border-bottom: 1px solid var(--border-subtle);
    padding: var(--space-3) 0;
    flex-wrap: wrap;
}

.gp-model-card__left {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.gp-model-card__eyebrow {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-model-card__name {
    color: var(--text-primary);
    font-size: var(--text-base);
    font-weight: 500;
}

.gp-model-card__badge {
    color: var(--text-secondary);
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-sm);
    padding: 2px var(--space-2);
    font-family: var(--font-mono);
    font-size: 10px;
    line-height: 1.4;
}

.gp-model-card__metrics {
    display: flex;
    align-items: center;
    gap: var(--space-5);
    flex-wrap: wrap;
}

.gp-model-card__metric {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
}

.gp-model-card__metric-label {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-model-card__metric-value {
    color: var(--text-secondary);
    font-size: 12px;
}

/* Insight card — eyebrow + relaxed-leading paragraph, no container chrome */
.gp-insight-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

.gp-insight-card__eyebrow {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-insight-card__body {
    color: var(--text-secondary);
    font-size: 13px;
    line-height: var(--leading-relaxed);
    margin: 0;
}

.gp-insight-card__delta--positive {
    color: var(--success);
    font-weight: 500;
}

.gp-insight-card__delta--negative {
    color: var(--danger);
    font-weight: 500;
}

.gp-insight-card__strong {
    color: var(--text-primary);
    font-weight: 500;
}

/* Page footer — small attribution row */
.gp-footer {
    color: var(--text-disabled);
    font-size: 10px;
    line-height: 1.4;
    padding-top: var(--space-4);
    border-top: 1px solid var(--border-subtle);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.gp-footer__sources {
    letter-spacing: 0.04em;
}

/* MetricsBar 4-up variant (Forecast tab) */
.gp-metrics-bar--4up {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* MetricsBar 3-up variant (Generation panel sub-bar) */
.gp-metrics-bar--3up {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* MetricsBar 5-up variant (Models leaderboard) */
.gp-metrics-bar--5up {
    grid-template-columns: repeat(5, minmax(0, 1fr));
}

/* MetricsBar 2-up variant (e.g. minimal-content states) */
.gp-metrics-bar--2up {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

/* Generation stack — sub-MetricsBar above stacked-area chart */
.gp-generation-stack {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
}

/* ── Risk tab (R4b) ──────────────────────────────────────────────── */

/* Risk MetricsBar uses 1-narrow + 1-wide layout: hero stress score on
 * the left, components breakdown on the right. */
.gp-metrics-bar--risk {
    grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
}

.gp-metric-cell--wide {
    /* Wide cell holds the components breakdown (badges or short rows) */
    align-items: stretch;
}

/* Severity timeline list — vertical stack of alert rows with border-left
 * thickness driving severity weight (4px critical, 2px warning, 1px info). */
.gp-severity-timeline {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding-right: var(--space-2);
}

.gp-severity-timeline .alert-card {
    background: var(--bg-base);
    border: 1px solid var(--border-subtle);
    border-left-width: 2px;
    border-radius: var(--radius-md);
    padding: var(--space-3) var(--space-4);
}

.gp-severity-timeline .alert-card.critical {
    border-left-color: var(--danger);
    border-left-width: 4px;
}

.gp-severity-timeline .alert-card.warning {
    border-left-color: var(--warning);
    border-left-width: 3px;
}

.gp-severity-timeline .alert-card.info {
    border-left-color: var(--info);
    border-left-width: 2px;
}

/* 2-up secondary chart grid (temp exceedance + historical timeline) */
.gp-risk-secondary {
    display: grid;
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--space-4);
}

@media (max-width: 768px) {
    .gp-metrics-bar--risk {
        grid-template-columns: 1fr;
    }

    .gp-risk-secondary {
        grid-template-columns: 1fr;
    }
}

/* Stress breakdown badges layout — slightly looser than the standard
 * MetricsBar so the per-component labels read clearly. */
.gp-metric-stress-breakdown {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    padding-top: var(--space-1);
}

/* Weather strip — compact horizontal row populated by callback */
.gp-weather-strip {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
}

/* ── Models tab (R4c) ──────────────────────────────────────────────── */

/* Multi-select segmented (dbc.Checklist) — same look as RadioItems */
.gp-segmented--multi .form-check-input:checked + .form-check-label {
    background: var(--accent-dim);
    color: var(--accent-base);
}

/* Metrics-table slot — give the existing tab3-metrics-table HTML some
 * v2-aligned breathing room without breaking the existing markup. */
.gp-metrics-table-slot table {
    width: 100%;
    border-collapse: collapse;
    font-size: 12px;
}

.gp-metrics-table-slot th {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    text-align: left;
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
}

.gp-metrics-table-slot td {
    color: var(--text-secondary);
    padding: var(--space-2) var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
    font-variant-numeric: tabular-nums;
}

.gp-metrics-table-slot tr:hover td {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.gp-metrics-table-slot td:first-child {
    color: var(--text-primary);
    font-weight: 500;
}

/* Residuals 3-up grid */
.gp-residual-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}

/* Models error+SHAP 2-up grid */
.gp-models-secondary {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-4);
}

@media (max-width: 768px) {
    .gp-residual-grid,
    .gp-models-secondary {
        grid-template-columns: 1fr;
    }

    .gp-metrics-bar--5up {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

/* ── Scenarios panel (R4a-4) ──────────────────────────────────────── */

.gp-preset-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.gp-preset-chip {
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    padding: 8px 14px;
    background: var(--bg-base);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    color: var(--text-secondary);
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease),
                border-color var(--duration-fast) var(--ease),
                color var(--duration-fast) var(--ease);
}

.gp-preset-chip:hover {
    background: var(--bg-hover);
    border-color: var(--border-default);
    color: var(--text-primary);
}

.gp-preset-chip:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.gp-preset-chip__label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary);
    line-height: 1.2;
}

.gp-preset-chip__sub {
    font-size: 10px;
    color: var(--text-tertiary);
    font-family: var(--font-mono);
    line-height: 1.3;
}

/* 3 sliders in a column */
.gp-scenario-sliders {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-2) 0;
}

.gp-slider-row {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.gp-slider__header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.gp-slider__label {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-slider__readout {
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 500;
    font-family: var(--font-mono);
}

/* dcc.Slider style overrides — match the v2 palette */
.gp-slider .rc-slider-rail {
    background-color: var(--bg-base);
}

.gp-slider .rc-slider-track {
    background-color: var(--accent-base);
}

.gp-slider .rc-slider-handle {
    background-color: var(--bg-raised);
    border: 2px solid var(--accent-base);
    box-shadow: none;
}

.gp-slider .rc-slider-handle:hover,
.gp-slider .rc-slider-handle:focus {
    border-color: var(--accent-hover);
    box-shadow: var(--shadow-focus);
}

.gp-slider .rc-slider-mark-text {
    color: var(--text-disabled);
    font-size: 10px;
}

.gp-slider .rc-slider-mark-text-active {
    color: var(--text-secondary);
}

.gp-slider .rc-slider-dot {
    background-color: var(--bg-base);
    border: 1px solid var(--border-subtle);
}

.gp-slider .rc-slider-dot-active {
    border-color: var(--accent-base);
}

/* Sub-line under a metric value (e.g., timestamp under Peak) */
.gp-metric-sub {
    color: var(--text-disabled);
    font-size: 10px;
    line-height: 1.3;
}

/* ── Controls row (segmented horizon + model — Forecast tab) ───── */

.gp-controls-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-6);
    align-items: flex-end;
}

.gp-control {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
}

.gp-control-eyebrow {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    line-height: 1.2;
}

/* Segmented control — restyles dbc.RadioItems(inline=True) into a
 * v2-style pill with an active-state background. The native radio
 * is hidden; the label takes all interaction. */
.gp-segmented {
    display: inline-flex;
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: 2px;
    gap: 0;
    flex-wrap: nowrap;
}

.gp-segmented .form-check {
    margin: 0;
    padding: 0;
    display: inline-flex;
    align-items: center;
}

.gp-segmented .form-check-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.gp-segmented .form-check-label {
    display: inline-block;
    cursor: pointer;
    padding: 5px 12px;
    border-radius: var(--radius-sm);
    font-size: 12px;
    font-weight: 500;
    color: var(--text-tertiary);
    line-height: 1.2;
    transition: color var(--duration-fast) var(--ease),
                background-color var(--duration-fast) var(--ease);
    margin: 0;
    user-select: none;
}

.gp-segmented .form-check-label:hover {
    color: var(--text-secondary);
}

.gp-segmented .form-check-input:checked + .form-check-label {
    background: var(--bg-hover);
    color: var(--text-primary);
}

.gp-segmented .form-check-input:focus-visible + .form-check-label {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* "Forecast as of" chip — small mono timestamp under the chart */
.gp-as-of-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: 4px 10px;
    background: transparent;
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-full);
    align-self: flex-start;
    margin-top: calc(-1 * var(--space-4));  /* tuck up under the chart card */
}

.gp-chip-label {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-chip-value {
    color: var(--text-secondary);
    font-size: 11px;
    font-family: var(--font-mono);
}

/* InsightCard slot — when the children are populated by a callback that
 * doesn't wrap them in .gp-insight-card itself, the slot div applies
 * the shared eyebrow + paragraph rhythm. */
.gp-insight-card-slot {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}

/* ── Inline panel toggles + collapsing panels (R4a-2) ─────────────── */

.gp-panel-toggles {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
}

.gp-panel-toggle {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding: 6px 12px;
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-full);
    color: var(--text-secondary);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color var(--duration-fast) var(--ease),
                border-color var(--duration-fast) var(--ease),
                color var(--duration-fast) var(--ease);
}

.gp-panel-toggle:hover {
    background: var(--bg-hover);
    border-color: var(--border-default);
    color: var(--text-primary);
}

.gp-panel-toggle:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

.gp-panel-toggle__sigil {
    color: var(--accent-base);
    font-weight: 600;
}

.gp-panel-toggle__label {
    color: inherit;
}

.gp-panel-toggle__hint {
    color: var(--text-disabled);
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-left: var(--space-1);
}

/* Inline panel container (the body inside dbc.Collapse) */
.gp-panel {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--card-padding);
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    box-shadow: var(--edge-highlight);
}

.gp-panel__header {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    flex-wrap: wrap;
}

.gp-panel__eyebrow {
    color: var(--text-disabled);
    font-size: 10px;
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.gp-panel__hint {
    color: var(--text-tertiary);
    font-size: 12px;
}

.gp-panel__placeholder {
    color: var(--text-tertiary);
    font-size: 13px;
    line-height: var(--leading-relaxed);
    margin: 0;
}

/* 3-up grid for the Drivers panel (Temperature / Wind / Solar) */
.gp-drivers-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--space-4);
}

.gp-driver-cell {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background: var(--bg-base);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    min-width: 0;
}

@media (max-width: 768px) {
    .gp-drivers-grid {
        grid-template-columns: 1fr;
    }
}

/* Mobile: stack the 5 metric cells into 2 rows of 2-3 */
@media (max-width: 768px) {
    .gp-metrics-bar {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .gp-metrics-bar--4up {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .gp-metric-cell {
        padding: var(--space-3);
        border-right: 1px solid var(--border-subtle);
        border-bottom: 1px solid var(--border-subtle);
    }

    .gp-metric-cell:nth-child(2n) {
        border-right: 0;
    }

    .gp-metric-cell:nth-last-child(-n+2) {
        border-bottom: 0;
    }
}

/* ── Header (R3 — v2 alignment) ────────────────────────────────
 *
 * Mirrors gridpulse-v2/dashboard/page.tsx:84-125 — fixed h-14, full-width
 * border-bottom, max-w-5xl inner content. Hosts the brand monogram +
 * wordmark on the left and region/persona/mode controls on the right.
 */

.gp-header {
    background: var(--bg-base);
    border-bottom: 1px solid var(--border-subtle);
    height: var(--header-height);
    margin: 0;
    padding: 0;
    /* Sticky chrome: header pins to top of the viewport. z-index 50
     * keeps it above the tab strip (40), KPI rows in flow, and the
     * body::before noise overlay (10000 — but that's fixed-positioned
     * so it occupies its own stacking context). */
    position: sticky;
    top: 0;
    z-index: 50;
}

.gp-header__inner {
    max-width: var(--content-max-width);
    margin: 0 auto;
    padding: 0 var(--content-gutter);
    height: 100%;
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.gp-header__brand {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-shrink: 0;
}

.gp-header__monogram {
    width: 24px;
    height: 24px;
    display: block;
    flex-shrink: 0;
}

.gp-header__wordmark {
    color: var(--text-primary);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    letter-spacing: -0.02em;
    line-height: 1;
    margin: 0;
}

.gp-header__wordmark-grid {
    color: var(--text-primary);
}

.gp-header__wordmark-pulse {
    color: var(--accent-base);
}

/* Right-aligned cluster of controls */
.gp-header__controls {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    flex-shrink: 0;
}

/* Compact select used inside the header (replaces the prior
   "Balancing Authority" / "View" labeled column layout). */
.gp-header__select {
    background-color: var(--bg-raised);
    color: var(--text-primary);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    font-size: var(--text-sm);
    font-weight: 500;
    height: 32px;
    padding: 0 var(--space-3);
    transition: border-color var(--duration-fast) var(--ease),
                background-color var(--duration-fast) var(--ease);
}

.gp-header__select:hover {
    background-color: var(--bg-hover);
    border-color: var(--border-default);
}

.gp-header__select:focus,
.gp-header__select:focus-visible {
    outline: none;
    border-color: var(--accent-base);
    box-shadow: var(--shadow-focus);
}

/* Persona chip — discreet pill, smaller and quieter than the region picker */
.gp-header__chip {
    max-width: 200px;
    background-color: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-full);
    font-size: 12px;
    font-weight: 500;
    height: 28px;
    padding: 0 var(--space-3);
}

.gp-header__chip:hover {
    background-color: var(--bg-raised);
    border-color: var(--border-default);
    color: var(--text-primary);
}

/* Text-only header link (Briefing Mode, Save View) — quieter than a button */
.gp-header__link {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    font-weight: 500;
    background: transparent;
    border: 0;
    padding: var(--space-1) var(--space-2);
    cursor: pointer;
    border-radius: var(--radius-sm);
    transition: color var(--duration-fast) var(--ease),
                background-color var(--duration-fast) var(--ease);
}

.gp-header__link:hover {
    color: var(--text-primary);
    background: var(--bg-raised);
}

.gp-header__link:focus-visible {
    outline: none;
    box-shadow: var(--shadow-focus);
}

/* Tab strip below the header — also bounded to max-w-5xl for visual balance */
.dashboard-tabs,
.gp-tabs-shell {
    max-width: var(--content-max-width);
    margin: 0 auto;
    padding: 0 var(--content-gutter);
}

@media (max-width: 768px) {
    .gp-header__inner {
        gap: var(--space-2);
    }

    .gp-header__chip,
    .gp-header__link {
        display: none;  /* keep only brand + region selector on phones */
    }
}

/* ── Legacy header (kept for callbacks toggling .meeting-mode) ─── */
.dashboard-header {
    background: var(--bg-overlay);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    border-bottom: 1px solid var(--border-subtle);
    padding: var(--space-3) var(--space-6);
    margin-bottom: 0;
}

.dashboard-title {
    color: var(--text-primary);
    font-family: var(--font-display);
    font-size: var(--text-lg);
    font-weight: 600;
    margin: 0;
    letter-spacing: -0.02em;
}

.dashboard-subtitle {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    margin: 0;
}

.persona-switcher {
    max-width: 280px;
    background-color: var(--bg-elevated);
    color: var(--text-primary);
    border: 1px solid var(--border-default);
    border-radius: var(--radius-md);
    font-size: var(--text-base);
    transition: border-color var(--duration-base) var(--ease),
                box-shadow var(--duration-base) var(--ease);
}

.persona-switcher:focus,
.persona-switcher:focus-visible {
    outline: none;
    border-color: var(--accent-base);
    box-shadow: var(--shadow-focus);
}

/* ── Welcome Card ──────────────────────────────────────── */
.welcome-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--accent-base);
    border-radius: var(--radius-lg);
    padding: var(--space-4) var(--space-5);
    margin: var(--space-3) 0;
    box-shadow: var(--shadow-xs);
    animation: fadeIn var(--duration-slow) var(--ease);
}

.welcome-card .welcome-title {
    color: var(--text-primary);
    font-size: var(--text-md);
    font-weight: 600;
    margin-bottom: var(--space-1);
    letter-spacing: -0.005em;
}

.welcome-card .welcome-message {
    color: var(--text-tertiary);
    font-size: var(--text-base);
    line-height: var(--leading-base);
    margin: 0;
}

/* ── KPI Cards ─────────────────────────────────────────── */
.kpi-row {
    margin: var(--space-2) 0 var(--space-3) 0;
}

/* Sub-pixel border via box-shadow (layer 1) so focus rings can stack
 * without layout shift; layer 2 is the inset highlight; layer 3 is depth.
 * Asymmetric transition: 80ms ease-in-quint on exit (snappy back),
 * 120ms ease-out-quint on enter (deliberate). */
.kpi-card {
    background: var(--bg-raised);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    text-align: center;
    box-shadow:
        0 0 0 1px var(--border-subtle),
        0 0 0 1px rgba(255, 255, 255, 0.03) inset,
        0 1px 2px rgba(0, 0, 0, 0.24);
    transition: transform 80ms var(--ease-in-quint),
                box-shadow 80ms var(--ease-in-quint);
}

.kpi-card:hover {
    transform: translateY(-1px);
    box-shadow:
        0 0 0 1px var(--border-default),
        0 0 0 1px rgba(255, 255, 255, 0.06) inset,
        0 4px 12px rgba(0, 0, 0, 0.40);
    transition: transform 120ms var(--ease-out-quint),
                box-shadow 120ms var(--ease-out-quint);
}

.kpi-label {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    margin-bottom: var(--space-1);
    font-weight: 500;
}

.kpi-value {
    color: var(--text-primary);
    font-size: var(--text-display);
    font-weight: 600;
    line-height: var(--leading-tight);
    letter-spacing: -0.01em;
}

.kpi-delta {
    font-size: var(--text-sm);
    margin-top: 2px;
    font-weight: 500;
}

.kpi-delta.positive { color: var(--success); }
.kpi-delta.negative { color: var(--danger); }
.kpi-delta.neutral  { color: var(--text-tertiary); }

/* ── Tabs ──────────────────────────────────────────────── */
.nav-tabs {
    border-bottom: 1px solid var(--border-subtle);
    padding: 0 var(--space-3);
    /* Sticky tab strip pins directly under the header (top:
     * --header-height). The blurred translucent background keeps
     * content under it readable on scroll without a hard line. */
    position: sticky;
    top: var(--header-height);
    z-index: 40;
    background: var(--bg-overlay);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
}

.nav-tabs .nav-link {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    font-weight: 500;
    padding: var(--space-3) var(--space-4);
    border: none;
    border-bottom: 2px solid transparent;
    background: transparent;
    transition: color var(--duration-base) var(--ease),
                border-color var(--duration-base) var(--ease);
}

.nav-tabs .nav-link:hover {
    color: var(--text-secondary);
    border-bottom-color: transparent;
}

.nav-tabs .nav-link.active {
    color: var(--text-primary);
    background: transparent;
    border-bottom-color: var(--accent-base);
}

.tab-content {
    padding: var(--space-4);
}

/* ── Charts ────────────────────────────────────────────── */
.chart-container {
    background: var(--bg-raised);
    border-radius: var(--radius-lg);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    box-shadow:
        0 0 0 1px var(--border-subtle),
        0 1px 2px rgba(0, 0, 0, 0.24);
    transition: box-shadow 80ms var(--ease-in-quint);
}

.chart-container:hover {
    box-shadow:
        0 0 0 1px var(--border-default),
        0 1px 2px rgba(0, 0, 0, 0.24);
    transition: box-shadow 120ms var(--ease-out-quint);
}

.chart-title {
    color: var(--text-primary);
    font-size: var(--text-md);
    font-weight: 500;
    margin-bottom: var(--space-2);
    letter-spacing: -0.005em;
}

/* ── Section Header (new, shared across tabs) ─────────── */
.section-header {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    padding-top: var(--space-5);
    padding-bottom: var(--space-2);
    margin-bottom: var(--space-3);
    border-bottom: 1px solid var(--border-subtle);
}

.section-header__title {
    color: var(--text-primary);
    font-family: var(--font-sans);
    font-size: var(--text-md);
    font-weight: 600;
    letter-spacing: -0.005em;
}

.section-header__subtitle {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    font-weight: 400;
}

/* ── Insight Cards ────────────────────────────────────── */
.insight-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-2) 0;
    box-shadow: var(--shadow-xs);
    animation: fadeIn var(--duration-slow) var(--ease);
}

.insight-card:empty {
    display: none;
}

/* ── Cross-Tab Links ──────────────────────────────────── */
.cross-tab-link {
    color: var(--accent-base);
    font-size: var(--text-xs);
    font-weight: 500;
    cursor: pointer;
    margin-left: var(--space-2);
    white-space: nowrap;
    transition: color 80ms var(--ease-in-quint);
}
.cross-tab-link:hover {
    text-decoration: underline;
    color: var(--accent-hover);
    transition: color 120ms var(--ease-out-quint);
}

.overview-quick-nav-card {
    transition: background var(--duration-base) var(--ease),
                border-color var(--duration-base) var(--ease),
                box-shadow var(--duration-base) var(--ease);
}
.overview-quick-nav-card:hover {
    background: var(--bg-elevated) !important;
    border-color: var(--border-default) !important;
    box-shadow: var(--shadow-sm);
}

/* ── What Changed Card ────────────────────────────────── */
.changes-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--warning);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    margin: var(--space-2) 0;
    box-shadow: var(--shadow-xs);
    animation: fadeIn var(--duration-slow) var(--ease);
}

.changes-card:empty {
    display: none;
}

.changes-card .changes-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: var(--space-2);
}

.changes-card .changes-title {
    font-weight: 600;
    color: var(--text-primary);
    font-size: var(--text-base);
}

.changes-card .changes-timestamp {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
}

.changes-card .change-item {
    padding: var(--space-1) 0;
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--text-base);
    color: var(--text-secondary);
    line-height: var(--leading-base);
}

.changes-card .change-item:last-child {
    border-bottom: none;
}

.changes-card .change-icon {
    margin-right: var(--space-2);
}

/* ── Scenario Simulator Sliders ───────────────────────── */
.slider-container {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    margin-bottom: var(--space-3);
}

.slider-label {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
    margin-bottom: 2px;
}

.slider-value {
    color: var(--text-primary);
    font-weight: 600;
    font-size: var(--text-base);
}

/* ── Preset Scenario Buttons ──────────────────────────── */
.preset-btn {
    background: var(--bg-elevated);
    border: 1px solid var(--border-default);
    color: var(--text-secondary);
    font-size: var(--text-sm);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-md);
    transition: background 80ms var(--ease-in-quint),
                border-color 80ms var(--ease-in-quint),
                color 80ms var(--ease-in-quint);
    width: 100%;
    text-align: left;
    margin-bottom: var(--space-2);
}

.preset-btn:hover {
    background: var(--bg-hover);
    border-color: var(--border-strong);
    color: var(--text-primary);
    transition: background 120ms var(--ease-out-quint),
                border-color 120ms var(--ease-out-quint),
                color 120ms var(--ease-out-quint);
}

.preset-btn .preset-name {
    font-weight: 600;
    display: block;
    color: var(--text-primary);
}

.preset-btn .preset-meta {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
}

/* ── Alerts ────────────────────────────────────────────── */
.alert-card {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--border-default);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    margin-bottom: var(--space-2);
    box-shadow: var(--shadow-xs);
}

.alert-card.critical { border-left-color: var(--danger); }
.alert-card.warning  { border-left-color: var(--warning); }
.alert-card.info     { border-left-color: var(--info); }

/* ── Metrics Table ────────────────────────────────────── */
.metrics-table {
    width: 100%;
    border-collapse: collapse;
}

.metrics-table th {
    background: var(--bg-elevated);
    color: var(--text-secondary);
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-sm);
    font-weight: 500;
    text-align: center;
    letter-spacing: 0.02em;
    text-transform: uppercase;
}

.metrics-table td {
    padding: var(--space-2) var(--space-3);
    text-align: center;
    border-bottom: 1px solid var(--border-subtle);
    font-size: var(--text-base);
    color: var(--text-secondary);
}

.metrics-table tbody tr {
    transition: background var(--duration-fast) var(--ease);
}

.metrics-table tbody tr:hover {
    background: var(--bg-hover);
}

/* ── News / Grid Signals ──────────────────────────────── */
.news-ribbon {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    margin-top: var(--space-4);
    box-shadow: var(--shadow-xs);
}

.news-ribbon-header {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-bottom: var(--space-3);
    font-weight: 500;
}

.news-ticker-viewport {
    overflow: hidden;
}

.news-ticker-track {
    display: flex;
    gap: var(--space-3);
    animation: ticker-scroll 60s linear infinite;
    width: max-content;
}

.news-ticker-viewport:hover .news-ticker-track {
    animation-play-state: paused;
}

@keyframes ticker-scroll {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}

.news-ribbon-card {
    flex: 0 0 260px;
    background: var(--bg-elevated);
    border: 1px solid var(--border-subtle);
    border-left: 3px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
    transition: border-color var(--duration-base) var(--ease),
                background var(--duration-base) var(--ease);
    text-decoration: none;
    display: block;
}

.news-ribbon-card:hover {
    border-color: var(--border-default);
    border-left-color: var(--accent-base);
    background: var(--bg-hover);
}

.news-ribbon-card .news-title {
    color: var(--text-secondary);
    font-size: var(--text-base);
    font-weight: 500;
    line-height: var(--leading-tight);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.news-ribbon-card:hover .news-title {
    color: var(--text-primary);
}

.news-ribbon-card .news-meta {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
    margin-top: var(--space-1);
}

/* ── AI Briefing Card ─────────────────────────────────── */
.briefing-card {
    background: var(--bg-raised);
    border-radius: var(--radius-lg);
    padding: var(--space-4) var(--space-5);
    margin: var(--space-2) 0;
    box-shadow:
        0 0 0 1px var(--border-subtle),
        0 1px 2px rgba(0, 0, 0, 0.24);
    animation: fadeIn var(--duration-slow) var(--ease);
}

.briefing-card-content {
    padding-left: var(--space-3);
}

/* ── Skeleton Loading ─────────────────────────────────── */
.skeleton-pulse {
    padding: var(--space-1) 0;
}

.skeleton-line {
    height: 12px;
    /* Tighter gradient stops (30/50/70) narrow the highlight band so the
     * shimmer reads as a single sweep rather than a wide gradient wash;
     * 1.8s slows the cadence for a calmer, less jittery feel. */
    background: linear-gradient(90deg,
        var(--bg-raised) 30%,
        var(--bg-elevated) 50%,
        var(--bg-raised) 70%);
    background-size: 200% 100%;
    border-radius: var(--radius-sm);
    margin-bottom: var(--space-2);
    animation: skeleton-shimmer 1.8s ease-in-out infinite;
}

.skeleton-line-long   { width: 90%; }
.skeleton-line-medium { width: 60%; }

@keyframes skeleton-shimmer {
    0%   { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}

/* ── Insight Digest ───────────────────────────────────── */
.insight-digest {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-lg);
    padding: var(--space-3) var(--space-4);
    min-height: 260px;
    box-shadow: var(--shadow-xs);
}

.insight-digest:empty::after {
    content: "Loading insights...";
    color: var(--text-tertiary);
    font-size: var(--text-base);
    font-style: italic;
}

/* ── Animations ───────────────────────────────────────── */
@keyframes fadeIn {
    from { opacity: 0; transform: translateY(-6px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* ── Data Freshness Badge ─────────────────────────────── */
.freshness-badge {
    font-size: var(--text-xs);
    padding: 2px var(--space-2);
    border-radius: var(--radius-full);
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-weight: 500;
    letter-spacing: 0.01em;
}

.freshness-badge::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
    display: inline-block;
}

.freshness-badge.fresh {
    background: var(--success-dim);
    color: var(--success);
}

.freshness-badge.stale {
    background: var(--warning-dim);
    color: var(--warning);
}

.freshness-badge.expired {
    background: var(--danger-dim);
    color: var(--danger);
}

/* ── Dash Dropdown (dark theme override) ──────────────── */
.Select-control {
    background-color: var(--bg-elevated) !important;
    border-color: var(--border-default) !important;
    color: var(--text-primary) !important;
    border-radius: var(--radius-md) !important;
}
.Select-menu-outer {
    background-color: var(--bg-elevated) !important;
    border-color: var(--border-default) !important;
    border-radius: var(--radius-md) !important;
    box-shadow: var(--shadow-md);
}
.VirtualizedSelectOption {
    background-color: var(--bg-elevated) !important;
    color: var(--text-primary) !important;
}
.VirtualizedSelectFocusedOption {
    background-color: var(--bg-hover) !important;
}
.Select-value-label, .Select-placeholder {
    color: var(--text-primary) !important;
}
.Select-input > input {
    color: var(--text-primary) !important;
}
.Select-arrow {
    border-color: var(--text-tertiary) transparent transparent !important;
}
.is-open > .Select-control .Select-arrow {
    border-color: transparent transparent var(--text-tertiary) !important;
}
.Select-clear-zone { color: var(--text-tertiary) !important; }

/* ── Region Selector ──────────────────────────────────── */
.region-selector {
    max-width: 240px;
}

/* ── Responsive ───────────────────────────────────────── */
@media (max-width: 768px) {
    .kpi-card { margin-bottom: var(--space-2); }
    .dashboard-title { font-size: var(--text-md); }
    .dashboard-header { padding: var(--space-2) var(--space-3); }
    .nav-tabs .nav-link { padding: var(--space-2) var(--space-3); font-size: var(--text-xs); }
    .slider-container { padding: var(--space-3); }
    .chart-container { padding: var(--space-2); }
    .news-ribbon-card { flex: 0 0 220px; }
}

@media (min-width: 1440px) {
    /* .kpi-value font-size now scales fluidly via --text-display; the
     * stepwise override at this breakpoint is no longer needed. */
    .chart-container { padding: var(--space-4); }
}

@media (min-width: 1920px) {
    .dashboard-header { padding: var(--space-4) var(--space-8); }
    .tab-content { padding: var(--space-5) var(--space-6); }
}

/* ── Focus Indicators (Accessibility) ─────────────────── */
/* Dual-layer ring (Radix/Vercel pattern):
 *   inner 2px in --bg-base creates a clean gap that follows the element's
 *   own border-radius; outer 2px in --accent-base is the visible ring.
 *   Avoids the awkward outline-offset on rounded corners. */
*:focus-visible {
    outline: none;
    box-shadow:
        0 0 0 2px var(--bg-base),
        0 0 0 4px var(--accent-base);
}

.nav-tabs .nav-link:focus-visible {
    outline: 2px solid var(--accent-base);
    outline-offset: -2px;
}

.preset-btn:focus-visible {
    outline: none;
    border-color: var(--accent-base);
    box-shadow: var(--shadow-focus);
}

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

.sr-only-focusable:focus {
    position: static;
    width: auto;
    height: auto;
    padding: var(--space-2) var(--space-4);
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
}

/* ── Reduced Motion ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
    .welcome-card,
    .insight-card,
    .changes-card,
    .briefing-card { animation: none; }
    .overview-quick-nav-card { transition: none !important; }
    .news-ticker-track { animation: none; }
    .kpi-card { transition: none; }
    .gp-region-card { transition: none !important; }
    * { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ── V1.β: US Grid small-multiples ─────────────────────── */
.gp-region-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: var(--space-4);
}

/* Geographic section headers inside the card grid. Span the full row
   via ``grid-column: 1 / -1``; the bottom border under the label
   creates the visual section break without needing a separate divider
   element. The first header drops its top spacing so the grid hugs
   the metrics bar above. */
.gp-region-grid__section-header {
    grid-column: 1 / -1;
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    padding: var(--space-3) 0 var(--space-1);
    border-bottom: 1px solid var(--border-subtle);
    margin-bottom: calc(var(--space-1) * -1);
}

.gp-region-grid__section-header:first-child {
    padding-top: 0;
}

.gp-region-card {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    padding: var(--card-padding);
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    cursor: pointer;
    transition: border-color 120ms ease, background 120ms ease, transform 120ms ease;
    min-width: 0;
    color: var(--text-secondary);
}

.gp-region-card:hover {
    border-color: var(--border-default);
    background: var(--bg-hover);
    transform: translateY(-1px);
}

.gp-region-card:focus-visible {
    outline: 2px solid var(--accent-ring);
    outline-offset: 2px;
}

.gp-region-card--empty {
    opacity: 0.6;
}

.gp-region-card__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
}

.gp-region-card__name {
    color: var(--text-primary);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.02em;
}

.gp-region-card__demand {
    display: flex;
    align-items: baseline;
    gap: var(--space-2);
    min-width: 0;
}

.gp-region-card__demand-value {
    color: var(--text-primary);
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.1;
}

.gp-region-card__demand-unit {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
}

.gp-region-card__demand-empty {
    color: var(--text-disabled);
    font-size: var(--text-2xl);
    font-weight: 500;
    line-height: 1.1;
}

.gp-region-card__delta {
    margin-left: auto;
    font-size: var(--text-xs);
    font-weight: 500;
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
}

.gp-region-card__delta--up {
    color: var(--warning);
    background: var(--warning-dim);
}

.gp-region-card__delta--down {
    color: var(--success);
    background: var(--success-dim);
}

.gp-region-card__stress {
    font-size: var(--text-xs);
    font-weight: 500;
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    font-variant-numeric: tabular-nums;
}

.gp-region-card__stress--low {
    color: var(--success);
    background: var(--success-dim);
}

.gp-region-card__stress--mid {
    color: var(--warning);
    background: var(--warning-dim);
}

.gp-region-card__stress--high {
    color: var(--danger);
    background: var(--danger-dim);
}

/* V3.η stop-gap: BAs whose served demand exceeds in-territory
   capacity by >2×. The capacity figure is wrong for ranking purposes
   (utility BAs that import nearly all their power); display a neutral
   "imports" label instead of a misleading multi-hundred-percent
   number. See ``_STRESS_RELIABLE_CEILING`` in components/callbacks.py. */
.gp-region-card__stress--imports {
    color: var(--text-tertiary);
    background: var(--bg-raised);
    font-style: italic;
}

/* V3.α — net BA-to-BA interchange chip. Sign-coded:
   export (+ flow out) reads success-tone, import (- flow in) reads
   forecast/orange-tone (the same accent forecasts use), and a near-
   zero net renders neutral so it doesn't compete for attention. */
.gp-region-card__interchange {
    font-size: var(--text-xs);
    font-weight: 500;
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    font-variant-numeric: tabular-nums;
}

.gp-region-card__interchange--export {
    color: var(--success);
    background: var(--success-dim);
}

.gp-region-card__interchange--import {
    color: var(--forecast);
    background: rgba(249, 115, 22, 0.12);
}

.gp-region-card__interchange--neutral {
    color: var(--text-tertiary);
    background: var(--surface-sunken);
}

.gp-region-card__sparkline {
    height: 28px;
    color: var(--accent-base);
}

.gp-region-card__sparkline--empty {
    color: var(--text-disabled);
}

.gp-region-card__sparkline-svg {
    width: 100%;
    height: 100%;
    display: block;
}

@media (max-width: 1024px) {
    .gp-region-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 768px) {
    .gp-region-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 480px) {
    .gp-region-grid {
        grid-template-columns: 1fr;
    }
}

/* V1.γ: Cards | Map view toggle row + map container */
.gp-us-grid-view-control {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    justify-content: flex-end;
}

.gp-region-map {
    background: var(--bg-raised);
    border: 1px solid var(--border-subtle);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    overflow: hidden;
}

.gp-region-map--empty {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 240px;
}

.gp-region-map__empty-message {
    color: var(--text-tertiary);
    font-size: var(--text-sm);
}

.gp-region-map__coverage-caption {
    color: var(--text-tertiary);
    font-size: var(--text-xs);
    text-align: center;
    margin-top: var(--space-2);
    line-height: 1.4;
}
