/* ============================================================
   CADENCE ANCHOR — design system v4

   Tokens taken from the LIVE surfaces, not from a local copy:
   francesvalentine.cadenceplan.com (the app canon) and
   cadenceplan.com (the marketing canon). Both are WARM —
   #fbfaf7 ground, #161616 ink, warm-alpha hairlines. An earlier
   pass here built on a stale checkout of the marketing CSS whose
   palette was cool slate-blue; that palette is not the house.

   The deep tone is PLUM, not green. Measured on the live
   surfaces: the canonical sign-in and the marketing site both
   land on #2b2134 independently, and a rendered colour census of
   FV and demo finds plum as the only non-neutral on the page.
   Green survives only as a semantic (positive numbers), never as
   the brand.

   The dark rail is still the shared signature — it just wears
   plum now. Content surfaces below it stay light.

   Type follows the app: Instrument Serif for display, Instrument
   Sans for UI, and Newsreader 720 reserved for the wordmark.

   Two themes, both explicit. views/_header.ejs stamps
   data-theme on <html> before first paint, so every colour is
   defined once on :root and once under [data-theme="dark"];
   nothing depends on prefers-color-scheme at the component
   level and no component declares a raw colour.
   ============================================================ */

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

:root {
  /* Type */
  /* Manrope + Newsreader — the pair the marketing site REQUESTS from Google.
     It never applies them (its stacks say Avenir Next and Georgia), so as of
     2026-08-23 the brand type is live on no surface at all; the client
     workspaces are on Instrument Sans/Serif. Two families, not three. */
  --sans:     'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  --serif:    'Newsreader', Georgia, 'Times New Roman', serif;
  --wordmark: 'Newsreader', Georgia, serif;
  --mono:     ui-monospace, 'SF Mono', 'JetBrains Mono', Menlo, monospace;
  --num:      var(--sans);

  /* Radii match the app: --radius 8, --radius-lg 12, admin cards 13. */
  --r-sm: 5px;
  --r:    8px;
  --r-md: 10px;
  --r-lg: 12px;
  --r-xl: 16px;

  /* Rhythm */
  --gap:      16px;
  --gap-lg:   22px;
  --row-h:    44px;
  --sidebar-w: 240px;

  --t-fast: 110ms cubic-bezier(0.4, 0, 0.2, 1);
  --t:      190ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

/* ---------- LIGHT ---------- */
/* Warm neutrals straight off the live app: --bg #fbfaf7, --text #161616,
   hairlines as warm alphas rather than a cool solid. */
:root, [data-theme="light"] {
  --bg:         #fbfaf7;
  --bg2:        #f3f2ee;
  --bg3:        #f0efe8;
  --card:       #ffffff;
  --border:     rgba(22,22,22,0.10);
  --border2:    rgba(22,22,22,0.18);
  --border3:    rgba(22,22,22,0.30);

  --text:       #161616;
  --text2:      #4a4944;
  --text3:      #63625d;   /* ink-600 — the muted workhorse */
  --text4:      #76756f;   /* ink-500 — decorative only, never a label */

  /* Plum #2b2134 is the deep primary both the sign-in and the marketing site
     use. It is nearly black, so it works as a button but not as a link — violet
     #6b38a8 is the readable relative, and what marketing sets its eyebrows in. */
  --accent:        #2b2134;
  --accent-dark:   #1d1624;
  --accent-text:   #5b2f92;   /* accent that has to survive as text on light */
  --accent-soft:   rgba(107,56,168,0.10);
  --accent-softer: rgba(107,56,168,0.05);
  --accent-ring:   rgba(43,33,52,0.20);
  --violet:        #6b38a8;

  /* The rail. Named --forest for continuity with the app CSS, but plum now,
     with a lilac highlight from the same family. There is no green anywhere in
     the chrome — green is a semantic in this app, never the brand. */
  --forest:      #2b2134;
  --forest-2:    #392c46;
  --forest-line: rgba(255,255,255,0.11);
  --forest-ink:  #f4f1f7;
  --forest-ink2: #c9bfd4;
  --forest-dim:  #9a8caa;
  --forest-card: rgba(255,255,255,0.07);
  --rail-hi:     #b9a4e0;

  /* Jewel accents from the app: teal, violet, coral, amber. */
  --red:    #b91c1c; --red-soft:    rgba(185,28,28,0.10);
  --amber:  #8a5409; --amber-soft:  rgba(186,117,23,0.12);   /* the app's #ba7517 misses AA as text on its own tint; this clears it with margin on both grounds */
  --blue:   #155f72; --blue-soft:   rgba(21,95,114,0.10);
  --green:  #047857; --green-soft:  rgba(4,120,87,0.10);   /* semantic positive only, not the brand */
  --slate:  #63625d; --slate-soft:  rgba(22,22,22,0.07);
  --purple: #6b38a8; --purple-soft: rgba(107,56,168,0.12);
  --teal:   #1d9e75; --coral: #d85a30;

  --shadow-sm: 0 1px 1px rgba(20,20,20,0.04);
  --shadow:    0 1px 2px rgba(20,20,20,0.05), 0 1px 3px rgba(20,20,20,0.04);
  --shadow-md: 0 6px 16px rgba(20,20,20,0.07), 0 1px 3px rgba(20,20,20,0.04);
  --shadow-lg: 0 12px 28px rgba(20,20,20,0.10), 0 4px 10px rgba(20,20,20,0.05);

  --login-ground:     #efede9;
  --login-ink:        #17141d;
  --login-muted:      #6f6b70;
  --login-faint:      #9a969b;
  --login-line:       #ddd5ca;
  --login-field-line: #c9c3bb;
  --login-plum:       #2b2134;

  --glass:        rgba(251,250,247,0.94);
  --glass-border: var(--border);
  --overlay:      rgba(20,18,16,0.34);
  --edge-fade:    linear-gradient(to right, rgba(251,250,247,0), rgba(251,250,247,1));
}

/* ---------- DARK ---------- */
/* Dark uses the app's night scale (--cad-night 14141a / 1c1c24 / 26262f). */
[data-theme="dark"] {
  --bg:         #14141a;
  --bg2:        #1c1c24;
  --bg3:        #26262f;
  --card:       #1a1a21;
  --border:     rgba(242,241,234,0.12);
  --border2:    rgba(242,241,234,0.20);
  --border3:    rgba(242,241,234,0.32);

  --text:       #f2f1ea;
  --text2:      #c3c1b8;
  --text3:      #a3a199;
  --text4:      #85837c;

  /* On a dark ground plum is invisible, so the accent lifts to the violet end. */
  --accent:        #b9a4e0;
  --accent-dark:   #cbbcea;
  --accent-text:   #c3b0e6;
  --accent-soft:   rgba(185,164,224,0.16);
  --accent-softer: rgba(185,164,224,0.08);
  --accent-ring:   rgba(185,164,224,0.28);
  --violet:        #b9a4e0;

  --forest:      #241b2d;
  --forest-2:    #322641;
  --forest-line: rgba(255,255,255,0.11);
  --forest-ink:  #f4f1f7;
  --forest-ink2: #c9bfd4;
  --forest-dim:  #9a8caa;
  --forest-card: rgba(255,255,255,0.07);
  --rail-hi:     #b9a4e0;

  --red:    #f98a80; --red-soft:    rgba(249,138,128,0.16);
  --amber:  #e5a63c; --amber-soft:  rgba(229,166,60,0.16);
  --blue:   #6fb3c4; --blue-soft:   rgba(111,179,196,0.16);
  --green:  #4ecfa0; --green-soft:  rgba(78,207,160,0.16);
  --slate:  #a3a199; --slate-soft:  rgba(242,241,234,0.10);
  --purple: #b9a4e0; --purple-soft: rgba(185,164,224,0.16);
  --teal:   #45c79a; --coral: #ef8055;

  --shadow-sm: 0 1px 1px rgba(0,0,0,0.35);
  --shadow:    0 1px 3px rgba(0,0,0,0.45);
  --shadow-md: 0 6px 18px rgba(0,0,0,0.5);
  --shadow-lg: 0 14px 34px rgba(0,0,0,0.6);

  --glass:        rgba(20,20,26,0.92);
  --glass-border: var(--border);
  --overlay:      rgba(0,0,0,0.62);
  --edge-fade:    linear-gradient(to right, rgba(20,20,26,0), rgba(20,20,26,1));
}

html { color-scheme: light dark; }

body {
  font-family: var(--sans);
  font-feature-settings: 'cv02', 'cv03', 'cv04', 'cv11';
  background: var(--bg);
  background-image: linear-gradient(to right, var(--forest) 0 var(--sidebar-w), var(--bg) var(--sidebar-w));
  color: var(--text);
  font-size: 13.5px;
  line-height: 1.5;
  min-height: 100vh;
  display: flex;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a { color: var(--accent-text); text-decoration: none; transition: color var(--t-fast); }
a:hover { color: var(--accent); text-decoration: underline; }
::selection { background: var(--accent-soft); color: var(--accent-dark); }

/* Figures line up in columns everywhere, so tabular numerals are the default
   for anything numeric rather than something each screen has to remember. */
.num, td, th, .kpi-tile .value, .stat-value, .money, table { font-variant-numeric: tabular-nums; }

:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }

/* Skip link. Off-screen until focused, then the first thing Tab reaches. */
.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 400;
  transform: translateY(-200%);
  padding: 9px 16px;
  background: var(--forest); color: var(--forest-ink);
  border-radius: var(--r); font-size: 13px; font-weight: 600;
  box-shadow: var(--shadow-lg);
  transition: transform var(--t-fast);
}
.skip-link:focus { transform: none; text-decoration: none; color: var(--forest-ink); }

/* ===================== SIDEBAR (forest chrome) ===================== */
/* The dark rail is Cadence's constant signature across every workspace, so
   Anchor reads as the same product. Content surfaces below it stay light. */
.sidebar {
  width: var(--sidebar-w);
  background: var(--forest);
  border-right: 1px solid var(--forest-line);
  padding: 16px 10px 10px;
  flex-shrink: 0;
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  color: var(--forest-ink2);
}
.brand {
  display: flex; align-items: flex-start; gap: 11px;
  /* left edge lines up with the nav icons below it */
  padding: 6px 10px 16px 20px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--forest-line);
}
/* The mark is dark purple. On the plum rail it disappears, so it sits in a light
   tile — which is what the brand contract specifies for the mark on dark grounds. */
.brand-mark {
  width: 30px; height: 30px; flex-shrink: 0;
  border-radius: 9px;
  background: #f4f1ec;
  display: grid; place-items: center;
  margin-top: 1px;   /* optical: sits on the wordmark cap height, not its line box */
}
.brand-mark img { width: 22px; height: 22px; display: block; object-fit: contain; }
/* Newsreader 720 at 21px, single colour — the wordmark spec, and the only
   place this face appears. */
.brand-name {
  font-family: var(--wordmark);
  font-size: 22px; font-weight: 720;
  letter-spacing: -0.018em; line-height: 1;
  color: var(--forest-ink);
  white-space: nowrap;
}
.brand-sub {
  font-size: 10px; font-weight: 700;
  letter-spacing: 0.11em; text-transform: uppercase;
  color: var(--forest-dim); margin-top: 5px;
  white-space: nowrap;
}

/* Ten flat links read as an undifferentiated list. Grouping them by what the
   section is FOR — the work, the money, the reference shelf — means the eye
   lands in the right third before it starts reading names. */
.nav { flex: 1; display: flex; flex-direction: column; gap: 2px; overflow-y: auto; padding: 4px 0; }
.nav-label {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--forest-dim);
  padding: 14px 8px 5px;
}
.nav-label:first-child { padding-top: 2px; }
.nav a {
  display: flex; align-items: center; gap: 9px;
  min-height: 36px; padding: 8px 10px;
  border-radius: var(--r);
  font-size: 14px; font-weight: 400; line-height: 1.2;
  color: var(--forest-ink2);
  transition: background var(--t-fast), color var(--t-fast);
  position: relative;
}
.nav a:hover { background: rgba(255,255,255,0.06); color: var(--forest-ink); text-decoration: none; }
.nav a.active {
  background: rgba(255,255,255,0.10);
  color: var(--forest-ink);
  font-weight: 700;
}
/* The active marker is a lilac pill inside the item, not a bar outside it. */
.nav a::before {
  content: ''; width: 4px; height: 18px; border-radius: 999px;
  background: var(--rail-hi); opacity: 0; flex: 0 0 auto;
  margin-left: -4px; margin-right: 1px;
  transition: opacity var(--t-fast);
}
.nav a.active::before { opacity: 1; }
.nav svg { width: 16px; height: 16px; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; opacity: 0.85; }
.nav a.active svg { opacity: 1; }
.nav a .nav-count {
  margin-left: auto;
  font-size: 11px; font-weight: 600;
  color: var(--forest-dim);
  font-variant-numeric: tabular-nums;
}

.sidebar-foot {
  border-top: 1px solid var(--forest-line);
  padding-top: 10px; margin-top: 10px;
  display: flex; flex-direction: column; gap: 8px;
  font-size: 12px; color: var(--forest-ink2);
}
/* The user block is a card in the rail, matching the workspace/user cards in
   the client workspaces. */
.sidebar-foot .who {
  display: flex; align-items: center; gap: 9px;
  padding: 8px; border-radius: var(--r);
  background: var(--forest-card);
  min-width: 0;
}
.sidebar-foot .avatar {
  width: 30px; height: 30px; border-radius: 8px;
  background: linear-gradient(135deg, #6b38a8, #8f7ac9); color: #fff;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 760; text-transform: uppercase;
  flex-shrink: 0;
}
.sidebar-foot strong { color: var(--forest-ink); font-weight: 600; }
.sidebar-foot form { display: inline; }
.foot-actions { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.foot-btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: none; border: none; padding: 6px 7px;
  border-radius: var(--r-sm);
  font-family: inherit; font-size: 12px; font-weight: 500;
  color: var(--forest-ink2); cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast);
}
.foot-btn:hover { color: var(--forest-ink); background: rgba(255,255,255,0.06); text-decoration: none; }
.foot-btn.danger:hover { color: #ffb4a8; background: rgba(255,255,255,0.06); }
.foot-btn svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }
.foot-btn kbd { margin-left: auto; }
kbd {
  font-family: var(--sans); font-size: 10px; font-weight: 600;
  color: var(--text3); background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 5px;
}
.sidebar kbd { color: var(--forest-ink2); background: rgba(255,255,255,0.10); border-color: var(--forest-line); }
.theme-toggle {
  width: 28px; height: 28px; flex-shrink: 0;
  border: 1px solid var(--forest-line); background: var(--forest-card);
  border-radius: var(--r-sm); color: var(--forest-ink2);
  display: grid; place-items: center; cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.theme-toggle:hover { color: var(--forest-ink); border-color: rgba(255,255,255,0.22); }
.theme-toggle svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
[data-theme="dark"]  .theme-toggle .icon-moon { display: none; }
[data-theme="light"] .theme-toggle .icon-sun  { display: none; }
:root:not([data-theme="dark"]) .theme-toggle .icon-sun { display: none; }

/* ===================== PAGE SHELL ===================== */
@keyframes page-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }

/* Views render straight into .main, so .main owns the horizontal rhythm and the
   page bar breaks back out of it with matching negative margins. That keeps the
   bar full-bleed and sticky without every view needing a wrapper element. */
/* Capped so a wide monitor does not stretch a funnel bar to 750px or run an
   activity line to 120 characters. Left-aligned rather than centred, so content
   still starts where the sidebar ends. No effect below ~1780px. */
.main {
  flex: 1; min-width: 0; max-width: 1500px;
  padding: 0 var(--pad) 64px;
}
:root { --pad: 34px; }

/* The page bar sticks, so the title and the primary action stay reachable on
   the long boards. It is the only chrome above the content. */
.page-header {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  margin: 0 calc(-1 * var(--pad)) 22px;
  padding: 20px var(--pad) 14px;
  background: var(--bg);
  border-bottom: 1px solid var(--border);
}
.page-header h1 {
  font-family: var(--serif);
  font-size: 30px; font-weight: 400;
  letter-spacing: -0.01em; line-height: 1.08;
  text-wrap: balance;
}
.page-header .sub { font-size: 12.5px; color: var(--text3); margin-top: 3px; max-width: 62ch; }
.page-header .actions { display: flex; align-items: center; gap: 8px; }
/* Views that want the old stacked-sections rhythm can opt in. */
.page-body { display: flex; flex-direction: column; gap: var(--gap-lg); }

/* ===================== BUTTONS ===================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  padding: 7px 13px;
  border: 1px solid var(--border2);
  border-radius: var(--r);
  background: var(--card);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text2); cursor: pointer; white-space: nowrap;
  transition: background var(--t-fast), border-color var(--t-fast), color var(--t-fast);
}
.btn:hover { background: var(--bg2); border-color: var(--border3); color: var(--text); text-decoration: none; }
.btn:active { transform: translateY(0.5px); }
.btn svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 2; }
.btn-primary {
  background: var(--accent); border-color: var(--accent); color: #fff;
}
.btn-primary:hover { background: var(--accent-dark); border-color: var(--accent-dark); color: #fff; }
[data-theme="dark"] .btn-primary { color: #241b2d; }
[data-theme="dark"] .btn-primary:hover { color: #241b2d; }
.btn-danger { color: var(--red); border-color: var(--border2); background: var(--card); }
.btn-danger:hover { background: var(--red-soft); border-color: var(--red); color: var(--red); }
.btn-ghost { background: none; border-color: transparent; color: var(--text3); }
.btn-ghost:hover { background: var(--bg2); border-color: transparent; color: var(--text); }
.btn-sm { padding: 4px 9px; font-size: 11.5px; }
.btn-lg { padding: 9px 18px; font-size: 13.5px; }

/* Quiet 24px icon button. Row actions use this so that Delete stops being the
   loudest thing on every row of every table. */
.icon-btn {
  width: 26px; height: 26px; flex-shrink: 0;
  border: 1px solid transparent; background: none;
  border-radius: var(--r-sm); color: var(--text3);
  display: grid; place-items: center; cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.icon-btn:hover { color: var(--text); background: var(--bg2); border-color: var(--border); text-decoration: none; }
.icon-btn.danger:hover { color: var(--red); background: var(--red-soft); border-color: var(--red-soft); }
.icon-btn svg { width: 14px; height: 14px; stroke: currentColor; fill: none; stroke-width: 1.9; }

/* ===================== SURFACES ===================== */
.card {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 16px 18px;
}
.card h3, .sec-title {
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.09em;
  color: var(--text3);
  margin-bottom: 12px;
}
.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 12px;
}
.card-head h3 { margin-bottom: 0; }
.card-head .more { font-size: 11.5px; font-weight: 600; }

.grid { display: grid; gap: var(--gap); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* align-items:start keeps a short card from stretching to match a tall
   neighbour, which is what produced the 700px of white space on the dashboard. */
.grid { align-items: start; }
/* The hero row is the exception: two panels side by side read as a pair, so they
   match height and the shorter one distributes its rows into the space. */
.dash-row {
  display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: var(--gap); align-items: stretch;
}
.dash-row > .card { display: flex; flex-direction: column; }
.dash-row > .card > .funnel { flex: 1; justify-content: space-between; }

/* Secondary dashboard cards, paired by how much they hold: the two long lists
   share the first row and the two short ones share the second, so neither row
   is stretched by a neighbour twice its height. align-items:start then lets each
   card end where its content ends. */
.dash-cards {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap); align-items: start;
}
/* Collapse only once the content column is genuinely too narrow for two cards.
   The old 980px breakpoint sat right at Will's working width (140% zoom ≈ 960–1000
   CSS px), so the whole dashboard stacked into a single tall column for him. Below
   760 the sidebar becomes a rail, which is the honest point to go single-column. */
@media (max-width: 760px) { .dash-cards { grid-template-columns: minmax(0, 1fr); } }

/* ---------- The forest panel ---------- */
/* One per page, carrying the single number that page exists to report. It is
   the only saturated surface in the app; everything else stays pale so this
   reads instantly. */
.deep {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 18px 20px;
  position: relative; overflow: hidden;
}
/* A hairline of accent along the top edge is the whole emphasis. */
.deep::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 2px;
  background: linear-gradient(to right, var(--accent), var(--rail-hi));
}
.deep .deep-figure {
  font-size: 38px; font-weight: 600; line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--accent-text);
  font-variant-numeric: tabular-nums;
  display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap;
}
[data-theme="dark"] .deep .deep-figure { color: var(--accent-text); }
.deep .deep-figure .unit { font-size: 13px; font-weight: 500; color: var(--text3); letter-spacing: 0; }
.deep .deep-note { font-size: 12px; color: var(--text3); margin-top: 8px; }
.deep-split {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 14px 18px;
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--border);
}
.deep-split .k { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--text3); }
.deep-split .v { font-size: 16px; font-weight: 600; margin-top: 3px; font-variant-numeric: tabular-nums; color: var(--text); }
.deep-split .v.hi { color: var(--accent-text); }
[data-theme="dark"] .deep-split .v.hi { color: var(--accent-text); }
.deep-alert { font-size: 12px; font-weight: 600; color: var(--red); margin-top: 12px; }

/* ---------- Metric strip ---------- */
/* Replaces the row of six equal boxes. Same numbers, one line, no card
   chrome — six counts do not each need a container. */
.kpis {
  display: flex; flex-wrap: wrap;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.kpi-tile {
  flex: 1 1 128px; min-width: 0;
  padding: 13px 16px;
  border-right: 1px solid var(--border);
  position: relative;
  transition: background var(--t-fast);
}
.kpi-tile:last-child { border-right: none; }
a.kpi-tile:hover { background: var(--bg2); text-decoration: none; }
.kpi-tile .label {
  font-size: 9.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text3);
  display: flex; align-items: center; gap: 6px;
}
.kpi-tile .value {
  font-size: 25px; font-weight: 600; line-height: 1.15;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  margin-top: 5px;
}
.kpi-tile .value.sm { font-size: 20px; }
.kpi-tile .foot { font-size: 11px; color: var(--text3); margin-top: 3px; }
.kpi-tile .dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.kpi-tile.is-zero .value { color: var(--text4); }
.kpi-tile.accent .value { color: var(--accent-text); }
[data-theme="dark"] .kpi-tile.accent .value { color: var(--accent); }

/* ===================== TABLE ===================== */
/* Setting overflow on one axis computes the other to auto, so this element is the
   scrollport for its table — which is what makes the sticky header work, but only
   if the region can actually scroll. Cap it and let long tables scroll in place
   under the page bar rather than running off the bottom of the document. */
.table-wrap {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  max-height: calc(100vh - 176px);
  overflow: auto;
}
.table-wrap table { border: none; border-radius: 0; min-width: 720px; }
.table-wrap th { background: var(--card); }
table {
  width: 100%;
  border-collapse: collapse;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
}
th, td {
  padding: 0 14px;
  height: var(--row-h);
  text-align: left;
  font-size: 12.5px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
th {
  height: 34px;
  font-size: 9.5px; color: var(--text3);
  text-transform: uppercase; letter-spacing: 0.1em;
  font-weight: 700;
  background: var(--card);
  border-bottom-color: var(--border2);
  position: sticky; top: 0; z-index: 2;
  white-space: nowrap;
}
td.num, th.num { text-align: right; font-variant-numeric: tabular-nums; }
td.nowrap, th.nowrap { white-space: nowrap; }
/* A select sized by its widest option, so "In progress" does not render as
   "To dc" in a column laid out for the shortest one. */
select.status-select { width: auto; min-width: 116px; padding: 4px 8px; font-size: 12px; }
/* On a table cell, `height` already behaves as a minimum — the row grows when the
   content is taller. min-height does nothing here, so setting it left rows sized
   only by their tallest control. */
td { height: var(--row-h); padding-top: 8px; padding-bottom: 8px; }
td strong { font-weight: 600; }
tbody tr:last-child td { border-bottom: none; }
tbody tr { transition: background var(--t-fast); }
tbody tr:hover td { background: var(--bg2); }

/* Row actions live in a fixed-width last cell and only appear on hover or
   keyboard focus, so scanning a table is scanning data, not buttons. */
td.row-actions { width: 1%; white-space: nowrap; text-align: right; padding-right: 10px; }
td.row-actions .actions { display: inline-flex; gap: 2px; opacity: 0; transition: opacity var(--t-fast); }
tr:hover td.row-actions .actions,
td.row-actions .actions:focus-within { opacity: 1; }
td.row-actions form { display: inline-flex; }

/* ===================== FORMS ===================== */
input[type="text"], input[type="email"], input[type="password"],
input[type="number"], input[type="tel"], input[type="date"],
input[type="url"], input[type="search"], input[type="time"],
input[type="month"], input[type="week"], input[type="datetime-local"],
input[type="file"], textarea, select {
  width: 100%;
  padding: 7.5px 11px;
  border: 1px solid var(--border2);
  border-radius: var(--r);
  font-family: inherit;
  font-size: 13px;
  background: var(--card);
  color: var(--text);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-ring);
}
input:hover, textarea:hover, select:hover { border-color: var(--border3); }
input::placeholder, textarea::placeholder { color: var(--text4); }
textarea { resize: vertical; min-height: 84px; line-height: 1.5; }
label {
  display: block;
  font-size: 9.5px; color: var(--text3);
  text-transform: uppercase; letter-spacing: 0.09em;
  font-weight: 700;
  margin-bottom: 5px;
  margin-top: 15px;
}
label:first-child { margin-top: 0; }
.form-row { display: grid; gap: 14px; }
.form-row.two { grid-template-columns: 1fr 1fr; }
.form-row + .form-row { margin-top: 15px; }
/* Named section break inside a long form. An unlabelled rule says something
   changes here without saying what. */
.form-sec {
  display: flex; align-items: center; gap: 12px;
  margin: 28px 0 14px;
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--text2);
}
.form-sec::after { content: ''; flex: 1; height: 1px; background: var(--border); }

/* ===================== TABS / SEGMENTED ===================== */
.tabs {
  display: flex; gap: 2px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 18px;
}
.tab-btn {
  background: none; border: none;
  padding: 9px 13px;
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  color: var(--text3); cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.tab-btn:hover { color: var(--text); }
.tab-btn.active { color: var(--text); border-bottom-color: var(--accent); }
.tab-content { display: none; }
.tab-content.active { display: block; }

.segmented {
  display: inline-flex; gap: 2px; padding: 2px;
  background: var(--bg2); border: 1px solid var(--border);
  border-radius: var(--r);
}
.segmented a, .segmented .vt {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4.5px 11px; border-radius: var(--r-sm);
  font-size: 12px; font-weight: 600; color: var(--text3);
  transition: background var(--t-fast), color var(--t-fast);
}
.segmented a:hover, .segmented .vt:hover { color: var(--text); text-decoration: none; }
.segmented a.active, .segmented .vt.on {
  background: var(--card); color: var(--text);
  box-shadow: var(--shadow-sm);
}
.segmented svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ===================== PILLS ===================== */
.stage-pill {
  display: inline-flex; align-items: center;
  color: #fff; font-size: 10px; font-weight: 700;
  padding: 2.5px 9px; border-radius: 999px;
  letter-spacing: 0.04em; text-transform: uppercase;
  white-space: nowrap;
}
.status-pill, .prio-pill {
  display: inline-flex; align-items: center;
  font-size: 10.5px; font-weight: 600;
  padding: 2px 8px; border-radius: 999px;
  white-space: nowrap;
}
.status-todo        { background: var(--slate-soft);  color: var(--slate); }
.status-in_progress { background: var(--blue-soft);   color: var(--blue); }
.status-done        { background: var(--green-soft);  color: var(--green); }
.priority-high   { color: var(--red); font-weight: 600; }
.priority-normal { color: var(--text3); }
.prio-p1 { background: var(--red-soft);    color: var(--red); }
.prio-p2 { background: var(--amber-soft);  color: var(--amber); }
.prio-p3 { background: var(--blue-soft);   color: var(--blue); }
.prio-p4 { background: var(--slate-soft);  color: var(--slate); }
.prio-p5 { background: var(--purple-soft); color: var(--purple); }

/* Category-style chip: takes its hue from --c and tints it, so a column of them
   reads as classification rather than as a row of buttons. */
.soft-pill, .rev-badge, .col-type {
  display: inline-flex; align-items: center;
  font-size: 10.5px; font-weight: 600;
  padding: 2px 9px; border-radius: 999px;
  white-space: nowrap;
  color: color-mix(in srgb, var(--c, var(--text2)) 86%, #000);
  background: color-mix(in srgb, var(--c, var(--text3)) 13%, transparent);
}
[data-theme="dark"] .soft-pill,
[data-theme="dark"] .rev-badge,
[data-theme="dark"] .col-type {
  /* On a dark ground the tint darkens the chip, so lift the text instead. */
  color: color-mix(in srgb, var(--c, var(--text2)) 78%, #fff);
  background: color-mix(in srgb, var(--c, var(--text3)) 20%, transparent);
}

.task-tag {
  display: inline-block; margin-top: 4px;
  font-size: 10px; font-weight: 600;
  color: var(--text3); background: var(--bg2);
  border: 1px solid var(--border);
  padding: 1px 7px; border-radius: 999px;
  overflow-wrap: anywhere;
}

/* ===================== KANBAN / TASK BOARD ===================== */
.kanban { display: grid; gap: 12px; align-items: start; }
.kanban-col {
  background: var(--bg2);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  padding: 8px;
  display: flex; flex-direction: column; gap: 7px;
  min-height: 60px;
}
.kanban-col.drag-over, .kanban-drop.drag-over {
  background: var(--accent-softer);
  border-color: var(--accent);
}
.kanban-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px; padding: 2px 4px 6px;
}
.kanban-head .name { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--text3); }
/* One column usually holds most of the cards. Left uncapped it ran ~1800px while
   its neighbours ran 200px, so the board became a single tall list with two stubs
   beside it. Cap the drop area and let it scroll, as every board does. */
.kanban-col > .kanban-drop {
  display: flex; flex-direction: column; gap: 7px;
  max-height: calc(100vh - 250px);
  overflow-y: auto;
  scrollbar-width: thin;
  overscroll-behavior: contain;
}

/* Applied by the footer script to any capped scroller that still has content
   below the fold. Purely an affordance — it never hides anything you cannot
   reach by scrolling. */
.has-more-y {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent 100%);
}
.kanban-head .count {
  font-size: 10.5px; font-weight: 700; color: var(--text3);
  background: var(--card); border: 1px solid var(--border);
  border-radius: 999px; padding: 0 7px;
  font-variant-numeric: tabular-nums;
}
.kanban-card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 9px 10px;
  cursor: grab;
  overflow-wrap: break-word;
  transition: border-color var(--t-fast), box-shadow var(--t-fast), opacity 150ms;
}
.kanban-card:hover { border-color: var(--border2); box-shadow: var(--shadow); }
.kanban-card.dragging { opacity: 0.35; cursor: grabbing; }
.kanban-card .name { font-weight: 600; font-size: 13px; color: var(--text); line-height: 1.3; }
.kanban-card .industry { font-size: 10.5px; color: var(--text3); margin-top: 2px; }
.kanban-card .next-step { font-size: 11.5px; color: var(--text2); margin-top: 7px; line-height: 1.45; }
.kanban-empty { font-size: 11px; color: var(--text4); text-align: center; padding: 12px 0; }

.task-board { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--gap); align-items: start; }
.task-card { position: relative; }
.task-card-edit {
  position: absolute; top: 8px; right: 8px;
  width: 24px; height: 24px; border-radius: var(--r-sm);
  border: 1px solid transparent; background: none;
  color: var(--text3);
  display: grid; place-items: center;
  opacity: 0; transition: opacity var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.task-card:hover .task-card-edit, .task-card-edit:focus-visible { opacity: 1; }
.task-card-edit:hover { color: var(--text); background: var(--bg2); text-decoration: none; }
.task-card-edit svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; }
.task-card-meta { font-size: 11px; color: var(--text3); margin-top: 5px; line-height: 1.45; }
.task-notes {
  font-size: 11.5px; color: var(--text2);
  margin-top: 7px; line-height: 1.5;
  border-left: 2px solid var(--border);
  padding-left: 9px;
}
/* In a table the quote rule reads as a stray vertical line, and full notes make
   rows wildly uneven. Clamp to two lines there; the edit form has the whole thing. */
td .task-notes {
  border-left: none; padding-left: 0; margin-top: 5px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
  overflow: hidden;
}
.task-card .prio-pill { margin-top: 7px; }

/* ===================== NOTES ===================== */
.note {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 14px 16px;
  transition: border-color var(--t-fast);
}
.note:hover { border-color: var(--border2); }
.note.pinned { border-left: 3px solid var(--accent); }
.note-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.note-title { font-weight: 600; font-size: 13.5px; }
.note-meta { font-size: 11px; color: var(--text3); }
.note-body { font-size: 12.5px; color: var(--text2); line-height: 1.6; margin-top: 7px; white-space: pre-wrap; }
.note-pin { width: 13px; height: 13px; stroke: var(--accent); fill: none; vertical-align: -1px; }
.note { position: relative; }
.note-del { position: absolute; top: 10px; right: 10px; opacity: 0; transition: opacity var(--t-fast); }
.note:hover .note-del, .note-del:focus-within { opacity: 1; }

/* ===================== TIMELINE / FUNNEL ===================== */
/* Label/value pairs on a record. A grid rather than a table so the values wrap
   under their own column instead of pushing the labels around. */
.facts {
  display: grid; grid-template-columns: minmax(84px, auto) minmax(0, 1fr);
  gap: 8px 16px; align-items: baseline;
  font-size: 12.5px;
}
.facts dt {
  font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.08em;
  color: var(--text3); white-space: nowrap;
}
.facts dd { color: var(--text); min-width: 0; overflow-wrap: anywhere; }
.facts dd.num { font-variant-numeric: tabular-nums; }
.mono { font-family: var(--mono); font-size: 11.5px; }

.timeline-row {
  display: flex; align-items: flex-start; gap: 11px;
  padding: 9px 0;
  border-bottom: 1px solid var(--border);
  font-size: 12.5px;
}
.timeline-row:last-child { border-bottom: none; }
.timeline-marker {
  flex-shrink: 0; width: 7px; height: 7px; margin-top: 6px;
  border-radius: 50%; background: var(--border2);
}
.timeline-content { flex: 1; min-width: 0; }
.timeline-when { font-size: 11px; color: var(--text3); flex-shrink: 0; font-variant-numeric: tabular-nums; }

.funnel { display: flex; flex-direction: column; }
.funnel-row {
  display: grid;
  grid-template-columns: 128px minmax(0, 1fr) 74px;
  align-items: center; gap: 12px;
  padding: 6px 8px;
  border-radius: var(--r-sm);
  transition: background var(--t-fast);
}
.funnel-row:hover { background: var(--bg2); }
.funnel-label { display: flex; align-items: center; gap: 8px; font-size: 12.5px; font-weight: 500; }
.funnel-label .dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.funnel-bar-wrap { position: relative; height: 22px; display: flex; align-items: center; }
.funnel-bar {
  height: 22px; border-radius: var(--r-sm);
  min-width: 3px;
  display: flex; align-items: center; justify-content: flex-end;
  padding: 0 8px;
  transition: width var(--t);
}
.funnel-bar-count { font-size: 11px; font-weight: 700; color: #fff; font-variant-numeric: tabular-nums; }
.funnel-bar-count-outer { font-size: 11px; font-weight: 700; color: var(--text3); margin-left: 7px; font-variant-numeric: tabular-nums; }
.funnel-meta { text-align: right; font-size: 12px; color: var(--text2); font-variant-numeric: tabular-nums; }
.funnel-arr { font-weight: 600; }
.funnel-threads { font-size: 10.5px; color: var(--text3); }
.funnel-threads span { letter-spacing: -0.02em; }

/* ===================== EMPTY / MISC ===================== */
.muted { color: var(--text3); }
.empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; padding: 30px 20px; gap: 4px;
}
.empty-icon {
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--bg2); color: var(--text3);
  display: grid; place-items: center; margin-bottom: 8px;
}
.empty-icon svg { width: 19px; height: 19px; stroke: currentColor; fill: none; stroke-width: 1.75; }
.empty-title { font-size: 13.5px; font-weight: 600; color: var(--text2); }
.empty-sub { font-size: 12px; color: var(--text3); }
.kanban-empty, .rev-cyc { color: var(--text3); }

.filter-label { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em; color: var(--text3); }

/* ===================== FILES / DROPZONE ===================== */
.dropzone {
  border: 1.5px dashed var(--border2);
  border-radius: var(--r-lg);
  padding: 18px;
  text-align: center;
  background: var(--bg2);
  transition: border-color var(--t-fast), background var(--t-fast);
  cursor: pointer;
}
.dropzone:hover { border-color: var(--accent); }
.dropzone.dragover, .dropzone.has-file { border-color: var(--accent); background: var(--accent-softer); }
.dropzone.has-file { border-style: solid; }
.dropzone-icon {
  width: 40px; height: 40px; margin: 0 auto 10px;
  border-radius: 50%; background: var(--card); color: var(--text3);
  display: grid; place-items: center;
  border: 1px solid var(--border);
}
.dropzone-icon svg { width: 19px; height: 19px; stroke: currentColor; fill: none; stroke-width: 1.9; }
.dropzone-text { font-size: 13px; color: var(--text2); }
.dropzone-link { color: var(--accent-text); font-weight: 600; }
.dropzone-hint { font-size: 11.5px; color: var(--text3); margin-top: 4px; }

.file-row {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 14px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast);
}
.file-row:hover { border-color: var(--border2); }
.file-row:hover .file-actions { opacity: 1; }
.file-ico {
  width: 34px; height: 34px; flex-shrink: 0;
  border-radius: var(--r); background: var(--bg2); color: var(--text3);
  display: grid; place-items: center;
}
.file-ico svg { width: 18px; height: 18px; stroke: currentColor; fill: none; stroke-width: 1.9; }
.file-ico.tint-blue   { background: var(--blue-soft);   color: var(--blue); }
.file-ico.tint-green  { background: var(--green-soft);  color: var(--green); }
.file-ico.tint-red    { background: var(--red-soft);    color: var(--red); }
.file-ico.tint-amber  { background: var(--amber-soft);  color: var(--amber); }
.file-ico.tint-purple { background: var(--purple-soft); color: var(--purple); }
.file-ico.tint-slate  { background: var(--slate-soft);  color: var(--slate); }
.file-main { flex: 1; min-width: 0; }
.file-name { font-size: 13px; font-weight: 600; color: var(--text); }
.file-meta { font-size: 11.5px; color: var(--text3); margin-top: 2px; line-height: 1.5; }
.file-actions { display: flex; align-items: center; gap: 4px; flex-shrink: 0; opacity: 0; transition: opacity var(--t-fast); }
.file-actions:focus-within { opacity: 1; }
.file-actions form { display: inline-flex; }

/* ===================== LINKS ===================== */
.link-section { display: flex; align-items: center; gap: 8px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em; color: var(--text3); }
.link-section-dot { width: 7px; height: 7px; border-radius: 50%; }
.link-section-count { color: var(--text3); font-weight: 600; }
.link-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(228px, 1fr)); gap: 12px; }
.link-card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  transition: border-color var(--t-fast), box-shadow var(--t-fast);
}
.link-card:hover { border-color: var(--border2); box-shadow: var(--shadow); }
.link-card-link { display: block; padding: 13px 14px; text-decoration: none; color: inherit; }
.link-card-link:hover { text-decoration: none; }
.link-host { display: flex; align-items: center; gap: 5px; font-size: 10.5px; color: var(--text3); }
.link-host svg { width: 12px; height: 12px; stroke: currentColor; fill: none; stroke-width: 2; flex-shrink: 0; }
.link-name { font-size: 13px; font-weight: 600; color: var(--text); margin-top: 6px; }
.link-desc { font-size: 11.5px; color: var(--text3); margin-top: 3px; line-height: 1.45; }
.link-actions { position: absolute; top: 7px; right: 7px; display: flex; gap: 2px; opacity: 0; transition: opacity var(--t-fast); }
.link-card:hover .link-actions, .link-actions:focus-within { opacity: 1; }
.link-actions form { display: flex; }
.link-act {
  width: 24px; height: 24px; border-radius: var(--r-sm);
  border: 1px solid transparent; background: var(--card);
  color: var(--text3);
  display: grid; place-items: center; cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
.link-act:hover { color: var(--text); border-color: var(--border); background: var(--bg2); text-decoration: none; }
.link-act-danger:hover { color: #fff; background: var(--red); border-color: var(--red); }
.link-act svg { width: 13px; height: 13px; stroke: currentColor; fill: none; stroke-width: 2; }

/* ===================== LOGIN (canonical Cadence sign-in) ===================== */
/* Measured off the shipped canonical login rather than copied from a screenshot:
   ground #efede9, one centred white card, Newsreader 720 wordmark over a rule,
   a WORKSPACE eyebrow naming where you are landing, Newsreader 580 heading, 48px
   controls at 9px radius, and the plum primary with a trailing arrow.
   Anchor is a Cadence workspace like any other, so it signs in like one. */
.login-split {
  min-height: 100vh; width: 100%;
  display: grid; place-items: center;
  padding: 40px 20px;
  background: var(--login-ground);
}
.login-card {
  width: 558px; max-width: 100%;
  background: var(--card);
  border-radius: 14px;
  padding: 34px 40px 30px;
  box-shadow: 0 18px 44px rgba(23,20,29,0.07), 0 2px 6px rgba(23,20,29,0.04);
  animation: page-in 220ms ease-out;
}
.login-brand-top { display: flex; align-items: center; gap: 11px; padding-bottom: 18px; }
.login-brand-top .mark { width: 30px; height: 30px; flex-shrink: 0; display: block; object-fit: contain; }
.login-brand-top .word {
  font-family: var(--wordmark); font-size: 27px; font-weight: 720;
  letter-spacing: -0.018em; line-height: 1; color: var(--login-ink);
}
.login-rule { height: 1px; background: var(--login-line); margin: 0 0 18px; }

.login-eyebrow {
  font-size: 10px; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.13em;
  color: var(--login-faint);
}
.login-workspace { font-size: 15px; font-weight: 600; color: var(--login-ink); margin-top: 4px; }

.login-form-inner h1 {
  font-family: var(--wordmark);
  font-size: 26px; font-weight: 580;
  letter-spacing: -0.035em; line-height: 1.1;
  color: var(--login-ink);
  margin-top: 16px;
}
.login-form-inner .sub { font-size: 13.5px; color: var(--login-muted); margin: 6px 0 20px; }

.login-card label {
  font-size: 11.5px; font-weight: 600; letter-spacing: 0;
  text-transform: none; color: var(--login-ink);
  margin: 14px 0 6px;
}
.login-card label:first-of-type { margin-top: 0; }
.login-card input[type="text"],
.login-card input[type="email"],
.login-card input[type="password"] {
  height: 48px; padding: 0 14px;
  border: 1px solid var(--login-field-line); border-radius: 9px;
  background: var(--card); color: var(--login-ink);
  font-size: 14px; font-weight: 400;
}
.login-card input:focus { border-color: var(--login-plum); box-shadow: 0 0 0 3px rgba(43,33,52,0.12); }

/* The primary is plum on the sign-in, not the app's green. */
.login-submit {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; height: 48px; margin-top: 20px;
  border: 1px solid var(--login-plum); border-radius: 9px;
  background: var(--login-plum); color: #fff;
  font-family: inherit; font-size: 13px; font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 11px rgba(43,33,52,0.10);
  transition: filter var(--t-fast);
}
.login-submit:hover { filter: brightness(1.12); color: #fff; text-decoration: none; }
.login-submit .arrow { font-size: 18px; font-weight: 400; color: rgba(255,255,255,0.78); line-height: 1; }

.google-btn {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%; height: 48px;
  background: var(--card); border: 1px solid var(--login-field-line);
  border-radius: 9px; font-size: 13px; font-weight: 600;
  color: var(--login-ink); cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.google-btn:hover { background: var(--bg2); border-color: var(--login-ink); text-decoration: none; }

.login-divider {
  display: flex; align-items: center; gap: 12px;
  margin: 18px 0; font-size: 10px; font-weight: 600;
  letter-spacing: 0.13em; text-transform: uppercase; color: var(--login-faint);
}
.login-divider::before, .login-divider::after { content: ''; flex: 1; height: 1px; background: var(--login-line); }

.login-alt {
  display: block; text-align: center; margin-top: 16px;
  font-size: 12px; color: var(--login-muted); text-decoration: underline;
}
.login-alt:hover { color: var(--login-ink); }
.login-foot {
  text-align: center; margin-top: 14px;
  font-size: 11.5px; color: var(--login-faint);
}
.login-form-inner .err {
  background: rgba(185,28,28,0.08); color: var(--red);
  border-radius: 9px; padding: 10px 13px;
  font-size: 12.5px; font-weight: 600; margin-bottom: 14px;
}
@media (max-width: 560px) { .login-card { padding: 26px 22px 22px; } }

/* ===================== MODAL + ICON BUTTON ===================== */
/* Used by Recurring Revenue and the Library. These once lived inside
   collateral.ejs, so revenue rendered the same class names with no styles at all.
   They were lost a second time when the login block was replaced wholesale and
   the splice ran to the next section marker — which is why a section replacement
   should be bounded by its OWN end, not by whatever comes after it. */
.col-overlay {
  position: fixed; inset: 0; z-index: 200;
  background: var(--overlay);
  display: flex; align-items: center; justify-content: center; padding: 20px;
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.col-panel {
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  width: 480px; max-width: 100%; max-height: 90vh; overflow-y: auto;
  padding: 20px 22px;
}
.col-panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 16px;
}
.col-panel-head strong { font-family: var(--serif); font-size: 19px; font-weight: 400; }
.col-x {
  background: none; border: none; cursor: pointer; color: var(--text3);
  display: grid; place-items: center; padding: 5px; border-radius: var(--r-sm);
}
.col-x:hover { background: var(--bg2); color: var(--text); }
.col-x svg { width: 16px; height: 16px; }
.col-actbtns { display: inline-flex; align-items: center; gap: 2px; }
.col-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; border-radius: var(--r-sm);
  border: 1px solid transparent; background: none;
  color: var(--text3); cursor: pointer; text-decoration: none;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.col-btn:hover { background: var(--bg2); color: var(--text); border-color: var(--border); text-decoration: none; }
.col-btn svg { width: 14px; height: 14px; }
.col-del:hover { color: var(--red); background: var(--red-soft); border-color: var(--red-soft); }

/* ===================== CMD+K ===================== */
.cmdk-item { transition: background var(--t-fast); }
.cmdk-item:hover { background: var(--bg2); }

/* ===================== ASK ===================== */
/* The assistant launcher lives in the sidebar foot rather than floating over the
   bottom-right corner, where it covered the row actions of whichever table row
   happened to be at the bottom of the scroll. */
.ask-launch {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  width: 100%; padding: 9px 12px;
  background: var(--forest-card); color: var(--forest-ink);
  border: 1px solid var(--forest-line); border-radius: var(--r);
  font-family: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.ask-launch:hover { background: rgba(255,255,255,0.12); border-color: rgba(255,255,255,0.22); color: var(--forest-ink); }
.ask-launch svg { stroke: var(--rail-hi); }
.ask-launch svg { width: 14px; height: 14px; stroke: var(--rail-hi); fill: none; stroke-width: 2; flex-shrink: 0; }
@media (max-width: 760px) { .ask-launch span { display: none; } .ask-launch { padding: 8px 0; } }

/* ===================== TOASTS ===================== */
#toast-container {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
  z-index: 300; display: flex; flex-direction: column; gap: 8px;
  pointer-events: none;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(6px); } }
.toast {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  font-size: 12.5px; font-weight: 500; color: var(--text);
  animation: toast-in 200ms cubic-bezier(0.2, 0.7, 0.3, 1);
  pointer-events: auto;
}
.toast .toast-icon { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.toast.toast-success .toast-icon { background: var(--green); }
.toast.toast-error   .toast-icon { background: var(--red); }
.toast.toast-info    .toast-icon { background: var(--slate); }
.toast.toast-success { border-left: 3px solid var(--green); }
.toast.toast-error   { border-left: 3px solid var(--red); }
.toast.toast-info    { border-left: 3px solid var(--slate); }
.toast.fading-out { animation: toast-out 220ms cubic-bezier(0.4, 0, 0.2, 1) forwards; }

/* ===================== FILTER BAR (pipeline sheet + library) ===================== */
.sheet-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 9px 14px; }
.sf-search {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--card); border: 1px solid var(--border2);
  border-radius: var(--r); padding: 0 10px; height: 31px;
}
.sf-search svg { width: 13px; height: 13px; color: var(--text3); }
.sf-search input { border: none; background: none; outline: none; box-shadow: none; padding: 0; font-family: var(--sans); font-size: 12.5px; color: var(--text); width: 200px; max-width: 46vw; }
.sf-search input:focus { box-shadow: none; }
/* The input has no chrome of its own, so the pill around it shows the focus. */
.sf-search:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-ring); }
.sf-group { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.sf-label { font-size: 9.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.09em; color: var(--text3); margin-right: 2px; }
.sf-pill {
  font-family: var(--sans); font-size: 11.5px; font-weight: 600;
  color: var(--text2); background: var(--card);
  border: 1px solid var(--border); border-radius: 999px;
  padding: 3.5px 10px; cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast), background var(--t-fast);
}
.sf-pill:hover { border-color: var(--border3); color: var(--text); }
.sf-pill.on { color: #fff; background: var(--pc, var(--accent)); border-color: var(--pc, var(--accent)); }
.sf-clear {
  display: inline-flex; align-items: center; gap: 4px;
  font-family: var(--sans); font-size: 11.5px; font-weight: 600;
  color: var(--text3); background: none; border: none; cursor: pointer;
  padding: 4px 6px; border-radius: var(--r-sm);
}
.sf-clear:hover { background: var(--bg2); color: var(--text); }
.sf-clear svg { width: 12px; height: 12px; }
.sf-count { font-size: 11.5px; color: var(--text3); margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }

/* ===================== UTILITIES ===================== */
.flex-row { display: flex; align-items: center; gap: 10px; }
.flex-row.between { justify-content: space-between; }
.gap-sm { gap: 6px; } .gap-md { gap: 12px; }
.mt-12 { margin-top: 12px; } .mt-16 { margin-top: 16px; } .mt-24 { margin-top: 24px; }
.mb-8 { margin-bottom: 8px; } .mb-12 { margin-bottom: 12px; } .mb-16 { margin-bottom: 16px; }
.text-sm { font-size: 12px; }
.text-xs { font-size: 10.5px; }
.bold { font-weight: 600; }
.right { text-align: right; }
.ellipsis { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.serif { font-family: var(--serif); font-weight: 500; }
.scroll-x { overflow-x: auto; }

@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }
.spin { animation: spin 800ms linear infinite; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

/* ===================== RESPONSIVE ===================== */
/* Will works at 140% zoom on a scaled display, so the app is routinely laid
   out at 960–1000 CSS px. That is the width these breakpoints are tuned for,
   not a phone. */
@media (max-width: 1180px) {
  :root { --sidebar-w: 204px; --pad: 24px; }
  .grid-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .task-board { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 860px) {
  .dash-row { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  :root { --sidebar-w: 56px; --pad: 14px; }
  .sidebar { padding: 14px 7px; }
  .sidebar .brand-name, .sidebar .brand-sub, .sidebar .brand > div:last-child,
  .nav a span, .nav-label, .sidebar-foot .who span, .foot-btn span, .foot-btn kbd { display: none; }
  .sidebar .brand { justify-content: center; border-bottom: none; }
  .nav a { justify-content: center; padding: 9px 0; }
  .nav a.active::before { display: none; }
  .foot-actions { flex-direction: column; gap: 6px; }
  .page-header { padding-top: 14px; padding-bottom: 10px; }
  .page-header h1 { font-size: 23px; }
  .kpis { flex-direction: column; }
  .kpi-tile { border-right: none; border-bottom: 1px solid var(--border); }
  .kpi-tile:last-child { border-bottom: none; }
  .grid-3, .grid-2, .task-board { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr !important; }
  .funnel-row { grid-template-columns: 104px minmax(0, 1fr); }
  .funnel-meta { display: none; }
  .table-wrap table { min-width: 640px; }
}
