/* Design System - Data Analyst Portal v2 */

:root {
    /* Colors — `--primary` is the canonical app-wide brand colour
       (blue), used across nav, buttons, links, and active states on
       login, dashboard, catalog, marketplace, admin, etc. The /home
       redesign opted into a green/navy palette via local
       `.home-mock` / `.advanced-mock` overrides; those scopes set
       their own `--hp-primary` so the green only applies where the
       redesign explicitly opts in. Everything else inherits blue. */
    --primary: #0073D1;
    --primary-light: rgba(0, 115, 209, 0.1);
    --primary-dark: #005BA3;
    --brand-accent: #4F9DEB;
    --hero-bg: #0f1b3a;
    --hero-ink: #f3f6ff;
    --text-primary: #0e1525;
    --text-secondary: #4a5168;
    --background: #f6f7fa;
    --surface: #ffffff;
    --surface-dim: #f0f2f6;
    --border: #e4e7ee;
    --border-light: #f0f2f6;
    --border-dark: #c4c4c4;
    --success: #10B77F;
    --warning: #F59F0A;
    --error: #EA580C;
    --info-bg: #eef3ff;
    --info-ink: #1c3994;
    --info-line: #4f7cf2;
    --warn-bg: #fff8e6;
    --warn-ink: #6e4d00;
    --warn-line: #f5c84b;

    /* Typography — system stack matching the CEO mock so weight +
       letterforms render identically on macOS (San Francisco) and
       Windows (Segoe UI). Inter remains a graceful fallback in the
       cascade. */
    --font-primary: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Inter", system-ui, sans-serif;
    --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

    /* Font sizes */
    --text-xs: 10px;
    --text-sm: 12px;
    --text-base: 14px;
    --text-md: 16px;
    --text-lg: 18px;
    --text-xl: 24px;
    --text-2xl: 30px;

    /* Font weights */
    --font-normal: 400;
    --font-medium: 500;
    --font-semibold: 600;
    --font-bold: 700;
    --font-extrabold: 800;

    /* Extra text colors — referenced by inline page styles that should
       eventually migrate (home hero used --hp-text-muted, etc.) */
    --text-muted: #9CA3AF;
    --text-disabled: #D1D5DB;

    /* Spacing — 4-multiple scale. Gaps filled to cover dashboard /home
       inline-style values (28px / 40px / 48px / 64px). */
    --space-1: 4px;
    --space-2: 8px;
    --space-3: 12px;
    --space-4: 16px;
    --space-5: 20px;
    --space-6: 24px;
    --space-7: 28px;
    --space-8: 32px;
    --space-9: 40px;
    --space-10: 48px;
    --space-12: 64px;

    /* App header — single source of truth for the sticky header height so
       page-level sticky sub-toolbars can offset off it (var, not magic
       numbers). Kept in sync with `.app-header` padding + content height. */
    --app-header-height: 57px;

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

    /* Shadows. --shadow-card is the canonical card elevation;
       --shadow-elevated lifts hero blocks. Shadow tints aligned with
       the new green/navy palette so heavy elevations don't carry a
       leftover blue cast. */
    --shadow-sm: rgba(15, 27, 58, 0.05) 0px 1px 2px 0px, rgba(15, 27, 58, 0.06) 0px 1px 3px 0px;
    --shadow-md: rgba(15, 27, 58, 0.08) 0px 4px 16px 0px;
    --shadow-card: 0 1px 3px 0 rgba(15, 27, 58, 0.06), 0 1px 2px -1px rgba(15, 27, 58, 0.05);
    --shadow-elevated: 0 8px 24px rgba(15, 27, 58, 0.14);

    /* Focus + interaction — alpha brand-green below uses color-mix on
       var(--ds-primary) so it follows the active theme (light/blue/dark);
       these were hardcoded brand-green rgba() literals (#497 §5). */
    --focus-ring: 0 0 0 3px color-mix(in srgb, var(--ds-primary) 25%, transparent);
    --transition-fast: 120ms ease;
    --transition-base: 200ms ease;
    --transition-slow: 320ms ease;

    /* Layout — outer chrome widths. Pages should reference these instead
       of hardcoding 1280 / 1200 / 800 to keep /home and /dashboard in
       step. */
    --width-narrow: 800px;
    --width-app: 1280px;
    --width-wide: 1400px;

    /* Legacy token aliases — keep absorbed style.css rules rendering
       until Task 16 cleanup. Each legacy name maps onto its modern
       equivalent so every absorbed selector resolves to a real value
       instead of falling back to `unset`. */
    --bg: var(--background);
    --card-bg: var(--surface);
    --text: var(--text-primary);
    --text-light: var(--text-secondary);
    --secondary: var(--text-secondary);
    --radius: var(--radius-lg);

    /* Intermediate font sizes used by the legacy absorbed section.
       These fill gaps in the 10/12/14/16/18/24/30px scale. Added in
       the design-token migration pass (issue #400) so rem literals
       in legacy selectors resolve through a named token and follow
       operator overrides. */
    --text-13: 13px;   /* 0.8125rem — help text, small labels, code snippets */
    --text-15: 15px;   /* 0.9375rem — slightly-larger body copy */
    --text-22: 22px;   /* 1.375rem  — logo / brand lockup heading */
    --text-28: 28px;   /* 1.75rem   — login card h2 display size */

    /* Card accent surface tints — applied as background on .card-error,
       .card-highlight, .card-ai, .card-success. Operator overrides to
       the corresponding --ds-accent-* set automatically flow through. */
    --card-error-bg:     #fff8f8;
    --card-highlight-bg: #f8faff;
    --card-ai-bg:        #f8fdf8;
    --card-success-bg:   #f8fdf8;

    /* Badge role colors — semantic fills for .badge-analyst / .badge-privileged /
       .badge-admin. These live outside the --ds-accent-* family because they map
       to UX roles rather than alert severity, but operator overrides apply. */
    --badge-success-bg:  #e8f5e9;
    --badge-success-ink: #2e7d32;
    --badge-warn-bg:     #fff3e0;
    --badge-warn-ink:    #ef6c00;
    --badge-info-bg:     #e3f2fd;
    --badge-info-ink:    #1565c0;

    /* Flash message fills — success / error / info / warning. Kept separate
       from --ds-accent-* so an operator can tune the flash palette independently
       of card accents. Names follow the existing .flash-{variant} class family. */
    --flash-success-bg:     #e8f5e9;
    --flash-success-ink:    #2e7d32;
    --flash-success-border: #c8e6c9;
    --flash-error-bg:       #ffebee;
    --flash-error-ink:      #c62828;
    --flash-error-border:   #ffcdd2;
    --flash-info-bg:        #e3f2fd;
    --flash-info-ink:       #1565c0;
    --flash-info-border:    #bbdefb;
    --flash-warn-bg:        #fff3e0;
    --flash-warn-ink:       #ef6c00;
    --flash-warn-border:    #ffe0b2;
    /* v2 flash ink shades (slightly darker than .flash-* for the v2 family). */
    --flash-success-v2-ink: #0d9668;
    --flash-error-v2-ink:   #c2410c;

    /* Code-block dark surface — the pre-highlight dark code panel used in the
       legacy Quick Start / SSH setup cards. Distinct from the page surface
       tokens (which are light) so dark-on-light and light-on-dark don't
       accidentally share the same token. */
    --code-dark-bg:     #1a1a2e;
    --code-dark-ink:    #e4e4e7;
    --code-dark-border: #2d2d44;
    /* Pure white for .code-block inside .code-block-wrapper (dark translucent
       surface) — distinct from --code-dark-ink so contrast there is maximal. */
    --code-wrapper-ink: #fff;

    /* Form placeholder — the medium-grey used in text inputs and textareas. */
    --placeholder-color: #9aa0a6;

    /* Username box — sky-blue highlight panel on the dashboard setup page.
       The copy-button family reuses the same blue so the panel reads
       as one coherent block. */
    --username-box-bg:   #f0f9ff;
    --username-box-line: #0ea5e9;
    --username-ink:      #0369a1;
    --btn-copy-bg:       #0ea5e9;
    --btn-copy-hover:    #0284c7;
    --btn-copy-success:  #22c55e;

    /* Info box — subtle surface used for hint / info panels in forms. */
    --info-box-bg:     #f8fafc;
    --info-box-border: #e2e8f0;

    /* CC setup card gradient — purple-to-indigo used by the Claude Code
       setup card. Exposed as tokens so an operator can swap the gradient
       without editing the rule directly. */
    --cc-gradient-from: #667eea;
    --cc-gradient-to:   #764ba2;

    /* Support info panel — same surface as --info-box-bg; named separately
       so the .support-info component can be themed independently. */
    --support-info-bg: var(--info-box-bg);

    /* Username preview text — slate-grey used in .username-preview label. */
    --username-preview-color: #64748b;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

body {
    font-family: var(--font-primary);
    background-color: var(--background);
    color: var(--text-primary);
    font-size: var(--text-base);
    line-height: 1.5;
    min-height: 100vh;
}

/* =====================================================
   Absorbed from the deleted app/web/static/style.css.
   Kept verbatim here so legacy classes used by login/auth
   pages, error pages, and password-setup pages keep
   rendering. Individual rules retire in the design-pass
   migration tasks; final cleanup in Task 16 removes the
   ones no template references after that sweep.
   ===================================================== */

.container {
    /* Canonical page-shell width + gutters. Pages inherit this
       directly — no per-page max-width / padding override needed.
       The 16px / 48px asymmetric vertical padding gives a tight gap
       between the sticky nav and the first hero (matches /home) and
       generous breathing room above the footer. Side gutters are
       32px so dense tables / grids align to the same vertical rules
       as the canonical `.page-header--hero`.
       Pages that genuinely need narrower line-length (setup wizards,
       single-form flows) opt in via .container--narrow; wide tables
       opt in via .container--wide. */
    max-width: var(--width-app);
    margin: 0 auto;
    padding: 16px 32px 48px;
}
/* Strip default `<main>` padding/margin when it sits inside our
   canonical `.container`. The container already owns the gutters,
   so the `<main>` element is a pure flow container. */
.container > main {
    margin: 0;
    padding: 0;
}

/* Width modifiers — opt-in alternatives to the default page shell. */
.container--narrow { max-width: var(--width-narrow); }   /* 800px — long-form reading, setup flows */
.container--wide   { max-width: var(--width-wide); }     /* 1400px — admin index lists, marketplace grids */
.container--full   { max-width: none; padding-left: var(--space-4); padding-right: var(--space-4); }

/* Index / resource-list page layout (#896 prototype) — used via
   base_index.html by My Stack, Catalog, and similar list pages. The
   header zone (title + description + actions + search + tabs) and the
   full-width band below it that carries the card grid are one unbroken
   surface, running to the foot of the page. Shared here so pages carry
   no per-page background/border styling. Structure/spacing/backgrounds
   only. */
.idx {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    /* The header zone reads as part of the page surface, not as a grey
       band above it: paint the whole shell --ds-surface so the app
       background never shows behind the title/description/actions row
       (full-width, so no grey gutters beside the centred header either). */
    background: var(--ds-surface);
}
.idx-head {
    width: 100%;
    max-width: var(--width-wide);
    margin: 0 auto;
    padding: 32px 32px 0;
}
/* The tab strip is the last row of the header; drop its bottom margin
   so the content band sits flush beneath it. */
.idx-head > :last-child { margin-bottom: 0; }
/* No divider above the band: header and body share one surface, so a
   hairline between them drew a line across the middle of a single page.
   Spacing alone separates the two zones. */
.idx-band {
    flex: 1 0 auto;
    background: var(--ds-surface);
}
.idx-band-inner {
    width: 100%;
    max-width: var(--width-wide);
    margin: 0 auto;
    padding: 28px 32px 48px;
}
/* The global `footer` rule adds a 48px top margin for breathing room on
   content pages; inside the index shell that margin opened a grey gap
   between the white band and the footer (the band's flex-grow stops at
   the margin). Zero it so the white band runs flush to the footer. The
   hairline `border-top` divider is dropped too — the white band already
   provides the visual break above the credit. */
.idx > footer {
    margin-top: 0;
    border-top: none;
    background: var(--ds-surface);
}

/* Catalog detail pages (package / table / recipe) drop the footer's
   hairline divider so the credit sits flush below the page body. Rail-
   scoped so the default topnav chrome renders byte-identically. */
html[data-ui-layout="rail"] body.detail-page footer {
    border-top: none;
}

/* ── Connect-anywhere banner component (macros/_connect_banner.html) ─────
   Reusable "same knowledge, everywhere" card. Two variants share one
   light-green, borderless surface and one CTA:
     .cbn--inline  compact row — copy + tool chips + CTA (e.g. /ask).
     .cbn--orbit   illustration-led — the Agnes orb as a hub with orbiting
                   tool satellites, then copy + CTA (e.g. /stack).
   Colours ride the --ds-* tokens; no raw hex, no per-page banner CSS. */
.cbn {
    background: var(--ds-agnes-soft);
    border: none;
    border-radius: 16px;
    text-align: left;
}
/* --ds-agnes-soft is a LIGHT-ONLY tint (it has no dark-theme override), so
   under `data-theme="dark"` the banner kept its near-white #ecfdf5 fill while
   --ds-text-primary flipped to near-white too — the title landed at ~1:1
   contrast and disappeared. Tint the current surface with the Agnes green
   instead, the same idiom `.ag-pv-bubble` (agents.html) already uses for this
   exact reason, so the fill follows the theme and the text tokens stay legible
   on it. Dark-scoped: the light + paper themes keep the flat -soft fill.
   `.cbn--bar` opts out — it paints the Knowledge Layer hero's gradient (see
   the shared fill rule below), which already follows --ds-surface. */
:root[data-theme="dark"] .cbn:not(.cbn--bar) {
    background: color-mix(in srgb, var(--ds-agnes) 18%, var(--ds-surface));
}
.cbn-title { color: var(--ds-text-primary); font-weight: 750; letter-spacing: -0.02em; }
.cbn-copy { color: var(--ds-text-secondary); }
.cbn-cta {
    display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0;
    background: var(--ds-primary); color: var(--ds-text-inverse);
    border: none; border-radius: var(--ds-radius-pill);
    padding: 11px 22px; font-size: 14px; font-weight: 650; letter-spacing: -0.01em;
    text-decoration: none; cursor: pointer;
    box-shadow: 0 4px 12px color-mix(in srgb, var(--ds-primary) 25%, transparent);
    transition: background 0.15s, transform 0.1s;
}
.cbn-cta:hover { background: var(--ds-primary-dark); }
.cbn-cta:active { transform: translateY(1px); }

/* Bar variant — one row: white "plugin" tile (Agnes orb) · copy · CTA right. */
.cbn--bar { display: flex; align-items: center; gap: 18px; padding: 16px 20px; }
.cbn-bar-icon {
    flex-shrink: 0; width: 52px; height: 52px; border-radius: 14px;
    background: var(--ds-surface); border: 1px solid var(--ds-border-light);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--ds-text-primary) 7%, transparent);
    display: grid; place-items: center;
}
.cbn-bar-orb { width: 30px; height: 30px; display: block; }
.cbn-bar-text { flex: 1 1 auto; min-width: 0; }
.cbn--bar .cbn-title { font-size: 17px; line-height: 1.18; margin: 0 0 3px; }
.cbn--bar .cbn-copy { margin: 0; font-size: 13px; line-height: 1.45; }
.cbn--bar .cbn-cta { flex-shrink: 0; }
@media (max-width: 620px) {
    .cbn--bar { flex-wrap: wrap; }
    .cbn--bar .cbn-bar-text { flex-basis: 100%; order: 2; }
    .cbn--bar .cbn-cta { order: 3; }
}

/* Shared tool chip */
.cbn-tool {
    display: grid; place-items: center;
    background: var(--ds-surface); border: 1px solid var(--ds-agnes-line);
    box-shadow: 0 1px 3px color-mix(in srgb, var(--ds-text-primary) 6%, transparent);
}
.cbn-tool img { object-fit: contain; display: block; }

/* Inline variant */
.cbn--inline { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; padding: 15px 18px; }
.cbn--inline .cbn-lead { display: flex; flex-direction: column; gap: 3px; flex: 1; min-width: 220px; }
.cbn--inline .cbn-title { font-size: 14.5px; }
.cbn--inline .cbn-copy { margin: 0; font-size: 12.5px; line-height: 1.45; }
.cbn--inline .cbn-tools { display: flex; align-items: center; gap: 12px; }
.cbn--inline .cbn-tool { width: 38px; height: 38px; border-radius: 11px; }
.cbn--inline .cbn-tool img { width: 22px; height: 22px; }
.cbn--inline .cbn-tool svg { width: 20px; height: 20px; color: var(--ds-text-secondary); }

/* Orbit variant */
.cbn--orbit { display: flex; align-items: center; gap: 26px; flex-wrap: wrap; padding: 18px 26px; }
.cbn--orbit .cbn-body { flex: 1 1 300px; min-width: 240px; }
.cbn--orbit .cbn-title { font-size: 20px; line-height: 1.14; margin: 0 0 7px; }
.cbn--orbit .cbn-copy { margin: 0 0 15px; font-size: 13.5px; line-height: 1.5; max-width: 420px; }
.cbn-orbit { position: relative; width: 200px; height: 168px; flex-shrink: 0; }
.cbn-orbit .ring { position: absolute; border-radius: 50%; border: 1.5px dashed var(--ds-agnes-line); }
.cbn-orbit .r1 { width: 156px; height: 156px; left: 22px; top: 6px; opacity: 0.8; }
.cbn-orbit .r2 {
    width: 106px; height: 106px; left: 47px; top: 31px; border-style: solid; border-color: transparent;
    background: radial-gradient(circle, color-mix(in srgb, var(--ds-agnes) 10%, transparent), transparent 70%);
}
.cbn-orbit .hub {
    position: absolute; left: 68px; top: 52px; width: 64px; height: 64px; border-radius: 17px;
    background: var(--ds-surface); border: 1px solid var(--ds-agnes-line); overflow: hidden;
    display: grid; place-items: center;
    box-shadow: 0 10px 22px color-mix(in srgb, var(--ds-agnes) 22%, transparent);
}
.cbn-orbit .hub img { width: 46px; height: 46px; object-fit: contain; display: block; }
.cbn-orbit .sat {
    position: absolute; width: 36px; height: 36px; border-radius: 11px;
    background: var(--ds-surface); border: 1px solid var(--ds-agnes-line);
    display: grid; place-items: center;
    box-shadow: 0 5px 13px color-mix(in srgb, var(--ds-text-primary) 12%, transparent);
}
.cbn-orbit .sat img { width: 19px; height: 19px; object-fit: contain; display: block; }
.cbn-orbit .s1 { left: 108px; top: 1px; }
.cbn-orbit .s2 { left: 2px; top: 66px; }
.cbn-orbit .s3 { left: 52px; top: 130px; }
.cbn-orbit .dot { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: color-mix(in srgb, var(--ds-agnes) 45%, transparent); }
.cbn-orbit .d1 { left: 154px; top: 32px; }
.cbn-orbit .d2 { left: 28px; top: 126px; }
.cbn-orbit .d3 { left: 108px; top: 150px; }
@media (max-width: 720px) {
    .cbn-orbit { display: none; }
    .cbn--orbit { padding: 18px 20px; }
}

/* ── Product notice (macros/_page_notice.html) ───────────────────────────
   The quiet "still being finished" caveat that closes a page head. Tuned to
   be secondary on purpose: the treatment it replaced filled the panel with
   --ds-warn-bg, then stacked a 34px tinted icon tile, a warn-ink 15px/650
   heading and a bordered pill on top of it — four amber signals for copy
   nobody has to act on, which read as a system error rather than a note.
   Here the amber survives as ONE carrier (a 15px glyph) over a
   half-strength wash, with neutral type on top. All three themes are covered
   by the tokens: --ds-warn-* is redefined per theme (dark maps to the
   translucent accent tints), so the mixes below follow the theme instead of
   pinning a light-only pastel. */
.pnote {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin: 0 0 10px;
    padding: 10px 13px;
    background: color-mix(in srgb, var(--ds-warn-bg) 45%, var(--ds-surface));
    border: 1px solid color-mix(in srgb, var(--ds-warn-line) 50%, transparent);
    border-radius: 10px;
}
/* Optical alignment: the glyph centres on the title's x-height rather than
   its line box, so it reads as sitting ON the first line. */
.pnote-icon {
    flex-shrink: 0;
    display: grid;
    place-items: center;
    margin-top: 2px;
    /* Full-strength ink: this glyph is the ONE amber carrier, so it should be
       the most saturated thing in the panel. Measured 4.8:1 against the wash
       in the weakest theme (paper) — comfortably over the 3:1 floor for a
       graphic, and it does not need to carry meaning on its own (aria-hidden;
       the title says the same thing in words). */
    color: var(--ds-warn-ink);
}
.pnote-body { min-width: 0; }
.pnote-title {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--ds-text-primary);
}
.pnote-text {
    margin: 3px 0 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--ds-text-secondary);
    max-width: 78ch;
}
/* Flat marker, not a chip — see the macro's note on why. At 9.5px this is
   "small text" for contrast purposes however bold it is, so the amber is
   pulled toward the text colour rather than thinned with alpha: warn-ink
   alone measures only 4.8:1 on the paper theme's wash, and alpha took it to
   4.0 — under the 4.5 floor. This mix keeps the amber cast and measures
   5.9 / 8.8 / 11.5 across paper / blue / dark. */
.pnote-badge {
    flex-shrink: 0;
    font-size: 9.5px;
    font-weight: 700;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: color-mix(in srgb, var(--ds-warn-ink) 85%, var(--ds-text-primary));
}

/* ── Knowledge Layer hero (macros/_knowledge_layer.html) ─────────────────
   A single premium horizontal banner: a text lead + green CTA on the left,
   the Agnes orb as the visual anchor in the centre, and lightweight floating
   integration chips (dotted connectors fanning back to the orb) on the right.
   No inner cards, no hard borders — depth is carried by soft layered
   gradients and generous spacing. Shared component; the rail chat dashboard
   is the first consumer. All colours ride --ds-* tokens so it follows every
   palette theme. */
.klb {
    position: relative;
    overflow: hidden;
    border-radius: 24px;
    padding: 38px 46px;
}

/* Shared knowledge-surface fill — the near-white layered gradient + soft lift.
   Both banners that speak for the Knowledge Layer paint the SAME surface: the
   full hero (`.klb`, chat landing) and the compact connect bar (`.cbn--bar`,
   Library / Workspace). One rule, so the two can only differ in geometry.
   Almost-white base with a whisper of mint on the left, a very light purple on
   the right, and subtle radial blues — an expensive-SaaS gradient, no hard
   edges. Kept faint so it reads as near-white. Every layer rides --ds-surface
   or a color-mix into it, so the fill follows every palette theme (which is
   why `.cbn--bar` needs no dark-theme override of its own). */
.klb,
.cbn--bar {
    background:
        radial-gradient(60% 120% at 84% 12%, color-mix(in srgb, var(--ds-kind-agent) 7%, transparent), transparent 60%),
        radial-gradient(58% 120% at 6% 92%, color-mix(in srgb, var(--ds-primary) 9%, transparent), transparent 60%),
        radial-gradient(90% 140% at 50% -20%, color-mix(in srgb, var(--ds-assistant) 6%, transparent), transparent 62%),
        linear-gradient(108deg,
            color-mix(in srgb, var(--ds-agnes) 5%, var(--ds-surface)) 0%,
            var(--ds-surface) 48%,
            color-mix(in srgb, var(--ds-kind-agent) 5%, var(--ds-surface)) 100%);
    /* Depth through light, not a heavy card: a whisper of a shadow + a soft
       coloured lift. */
    box-shadow:
        0 1px 2px color-mix(in srgb, var(--ds-text-primary) 4%, transparent),
        0 22px 52px -42px color-mix(in srgb, var(--ds-primary) 34%, transparent);
}

/* Decorative layers — dotted field fading in from the far left, thin curved
   lines in the top-right corner. */
.klb-decor { position: absolute; inset: 0; pointer-events: none; }
.klb-decor-dots {
    position: absolute; left: 0; top: 0; bottom: 0; width: 260px;
    background-image: radial-gradient(color-mix(in srgb, var(--ds-primary) 30%, transparent) 1.3px, transparent 1.4px);
    background-size: 17px 17px;
    -webkit-mask-image: linear-gradient(90deg, rgba(0, 0, 0, .55), transparent 76%);
    mask-image: linear-gradient(90deg, rgba(0, 0, 0, .55), transparent 76%);
    opacity: .55;
}
.klb-decor-curves {
    position: absolute; top: -10px; right: -10px; width: 320px; height: 220px;
    color: color-mix(in srgb, var(--ds-kind-agent) 22%, transparent);
    opacity: .6;
}

/* Composition — text lead | centred orb | floating chips. */
.klb-inner {
    position: relative; z-index: 1;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 185px);
    align-items: center;
    gap: 26px;
}

/* LEFT — text lead. */
.klb-lead { max-width: 460px; min-width: 0; }
.klb-pill {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 5px 12px;
    border-radius: var(--ds-radius-pill, 999px);
    background: color-mix(in srgb, var(--ds-assistant) 12%, var(--ds-surface));
    color: var(--ds-assistant-dark);
    font-size: 12.5px; font-weight: 650; letter-spacing: -0.005em;
}
.klb-pill svg { width: 15px; height: 15px; }
.klb-headline {
    margin: 14px 0 0;
    font-size: clamp(22.5px, 2vw, 30px);
    line-height: 1.05;
    font-weight: 760;
    letter-spacing: -0.032em;
    color: var(--ds-text-primary);
}
/* Second line — blue → purple accent gradient. */
.klb-headline-grad {
    background: linear-gradient(96deg, var(--ds-assistant) 6%, var(--ds-kind-agent) 94%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}
.klb-sub {
    /* 12px → 10px, and .klb-cta's lead 20px → 14px: the two together buy back
       exactly the 30px the onboarding link under the CTA costs, so the lead
       column stays shorter than the chips column and the hero's height is
       unchanged (312px at 1280px wide, measured with and without the link). */
    margin: 10px 0 0;
    max-width: 460px;
    font-size: 14.5px;
    line-height: 1.5;
    color: var(--ds-text-secondary);
}
.klb-cta {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 14px;  /* see .klb-sub — the height budget for .klb-orient */
    padding: 10px 14px;
    border-radius: var(--ds-radius-pill, 999px);
    background: var(--ds-primary); color: var(--ds-text-inverse);
    font-size: 14.5px; font-weight: 650; text-decoration: none;
    box-shadow: 0 8px 20px -10px color-mix(in srgb, var(--ds-primary) 50%, transparent);
    transition: background var(--ds-motion-fast, 120ms) var(--ds-ease-standard, ease),
                transform var(--ds-motion-fast, 120ms) var(--ds-ease-standard, ease);
}
.klb-cta svg { width: 15px; height: 15px; }
.klb-cta:hover { background: var(--ds-primary-dark); }
.klb-cta:active { transform: translateY(1px); }

/* Optional onboarding link under the CTA — muted, unfilled, smaller than the
   sub-copy, so it reads as an aside the reader may take rather than a second
   action competing with "Connect your tools". Its 8px lead plus the 6px taken
   off .klb-cta and the 2px off .klb-sub is the whole 30px it costs — the lead
   column stays under the chips column's height, so the hero does not grow. */
.klb-orient {
    /* Block-level (fit-content) so it starts its own line under the inline-flex
       CTA without a wrapper element. */
    display: flex; align-items: center; gap: 6px;
    width: fit-content;
    margin-top: 8px;
    font-size: 13px; font-weight: 500;
    color: var(--ds-text-muted);
    text-decoration: none;
    transition: color var(--ds-motion-fast, 120ms) var(--ds-ease-standard, ease);
}
.klb-orient svg { width: 14px; height: 14px; flex-shrink: 0; opacity: .85; }
.klb-orient:hover { color: var(--ds-text-secondary); text-decoration: underline; }

/* CENTER — the orb, visual anchor: glow + dotted halo ring, gentle float.
   Nudged down a touch so its centre sits at the optical midpoint of the
   headline → description → CTA block (rather than the whole column, whose
   pill sits higher), keeping the composition from feeling top-heavy. */
.klb-orb { position: relative; display: grid; place-items: center; transform: translateY(22px); }
.klb-orb-glow {
    position: absolute; width: 204px; height: 204px; border-radius: 50%;
    background: radial-gradient(circle,
        color-mix(in srgb, var(--ds-primary) 16%, transparent),
        color-mix(in srgb, var(--ds-kind-agent) 10%, transparent) 42%,
        transparent 68%);
    filter: blur(6px);
}
.klb-orb-ring {
    position: relative;
    width: 176px; height: 176px; border-radius: 50%;
    border: 1.5px dashed color-mix(in srgb, var(--ds-primary) 22%, transparent);
    display: grid; place-items: center;
    background: radial-gradient(circle, color-mix(in srgb, var(--ds-surface) 55%, transparent), transparent 70%);
}
.klb-orb-img {
    display: block;
    filter: drop-shadow(0 14px 30px color-mix(in srgb, var(--ds-primary) 28%, transparent));
    animation: klb-orb-float 4s ease-in-out infinite;
    will-change: transform;
}
@keyframes klb-orb-float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-8px); }
}
@media (prefers-reduced-motion: reduce) {
    .klb-orb-img { animation: none; }
}

/* RIGHT — floating chips + dotted connectors. */
.klb-integrations {
    position: relative;
    display: flex; flex-direction: column; gap: 14px;
    align-items: stretch;
}
.klb-connectors {
    position: absolute; top: 0; bottom: 0; right: calc(100% + 2px);
    width: clamp(30px, 3.4vw, 52px); height: 100%;
    overflow: visible; pointer-events: none;
}
.klb-connectors path {
    fill: none;
    stroke: color-mix(in srgb, var(--ds-primary) 18%, transparent);
    stroke-width: 1;
    stroke-linecap: round;
    stroke-dasharray: 1.4 5;
    vector-effect: non-scaling-stroke;
}
.klb-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; align-items: flex-end; }
.klb-chip {
    display: inline-flex; align-items: center; gap: 11px;
    padding: 10px 18px 10px 11px;
    border-radius: var(--ds-radius-pill, 999px);
    background: var(--ds-surface);
    box-shadow:
        0 0 0 1px color-mix(in srgb, var(--ds-border) 70%, transparent),
        0 6px 18px -8px color-mix(in srgb, var(--ds-text-primary) 22%, transparent);
    font-size: 14.5px; font-weight: 600; color: var(--ds-text-primary);
    white-space: nowrap;
}
.klb-chip-logo {
    flex-shrink: 0; width: 30px; height: 30px; border-radius: 9px;
    display: grid; place-items: center;
    background: color-mix(in srgb, var(--ds-bg-dim, var(--ds-border)) 40%, var(--ds-surface));
    color: var(--ds-text-secondary);
}
.klb-chip-logo img { width: 19px; height: 19px; object-fit: contain; display: block; }
.klb-chip-logo svg { width: 18px; height: 18px; }

/* The trust caption ("Secure. Private. Always in sync.") — rendered on its
   own beneath the hero by the rail chat dashboard. */
.klb-hub-title { margin-top: 14px; font-size: 14.5px; font-weight: 650; letter-spacing: -0.01em; color: var(--ds-text-primary); }
.klb-hub-caption {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12.5px; color: var(--ds-text-muted);
}
.klb-lock { width: 13px; height: 13px; flex-shrink: 0; }

/* Stack below tablet width: lead → orb → chips, connectors off. */
@media (max-width: 980px) {
    .klb { padding: 34px 26px; border-radius: 22px; }
    .klb-inner {
        grid-template-columns: minmax(0, 1fr);
        justify-items: center;
        text-align: center;
        gap: 28px;
    }
    .klb-lead { max-width: 540px; }
    .klb-sub { max-width: none; margin-left: auto; margin-right: auto; }
    /* Centred with the rest of the stacked lead. */
    .klb-orient { margin-left: auto; margin-right: auto; }
    .klb-decor-dots { display: none; }
    .klb-connectors { display: none; }
    .klb-chips { flex-direction: row; flex-wrap: wrap; justify-content: center; align-items: center; }
}
@media (max-width: 560px) {
    .klb { padding: 26px 18px; border-radius: 18px; }
    .klb-orb-ring { width: 176px; height: 176px; }
    .klb-orb-glow { width: 200px; height: 200px; }
}

/* Dashboard */
.dashboard h2 {
    font-size: var(--text-xl);
    font-weight: 600;
    margin-bottom: 24px;
    color: var(--text);
}

/* Header */
header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px 0;
    margin-bottom: 24px;
    border-bottom: 1px solid var(--border);
    flex-wrap: wrap;
    gap: 16px;
}

a.logo { text-decoration: none; color: inherit; display: block; }
a.logo:hover h1 { color: var(--primary); }

.logo h1 {
    font-size: var(--text-22);
    font-weight: 600;
    color: var(--text);
    margin: 0;
    letter-spacing: -0.02em;
}

.logo .subtitle {
    font-size: var(--text-13);
    color: var(--text-light);
    margin-top: 2px;
}

nav {
    display: flex;
    align-items: center;
    gap: 15px;
}

.user-info {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: var(--text-base);
    color: var(--text-light);
}

.avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
}

/* Buttons */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 20px;
    font-size: var(--text-base);
    font-weight: 500;
    text-decoration: none;
    border-radius: var(--radius);
    border: none;
    cursor: pointer;
    transition: background-color 0.2s, box-shadow 0.2s;
}

.btn-primary {
    /* Primary action buttons across the app share /home's green CTA
       fill (`--ds-primary`) so users see one consistent "do it"
       affordance everywhere. The brand-blue `--primary` stays as
       the link / accent colour elsewhere; only the filled button
       background flips to green. */
    background-color: var(--ds-primary);
    color: white;
    font-weight: 500;
    transition: all 0.15s ease;
}

.btn-primary:hover {
    background-color: var(--ds-primary-dark);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--ds-primary) 30%, transparent);
}

.btn-primary:active {
    transform: scale(0.98);
}

.btn-secondary {
    background-color: transparent;
    color: var(--secondary);
    border: 1px solid var(--border);
}

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

.btn-sm {
    padding: 6px 12px;
    font-size: var(--text-sm);
}

.btn-google {
    background-color: white;
    color: var(--text);
    border: 1px solid var(--border);
    padding: 14px 28px;
    font-size: var(--text-md);
    font-weight: 500;
    width: 100%;
    max-width: 280px;
    transition: all 0.2s ease;
}

.btn-google:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    border-color: var(--border-dark);
    background-color: var(--background);
}

.btn-google:active {
    transform: scale(0.98);
}

.google-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
}

/* Cards */
.card {
    background: var(--card-bg);
    border-radius: var(--radius);
    padding: 24px;
    margin-bottom: 20px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
    border: 1px solid var(--border);
}

.card h3 {
    font-size: var(--text-md);
    font-weight: 600;
    margin-bottom: 16px;
    color: var(--text);
    letter-spacing: -0.01em;
}

.card p {
    color: var(--text-light);
    margin-bottom: 12px;
}

.card-error {
    border-left: 4px solid var(--error);
    background-color: var(--card-error-bg);
}

.card-highlight {
    border-left: 4px solid var(--primary);
    background-color: var(--card-highlight-bg);
}

.card-ai {
    border-left: 4px solid var(--success);
    background-color: var(--card-ai-bg);
}

/* Manual setup collapsible */
.manual-setup {
    margin-top: 16px;
}

.manual-setup summary {
    cursor: pointer;
    font-size: var(--text-base);
    color: var(--text-light);
    padding: 8px 0;
}

.manual-setup summary:hover {
    color: var(--text);
}

.manual-setup .card {
    margin-top: 12px;
    margin-bottom: 0;
}

.card-error h3 {
    color: var(--error);
}

.error-message {
    color: var(--error);
    font-weight: 500;
}

/* Info grid */
.info-grid {
    display: grid;
    gap: 12px;
}

.info-item {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.info-item .label {
    font-weight: 500;
    min-width: 140px;
}

.info-item .value {
    color: var(--text-light);
}

/* Badges */
.badge {
    display: inline-block;
    padding: 2px 8px;
    font-size: var(--text-sm);
    font-weight: 500;
    border-radius: 4px;
    background-color: var(--bg);
    color: var(--text-light);
    margin-right: 4px;
}

.badge-analyst {
    background-color: var(--badge-success-bg);
    color: var(--badge-success-ink);
}

.badge-privileged {
    background-color: var(--badge-warn-bg);
    color: var(--badge-warn-ink);
}

.badge-admin {
    background-color: var(--badge-info-bg);
    color: var(--badge-info-ink);
}

/* Code blocks */
code {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    background: var(--border-light);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    padding: 1px var(--space-1);
    color: var(--text-primary);
}

/* Label qualifiers — optional, default, hint text next to form labels */
.label-qualifier,
.optional {
    font-size: var(--text-sm);
    font-weight: var(--font-normal);
    color: var(--text-secondary);
    margin-left: var(--space-1);
}

/* Radio option cards — visual selected state */
.sync-option-card:has(input:checked) {
    border-color: var(--primary) !important;
    background: var(--primary-light) !important;
}

.code-block {
    background-color: var(--code-dark-bg);
    color: var(--code-dark-ink);
    padding: 14px 16px;
    border-radius: var(--radius);
    overflow-x: auto;
    margin: 12px 0;
    border: 1px solid var(--code-dark-border);
}

.code-block code,
.code-block pre {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
    font-size: var(--text-13);
    color: inherit;
    line-height: 1.6;
}

.code-block pre {
    margin: 0;
    white-space: pre-wrap;
    word-break: break-all;
}

.code-block.code-compact {
    padding: 10px 14px;
    margin: 6px 0;
}

/* Command rows for Quick Start */
.command-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
}

.command-row .command-label {
    font-weight: 500;
    font-size: var(--text-base);
    min-width: 70px;
    color: var(--text-light);
}

.command-row .code-block {
    flex: 1;
    margin: 0;
}

/* SSH config details/summary */
.ssh-config-details {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
}

.ssh-config-details summary {
    cursor: pointer;
    font-size: var(--text-base);
    font-weight: 500;
    color: var(--primary);
    padding: 4px 0;
    user-select: none;
}

.ssh-config-details summary:hover {
    color: var(--primary-dark);
}

.ssh-config-details[open] summary {
    margin-bottom: 8px;
}

.ssh-config-details .help-text {
    margin-top: 4px;
    margin-bottom: 4px;
}

/* Forms */
.form-group {
    margin-bottom: 20px;
}

.form-group label {
    display: block;
    font-weight: 500;
    margin-bottom: 8px;
}

.form-group textarea {
    width: 100%;
    padding: 12px 14px;
    font-family: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", monospace;
    font-size: var(--text-13);
    line-height: 1.5;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    resize: vertical;
    min-height: 100px;
    background-color: var(--card-bg);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-group textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

.form-group textarea::placeholder {
    color: var(--placeholder-color);
}

.help-text {
    font-size: var(--text-13);
    color: var(--text-light);
    margin-top: 8px;
    line-height: 1.5;
}

.help-text strong {
    color: var(--text);
    font-weight: 500;
}

/* Flash messages */
.flash-messages {
    margin-bottom: 24px;
}

.flash {
    padding: 14px 18px;
    border-radius: var(--radius);
    margin-bottom: 12px;
    font-size: var(--text-base);
    font-weight: 500;
}

.flash-success {
    background-color: var(--flash-success-bg);
    color: var(--flash-success-ink);
    border: 1px solid var(--flash-success-border);
}

.flash-error {
    background-color: var(--flash-error-bg);
    color: var(--flash-error-ink);
    border: 1px solid var(--flash-error-border);
}

.flash-info {
    background-color: var(--flash-info-bg);
    color: var(--flash-info-ink);
    border: 1px solid var(--flash-info-border);
}

.flash-warning {
    background-color: var(--flash-warn-bg);
    color: var(--flash-warn-ink);
    border: 1px solid var(--flash-warn-border);
}

/* Login page */
.login-container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 60vh;
    padding: 20px;
}

.login-card {
    background: var(--card-bg);
    border-radius: 12px;
    padding: 48px 40px;
    text-align: center;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
    max-width: 640px;
    width: 100%;
    border: 1px solid var(--border);
}

/* Operator brand lockup above the Sign In heading. The card has a light
   `--card-bg`, so a colored wordmark SVG (the typical operator logo) reads
   well here. Constrain height and let width scale so any aspect ratio fits;
   `svg { display: block }` drops the inline-baseline gap under the lockup. */
.login-card-logo {
    margin-bottom: 24px;
    display: flex;
    justify-content: center;
}

.login-card-logo svg,
.login-card-logo img {
    display: block;
    height: 36px;
    width: auto;
    max-width: 100%;
}

.login-card h2 {
    margin-bottom: 12px;
    font-size: var(--text-28);
    font-weight: 600;
    color: var(--text);
}

.login-description {
    color: var(--text-light);
    margin-bottom: 32px;
    font-size: var(--text-md);
    line-height: 1.5;
}

.login-steps {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--border);
    text-align: left;
}

.login-steps .step {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: var(--text-base);
    color: var(--text-light);
    padding: 6px 0;
}

.login-steps .step-num,
.steps-horizontal .step-num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    background-color: var(--primary);
    color: white;
    border-radius: 50%;
    font-size: var(--text-sm);
    font-weight: 600;
    flex-shrink: 0;
}

/* Inline steps for compact layout */
.steps-inline {
    display: flex;
    gap: 20px;
    flex-wrap: wrap;
    margin-bottom: 16px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--border);
}

.steps-inline .step-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-13);
    color: var(--text-light);
}

/* Form row for inline layout */
.form-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.form-group-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 0;
}

.form-group-inline label {
    margin-bottom: 0;
}

/* AI hint inline */
.ai-hint {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid var(--border);
    font-size: var(--text-13);
    color: var(--text-light);
}

.ai-hint code {
    display: inline;
    font-size: var(--text-sm);
    color: var(--primary);
}

/* Manual setup compact */
.manual-content {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 12px 0;
}

.manual-content code {
    font-size: var(--text-sm);
}

.manual-content .help-text {
    margin: 0;
    font-size: var(--text-sm);
}

.login-note {
    font-size: var(--text-13);
    color: var(--text-light);
    margin-top: 12px;
}

/* Error page */
.error-container {
    display: flex;
    justify-content: center;
    align-items: center;
    min-height: 60vh;
}

.error-card {
    text-align: center;
}

.error-card h2 {
    font-size: 3rem;
    margin-bottom: 16px;
}

.error-card p {
    color: var(--text-light);
    margin-bottom: 24px;
}

/* Footer */
footer {
    margin-top: 48px;
    padding-top: 20px;
    padding-bottom: 8px;
    border-top: 1px solid var(--border);
    text-align: center;
    color: var(--text-light);
    font-size: var(--text-13);
}

/* Username box and copy buttons */
.username-box {
    background: var(--username-box-bg);
    border: 2px solid var(--username-box-line);
    border-radius: 8px;
    padding: 16px;
    margin: 16px 0;
}

.username-display {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-top: 8px;
}

.username-display code {
    font-size: 20px;
    font-weight: bold;
    color: var(--username-ink);
    background: white;
    padding: 8px 16px;
    border-radius: 6px;
    flex-grow: 1;
}

.btn-copy {
    background: var(--btn-copy-bg);
    color: white;
    border: none;
    padding: 8px 16px;
    border-radius: 6px;
    cursor: pointer;
    font-size: var(--text-base);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    transition: all 0.2s ease;
}

.btn-copy:hover {
    background: var(--btn-copy-hover);
}

.btn-copy:active {
    transform: scale(0.98);
}

.btn-copy.copied {
    background: var(--btn-copy-success);
}

.btn-copy-inline {
    background: var(--btn-copy-bg);
    color: white;
    border: none;
    padding: 4px 10px;
    border-radius: 4px;
    cursor: pointer;
    font-size: var(--text-sm);
    margin-left: 8px;
    transition: background 0.15s ease;
}

.btn-copy-inline:hover {
    background: var(--btn-copy-hover);
}

.btn-copy-block {
    background: var(--btn-copy-bg);
    color: white;
    border: none;
    padding: 10px 24px;
    border-radius: 6px;
    cursor: pointer;
    font-size: var(--text-base);
    font-weight: 600;
    width: 100%;
    transition: all 0.2s ease;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.btn-copy-block:hover {
    background: var(--btn-copy-hover);
    box-shadow: 0 2px 8px rgba(14, 165, 233, 0.3);
}

.btn-copy-block:active {
    transform: scale(0.98);
}

.btn-copy-block.copied {
    background: var(--btn-copy-success);
}

.username-preview {
    font-size: 18px;
    color: var(--username-preview-color);
}

.info-box {
    background: var(--info-box-bg);
    border: 1px solid var(--info-box-border);
    border-radius: 6px;
    padding: 12px;
    margin-bottom: 16px;
}

.card-success {
    border-left: 4px solid var(--success);
    background-color: var(--card-success-bg);
}

.help-details {
    margin-top: 12px;
    font-size: var(--text-base);
}

.help-details summary {
    cursor: pointer;
    color: var(--primary);
    padding: 4px 0;
    font-weight: 500;
}

.help-details summary:hover {
    color: var(--primary-dark);
}

.help-details ul {
    margin-top: 8px;
    margin-left: 20px;
    color: var(--text-light);
}

.help-details li {
    margin-bottom: 4px;
}

/* Claude Code Setup Card on Dashboard */
.cc-setup-card {
    background: linear-gradient(135deg, var(--cc-gradient-from) 0%, var(--cc-gradient-to) 100%);
    color: white;
    border: none;
    margin-bottom: 24px;
}

.cc-setup-card h3 {
    color: white;
    margin-bottom: 12px;
}

.cc-setup-card .cc-instruction {
    color: rgba(255, 255, 255, 0.95);
    margin-bottom: 16px;
    font-size: var(--text-15);
    line-height: 1.6;
}

.cc-setup-card .cc-helper-text {
    color: rgba(255, 255, 255, 0.8);
    font-size: var(--text-13);
    margin-top: 12px;
    margin-bottom: 0;
}

.cc-setup-card .btn-copy-block {
    background: white;
    color: var(--cc-gradient-from);
    font-weight: 600;
    padding: 12px 24px;
    border-radius: 6px;
    border: none;
    cursor: pointer;
    font-size: var(--text-base);
    width: 100%;
    transition: all 0.2s ease;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.cc-setup-card .btn-copy-block:hover {
    background: var(--border-light);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.cc-setup-card .btn-copy-block:active {
    transform: scale(0.98);
}

.cc-setup-card .btn-copy-block.copied {
    background: var(--btn-copy-success);
    color: white;
}

/* CLI hint in setup card */
.cc-setup-card .cli-hint {
    margin-top: 16px;
    padding-top: 12px;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.cc-setup-card .cli-hint summary {
    cursor: pointer;
    color: rgba(255, 255, 255, 0.85);
    font-size: var(--text-13);
    font-weight: 500;
    padding: 4px 0;
}

.cc-setup-card .cli-hint summary:hover {
    color: white;
}

.cc-setup-card .cli-hint .cli-content {
    margin-top: 10px;
    background: rgba(255, 255, 255, 0.1);
    padding: 10px 12px;
    border-radius: 6px;
}

.cc-setup-card .cli-hint .cli-content code {
    display: block;
    background: rgba(0, 0, 0, 0.2);
    color: white;
    padding: 8px 10px;
    border-radius: 4px;
    font-size: var(--text-sm);
    margin-bottom: 6px;
}

.cc-setup-card .cli-hint .cli-desc {
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--text-sm);
}

/* Support info banner */
.support-info {
    text-align: center;
    color: var(--text-light);
    font-size: var(--text-13);
    padding: 12px 16px;
    background: var(--support-info-bg);
    border-radius: 6px;
    margin-bottom: 20px;
    border: 1px solid var(--border);
}

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

/* Auth tabs */
.auth-tabs {
    display: flex;
    gap: 0;
    margin-bottom: 24px;
    border-bottom: 2px solid var(--border);
}

.auth-tab {
    flex: 1;
    padding: 12px 16px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    font-size: var(--text-15);
    font-weight: 500;
    color: var(--text-light);
    cursor: pointer;
    transition: all 0.2s ease;
}

.auth-tab:hover {
    color: var(--text);
}

.auth-tab.active {
    color: var(--primary);
    border-bottom-color: var(--primary);
}

.auth-tab-content {
    display: none;
}

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

.tab-description {
    color: var(--text-light);
    font-size: var(--text-base);
    margin-bottom: 20px;
    text-align: center;
}

.signup-note {
    color: var(--text-light);
    font-size: var(--text-13);
    text-align: center;
    margin-top: 16px;
}

/* Login form styles */
.login-form {
    text-align: left;
    margin: 24px 0;
}

.login-form .form-group {
    margin-bottom: 16px;
}

.login-form .form-group label {
    display: block;
    font-weight: 500;
    font-size: var(--text-base);
    margin-bottom: 6px;
    color: var(--text);
}

.login-form .form-group input {
    width: 100%;
    padding: 12px 14px;
    font-size: var(--text-15);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background-color: var(--card-bg);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.login-form .form-group input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

.login-form .form-group input::placeholder {
    color: var(--placeholder-color);
}

.login-form .form-hint {
    display: block;
    font-size: var(--text-sm);
    color: var(--text-light);
    margin-top: 4px;
}

.btn-block {
    width: 100%;
}

.btn-link {
    background: transparent;
    color: var(--primary);
    border: none;
    padding: 8px 4px;
    font-size: var(--text-base);
    cursor: pointer;
    text-decoration: none;
}

.btn-link:hover {
    color: var(--primary-dark);
    text-decoration: underline;
}

/* Login page links */
.login-links {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin: 16px 0;
    flex-wrap: wrap;
}

.login-links form {
    margin: 0;
}

/* Request access form */
.request-access-form,
.reset-form {
    display: inline;
}

/* Divider */
.divider {
    display: flex;
    align-items: center;
    margin: 24px 0;
    color: var(--text-light);
    font-size: var(--text-base);
}

.divider::before,
.divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--border);
}

.divider span {
    padding: 0 16px;
}

/* Account email display */
.account-email {
    background-color: var(--bg);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: 12px 16px;
    margin-bottom: 20px;
    text-align: center;
    font-size: var(--text-15);
}

/* Responsive */
@media (max-width: 600px) {
    .container {
        padding: 15px;
    }

    header {
        flex-direction: column;
        gap: 15px;
        text-align: center;
    }

    .info-item {
        flex-direction: column;
        gap: 4px;
    }

    .info-item .label {
        min-width: auto;
    }

    .username-display {
        flex-direction: column;
        align-items: stretch;
    }

    .username-display code {
        text-align: center;
    }

    .login-links {
        flex-direction: column;
        gap: 8px;
    }
}


/* Container */
.container-v2 {
    max-width: 1400px;
    margin: 0 auto;
    padding: var(--space-6) var(--space-5);
}

/* Header */
.header-v2 {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: var(--space-4) 0;
    margin-bottom: var(--space-6);
    border-bottom: 1px solid var(--border);
}

.logo-v2 h1 {
    font-size: var(--text-lg);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    margin: 0;
}

.logo-v2 .subtitle {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: 2px;
}

.nav-v2 {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.user-info-v2 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.avatar-v2 {
    width: 32px;
    height: 32px;
    border-radius: var(--radius-full);
}

/* Buttons */
.btn-v2 {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0 var(--space-3);
    height: 36px;
    font-size: var(--text-base);
    font-weight: var(--font-medium);
    text-decoration: none;
    border-radius: var(--radius-md);
    border: none;
    cursor: pointer;
    transition: all 0.15s ease;
}

.btn-primary-v2 {
    background-color: var(--primary);
    color: white;
}

.btn-primary-v2:hover {
    background-color: var(--primary-dark);
}

.btn-secondary-v2 {
    background-color: var(--background);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

.btn-secondary-v2:hover {
    background-color: var(--border);
}

.btn-ghost-v2 {
    background-color: transparent;
    color: var(--text-secondary);
}

.btn-ghost-v2:hover {
    background-color: rgba(243, 244, 246, 0.5);
}

/* Cards */
.card-v2 {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    margin-bottom: var(--space-5);
    box-shadow: var(--shadow-sm);
}

.card-v2 h3 {
    font-size: var(--text-md);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-4);
}

.card-v2 p {
    color: var(--text-secondary);
    margin-bottom: var(--space-3);
}

/* Welcome section */
.welcome-v2 {
    margin-bottom: var(--space-6);
}

.welcome-v2 h2 {
    font-size: var(--text-xl);
    font-weight: var(--font-extrabold);
    color: var(--text-primary);
    margin-bottom: var(--space-2);
}

/* AI Setup Card - Primary CTA */
.ai-setup-card {
    background: linear-gradient(135deg, var(--primary) 0%, #0056A3 100%);
    border: none;
    color: white;
    padding: var(--space-6);
    margin-bottom: var(--space-5);
}

.ai-setup-card h3 {
    color: white;
    font-size: var(--text-lg);
    margin-bottom: var(--space-3);
}

.ai-setup-card .setup-description {
    color: rgba(255, 255, 255, 0.9);
    font-size: var(--text-base);
    line-height: 1.6;
    margin-bottom: var(--space-4);
}

.ai-setup-card .btn-copy-v2 {
    background: white;
    color: var(--primary);
    font-weight: var(--font-semibold);
    padding: var(--space-3) var(--space-6);
    height: 44px;
    width: 100%;
    border-radius: var(--radius-md);
    border: none;
    cursor: pointer;
    font-size: var(--text-base);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    transition: all 0.2s ease;
}

.ai-setup-card .btn-copy-v2:hover {
    background: var(--border-light);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.ai-setup-card .btn-copy-v2.copied {
    background: var(--success);
    color: white;
}

.ai-setup-card .helper-text {
    color: rgba(255, 255, 255, 0.9);
    font-size: var(--text-sm);
    margin-top: var(--space-3);
    margin-bottom: 0;
    line-height: 1.5;
}

/* CLI Hint */
.cli-hint-v2 {
    margin-top: var(--space-4);
    padding-top: var(--space-3);
    border-top: 1px solid rgba(255, 255, 255, 0.2);
}

.cli-hint-v2 summary {
    cursor: pointer;
    color: rgba(255, 255, 255, 0.8);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    padding: var(--space-1) 0;
    list-style: none;
}

.cli-hint-v2 summary::-webkit-details-marker {
    display: none;
}

.cli-hint-v2 summary::before {
    content: '+ ';
}

.cli-hint-v2[open] summary::before {
    content: '- ';
}

.cli-hint-v2 summary:hover {
    color: white;
}

.cli-hint-v2 .cli-content {
    margin-top: var(--space-3);
    background: rgba(0, 0, 0, 0.15);
    padding: var(--space-3);
    border-radius: var(--radius-md);
}

.cli-hint-v2 code {
    display: block;
    background: rgba(0, 0, 0, 0.2);
    color: white;
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    margin-bottom: var(--space-2);
}

.cli-hint-v2 .cli-desc {
    color: rgba(255, 255, 255, 0.7);
    font-size: var(--text-xs);
}

/* Support banner */
.support-banner {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-5);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.support-banner strong {
    color: var(--text-primary);
}

.support-banner .slack-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: var(--primary-light);
    color: var(--primary);
    padding: 2px var(--space-2);
    border-radius: var(--radius-full);
    font-weight: var(--font-medium);
}

/* Status cards */
.status-card {
    border-left: 3px solid var(--success);
}

.status-card.error {
    border-left-color: var(--error);
}

.status-card.warning {
    border-left-color: var(--warning);
}

/* Username box */
.username-box-v2 {
    background: var(--primary-light);
    border: 1px solid var(--primary);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    margin: var(--space-4) 0;
}

.username-box-v2 label {
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--text-secondary);
    display: block;
    margin-bottom: var(--space-2);
}

.username-display-v2 {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.username-display-v2 code {
    font-family: var(--font-mono);
    font-size: var(--text-xl);
    font-weight: var(--font-bold);
    color: var(--primary);
    background: white;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    flex-grow: 1;
}

.username-display-v2 .btn-copy-sm {
    background: var(--primary);
    color: white;
    border: none;
    padding: var(--space-2) var(--space-4);
    border-radius: var(--radius-md);
    cursor: pointer;
    font-size: var(--text-sm);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    transition: all 0.15s ease;
}

.username-display-v2 .btn-copy-sm:hover {
    background: var(--primary-dark);
}

.username-display-v2 .btn-copy-sm.copied {
    background: var(--success);
}

/* Info grid */
.info-grid-v2 {
    display: grid;
    gap: var(--space-3);
}

.info-item-v2 {
    display: flex;
    align-items: center;
    gap: var(--space-3);
}

.info-item-v2 .label {
    font-weight: var(--font-medium);
    color: var(--text-secondary);
    min-width: 120px;
    font-size: var(--text-sm);
}

.info-item-v2 .value {
    color: var(--text-primary);
}

.info-item-v2 code {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    background: var(--background);
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
}

/* Badges */
.badge-v2 {
    display: inline-flex;
    align-items: center;
    padding: 2px var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--font-medium);
    border-radius: var(--radius-full);
    background: var(--background);
    color: var(--text-secondary);
    margin-right: var(--space-1);
}

.badge-analyst-v2 {
    background: rgba(16, 183, 127, 0.1);
    color: var(--success);
}

.badge-privileged-v2 {
    background: rgba(245, 159, 10, 0.1);
    color: var(--warning);
}

.badge-admin-v2 {
    background: color-mix(in srgb, var(--ds-primary) 10%, transparent);
    color: var(--primary);
}

/* Form */
.form-v2 {
    margin-top: var(--space-4);
}

.form-group-v2 {
    margin-bottom: var(--space-4);
}

.form-group-v2 label {
    display: block;
    font-weight: var(--font-medium);
    color: var(--text-primary);
    margin-bottom: var(--space-2);
    font-size: var(--text-sm);
}

.form-group-v2 textarea {
    width: 100%;
    padding: var(--space-3);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    line-height: 1.5;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    resize: vertical;
    min-height: 80px;
    background: var(--surface);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.form-group-v2 textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 2px var(--primary-light);
}

.form-group-v2 textarea::placeholder {
    color: var(--text-secondary);
}

.form-row-v2 {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

.form-info-v2 {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.form-info-v2 code {
    font-family: var(--font-mono);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

/* Help text */
.help-text-v2 {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: var(--space-2);
}

.help-text-v2 strong {
    color: var(--text-primary);
}

/* Info box */
.info-box-v2 {
    background: var(--background);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    margin-bottom: var(--space-4);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.info-box-v2 .username-preview {
    font-family: var(--font-mono);
    font-size: var(--text-lg);
    font-weight: var(--font-semibold);
    color: var(--primary);
}

/* Alert */
.alert-v2 {
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    padding: var(--space-4);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-4);
}

.alert-success-v2 {
    background: rgba(16, 183, 127, 0.1);
    border-left: 3px solid var(--success);
}

.alert-error-v2 {
    background: rgba(234, 88, 12, 0.1);
    border-left: 3px solid var(--error);
}

.alert-warning-v2 {
    background: rgba(245, 159, 10, 0.1);
    border-left: 3px solid var(--warning);
}

.alert-v2 .alert-icon {
    font-size: var(--text-lg);
}

.alert-v2 h4 {
    font-size: var(--text-base);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    margin-bottom: var(--space-1);
}

.alert-v2 p {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin: 0;
}

/* Flash messages */
.flash-messages-v2 {
    margin-bottom: var(--space-5);
}

.flash-v2 {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-3);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
}

.flash-success-v2 {
    background: rgba(16, 183, 127, 0.1);
    color: var(--flash-success-v2-ink);
    border: 1px solid rgba(16, 183, 127, 0.3);
}

.flash-error-v2 {
    background: rgba(234, 88, 12, 0.1);
    color: var(--flash-error-v2-ink);
    border: 1px solid rgba(234, 88, 12, 0.3);
}

.flash-info-v2 {
    background: var(--primary-light);
    color: var(--primary);
    border: 1px solid color-mix(in srgb, var(--ds-primary) 30%, transparent);
}

/* Footer */
.footer-v2 {
    margin-top: var(--space-8);
    padding-top: var(--space-5);
    border-top: 1px solid var(--border);
    text-align: center;
    color: var(--text-secondary);
    font-size: var(--text-sm);
}

/* Next step card */
.next-step-card {
    background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
    border: 1px solid var(--primary);
    border-left: 3px solid var(--primary);
}

.next-step-card h3 {
    color: var(--primary);
}

/* Data Link Card */
.data-link-card {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-4) var(--space-5);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    text-decoration: none;
    transition: all 0.15s ease;
    margin-bottom: var(--space-5);
}

.data-link-card:hover {
    border-color: var(--primary);
    box-shadow: 0 0 0 1px var(--primary);
}

.data-link-content {
    display: flex;
    align-items: center;
    gap: var(--space-4);
}

.data-link-icon {
    width: 44px;
    height: 44px;
    background: var(--primary-light);
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.data-link-text h3 {
    font-size: var(--text-md);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    margin-bottom: 2px;
}

.data-link-text p {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin: 0;
}

.data-link-stats {
    display: flex;
    gap: var(--space-4);
    padding: var(--space-3) var(--space-4);
    background: var(--background);
    border-radius: var(--radius-md);
}

.data-stat {
    text-align: center;
    padding: 0 var(--space-2);
}

.data-stat .value {
    font-size: var(--text-md);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

.data-stat .label {
    font-size: 10px;
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.3px;
}

.data-stat-divider {
    width: 1px;
    background: var(--border);
}

.data-link-arrow {
    width: 32px;
    height: 32px;
    background: var(--primary-light);
    border-radius: var(--radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--primary);
    transition: all 0.15s ease;
    flex-shrink: 0;
}

.data-link-card:hover .data-link-arrow {
    background: var(--primary);
    color: white;
    transform: translateX(2px);
}

.data-categories {
    display: flex;
    gap: var(--space-2);
    margin-top: var(--space-2);
}

.category-tag {
    font-size: var(--text-xs);
    padding: 2px 8px;
    border-radius: var(--radius-full);
    font-weight: var(--font-medium);
}

.category-tag.finance { background: rgba(16, 183, 127, 0.1); color: #0d9668; }
.category-tag.hr { background: rgba(139, 92, 246, 0.1); color: #7c3aed; }
.category-tag.sales { background: color-mix(in srgb, var(--ds-primary) 10%, transparent); color: var(--primary); }
.category-tag.telemetry { background: rgba(245, 159, 10, 0.1); color: #b45309; }
.category-tag.support { background: rgba(234, 88, 12, 0.1); color: #EA580C; }
.category-tag.revenue { background: color-mix(in srgb, var(--ds-primary) 10%, transparent); color: var(--primary); }
.category-tag.customers { background: rgba(139, 92, 246, 0.1); color: #7c3aed; }
.category-tag.marketing { background: rgba(245, 159, 10, 0.1); color: #b45309; }

.data-highlights {
    display: flex;
    gap: var(--space-4);
    margin-top: var(--space-3);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.data-highlight {
    display: flex;
    align-items: center;
    gap: 4px;
}

.data-highlight strong {
    color: var(--text-primary);
    font-weight: var(--font-semibold);
}

/* Slack badge as link */
a.slack-badge {
    text-decoration: none;
    transition: all 0.15s ease;
}

a.slack-badge:hover {
    background: var(--primary);
    color: white;
}

/* Dashboard 2-column grid */
.dashboard-grid {
    display: grid;
    grid-template-columns: 3fr 2fr;
    gap: var(--space-5);
    align-items: start;
}

.col-left {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.col-right {
    display: flex;
    flex-direction: column;
    gap: var(--space-5);
}

.full-width {
    grid-column: 1 / -1;
}

/* Remove bottom margin for cards inside grid (grid gap handles spacing) */
.dashboard-grid .card-v2 {
    margin-bottom: 0;
}

.dashboard-grid .data-link-card {
    margin-bottom: 0;
}

.dashboard-grid .support-banner {
    margin-bottom: 0;
}

.support-banner .heart {
    color: #e74c3c;
}

/* Responsive */
@media (max-width: 1024px) {
    .dashboard-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 640px) {
    .container-v2 {
        padding: var(--space-4);
    }

    .header-v2 {
        flex-direction: column;
        gap: var(--space-3);
        text-align: center;
    }

    .username-display-v2 {
        flex-direction: column;
    }

    .username-display-v2 code {
        width: 100%;
        text-align: center;
    }

    .form-row-v2 {
        flex-direction: column;
        align-items: stretch;
    }

    .info-item-v2 {
        flex-direction: column;
        align-items: flex-start;
        gap: var(--space-1);
    }

    .info-item-v2 .label {
        min-width: auto;
    }

    .dashboard-grid {
        grid-template-columns: 1fr;
    }
}

/* Setup steps styling */
.setup-steps {
    margin: 24px 0;
    display: flex;
    flex-direction: column;
    gap: 20px;
}

.step-item {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.step-header {
    display: flex;
    align-items: center;
    gap: 12px;
}

.step-number {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    background: white;
    color: var(--primary);
    border-radius: 50%;
    font-weight: 700;
    font-size: 16px;
    flex-shrink: 0;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.step-header strong {
    color: white;
    font-size: 16px;
    font-weight: 600;
}

.step-body {
    margin-left: 44px;
}

.step-body p {
    margin: 0 0 8px 0;
    color: rgba(255, 255, 255, 0.9);
    font-size: 14px;
    line-height: 1.5;
}

/* Code block styling */
.code-block-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    background: rgba(0, 0, 0, 0.2);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 6px;
    padding: 12px 48px 12px 12px;
    margin-top: 8px;
}

.code-block {
    flex: 1;
    font-family: 'Monaco', 'Menlo', 'Courier New', monospace;
    font-size: var(--text-13);
    /* Pure white (not --code-dark-ink's #e4e4e7): this .code-block sits inside
       .code-block-wrapper's dark translucent surface and needs max contrast. */
    color: var(--code-wrapper-ink);
    background: transparent;
    border: none;
    white-space: pre;
    overflow-x: auto;
}

.btn-copy-code {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(255, 255, 255, 0.15);
    border: 1px solid rgba(255, 255, 255, 0.3);
    border-radius: 4px;
    padding: 6px 8px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
}

.btn-copy-code:hover {
    background: rgba(255, 255, 255, 0.25);
    border-color: rgba(255, 255, 255, 0.4);
}

.btn-copy-code.copied {
    background: rgba(76, 175, 80, 0.3);
    border-color: rgba(76, 175, 80, 0.5);
}

.btn-copy-code svg {
    width: 16px;
    height: 16px;
}

/* Compact setup banner (existing users) */
.setup-compact {
    background: linear-gradient(135deg, var(--primary) 0%, #0056A3 100%);
    border: none;
    color: white;
    padding: var(--space-4) var(--space-5);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
}

.setup-compact h3 {
    color: white;
    margin-bottom: 0;
    font-size: var(--text-base);
}

.setup-compact p {
    color: rgba(255, 255, 255, 0.85);
    margin: 4px 0 0 0;
    font-size: var(--text-sm);
}

.setup-compact .btn-copy-v2 {
    background: white;
    color: var(--primary);
    font-weight: var(--font-semibold);
    padding: var(--space-2) var(--space-5);
    height: 40px;
    border-radius: var(--radius-md);
    border: none;
    cursor: pointer;
    font-size: var(--text-sm);
    white-space: nowrap;
    transition: all 0.15s ease;
    flex-shrink: 0;
}

.setup-compact .btn-copy-v2:hover {
    background: var(--border-light);
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.setup-compact .btn-copy-v2.copied {
    background: var(--success);
    color: white;
}

/* Unified Notifications card */
.notifications-card {
    padding: 0;
}

.notifications-card h3 {
    padding: var(--space-5) var(--space-5) 0;
    margin-bottom: var(--space-3);
}

.notif-channels {
    display: flex;
    flex-direction: column;
}

.notif-channel {
    padding: var(--space-4) var(--space-5);
    border-top: 1px solid var(--border);
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
}

.notif-channel-icon {
    width: 36px;
    height: 36px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}

.notif-channel-icon.telegram {
    background: #e3f2fd;
}

.notif-channel-icon.desktop {
    background: #f3e8ff;
}

.notif-channel-body {
    flex: 1;
    min-width: 0;
}

.notif-channel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    margin-bottom: var(--space-1);
}

.notif-channel-name {
    font-weight: var(--font-semibold);
    font-size: var(--text-base);
    color: var(--text-primary);
}

.notif-status-badge {
    font-size: var(--text-xs);
    font-weight: var(--font-medium);
    padding: 2px 8px;
    border-radius: var(--radius-full);
}

.notif-status-badge.linked {
    background: rgba(16, 183, 127, 0.1);
    color: var(--success);
}

.notif-status-badge.not-linked {
    background: var(--background);
    color: var(--text-secondary);
}

.notif-channel-desc {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-bottom: var(--space-3);
}

.notif-channel-action {
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.notif-channel-action input[type="text"] {
    width: 120px;
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    text-align: center;
}

.btn-sm-v2 {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    padding: 0 var(--space-3);
    height: 32px;
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    text-decoration: none;
    border-radius: var(--radius-md);
    border: none;
    cursor: pointer;
    transition: all 0.15s ease;
}

.btn-sm-primary {
    background-color: var(--primary);
    color: white;
}

.btn-sm-primary:hover {
    background-color: var(--primary-dark);
}

.btn-sm-secondary {
    background-color: var(--background);
    color: var(--text-primary);
    border: 1px solid var(--border);
}

.btn-sm-secondary:hover {
    background-color: var(--border);
}

.download-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--primary);
    text-decoration: none;
}

.download-link:hover {
    text-decoration: underline;
}

.notif-install-steps {
    margin: 4px 0 0;
    padding-left: 20px;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: 1.7;
}

.notif-install-steps li {
    padding-left: 4px;
}

.notif-install-steps .download-link {
    font-weight: var(--font-normal);
}

/* Beta warning styles */
.beta-warning {
    background: rgba(245, 159, 10, 0.1);
    border: 1px solid rgba(245, 159, 10, 0.3);
    border-radius: var(--radius-md);
    padding: var(--space-2) var(--space-3);
    margin-bottom: var(--space-3);
    font-size: var(--text-sm);
    color: #b45309;
}

.beta-warning strong {
    color: #92400e;
}

.beta-tag {
    display: inline-flex;
    align-items: center;
    background: rgba(245, 159, 10, 0.15);
    color: #b45309;
    font-size: var(--text-xs);
    font-weight: var(--font-medium);
    padding: 1px 6px;
    border-radius: var(--radius-full);
    margin-left: var(--space-1);
}

@media (max-width: 640px) {
    .setup-compact {
        flex-direction: column;
        align-items: stretch;
        text-align: center;
    }

    .setup-compact .btn-copy-v2 {
        width: 100%;
    }
}

/* Data Settings Card */
.settings-card {
    border-left: 3px solid var(--primary);
}

.settings-card h3 {
    margin-bottom: var(--space-3);
}

.dataset-toggles {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.dataset-toggle {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    padding: var(--space-3);
    background: var(--background);
    border-radius: var(--radius-md);
    gap: var(--space-3);
}

.dataset-toggle.disabled {
    opacity: 0.5;
    pointer-events: none;
}

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

.dataset-label {
    font-weight: var(--font-medium);
    font-size: var(--text-base);
    color: var(--text-primary);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.dataset-size {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    font-weight: var(--font-normal);
}

.dataset-desc {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: 2px;
}

/* Toggle Switch */
.toggle-switch {
    position: relative;
    width: 44px;
    height: 24px;
    flex-shrink: 0;
}

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

.toggle-slider {
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: var(--border);
    transition: 0.2s ease;
    border-radius: 24px;
}

.toggle-slider:before {
    position: absolute;
    content: "";
    height: 18px;
    width: 18px;
    left: 3px;
    bottom: 3px;
    background-color: white;
    transition: 0.2s ease;
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

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

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

.toggle-switch input:disabled + .toggle-slider {
    cursor: not-allowed;
    opacity: 0.6;
}

.settings-hint {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: var(--space-3);
    margin-bottom: 0;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
}

.settings-saving {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.settings-error {
    font-size: var(--text-sm);
    color: var(--error);
    margin-top: var(--space-2);
}

/* ========== KPI Card (Your Data Widget) ========== */
.kpi-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.kpi-header {
    background: linear-gradient(135deg, #1e3a5f 0%, #0f172a 100%);
    color: white;
    padding: var(--space-5);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.kpi-header h3 {
    font-size: var(--text-md);
    font-weight: var(--font-semibold);
    color: white;
    margin: 0;
}

.kpi-header-stats {
    display: flex;
    gap: var(--space-5);
}

.kpi-header-stat {
    text-align: center;
}

.kpi-header-stat .value {
    font-size: var(--text-xl);
    font-weight: var(--font-semibold);
}

.kpi-header-stat .label {
    font-size: var(--text-xs);
    opacity: 0.7;
    text-transform: uppercase;
}

.kpi-header-stat-secondary {
    opacity: 0.7;
}

.kpi-body {
    padding: var(--space-5);
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-4);
}

.kpi-section {
    padding: var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
}

.kpi-section-disabled {
    opacity: 0.5;
}

.kpi-section-header {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-bottom: var(--space-3);
}

.kpi-icon {
    width: 24px;
    height: 24px;
    border-radius: var(--radius-sm);
    display: flex;
    align-items: center;
    justify-content: center;
}

.kpi-icon.batch {
    background: var(--primary-light);
}

.kpi-icon.live {
    background: rgba(16, 183, 127, 0.1);
}

.kpi-icon.disabled {
    background: var(--background);
}

.kpi-section-title {
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
}

.kpi-badge {
    margin-left: auto;
    font-size: 9px;
    font-weight: var(--font-semibold);
    padding: 2px 6px;
    border-radius: var(--radius-full);
    text-transform: uppercase;
    display: flex;
    align-items: center;
    gap: 4px;
}

.kpi-badge.live {
    background: rgba(16, 183, 127, 0.1);
    color: var(--success);
}

.kpi-section-time {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin-bottom: var(--space-2);
}

.kpi-section-time.live {
    color: var(--success);
}

.kpi-section-datasets {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.kpi-footer {
    padding: var(--space-3) var(--space-5);
    background: var(--background);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.kpi-highlights {
    display: flex;
    gap: var(--space-4);
    font-size: var(--text-sm);
    color: var(--text-secondary);
}

.kpi-highlights strong {
    color: var(--text-primary);
}

.kpi-link {
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--primary);
    text-decoration: none;
    display: flex;
    align-items: center;
    gap: 4px;
    transition: all 0.15s ease;
}

.kpi-link:hover {
    text-decoration: underline;
}

/* Live dot animation */
.live-dot {
    width: 6px;
    height: 6px;
    background: var(--success);
    border-radius: 50%;
    animation: pulse 2s infinite;
    display: inline-block;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.4; }
}

/* Disabled category tag */
.category-tag.disabled {
    background: var(--background);
    color: var(--text-secondary);
}

/* Responsive KPI card */
@media (max-width: 640px) {
    .kpi-header {
        flex-direction: column;
        gap: var(--space-3);
        text-align: center;
    }

    .kpi-body {
        grid-template-columns: 1fr;
    }

    .kpi-footer {
        flex-direction: column;
        gap: var(--space-3);
        text-align: center;
    }

    .kpi-highlights {
        flex-wrap: wrap;
        justify-content: center;
    }
}

/* ========== Login Page Split Layout ========== */
.login-page {
    min-height: 100vh;
    background: var(--background);
}

.login-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 100vh;
}

/* Left side: Features */
.login-features {
    background: var(--primary);
    color: white;
    padding: var(--space-6) var(--space-8);
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Navy theme — when the instance opts in via
   `AGNES_INSTANCE_THEME=navy` / `instance.theme=navy`, the
   `<html data-theme="navy">` attribute is set by base_login.html and
   we flip the login-page hero panel from the legacy brand-blue
   `--primary` to the deep-navy gradient used by the design-system
   hero so /login matches the rest of the navy-themed app. Only
   `.login-features` carries a brand colour on the pre-login screens;
   the rest of the login chrome is theme-neutral. */
:root[data-theme="navy"] .login-features {
    background: linear-gradient(135deg, #0f1b3a 0%, #0a1430 100%);
}

.features-content {
    max-width: 480px;
}

.features-title {
    font-size: 28px;
    font-weight: var(--font-semibold);
    line-height: 1.3;
    margin-bottom: var(--space-3);
}

.features-subtitle {
    font-size: var(--text-md);
    line-height: 1.6;
    opacity: 0.9;
    margin-bottom: var(--space-4);
}

/* Feature cards */
.feature-cards {
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
}

.feature-card {
    display: flex;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-4);
    background: rgba(255, 255, 255, 0.1);
    border-radius: var(--radius-lg);
    border: 1px solid rgba(255, 255, 255, 0.15);
}

.feature-icon {
    width: 40px;
    height: 40px;
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    background: rgba(255, 255, 255, 0.15);
    color: white;
}

.feature-text h3 {
    font-size: var(--text-base);
    font-weight: var(--font-semibold);
    margin-bottom: 2px;
    color: white;
}

/* BETA chip on a feature-card heading — translucent-white chip readable
   on the brand-coloured features panel. Marks every capability that
   isn't the mature data-package core. */
.feature-text h3 .feature-beta {
    display: inline-block;
    margin-left: var(--space-2);
    padding: 1px 6px;
    font-size: 10px;
    font-weight: var(--font-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;
    vertical-align: middle;
    border-radius: var(--radius-sm);
    background: rgba(255, 255, 255, 0.2);
    color: white;
    border: 1px solid rgba(255, 255, 255, 0.35);
}

.feature-text p {
    font-size: var(--text-sm);
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.8);
    margin: 0;
}

/* "Made by Keboola" attribution lockup at the foot of the brand panel.
   Logo paths use currentColor so the wordmark renders white on the
   coloured features panel. */
.login-made-by {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    margin-top: var(--space-5);
    color: rgba(255, 255, 255, 0.8);
    font-size: var(--text-sm);
}

.login-made-by .made-by-logo {
    height: 26px;
    width: auto;
    color: white;
}

/* Right side: Login card */
.login-card-wrapper {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-6);
    background: var(--background);
}

.login-page .login-card {
    background: var(--surface);
    border-radius: var(--radius-xl);
    padding: 48px 40px;
    text-align: center;
    box-shadow: 0 4px 24px rgba(0, 0, 0, 0.08), 0 1px 2px rgba(0, 0, 0, 0.04);
    max-width: 420px;
    width: 100%;
    border: 1px solid var(--border);
}

.login-page .login-card h2 {
    margin-bottom: var(--space-2);
    font-size: var(--text-xl);
    font-weight: var(--font-semibold);
    color: var(--text-primary);
}

.login-page .login-description {
    color: var(--text-secondary);
    margin-bottom: var(--space-6);
    font-size: var(--text-base);
    line-height: 1.5;
}

.login-page .login-note {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-top: var(--space-3);
}

.login-page .login-note strong {
    color: var(--text-primary);
}

.login-page .divider {
    display: flex;
    align-items: center;
    margin: var(--space-5) 0;
    color: var(--text-secondary);
    font-size: var(--text-sm);
}

.login-page .divider::before,
.login-page .divider::after {
    content: "";
    flex: 1;
    height: 1px;
    background-color: var(--border);
}

.login-page .divider span {
    padding: 0 var(--space-4);
}

/* Google button styling */
.login-page .btn-google {
    background-color: white;
    color: var(--text-primary);
    border: 1px solid var(--border);
    padding: 14px 28px;
    font-size: var(--text-base);
    font-weight: var(--font-medium);
    width: 100%;
    max-width: 280px;
    transition: all 0.2s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    border-radius: var(--radius-md);
    text-decoration: none;
    cursor: pointer;
}

.login-page .btn-google:hover {
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
    border-color: var(--border-dark);
    background-color: var(--background);
}

.login-page .btn-google:active {
    transform: scale(0.98);
}

/* Email magic link button styling */
.login-page .btn-email {
    background-color: #4361ee;
    color: white;
    border: 1px solid #3a56d4;
    padding: 14px 28px;
    font-size: var(--text-base);
    font-weight: var(--font-medium);
    border-radius: var(--radius-md);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    transition: all 0.2s ease;
    cursor: pointer;
}

.login-page .btn-email:hover {
    background-color: #3a56d4;
    box-shadow: 0 2px 8px rgba(67, 97, 238, 0.3);
}

.login-page .btn-email:active {
    transform: scale(0.98);
}

.login-page .btn-secondary {
    background-color: transparent;
    color: var(--text-secondary);
    border: 1px solid var(--border);
    padding: 14px 28px;
    font-size: var(--text-base);
    font-weight: var(--font-medium);
    border-radius: var(--radius-md);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s ease;
    cursor: pointer;
}

.login-page .btn-secondary:hover {
    background-color: var(--background);
    border-color: var(--text-secondary);
}

/* Login-card width constraints — provider buttons + inline error banner
   sit centred at 280px max-width so they line up with the card's content
   column. Previously these widths were carried inline on each element
   (`style="max-width: 280px"`); pulled into the stylesheet so markup can
   compose `.btn .btn-primary/secondary .btn-block .login-provider-btn`
   via `ds.button(klass=...)`. */
.login-page .login-provider-btn {
    max-width: 280px;
}
.login-page .login-error {
    max-width: 280px;
    margin: 0 auto var(--space-4);
    text-align: left;
}

/* Responsive: Tablet */
@media (max-width: 1024px) {
    .login-split {
        grid-template-columns: 1fr;
    }

    .login-features {
        padding: var(--space-6);
        min-height: auto;
    }

    .features-content {
        max-width: 600px;
    }

    .features-title {
        font-size: 28px;
    }

    .features-subtitle {
        margin-bottom: var(--space-6);
    }

    .feature-cards {
        display: grid;
        grid-template-columns: 1fr 1fr;
        gap: var(--space-3);
    }

    .feature-card {
        padding: var(--space-3);
    }

    .feature-icon {
        width: 36px;
        height: 36px;
    }

    .login-card-wrapper {
        padding: var(--space-6);
    }
}

/* Responsive: Mobile */
@media (max-width: 640px) {
    .login-features {
        padding: var(--space-5);
    }

    .features-content {
        max-width: 100%;
    }

    .features-title {
        font-size: 24px;
    }

    .features-subtitle {
        font-size: var(--text-base);
        margin-bottom: var(--space-5);
    }

    .feature-cards {
        grid-template-columns: 1fr;
        gap: var(--space-3);
    }

    .feature-card {
        padding: var(--space-3);
        gap: var(--space-3);
    }

    .feature-text h3 {
        font-size: var(--text-base);
    }

    .feature-text p {
        font-size: var(--text-xs);
    }

    .login-card-wrapper {
        padding: var(--space-4);
    }

    .login-page .login-card {
        padding: var(--space-6);
    }
}

/* ========== Corporate Memory Widget (Design System - Warning Color) ========== */
.memory-widget {
    border-left: 3px solid var(--warning);
}

.memory-widget .card-header-custom {
    background: rgba(245, 159, 10, 0.08);
    padding: var(--space-4) var(--space-5);
    margin: calc(-1 * var(--space-5));
    margin-bottom: var(--space-4);
    border-bottom: 1px solid var(--border);
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.memory-icon {
    width: 28px;
    height: 28px;
    background: var(--warning);
    border-radius: var(--radius-md);
    display: flex;
    align-items: center;
    justify-content: center;
    color: white;
}

.memory-widget h3 {
    margin-bottom: 0;
    display: flex;
    align-items: center;
    gap: var(--space-2);
}

.memory-stats-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-4);
    margin-bottom: var(--space-4);
}

.memory-stat {
    text-align: center;
    padding: var(--space-4);
    background: var(--background);
    border-radius: var(--radius-lg);
}

.memory-stat .value {
    font-size: var(--text-2xl);
    font-weight: var(--font-bold);
    color: var(--text-primary);
    line-height: 1;
}

.memory-stat .label {
    font-size: var(--text-xs);
    color: var(--text-secondary);
    margin-top: var(--space-1);
}

.memory-stat.highlight {
    background: var(--warning);
}

.memory-stat.highlight .value,
.memory-stat.highlight .label {
    color: white;
}

.memory-description {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: 1.6;
    padding: var(--space-3) var(--space-4);
    background: var(--background);
    border-radius: var(--radius-md);
    border-left: 3px solid rgba(245, 159, 10, 0.3);
    margin-bottom: var(--space-4);
}

.memory-description strong {
    color: var(--text-primary);
}

.memory-description code {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    background: rgba(0, 0, 0, 0.05);
    padding: 1px 4px;
    border-radius: var(--radius-sm);
}

.memory-footer {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding-top: var(--space-3);
    border-top: 1px solid var(--border);
    margin-top: var(--space-4);
}

.sync-status {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: var(--text-sm);
    color: var(--success);
}

.memory-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: var(--space-2) var(--space-4);
    background: var(--warning);
    color: white;
    text-decoration: none;
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    border-radius: var(--radius-md);
    transition: all 0.15s ease;
}

.memory-link:hover {
    background: #d97706;
    transform: translateY(-1px);
}

/* ─── Shared modern header (used by base.html + future pages) ─── */
/* Mirrors the inline header styles in dashboard.html so all pages share chrome. */

/* Adaptive header. Narrow/medium screens: a compact two-row layout —
     Row 1 (.app-header-bar) — product name (left) + search / help / user (right).
     Row 2 (.app-header-nav) — primary navigation, left-aligned under the name.
   Wide screens (≥1200px, see media query below): everything collapses onto a
   single compact row so the header isn't unnecessarily tall.
   A subtle 1px bottom border separates the header from page content. */
/* Single horizontal band: [logo] [primary nav ····] ⟨spacer⟩ [search]
   [Admin*] [help] [user]. The nav grows to fill the middle and hands overflow
   to the "More" menu (priority-plus in app.js) so the row never wraps on
   desktop/laptop widths. `flex-wrap` is the graceful fallback for very narrow
   (mobile) viewports where even a minimal nav + the actions cluster can't
   share a line with the logo — the actions cluster wraps below rather than
   clipping. */
.app-header {
    background: var(--surface, #fff);
    border-bottom: 1px solid var(--border, #e5e7eb);
    /* Override the legacy generic `header { margin-bottom: 24px }` rule from
       style.css — the .app-header sits flush against the page container. */
    margin-bottom: 0;
    padding: var(--space-2) var(--space-8);   /* 8px 32px — compact single row */
    display: flex;
    flex-direction: row;
    /* nowrap so a tight width squeezes the nav (which then sheds items into
       "More" via priority-plus) instead of wrapping the actions cluster to a
       second row. Mobile (<640px) flips this to `wrap` for a deliberate
       two-row layout. */
    flex-wrap: nowrap;
    align-items: center;
    column-gap: var(--space-6);
    row-gap: var(--space-2);
    /* Neutralize the legacy generic `header { text-align: center }`
       (@media max-width:600px in this file) so the header never center-aligns. */
    text-align: left;
    min-height: var(--app-header-height);
    position: sticky;
    top: 0;
    z-index: 100;
}

/* Logo pinned left — never shrinks. */
.app-header-logo { flex: 0 0 auto; }

/* `.app-header-left` — kept for the `ds.primary_nav` macro (_components.html),
   the scaffolded future header that groups logo + subtitle in a left cluster.
   `_app_header.html` places the logo directly now, but the macro still wraps
   it, so this rule keeps that cluster a sane inline flex item on the single
   row. */
.app-header-left { display: inline-flex; align-items: center; gap: var(--space-3); flex: 0 0 auto; }

/* Primary nav — the flexible middle. Grows to fill, shrinks toward zero
   (handing items to "More") so the actions cluster keeps its space. */
.app-header-nav {
    display: flex;
    align-items: center;
    flex: 1 1 auto;
    gap: var(--space-1);
    /* Never let the nav grow past the header (otherwise a too-wide nav
       overflows the page instead of being measured as overflow). Combined
       with `.is-priority`'s `overflow:hidden`, this makes clientWidth track
       the available width so the priority-plus logic can detect overflow. */
    min-width: 0;
    max-width: 100%;
    flex-wrap: wrap;   /* no-JS fallback: links wrap rather than clip */
}
.app-header-nav.is-priority {
    flex-wrap: nowrap;
    overflow: hidden;
}

/* Right cluster — search + Admin + help + user. Pinned right (margin-left
   auto so it hugs the far edge even when the nav shrinks), never shrinks its
   own gaps; the search inside it does the shrinking. */
.app-header-actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex: 0 0 auto;
    margin-left: auto;
    justify-content: flex-end;
    min-width: 0;
}

.app-header-logo {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    color: inherit;
    font-weight: 600;
    font-size: 16px;
}
.app-header-logo svg {
    display: block;
    max-height: 40px;
    width: auto;
}
a.app-header-logo:focus-visible {
    outline: 2px solid var(--primary, #6366f1);
    outline-offset: 2px;
    border-radius: 4px;
}

.app-header-subtitle {
    font-size: 11px;
    font-weight: 500;
    color: var(--text-secondary, #6b7280);
    letter-spacing: 0.4px;
    text-transform: uppercase;
    margin-top: 2px;
}

.app-header-right {
    display: flex;
    align-items: center;
    gap: 16px;
    /* `.app-header` now uses `justify-content: flex-start` (was
       space-between), so the legacy `primary_nav` macro that still uses
       this class keeps its right alignment via an explicit auto margin. */
    margin-left: auto;
}

.app-header-email {
    font-size: 13px;
    color: var(--text-secondary, #6b7280);
    font-weight: 500;
}

.app-avatar {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: var(--primary-light, #eef2ff);
    color: var(--primary, #6366f1);
    font-size: 13px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
    letter-spacing: 0.3px;
}

.app-avatar-img {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 2px solid var(--border, #e5e7eb);
}

/* Top-nav entries. Both <a class="app-nav-link"> and
   <button class="app-nav-link app-nav-menu-trigger"> share this rule
   so the Admin dropdown trigger renders identical to its siblings —
   same font, color, padding, hover, active state. The button-element
   resets (background/border/font-family) flow from here, so
   .app-nav-menu-trigger no longer needs to strip <button> chrome
   separately. */
.app-nav-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 14px;
    font-weight: 500;
    font-family: inherit;
    color: var(--text-secondary);
    text-decoration: none;
    padding: 8px 14px;
    border-radius: 8px;
    border: 0;
    background: transparent;
    cursor: pointer;
    line-height: 1.2;
    /* Keep each label on one line so a tight nav row overflows horizontally
       (→ items move into the "More" menu) instead of wrapping its text. */
    white-space: nowrap;
    transition: all 0.15s ease;
}
.app-nav-link:hover {
    color: var(--primary-dark);
    background: var(--primary-light);
}
.app-nav-link.is-active,
.app-nav-link[aria-expanded="true"] {
    color: var(--primary-dark);
    background: var(--primary-light);
}
.app-nav-link:focus { outline: none; }
.app-nav-link:focus-visible {
    outline: none;
    box-shadow: var(--focus-ring);
}

/* ── Global search box — sits right of the primary nav links, before the
   Admin dropdown / user menu. Combobox input + listbox dropdown; fetch +
   debounce wiring in app/web/static/js/global_search.js. Tokens only
   (var(--ds-*)) so it themes for free in dark mode. ── */
.app-header-search {
    position: relative;
    /* Sits in the right cluster (not the flexible middle), so it takes a
       responsive fixed-ish width and shrinks — never clips — as the viewport
       narrows before the nav starts shedding items into "More". */
    flex: 0 1 clamp(180px, 22vw, 300px);
    min-width: 150px;
}
.app-header-search-input {
    width: 100%;
    height: 36px;
    padding: 0 12px;
    font-family: inherit;
    font-size: 13px;
    color: var(--ds-text-primary);
    background: var(--ds-surface-dim);
    border: 1px solid var(--ds-border);
    border-radius: 8px;
    transition: width 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.app-header-search-input::placeholder { color: var(--ds-text-muted); }
.app-header-search-input:focus {
    outline: none;
    /* Width is owned by the flexible `.app-header-search` wrapper now, so
       focus only changes the surface/border (no jarring width jump). */
    background: var(--ds-surface);
    border-color: var(--ds-primary);
}
.app-header-search-input:focus-visible {
    outline: var(--ds-focus-outline);
    outline-offset: var(--ds-focus-outline-offset);
}
.app-header-search-panel {
    position: absolute;
    top: calc(100% + 8px);
    /* Right-anchored: the search now sits on the right of the top row, so the
       results panel opens leftward and is capped to the viewport width to
       avoid overflowing off-screen on narrow widths. */
    right: 0;
    left: auto;
    width: min(360px, 92vw);
    max-height: 60vh;
    overflow-y: auto;
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: 10px;
    box-shadow: var(--ds-shadow-md);
    padding: 6px;
    z-index: 60;
}
.app-header-search-panel[hidden] { display: none; }
.app-header-search-group {
    padding: 6px 10px 4px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--ds-text-muted);
}
.app-header-search-result {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 10px;
    border-radius: 6px;
    font-size: 13px;
    color: var(--ds-text-primary);
    text-decoration: none;
}
.app-header-search-result:hover,
.app-header-search-result:focus-visible {
    background: var(--ds-border-light);
    outline: none;
}
/* Left column of a hit: the title, plus a definition line on the two types
   that have one (metric, glossary — see definitionFor() in global_search.js).
   `min-width: 0` is what lets both lines ellipsis inside a flex row. */
.app-header-search-result-main {
    display: flex;
    flex-direction: column;
    gap: 1px;
    min-width: 0;
}
.app-header-search-result-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* The definition itself — the answer to a lookup, so it is present but clearly
   subordinate to the term it defines. One line: it is a reminder of the
   meaning, not the full entry (that is what the row still links to). */
.app-header-search-result-def {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 12px;
    line-height: 1.35;
    color: var(--ds-text-secondary);
}
.app-header-search-result-badge {
    flex: none;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    color: var(--ds-text-muted);
}
.app-header-search-empty {
    padding: 12px 10px;
    font-size: 13px;
    color: var(--ds-text-muted);
}

.app-btn-logout {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-secondary, #6b7280);
    background: none;
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px;
    padding: 6px 14px;
    cursor: pointer;
    transition: all 0.15s ease;
    text-decoration: none;
    display: inline-block;
}
.app-btn-logout:hover {
    color: var(--text-primary, #111827);
    border-color: #d1d5db;
    background: var(--border-light, #f3f4f6);
}

/* ── User menu (dropdown) ── */
.app-user-menu { position: relative; display: inline-flex; align-items: center; }
.app-user-menu-trigger {
    display: inline-flex; align-items: center; gap: 6px;
    background: none; border: 1px solid transparent;
    border-radius: 999px; padding: 4px 10px 4px 4px;
    cursor: pointer; transition: all 0.15s ease;
}
.app-user-menu-trigger:hover { background: var(--border-light, #f3f4f6); border-color: var(--border, #e5e7eb); }
.app-user-menu-trigger[aria-expanded="true"] { background: var(--border-light, #f3f4f6); border-color: var(--border, #e5e7eb); }
.app-user-menu-chevron { color: var(--text-secondary, #6b7280); transition: transform 0.15s ease; }
.app-user-menu-trigger[aria-expanded="true"] .app-user-menu-chevron { transform: rotate(180deg); }
.app-user-menu-panel {
    position: absolute; top: calc(100% + 8px); right: 0;
    min-width: 240px;
    /* The Admin sections now live in here, so cap the height and scroll
       rather than run off the bottom of the viewport. */
    max-height: calc(100vh - 88px);
    overflow-y: auto;
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    padding: 6px;
    z-index: 50;
}
.app-user-menu-panel[hidden] { display: none; }
/* Admin block inside the user dropdown — the collapsible <details> groups
   reuse the .app-nav-menu-* look; this just labels the block and nudges the
   nested section headers to line up with the flat items above them. */
.app-user-menu-admin-label { padding-left: 12px; }
.app-user-menu-admin .app-nav-menu-group > summary.app-nav-menu-section { padding-left: 12px; }
.app-user-menu-admin .app-nav-menu-item { padding-left: 20px; }
.app-user-menu-header {
    padding: 10px 12px 8px;
    border-bottom: 1px solid var(--border-light, #f3f4f6);
    margin-bottom: 4px;
}
.app-user-menu-email { font-size: 13px; font-weight: 500; color: var(--text-primary, #111827); word-break: break-all; }
.app-user-menu-role { font-size: 11px; color: var(--text-secondary, #6b7280); margin-top: 2px; text-transform: uppercase; letter-spacing: 0.3px; }
.app-user-menu-item {
    display: block; padding: 8px 12px;
    font-size: 13px; color: var(--text-primary, #111827);
    text-decoration: none; border-radius: 6px;
}
.app-user-menu-item:hover { background: var(--border-light, #f3f4f6); }
.app-user-menu-item.is-active { background: var(--primary-light); color: var(--primary); font-weight: 500; }
/* Onboarding launcher — the "?" help icon in the header that re-opens the
   guided tour. Borderless icon button that sits next to the user menu. */
.app-onboarding-launch {
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px; padding: 0;
    border: 0; border-radius: 8px; background: transparent;
    color: var(--text-secondary, #6b7280); cursor: pointer;
}
.app-onboarding-launch:hover { background: var(--border-light, #f3f4f6); color: var(--text-primary, #111827); }
.app-onboarding-launch:focus-visible { outline: var(--ds-focus-outline); outline-offset: var(--ds-focus-outline-offset); }

/* ── Theme toggle — Light / Dark / System segmented control in the user menu.
   Built only from tokens that flip under [data-theme="dark"] (--surface,
   --surface-dim, --border, --text-*, --shadow-sm), so it themes itself in both
   modes with no dark-specific rules. Wiring: app.js → window.__agnesTheme. ── */
.app-user-menu-sep { height: 1px; background: var(--border-light, #f3f4f6); margin: 6px 4px; }
.app-theme-toggle { padding: 6px 8px 4px; }
.app-theme-toggle-label {
    display: block; margin-bottom: 6px;
    font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px;
    color: var(--text-secondary, #6b7280);
}
.app-theme-toggle-options {
    display: flex; gap: 3px; padding: 3px;
    background: var(--surface-dim, #f0f2f6);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px;
}
.app-theme-toggle-btn {
    flex: 1; border: 1px solid transparent; border-radius: 6px;
    padding: 5px 6px;
    font: inherit; font-size: 12px; line-height: 1.4;
    color: var(--text-secondary, #6b7280);
    background: transparent; cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.app-theme-toggle-btn:hover { color: var(--text-primary, #111827); }
.app-theme-toggle-btn.is-active {
    background: var(--surface, #fff);
    border-color: var(--border, #e5e7eb);
    color: var(--text-primary, #111827);
    font-weight: 600;
    box-shadow: var(--shadow-sm, 0 1px 2px rgba(0, 0, 0, 0.08));
}
.app-theme-toggle-btn:focus-visible { outline: 2px solid var(--ds-primary, #2ea877); outline-offset: 2px; }

/* ── Admin nav dropdown — same vocabulary as user menu, scoped under nav links ── */
.app-nav-menu { position: relative; display: inline-flex; }
/* The "More" overflow container is toggled via the `hidden` attribute by
   app.js; the class `display:inline-flex` above would otherwise defeat the
   native `[hidden]`, so restore it explicitly. */
.app-nav-more[hidden] { display: none; }
/* .app-nav-menu-trigger styling flows entirely from .app-nav-link above.
   The trigger class is kept in markup as a hook for app.js dropdown
   wiring and for targeting the chevron rotation below. */
.app-nav-menu-chevron { color: currentColor; transition: transform 0.15s ease; }
.app-nav-menu-trigger[aria-expanded="true"] .app-nav-menu-chevron { transform: rotate(180deg); }
.app-nav-menu-panel {
    position: absolute; top: calc(100% + 8px); right: 0;
    min-width: 200px;
    max-height: calc(100vh - 80px);
    overflow-y: auto;
    background: var(--surface, #fff);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
    padding: 6px;
    z-index: 50;
}
.app-nav-menu-panel[hidden] { display: none; }
.app-nav-menu-item {
    display: block; padding: 8px 12px;
    font-size: 13px; color: var(--text-primary, #111827);
    text-decoration: none; border-radius: 6px;
}
.app-nav-menu-item:hover { background: var(--border-light, #f3f4f6); }
.app-nav-menu-item.is-active { background: var(--primary-light); color: var(--primary-dark); font-weight: 500; }

/* ── Admin mega-menu — first-class, admin-only. The trigger reuses
   `.app-nav-link`; this styles its wide multi-column panel so all admin
   domains are visible at once (vs. the old one-at-a-time accordion buried in
   the user menu). Panel is right-anchored under the trigger and capped to the
   viewport so it never runs off-screen. ── */
.app-admin-menu { position: relative; display: inline-flex; }
.app-admin-menu-trigger .app-nav-menu-chevron { margin-left: 2px; }
.app-admin-menu-panel {
    /* Override the narrow single-column `.app-nav-menu-panel` width. */
    width: min(680px, 94vw);
    min-width: 0;
    max-height: calc(100vh - var(--app-header-height) - 24px);
}
.app-admin-menu-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    padding: 4px 8px 8px;
    margin-bottom: 4px;
    border-bottom: 1px solid var(--border-light, #f3f4f6);
}
.app-admin-menu-title {
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-secondary, #6b7280);
}
.app-admin-menu-hub {
    font-size: 12px;
    font-weight: 500;
    color: var(--primary-dark);
    text-decoration: none;
    padding: 2px 8px;
    border-radius: 6px;
}
.app-admin-menu-hub:hover { background: var(--primary-light); }
.app-admin-menu-hub.is-active { background: var(--primary-light); }
.app-admin-menu-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 2px var(--space-4);
}
.app-admin-menu-col { min-width: 0; }
/* Column section header — small-caps label, no background band (the columns
   already separate the groups visually). First label in a column has no top
   margin; subsequent ones (a column holding two groups) get breathing room. */
.app-admin-menu-section {
    padding: 6px 12px 2px;
    font-size: 10px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted, #9ca3af);
}
.app-admin-menu-col > .app-admin-menu-section:first-child { padding-top: 0; }
.app-admin-menu-panel .app-nav-menu-item { padding: 6px 12px; }
@media (max-width: 720px) {
    .app-admin-menu-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Primary-nav links relocated into the "More" overflow menu by app.js: render
   the pill links as full-width block rows so they read as menu items. Their
   hover / active / focus states come from `.app-nav-link` above, unchanged. */
.app-nav-more-panel .app-nav-link {
    display: flex;
    width: 100%;
    justify-content: flex-start;
    padding: 8px 12px;
    border-radius: 6px;
}
/* One-line explainer under a nav item (#755 "Sources" group — Data sources
   vs. MCP sources were visually indistinguishable, which is exactly the
   confusion the issue reported). Muted, wraps under the link label. */
.app-nav-menu-item-desc {
    display: block;
    font-size: 11px;
    font-weight: 400;
    color: var(--text-secondary, #6b7280);
    margin-top: 1px;
    white-space: normal;
}
.admin-menu-separator { margin: 4px 8px; border: 0; border-top: 1px solid var(--border, #e5e7eb); }
/* Section header inside the admin dropdown — non-clickable, small-caps,
   sitting in a light gray band so each named group (Activity Center /
   Users & Access / Data / Agent Experience / Server) reads as a
   visually contained cluster. The negative horizontal margins extend
   the band edge-to-edge inside the panel (panel has 6px padding;
   matching -6px here). Rounded top corners on the first header line
   up with the panel's own border-radius so the first band tucks
   into the top of the panel cleanly. */
.app-nav-menu-section {
    background: var(--border-light, #f3f4f6);
    margin: 8px -6px 4px;
    padding: 6px 12px;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-secondary, #6b7280);
    font-weight: 700;
}
.app-nav-menu-section:first-child {
    margin-top: -6px;
    border-radius: 10px 10px 0 0;
}
.app-nav-menu-section + .app-nav-menu-item { margin-top: 4px; }

/* <details data-section=...> group wrapper — visually identical to the
   pre-collapse render, but each section can fold up. <summary> reuses
   the .app-nav-menu-section style and gets a chevron via :before that
   rotates 90deg when [open] (no JS for the visual). */
.app-nav-menu-group { margin: 0; }
.app-nav-menu-group > summary.app-nav-menu-section {
    cursor: pointer;
    user-select: none;
    list-style: none;       /* hide native disclosure triangle (most browsers) */
    display: flex;
    align-items: center;
    gap: 6px;
}
.app-nav-menu-group > summary.app-nav-menu-section::-webkit-details-marker {
    display: none;          /* WebKit fallback */
}
.app-nav-menu-group > summary.app-nav-menu-section::before {
    content: "›";
    font-size: 12px;
    line-height: 1;
    color: var(--text-secondary, #6b7280);
    transition: transform 0.12s ease;
}
.app-nav-menu-group[open] > summary.app-nav-menu-section::before {
    transform: rotate(90deg);
}
/* First-section rounded corners stayed on the original first-child rule,
   but the wrapper <details> is now the first child — re-apply on the
   nested <summary>. */
.app-nav-menu-group:first-of-type > summary.app-nav-menu-section {
    margin-top: -6px;
    border-radius: 10px 10px 0 0;
}

/* Mobile — a single row can't hold logo + nav + the full actions cluster, so
   deliberately wrap into two rows: row 1 is logo + actions (search / Admin /
   help / user), row 2 is the primary nav full-width beneath. This is the only
   width at which the header is intentionally multi-row. */
@media (max-width: 640px) {
    .app-header {
        flex-wrap: wrap;
        padding-left: var(--space-4);
        padding-right: var(--space-4);
        column-gap: var(--space-4);
    }
    .app-header-logo { order: 1; }
    .app-header-actions { order: 2; flex: 0 0 auto; margin-left: auto; gap: var(--space-1); }
    /* The global search is dropped on mobile — there isn't room for logo +
       search + Admin + help + user on one line, and a squeezed ~40px stub is
       worse than none. Row 1 is a comfortable logo + Admin + help + user; the
       nav wraps to row 2. In-page search remains available on each surface. */
    .app-header-search { display: none; }
    .app-header-nav { order: 3; flex-basis: 100%; }
    /* initPriorityNav() adds .is-priority regardless of viewport (it only
       reacts to overflow, not screen width), which would otherwise force
       flex-wrap: nowrap here and fight the two-row mobile layout above —
       the nav needs to wrap on its own row, not overflow into "More". */
    .app-header-nav.is-priority { flex-wrap: wrap; overflow: visible; }
    .app-nav-link { padding: 6px 10px; }
}

/* ── Standard page shell ─────────────────────────────────────────────
   Shared layout container for pages that extend base.html. Matches the
   dashboard's `.main` dimensions so /dashboard, /marketplace, and the
   marketplace detail pages all align. Add `page-shell` to a page's root
   wrapper to opt in. */
/* `.page-shell` opt-in is now redundant — the canonical `.container`
   already provides the 1280px max-width + `16px 32px 48px` padding +
   stripped `<main>` defaults that this rule used to add. Kept as a
   no-op marker so existing templates that opt in continue to render
   the same as everything else. */


/* ==============================================================
   News content vocabulary (shared)
   --------------------------------------------------------------
   Used by: /news (full content), /home (perex slot via .home-news-body),
            /admin/news preview pane.

   Author classes documented in docs/operator/news-content-guide.md:
     .news-hero, .callout, .callout-{info,warn,success,danger},
     .video-embed, .news-section, .news-grid-2, .news-grid-3, .news-cta.

   Selectors are scope-free where the class itself is the marker
   (.callout, .news-hero, .video-embed, .news-grid-*, .news-cta) so
   authors can drop them anywhere — /home perex, /news body,
   /admin/news preview, future admin pages.

   The table / pre / code overrides ARE scoped to .news-content because
   `<table>` / `<pre>` / inline `<code>` exist on plenty of other pages
   that should not inherit this styling.
   ============================================================== */

/* Callouts — boxed inline notice with colored left border. */
.callout {
    border-left: 4px solid var(--primary);
    background: var(--primary-light);
    color: #111827;
    padding: 12px 16px;
    border-radius: 6px;
    margin: 12px 0;
}
.callout-info    { border-left-color: var(--primary); background: var(--primary-light); }
.callout-warn    { border-left-color: #C2410C; background: #FED7AA; }
.callout-success { border-left-color: #047857; background: #D1FAE5; }
.callout-danger  { border-left-color: #B91C1C; background: #FEE2E2; }
.callout > :first-child { margin-top: 0; }
.callout > :last-child  { margin-bottom: 0; }

/* 16:9 wrapper for YouTube/Vimeo/Loom iframes. */
.video-embed {
    position: relative;
    padding-bottom: 56.25%;
    height: 0;
    overflow: hidden;
    border-radius: 8px;
    margin: 14px 0;
    background: black;
}
.video-embed iframe,
.video-embed video,
.video-embed a {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    border: 0;
}
.video-embed a {
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
    text-decoration: underline;
}

/* Section divider — subtle top margin to separate topics. */
.news-section { margin-top: 28px; }
.news-section:first-child { margin-top: 0; }

/* 2- / 3-column responsive grids. */
.news-grid-2,
.news-grid-3 {
    display: grid;
    gap: 16px;
    margin: 12px 0;
}
.news-grid-2 { grid-template-columns: repeat(2, 1fr); }
.news-grid-3 { grid-template-columns: repeat(3, 1fr); }
@media (max-width: 720px) {
    .news-grid-2,
    .news-grid-3 { grid-template-columns: 1fr; }
}

/* Anchor styled as primary button. */
a.news-cta {
    display: inline-block;
    background: var(--primary);
    color: white !important;       /* override link colors on /home */
    text-decoration: none !important;
    padding: 9px 18px;
    border-radius: 6px;
    font-size: 14px;
    font-weight: 500;
    margin: 8px 0;
    transition: background 120ms ease;
}
a.news-cta:hover { background: #0056A3; }

/* --- .news-content scope: tables, code, pre, blockquote, headings ---
   Anything inside the long-form body needs these refinements; they
   would over-style chrome elsewhere on the site so we scope them. */

.news-content { font-size: 15px; line-height: 1.6; color: #111827; }
.news-content h1 { font-size: 24px; margin: 24px 0 12px; line-height: 1.25; }
.news-content h2 { font-size: 20px; margin: 22px 0 10px; line-height: 1.3; }
.news-content h3 { font-size: 17px; margin: 18px 0 8px; }
.news-content p  { margin: 0 0 12px; }
.news-content ul,
.news-content ol { margin: 0 0 12px 24px; }
.news-content li { margin: 4px 0; }
.news-content blockquote {
    border-left: 4px solid #E5E7EB;
    padding: 6px 16px;
    margin: 14px 0;
    color: #4B5563;
    font-style: italic;
    background: #F9FAFB;
    border-radius: 0 6px 6px 0;
}

/* Code: inline = light gray pill; block = dark navy with amber text.
   The :not(pre code) split keeps inline code from overriding the
   pre>code dark scheme — earlier versions had pre>code inheriting
   the light background from the inline rule, producing the
   "yellow-on-silver" unreadable combo. */
.news-content code {
    background: #F3F4F6;
    color: #0F172A;
    padding: 1px 6px;
    border-radius: 4px;
    font-family: var(--font-mono);
    font-size: 13px;
}
.news-content pre {
    background: #0F172A;
    color: #FBBF24;
    padding: 14px 18px;
    border-radius: 8px;
    overflow-x: auto;
    margin: 14px 0;
    line-height: 1.55;
}
.news-content pre code {
    background: transparent;
    color: inherit;
    padding: 0;
    font-size: 13px;
    border-radius: 0;
}

/* Tables: border-collapse, header band, zebra rows on hover, compact
   padding. Authors get a presentable default without writing custom
   classes; .news-grid-2 / .news-grid-3 covers the layout-grid use case. */
.news-content table {
    width: 100%;
    border-collapse: collapse;
    margin: 14px 0;
    font-size: 14px;
    background: white;
    border: 1px solid #E5E7EB;
    border-radius: 8px;
    overflow: hidden;
}
.news-content thead { background: #F9FAFB; }
.news-content th {
    text-align: left;
    padding: 10px 14px;
    font-weight: 600;
    color: #374151;
    border-bottom: 1px solid #E5E7EB;
}
.news-content td {
    padding: 10px 14px;
    border-bottom: 1px solid #F3F4F6;
    vertical-align: top;
}
.news-content tbody tr:last-child td { border-bottom: none; }
.news-content tbody tr:hover { background: #F9FAFB; }
.news-content table code {
    /* Inline code inside table cells reads better with a slightly
       lighter background than the page default. */
    background: #EEF2F7;
}

/* Reusable hero block — blue gradient, eyebrow + title + lead.
   Defined AFTER the .news-content overrides so its `color: white` on
   nested headings wins source-order ties (both selectors share
   specificity 0,1,1 since they're "one class + one type"). Authors
   drop `<section class="news-hero">` anywhere — /home perex, /news
   body, /admin/news preview. */
.news-hero {
    background: linear-gradient(135deg, var(--primary) 0%, #0056A3 100%);
    color: white;
    border-radius: 16px;
    padding: 28px 32px;
    margin: 18px 0;
    box-shadow: 0 8px 24px rgba(31, 138, 94, 0.18);
}
.news-hero .eyebrow {
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.8px;
    opacity: 0.85;
    margin-bottom: 10px;
    color: white;
}
.news-hero h1,
.news-hero h2,
.news-hero h3 {
    color: white;
    margin: 0 0 8px;
    font-weight: 600;
    line-height: 1.25;
}
.news-hero h1 { font-size: 26px; letter-spacing: -0.4px; }
.news-hero h2 { font-size: 20px; }
.news-hero h3 { font-size: 17px; }
.news-hero .lead,
.news-hero p {
    font-size: 15px;
    opacity: 0.94;
    line-height: 1.55;
    margin: 0;
    color: white;
}
.news-hero a {
    color: #FBBF24;
    text-decoration: underline;
}
.news-hero code {
    background: rgba(15, 23, 42, 0.55);
    color: #FBBF24;
    border: 1px solid rgba(255, 255, 255, 0.18);
    padding: 1px 6px;
    border-radius: 4px;
    font-size: 12.5px;
}

/* /home perex slot: the same callout / video-embed / hero classes
   work inside .home-news-body without selector duplication, since the
   rules above don't depend on a parent. The home-specific chrome
   (margin, header strip) lives in home_not_onboarded.html. */


/* ==============================================================
   Marketplace format guide page (/marketplace/format-guide).
   Renders curator-facing markdown via markdown-it-py; the rules
   below scope the document chrome to .format-guide so we don't
   override <h1>/<pre>/<table> styling on other pages. Dark <pre>
   matches the JSON snippets the guide includes.
   ============================================================== */
.container:has(.format-guide) { max-width: none; padding: 24px 16px; }
.format-guide {
    max-width: 880px;
    margin: 0 auto;
    padding: 0;
    line-height: 1.55;
}
.format-guide h1 {
    font-size: 28px; font-weight: 700;
    margin: 0 0 8px;
    color: var(--text-primary, #111827);
}
.format-guide .lead {
    font-size: 15px; color: var(--text-secondary, #6b7280);
    margin-bottom: 32px; padding-bottom: 16px;
    border-bottom: 1px solid var(--border, #e5e7eb);
}
.format-guide h2 {
    font-size: 20px; font-weight: 600;
    margin: 32px 0 12px;
    color: var(--text-primary, #111827);
}
.format-guide h3 {
    font-size: 16px; font-weight: 600;
    margin: 24px 0 8px;
    color: var(--text-primary, #111827);
}
.format-guide p {
    margin: 0 0 12px;
    color: var(--text-primary, #111827);
}
.format-guide a { color: var(--primary, #6366f1); text-decoration: none; }
.format-guide a:hover { text-decoration: underline; }
.format-guide code {
    background: var(--surface-alt, #f3f4f6);
    padding: 2px 6px; border-radius: 4px;
    font-family: var(--font-mono, ui-monospace, monospace);
    font-size: 13px;
}
.format-guide pre {
    background: #0f172a; color: #e2e8f0;
    padding: 16px; border-radius: 8px; overflow-x: auto;
    font-size: 13px;
    font-family: var(--font-mono, ui-monospace, monospace);
    line-height: 1.5;
}
.format-guide pre code { background: none; color: inherit; padding: 0; }
.format-guide table {
    width: 100%; border-collapse: collapse;
    margin: 12px 0 20px;
    font-size: 13.5px;
}
.format-guide th, .format-guide td {
    text-align: left; padding: 8px 12px;
    border-bottom: 1px solid var(--border-light, #f3f4f6);
}
.format-guide thead th {
    background: var(--surface-alt, #f9fafb);
    font-weight: 600; font-size: 12px;
    text-transform: uppercase; letter-spacing: 0.4px;
    color: var(--text-secondary, #6b7280);
}
.format-guide ul, .format-guide ol {
    margin: 0 0 12px; padding-left: 24px;
}
.format-guide li { margin-bottom: 6px; }
.format-guide blockquote {
    border-left: 3px solid var(--primary, #6366f1);
    margin: 12px 0; padding: 4px 12px;
    background: var(--surface-alt, #f9fafb);
    border-radius: 0 8px 8px 0;
}
.format-guide .back-link {
    display: inline-flex; align-items: center; gap: 4px;
    color: var(--text-secondary, #6b7280);
    font-size: 13px;
    margin-bottom: 16px;
}
.format-guide .back-link:hover { color: var(--primary, #6366f1); }

/* =====================================================
   Canonical button family (Task 4)
   .btn + .btn-primary | .btn-secondary | .btn-ghost | .btn-danger
                       + .btn-sm | .btn-lg

   Base .btn, .btn-primary, .btn-secondary, .btn-sm come from the
   absorbed style.css block above (no change needed — they already use
   the new tokens via the legacy-alias layer). This section appends
   selector-list aliases for legacy class names (   .btn-secondary-v2, .btn-ghost-v2, .modal-btn) and defines the new
   variants (.btn-ghost, .btn-danger, .btn-lg) that the legacy stylesheet
   didn't ship.

   Aliases removed in Task 16 once templates migrate to canonical names.
   Cascade-order note: this section is the LAST in the file, so it wins
   over both the absorbed legacy rules AND any earlier v2-suffixed rules
   (e.g. .btn-primary-v2 hover color in the absorbed block). Adding
   per-page <style> overrides will still beat this on equal-specificity
   selectors due to source order — Tasks 8–14 strip those.
   ===================================================== */

.btn-primary {
    background-color: var(--ds-primary);
    color: #fff;
    border: 1px solid var(--ds-primary);
    transition: all 0.15s ease;
}
.btn-primary:hover,
.btn-primary-v2:hover,
.modal-btn.primary:hover {
    background-color: var(--ds-primary-dark);
    border-color: var(--ds-primary-dark);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--ds-primary) 30%, transparent);
}

.btn-secondary {
    background-color: var(--surface);
    color: var(--text-primary);
    border: 1px solid var(--border);
}
.btn-secondary:hover,
.btn-secondary-v2:hover,
.modal-btn:not(.primary):not(.danger):hover {
    background-color: var(--border-light);
}

.btn-ghost {
    background-color: transparent;
    color: var(--text-secondary);
    border: 1px solid transparent;
}
.btn-ghost:hover,
.btn-ghost-v2:hover {
    background-color: var(--border-light);
    color: var(--text-primary);
}

/* When the ds.button macro composes variant='ghost' with klass='btn-link'
 * (the 3 auth pages — login_email, password_reset, password_setup —
 * use this combo for "Forgot Password?" / "Back to Login" affordances
 * that should look like links, not buttons), the cascade default would
 * let .btn-ghost (defined later in this file) override .btn-link's
 * blue with text-secondary grey. Boost specificity (0,0,3,0 beats the
 * single-class rules above) to keep the link color in that case.
 * Devin review on PR #375 flagged this contrast regression. */
.btn.btn-ghost.btn-link {
    color: var(--primary);
}
.btn.btn-ghost.btn-link:hover {
    color: var(--primary-dark);
    text-decoration: underline;
    background-color: transparent;
}

.btn-danger {
    background-color: #fff;
    color: var(--error);
    border: 1px solid var(--error);
}
.btn-danger:hover,
.modal-btn.danger:hover {
    background-color: var(--error);
    color: #fff;
}

/* `.btn-warning` removed — the single use in admin_marketplaces.html
   (system-confirm modal Confirm button) was destructive in spirit (fans
   out a forced grant to every principal) and now renders via .btn-danger.
   The 4 canonical variants (primary / secondary / ghost / danger) cover
   every honest CTA without inventing a 5th amber-fill axis. */

/* `.btn-required` — amber-disabled affordance for the "already in stack,
   mandated by your org" state on catalog_package_detail + memory_domain_detail.
   Always paired with the `disabled` attribute, so the base `.btn:disabled`
   rule below applies its opacity wash on top of the amber accent. Uses the
   canonical --ds-accent-warn-* vocabulary so a future warn-palette tweak
   propagates here. */
.btn-required {
    background: var(--ds-accent-warn-bg);
    color: var(--ds-accent-warn-ink);
    border: 1px solid var(--ds-accent-warn-line);
    cursor: not-allowed;
}

.btn-lg { padding: 12px 20px; font-size: var(--text-md); }

/* `.info-panel-accent` — emitted by `ds.info_panel_accent(accent='…')`.
   Canonical replacement for `.mp-curator-block`-style aside panels. The
   `--{accent}` modifier supplies the surface tokens. Four canonical
   accents reuse the `--ds-accent-{info,warn,success,danger}-*` family;
   bespoke pages can layer additional modifiers locally. */
.info-panel-accent {
    border: 1px solid var(--ds-border);
    border-left-width: 4px;
    border-radius: 8px;
    padding: 14px 18px;
    background: var(--ds-surface);
    color: var(--ds-text-primary);
}
.info-panel-accent__title {
    font-size: var(--text-md);
    font-weight: 600;
    margin: 0 0 6px;
    color: inherit;
}
.info-panel-accent__body { font-size: var(--text-sm); line-height: 1.55; }
.info-panel-accent--info {
    background: var(--ds-accent-info-bg);
    color: var(--ds-accent-info-ink);
    border-left-color: var(--ds-accent-info-line);
}
.info-panel-accent--warn {
    background: var(--ds-accent-warn-bg);
    color: var(--ds-accent-warn-ink);
    border-left-color: var(--ds-accent-warn-line);
}
.info-panel-accent--success {
    background: var(--ds-accent-success-bg);
    color: var(--ds-accent-success-ink);
    border-left-color: var(--ds-accent-success-line);
}
.info-panel-accent--danger {
    background: var(--ds-accent-danger-bg);
    color: var(--ds-accent-danger-ink);
    border-left-color: var(--ds-accent-danger-line);
}

.btn:disabled,
.btn[aria-disabled="true"] { opacity: 0.5; cursor: not-allowed; }

.btn:focus { outline: none; }
.btn:focus-visible { outline: none; box-shadow: var(--focus-ring); }

/* =====================================================
   Canonical form controls (Task 5)
   .search-input | .filter-bar | .filter-pill | .form-input

   Selector-list aliases for legacy per-page classes (   .marketplaces-search, .kb-search, .filters-card, .pill) so existing
   markup keeps rendering until migration tasks swap them out.
   ===================================================== */

.search-input,
.filter-bar input[type="search"],
.filter-bar input[type="text"],
.filter-bar select {
    height: 36px;
    padding: 0 var(--space-3);
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    color: var(--text-primary);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.search-input::placeholder,
.users-search::placeholder,
.marketplaces-search::placeholder,
.kb-search::placeholder,
.filter-bar input::placeholder { color: var(--text-muted); }

.search-input:focus,
.users-search:focus,
.marketplaces-search:focus,
.kb-search:focus,
.filter-bar input:focus,
.filter-bar select:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

.filter-bar {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
    padding: var(--space-3) var(--space-4);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    margin-bottom: var(--space-4);
}

.filter-bar > .search-input,
.filters-card > .search-input { flex: 1 1 240px; min-width: 200px; }

.filter-pill {
    display: inline-flex;
    align-items: center;
    height: 28px;
    padding: 0 var(--space-3);
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--text-secondary);
    background: transparent;
    border: 1px solid var(--border);
    border-radius: var(--radius-full);
    cursor: pointer;
    transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
    text-decoration: none;
}

.filter-pill:hover {
    background: var(--border-light);
    color: var(--text-primary);
}

.filter-pill.is-active,
.filter-pill[aria-pressed="true"] {
    background: var(--primary-light);
    color: var(--primary);
    border-color: var(--primary);
}

/* Form input — sibling of .search-input for forms (multi-line capable). */
.form-input,
input.form-input,
select.form-input,
textarea.form-input {
    width: 100%;
    min-height: 36px;
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    color: var(--text-primary);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

textarea.form-input {
    min-height: 96px;
    resize: vertical;
    font-family: var(--font-mono);
    line-height: 1.5;
}

textarea.form-textarea {
    width: 100%;
    min-height: 80px;
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    color: var(--text-primary);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-md);
    resize: vertical;
    line-height: normal;
    transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

textarea.form-textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

textarea.form-textarea::placeholder { color: var(--text-muted); }

.form-input:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: var(--focus-ring);
}

.form-input::placeholder { color: var(--text-muted); }

/* chip-input widget — set font on the container so the inner input's
   `font: inherit` inline style picks up the right value */
.chip-input {
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    color: var(--text-primary);
}

/* =====================================================
   Page-header primitive (Task 6)
   .page-header + __main / __title / __subtitle / __actions / __eyebrow
   + variants: .page-header--hero | .page-header--compact
   + .tab-strip (paired tab row for marketplace tabs etc.)
   ===================================================== */

.page-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-4);
    margin: var(--space-6) 0 var(--space-5);
    flex-wrap: wrap;
}

.page-header__main { min-width: 0; flex: 1 1 auto; }

.page-header__title {
    margin: 0;
    font-size: 22px;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    line-height: 1.2;
}

.page-header__subtitle {
    margin: var(--space-2) 0 0;
    font-size: var(--text-sm);
    color: var(--text-secondary);
    line-height: 1.4;
}

.page-header__eyebrow {
    margin: 0 0 var(--space-2);
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.8px;
    color: var(--text-secondary);
}

.page-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    flex-wrap: wrap;
}

/* Hero variant — gradient background, larger title, light eyebrow.
   Tuned to match the look of admin_tokens.html's per-page .tokens-hero
   (which analysts already liked): tighter padding, 14px radius, soft
   blue glow shadow. Applied across all primary-content pages so the
   admin section reads as one product instead of a patchwork. */
.page-header--hero {
    padding: 28px 32px 24px;
    /* Spans the parent container width. `.container` already provides
       the canonical max-width (1280px) + 32px side gutters, so the
       hero sits flush with the rest of the page content rather than
       self-constraining. Standalone pages without a `.container`
       wrapper still get a sensible width via `.container--wide` /
       `.container--narrow` modifiers on their own wrappers. */
    margin: 0 0 var(--space-5);
    box-sizing: border-box;
    /* Hero gradient — `--ds-hero-bg` / `--ds-hero-bg-deep` flip
       between themes (navy by default, blue under
       `data-theme="blue"`). Markup and class names don't change. */
    background: linear-gradient(135deg, var(--ds-hero-bg) 0%, var(--ds-hero-bg-deep) 100%);
    color: #fff;
    border-radius: 14px;
    /* Shadow tint follows the gradient via `--ds-hero-shadow`. */
    box-shadow: 0 4px 16px var(--ds-hero-shadow);
    position: relative;
    overflow: hidden;
}
.page-header--hero .page-header__main { color: inherit; }
.page-header--hero .page-header__title {
    font-size: 28px;
    font-weight: 600;
    letter-spacing: -0.01em;
    color: #fff;
    margin: 0 0 6px;
}
.page-header--hero .page-header__subtitle {
    color: rgba(255, 255, 255, 0.85);
    font-size: 13.5px;
    margin: 6px 0 0;
    max-width: 720px;
}
.page-header--hero .page-header__eyebrow {
    /* Eyebrow accent follows the theme: mint-green on navy
       (default) or translucent white on blue. `--ds-hero-eyebrow`
       is set per-theme in design-tokens.css. */
    color: var(--ds-hero-eyebrow);
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 1.2px;
    margin: 0 0 6px;
}
.page-header--hero .page-header__actions a,
.page-header--hero .page-header__actions button {
    color: #fff;
}
/* Any anchor anywhere inside the gradient hero — default `--primary`
   blue would disappear on the blue background, so force a white,
   underlined link with full contrast. Applies without needing a
   per-page class. */
.page-header--hero a {
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 2px;
}
.page-header--hero a:hover { color: rgba(255, 255, 255, 0.85); }
/* `<code>` chips inside the gradient hero — translucent white pill
   with white amber-yellow text so they read as code samples
   against the navy background. The global `code` rule sets a
   dark `color: var(--text-primary)` that turned chips into dark
   text on a faint white pill (invisible on navy). */
.page-header--hero code {
    background: rgba(255, 255, 255, 0.18);
    border: 1px solid rgba(255, 255, 255, 0.22);
    color: #ffd866;
    font-family: var(--font-mono);
    font-size: 12px;
    padding: 1px 6px;
    border-radius: 4px;
}
@media (max-width: 640px) {
    .page-header--hero { padding: 24px 20px 20px; border-radius: 12px; }
    .page-header--hero .page-header__title { font-size: 22px; }
}

/* Compact variant — for dense admin index pages that have many controls
   already and don't need vertical generosity. Smaller title, tighter
   spacing, no border. */
.page-header--compact {
    margin: var(--space-4) 0 var(--space-3);
}
.page-header--compact .page-header__title { font-size: 18px; }

/* Tab strip — the secondary row pattern used by /marketplace?tab=… and
   similar tabbed pages. Sits below the .page-header (or inside it on
   hero-variant pages). */
.tab-strip {
    display: flex;
    gap: var(--space-1);
    align-items: center;
    border-bottom: 1px solid var(--border);
    margin-bottom: var(--space-5);
}

.tab-strip__item {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    font-family: var(--font-primary);
    font-size: var(--text-sm);
    font-weight: var(--font-medium);
    color: var(--text-secondary);
    text-decoration: none;
    background: transparent;
    border: 0;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    cursor: pointer;
    transition: color var(--transition-fast), border-color var(--transition-fast);
}

.tab-strip__item:hover { color: var(--text-primary); }

.tab-strip__item.is-active,
.tab-strip__item[aria-selected="true"] {
    color: var(--primary);
    border-bottom-color: var(--primary);
}

/* =====================================================
   Data display + feedback primitives (Task 7)
   .data-table (+ --compact) | .empty-state | .toast | .stat-card

   Selector-list aliases for legacy per-page tables (   .gp-table, .marketplaces-table, .audit-table) so existing markup
   keeps rendering until migration tasks swap them out.
   ===================================================== */

.data-table,
.ad-table,
.ea-table,
.md-table,
.members-table,
.obs-table,
.overview-stats-table,
.registry-table,
.sample-table,
.sched-table,
.sess-table,
.sub-table,
.subs-table,
.ud-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    font-variant-numeric: tabular-nums;
}

.data-table thead,
.ad-table thead,
.ea-table thead,
.md-table thead,
.members-table thead,
.obs-table thead,
.overview-stats-table thead,
.registry-table thead,
.sample-table thead,
.sched-table thead,
.sess-table thead,
.sub-table thead,
.subs-table thead,
.ud-table thead {
    background: var(--border-light);
}

.data-table th,
.ad-table th,
.ea-table th,
.md-table th,
.members-table th,
.obs-table th,
.overview-stats-table th,
.registry-table th,
.sample-table th,
.sched-table th,
.sess-table th,
.sub-table th,
.subs-table th,
.ud-table th {
    padding: var(--space-3) var(--space-4);
    text-align: left;
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-secondary);
    border-bottom: 1px solid var(--border);
}

.data-table td,
.ad-table td,
.ea-table td,
.md-table td,
.members-table td,
.obs-table td,
.overview-stats-table td,
.registry-table td,
.sample-table td,
.sched-table td,
.sess-table td,
.sub-table td,
.subs-table td,
.ud-table td {
    padding: var(--space-3) var(--space-4);
    font-size: var(--text-sm);
    color: var(--text-primary);
    border-bottom: 1px solid var(--border-light);
    vertical-align: middle;
}

.data-table tbody tr:last-child td,
.ad-table tbody tr:last-child td,
.ea-table tbody tr:last-child td,
.md-table tbody tr:last-child td,
.members-table tbody tr:last-child td,
.obs-table tbody tr:last-child td,
.overview-stats-table tbody tr:last-child td,
.registry-table tbody tr:last-child td,
.sample-table tbody tr:last-child td,
.sched-table tbody tr:last-child td,
.sess-table tbody tr:last-child td,
.sub-table tbody tr:last-child td,
.subs-table tbody tr:last-child td,
.ud-table tbody tr:last-child td {
    border-bottom: none;
}

.data-table tbody tr:hover,
.ad-table tbody tr:hover,
.ea-table tbody tr:hover,
.md-table tbody tr:hover,
.members-table tbody tr:hover,
.obs-table tbody tr:hover,
.overview-stats-table tbody tr:hover,
.registry-table tbody tr:hover,
.sample-table tbody tr:hover,
.sched-table tbody tr:hover,
.sess-table tbody tr:hover,
.sub-table tbody tr:hover,
.subs-table tbody tr:hover,
.ud-table tbody tr:hover {
    background: var(--border-light);
}

/* Compact modifier — for dense lists like /admin/activity (audit log). */
.data-table--compact th,
.data-table--compact td {
    padding: var(--space-2) var(--space-3);
    font-size: var(--text-xs);
}

/* =====================================================
   .empty-state — for "no records" / "no results" panels
   ===================================================== */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-8) var(--space-6);
    text-align: center;
    background: var(--surface);
    border: 1px dashed var(--border);
    border-radius: var(--radius-lg);
    color: var(--text-secondary);
}

.empty-state__icon {
    font-size: 32px;
    opacity: 0.5;
    line-height: 1;
}

.empty-state__title {
    margin: 0;
    font-size: var(--text-md);
    font-weight: var(--font-medium);
    color: var(--text-primary);
}

.empty-state__description {
    margin: 0;
    max-width: 480px;
    font-size: var(--text-sm);
    line-height: 1.5;
}

.empty-state__actions {
    margin-top: var(--space-3);
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
    justify-content: center;
}

/* =====================================================
   .toast — global notification surface
   Paired with window.appToast({kind, msg, timeout}) in app.js
   ===================================================== */

.toast-container {
    position: fixed;
    right: var(--space-5);
    bottom: var(--space-5);
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    z-index: 9999;
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    display: flex;
    align-items: flex-start;
    gap: var(--space-3);
    min-width: 240px;
    max-width: 380px;
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    background: var(--surface);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-elevated);
    font-size: var(--text-sm);
    line-height: 1.45;
    color: var(--text-primary);
    cursor: pointer;
    animation: toast-in 200ms ease;
}

/* A receipt can be a sentence ("Loaded SKILL.md — filled in name and
   description"), so it wraps rather than clipping. */
.toast-msg { flex: 1; min-width: 0; overflow-wrap: anywhere; }

/* Dismiss. Low-contrast until hovered — present, never louder than the
   message it sits beside. */
.toast-x {
    flex-shrink: 0;
    border: none;
    background: none;
    padding: 0;
    margin: 1px 0 0;
    font: inherit;
    font-size: 13px;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
    border-radius: var(--radius-sm);
}
.toast-x:hover { color: var(--text-primary); }
.toast-x:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.toast.is-success { border-left: 3px solid var(--success); }
.toast.is-warning { border-left: 3px solid var(--warning); }
.toast.is-error   { border-left: 3px solid var(--error); }
.toast.is-info    { border-left: 3px solid var(--primary); }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .toast { animation: none; }
}

/* =====================================================
   .stat-card — for dashboard metric tiles
   ===================================================== */

.stat-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-lg);
    padding: var(--space-4);
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    min-width: 0;
}

.stat-card__label {
    font-size: var(--text-xs);
    font-weight: var(--font-semibold);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-secondary);
}

.stat-card__value {
    font-size: 28px;
    font-weight: var(--font-semibold);
    color: var(--text-primary);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
}

.stat-card__hint {
    font-size: var(--text-xs);
    color: var(--text-muted);
}

.stat-card__icon {
    font-size: 18px;
    opacity: 0.6;
}

/* Variant: with primary accent. */
.stat-card--accent {
    border-color: var(--primary);
    background: var(--primary-light);
}
.stat-card--accent .stat-card__value { color: var(--primary); }

/* Stat row container — gap-spaced grid for the dashboard tile row. */
.stat-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: var(--space-3);
    margin-bottom: var(--space-5);
}

/* ═══════════════════════════════════════════════════════════════════════
   Design-system additions driven by .interface-design/system.md
   ─────────────────────────────────────────────────────────────────────
   Net-new canonical class families consumed by the `ds.button`,
   `ds.panel`, `ds.tabs`, and `ds.table` macros in _components.html.
   Append-only; nothing above this block was modified. Order:
     1. `.btn--icon`           — icon-only square modifier
     2. `.ds-card` family      — canonical card/panel surface + accent
     3. `.ds-table` family     — canonical table + 15 legacy aliases
     4. `.badge--*` modifiers  — accent vocabulary for badges
     5. `.code-inline`         — mint inline-code chip
   ═══════════════════════════════════════════════════════════════════════ */

/* ─── Icon-only button modifier ────────────────────────────────────────
   Squares the button so an icon glyph (✕, ↡, etc.) sits centred without
   the default 10×20 padding making it rectangular. Composes with any
   .btn-* variant: `.btn .btn-ghost .btn--icon .btn-sm`. */
.btn--icon {
    width: 32px;
    height: 32px;
    padding: 0;
    flex-shrink: 0;
}
.btn--icon.btn-sm { width: 28px; height: 28px; }

/* ─── Cards — canonical .ds-card family ───────────────────────────────
   `.ds-card`            white surface, 1px border, 8px radius, 24px pad,
                         whisper shadow. The standard admin/data panel.
   `.ds-card__title`     <h3> styling inside the card.
   `.ds-card--accent`    adds a 4px solid left border in `--ds-card-accent`,
                         defaults to `--ds-border`. Pair with an accent
                         helper modifier (`--info`/`--success`/`--warn`/
                         `--danger`) for the unified status vocabulary.
   `.ds-card[data-clickable]`  opt-in hover lift (cards stay still by
                         default — calm). */
.ds-card {
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--radius-lg);
    padding: var(--space-6);
    box-shadow: var(--shadow-sm);
    margin-bottom: 0;
}
.ds-card > :first-child { margin-top: 0; }
.ds-card > :last-child  { margin-bottom: 0; }

.ds-card h2,
.ds-card h3,
.ds-card__title {
    margin: 0 0 var(--space-3);
    font-size: var(--text-md);
    font-weight: var(--font-semibold);
    color: var(--ds-text-primary);
    line-height: 1.3;
}

.ds-card p,
.ds-card__body {
    margin: 0 0 var(--space-3);
    color: var(--ds-text-secondary);
    line-height: 1.55;
}

.ds-card--accent {
    --ds-card-accent: var(--ds-border);
    border-left: 4px solid var(--ds-card-accent);
}
.ds-card--info    { --ds-card-accent: var(--ds-accent-info-line); }
.ds-card--success { --ds-card-accent: var(--ds-accent-success-line); }
.ds-card--warn    { --ds-card-accent: var(--ds-accent-warn-line); }
.ds-card--danger  { --ds-card-accent: var(--ds-accent-danger-line); }

.ds-card[data-clickable] {
    cursor: pointer;
    text-decoration: none;
    color: inherit;
    transition:
        border-color var(--transition-fast),
        box-shadow var(--transition-fast),
        transform var(--transition-fast);
}
.ds-card[data-clickable]:hover {
    border-color: var(--ds-text-muted);
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
}
.ds-card[data-clickable]:focus-visible {
    outline: var(--ds-focus-outline);
    outline-offset: var(--ds-focus-outline-offset);
}

/* ─── Tables — canonical .ds-table family ─────────────────────────────
   `.ds-table`            border-collapse, 1px row borders, 8px radius
                          on the wrapping border, sticky header,
                          `--ds-surface-dim` row hover (matches button
                          hover), tabular-nums.
   `.ds-table--dense`     reduced cell padding for reference tables.
   `.ds-table--zebra`     optional row striping for long lists.
   `td.num` / `th.num`    right-aligned monospace column.
   Legacy aliases below   so admin pages can keep their existing class
                          names while inheriting the canonical look. */
.ds-table,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--text-sm);
    background: var(--ds-surface);
    border: 1px solid var(--ds-border);
    border-radius: var(--radius-lg);
    overflow: hidden;
    font-variant-numeric: tabular-nums;
}
.ds-table thead th,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    text-align: left;
    padding: var(--space-3) var(--space-4);
    background: var(--ds-surface-dim);
    border-bottom: 1px solid var(--ds-border);
    font-weight: var(--font-semibold);
    color: var(--ds-text-muted);
    font-size: var(--text-xs);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    white-space: nowrap;
}
.ds-table tbody td,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) tbody td {
    padding: var(--space-2) var(--space-4);
    border-bottom: 1px solid var(--border-light);
    vertical-align: top;
    color: var(--ds-text-primary);
}
.ds-table tbody tr:last-child td,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) tbody tr:last-child td {
    border-bottom: none;
}
.ds-table tbody tr:hover,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) tbody tr:hover {
    background: var(--ds-surface-dim);
}
.ds-table th.num, .ds-table td.num,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) th.num,
:is(.data-table, .ad-table, .ea-table, .md-table, .members-table,
    .obs-table, .overview-stats-table, .registry-table, .sample-table,
    .sched-table, .sess-table, .sub-table, .subs-table, .ud-table,
    .versions) td.num {
    text-align: right;
    font-family: var(--ds-font-mono);
    font-variant-numeric: tabular-nums;
}

.ds-table--dense thead th,
.data-table--compact thead th { padding: var(--space-1) var(--space-3); }
.ds-table--dense tbody td,
.data-table--compact tbody td  { padding: 6px var(--space-3); }

.ds-table--zebra tbody tr:nth-child(even) td {
    background: var(--ds-surface-dim);
}

/* ─── Badges — accent vocabulary ──────────────────────────────────────
   The canonical .badge above gets neutral chrome (chip on
   `--ds-surface-dim`). These modifiers add the cross-pattern accent
   vocabulary so a "success" badge reads identically to a
   `.ds-card--success` accent and a `.flash-success`. */
.badge--info {
    background: var(--ds-accent-info-bg);
    color: var(--ds-accent-info-ink);
}
.badge--success {
    background: var(--ds-accent-success-bg);
    color: var(--ds-accent-success-ink);
}
.badge--warn {
    background: var(--ds-accent-warn-bg);
    color: var(--ds-accent-warn-ink);
}
.badge--danger {
    background: var(--ds-accent-danger-bg);
    color: var(--ds-accent-danger-ink);
}

/* ─── Inline-code chip — `.code-inline` ──────────────────────────────
   Mint chip applied to `<code>` outside of `<pre>` blocks. Replaces
   the legacy grey-blue inline-code styling. Used by `ds.code-inline`
   class callsites; bare `<code>` keeps its existing rules from
   elsewhere in this stylesheet (those are scoped to specific
   parents so they don't conflict). */
.code-inline {
    display: inline-block;
    padding: 1px 6px;
    background: var(--ds-primary-light);
    color: var(--ds-primary-dark);
    border-radius: var(--radius-sm);
    font-family: var(--ds-font-mono);
    font-size: 0.9em;
}

/* =====================================================
   /news page — page chrome
   body.news-page class added by a DOMContentLoaded
   script in news.html so these rules only apply there.
   ===================================================== */
body.news-page { background: var(--background); }
body.news-page .container { max-width: 1280px; padding: 0 var(--space-8) var(--space-10); }
body.news-page main { color: var(--text-primary); line-height: 1.6; }

body.news-page .news-card {
    margin-top: var(--space-7);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    padding: var(--space-8) var(--space-9);
}
body.news-page .news-meta {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    text-transform: uppercase;
    letter-spacing: 0.6px;
    margin-bottom: var(--space-4);
}
body.news-page .news-intro {
    font-size: var(--text-md);
    color: var(--text-secondary);
    line-height: 1.55;
    margin-bottom: 22px;
    padding-bottom: 22px;
    border-bottom: 1px solid var(--border-light);
}
body.news-page .news-intro p { margin: 0 0 8px; }
body.news-page .news-intro p:last-child { margin-bottom: 0; }

body.news-page .news-empty {
    text-align: center;
    padding: var(--space-12) var(--space-6);
    color: var(--text-secondary);
}
body.news-page .news-empty h2 {
    margin-bottom: var(--space-2);
    color: var(--text-primary);
}

/* =====================================================
   /me/profile page — read-only account view
   ===================================================== */
.container:has(.profile-page) { max-width: 1100px; }
.profile-page {
    max-width: 1100px;
    margin: 0 auto;
    padding: var(--space-7) var(--space-2) var(--space-10);
    box-sizing: border-box;
    font-family: var(--font-primary);
}
@media (max-width: 720px) {
    .profile-page { padding: 20px 0 var(--space-8); }
}
.section-card {
    border-radius: var(--radius-xl);
    padding: var(--space-5) var(--space-6);
    margin-bottom: var(--space-4);
}
.section-card h3 {
    margin: 0 0 14px;
    font-size: var(--text-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-secondary);
}
details.section-card > summary {
    font-size: var(--text-sm);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    color: var(--text-secondary);
    cursor: pointer;
}
.account-grid {
    display: grid;
    grid-template-columns: max-content 1fr;
    gap: 10px 18px;
    font-size: var(--text-base);
}
.account-grid .k {
    color: var(--text-secondary);
    font-size: var(--text-sm);
    text-transform: uppercase;
    letter-spacing: 0.4px;
    font-weight: 600;
    align-self: center;
}
.account-grid .v {
    color: var(--text-primary);
    font-weight: 500;
    word-break: break-word;
}
.groups-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.group-row {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--background);
}
.group-row .group-name {
    font-size: var(--text-base);
    font-weight: 600;
    color: var(--text-primary);
    min-width: 0;
    flex: 0 1 auto;
}
.group-row .group-id {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    color: var(--text-secondary);
    word-break: break-all;
    flex: 1 1 auto;
}
.role-chips {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1p5, 6px);
    margin: 0 0 4px;
}
.role-chip {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1p5, 6px);
    padding: 4px 10px;
    border-radius: var(--radius-full);
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    font-weight: 600;
    background: color-mix(in srgb, var(--ds-primary) 10%, transparent);
    color: var(--primary);
    border: 1px solid color-mix(in srgb, var(--ds-primary) 25%, transparent);
}
.role-chip.is-core { background: rgba(16, 185, 129, 0.10); color: #047857; border-color: rgba(16, 185, 129, 0.25); }
.grant-list, .group-roles-list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.grant-row, .group-roles-row {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 10px 14px;
    border: 1px solid var(--border);
    border-radius: 10px;
    background: var(--background);
    flex-wrap: wrap;
}
.grant-row .grant-key, .group-roles-row .group-roles-name {
    font-family: var(--font-mono);
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
}
.group-roles-row .group-roles-name { font-family: var(--font-primary); }
.grant-row .grant-source {
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: 0.4px;
    padding: 2px var(--space-2);
    border-radius: var(--radius-sm);
    background: rgba(107, 114, 128, 0.12);
    color: var(--text-secondary);
    font-weight: 600;
}
.grant-row .grant-source.source-direct { background: color-mix(in srgb, var(--ds-primary) 12%, transparent); color: var(--primary); }
.grant-row .grant-source.source-auto { background: rgba(245, 158, 11, 0.12); color: #b45309; }
.grant-row .grant-meta {
    font-size: var(--text-sm);
    color: var(--text-secondary);
    margin-left: auto;
}
.group-roles-row .group-roles-arrow { color: var(--text-secondary); font-weight: 400; }
.group-roles-row .role-chips { margin: 0; }
.empty-state {
    padding: 20px 0 4px;
    color: var(--text-secondary);
    font-size: var(--text-base);
    line-height: 1.55;
}
.empty-state .empty-title {
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 4px;
}
.effective-help {
    margin-top: var(--space-3);
    font-size: 12.5px;
    color: var(--text-secondary);
    line-height: 1.55;
}

/* Group chip — semantic role pill used on /me/profile and /admin/users.
   Name-match wins: Admin/Everyone keep their canonical color even when
   their server-side origin is google_sync. */
.group-chip {
    display: inline-block;
    padding: 3px 10px;
    border-radius: var(--radius-full);
    font-size: var(--text-sm);
    font-weight: 500;
    background: #ede9fe;
    color: #6d28d9;
}
.group-chip.is-admin       { background: #fef3c7; color: #92400e; font-weight: 600; }
.group-chip.is-everyone    { background: #f3f4f6; color: #4b5563; }
.group-chip.is-google_sync { background: #dcfce7; color: #166534; }
.group-chip.is-custom      { background: #ede9fe; color: #6d28d9; }

/* =====================================================
   Error pages (4xx / 5xx)
   ===================================================== */
.error-container {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 60vh;
    padding: var(--space-5) var(--space-3);
}
.error-card {
    max-width: 36rem;
    width: 100%;
    padding: var(--space-9) var(--space-8);
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-md);
    text-align: center;
}
.error-code {
    font-size: 4rem;
    font-weight: 700;
    line-height: 1;
    color: var(--ds-accent-danger-ink);
    margin-bottom: var(--space-1);
    letter-spacing: -0.02em;
}
.error-title {
    margin: 0 0 var(--space-3);
    font-size: var(--text-xl);
    font-weight: 600;
}
.error-message {
    color: var(--text-secondary);
    margin: 0 0 var(--space-5);
    line-height: 1.5;
}
.error-path {
    margin: 0 0 var(--space-6);
    font-size: var(--text-sm);
}
.error-path-label { color: var(--text-secondary); margin-right: var(--space-1); }
.error-path code,
.error-traceback pre,
.error-request-id code {
    background: var(--background);
    border-radius: var(--radius-sm);
    font-family: var(--font-mono);
}
.error-path code,
.error-request-id code { padding: 0.15rem 0.4rem; font-size: 0.85em; }
.error-traceback {
    text-align: left;
    margin: 0 0 var(--space-6);
    padding: var(--space-3) var(--space-4);
    background: var(--background);
    border-radius: var(--radius-md);
    border: 1px solid var(--border);
}
.error-traceback summary {
    cursor: pointer;
    font-size: 0.85rem;
    color: var(--text-secondary);
    user-select: none;
}
.error-traceback pre {
    margin: var(--space-3) 0 0;
    font-size: var(--text-sm);
    line-height: 1.4;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-word;
}
.error-request-id {
    margin: 0 0 var(--space-5);
    font-size: 0.8rem;
    color: var(--text-secondary);
}
.error-request-id-label { margin-right: var(--space-1); }
.error-request-id code { user-select: all; }
.error-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: center;
    flex-wrap: wrap;
}

/* =====================================================================
   Modal — global structural styles (#497 §1).

   Promoted verbatim from the page-local <style> in admin_users.html so
   the shared modal helper (static/js/modal.js → window.confirmModal /
   alertModal / promptModal) renders correctly on EVERY page, not just
   the three admin pages that hand-rolled these rules. admin_users.html /
   admin_tokens.html / admin_marketplaces.html still ship identical
   page-local copies; those are redundant now but harmless (same rules)
   and can be stripped in a later cleanup pass.

   Buttons inside .modal-actions use the canonical .btn / .btn-* variants
   (via the ds.button macro or modal.js), so no .modal-btn rules here.
   ===================================================================== */
.modal-backdrop {
    position: fixed; inset: 0; background: rgba(15, 23, 42, 0.55);
    display: none; align-items: center; justify-content: center; z-index: 1000;
    padding: 16px;
}
.modal-backdrop.is-open { display: flex; }
.modal-card {
    background: var(--surface, #fff); border-radius: 12px;
    padding: 24px; width: 100%; max-width: 440px;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25);
}
.modal-card h3 { margin: 0 0 6px; font-size: 17px; font-weight: 600; }
.modal-card p.sub { margin: 0 0 18px; font-size: 13px; color: var(--text-secondary, #6b7280); }
.modal-card label { display: block; font-size: 12px; font-weight: 500; color: var(--text-secondary, #6b7280); margin: 12px 0 6px; }
.modal-card input[type="text"], .modal-card input[type="email"], .modal-card input[type="password"], .modal-card select {
    width: 100%; padding: 9px 12px; border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px; font-size: 13px; box-sizing: border-box;
    background: var(--surface, #fff); color: var(--text-primary, #111827);
}
.modal-card input:focus, .modal-card select:focus { outline: 2px solid var(--ds-primary, #6366f1); outline-offset: -1px; }
.modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px; }
/* Preserve newlines in helper-supplied messages — native alert/confirm/
   prompt rendered \n as line breaks (e.g. bulleted error lists).
   OPT-IN, via the attribute modal.js stamps on the cards it builds. The
   rule used to be unscoped, and the comment already knew that was wrong
   ("the page-local admin_users copy never needed this") — it just had no
   way to say so in a selector. Unscoped, it also hit STATIC modal copy in
   templates, where the newlines and indentation are source formatting: a
   helper paragraph written across three template lines rendered as three
   jaggedly-indented lines instead of one wrapped paragraph (#1171). */
.modal-card[data-preserve-newlines] h3,
.modal-card[data-preserve-newlines] p.sub { white-space: pre-wrap; }

/* Shared inline-icon glyphs (macros/_icon.html) — replaces the pictographic
   emoji we used to inline. Nudge the baseline so an icon sits centered next
   to heading/label text. Block-level empty-state icons ignore this. */
.ui-ico { vertical-align: -0.18em; }
