/* Sundae design system — tokens + shared components.
   Working accent: Sundae blue. Lavender is the rationed signature accent.
   State speaks in tint+ink pairs. Red is reserved for STOP/DNC/consent-block. */
:root {
  color-scheme: light;
  /* Ground + ink (Phantom-warm paper, confident near-black) */
  --paper: #fffdf8;
  --surface: #ffffff;
  --surface-2: #faf7f0;
  --ink: #1c1c1c;
  --muted: #6e6e6e;
  --line: #eceae4;
  --line-2: #dcdad2;
  --nav: #fdfbf5;
  --nav-ink: #1c1c1c;
  --nav-muted: #6e6e6e;
  /* Working accent (blue) + rationed signature (lavender) */
  /* #3061d9, not #3d6fe0: the brighter blue was 4.38:1 on the warm paper —
     under the 4.5:1 AA floor for the 11px eyebrows/kickers that consume it.
     See tests/test_design_contrast.py. */
  --accent: #3061d9;
  --accent-ink: #ffffff;
  --accent-deep: #1e3a6e;
  --accent-soft: #e3ebfd;
  --accent-faint: #f2f6fe;
  --accent-line: rgba(48, 97, 217, .38);
  --lav: #ab9ff2;
  --lav-soft: #e2dffe;
  --lav-ink: #3c315b;
  /* Positive state: pale tint surface + deep matched ink (Phantom pattern).
     `-dot` variants are darker so a status dot clears 3:1 on its own tint
     (tests/test_design_contrast.py); the vivid parents stay for fills/rails.
     `--go-text` is the green for small TEXT (a good rate, a SOLD mark): the
     dot green is a 3:1 mark, not a 4.5:1 ink (a11y audit 2026-09-30). */
  --go: #2fae4e;
  --go-dot: #1f9440;
  --go-text: #177a34;
  --go-soft: #dbf9df;
  --go-ink: #0a3d18;
  --lav-dot: #7d6ce0;
  /* Restrained data-visualization palette */
  --viz-blue: #2f6fdb; --viz-cyan: #1696a7; --viz-gold: #b07c0e; --viz-violet: #7657c8;
  /* Warnings are amber. Red is ONLY for STOP/DNC/consent-block. */
  --warn: #4a3b00;
  --warn-soft: #fff3cd;
  --warn-dot: #a97a00;
  --stop: #b3123a;
  --stop-soft: #ffdadc;
  /* Garnish: sticker yellow + hanko vermilion (see .sticker/.hanko/.seal) */
  --sticker-yellow: #fcc20f;
  --vermilion: #d8432f;
  /* Type */
  --font-sans: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI",
    "Helvetica Neue", Arial, sans-serif;
  --font-script: "SignPainter", "SignPainter-HouseScript", "Snell Roundhand",
    "Brush Script MT", cursive;
  --display-weight: 700;
  /* Shape + depth */
  --radius: 9px;
  --radius-lg: 14px;
  --shadow: 0 1px 2px rgba(28, 28, 28, .04), 0 8px 24px rgba(28, 28, 28, .04);
  --focus-ring: 0 0 0 3px rgba(48, 97, 217, .3);
  /* Rhythm */
  --tap: 44px;
  --gap: 16px;
}
/* Dark theme — DELIBERATELY UNUSED. No page opts in: every screen, dialer
   included, ships on the light paper ground so the product reads as one
   product. These tokens stay as the seam an opt-in dark preference would hang
   from later. Do not wire a screen to it without that preference. */
[data-theme="dark"] {
  color-scheme: dark;
  --paper: #0f0f0f;
  --surface: #1c1c1c;
  --surface-2: #202020;
  --ink: #fffdf8;
  --muted: #b4b4b4;
  --line: rgba(255, 255, 255, .12);
  --line-2: rgba(255, 255, 255, .2);
  --accent: #6ca0fb;
  --accent-ink: #0f1a33;
  --accent-deep: #cdddfa;
  --accent-soft: rgba(108, 160, 251, .14);
  --accent-faint: rgba(108, 160, 251, .08);
  --accent-line: rgba(108, 160, 251, .45);
  --lav-soft: rgba(171, 159, 242, .16);
  --lav-ink: #e2dffe;
  --go-soft: rgba(69, 232, 99, .12);
  --go-text: #7fe09a;
  --go-ink: #dbf9df;
  --warn: #ffe29a;
  --warn-soft: rgba(255, 214, 0, .12);
  --stop: #ff8d97;
  --stop-soft: rgba(255, 0, 55, .14);
  --shadow: 0 24px 70px rgba(0, 0, 0, .28);
  --focus-ring: 0 0 0 3px rgba(108, 160, 251, .35);
}
/* Base */
* { box-sizing: border-box; }
html, body { margin: 0; min-height: 100vh; }
body {
  color: var(--ink);
  background: var(--paper);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
button, input, select, textarea { font: inherit; color: inherit; }
:focus-visible { outline: none; box-shadow: var(--focus-ring); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}
/* Layout shell */
.shell { width: min(1180px, 100% - 32px); margin: 0 auto; padding: 20px 0 72px; }
.shell-narrow { width: min(560px, 100% - 32px); margin: 0 auto; padding: 20px 0 72px; }
.stack > * + * { margin-top: var(--gap); }
.row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.row-between {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
}
/* App chrome: brand + screen name + session slot */
.appbar {
  display: flex; align-items: center; justify-content: space-between; gap: 14px;
  min-height: 64px; padding: 10px 0; margin-bottom: 20px; border-bottom: 1px solid var(--line);
}
.appbar-brand { display: flex; align-items: baseline; gap: 10px; min-width: 0; }
.appbar-name { font-weight: 800; font-size: 17px; letter-spacing: -.02em; }
.appbar-screen { color: var(--muted); font-size: 14px; }
.appbar-screen::before { content: "/ "; color: var(--line); }
/* Screens that carry the sidebar name themselves here: the wordmark is in the
   sidebar and is never repeated in the page header. */
.appbar-screen-lead {
  color: var(--muted); font-size: 12px; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase;
}
.appbar-screen-lead::before { content: none; }
.appbar-session {
  display: flex; align-items: center; gap: 9px; flex-wrap: wrap; justify-content: flex-end;
}
.appbar-session .who { color: var(--muted); font-size: 13px; }
.brand-lockup {
  display: inline-flex; align-items: center; color: var(--ink); text-decoration: none;
}
.brand-logo-link { display: inline-flex; align-items: center; text-decoration: none; }
.brand-logo-crop {
  display: block; flex: 0 0 auto;
}
.brand-logo {
  display: block; height: 44px; width: auto;
}
/* Conventional CRM frame: persistent navigation, working canvas, record.
   One implementation for every screen — the dialer included. */
.crm-shell {
  min-height: 100vh; min-height: 100dvh;
  display: grid; grid-template-columns: 236px minmax(0, 1fr);
}
.crm-nav {
  position: sticky; top: 0; height: 100vh; height: 100dvh; overflow-y: auto;
  display: flex; flex-direction: column; gap: 4px; padding: 16px 14px;
  border-right: 1px solid var(--line); background: var(--nav); color: var(--nav-ink);
}
.crm-nav-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
/* The brand lockup is the bare logo on the nav ground — no plate (Blake 2026-09-01). */
.crm-nav .brand-lockup {
  margin: 0 2px 14px; padding: 4px 2px;
}
.crm-nav-links, .crm-nav-hubs {
  display: flex; flex-direction: column; gap: 4px; min-width: 0;
}
.crm-lead-finder {
  position: relative; display: flex; align-items: center; margin: 4px 4px 8px;
}
.crm-lead-finder input {
  width: 100%; min-width: 0; min-height: 40px; padding: 7px 42px 7px 11px;
  border: 1px solid var(--line-2); border-radius: 10px;
  background: var(--surface); color: var(--nav-ink);
}
.crm-lead-finder input::placeholder { color: var(--nav-muted); opacity: 1; }
.crm-lead-finder input:focus {
  border-color: var(--accent); background: var(--surface);
}
.crm-lead-finder-shortcut {
  position: absolute; right: 7px; display: inline-flex; align-items: center;
  min-height: 22px; padding: 0 5px; border: 1px solid var(--line-2);
  border-bottom-width: 2px; border-radius: 5px; background: var(--surface);
  color: var(--nav-muted); font-family: var(--font-sans); font-size: 10px; line-height: 1;
}
/* The command palette: a light card over the dark nav. Options are the nav's
   own destinations; the last rows search leads (form submit) and the board. */
.crm-palette {
  position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 40;
  padding: 4px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--surface); box-shadow: var(--shadow);
  max-height: 60vh; overflow: auto;
}
.crm-palette-option {
  display: flex; align-items: center; gap: 8px; min-height: 36px;
  padding: 6px 10px; border-radius: 5px; color: var(--ink); cursor: pointer;
}
.crm-palette-option .muted { margin-left: auto; font-size: 11px; }
.crm-palette-option[aria-selected="true"], .crm-palette-option:hover {
  background: var(--accent-soft);
}
/* Six jobs, flat (owner, 2026-09-21): no group headers, no rails, no folds
   -- the nav is a map of jobs, and everything else is a tab inside one. */
/* Workload badge: a quiet number, warm amber family, no alarm color ever. */
.crm-nav-count {
  margin-left: auto; padding: 1px 8px; border-radius: 999px; font-size: 11px;
  font-weight: 700; line-height: 1.6; background: var(--warn-soft);
  border: 1px solid #f0dfa8; color: var(--warn);
}
/* The phone disclosure. Absent from the desktop sidebar, where the whole list
   is already on screen and a toggle would be a click tax. */
.crm-nav-toggle {
  display: none; align-items: center; gap: 8px; min-height: var(--tap);
  padding: 0 14px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); color: var(--ink); font-size: 14px; font-weight: 650;
  cursor: pointer;
}
.crm-nav-toggle-bars {
  width: 16px; height: 2px; background: currentColor; border-radius: 2px;
  box-shadow: 0 -5px 0 currentColor, 0 5px 0 currentColor;
}
.crm-nav-link {
  display: flex; align-items: center; min-height: var(--tap); padding: 7px 12px;
  border-radius: 8px; color: var(--nav-muted); font-weight: 550; text-decoration: none;
  transition: background .15s ease, color .15s ease, box-shadow .15s ease;
}
.crm-nav-link:hover {
  color: var(--nav-ink); background: var(--surface);
  box-shadow: inset 2px 0 0 var(--accent);
}
.crm-nav-link.active {
  color: var(--accent-deep); background: var(--accent-soft); font-weight: 700;
  box-shadow: inset 2px 0 0 var(--accent);
}
/* The operator's own entry at the foot of the nav, every role: initials in a
   quiet disc, the name beside it (filled by the shell from the session). */
.crm-nav-profile {
  display: flex; align-items: center; gap: 10px; min-height: var(--tap);
  padding: 6px 10px; border-radius: 8px; color: var(--nav-ink); font-weight: 600;
  font-size: 13px; text-decoration: none;
}
.crm-nav-profile:hover, .crm-nav-profile[aria-current="page"] { background: var(--surface); }
.crm-nav-avatar {
  display: inline-grid; place-items: center; width: 28px; height: 28px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-deep); font-size: 11px; font-weight: 800;
}
.crm-nav-avatar:empty { background: var(--line-2); }
/* A hub's tab strip: the rhythm tabs, as links, at the top of the hub's pages.
   The current tab is the page you are on. */
.hub-tabs .tab[aria-current="page"] {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
body[data-sundae-role="dialer"] [data-manager-only],
body[data-sundae-role="closer"] [data-manager-only],
body[data-sundae-role="sales_ops"] [data-manager-only],
body[data-sundae-role="viewer"] [data-manager-only] { display: none; }
body[data-sundae-role="manager"] [data-admin-only],
body[data-sundae-role="executive"] [data-admin-only] { display: none; }
body[data-sundae-role="viewer"] .crm-nav-link:not([href="/scoreboard"]),
body[data-sundae-role="viewer"] .hub-tabs,
body[data-sundae-role="viewer"] .crm-lead-finder { display: none; }
/* The setter presentation (owner, 2026-09-21): a dialer session (lite or
   not) and a manager's "View as: Setter" lens see exactly two items,
   Dashboard then Appointments, and no hub tab strip (their Appointments page
   is the three-zone board). Keyed on the VIEWED role the shell stamps
   (setRole), so the lens and the real seat share one rule; the lead finder
   steps aside. The appointments-only flag keeps its redirect in
   applyLiteMode. The lens rewrites hrefs to carry ?view_as=, so matches are
   on the path prefix. */
body[data-sundae-role="dialer"]
  .crm-nav-link:not([href^="/dashboard"]):not([href^="/appointments"]),
body[data-sundae-role="dialer"] .hub-tabs,
body[data-sundae-role="dialer"] .crm-lead-finder { display: none; }
body[data-sundae-role="dialer"] .crm-nav-link[href^="/dashboard"] { display: flex; }
/* View-as: the manager lens. Ships hidden on every screen; only
   Sundae.applyViewAs reveals it, keyed to the server-resolved session role. */
.crm-view-as { margin: 12px 4px 2px; padding: 10px 8px 0; border-top: 1px solid var(--line); }
.crm-view-as-label {
  display: block; color: var(--nav-muted); font-size: 10px; font-weight: 800;
  letter-spacing: .13em; text-transform: uppercase;
}
.crm-view-as-options { display: flex; gap: 4px; margin-top: 6px; }
.crm-view-as-option {
  flex: 1; min-height: 36px; padding: 4px 2px; border: 1px solid var(--line-2);
  border-radius: 7px; background: var(--surface); color: var(--nav-muted);
  font-size: 12px; font-weight: 650; cursor: pointer;
}
.crm-view-as-option:hover { color: var(--nav-ink); }
.crm-view-as-option[aria-pressed="true"] {
  background: var(--accent-soft); border-color: var(--accent-line);
  color: var(--accent-deep); font-weight: 700;
}
/* The lens chip stays lavender: informational, never an alarm. */
.view-as-banner { border-color: var(--lav); background: var(--lav-soft); color: var(--lav-ink); }
.view-as-banner a { color: inherit; font-weight: 700; }
.crm-nav-session {
  margin-top: auto; padding: 14px 8px 0; border-top: 1px solid var(--line);
}
.crm-nav-session .muted { color: var(--nav-muted); }
.crm-nav-divider, .crm-nav-current { display: none; }
.crm-main { min-width: 0; padding: 0 24px 56px; }
/* Working width: lines, forms and tables stop stretching on wide monitors. */
.crm-main > * { width: min(1240px, 100%); }
.crm-main-narrow > * { width: min(720px, 100%); }
/* Signed-out pages are product access, not a disabled CRM. Keep the full
   navigation out of the way until an authenticated session exists. */
body:has(#screen-login:not(.hidden)) .crm-shell { grid-template-columns: minmax(0, 1fr); }
body:has(#screen-login:not(.hidden)) .crm-nav,
body:has(#screen-login:not(.hidden)) .hub-tabs,
body:has(#screen-login:not(.hidden)) .appbar { display: none; }
body:has(#screen-login:not(.hidden)) .crm-main {
  min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 32px;
}
body:has(#screen-login:not(.hidden)) #screen-login { width: min(460px, 100%); }
body:has(#screen-login:not(.hidden)) .crm-main::before {
  content: ""; position: fixed; top: 26px; left: 28px; width: 170px; height: 58px;
  background: url("/assets/sundae-logo.png") center / contain no-repeat;
}
/* Session boot: the first paint of every screen. Not the login form, not a
   blank page — a calm branded ground while the session cookie is checked. */
.session-boot {
  position: fixed; inset: 0; z-index: 50; display: none; place-items: center;
  background: var(--paper);
}
body[data-session="checking"] .session-boot { display: grid; }
.session-boot-inner { display: grid; justify-items: center; gap: 14px; }
.session-boot-dot {
  width: 10px; height: 10px; border-radius: 50%; background: var(--accent);
  animation: session-boot-pulse 1.5s ease-in-out infinite;
}
@keyframes session-boot-pulse { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
.session-boot-copy { margin: 0; color: var(--muted); font-size: 13.5px; }
/* Skeletons instead of spinner theater: the shape of what is coming, once. */
.skeleton {
  border-radius: var(--radius); background: var(--surface-2);
  animation: skeleton-breathe 1.6s ease-in-out infinite;
}
@keyframes skeleton-breathe { 0%, 100% { opacity: .5; } 50% { opacity: .9; } }
.skeleton-line { height: 12px; margin: 10px 0; }
.skeleton-line.short { width: 55%; }
.skeleton-tile { height: 64px; }
/* Stale-while-revalidate: the last good data stays on screen, quietly. */
.is-refreshing { opacity: .68; transition: opacity .15s ease; }
/* A panel that could not load says so and offers the one fix. Amber, never red. */
.retry-box {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
}
/* Type scale: big bold display, tight leading, roomy body */
h1, .display {
  margin: 0; font-size: clamp(30px, 5vw, 46px); line-height: 1.04;
  letter-spacing: -.03em; font-weight: var(--display-weight);
}
h2 { margin: 0; font-size: 19px; letter-spacing: -.015em; font-weight: 700; }
/* On a working screen the title is a title, not a poster; the display
   scale stays for public pages. Bare links read as links, quietly. */
.crm-main h1:not(.appbar-screen) { font-size: clamp(26px, 2.4vw, 32px); }
:where(a:not([class])) {
  color: var(--accent); text-underline-offset: 2px; text-decoration-color: var(--accent-line);
}
h3 { margin: 0; font-size: 15px; font-weight: 650; }
.lede { margin: 12px 0 0; max-width: 620px; color: var(--muted); font-size: 16px; }
.eyebrow {
  margin: 0 0 8px; color: var(--accent); font-size: 12px; font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
}
.small { font-size: 13px; }
.muted { color: var(--muted); }
.num { font-variant-numeric: tabular-nums; }
/* Buttons — one obvious primary action per screen. Always pills. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: var(--tap); padding: 0 20px; border-radius: 999px;
  border: 1px solid var(--line-2); background: var(--surface); color: var(--ink);
  font-weight: 650; cursor: pointer; text-decoration: none;
  transition: border-color .15s ease, background .15s ease, transform .15s ease;
}
.btn:hover { border-color: var(--accent-line); transform: translateY(-1px); }
.btn:active { transform: none; }
.btn:disabled { opacity: .5; cursor: default; transform: none; }
.btn-primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn-primary:hover { background: #2f5cc4; border-color: #2f5cc4; }
.btn-quiet { background: transparent; border-color: transparent; }
.btn-quiet:hover { border-color: var(--line-2); }
/* STOP-only. Never use for cancel/close/ordinary destructive-ish actions. */
.btn-stop { background: var(--stop); border-color: var(--stop); color: #fff; }
.btn-small { min-height: 34px; padding: 0 14px; font-size: 13px; border-radius: 999px; }
.btn-block { width: 100%; }
/* Status pills — tint surface + deep matched ink, never raw accent text. */
.pill {
  display: inline-flex; align-items: center; gap: 7px; min-height: 28px;
  padding: 2px 12px; border-radius: 999px; border: 1px solid var(--line);
  background: var(--surface); color: var(--muted); font-size: 13px; font-weight: 550;
}
.pill::before {
  content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted);
}
.pill-ok { color: var(--go-ink); border-color: #c4ecca; background: var(--go-soft); }
.pill-ok::before { background: var(--go-dot); }
.pill-warn { color: var(--warn); border-color: #f0dfa8; background: var(--warn-soft); }
.pill-warn::before { background: var(--warn-dot); }
.insight-stack { display: grid; gap: 10px; }
.insight-now {
  padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface);
}
.insight-now h2 { margin: 4px 0 6px; font-size: 18px; }
.insight-cta {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: var(--tap); padding: 0 12px;
}
.insight-work { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.insight-work .insight-cta {
  display: inline-block; max-width: 100%; min-height: 34px; line-height: 32px; padding: 0 12px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface);
  color: var(--ink); font-size: 13px; text-decoration: none;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.insight-more { display: grid; gap: 8px; }
/* STOP/DNC/consent-block only. */
.pill-stop { color: var(--stop); border-color: #f2c3c6; background: var(--stop-soft); }
.pill-stop::before { background: var(--stop); }
/* Informational (blue) and the rationed lavender signature (VIP/highlight). */
.pill-info { color: var(--accent-deep); border-color: #cdddfa; background: var(--accent-soft); }
.pill-info::before { background: var(--accent); }
.pill-vip { color: var(--lav-ink); border-color: #d8d2fa; background: var(--lav-soft); }
.pill-vip::before { background: var(--lav-dot); }
/* A live indicator breathes; everything else holds still. */
.pill-live::before { animation: sundae-breathe 2.4s ease-in-out infinite; }
/* League tier chips + the streak flame: one vocabulary on /dashboard,
   /scoreboard and /dialer (rep standing, 2026-08-29). Bronze rides the amber
   pair, never red. Pages provide the `#i-flame` <symbol> themselves. */
.tier {
  display: inline-flex; align-items: center; gap: 5px; padding: 1px 8px;
  border-radius: 999px; border: 1px solid transparent; font-size: 10.5px;
  font-weight: 750; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap;
}
.tier::before {
  content: ""; width: 6px; height: 6px; border-radius: 2px; background: currentColor; opacity: .7;
}
.tier-bronze { background: var(--warn-soft); color: var(--warn); border-color: #f0dfa8; }
.tier-silver { background: var(--surface-2); color: var(--muted); border-color: var(--line-2); }
.tier-gold { background: #f7e7a9; color: #6e4c00; }
.tier-diamond { background: var(--accent-soft); color: var(--accent-deep); border-color: #cdddfa; }
.streak { white-space: nowrap; }
.streak .flame {
  width: 14px; height: 14px; vertical-align: -2px; margin-right: 3px; fill: var(--viz-gold);
}
.streak-none .flame { fill: var(--line-2); }
/* Cards + stat tiles (summary first, detail on demand) */
.card {
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface); box-shadow: var(--shadow); padding: 18px;
}
.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.card-head-text { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; min-width: 0; }
.card-callout { border-color: var(--accent-line); background: var(--accent-faint); }
/* Cards never touch: sibling cards get the system gap without a wrapper;
   grids and rows already space their own children. */
.crm-main :where(.card) + :where(.card) { margin-top: var(--gap); }
.crm-main :is([class*="grid"], .row, .row-between) > .card + .card { margin-top: 0; }
.card .card { box-shadow: none; background: var(--surface-2); }
.card .insight-now { padding: 0; border: 0; background: transparent; }
.tab-panel {
  display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap); align-content: start;
}
/* Section tabs: quiet pills, the selected one wears the accent tint. */
.tabs {
  display: flex; gap: 4px; flex-wrap: wrap; margin-bottom: 20px;
  padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.tab {
  display: inline-flex; align-items: center; gap: 8px; min-height: var(--tap); padding: 0 14px;
  border-radius: 999px; border: 1px solid transparent; background: transparent;
  color: var(--muted); font-weight: 650; font-size: 13.5px; cursor: pointer; text-decoration: none;
}
.tab:hover { color: var(--ink); background: var(--surface-2); }
.tab[aria-selected="true"] {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.tab .count { font-variant-numeric: tabular-nums; font-weight: 600; }
/* Page head under the bar: one title, one line of intent. */
.page-head { margin: 2px 0 14px; }
.page-title {
  margin: 0; font-size: 28px; line-height: 1.1; letter-spacing: -.025em; font-weight: 700;
}
.page-head .lede { margin-top: 4px; font-size: 14.5px; }
.section-hint { margin: 0 0 14px; max-width: 72ch; color: var(--muted); font-size: 12.5px; }
.inset {
  margin: 4px 0 18px; padding: 16px 18px; border: 1px solid var(--line);
  border-radius: var(--radius); background: var(--surface-2);
}
/* Forms: fields share a row and the button sits with them. */
.form-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px 16px; align-items: end;
}
.form-grid .field { margin: 0; }
.form-action { display: flex; align-items: flex-end; }
.form-foot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 14px; }
.stat-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px;
}
.stat {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 12px 14px;
}
.stat b { display: block; font-size: 24px; letter-spacing: -.02em; line-height: 1.15; }
.stat span { color: var(--muted); font-size: 12.5px; }
/* Tables — quiet rows, no zebra noise */
.table-scroll { overflow-x: auto; }
table.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th {
  text-align: left; padding: 8px 12px; color: var(--muted); font-size: 12px;
  font-weight: 650; letter-spacing: .05em; text-transform: uppercase;
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.table td { padding: 11px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.table tr:last-child td { border-bottom: 0; }
/* Cells: two-line stacks, small pills, actions pinned to the right edge. */
.table .pill { min-height: 24px; padding: 0 10px; font-size: 12px; gap: 6px; }
.pills { display: flex; gap: 5px; flex-wrap: wrap; }
.cell-stack { display: grid; gap: 2px; min-width: 0; }
.cell-stack strong { font-weight: 650; }
.cell-stack .sub {
  color: var(--muted); font-size: 12.5px; line-height: 1.4; overflow-wrap: anywhere;
}
th.col-actions, td.col-actions { width: 1%; white-space: nowrap; text-align: right; }
.actions { display: flex; gap: 6px; flex-wrap: wrap; }
td.col-actions .actions { justify-content: flex-end; flex-wrap: nowrap; }

/* Garnish — the Dell '96 inventory. Discipline: at most ONE of each per
   screen; these are punctuation, not furniture. */
.sticker {
  display: inline-block; padding: 4px 8px; border: 1px solid var(--ink);
  border-radius: 3px; background: var(--sticker-yellow); color: var(--ink);
  font-weight: 700; font-size: 10.5px; letter-spacing: .02em; white-space: nowrap;
  box-shadow: 2px 2px 0 rgba(28, 28, 28, .85);
  transition: transform .18s ease;
}
.sticker-burst { transform: rotate(-8deg); }
/* Hanko: a small vermilion stamp with a script monogram — the sign-off mark. */
.hanko {
  display: inline-grid; place-items: center; width: 38px; height: 38px;
  border-radius: 7px; background: var(--vermilion); color: #fff;
  font-family: var(--font-script); font-size: 21px; line-height: 1;
  transform: rotate(-4deg);
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, .55), 1px 1px 0 rgba(28, 28, 28, .5);
}
/* Award seal: rotated yellow circle, hard bevel. Scoreboards and milestones. */
.seal {
  display: inline-grid; place-items: center; width: 64px; height: 64px;
  border-radius: 50%; padding: 6px; background: var(--sticker-yellow);
  border: 1px solid var(--ink); box-shadow: 2px 2px 0 rgba(28, 28, 28, .85);
  transform: rotate(8deg); text-align: center; color: var(--ink);
  font-size: 6.5px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; line-height: 1.5;
}
/* Section divider: quiet caps + hairline, the page's zoning system. */
.divider { display: flex; align-items: center; gap: 10px; margin: 26px 0 12px; }
.divider-label {
  font-size: 10.5px; font-weight: 750; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted);
}
.divider-rule { flex: 1; height: 1px; background: var(--line); }
/* Motion — one system: rise on load (opt-in per element), grow for bars,
   breathe for live dots, land for stickers. Reduced-motion kills all of it. */
@keyframes sundae-rise { from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: none; } }
@keyframes sundae-land { from { opacity: 0; transform: rotate(-8deg) scale(.5); }
  to { opacity: 1; transform: rotate(-8deg) scale(1); } }
@keyframes sundae-grow { from { transform: scaleX(0); } }
@keyframes sundae-breathe { 0%, 100% { transform: scale(1); opacity: 1; }
  50% { transform: scale(1.35); opacity: .65; } }
.rise { animation: sundae-rise .55s cubic-bezier(.22, .7, .3, 1) both; }
.rise-2 { animation-delay: .06s; } .rise-3 { animation-delay: .12s; }
.rise-4 { animation-delay: .18s; } .rise-5 { animation-delay: .24s; }
.rise-6 { animation-delay: .3s; }
.sticker-land { animation: sundae-land .6s cubic-bezier(.34, 1.56, .64, 1) .55s both; }
.bar-grow { transform-origin: left center;
  animation: sundae-grow .8s cubic-bezier(.22, .7, .3, 1) .45s both; }

/* Forms */
.field { display: block; margin: 12px 0 0; }
.field > span { display: block; margin-bottom: 5px; color: var(--muted); font-size: 13px; }
.input, input.input, select.input, textarea.input {
  width: 100%; min-height: var(--tap); padding: 10px 14px;
  border: 1px solid var(--line); border-radius: var(--radius); outline: none;
  background: var(--surface); color: var(--ink);
}
textarea.input { min-height: 72px; resize: vertical; }
.input:focus { border-color: var(--accent); box-shadow: var(--focus-ring); }
.hint { margin: 8px 0 0; color: var(--muted); font-size: 12.5px; }
.account-recovery { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line); }
.account-recovery summary {
  display: inline-flex; align-items: center; width: fit-content; min-height: var(--tap);
  cursor: pointer; color: var(--accent);
  font-size: 13px; font-weight: 700; list-style: none;
}
.account-recovery summary::-webkit-details-marker { display: none; }
.account-recovery summary::after { content: " +"; }
.account-recovery[open] summary::after { content: " –"; }
.account-recovery-form { padding-top: 3px; }
.account-recovery [data-recovery-submit] { margin-top: 12px; }
.account-recovery .recovery-accepted { color: var(--accent); }
.field-error { margin: 6px 0 0; color: var(--warn); font-size: 12.5px; }
/* Show/hide control on password fields — quiet, keyboard-first */
.password-box { position: relative; display: block; }
.password-box > .input { padding-right: 54px; }
.password-toggle {
  position: absolute; top: 50%; right: 0; transform: translateY(-50%);
  display: inline-flex; align-items: center; justify-content: center;
  width: var(--tap); height: var(--tap); padding: 0; border: 0; border-radius: 11px;
  background: transparent; color: var(--muted); cursor: pointer;
}
.password-toggle:hover { color: var(--ink); background: var(--surface-2); }
.password-toggle:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.password-toggle .password-toggle-slash { display: none; }
.password-toggle[aria-pressed="true"] .password-toggle-slash { display: block; }
/* Banners — calm by default */
.banner {
  padding: 12px 15px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface-2); color: var(--muted); font-size: 13.5px;
}
.banner-ok {
  border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent);
}
.banner-warn { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }
/* STOP/DNC/consent-block only. */
.banner-stop { border-color: var(--stop); background: var(--stop-soft); color: var(--stop); }
/* Utility */
.hidden { display: none !important; }
.divider { border: 0; border-top: 1px solid var(--line); margin: var(--gap) 0; }

/* Calendar primitives — shared by /schedule and /availability. Token-only,
   no new colors: open/booked reuse the accent + muted pair every other
   component already uses, closed is a quieter dashed variant of the same
   muted family, and the coverage warning reuses --warn like every other
   amber in the system. */
.cal-chip {
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  min-height: 26px; padding: 3px 9px; border-radius: 8px; font-size: 11px;
  font-weight: 650; border: 1px solid var(--accent-line); background: var(--accent-soft);
  color: var(--accent);
}
.cal-chip-open { cursor: pointer; }
.cal-chip-booked { border-color: var(--line); background: var(--surface-2); color: var(--muted); }
.cal-chip-closed {
  border-style: dashed; background: transparent; color: var(--muted); opacity: .72;
}
.cal-lane { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cal-lane-name { font-weight: 650; font-size: 13px; }
.cal-cap {
  display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 1px 9px;
  border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font-size: 11px; font-weight: 650; font-variant-numeric: tabular-nums;
}
.cal-cap-open {
  border-color: var(--accent-line); background: var(--accent-soft); color: var(--accent);
}
.cal-warn {
  display: inline-flex; align-items: center; min-height: 22px; padding: 1px 9px;
  border-radius: 999px; border: 1px solid var(--warn); background: var(--warn-soft);
  color: var(--warn); font-size: 11px; font-weight: 650;
}
.cal-toggle {
  display: inline-flex; align-items: center; justify-content: center; min-height: 30px;
  padding: 0 12px; border-radius: 999px; border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font-size: 11px; font-weight: 700; letter-spacing: .03em;
  text-transform: uppercase; cursor: pointer;
}
.cal-toggle[aria-pressed="true"] {
  border-color: var(--accent); background: var(--accent-soft); color: var(--accent);
}
/* Two-step confirm state, shared by `.cal-toggle` and `.cal-chip`: the same
   destructive action never fires on the click that arms it. Declared last so
   it wins the tie against the other same-specificity modifiers above. */
.cal-armed { border-color: var(--warn); background: var(--warn-soft); color: var(--warn); }

/* Phone-first adjustments */
@media (max-width: 640px) {
  .shell, .shell-narrow { width: min(100% - 24px, 1180px); padding-top: 12px; }
  .appbar { flex-wrap: wrap; }
  .btn { width: 100%; }
  .btn-small, .appbar .btn { width: auto; }
  /* A roster table stacks each row (head off, cells in a column, actions
     wrapping) so no nowrap cell can push the page past a phone's width. */
  .table-stack thead { display: none; }
  .table-stack tr {
    display: grid; gap: 6px; padding: 12px 0; border-bottom: 1px solid var(--line);
  }
  .table-stack td { display: block; padding: 0; border: 0; }
  .table-stack td.col-actions { width: auto; text-align: left; white-space: normal; }
  .table-stack td.col-actions .actions { justify-content: flex-start; flex-wrap: wrap; }
  body:has(#screen-login:not(.hidden)) .crm-main{place-items:start center;padding:104px 16px 28px}
  body:has(#screen-login:not(.hidden)) .crm-main::before{top:20px;left:20px;width:140px;height:48px}
}
/* Phones: the sidebar becomes a compact top bar. A 220px column would eat
   more than half a 390px screen, so below this breakpoint the destinations
   collapse behind one 44px disclosure and the canvas keeps the whole width.
   Closed is the default on every load — the work is what the screen is for. */
@media (max-width: 820px) {
  .crm-shell {
    grid-template-columns: minmax(0, 1fr); width: 100%; min-width: 0;
    /* `1fr` keeps its content-based minimum, so the canvas fills the rest of
       the screen when the lead card is short and grows past it when the
       disposition grid is long. Opening the menu never squeezes the work. */
    grid-template-rows: auto 1fr;
  }
  .crm-nav {
    position: sticky; top: 0; z-index: 30; height: auto; overflow: visible;
    flex-direction: column; align-items: stretch; gap: 0; padding: 8px 12px;
    border-right: 0; border-bottom: 1px solid var(--line);
    min-width: 0; max-width: 100vw;
  }
  .crm-nav-bar { min-height: var(--tap); }
  .crm-nav .brand-lockup { margin: 0; }
  .brand-logo { height: 38px; }
  .crm-nav-toggle { display: inline-flex; }
  .crm-nav-current {
    display: block; flex: 1; min-width: 0; overflow: hidden; padding: 0 10px;
    text-overflow: ellipsis; white-space: nowrap; color: var(--nav-ink); font-weight: 650;
  }
  /* Collapsed by default; the toggle is the only thing that opens it. */
  .crm-nav-links { display: none; padding: 6px 0 2px; }
  .crm-nav[data-nav-open="true"] .crm-nav-links { display: flex; }
  .crm-lead-finder { margin: 4px 0 8px; }
  .crm-lead-finder input {
    min-height: var(--tap); background: var(--surface); color: var(--ink);
    border-color: var(--line);
  }
  .crm-lead-finder input::placeholder { color: var(--muted); }
  .crm-lead-finder-shortcut { display: none; }
  .crm-view-as-option { min-height: var(--tap); }
  .crm-nav-link { white-space: nowrap; }
  /* The operator's own entry rides the phone menu: shown only while open. */
  .crm-nav-session { display: none; padding: 8px 0 6px; }
  .crm-nav[data-nav-open="true"] .crm-nav-session { display: block; }
  .crm-main { padding: 14px 12px 44px; }
}
