/* =============================================================================
   EPB CRM — Application Stylesheet
   -----------------------------------------------------------------------------
   Premium minimal design system, Linear/Stripe/Vercel-inspired.
   Loaded once from base.html (<link rel="stylesheet" href="/static/css/app.css">)
   on top of Tailwind (CDN). Tailwind utilities still work; this file owns the
   custom component classes and the design tokens (CSS variables).

   Sections:
     1.  Design tokens (CSS variables)
     2.  Global baseline (html, body, focus, scrollbars)
     3.  Typography utilities (.h-display, .h-page, .font-display)
     4.  Inputs, labels, segmented controls
     5.  Buttons
     6.  Cards
     7.  Pills (status chips)
     8.  Tables
     9.  Sidebar nav
     10. Tabs
     11. Avatars
     12. Dialog
     13. KPI tiles (.kpi, .kpi-hero, .kpi-sm)
     14. Topbar
     15. Chart wrappers
     16. Empty states
     17. Misc (divider, meta-row, scroll-area, clamp)
     18. Foundation layer — skeleton, sparkline, peek-card, inline-bar, dots
     19. Editable cells
     20. New flagship helpers — meta-chip, delta-chip, hero-gradient, login-split
   ============================================================================= */


/* -----------------------------------------------------------------------------
   1. Design tokens
   ----------------------------------------------------------------------------- */
:root {
  /* Surfaces — layered neutrals (replaces flat #FAFAFA canvas) */
  --canvas:         #FAFBFC;
  --canvas-raised: #FFFFFF;
  --canvas-sunken: #F5F6F8;
  --sidebar:        #F7F7F9;

  /* Ink — warmer near-blacks read more premium than pure cold gray */
  --ink-1: #0B0D14;
  --ink-2: #353945;
  --ink-3: #6A6F7B;
  --ink-4: #9CA1AE;

  /* Lines — three tiers so card borders, dividers, and section breaks differ */
  --line-subtle: #EFF0F3;
  --line:        #E3E5EA;
  --line-strong: #D0D3DA;

  /* Accent — kept indigo, tightened (slightly desaturated, Linear-style) */
  --accent-50:  #EEF0FF;
  --accent-100: #DDE0FF;
  --accent-200: #C2C7FF;
  --accent-500: #5B5BD6;   /* primary */
  --accent-600: #4747C7;   /* hover */
  --accent-700: #3C3CB1;   /* active */
  --accent-950: #1A1A52;
  --accent-glow:   rgba(91, 91, 214, 0.16);
  --accent-tint:   rgba(91, 91, 214, 0.04); /* for table-row hover */
  --accent-faint:  rgba(91, 91, 214, 0.06);
  --accent-tint-2: rgba(91, 91, 214, 0.12);

  /* Mono stack — used for plan IDs, EINs, ACK IDs, timestamps, system
     refs. The "engineered" signal Vercel pioneered: when a value is a
     data identifier rather than human text, render it in mono. Loads
     JetBrains Mono via Google Fonts in base.html; falls back through
     the OS mono stack so an offline boot still renders cleanly. */
  --mono-stack: 'JetBrains Mono', ui-monospace, 'SF Mono', 'SFMono-Regular',
                Menlo, Consolas, 'Liberation Mono', monospace;

  /* Premium shadow system */
  --shadow-xs: 0 1px 1px rgba(11, 13, 20, 0.04), 0 0 0 1px rgba(11, 13, 20, 0.02);
  --shadow-sm: 0 1px 2px rgba(11, 13, 20, 0.05),
               0 2px 4px rgba(11, 13, 20, 0.04);
  --shadow-md: 0 4px 6px -1px rgba(11, 13, 20, 0.08),
               0 2px 4px -2px rgba(11, 13, 20, 0.05),
               0 0 0 1px rgba(11, 13, 20, 0.02);
  --shadow-lg: 0 12px 24px -8px rgba(11, 13, 20, 0.14),
               0 6px 12px -4px rgba(11, 13, 20, 0.06),
               0 2px 4px -2px rgba(11, 13, 20, 0.04);
  --shadow-xl: 0 24px 48px -12px rgba(11, 13, 20, 0.20),
               0 8px 16px -6px rgba(11, 13, 20, 0.08);
  --shadow-inset-top: inset 0 1px 0 rgba(255, 255, 255, 0.6);

  /* Radii */
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 10px;
  --radius-xl: 14px;     /* cards bumped from 12 → 14 */
  --radius-2xl: 16px;    /* dialogs */

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  --dur-fast: 120ms;
  --dur-base: 160ms;
  --dur-slow: 280ms;
}


/* -----------------------------------------------------------------------------
   2. Global baseline
   ----------------------------------------------------------------------------- */
:root { --inter-fallback: 'Inter', ui-sans-serif, system-ui, sans-serif; }

html {
  font-family: 'Inter var', var(--inter-fallback);
  font-feature-settings: 'cv11', 'ss01', 'cv02';
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Audit-r5 UI pass: tabular figures + slashed zero globally.
     A retirement-plan CRM lives or dies on whether $12,345,678 lines
     up between rows. Default proportional digits make every table look
     unprofessional. Per-element opt-outs available via .prop-nums. */
  font-variant-numeric: tabular-nums slashed-zero lining-nums;
}

body {
  background: var(--canvas);
  color: var(--ink-1);
  line-height: 1.55;
}

/* Opt-out: marketing copy / running prose where proportional digits
   read better than monospaced columns. */
.prop-nums { font-variant-numeric: proportional-nums; }

.tabular-nums {
  font-variant-numeric: tabular-nums slashed-zero lining-nums;
}

/* Font-stack utility — for plan IDs, EINs, ACK IDs, timestamps.
   Use whenever a value is a system identifier rather than human text. */
.font-mono { font-family: var(--mono-stack); }

/* Inset-ring utility — replaces `border: 1px solid` for cards / inputs
   so hover transitions don't 1px-jump and edges read crisp on hi-DPI.
   Linear's whole interface uses this pattern.

   Usage: <div class="ring-line">    -> normal border
          <div class="ring-line-strong">  -> hover/focus state
          <div class="ring-line-subtle"> -> the lightest divider tier */
.ring-line        { box-shadow: inset 0 0 0 1px var(--line); }
.ring-line-strong { box-shadow: inset 0 0 0 1px var(--line-strong); }
.ring-line-subtle { box-shadow: inset 0 0 0 1px var(--line-subtle); }

/* Reference chip — for plan IDs, EINs, ACK IDs displayed inline.
   Tiny, mono, low-contrast. Reads "this is a data ref" not "this is
   a label". Pair with .ref-chip-strong for the primary identifier. */
.ref-chip {
  font-family: var(--mono-stack);
  font-size: 11px;
  font-weight: 400;
  color: var(--ink-3);
  letter-spacing: 0;
  line-height: 1;
  padding: 3px 6px;
  border-radius: 4px;
  background: var(--canvas-sunken);
  white-space: nowrap;
}
.ref-chip-strong {
  color: var(--ink-2);
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--line-subtle);
}

/* Refined focus ring — soft glow (Linear-style), not bright outline */
.focus-ring:focus-visible,
button:focus-visible,
a:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-glow);
  border-radius: var(--radius-sm);
}

/* Custom scrollbars — thinner, neutral */
.scroll-area { overflow-y: auto; min-height: 0; }
.scroll-area::-webkit-scrollbar { width: 8px; height: 8px; }
.scroll-area::-webkit-scrollbar-track { background: transparent; }
.scroll-area::-webkit-scrollbar-thumb {
  background: var(--line);
  border-radius: 4px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
.scroll-area:hover::-webkit-scrollbar-thumb { background: var(--line-strong); background-clip: padding-box; border: 2px solid transparent; }

/* Lucide icons — finer line weight reads more refined */
.lucide { stroke-width: 1.75; }

/* Alpine cloak */
[x-cloak] { display: none !important; }


/* -----------------------------------------------------------------------------
   3. Typography utilities
   ----------------------------------------------------------------------------- */
/* Audit-r5 UI pass: display + hero numbers use a light weight (320)
   with very tight tracking. This is the single most "billion-dollar"
   typography move — Stripe's 32-56px headlines are weight 300, Mercury's
   are weight 480, both negative-tracked. Reads editorial, not enterprise.
   Pair with Inter's stylistic sets (cv11 / ss01) inherited from html. */
.h-display {
  font-size: 36px;
  font-weight: 320;
  line-height: 1.08;
  letter-spacing: -0.03em;
  color: var(--ink-1);
}

.h-page {
  font-size: 22px;
  font-weight: 500;
  line-height: 1.22;
  letter-spacing: -0.02em;
  color: var(--ink-1);
}

.h-section {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.font-display {
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'ss01' 1, 'cv11' 1;
  letter-spacing: -0.02em;
}

/* Slightly tighter prose by default */
.prose-tight { line-height: 1.5; letter-spacing: -0.003em; }


/* -----------------------------------------------------------------------------
   4. Inputs, labels, segmented controls
   ----------------------------------------------------------------------------- */
/* UI pass: input border becomes an inset ring so the focus state can
   layer ring-strong + outer accent glow simultaneously without the
   1px shift that border-color change causes. */
.input {
  width: 100%;
  background: #fff;
  border: 0;
  border-radius: var(--radius-md);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--ink-1);
  box-shadow: inset 0 0 0 1px var(--line);
  transition: box-shadow var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}
.input:hover { box-shadow: inset 0 0 0 1px var(--line-strong); }
.input:focus {
  outline: none;
  /* Inset accent-500 ring + outer soft glow at the same time. */
  box-shadow:
    inset 0 0 0 1px var(--accent-500),
    0 0 0 3px var(--accent-glow);
}
.input::placeholder { color: var(--ink-4); }
.input-sm { padding: 4px 8px; font-size: 12px; height: 28px; line-height: 1; }

.label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  margin-bottom: 6px;
}

/* Segmented control — used for the dashboard scope toggle and others */
.segmented {
  display: inline-flex;
  background: var(--canvas-sunken);
  border: 1px solid var(--line);
  border-radius: var(--radius-md);
  padding: 3px;
  gap: 2px;
}
.segmented > * {
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  border-radius: 6px;
  transition: background var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out);
  cursor: pointer;
}
.segmented > *:hover { color: var(--ink-1); }
.segmented > .is-active,
.segmented > [aria-selected="true"] {
  background: #fff;
  color: var(--ink-1);
  box-shadow: var(--shadow-xs);
}


/* -----------------------------------------------------------------------------
   5. Buttons
   ----------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 0 14px;
  height: 36px;
  font-size: 14px;
  font-weight: 500;
  border-radius: var(--radius-md);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-base) var(--ease-out);
}
.btn .lucide { width: 16px; height: 16px; }

.btn-primary {
  background: var(--accent-500);
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14),
              0 1px 2px rgba(11, 13, 20, 0.08),
              0 0 0 1px rgba(11, 13, 20, 0.04);
}
.btn-primary:hover {
  background: var(--accent-600);
  transform: translateY(-0.5px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16),
              0 4px 8px -2px rgba(91, 91, 214, 0.28),
              0 0 0 1px rgba(11, 13, 20, 0.04);
}
.btn-primary:active {
  background: var(--accent-700);
  transform: translateY(0);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10),
              0 1px 2px rgba(11, 13, 20, 0.10);
}

/* UI pass: secondary button border becomes inset ring + xs drop shadow.
   Hover shifts the ring weight; the button never jumps. */
.btn-secondary {
  background: #fff;
  color: var(--ink-1);
  border: 0;
  box-shadow:
    inset 0 0 0 1px var(--line),
    0 1px 1px rgba(11, 13, 20, 0.04);
}
.btn-secondary:hover {
  background: var(--canvas);
  box-shadow:
    inset 0 0 0 1px var(--line-strong),
    0 1px 2px rgba(11, 13, 20, 0.06);
}

.btn-ghost {
  background: transparent;
  color: var(--ink-3);
}
.btn-ghost:hover {
  background: var(--canvas-sunken);
  color: var(--ink-1);
}

.btn-danger {
  background: #DC2626;
  color: #fff;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.14), 0 1px 2px rgba(220, 38, 38, 0.18);
}
.btn-danger:hover { background: #B91C1C; transform: translateY(-0.5px); }

.btn-sm { height: 28px; padding: 0 10px; font-size: 13px; }
.btn-sm .lucide { width: 14px; height: 14px; }
.btn-lg { height: 40px; padding: 0 18px; font-size: 14px; }

/* Icon-only button */
.btn-icon { width: 32px; height: 32px; padding: 0; border-radius: var(--radius-md); }
.btn-icon.btn-sm { width: 28px; height: 28px; }


/* -----------------------------------------------------------------------------
   6. Cards
   ----------------------------------------------------------------------------- */
/* UI pass: border -> inset shadow. Avoids the 1px hover-jump that
   `border-width` change causes, and lets us transition ring weight
   + drop shadow in a single transform-less animation. Linear, Notion,
   and Mercury all use this pattern. */
.card {
  background: var(--canvas-raised);
  border-radius: var(--radius-xl);
  /* xs shadow at rest + inset 1px ring acts as the visible edge. */
  box-shadow:
    inset 0 0 0 1px var(--line-subtle),
    0 1px 1px rgba(11, 13, 20, 0.04);
  transition: box-shadow var(--dur-base) var(--ease-out);
}
.card-interactive {
  cursor: pointer;
}
.card-interactive:hover {
  /* Ring strengthens + the drop shadow softens upward. No layout shift. */
  box-shadow:
    inset 0 0 0 1px var(--line),
    0 2px 4px -1px rgba(11, 13, 20, 0.06),
    0 4px 8px -2px rgba(11, 13, 20, 0.04);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-subtle);
  flex-wrap: wrap;
  gap: 8px;
}
.card-header > * { min-width: 0; }
.card-title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-1);
  letter-spacing: -0.005em;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-subtitle {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 2px;
}

/* Hero gradient card — used by AI briefing, login brand panel.
   UI pass: inset-ring pattern; gradient stays. */
.card-gradient {
  position: relative;
  background:
    radial-gradient(80% 60% at 0% 0%, rgba(91, 91, 214, 0.07) 0%, rgba(91, 91, 214, 0) 60%),
    radial-gradient(60% 50% at 100% 100%, rgba(124, 58, 237, 0.05) 0%, rgba(124, 58, 237, 0) 60%),
    var(--canvas-raised);
  box-shadow:
    inset 0 0 0 1px var(--line-subtle),
    inset 0 1px 0 rgba(255, 255, 255, 0.6),
    0 1px 2px rgba(11, 13, 20, 0.05),
    0 2px 4px rgba(11, 13, 20, 0.04);
}


/* -----------------------------------------------------------------------------
   7. Pills (status badges)
   ----------------------------------------------------------------------------- */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 9px;
  border-radius: 9999px;
  font-size: 11.5px;
  font-weight: 500;
  line-height: 18px;
  white-space: nowrap;
}
.pill .lucide { width: 12px; height: 12px; }

.pill-neutral { background: #F2F3F5; color: var(--ink-2); }
.pill-success { background: #ECFDF5; color: #047857; }
.pill-warning { background: #FEF7E6; color: #92400E; }
.pill-danger  { background: #FEF2F3; color: #B91C1C; }
.pill-info    { background: #EEF6FF; color: #1D4ED8; }
.pill-accent  { background: var(--accent-50); color: var(--accent-700); }
.pill-mono    { background: #F6F7F9; color: #334155; font-family: ui-monospace, 'SF Mono', Menlo, monospace; font-size: 11px; }


/* -----------------------------------------------------------------------------
   8. Tables
   ----------------------------------------------------------------------------- */
/* Audit-r5 UI pass: tables tighten to 13px body / py-2 (8px padding) and
   row hover shifts to a NEUTRAL canvas-sunken bg instead of the accent
   tint. Linear / Attio / Notion all do this — accent on hover reads
   loud; neutral reads professional. The accent stays in semantic places
   (active state, primary button, focus ring) only. */
.table {
  width: 100%;
  font-size: 13px;
  line-height: 1.4;
  border-collapse: separate;
  border-spacing: 0;
}
.table thead { background: var(--canvas); }
.table thead th {
  text-align: left;
  padding: 10px 16px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 1;
  /* Backdrop-blur lets the table header overlay scrolling rows
     without a hard cut — premium scroll behavior. */
  background: rgba(250, 251, 252, 0.92);
  backdrop-filter: saturate(180%) blur(8px);
  -webkit-backdrop-filter: saturate(180%) blur(8px);
  white-space: nowrap;
}
.table tbody td {
  padding: 8px 16px;
  border-bottom: 1px solid var(--line-subtle);
  vertical-align: middle;
  color: var(--ink-2);
}
.table tbody tr {
  transition: background-color var(--dur-fast) var(--ease-out);
}
.table tbody tr:hover {
  background: var(--canvas-sunken);
  cursor: pointer;
}
.table tbody tr:last-child td { border-bottom: none; }
.table .col-num {
  text-align: right;
  font-variant-numeric: tabular-nums slashed-zero lining-nums;
  white-space: nowrap;
}
/* Mono-style cell — for plan IDs / EINs / ACK IDs in dense lists.
   Smaller, mono, low-contrast so it doesn't compete with the human name. */
.table .col-ref {
  font-family: var(--mono-stack);
  font-size: 11px;
  color: var(--ink-3);
  letter-spacing: 0;
  white-space: nowrap;
}

/* Wide-table modifier: forces horizontal scroll instead of column squeeze */
.table-wide { min-width: 1040px; width: max-content; }
.table-wide thead th:nth-child(1),
.table-wide thead th:nth-child(2),
.table-wide tbody td:nth-child(1),
.table-wide tbody td:nth-child(2) {
  position: sticky; left: 0; background: #fff; z-index: 2;
}
.table-wide thead th:nth-child(1) { left: 0; background: var(--canvas); }
.table-wide thead th:nth-child(2) { left: 44px; background: var(--canvas); z-index: 3; }
.table-wide tbody td:nth-child(1) { left: 0; }
.table-wide tbody td:nth-child(2) { left: 44px; box-shadow: 1px 0 0 var(--line-subtle); }
.table-wide tbody tr:hover td:nth-child(1),
.table-wide tbody tr:hover td:nth-child(2) { background: #FAFBFE; }

.table-scroll { position: relative; overflow-x: auto; }
.table-scroll::after {
  content: "";
  position: sticky; right: 0; top: 0; bottom: 0;
  display: block;
  width: 32px; height: 100%;
  background: linear-gradient(to right, transparent, rgba(255, 255, 255, 0.92));
  pointer-events: none;
  margin-left: -32px;
}

.table-sticky-actions tbody td:last-child,
.table-sticky-actions thead th:last-child {
  position: sticky; right: 0; background: #fff; z-index: 2;
  box-shadow: -1px 0 0 var(--line-subtle);
}
.table-sticky-actions thead th:last-child { background: var(--canvas); z-index: 3; }
.table-sticky-actions tbody tr:hover td:last-child { background: #FAFBFE; }

/* Constrain pill cells so a long firm name (e.g. "International Business
   Machines Corporation Retirement Trust") doesn't push the table past
   the viewport and cut off downstream columns. Cap each pill at 180px
   with ellipsis + hover tooltip preserving the full name. Used on
   workplace_detail.html's auditor/RK/advisor columns. */
.cell-pill { max-width: 200px; }
.pill-truncate {
  max-width: 180px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
  vertical-align: middle;
}

.sort-header {
  cursor: pointer; user-select: none;
  transition: color var(--dur-fast) var(--ease-out);
}
.sort-header:hover { color: var(--ink-1) !important; }
.sort-header a { text-decoration: none; }
.sort-header.is-active { color: var(--accent-700) !important; }


/* -----------------------------------------------------------------------------
   9. Sidebar nav
       Tier-1 rail + tier-2 flyout styles live in section 9b below. The
       legacy .nav-section-* classes (collapsible "Workspace" / "Intelligence"
       sections with chevron toggles) were retired with the HubSpot-style
       rail; .nav-item is the only legacy class still in use, kept as the
       base for the flyout-item style.
   ----------------------------------------------------------------------------- */

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 7px 12px;
  margin: 1px 0;
  border-radius: var(--radius-md);
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 500;
  position: relative;
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.nav-item:hover {
  background: rgba(255, 255, 255, 0.7);
  color: var(--ink-1);
}
.nav-item.active {
  background: #fff;
  color: var(--ink-1);
  box-shadow: var(--shadow-xs), inset 0 0 0 1px var(--line-subtle);
}
/* Active state — left indigo rail */
.nav-item.active::before {
  content: "";
  position: absolute;
  left: -3px;
  top: 7px;
  bottom: 7px;
  width: 2.5px;
  background: var(--accent-500);
  border-radius: 0 2px 2px 0;
}
.nav-item .lucide {
  width: 16px;
  height: 16px;
  color: var(--ink-3);
  flex-shrink: 0;
  transition: color var(--dur-base) var(--ease-out);
}
.nav-item:hover .lucide { color: var(--ink-2); }
.nav-item.active .lucide { color: var(--accent-500); }
.nav-item.disabled {
  color: var(--ink-4);
  cursor: not-allowed;
}
.nav-item.disabled:hover {
  background: transparent;
  color: var(--ink-4);
}


/* -----------------------------------------------------------------------------
   9b. Two-tier nav rail + flyout (HubSpot-style)
       Driven by app/services/nav.py + base.html nav-rail block.
   ----------------------------------------------------------------------------- */

/* Tier-1 rail item — same visual language as .nav-item but designed
   for the new module rail (singletons and module-toggle buttons share
   this class). Padding slightly tighter than .nav-item since modules
   are the primary surface now and we want 10 to fit comfortably. */
.rail-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius-md);
  color: var(--ink-2);
  font-size: 13.5px;
  font-weight: 500;
  background: transparent;
  border: 1px solid transparent;
  cursor: pointer;
  width: 100%;
  text-align: left;
  position: relative;
  transition: background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.rail-item:hover {
  background: rgba(255, 255, 255, 0.7);
  color: var(--ink-1);
}
.rail-item:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--accent-500), 0 0 0 4px rgba(91, 91, 214, 0.15);
}
.rail-item-active {
  background: #fff;
  color: var(--ink-1);
  box-shadow: var(--shadow-xs), inset 0 0 0 1px var(--line-subtle);
}
.rail-item-active::before {
  content: "";
  position: absolute;
  left: -2px;
  top: 7px;
  bottom: 7px;
  width: 2.5px;
  background: var(--accent-500);
  border-radius: 0 2px 2px 0;
}
.rail-item-open {
  background: #fff;
  box-shadow: var(--shadow-xs), inset 0 0 0 1px var(--line-subtle);
}
.rail-icon {
  width: 16px;
  height: 16px;
  color: var(--ink-3);
  flex-shrink: 0;
  transition: color var(--dur-base) var(--ease-out);
}
.rail-item:hover .rail-icon { color: var(--ink-2); }
.rail-item-active .rail-icon { color: var(--accent-500); }
.rail-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rail-chevron {
  width: 12px;
  height: 12px;
  color: var(--ink-4);
  flex-shrink: 0;
  transition: transform var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.rail-item-open .rail-chevron {
  transform: rotate(90deg);
  color: var(--ink-2);
}

/* Tier-1 badge pill — count of overdue/saved/etc. Kinds:
   danger (rose), warning (amber), info (accent). */
.rail-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1;
}
.rail-badge-danger  { background: #FEE2E2; color: #B91C1C; }
.rail-badge-warning { background: #FEF3C7; color: #92400E; }
.rail-badge-info    { background: var(--accent-50); color: var(--accent-700); }

/* Tier-2 flyout panel — sits to the immediate right of the rail
   button. We use position:fixed (not absolute) because the rail's
   parent <nav> has overflow:auto for scroll, which would clip an
   absolutely-positioned child. Fixed positioning escapes the clip
   region entirely. The top is set inline by Alpine when the flyout
   opens so it lines up with the clicked button.

   248px aside width + 4px gap = 252px from the left edge of viewport.
   264px wide so labels never wrap. Max-height with internal scroll
   for modules with many items (Intelligence has 12). */
.nav-flyout {
  position: fixed;
  left: 252px;
  top: 80px;            /* default — Slice 3 anchors to clicked button */
  z-index: 40;
  width: 264px;
  max-height: calc(100vh - 100px);
  display: flex;
  flex-direction: column;
  /* Tailwind config defines `surface: '#FFFFFF'` as a color, but it
     isn't surfaced as a CSS custom property — only --canvas-raised is.
     Same for shadow-pop (Tailwind utility only). Use the literal
     hex / shadow-lg variable that already exists. */
  background: var(--canvas-raised);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.nav-flyout-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--line-subtle);
  background: var(--canvas);
}
.nav-flyout-items {
  padding: 6px;
  overflow-y: auto;
  flex: 1;
}
.nav-flyout-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border-radius: var(--radius-md);
  color: var(--ink-1);
  font-size: 13px;
  font-weight: 450;
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--dur-base) var(--ease-out);
}
.nav-flyout-item:hover {
  background: var(--canvas);
}
.nav-flyout-item-active {
  background: var(--accent-50);
  color: var(--accent-700);
  font-weight: 550;
}
.nav-flyout-item-active .lucide {
  color: var(--accent-600);
}
.nav-flyout-empty {
  padding: 24px 16px;
  text-align: center;
  color: var(--ink-3);
}
[x-cloak] { display: none !important; }


/* -----------------------------------------------------------------------------
   9c. Sidebar compact mode
       html[data-nav-mode="compact"] narrows the rail to icon-only.
       Saves ~140px of horizontal space — the main column gets it.
       Toggle from /profile (writes localStorage.cb_nav_mode). The
       inline script in base.html applies the data attribute before
       paint so there's no flash of expanded-then-compact.

       NOT applied at mobile breakpoints — the rail is hidden behind
       a hamburger there instead (future work).
   ----------------------------------------------------------------------------- */

html[data-nav-mode="compact"] aside.w-\[248px\] {
  /* Override the inline Tailwind width. 64px = icon + paddings;
     same width that HubSpot uses in their compact mode. */
  width: 64px !important;
}

/* Hide labels, chevrons, badges in compact mode — only the icon remains. */
html[data-nav-mode="compact"] .rail-label,
html[data-nav-mode="compact"] .rail-chevron,
html[data-nav-mode="compact"] .rail-badge {
  display: none !important;
}

/* Center the icon in the now-narrower button. */
html[data-nav-mode="compact"] .rail-item {
  justify-content: center;
  padding: 8px 0;
}

/* Persona switcher (workspace badge) at the top of the rail — hide the
   firm name + persona subtitle, show only the colored letter tile.
   The aside <button> wraps `.avatar` + a text block; we hide the text. */
html[data-nav-mode="compact"] aside > div:first-child {
  padding-left: 8px;
  padding-right: 8px;
}
/* Only the OUTER toggle button gets its label hidden (it's a direct
   child of div:first-child). The dropdown's nested persona-row
   buttons must keep their labels — those are inside the popout
   panel which is sized at 260px in compact mode below. */
html[data-nav-mode="compact"] aside > div:first-child > button > div.flex-1,
html[data-nav-mode="compact"] aside > div:first-child > button > i[data-lucide="chevrons-up-down"] {
  display: none !important;
}
html[data-nav-mode="compact"] aside > div:first-child > button {
  justify-content: center;
  padding: 0;
}

/* User profile button at the bottom — same treatment: avatar only,
   no name / title text, no chevron. */
html[data-nav-mode="compact"] #userMenuWrap > button > div.flex-1,
html[data-nav-mode="compact"] #userMenuWrap > button > i[data-lucide="chevron-up"] {
  display: none !important;
}
html[data-nav-mode="compact"] #userMenuWrap > button {
  justify-content: center;
  padding: 6px;
}

/* The flyout's left-position is computed relative to the aside's
   right edge (252px = 248 + 4). When the aside narrows to 64px,
   the flyout needs to slide to 68px so it still anchors. */
html[data-nav-mode="compact"] .nav-flyout {
  left: 68px;
}

/* Workspace switcher dropdown — when the rail is collapsed to 64px,
   the dropdown's `left-4 right-4` Tailwind positioning crushes it
   to ~32px wide and wraps "Profile & identity" onto 4 lines. Pop the
   panel OUT to the right of the rail at a fixed 260px width instead.
   The dropdown lives at `aside > div:first-child > div[x-show]`
   (the persona dropdown panel directly inside the relative+x-data
   wrapper). Same treatment for the user menu at the bottom. */
html[data-nav-mode="compact"] aside > div:first-child > div[x-show] {
  left: 60px !important;
  right: auto !important;
  width: 260px !important;
  margin-top: 0 !important;
  top: 8px !important;
}
html[data-nav-mode="compact"] #userMenuWrap > div[x-show] {
  left: 60px !important;
  right: auto !important;
  width: 240px !important;
  bottom: 8px !important;
  top: auto !important;
  margin-bottom: 0 !important;
}


/* -----------------------------------------------------------------------------
   10. Tabs (underline style)
   ----------------------------------------------------------------------------- */
.tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 12px 4px;
  margin-right: 24px;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink-3);
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.tab:hover { color: var(--ink-1); }
.tab.active {
  color: var(--ink-1);
  border-bottom-color: var(--accent-500);
}
.tab .lucide { width: 14px; height: 14px; }
.tab .count {
  background: var(--canvas-sunken);
  color: var(--ink-3);
  font-size: 11px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: 10px;
  margin-left: 2px;
}
.tab.active .count {
  background: var(--accent-50);
  color: var(--accent-700);
}


/* -----------------------------------------------------------------------------
   11. Avatars
   ----------------------------------------------------------------------------- */
.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 9999px;
  font-weight: 600;
  flex-shrink: 0;
  background: linear-gradient(135deg, #E0E7FF 0%, #C7D2FE 100%);
  color: var(--accent-700);
  box-shadow: inset 0 0 0 1px rgba(91, 91, 214, 0.08);
}
.avatar-xs { width: 24px; height: 24px; font-size: 10px; }
.avatar-sm { width: 28px; height: 28px; font-size: 11px; }
.avatar-md { width: 36px; height: 36px; font-size: 13px; }
.avatar-lg { width: 56px; height: 56px; font-size: 18px; letter-spacing: -0.02em; }


/* -----------------------------------------------------------------------------
   12. Dialog
   ----------------------------------------------------------------------------- */
dialog {
  border: none;
  padding: 0;
  border-radius: var(--radius-2xl);
  box-shadow: var(--shadow-xl);
  width: 100%;
  max-width: 540px;
  background: #fff;
}
dialog::backdrop {
  background: rgba(11, 13, 20, 0.42);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}


/* -----------------------------------------------------------------------------
   13. KPI tiles
   ----------------------------------------------------------------------------- */
/* UI pass: same border->inset-shadow as .card. KPI tiles share the
   same visual language. */
.kpi {
  background: var(--canvas-raised);
  border-radius: var(--radius-xl);
  padding: 16px 18px;
  box-shadow:
    inset 0 0 0 1px var(--line-subtle),
    0 1px 1px rgba(11, 13, 20, 0.04);
  min-width: 0;
  transition: box-shadow var(--dur-base) var(--ease-out);
}
.kpi-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-3);
  display: flex;
  align-items: center;
  gap: 6px;
}
.kpi-label .lucide {
  width: 14px;
  height: 14px;
  color: var(--ink-4);
}
/* Audit-r5 UI pass: KPI values drop from weight 600 to a lighter scale.
   24px-and-up reads thin-and-elegant at weight 360-400; sub-20px stays
   at 500 because too-thin reads anemic at small sizes. Slashed zero +
   tnum inherited from html. */
.kpi-value {
  font-size: 24px;
  font-weight: 400;
  color: var(--ink-1);
  letter-spacing: -0.025em;
  line-height: 1.18;
  margin-top: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.kpi-meta {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 2px;
}

/* Hero variant — bigger value, room for sparkline + delta row.
   36px / weight 320 / -0.03em tracking is the Stripe-headline move
   transferred to financial KPIs. Reads editorial. */
.kpi-hero {
  padding: 20px 22px;
}
.kpi-hero .kpi-value {
  font-size: 36px;
  font-weight: 320;
  letter-spacing: -0.03em;
  margin-top: 10px;
}
.kpi-hero:hover {
  /* Ring strengthens; matching .card-interactive treatment. */
  box-shadow:
    inset 0 0 0 1px var(--line),
    0 2px 4px -1px rgba(11, 13, 20, 0.06),
    0 4px 8px -2px rgba(11, 13, 20, 0.04);
}

/* Compact variant — plan-detail strip, dense places.
   18px is too small for weight 320; keep 500 for legibility. */
.kpi-sm {
  padding: 12px 14px;
}
.kpi-sm .kpi-label { font-size: 11px; }
.kpi-sm .kpi-value { font-size: 18px; font-weight: 500; margin-top: 4px; letter-spacing: -0.015em; }
.kpi-sm .kpi-meta { font-size: 11px; }


/* -----------------------------------------------------------------------------
   14. Topbar
   ----------------------------------------------------------------------------- */
.topbar {
  background: rgba(255, 255, 255, 0.85);
  backdrop-filter: saturate(180%) blur(10px);
  -webkit-backdrop-filter: saturate(180%) blur(10px);
  border-bottom: 1px solid var(--line-subtle);
  height: 60px;
  display: flex;
  align-items: center;
  padding: 0 24px;
  gap: 16px;
  /* backdrop-filter above creates a stacking context, which traps the search
     dropdown (z-50) *inside* the topbar. Without a z-index here the scrolling
     content below (a later sibling) paints over the whole topbar — so the
     dropdown appears behind the page. Lift the topbar above the content. */
  position: relative;
  z-index: 40;
}


/* -----------------------------------------------------------------------------
   15. Chart wrappers
   ----------------------------------------------------------------------------- */
.chart-wrap    { position: relative; width: 100%; height: 220px; }
.chart-wrap-sm { position: relative; width: 100%; height: 120px; }
.chart-wrap-lg { position: relative; width: 100%; height: 320px; }
.chart-wrap > canvas,
.chart-wrap-sm > canvas,
.chart-wrap-lg > canvas {
  position: absolute; inset: 0;
  width: 100% !important;
  height: 100% !important;
}

.chart-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  gap: 8px;
  color: var(--ink-4);
  text-align: center;
  padding: 16px;
}
.chart-empty .lucide { width: 28px; height: 28px; color: var(--line-strong); }
.chart-empty .title { font-size: 13px; font-weight: 500; color: var(--ink-3); }
.chart-empty .sub { font-size: 12px; color: var(--ink-4); max-width: 240px; line-height: 1.4; }


/* -----------------------------------------------------------------------------
   16. Empty states
   ----------------------------------------------------------------------------- */
.empty-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 48px 24px;
  gap: 10px;
  color: var(--ink-3);
  text-align: center;
}
.empty-block .icon-bubble {
  width: 44px; height: 44px;
  border-radius: 9999px;
  background: var(--canvas-sunken);
  box-shadow: inset 0 0 0 1px var(--line-subtle);
  display: flex; align-items: center; justify-content: center;
}
.empty-block .icon-bubble .lucide {
  width: 20px; height: 20px; color: var(--ink-4);
}
.empty-block .title { font-size: 14px; font-weight: 600; color: var(--ink-1); }
.empty-block .sub   { font-size: 13px; color: var(--ink-3); max-width: 340px; }


/* ----------------------------------------------------------------
   Canonical empty-state (Slice 4 macro target).
   Used everywhere the platform has "no data yet". Two sizes; same
   visual contract regardless of context.
---------------------------------------------------------------- */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  color: var(--ink-3);
}
.empty-state__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-4);
  opacity: 0.6;
}
.empty-state__icon .lucide { width: 24px; height: 24px; }
.empty-state__title {
  font-size: 14px;
  font-weight: 600;
  color: var(--ink-1);
  letter-spacing: -0.005em;
}
.empty-state__sub {
  font-size: 12.5px;
  color: var(--ink-3);
  line-height: 1.45;
  max-width: 360px;
}

/* Small — inside-card empties, panels, sidebar lists. */
.empty-state-small {
  padding: 20px 16px;
  gap: 8px;
}
.empty-state-small .empty-state__icon { margin-bottom: 2px; }

/* Large — whole-page or top-of-card hero empty. */
.empty-state-large {
  padding: 48px 24px;
  gap: 12px;
}
.empty-state-large .empty-state__icon {
  width: 48px;
  height: 48px;
  border-radius: 9999px;
  background: var(--canvas-sunken);
  box-shadow: inset 0 0 0 1px var(--line-subtle);
  margin-bottom: 6px;
}
.empty-state-large .empty-state__icon .lucide {
  width: 22px; height: 22px;
}
.empty-state-large .empty-state__title {
  font-size: 16px;
  font-weight: 500;
  letter-spacing: -0.01em;
}


/* -----------------------------------------------------------------------------
   17. Misc utilities
   ----------------------------------------------------------------------------- */
.divider {
  height: 1px;
  background: var(--line-subtle);
  margin: 16px 0;
}

.meta-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 0;
  font-size: 13px;
  gap: 16px;
}
.meta-row + .meta-row { border-top: 1px solid var(--line-subtle); }
.meta-key { color: var(--ink-3); font-weight: 500; flex-shrink: 0; }
.meta-val { color: var(--ink-1); text-align: right; min-width: 0; }
.meta-val.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  line-height: 1.35;
}


/* =============================================================================
   18. Foundation layer — skeleton, sparkline, peek-card, inline-bar, dots
   ============================================================================= */

/* Skeleton loaders (shimmer). Slowed + softened for a calmer premium feel. */
@keyframes skeleton-shimmer {
  0%   { background-position: -200% 0; }
  100% { background-position:  200% 0; }
}
.skel {
  display: inline-block;
  border-radius: var(--radius-sm);
  background: linear-gradient(90deg, #F1F2F5 0%, #E7E9ED 50%, #F1F2F5 100%);
  background-size: 200% 100%;
  animation: skeleton-shimmer 2.2s ease-in-out infinite;
}
.skel-text  { height: 12px; width: 100%; }
.skel-num   { height: 22px; width: 64px; }
.skel-kpi   { height: 80px; width: 100%; border-radius: var(--radius-xl); }
.skel-row   { height: 36px; width: 100%; margin-bottom: 6px; border-radius: var(--radius-md); }
.skel-bar   { height: 8px;  width: 100%; border-radius: 4px; }
.skel-chart { height: 220px; width: 100%; border-radius: var(--radius-lg); }

/* Sparkline */
.spark    { display: block; width: 100%; max-width: 140px; height: 28px; }
.spark-sm { height: 18px; max-width: 80px; }
.spark-lg { height: 40px; max-width: 220px; }

/* Inline horizontal bar (used in ranking lists, KPI internals) */
.inbar {
  position: relative;
  height: 6px;
  background: var(--canvas-sunken);
  border-radius: 4px;
  overflow: hidden;
  min-width: 60px;
}
.inbar-fill {
  position: absolute;
  left: 0; top: 0; bottom: 0;
  background: linear-gradient(90deg, #818CF8 0%, var(--accent-600) 100%);
  border-radius: 4px;
  transition: width var(--dur-slow) var(--ease-out);
}
.inbar-fill.is-rose    { background: linear-gradient(90deg, #FB7185 0%, #E11D48 100%); }
.inbar-fill.is-amber   { background: linear-gradient(90deg, #FBBF24 0%, #D97706 100%); }
.inbar-fill.is-emerald { background: linear-gradient(90deg, #34D399 0%, #059669 100%); }
.inbar-fill.is-slate   { background: linear-gradient(90deg, #94A3B8 0%, #475569 100%); }

/* Peek-card */
.peek-card {
  position: fixed;
  z-index: 9000;
  width: 320px;
  max-width: 90vw;
  background: rgba(255, 255, 255, 0.96);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-radius: var(--radius-xl);
  /* UI pass: inset ring + lg shadow. Avoids border-+-shadow stack
     looking heavy on Retina. */
  box-shadow: inset 0 0 0 1px var(--line), var(--shadow-lg);
  pointer-events: auto;
  transform: translateY(4px);
  opacity: 0;
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-base) var(--ease-out);
}
.peek-card.is-open { transform: translateY(0); opacity: 1; }
.peek-card .peek-header {
  padding: 12px 14px;
  border-bottom: 1px solid var(--line-subtle);
  display: flex;
  align-items: center;
  gap: 10px;
}
.peek-card .peek-body {
  padding: 10px 14px;
  max-height: 240px;
  overflow-y: auto;
}
.peek-card .peek-footer {
  padding: 8px 14px;
  border-top: 1px solid var(--line-subtle);
  background: var(--canvas);
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12px;
  color: var(--ink-3);
}

/* Status dots */
.dot {
  display: inline-block;
  width: 6px; height: 6px;
  border-radius: 9999px;
  vertical-align: middle;
  flex-shrink: 0;
}
.dot-success { background: #10B981; }
.dot-warning { background: #F59E0B; }
.dot-danger  { background: #E11D48; }
.dot-info    { background: var(--accent-500); }
.dot-muted   { background: #94A3B8; }
.dot-pulse   { animation: dot-pulse 2.4s ease-out infinite; }
@keyframes dot-pulse {
  0%   { box-shadow: 0 0 0 0 var(--accent-glow); }
  70%  { box-shadow: 0 0 0 8px rgba(91, 91, 214, 0); }
  100% { box-shadow: 0 0 0 0 rgba(91, 91, 214, 0); }
}

/* Coverage chip */
.coverage {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  border-radius: 9999px;
  background: var(--canvas-sunken);
  color: var(--ink-2);
  font-size: 11.5px;
  font-weight: 500;
}
.coverage strong {
  color: var(--ink-1);
  font-variant-numeric: tabular-nums;
}


/* -----------------------------------------------------------------------------
   19. Editable cells
   ----------------------------------------------------------------------------- */
.editable-cell {
  cursor: text;
  position: relative;
  padding-right: 14px;
  min-height: 22px;
}
.editable-cell::after {
  content: "";
  position: absolute;
  right: 0; top: 50%;
  transform: translateY(-50%);
  width: 8px; height: 8px;
  background: var(--line-strong);
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z'/></svg>") no-repeat center / contain;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><path d='M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z'/></svg>") no-repeat center / contain;
  opacity: 0;
  transition: opacity var(--dur-fast);
}
.editable-cell:hover::after { opacity: 1; }
.editable-cell input.cell-input {
  width: 100%;
  padding: 2px 6px;
  font: inherit;
  border: 1px solid var(--accent-500);
  border-radius: 4px;
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-glow);
  background: #fff;
}
.cell-saving { opacity: 0.6; }
.cell-saved-flash { animation: cell-flash .8s ease-out; }
@keyframes cell-flash {
  0%   { background: rgba(16, 185, 129, 0.18); }
  100% { background: transparent; }
}


/* =============================================================================
   20. Flagship helpers — meta-chip, delta-chip, hero-gradient, login-split
   ============================================================================= */

/* Meta chip — used in plan-detail header.
   UI pass: inset ring so hover doesn't 1px-shift the chip; this rail
   is high-density and any movement is visible. */
.meta-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  background: var(--canvas-raised);
  border-radius: 9999px;
  font-size: 12px;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
  box-shadow: inset 0 0 0 1px var(--line-subtle);
  transition: box-shadow var(--dur-base) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}
.meta-chip:hover {
  box-shadow: inset 0 0 0 1px var(--line);
  background: var(--canvas);
}
.meta-chip .lucide { width: 12px; height: 12px; color: var(--ink-4); }
.meta-chip .meta-chip-key { color: var(--ink-3); font-weight: 500; }
.meta-chip .meta-chip-val { color: var(--ink-1); font-weight: 500; }

/* =============================================================================
   5500RADAR brand lockup — wordmark + animated "radar blip" persona sweep.
   Used on the login/auth hero (animated, dark bg) and the sidebar (compact).
   Wordmark = Michroma (loaded in base.html <head>); persona row inherits the
   UI sans. Pure CSS animation — CSP-safe.
   ============================================================================= */
.cb-wordmark { font-family: 'Michroma', ui-sans-serif, system-ui, sans-serif;
  letter-spacing: .05em; white-space: nowrap; line-height: 1; font-weight: 400; }
.cb-wordmark .num   { color: #fff; }
.cb-wordmark .radar { color: #4674f5; }
.cb-wordmark.is-ink .num   { color: var(--ink-1); }     /* light-bg (sidebar) */
.cb-wordmark.is-ink .radar { color: #3f6ae6; }

.cb-brand-hero .cb-wordmark { font-size: clamp(32px, 4.6vw, 50px); }
.cb-brand-hero .cb-wordmark .radar { text-shadow: 0 0 26px rgba(70,116,245,.55);
  animation: cbBreathe 4.5s ease-in-out infinite; }
@keyframes cbBreathe { 0%,100% { text-shadow: 0 0 20px rgba(70,116,245,.4); }
  50% { text-shadow: 0 0 38px rgba(70,116,245,.75); } }

.cb-personas { position: relative; display: inline-flex; align-items: center;
  gap: clamp(10px, 1.4vw, 20px); margin-top: 18px; padding-bottom: 26px;
  font-size: 12px; letter-spacing: .26em; text-transform: uppercase; }
.cb-personas .cb-sep { color: #4674f5; opacity: .55; font-size: .62em; }
.cb-persona { color: rgba(255,255,255,.40); white-space: nowrap;
  transition: color .5s ease, text-shadow .5s ease; }
.cb-persona.active { color: rgba(255,255,255,.92); text-shadow: 0 0 14px rgba(95,139,255,.35); }
.cb-blip { position: absolute; bottom: 8px; left: 0; width: 7px; height: 7px; border-radius: 50%;
  background: #5f8bff; transform: translateX(-50%); box-shadow: 0 0 10px 2px rgba(70,116,245,.6);
  transition: left .8s cubic-bezier(.66,0,.2,1); }
.cb-blip::after { content: ""; position: absolute; inset: 50% auto auto 50%; width: 7px; height: 7px;
  border-radius: 50%; transform: translate(-50%,-50%); animation: cbPing 2.4s ease-out infinite; }
@keyframes cbPing { 0% { box-shadow: 0 0 0 0 rgba(95,139,255,.55); }
  70% { box-shadow: 0 0 0 14px rgba(95,139,255,0); } 100% { box-shadow: 0 0 0 0 rgba(95,139,255,0); } }

/* sidebar compact lockup */
.cb-brand-rail { display: inline-flex; align-items: center; gap: 7px; text-decoration: none; }
.cb-brand-rail .cb-wordmark { font-size: 16px; }
.cb-brand-rail .cb-rail-dot { width: 6px; height: 6px; border-radius: 50%; background: #4674f5;
  animation: cbPing 2.4s ease-out infinite; }

@media (prefers-reduced-motion: reduce) {
  .cb-blip { transition: none; }
  .cb-blip::after, .cb-brand-hero .cb-wordmark .radar, .cb-brand-rail .cb-rail-dot { animation: none; }
}

/* Delta chip — green/red/neutral pill with arrow */
.delta-chip {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  padding: 2px 7px;
  border-radius: 9999px;
  font-size: 11px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 16px;
}
.delta-chip .lucide { width: 11px; height: 11px; }
.delta-up   { background: #ECFDF5; color: #047857; }
.delta-down { background: #FEF2F3; color: #B91C1C; }
.delta-flat { background: var(--canvas-sunken); color: var(--ink-3); }

/* ----------------------------------------------------------------
   Page hero (Slice 5 macro target).
   Eyebrow / h-display title / subtitle / optional action row.
   The visual through-line that makes every top-level page feel
   like the same product.
---------------------------------------------------------------- */
.page-hero {
  padding-top: 8px;
  padding-bottom: 32px;
  margin-bottom: 8px;
}
.page-hero__eyebrow {
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 6px;
}
.page-hero__title {
  /* Inherits .h-display: 36px / weight 320 / -0.03em / 1.08 lh. */
  margin: 0;
}
.page-hero__sub {
  font-size: 14px;
  color: var(--ink-3);
  line-height: 1.5;
  margin-top: 6px;
  max-width: 720px;
}
.page-hero__actions {
  margin-top: 18px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}


/* ----------------------------------------------------------------
   Density toggle (Slice 5).
   Power users want denser tables; default stays roomy. Toggle via
   adding `data-density="compact"` on <body> (set by profile pref,
   stored in localStorage, or session). Three CSS variables drive
   it; per-component overrides use them.

   Default (data-density="cozy" or absent):
     --row-py: 8px      (table row vertical padding, matches Slice 1)
     --row-font: 13px

   Compact:
     --row-py: 5px
     --row-font: 12.5px
---------------------------------------------------------------- */
:root {
  --row-py: 8px;
  --row-font: 13px;
}
[data-density="compact"] {
  --row-py: 5px;
  --row-font: 12.5px;
}
[data-density="compact"] .table {
  font-size: var(--row-font);
}
[data-density="compact"] .table tbody td {
  padding-top: var(--row-py);
  padding-bottom: var(--row-py);
}
[data-density="compact"] .kpi { padding: 12px 14px; }
[data-density="compact"] .kpi-hero { padding: 16px 18px; }
[data-density="compact"] .kpi-hero .kpi-value { font-size: 30px; }


/* Hero gradient band — used by dashboard hero. UI pass: inset ring. */
.hero-band {
  position: relative;
  background:
    radial-gradient(60% 70% at 0% 0%,  rgba(91, 91, 214, 0.08) 0%, rgba(91, 91, 214, 0) 60%),
    radial-gradient(50% 60% at 100% 100%, rgba(124, 58, 237, 0.06) 0%, rgba(124, 58, 237, 0) 60%),
    linear-gradient(180deg, #FCFCFD 0%, var(--canvas) 100%);
  border-radius: var(--radius-xl);
  padding: 24px 28px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line-subtle);
}
.hero-band::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(120% 120% at 50% 0%, rgba(255, 255, 255, 0.6) 0%, rgba(255, 255, 255, 0) 50%);
}

/* Login split layout */
.login-shell {
  height: 100vh;
  overflow: hidden;
  display: grid;
  grid-template-columns: 55% 45%;
  background: var(--canvas-raised);
}
.login-shell > * { min-height: 0; overflow: auto; }
@media (max-width: 900px) {
  .login-shell { grid-template-columns: 1fr; grid-template-rows: 140px 1fr; }
}

.login-brand {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(70% 80% at 10% 10%,  rgba(91, 91, 214, 0.22) 0%, rgba(91, 91, 214, 0) 60%),
    radial-gradient(60% 70% at 90% 90%, rgba(124, 58, 237, 0.16) 0%, rgba(124, 58, 237, 0) 60%),
    radial-gradient(50% 60% at 50% 50%, rgba(56, 189, 248, 0.10) 0%, rgba(56, 189, 248, 0) 60%),
    linear-gradient(135deg, #0F1A3D 0%, #1A1A52 50%, #2D2A6E 100%);
  color: #fff;
  padding: 48px 56px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.login-brand::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(255,255,255,0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,0.03) 1px, transparent 1px);
  background-size: 32px 32px;
  pointer-events: none;
  opacity: 0.6;
  mask-image: radial-gradient(80% 80% at 50% 30%, #000 0%, transparent 80%);
  -webkit-mask-image: radial-gradient(80% 80% at 50% 30%, #000 0%, transparent 80%);
}
.login-brand > * { position: relative; z-index: 1; }

.login-brand .wordmark {
  display: flex;
  align-items: center;
  gap: 12px;
}
.login-brand .wordmark .mark {
  width: 36px;
  height: 36px;
  border-radius: 10px;
  background: linear-gradient(135deg, #fff 0%, rgba(255,255,255,0.85) 100%);
  color: #0F1A3D;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 16px;
  letter-spacing: -0.02em;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18), inset 0 1px 0 rgba(255,255,255,0.6);
}
.login-brand .wordmark .name {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.login-brand .wordmark .sub {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
  margin-top: 1px;
}

.login-brand .hero-text {
  font-size: 38px;
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.028em;
  max-width: 520px;
  color: rgba(255, 255, 255, 0.97);
}
.login-brand .hero-text em {
  font-style: normal;
  background: linear-gradient(120deg, #C7D2FE 0%, #FBCFE8 100%);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.login-brand .hero-sub {
  font-size: 14px;
  color: rgba(255, 255, 255, 0.65);
  margin-top: 18px;
  max-width: 480px;
  line-height: 1.55;
}

.login-brand .brand-stats {
  display: flex;
  gap: 32px;
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding-top: 22px;
}
.login-brand .brand-stat .num {
  font-size: 22px;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: #fff;
  font-variant-numeric: tabular-nums;
}
.login-brand .brand-stat .lbl {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 3px;
}

.login-form-wrap {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 64px 72px;
  background: var(--canvas-raised);
}
@media (max-width: 1100px) { .login-form-wrap { padding: 48px 48px; } }
@media (max-width: 900px)  { .login-form-wrap { padding: 32px 28px; } }

.login-form-wrap .form-inner {
  max-width: 380px;
  width: 100%;
  margin: 0 auto;
}
.login-form-wrap .form-title {
  font-size: 26px;
  font-weight: 600;
  letter-spacing: -0.022em;
  color: var(--ink-1);
}
.login-form-wrap .form-sub {
  font-size: 14px;
  color: var(--ink-3);
  margin-top: 6px;
}


/* -----------------------------------------------------------------------------
   Bridge: ensure Tailwind bg-canvas / text-ink utilities resolve to the new
   tokens (because the inline tailwind config in base.html runs *before* this
   file loads — keeping a CSS fallback for the body bg matters).
   ----------------------------------------------------------------------------- */
.bg-canvas        { background-color: var(--canvas) !important; }
.bg-canvas-raised { background-color: var(--canvas-raised) !important; }
.bg-canvas-sunken { background-color: var(--canvas-sunken) !important; }
.bg-sidebar       { background-color: var(--sidebar) !important; }
.text-ink-1       { color: var(--ink-1) !important; }
.text-ink-2       { color: var(--ink-2) !important; }
.text-ink-3       { color: var(--ink-3) !important; }
.text-ink-4       { color: var(--ink-4) !important; }
.border-line         { border-color: var(--line) !important; }
.border-line-subtle  { border-color: var(--line-subtle) !important; }
.border-line-strong  { border-color: var(--line-strong) !important; }


/* =============================================================================
   21. View Transitions API — cross-document page fades (Slice 8)

   Opt into the native browser cross-document fade for any same-origin
   click between pages. Where supported (Chrome 126+, Safari TP, Firefox
   behind a flag), the old page cross-fades to the new page over ~200ms.
   Where unsupported, the transition is skipped — no fallback needed, no
   JS shim. This is the single most "billion-dollar" interaction polish
   that's free at the platform level: no per-link wiring, just a CSS
   declaration.

   `same-origin` so external links (DOL PDF previews, Apollo profile pages)
   don't get a fade — only internal navigation. Duration tuned to match
   our --dur-base (160ms) so transitions feel consistent with in-page
   animations like modal slides.
   ============================================================================= */

@view-transition {
  navigation: auto;
}

::view-transition-old(root),
::view-transition-new(root) {
  animation-duration: var(--dur-base, 160ms);
  animation-timing-function: var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

/* Named transitions on the page hero title — when navigating between
   pages, the title smoothly fades through its own animation lane while
   the rest of the page does the root crossfade. Linear-style. */
.page-hero__title {
  view-transition-name: page-hero-title;
}

/* Sidebar nav active state shares a transition lane — the active
   pill smoothly travels between nav items on persona switch. */
.nav-item.active {
  view-transition-name: nav-active;
}


/* =============================================================================
   22. Reduced-motion respect (Slice 8)

   prefers-reduced-motion: reduce  -> remove all motion. Required for
   accessibility. Every premium tool gates animations behind this; this
   block centralizes the discipline so future additions inherit it.

   We DON'T set `transition: none` on inputs/buttons because color/bg
   changes without transitions read JANK on hover (the eye expects SOME
   easing on color shifts; instant is uncanny). Instead: kill the LONG
   motions (modals, drawers, drag, view transitions) and keep micro-color
   transitions at half-duration so they still feel "smoothed" not "off".

   Same pattern Stripe uses (verified in Stripe Dashboard inspect).
   ============================================================================= */

@media (prefers-reduced-motion: reduce) {
  /* View Transitions API — disable cross-page fades entirely */
  @view-transition {
    navigation: none;
  }
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }

  /* Disable all keyframe animations (skeleton shimmer, dot pulse, etc.) */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
  }

  /* Halve the duration on the workhorse transitions so they still feel
     smoothed, never abrupt. Override our motion tokens locally. */
  :root {
    --dur-fast: 60ms;
    --dur-base: 80ms;
    --dur-slow: 120ms;
  }

  /* Skeleton shimmer becomes a static gray block. Movement-free. */
  .skel {
    animation: none;
    background: #ECEEF2;
  }

  /* Dot pulse becomes a solid dot. */
  .dot-pulse {
    animation: none;
  }
}


/* =============================================================================
   23. Print stylesheet — audit-firm grade (Slice 8)

   The platform is used by retirement-plan auditors. The single most
   common physical artifact is a printed audit packet — and it's the
   only surface a partner ever shows a client in person. Generic web
   print is awful: sidebar prints across the top, color cards eat ink,
   tables clip mid-row at page breaks.

   This block treats print as a first-class theme:

     - Hide all chrome (sidebar, topbar, action buttons, peek cards,
       command palette, notification bell — anything interactive)
     - Switch body to serif (Source Serif 4 if loaded, else georgia)
       at 10.5pt with generous line-height — reads as a formal report
     - Force ink-black on white. Discard gradients. Discard hover
       backgrounds. Mute accent to gray.
     - Force tabular figures everywhere (financial print discipline)
     - Page-break-before on .page-hero so each section starts cleanly
     - Page-break-inside: avoid on .card and .table tbody tr so
       a card doesn't split across page boundaries
     - Print-only footer with timestamp + URL (added in template)
     - .print-only / .screen-only utilities for conditional content
   ============================================================================= */

.print-only { display: none; }

@media print {
  /* Page layout — generous margins, serif body, black ink */
  @page {
    size: letter;
    margin: 0.75in 0.6in 0.85in 0.6in;
  }

  html, body {
    background: #fff !important;
    color: #000 !important;
    font-family: 'Source Serif 4', Georgia, 'Times New Roman', serif !important;
    font-size: 10.5pt;
    line-height: 1.45;
    font-variant-numeric: tabular-nums slashed-zero lining-nums;
    -webkit-print-color-adjust: economy;
    print-color-adjust: economy;
  }

  /* Hide every interactive / chrome surface */
  aside,
  .topbar,
  .btn,
  .pill-mono,
  #notifPanel,
  #notifWrap,
  #cmdK,
  .peek-card,
  .nav-item,
  #liveDot,
  #liveText,
  [x-cloak],
  .skel,
  .segmented,
  .page-hero__actions,
  .screen-only {
    display: none !important;
  }

  .print-only { display: block !important; }

  /* Flatten layout — undo flex/grid wrappers that fight printing */
  .flex, .grid, [class*="lg:grid-cols"] {
    display: block !important;
  }

  main, .content, .container, body > div {
    display: block !important;
    width: 100% !important;
    max-width: none !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  /* Headings — keep editorial weight but switch family to the serif
     stack. Page title in 18pt is right for letter-size print. */
  h1, .h-display, .page-hero__title {
    font-family: 'Source Serif 4', Georgia, serif !important;
    font-size: 18pt !important;
    font-weight: 600 !important;
    color: #000 !important;
    letter-spacing: -0.01em;
    margin: 0 0 6pt 0;
    break-after: avoid;
  }
  h2 { font-size: 13pt; font-weight: 600; margin: 14pt 0 6pt; break-after: avoid; }
  h3 { font-size: 11pt; font-weight: 600; margin: 10pt 0 4pt; break-after: avoid; }

  .page-hero__eyebrow {
    font-size: 8pt;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #555 !important;
    margin-bottom: 2pt;
  }
  .page-hero__sub {
    font-size: 10pt;
    color: #333 !important;
    margin-top: 2pt;
  }

  /* Cards — flatten, no shadows, light border for grouping only */
  .card, .kpi, .hero-band, .card-gradient {
    background: #fff !important;
    box-shadow: none !important;
    border: 1px solid #ccc !important;
    border-radius: 4px !important;
    padding: 10pt !important;
    margin-bottom: 10pt !important;
    break-inside: avoid;
  }

  .page-hero {
    page-break-before: auto;
    border-bottom: 1px solid #000;
    padding-bottom: 8pt;
    margin-bottom: 12pt;
  }

  /* Tables — preserve hierarchy, force black, never split rows */
  .table {
    font-size: 9pt !important;
    border-collapse: collapse !important;
  }
  .table thead th {
    background: #fff !important;
    backdrop-filter: none !important;
    color: #000 !important;
    border-bottom: 1.5pt solid #000 !important;
    padding: 5pt 8pt !important;
    text-transform: uppercase;
    letter-spacing: 0.05em;
  }
  .table tbody td {
    color: #000 !important;
    border-bottom: 0.5pt solid #ccc !important;
    padding: 4pt 8pt !important;
  }
  .table tbody tr {
    break-inside: avoid;
  }
  .table tbody tr:hover {
    background: transparent !important;
  }

  /* Mono IDs stay mono in print — still reads as a system ref */
  .font-mono, code, kbd, samp, .ref-chip, .ref-chip-strong {
    font-family: 'Courier New', Courier, monospace !important;
    font-size: 9.5pt;
    background: transparent !important;
    box-shadow: none !important;
    color: #000 !important;
  }

  /* Pills/badges — outline-only when printed */
  .pill {
    background: transparent !important;
    color: #000 !important;
    border: 0.5pt solid #999 !important;
    padding: 1pt 6pt !important;
    font-size: 8.5pt;
  }

  /* Strip all gradient backgrounds */
  [class*="bg-gradient"],
  [style*="gradient"] {
    background: #fff !important;
    background-image: none !important;
  }

  /* Force every page break opportunity to favor whole sections */
  main > section,
  .card,
  .table {
    break-inside: avoid;
  }

  /* Hyperlinks — print URL after link text in [brackets] for context.
     Skip on internal links so an audit packet doesn't bleed pathnames.
     This is the formal-report convention. */
  a[href^="http"]:after {
    content: " [" attr(href) "]";
    font-size: 8pt;
    color: #555;
    word-break: break-all;
  }
}


/* =============================================================================
   24. Accessibility polish (Slice 8)

   Skip-to-content keyboard link, stronger focus rings on dark surfaces,
   semantic helpers. None of these are visible in the default visual
   pass — they show up for keyboard users and screen readers. Premium
   tools care about this; bottom-tier tools don't.
   ============================================================================= */

/* Skip-to-content link — visually hidden until focused. Press Tab as
   the first keystroke on any page and a button appears that jumps the
   cursor to the main content, skipping the sidebar nav. WCAG 2.4.1. */
.skip-to-content {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 10000;
  padding: 8px 16px;
  background: var(--accent-500);
  color: #fff;
  border-radius: var(--radius-md);
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transform: translateY(-200%);
  transition: transform var(--dur-base) var(--ease-out);
}
.skip-to-content:focus {
  transform: translateY(0);
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* Strengthen focus ring on dark/colored surfaces where the soft accent
   glow can disappear. Used by .hero-band, .card-gradient, and the
   .executive hero band. The double-ring (white inner + accent outer)
   stays visible regardless of background. */
.on-dark *:focus-visible,
.hero-band *:focus-visible,
.card-gradient *:focus-visible {
  outline: none;
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 4px var(--accent-500);
  border-radius: var(--radius-sm);
}

/* Visually hidden but available to screen readers — for labels that
   are obvious to sighted users via icon but need text for VO/JAWS.
   Tailwind ships `sr-only` but we use it widely enough to alias. */
.visually-hidden,
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ============================================================
   §10 — Erisify Copilot chat dock
   Floating bottom-right copilot. Collapsed = 48px circular button;
   expanded = 380px-wide panel with messages + input. Mirrors the
   command palette polish (shadow-pop, rounded-xl, inset ring).
   ============================================================ */
.cb-agent-dock {
  position: fixed;
  bottom: 16px;
  right: 16px;
  z-index: 50;
  font-family: 'Inter var', Inter, ui-sans-serif, system-ui, sans-serif;
}
.cb-agent-fab {
  width: 48px;
  height: 48px;
  border-radius: 24px;
  background: #5B5BD6;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow:
    0 12px 24px -8px rgba(11,13,20,0.20),
    0 6px 12px -4px rgba(11,13,20,0.10);
  border: 0;
  cursor: pointer;
  transition: transform .12s ease-out, box-shadow .12s ease-out;
}
.cb-agent-fab:hover {
  transform: translateY(-1px);
  box-shadow:
    0 16px 28px -8px rgba(11,13,20,0.24),
    0 8px 14px -4px rgba(11,13,20,0.12);
}
.cb-agent-fab:focus-visible {
  outline: 2px solid #5B5BD6;
  outline-offset: 3px;
}

.cb-agent-panel {
  width: 380px;
  max-width: calc(100vw - 32px);
  height: 600px;
  max-height: calc(100vh - 32px);
  background: #fff;
  border-radius: 16px;
  display: flex;
  flex-direction: column;
  box-shadow:
    0 24px 48px -12px rgba(11,13,20,0.22),
    0 8px 16px -6px rgba(11,13,20,0.10),
    inset 0 0 0 1px rgba(11,13,20,0.04);
  overflow: hidden;
}

.cb-agent-head {
  padding: 12px 14px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-bottom: 1px solid #EFF0F3;
  background: #FAFBFC;
}
.cb-agent-avatar {
  width: 24px;
  height: 24px;
  border-radius: 6px;
  background: linear-gradient(135deg, #5B5BD6, #4747C7);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.10);
}

.cb-agent-msgs {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  background: #FFFFFF;
}

.cb-agent-empty {
  padding: 14px;
  border: 1px dashed #E3E5EA;
  border-radius: 10px;
  background: #FAFBFC;
}
.cb-agent-suggest {
  width: 100%;
  text-align: left;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: #fff;
  border: 1px solid #E3E5EA;
  font-size: 12px;
  color: #353945;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.cb-agent-suggest:hover {
  background: #F7F7F9;
  border-color: #D0D3DA;
}

.cb-agent-row {
  display: flex;
  flex-direction: column;
}
.cb-agent-row--user { align-items: flex-end; }
.cb-agent-row--bot  { align-items: flex-start; }

.cb-agent-bubble {
  max-width: 92%;
  padding: 8px 11px;
  border-radius: 10px;
  font-size: 12.5px;
  line-height: 1.5;
  white-space: pre-wrap;
  word-wrap: break-word;
}
.cb-agent-row--user .cb-agent-bubble {
  background: #EEF0FF;
  color: #1A1A52;
}
.cb-agent-row--bot .cb-agent-bubble {
  background: #F7F7F9;
  color: #0B0D14;
}
.cb-agent-bubble--typing {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 10px 12px;
}
.cb-agent-dot {
  width: 6px;
  height: 6px;
  border-radius: 3px;
  background: #9CA1AE;
  display: inline-block;
  animation: cbAgentDotPulse 1.2s ease-in-out infinite;
}
@keyframes cbAgentDotPulse {
  0%, 80%, 100% { opacity: .25; transform: translateY(0); }
  40%           { opacity: 1;   transform: translateY(-2px); }
}

.cb-agent-toolcalls {
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  max-width: 92%;
}
.cb-agent-toolcall {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 6px;
  background: #FAFBFC;
  border: 1px solid #EFF0F3;
  font-size: 11px;
  color: #6A6F7B;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  min-width: 0;
  overflow: hidden;
}
.cb-agent-toolcall span:last-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cb-agent-form {
  border-top: 1px solid #EFF0F3;
  padding: 10px 12px 12px;
  background: #fff;
}
.cb-agent-input {
  width: 100%;
  resize: none;
  padding: 8px 10px;
  border-radius: 8px;
  border: 1px solid #E3E5EA;
  font-size: 13px;
  font-family: inherit;
  background: #fff;
  color: #0B0D14;
  outline: none;
  transition: border-color .12s, box-shadow .12s;
}
.cb-agent-input:focus {
  border-color: #5B5BD6;
  box-shadow: 0 0 0 3px rgba(91,91,214,0.12);
}
.cb-agent-input:disabled { background: #FAFBFC; color: #9CA1AE; cursor: not-allowed; }

.cb-agent-form-foot {
  margin-top: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.cb-agent-send {
  width: 28px;
  height: 28px;
  border-radius: 14px;
  background: #5B5BD6;
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  cursor: pointer;
}
.cb-agent-send:disabled { background: #D0D3DA; cursor: not-allowed; }
.cb-agent-send:hover:not(:disabled) { background: #4747C7; }

/* Inline proposal card — the "are you sure?" surface for agent write
   actions (Slice 2). Lives in the assistant-side row of the chat
   thread; flips from pending → confirmed/cancelled/error in place. */
.cb-agent-proposal {
  margin-top: 4px;
  max-width: 100%;
  border: 1px solid #DDE0FF;
  background: #EEF0FF;
  border-radius: 10px;
  padding: 10px;
  font-size: 12px;
}
.cb-agent-proposal-head {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: #1A1A52;
  font-size: 12.5px;
  margin-bottom: 6px;
}
.cb-agent-proposal-body {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 10px;
  row-gap: 3px;
  margin: 0 0 8px;
  padding: 8px 10px;
  background: #FFFFFF;
  border-radius: 8px;
  border: 1px solid rgba(11,13,20,0.04);
}
.cb-agent-proposal-row { display: contents; }
.cb-agent-proposal-body dt {
  font-size: 11px;
  color: #6A6F7B;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.cb-agent-proposal-body dd {
  font-size: 12.5px;
  color: #0B0D14;
  word-wrap: break-word;
  min-width: 0;
}
.cb-agent-proposal-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}
.cb-agent-btn {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 10px;
  border-radius: 6px;
  font-size: 12px;
  background: #FFFFFF;
  border: 1px solid #D0D3DA;
  color: #353945;
  cursor: pointer;
  transition: background .12s, border-color .12s;
}
.cb-agent-btn:hover { background: #FAFBFC; border-color: #9CA1AE; }
.cb-agent-btn--primary {
  background: #5B5BD6;
  border-color: #5B5BD6;
  color: #fff;
}
.cb-agent-btn--primary:hover { background: #4747C7; border-color: #4747C7; }
.cb-agent-proposal-status {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  padding: 4px 8px;
  border-radius: 6px;
  background: #FFFFFF;
}
.cb-agent-proposal-status--ok     { color: #047857; }
.cb-agent-proposal-status--cancel { color: #6A6F7B; }
.cb-agent-proposal-status--err    { color: #B91C1C; }
.cb-agent-proposal[data-state="confirmed"] { background: #ECFDF5; border-color: #A7F3D0; }
.cb-agent-proposal[data-state="cancelled"] { background: #F7F7F9; border-color: #D0D3DA; opacity: .85; }
.cb-agent-proposal[data-state="error"]     { background: #FEF2F2; border-color: #FCA5A5; }

/* Hide the dock while Alpine is still mounting so we don't flash the
   panel open before x-show evaluates. */
[x-cloak] { display: none !important; }

