:root {
  --primary: #1b6b52;
  --primary-dark: #124a3b;
  --navy: #17221e;
  --text: #17221e;
  --muted: #66736d;
  --bg: #fffefa;
  --surface: #fffefa;
  --soft: #f1f4ed;
  --line: #dfe4df;
  /* The border a form control draws, a step stronger than --line so an empty
     input reads as somewhere to type. Defined here as well as in the console
     block because .field applies to every page: undefined, the whole
     "border: 1px solid var(--line-strong)" declaration is invalid and dropped,
     which left login, register and contact with invisible inputs. */
  --line-strong: #c8d1c8;
  --success: #1b6b52;
  --danger: #b42318;
  /* Four steps, smallest to largest. Every corner in the app picks one of
     these; the file had grown fifteen ad-hoc values (6, 7, 8, 9, 10, 11, 12,
     14, 18, 20, 24px) that no one could tell apart on purpose but that read
     as sloppiness when two of them sat side by side. --radius is the card
     step and keeps its name because it was already used in 23 places.
     Circles (50%) and pills (999px) are shapes, not steps, and stay as they
     are. The console block below retunes the two larger steps; anything used
     outside a console must be defined here or the declaration is dropped. */
  --radius-xs: 4px;
  --radius-sm: 8px;
  --radius-md: 12px;
  --radius: 18px;

  /* Pipeline-stage bar fills. Deliberately a shade lighter than the status-pill
     backgrounds they echo: the count badge sits in --muted, and on the pill
     tints that lands at 4.46:1, just under AA. These clear it (4.65 and 4.74)
     and read more quietly behind text, which is what a share bar wants. */
  --stage-bar-ok: #e0efe8;
  --stage-bar-over: #fbe8e5;

  /* ----------------------------------------------------------------------
     Two ramps, and everything else is mixed from them.
     The file used to pick colours one at a time, which is why three different
     greys sat next to each other on the same card and the sidebar still had
     blue-grey icons left over from before the green rebrand. A ramp makes
     "one step lighter" an actual operation rather than a guess.

     --green-500 is the brand green, unchanged to the byte. Every other green
     is that hue carried lighter or darker, so a hover state is the same colour
     the logo is, not a near-miss.

     The neutrals lean very slightly green (hue 150, saturation under 8%), so
     greys sit on the brand rather than fighting it — the usual trick for
     making a one-colour palette feel designed instead of plain.
     ---------------------------------------------------------------------- */
  --green-50:  #eff6f2;
  --green-100: #daebe2;
  --green-200: #b5d7c6;
  --green-300: #86bca4;
  --green-400: #4e9b7d;
  --green-500: #1b6b52;
  --green-600: #175c47;
  --green-700: #124a3b;
  --green-800: #0d3a2e;
  --green-900: #0a2b22;

  --n-0:   #ffffff;
  --n-25:  #fbfcfb;
  --n-50:  #f5f8f6;
  --n-100: #edf2ef;
  --n-200: #e3eae6;
  --n-300: #d2dcd6;
  --n-400: #adbab3;
  --n-500: #7d8b84;
  --n-600: #5c6a63;
  --n-700: #42504a;
  --n-800: #2b3630;
  --n-900: #19231e;
  --shadow: 0 20px 60px rgba(31, 52, 44, 0.1);
  --focus-ring: rgba(27, 107, 82, .14);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; color: var(--text); background: var(--bg); font-family: "DM Sans", Arial, sans-serif; line-height: 1.6; }
h1, h2, h3, p { margin-top: 0; }
h1, h2, h3, .brand { color: var(--navy); font-family: "Manrope", Arial, sans-serif; line-height: 1.15; }
h1 { font-size: clamp(2.6rem, 6vw, 4.6rem); letter-spacing: -.04em; }
h2 { font-size: clamp(2rem, 4vw, 3rem); letter-spacing: -.03em; }
h3 { font-size: 1.25rem; }
a { color: inherit; text-decoration: none; }
button, input, textarea, select { font: inherit; }
.container { width: min(1120px, calc(100% - 40px)); margin-inline: auto; }
.narrow { max-width: 820px; }
.section { padding: 72px 0; }
.soft-bg { background: var(--soft); }
.eyebrow { display: inline-block; margin-bottom: 10px; color: var(--primary); font-size: .76rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; }
.eyebrow.light { color: #d9ef9f; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; left: 16px; top: -100px; z-index: 100; padding: 10px 14px; background: var(--navy); color: white; }
.skip-link:focus { top: 16px; }

.button { display: inline-flex; min-height: 48px; align-items: center; justify-content: center; padding: 10px 22px; border: 1px solid var(--primary); border-radius: 999px; background: var(--primary); color: white; font-weight: 700; cursor: pointer; transition: background .2s, border-color .2s, box-shadow .2s, transform .2s; }
.button:hover { background: var(--primary-dark); transform: translateY(-1px); }
.button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.button:disabled { opacity: .65; cursor: wait; transform: none; }
.button-small { min-height: 38px; padding: 7px 14px; font-size: .88rem; }
.button-full { width: 100%; }
.button-light { border-color: #d9ef9f; background: #d9ef9f; color: var(--navy); }
.button-secondary { border-color: var(--line); background: white; color: var(--primary); }
.button-secondary:hover { background: var(--soft); border-color: var(--primary); }
/* Author `display: inline-flex` above outranks the UA's [hidden] rule, so restate it
   explicitly — otherwise a hidden .button (the verify-email login link) still shows. */
.button[hidden] { display: none; }
.text-link { color: var(--primary); font-weight: 700; }

.site-header { position: relative; z-index: 20; border-bottom: 1px solid rgba(23,34,30,.08); background: rgba(255,254,250,.95); }
.nav-wrap { min-height: 72px; display: flex; align-items: center; justify-content: space-between; gap: 24px; }
.brand { display: inline-flex; align-items: center; gap: 9px; color: var(--navy); font-size: 1.12rem; font-weight: 800; }
.brand-mark { display: inline-grid; width: 34px; height: 34px; place-items: center; border-radius: 10px 3px 10px 3px; background: #d9ef9f; color: var(--navy); font-size: .84rem; }
.brand-product { padding: 2px 7px; border: 1px solid #c9d5cf; border-radius: 999px; color: var(--primary); font: 800 .62rem/1.5 "DM Sans", Arial, sans-serif; letter-spacing: .08em; }
.brand-product-light { border-color: #506159; color: #d9ef9f; }
.brand-light { color: white; }
.nav-links { display: flex; align-items: center; gap: 24px; color: #475569; font-size: .94rem; font-weight: 600; }
.nav-links > a:not(.button):hover { color: var(--primary); }
.nav-toggle { display: none; padding: 8px; border: 0; background: transparent; cursor: pointer; }
.nav-toggle span:not(.sr-only) { display: block; width: 22px; height: 2px; margin: 5px; background: var(--navy); }

.hero { position: relative; overflow: hidden; background: linear-gradient(145deg, #fffefa 0%, #f3f5e8 100%); }
.hero-glow { position: absolute; display: block; width: 520px; height: 520px; right: -150px; top: -170px; border-radius: 50%; background: #d9ef9f; opacity: .3; }
.hero-grid { min-height: 650px; display: grid; grid-template-columns: 1.1fr .9fr; align-items: center; gap: 64px; padding: 76px 0; }
.hero-copy h1 { max-width: 720px; margin: 16px 0 22px; }
.hero-copy > p { max-width: 620px; color: var(--muted); font-size: 1.12rem; }
.hero-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 22px; margin-top: 30px; }
.trust-row { display: flex; flex-wrap: wrap; gap: 20px; margin-top: 38px; color: var(--muted); font-size: .82rem; font-weight: 700; }
.trust-row span::before { content: "✓"; margin-right: 6px; color: var(--success); }
.hero-visual { position: relative; height: 440px; }
.orbit { position: absolute; display: block; border: 1px solid rgba(27,107,82,.22); border-radius: 50%; }
.orbit-one { width: 390px; height: 390px; top: 25px; left: 0; }
.orbit-two { width: 285px; height: 285px; top: 78px; left: 52px; border-style: dashed; }
.visual-pill { position: absolute; top: 48px; right: 8px; display: block; padding: 9px 16px; border-radius: 999px; background: var(--navy); color: white; font-size: .78rem; font-weight: 700; transform: rotate(5deg); }
.visual-card { position: absolute; border: 1px solid rgba(255,255,255,.8); border-radius: var(--radius); background: rgba(255,255,255,.88); box-shadow: var(--shadow); }
.card-main { width: 280px; left: 55px; top: 82px; padding: 28px; border-radius: 26px 8px 26px 8px; transform: rotate(-2deg); }
.mini-label { color: var(--muted); font-size: .76rem; font-weight: 700; text-transform: uppercase; }
.card-main strong { display: block; margin: 5px 0 20px; color: var(--navy); font-size: 2.8rem; }
.chart-bars { height: 80px; display: flex; align-items: flex-end; gap: 8px; }
.chart-bars i { width: 24px; border-radius: var(--radius-xs) var(--radius-xs) 0 0; background: var(--primary); }
.chart-bars i:nth-child(1) { height: 34%; opacity: .35; }.chart-bars i:nth-child(2) { height: 52%; opacity: .45; }.chart-bars i:nth-child(3) { height: 43%; opacity: .55; }.chart-bars i:nth-child(4) { height: 68%; opacity: .7; }.chart-bars i:nth-child(5) { height: 78%; opacity: .85; }.chart-bars i:nth-child(6) { height: 100%; }
.card-float { right: -8px; bottom: 58px; display: flex; align-items: center; gap: 11px; padding: 14px 18px; }
.card-float strong, .card-float small { display: block; }.card-float small { color: var(--muted); }
.status-dot { width: 10px; height: 10px; border-radius: 50%; background: #22c55e; }

.section-heading { max-width: 680px; margin-bottom: 38px; }
.section-heading h2 { margin: 10px 0; }.section-heading p { color: var(--muted); font-size: 1.05rem; }
.card-grid { display: grid; gap: 18px; }.card-grid.three { grid-template-columns: repeat(3, 1fr); }
.feature-card, .value-card { padding: 28px; border: 1px solid var(--line); border-radius: var(--radius); background: white; box-shadow: var(--shadow); }
.feature-card.featured { border-color: var(--primary); background: var(--primary); color: white; transform: translateY(-10px); }
.card-number { color: var(--primary); font-size: .78rem; font-weight: 700; }
.feature-card h3 { margin: 46px 0 12px; }.feature-card p, .value-card p { color: var(--muted); }.feature-card a { color: var(--primary); font-weight: 700; }.feature-card.featured h3 { color: white; }.feature-card.featured p { color: var(--line); }.feature-card.featured a, .feature-card.featured .card-number { color: #d9ef9f; }
.section-dark { background: var(--navy); color: white; }
.section-dark h2, .section-dark h3 { color: white; }
.stats-grid { display: grid; grid-template-columns: repeat(3, 1fr) 1.7fr; gap: 28px; align-items: center; }
.stats-grid strong { display: block; color: #d9ef9f; font-size: 2.4rem; }.stats-grid span { color: #acb9b4; }
blockquote { margin: 0; padding-left: 24px; border-left: 2px solid #64748b; font-size: 1.08rem; font-weight: 600; }
blockquote cite { display: block; margin-top: 14px; color: #aab6ca; font-size: .8rem; font-style: normal; font-weight: 400; }
.cta-panel { display: flex; align-items: center; justify-content: space-between; gap: 30px; padding: 40px; border-radius: var(--radius); background: var(--primary); color: white; }
.cta-panel h2 { margin: 8px 0 0; color: white; }
.cta-panel .eyebrow { color: #d9ef9f; }

/* CRM homepage */
.crm-hero { min-height: 740px; border-bottom: 1px solid #dde7e1; background: var(--soft); }
.crm-hero::before { content: ""; position: absolute; width: 720px; height: 720px; right: -170px; top: -260px; border-radius: 50%; background: radial-gradient(circle, rgba(190, 232, 161, .55) 0%, rgba(217, 239, 159, .18) 48%, transparent 70%); }
.crm-hero-grid { position: absolute; inset: 0; opacity: .33; background-image: linear-gradient(rgba(27,107,82,.07) 1px, transparent 1px), linear-gradient(90deg, rgba(27,107,82,.07) 1px, transparent 1px); background-size: 44px 44px; mask-image: linear-gradient(to right, transparent 0%, black 50%, black 100%); }
.crm-hero .crm-hero-layout { width: min(1240px, calc(100% - 40px)); min-height: 740px; grid-template-columns: .82fr 1.18fr; gap: 52px; padding: 74px 0 92px; }
.crm-hero-copy { position: relative; z-index: 3; }
.crm-hero-copy h1 { max-width: 610px; margin: 17px 0 23px; font-size: clamp(3rem, 5.25vw, 4.7rem); line-height: 1.04; letter-spacing: -.055em; }
.crm-hero-copy > p { max-width: 570px; font-size: 1.12rem; line-height: 1.7; }
.crm-eyebrow { display: inline-flex; align-items: center; gap: 8px; padding: 6px 10px 6px 8px; border: 1px solid #c8ded2; border-radius: 999px; background: rgba(255,255,255,.72); letter-spacing: .08em; }
.crm-eyebrow i { width: 7px; height: 7px; border-radius: 50%; background: #3caf75; box-shadow: 0 0 0 4px rgba(60,175,117,.13); }
.crm-primary-cta { gap: 15px; min-height: 54px; padding-inline: 25px; box-shadow: 0 12px 28px rgba(27,107,82,.2); }
.crm-primary-cta span, .crm-final-cta .button span { font-size: 1.2rem; transition: transform .2s; }
.crm-primary-cta:hover span, .crm-final-cta .button:hover span { transform: translateX(3px); }
.crm-demo-link { display: inline-flex; align-items: center; gap: 10px; color: var(--navy); font-weight: 700; }
.crm-play { display: inline-grid; width: 38px; height: 38px; place-items: center; border: 1px solid #cbd8d1; border-radius: 50%; background: white; color: var(--primary); font-size: .68rem; box-shadow: 0 8px 18px rgba(31,52,44,.08); }
.crm-trust-row { display: flex; flex-wrap: wrap; gap: 10px 20px; margin-top: 34px; color: #64746c; font-size: .79rem; font-weight: 700; }
.crm-trust-row span::before { content: "✓"; display: inline-grid; width: 18px; height: 18px; margin-right: 6px; place-items: center; border-radius: 50%; background: #e1f2e8; color: var(--primary); font-size: .68rem; }

.crm-preview-wrap { position: relative; z-index: 2; min-width: 0; padding: 34px 0 16px; }
.crm-preview-glow { position: absolute; width: 82%; height: 74%; left: 8%; top: 15%; border-radius: 50%; background: rgba(188,229,159,.5); filter: blur(45px); }
.crm-app-window { position: relative; z-index: 2; overflow: hidden; border: 1px solid #cedbd4; border-radius: var(--radius); background: white; box-shadow: 0 36px 80px rgba(24,62,47,.18), 0 3px 12px rgba(24,62,47,.1); transform: perspective(1200px) rotateY(-2deg) rotateX(1deg); transform-origin: center; }
.crm-window-bar { height: 48px; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; padding: 0 16px; border-bottom: 1px solid #e6ece8; background: var(--surface); color: #6e7b75; font-size: .68rem; font-weight: 800; letter-spacing: .06em; }
.crm-window-dots { display: flex; gap: 5px; }.crm-window-dots i { width: 7px; height: 7px; border-radius: 50%; background: #d9dfdb; }.crm-window-dots i:first-child { background: #ee8d76; }.crm-window-dots i:nth-child(2) { background: #efca66; }.crm-window-dots i:last-child { background: #78c99a; }
.crm-window-user { justify-self: end; display: grid; width: 27px; height: 27px; place-items: center; border-radius: 50%; background: #d9ef9f; color: var(--navy); font-size: .59rem; }
.crm-app-body { height: 442px; display: grid; grid-template-columns: 55px 1fr; }
.crm-preview-sidebar { display: flex; align-items: center; flex-direction: column; gap: 15px; padding: 14px 8px; border-right: 1px solid #e5ebe7; background: #173b30; }
.crm-preview-sidebar strong { display: grid; width: 27px; height: 27px; margin-bottom: 9px; place-items: center; border-radius: 8px 2px 8px 2px; background: #d9ef9f; color: var(--navy); font-size: .68rem; }
.crm-preview-sidebar span { display: grid; width: 29px; height: 29px; place-items: center; border-radius: var(--radius-sm); color: #91aaa0; font-size: .8rem; }.crm-preview-sidebar span.is-active { background: rgba(217,239,159,.15); color: #d9ef9f; }.crm-preview-sidebar .crm-sidebar-bottom { margin-top: auto; }
.crm-preview-main { min-width: 0; padding: 21px; background: var(--soft); }
.crm-preview-heading { display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px; }.crm-preview-heading small, .crm-preview-heading strong { display: block; }.crm-preview-heading small { color: #85928c; font-size: .5rem; font-weight: 800; letter-spacing: .12em; }.crm-preview-heading strong { color: var(--navy); font: 800 1.05rem/1.5 "Manrope", Arial, sans-serif; }.crm-preview-heading button { padding: 7px 11px; border: 0; border-radius: var(--radius-sm); background: var(--primary); color: white; font-size: .65rem; font-weight: 700; }
.crm-kpi-grid { display: grid; grid-template-columns: repeat(3,1fr); gap: 9px; }.crm-kpi-grid article { padding: 11px 12px; border: 1px solid #e1e8e4; border-radius: var(--radius-sm); background: white; }.crm-kpi-grid span, .crm-kpi-grid small, .crm-kpi-grid strong { display: block; }.crm-kpi-grid span { color: #7c8a83; font-size: .56rem; font-weight: 700; }.crm-kpi-grid strong { margin: 3px 0; color: var(--navy); font: 800 1.28rem "Manrope", Arial, sans-serif; }.crm-kpi-grid small { color: #6e7d76; font-size: .49rem; }.crm-kpi-grid .up { display: inline-block; width: 5px; height: 5px; margin-right: 3px; border-radius: 50%; background: #4ab57d; }
.crm-pipeline-head { display: flex; align-items: center; justify-content: space-between; margin: 17px 0 8px; }.crm-pipeline-head strong { color: var(--navy); font-size: .68rem; }.crm-pipeline-head span { color: var(--primary); font-size: .52rem; font-weight: 700; }
.crm-pipeline { display: grid; grid-template-columns: repeat(3,1fr); gap: 8px; }.crm-pipeline > section { min-width: 0; padding: 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--soft); }.crm-pipeline section > header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 7px; color: #68766f; font-size: .52rem; font-weight: 800; }.crm-pipeline section > header span { display: flex; align-items: center; }.crm-pipeline section > header i { width: 6px; height: 6px; margin-right: 4px; border-radius: 50%; }.dot-new { background: #6baad5; }.dot-contacted { background: #e1b14f; }.dot-qualified { background: #55ad7d; }.crm-pipeline section > header b { font-size: .5rem; }
.crm-pipeline article { display: flex; align-items: center; justify-content: space-between; gap: 5px; margin-top: 6px; padding: 8px; border: 1px solid #e5eae7; border-radius: var(--radius-sm); background: white; box-shadow: 0 3px 8px rgba(36,57,48,.035); }.crm-pipeline article div { min-width: 0; }.crm-pipeline article strong, .crm-pipeline article small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.crm-pipeline article strong { color: var(--navy); font-size: .55rem; }.crm-pipeline article small { margin-top: 2px; color: #89958f; font-size: .46rem; }.crm-pipeline article > span { flex: none; display: grid; width: 21px; height: 21px; place-items: center; border-radius: 50%; background: #eaf2e6; color: #35584b; font-size: .42rem; font-weight: 800; }.crm-pipeline .crm-hot-lead { border-color: #c8dfd1; box-shadow: 0 0 0 2px rgba(58,151,103,.06); }
.crm-floating-card { position: absolute; z-index: 4; display: flex; align-items: center; gap: 11px; padding: 11px 14px; border: 1px solid rgba(208,221,214,.95); border-radius: var(--radius-md); background: rgba(255,255,255,.95); box-shadow: 0 15px 35px rgba(26,60,47,.15); backdrop-filter: blur(12px); }.crm-floating-card strong, .crm-floating-card small { display: block; }.crm-floating-card strong { color: var(--navy); font-size: .7rem; }.crm-floating-card small { color: #75827c; font-size: .54rem; }.crm-owner-card { left: -28px; bottom: -9px; }.crm-followup-card { right: -20px; top: 8px; }.crm-followup-card > span { display: grid; width: 28px; height: 28px; place-items: center; border-radius: 50%; background: #e2f4e9; color: var(--primary); font-size: .7rem; font-weight: 900; }
.crm-avatar-stack { display: flex; padding-left: 11px; }.crm-avatar-stack i { display: grid; width: 26px; height: 26px; margin-left: -11px; place-items: center; border: 2px solid white; border-radius: 50%; background: #d9ef9f; color: var(--navy); font-size: .45rem; font-style: normal; font-weight: 800; }.crm-avatar-stack i:nth-child(2) { background: #d8e7f4; }.crm-avatar-stack i:nth-child(3) { background: var(--danger-bg); }

.crm-confidence-bar { padding: 24px 0; border-bottom: 1px solid #e0e7e3; background: white; }.crm-confidence-bar .container { display: flex; align-items: center; justify-content: space-between; gap: 30px; }.crm-confidence-bar p { margin: 0; color: #738079; font-size: .78rem; font-weight: 700; }.crm-confidence-bar div div { display: flex; align-items: center; gap: 19px; color: #2f4139; font-size: .76rem; font-weight: 800; }.crm-confidence-bar div div i { width: 3px; height: 3px; border-radius: 50%; background: #a9b8b0; }
.crm-features-section { padding: 104px 0; background: #fff; }.crm-section-heading { max-width: 720px; margin: 0 auto 52px; text-align: center; }.crm-section-heading h2 { margin: 10px 0 13px; }.crm-section-heading p { max-width: 650px; margin-inline: auto; }
.crm-bento-grid { display: grid; grid-template-columns: repeat(2,1fr); gap: 18px; }.crm-bento-card { position: relative; min-height: 390px; overflow: hidden; padding: 31px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--soft); }.crm-bento-card h3 { margin: 12px 0 9px; font-size: 1.42rem; }.crm-bento-card p { max-width: 520px; margin-bottom: 0; color: var(--muted); }.crm-feature-icon { display: grid; width: 38px; height: 38px; place-items: center; border: 1px solid #cfe0d6; border-radius: var(--radius-md); background: white; color: var(--primary); font-weight: 900; box-shadow: 0 6px 14px rgba(31,52,44,.05); }.crm-bento-large, .crm-bento-wide { grid-column: 1 / -1; min-height: 350px; }.crm-bento-large { display: grid; grid-template-columns: .9fr 1.1fr; gap: 50px; align-items: center; background: linear-gradient(135deg,#f4f9f1,var(--soft)); }.crm-card-copy { position: relative; z-index: 2; }
.crm-source-visual { position: relative; display: grid; gap: 10px; align-content: center; height: 250px; }.crm-source-visual::before { content: ""; position: absolute; width: 1px; height: 150px; left: 50%; top: 50%; background: #bed4c8; transform: translate(-50%,-50%); }.crm-source-visual span { position: relative; z-index: 2; display: grid; grid-template-columns: 38px 1fr auto; gap: 11px; align-items: center; padding: 13px 15px; border: 1px solid #d8e2dd; border-radius: var(--radius-md); background: white; color: var(--navy); font-size: .79rem; font-weight: 800; box-shadow: 0 9px 25px rgba(35,67,54,.08); }.crm-source-visual span:nth-child(1) { margin-left: 18px; }.crm-source-visual span:nth-child(2) { margin-right: 25px; }.crm-source-visual span:nth-child(3) { margin-left: 35px; }.crm-source-visual span i { display: grid; width: 34px; height: 34px; place-items: center; border-radius: var(--radius-sm); color: white; font-style: normal; }.source-meta { background: #3b70ce; }.source-csv { background: #e39b44; }.source-manual { background: var(--primary); }.crm-source-visual span small { color: #7d8a84; font-size: .65rem; font-weight: 600; }.crm-source-visual b { position: absolute; z-index: 3; right: -7px; top: 50%; width: 15px; height: 15px; border: 4px solid white; border-radius: 50%; background: #4bb57e; transform: translateY(-50%); box-shadow: 0 0 0 1px #bed5c8; }
.crm-assignment-visual { position: absolute; left: 30px; right: 30px; bottom: 30px; display: grid; grid-template-columns: 1fr auto 1fr; gap: 10px; align-items: center; }.crm-assignment-visual > div { display: flex; align-items: center; gap: 9px; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: white; }.crm-assignment-visual > div > span { flex: none; display: grid; width: 34px; height: 34px; place-items: center; border-radius: 50%; background: #e9eee9; color: var(--navy); font-size: .58rem; font-weight: 800; }.crm-assignment-visual > .assigned-rep { border-color: #bddcc9; box-shadow: 0 8px 20px rgba(41,112,82,.08); }.crm-assignment-visual > .assigned-rep > span { background: #d9ef9f; }.crm-assignment-visual p { min-width: 0; }.crm-assignment-visual strong, .crm-assignment-visual small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }.crm-assignment-visual strong { font-size: .67rem; }.crm-assignment-visual small { color: var(--muted); font-size: .51rem; }.crm-assignment-visual > i { color: var(--primary); font-style: normal; font-weight: 900; }
.crm-timeline-visual { position: absolute; left: 31px; right: 31px; bottom: 31px; display: grid; grid-template-columns: 22px 1fr; column-gap: 10px; row-gap: 14px; align-items: start; }.crm-timeline-visual::before { content: ""; position: absolute; width: 1px; left: 10px; top: 12px; bottom: 12px; background: #bad1c5; }.crm-timeline-visual i { position: relative; z-index: 2; width: 21px; height: 21px; border: 6px solid #dff0e6; border-radius: 50%; background: var(--primary); }.crm-timeline-visual div { padding: 10px 12px; border: 1px solid #dde5e1; border-radius: var(--radius-sm); background: white; }.crm-timeline-visual strong, .crm-timeline-visual small { display: block; }.crm-timeline-visual strong { font-size: .71rem; }.crm-timeline-visual small { margin-top: 2px; color: var(--muted); font-size: .55rem; }
.crm-bento-wide { display: grid; grid-template-columns: .8fr 1.2fr; gap: 42px; align-items: center; min-height: 290px; background: #173b30; color: white; }.crm-bento-wide h3 { color: white; }.crm-bento-wide p { color: #b9cbc3; }.crm-bento-wide .crm-feature-icon { border-color: #47695d; background: #254c3f; color: #d9ef9f; }.crm-stage-track { display: grid; grid-template-columns: repeat(4,1fr); gap: 7px; }.crm-stage-track span { position: relative; display: flex; align-items: center; flex-direction: column; gap: 8px; padding: 22px 8px 16px; border: 1px solid #45655a; border-radius: var(--radius-md); background: #23483c; color: #c7d7d0; font-size: .65rem; font-weight: 700; }.crm-stage-track span::after { content: ""; position: absolute; width: 8px; height: 8px; right: -8px; top: 50%; border-top: 1px solid #799188; border-right: 1px solid #799188; transform: rotate(45deg); }.crm-stage-track span:last-child::after { display: none; }.crm-stage-track i { width: 8px; height: 8px; border-radius: 50%; background: #6faad3; }.crm-stage-track span:nth-child(2) i { background: #e6b85e; }.crm-stage-track span:nth-child(3) i { background: #72c497; }.crm-stage-track span:nth-child(4) i { background: #d9ef9f; }.crm-stage-track b { color: white; font: 800 1.45rem "Manrope",Arial,sans-serif; }

.crm-workflow-section { padding: 110px 0; background: #173b30; color: white; }.crm-workflow-grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: 100px; align-items: center; }.crm-workflow-copy h2 { margin: 11px 0 18px; color: white; }.crm-workflow-copy p { max-width: 500px; margin-bottom: 30px; color: #b5c7bf; }.crm-steps { margin: 0; padding: 0; list-style: none; }.crm-steps li { display: grid; grid-template-columns: 54px 1fr; gap: 22px; padding: 25px 0; border-bottom: 1px solid #3a594e; }.crm-steps li:first-child { border-top: 1px solid #3a594e; }.crm-steps li > span { display: grid; width: 49px; height: 49px; place-items: center; border: 1px solid #527064; border-radius: 50%; color: #d9ef9f; font-size: .72rem; font-weight: 800; }.crm-steps h3 { margin: 1px 0 6px; color: white; font-size: 1.15rem; }.crm-steps p { margin: 0; color: #afc0b9; font-size: .9rem; }
.crm-focus-section { padding: 115px 0; background: var(--soft); }.crm-focus-grid { display: grid; grid-template-columns: 1.05fr .95fr; gap: 105px; align-items: center; }.crm-focus-copy h2 { margin: 10px 0 18px; }.crm-focus-copy > p { color: var(--muted); font-size: 1.05rem; }.crm-focus-copy ul { display: grid; gap: 9px; margin: 25px 0 28px; padding: 0; list-style: none; }.crm-focus-copy li { color: #34483f; font-weight: 700; }.crm-focus-copy li::before { content: "✓"; display: inline-grid; width: 20px; height: 20px; margin-right: 9px; place-items: center; border-radius: 50%; background: #dcefe4; color: var(--primary); font-size: .65rem; }
.crm-contact-visual { position: relative; padding: 28px; border: 1px solid #d9e2dd; border-radius: var(--radius); background: white; box-shadow: 0 30px 60px rgba(31,52,44,.1); }.crm-contact-visual::before { content: ""; position: absolute; z-index: -1; width: 70%; height: 70%; left: -32px; bottom: -32px; border-radius: var(--radius); background: #d9ef9f; opacity: .6; }.crm-contact-header { display: grid; grid-template-columns: 47px 1fr auto; gap: 12px; align-items: center; padding-bottom: 21px; border-bottom: 1px solid var(--line); }.crm-contact-header > span { display: grid; width: 47px; height: 47px; place-items: center; border-radius: 50%; background: #d9ef9f; color: var(--navy); font-size: .75rem; font-weight: 800; }.crm-contact-header strong, .crm-contact-header small { display: block; }.crm-contact-header small { color: var(--primary); font-size: .68rem; font-weight: 700; }.crm-contact-header > i { color: var(--muted); font-style: normal; letter-spacing: 2px; }.crm-contact-details { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 20px 0; }.crm-contact-details span { padding: 12px; border-radius: var(--radius-sm); background: var(--soft); }.crm-contact-details small, .crm-contact-details strong { display: block; }.crm-contact-details small { color: var(--muted); font-size: .62rem; }.crm-contact-details strong { margin-top: 3px; font-size: .76rem; }.crm-next-action { display: flex; gap: 13px; padding: 17px; border: 1px solid #bcdcc9; border-radius: var(--radius-md); background: var(--success-bg); }.crm-next-action > span { flex: none; display: grid; width: 33px; height: 33px; place-items: center; border-radius: 50%; background: var(--primary); color: white; font-size: .7rem; }.crm-next-action small, .crm-next-action strong { display: block; }.crm-next-action small { color: #678076; font-size: .57rem; font-weight: 800; letter-spacing: .08em; }.crm-next-action strong { margin-top: 3px; font-size: .83rem; }.crm-next-action p { margin: 1px 0 0; color: var(--muted); font-size: .67rem; }.crm-mini-activity { display: flex; gap: 12px; margin-top: 18px; padding: 13px; border-top: 1px solid var(--line); }.crm-mini-activity i { width: 9px; height: 9px; margin-top: 5px; border-radius: 50%; background: #60b487; box-shadow: 0 0 0 4px #e4f2e9; }.crm-mini-activity p { margin: 0; }.crm-mini-activity strong, .crm-mini-activity small { display: block; }.crm-mini-activity strong { font-size: .75rem; }.crm-mini-activity small { color: var(--muted); font-size: .62rem; }
.crm-final-cta-section { padding: 70px 0; background: white; }.crm-final-cta { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 45px; overflow: hidden; padding: 60px 65px; border-radius: var(--radius); background: var(--primary); color: white; }.crm-final-cta::after { content: ""; position: absolute; width: 300px; height: 300px; right: -80px; bottom: -200px; border: 55px solid rgba(217,239,159,.13); border-radius: 50%; }.crm-final-cta > * { position: relative; z-index: 2; }.crm-final-cta h2 { margin: 8px 0 10px; color: white; }.crm-final-cta p { max-width: 610px; margin: 0; color: #d2e1db; }.crm-final-cta .button { flex: none; gap: 14px; }

.page-hero { padding: 82px 0; border-bottom: 1px solid var(--line); background: #f7f5ee; text-align: center; }
.page-hero.compact { padding: 60px 0; }
.page-hero h1 { max-width: 850px; margin: 12px auto 18px; font-size: clamp(2.5rem, 5vw, 4rem); }
.page-hero p { max-width: 680px; margin-inline: auto; color: var(--muted); font-size: 1.08rem; }
.split { display: grid; grid-template-columns: .85fr 1.15fr; gap: 64px; }
.split h2 { margin-top: 10px; }.prose { color: var(--muted); font-size: 1.06rem; }.prose p + p { margin-top: 20px; }
.value-card > span { display: grid; width: 44px; height: 44px; place-items: center; border-radius: var(--radius-sm); background: var(--soft); color: var(--primary); }
.value-card h3 { margin: 26px 0 10px; }
.services-list { border-top: 1px solid var(--line); }
.service-row { display: grid; grid-template-columns: 80px 1fr; gap: 30px; padding: 50px 0; border-bottom: 1px solid var(--line); }
.service-row > span { color: var(--primary); font-weight: 700; }.service-row h2 { font-size: 2.2rem; }.service-row p { max-width: 760px; color: var(--muted); }
.tag-list { display: flex; flex-wrap: wrap; gap: 8px; margin: 24px 0 0; padding: 0; list-style: none; }.tag-list li { padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px; background: white; font-size: .82rem; font-weight: 600; }
.process ol { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; padding: 0; list-style: none; counter-reset: step; }
.process li { padding: 24px; border: 1px solid var(--line); border-radius: var(--radius); background: white; }.process li::before { counter-increment: step; content: "0" counter(step); display: block; margin-bottom: 30px; color: var(--primary); font-weight: 700; }.process p { margin: 8px 0 0; color: var(--muted); }

/* Pricing page */
.pricing-toggle { display: inline-flex; gap: 4px; margin: 0 auto 48px; padding: 5px; border: 1px solid var(--line); border-radius: 999px; background: var(--soft); }
.pricing-section .container { text-align: center; }
.pricing-toggle-option { padding: 10px 20px; border: 0; border-radius: 999px; background: transparent; color: var(--muted); font-weight: 700; cursor: pointer; }
.pricing-toggle-option.is-active { background: white; color: var(--navy); box-shadow: 0 4px 14px rgba(31,52,44,.1); }
.pricing-toggle-badge { margin-left: 7px; padding: 2px 8px; border-radius: 999px; background: #d9ef9f; color: var(--navy); font-size: .68rem; font-weight: 800; }
.pricing-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 24px; max-width: 900px; margin: 0 auto; text-align: left; }
.pricing-card { position: relative; padding: 36px; border: 1px solid var(--line); border-radius: var(--radius); background: white; box-shadow: var(--shadow); }
.pricing-card.is-featured { border-color: var(--primary); background: var(--primary); color: white; transform: translateY(-8px); }
.pricing-card.is-featured p, .pricing-card.is-featured .pricing-feature-list li { color: var(--line); }
.pricing-card.is-featured .pricing-amount span { color: #cfe2da; }
.pricing-ribbon { position: absolute; top: -13px; right: 28px; padding: 6px 14px; border-radius: 999px; background: #d9ef9f; color: var(--navy); font-size: .72rem; font-weight: 800; }
.pricing-card-head p { margin-top: 10px; color: var(--muted); font-size: .92rem; }
.pricing-amount { display: flex; align-items: flex-end; gap: 3px; margin: 14px 0 4px; }
.pricing-amount sup { margin-bottom: 10px; font-size: 1.2rem; font-weight: 700; }
.pricing-amount strong { font: 800 3rem "Manrope", Arial, sans-serif; letter-spacing: -.02em; }
.pricing-amount span { margin-bottom: 10px; color: var(--muted); font-weight: 700; }
.pricing-feature-list { display: grid; gap: 11px; margin: 26px 0 30px; padding: 0; list-style: none; }
.pricing-feature-list li { position: relative; padding-left: 26px; font-weight: 600; font-size: .92rem; }
.pricing-feature-list li::before { content: "✓"; position: absolute; left: 0; color: inherit; font-weight: 800; }
.pricing-card:not(.is-featured) .pricing-feature-list li::before { color: var(--primary); }
.pricing-note { max-width: 560px; margin: 30px auto 0; color: var(--muted); font-size: .85rem; }
.pricing-card.is-highlighted { box-shadow: 0 0 0 3px var(--primary), var(--shadow); }

.form-section { padding-top: 60px; }
.contact-grid { display: grid; grid-template-columns: .75fr 1.25fr; gap: 60px; }
.contact-grid aside > p { color: var(--muted); }.contact-detail { margin-top: 30px; }.contact-detail > span { display: block; margin-bottom: 4px; color: var(--muted); font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }.contact-detail a { color: var(--primary); font-weight: 700; }.contact-detail p { margin: 0; }
.form-card, .settings-card { padding: 32px; border: 1px solid var(--line); border-radius: var(--radius); background: white; box-shadow: var(--shadow); }
/* Cap the form measure. These cards run the full width of the console, so a
   single-column field stretched to match: the support ticket's subject line,
   its category dropdown and its description were each 1278px at 1440px, which
   reads as three grey bars rather than a form, and puts a select's chevron a
   metre from its label. 720px keeps a two-up .field-row at a comfortable
   352px per column. The card itself stays full-bleed, matching the tables. */
.settings-card .field, .settings-card .field-row { max-width: 720px; }
.field-row { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; }.field { margin-bottom: 18px; }.field label { display: flex; justify-content: space-between; margin-bottom: 7px; color: var(--navy); font-size: .88rem; font-weight: 700; }.field label em { color: var(--muted); font-style: normal; font-weight: 400; }
.field input, .field textarea, .field select, .table-heading select { width: 100%; min-height: 48px; padding: 11px 13px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); outline: none; background: white; color: var(--text); transition: border-color .15s ease, box-shadow .15s ease; }
.field textarea { resize: vertical; }.field input:focus, .field textarea:focus, .field select:focus, .table-heading select:focus { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }.field input:disabled, .field select:disabled { background: var(--soft); }.field small { color: var(--muted); }.field .field-error { display: block; min-height: 4px; margin-top: 4px; color: var(--danger); }.field .field-error.is-hint { color: var(--muted); }.field.has-error input, .field.has-error textarea, .field.has-error select { border-color: var(--danger); }
.form-alert, .admin-alert { display: none; margin-bottom: 16px; padding: 11px 13px; border-radius: var(--radius-sm); font-size: .9rem; }.form-alert.visible, .admin-alert.visible { display: block; }.form-alert.success, .admin-alert.success { background: var(--success-bg); color: var(--success); }.form-alert.error, .admin-alert.error { background: var(--danger-bg); color: var(--danger); }

.auth-page { min-height: 100vh; }.auth-page + .site-footer, body[data-page="login"] > .site-header, body[data-page="register"] > .site-header { display: none; }
.auth-shell { min-height: 100vh; display: grid; grid-template-columns: .9fr 1.1fr; }
.auth-intro { display: flex; flex-direction: column; justify-content: space-between; padding: 50px clamp(30px,6vw,75px); background: var(--primary); color: white; }.auth-intro h1 { max-width: 520px; margin: 14px 0; color: white; font-size: clamp(2.6rem,5vw,4.2rem); }.auth-intro p, .auth-intro small { color: #d5e2dd; }.register-art { background: #213d34; }
.auth-panel { display: grid; place-items: center; padding: 45px 24px; background: white; }.auth-form-wrap { width: min(500px,100%); }.auth-form-wrap h2 { margin: 8px 0; font-size: 2rem; }.auth-form-wrap > p { margin-bottom: 28px; color: var(--muted); }.auth-form-wrap > p a, .admin-link { color: var(--primary); font-weight: 700; }.admin-link { display: block; margin-top: 22px; text-align: center; font-size: .86rem; }

/* Signup wizard + payment step */
.wizard-wrap { width: min(540px, 100%); }
.signup-steps { display: flex; gap: 10px; margin: 0 0 30px; padding: 0; list-style: none; }
.signup-steps li { display: flex; align-items: center; gap: 8px; color: #b7c0ba; font-size: .84rem; font-weight: 700; }
.signup-steps li span { display: grid; width: 24px; height: 24px; place-items: center; border: 1px solid var(--line); border-radius: 50%; color: var(--muted); font-size: .76rem; }
.signup-steps li.is-active { color: var(--navy); }
.signup-steps li.is-active span { border-color: var(--primary); background: var(--primary); color: white; }
.signup-steps li.is-complete span { border-color: var(--primary); background: var(--primary); color: white; }
.signup-steps li.is-complete span::before { content: "✓"; }
.signup-steps li:not(:last-child)::after { content: ""; width: 24px; height: 1px; margin-left: 2px; background: var(--line); align-self: center; }

.plan-toggle { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 18px; }
.plan-toggle-option { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; padding: 14px 16px; border: 1.5px solid var(--line); border-radius: var(--radius-md); background: white; cursor: pointer; text-align: left; }
.plan-toggle-option span { color: var(--muted); font-size: .82rem; font-weight: 700; }
.plan-toggle-option strong { color: var(--navy); font-size: 1.15rem; font-weight: 800; }
.plan-toggle-option strong em { color: var(--muted); font-size: .74rem; font-style: normal; font-weight: 600; }
.plan-toggle-option.is-active { border-color: var(--primary); background: var(--soft); box-shadow: 0 0 0 3px rgba(27,107,82,.1); }
.plan-toggle-option.is-active span { color: var(--primary); }
.plan-save-badge { margin-left: 5px; padding: 1px 7px; border-radius: 999px; background: #d9ef9f; color: var(--navy); font-size: .64rem; font-weight: 800; }

.order-summary { margin-bottom: 20px; padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.order-summary-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; font-size: .9rem; }
.order-summary-row + .order-summary-row { margin-top: 6px; }
.order-summary-row.muted { color: var(--muted); font-size: .8rem; }
.order-summary-total { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 12px; padding-top: 12px; border-top: 1px dashed #c7d2cc; font-weight: 800; color: var(--navy); }
.order-summary-total strong { font-size: 1.2rem; }

.card-number-field { position: relative; }
.card-number-field input { padding-right: 44px; letter-spacing: .04em; font-variant-numeric: tabular-nums; }
.card-brand-icon { position: absolute; top: 50%; right: 13px; width: 26px; height: 17px; color: var(--muted); transform: translateY(-50%); }
.payment-secure-note { display: flex; align-items: center; gap: 7px; margin: 6px 0 22px; color: var(--muted); font-size: .8rem; }
.payment-secure-note svg { flex: none; width: 16px; height: 16px; color: var(--primary); }
.wizard-actions { display: grid; gap: 12px; }
.wizard-actions .text-button { justify-self: start; font-weight: 700; }
[data-plan-total-inline] { margin: 0 3px; }
.wizard-actions .button span, .signup-processing span { display: inline-block; }

/* Enterprise CRM app shell — scoped to logged-in workspaces so the marketing site keeps its own brand palette */
/**
 * The consoles, themed to match the marketing site.
 *
 * These were a warm beige-and-gold theme while the landing page was green, so
 * the two halves of the product did not look related. The values below are the
 * landing page's own greens rather than approximations of them — --primary is
 * literally the :root primary — which is what makes a lead page and the home
 * page read as one piece of software.
 *
 * Green is reserved for brand, primary actions, active navigation and positive
 * states. Surfaces stay white and near-white; a console that is green
 * everywhere is harder to read, not more branded.
 */
body[data-page="dashboard"], body[data-page="admin-dashboard"], body[data-page="supervisor-dashboard"], body[data-page="supervisor-dashboard"], body[data-page="admin-login"] {
  /* The console's semantic layer. Nothing below picks a hex: every value is a
     step on one of the two ramps in :root, so "a shade lighter" is a real
     operation and two surfaces meant to match cannot drift apart. */
  --primary: var(--green-500);
  --primary-dark: var(--green-700);
  --primary-hover: var(--green-600);
  --primary-light: var(--green-50);
  --primary-tint: var(--green-100);
  --primary-border: var(--green-200);
  /* Was gold, then the landing page's brighter green. Kept: it is the one
     colour allowed to be louder than the brand, used for the current step of
     a timeline and the active marker in the sidebar. */
  --accent: #2fa978;
  --accent-dark: var(--green-600);
  --accent-light: var(--green-50);

  --navy: var(--n-900);
  --text: var(--n-900);
  /* One step darker than before (#636f69 -> #5c6a63): secondary text on white
     now clears AA comfortably instead of sitting just over the line. */
  --muted: var(--n-600);
  --muted-strong: var(--n-700);
  /* A touch cooler and deeper than the old #f7f9f5. White cards have to read
     as lifted off the page, and they barely did against a background that was
     almost white itself. */
  --bg: var(--n-50);
  --surface: var(--n-0);
  --soft: var(--n-100);
  --line: var(--n-200);
  --line-strong: var(--n-300);

  /* Status colours stay semantic. A green "Lost" pill would be pretty and
     wrong, so only the neutral and positive ends of the scale are green.
     The tints are a half-step cleaner than before — same hue, less mud, so
     text sitting on them keeps its contrast. */
  --success: var(--green-600);
  --success-bg: #e4f1ea;
  --success-border: #c2e0d0;
  /* Qualified sits between contacted and won, so it reads as green but lighter
     than success. Named for the thing it marks — it used to be --purple, which
     stopped being true the moment it was not purple. */
  --qualified: #2b7a63;
  --qualified-bg: #e9f4ee;
  --qualified-border: #cbe6d9;
  --warning: #8a5d05;
  --warning-bg: #fcf3e2;
  --warning-border: #f0ddb4;
  /* Slate with a green lean rather than a primary blue: "New" should read as
     neutral information, not as another brand colour competing with the green. */
  --info: #3f6276;
  --info-bg: #eaf2f6;
  --info-border: #cfe0e9;
  --danger: #b42318;
  --danger-bg: #fdedea;
  --danger-border: #f5cdc7;

  /* The console runs a tighter scale than the marketing site: cards sit at
     10px, so the panel step collapses onto them rather than standing prouder
     than the card it is nested in. --radius-xs and --radius-sm are the same
     on both surfaces and are inherited from :root. */
  --radius-md: 10px;
  --radius: 10px;

  /* Five steps, and every raised thing picks one. Each is two shadows — a
     tight contact shadow plus a wide soft one — because a single blur reads
     as a smudge, and the pair is what makes a card look like it is resting on
     the page. Tinted with the darkest green rather than black: a neutral-black
     shadow over a green-tinted background goes grey and dirty. */
  --shadow-xs: 0 1px 2px rgba(13,42,33,.05);
  --shadow-sm: 0 1px 2px rgba(13,42,33,.05), 0 2px 6px -1px rgba(13,42,33,.05);
  --shadow: 0 1px 2px rgba(13,42,33,.04), 0 6px 16px -4px rgba(13,42,33,.07);
  --shadow-md: 0 2px 4px rgba(13,42,33,.04), 0 12px 24px -6px rgba(13,42,33,.09);
  --shadow-lg: 0 8px 20px -6px rgba(13,42,33,.10), 0 24px 48px -12px rgba(13,42,33,.14);
  --focus-ring: rgba(27,107,82,.20);

  /* Deeper than the old #123f32, and a gradient rather than a flat fill, so
     the rail reads as a surface with weight instead of a block of colour. */
  --sidebar-bg: var(--green-800);
  --sidebar-bg-deep: var(--green-900);
  --sidebar-text: #a7c3b6;
  --sidebar-text-dim: #8bab9d;
  --sidebar-active-bg: var(--green-500);
  --sidebar-accent: #ddf3a8;
  --sidebar-line: rgba(255,255,255,.08);

  /* One spacing scale, so the gap between a heading and its table is the same
     gap everywhere rather than whichever of 12, 14, 16 or 18px was typed. */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 22px;
  --space-6: 30px;
}
body[data-page="dashboard"] .button, body[data-page="admin-dashboard"] .button, body[data-page="supervisor-dashboard"] .button, body[data-page="admin-login"] .button { border-radius: var(--radius-sm); }
/* The four dialog cards read var(--surface) in their own rules now. They used
   to hardcode #fffefa and be corrected here, per console and per dialog --
   which covered two of the four on each side, and left the member console's
   "Add a transaction" with dark-mode labels on a light card. */
body[data-page="dashboard"] .lead-avatar, body[data-page="dashboard"] .remark-marker { background: var(--primary-light); color: var(--primary); }body[data-page="admin-dashboard"] .panel-orb,
body[data-page="supervisor-dashboard"] .panel-orb { background: rgba(255,255,255,.16); color: white; }

.user-chip { display: grid; flex: none; width: 36px; height: 36px; place-items: center; border-radius: 50%; background: var(--primary); color: white; font-weight: 700; line-height: 1; text-align: center; }.text-button { border: 0; background: none; color: var(--muted); cursor: pointer; }
.dashboard-welcome { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 28px; }.dashboard-welcome h1 { margin: 6px 0; font-size: 1.9rem; }.dashboard-welcome p { color: var(--muted); }.status-badge { padding: 7px 12px; border-radius: 999px; background: var(--success-bg); color: var(--success); font-size: .8rem; font-weight: 700; }.status-badge i { display: inline-block; width: 7px; height: 7px; margin-right: 6px; border-radius: 50%; background: var(--success); }
[data-workspace-panel][hidden] { display: none; }
.dashboard-grid { display: grid; grid-template-columns: 260px 1fr; gap: 22px; align-items: start; }.profile-summary { padding: 28px 22px; border: 1px solid var(--line); border-radius: var(--radius); background: white; text-align: center; }.avatar { display: grid; width: 78px; height: 78px; margin: 0 auto 18px; place-items: center; border-radius: 50%; background: var(--soft); color: var(--primary); font-size: 1.7rem; font-weight: 800; }.profile-summary h2 { margin-bottom: 4px; font-size: 1.25rem; }.profile-summary p { color: var(--muted); overflow-wrap: anywhere; }.profile-summary > span { display: block; padding-top: 18px; border-top: 1px solid var(--line); color: var(--muted); font-size: .78rem; }
.profile-summary > span.plan-chip { display: inline-block; margin: 4px 0 14px; padding: 6px 12px; border: 0; border-radius: 999px; background: var(--soft); color: var(--primary); font-size: .78rem; font-weight: 700; }.settings-stack { display: grid; gap: 20px; }.settings-card { box-shadow: none; }.card-heading { margin-bottom: 22px; padding-bottom: 18px; border-bottom: 1px solid var(--line); }.card-heading h2 { margin: 0 0 4px; font-size: 1.3rem; }.card-heading p { margin: 0; color: var(--muted); }
.lead-form-actions { display: flex; align-items: center; gap: 16px; }
.lead-selection-actions { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin-bottom: 14px; }
.lead-selection-actions > span { margin-right: auto; color: var(--muted); font-size: .8rem; }
.lead-selection-actions button:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.lead-delete-button { border-color: #c95f54; background: white; color: var(--danger); }
.lead-delete-button:hover { background: var(--danger-bg); color: var(--danger); }
.lead-select { width: 18px; height: 18px; margin: 0; accent-color: var(--primary); cursor: pointer; }
.phone-dialog { width: min(92vw, 430px); padding: 0; border: 0; border-radius: var(--radius); overflow: visible; background: transparent; box-shadow: 0 24px 70px rgba(23, 34, 30, .28); }
.phone-dialog::backdrop { background: rgba(23, 34, 30, .56); backdrop-filter: blur(3px); }
.phone-dialog-card { position: relative; padding: 32px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.phone-dialog-close-form { position: absolute; top: 13px; right: 13px; }
.phone-dialog-close { display: grid; width: 34px; height: 34px; padding: 0; place-items: center; border: 1px solid var(--line); border-radius: 50%; background: white; color: var(--muted); font-size: 1.35rem; line-height: 1; cursor: pointer; }
.phone-dialog-close:hover { border-color: var(--primary); color: var(--primary); }
.phone-dialog-card h2 { margin: 5px 0 0; font-size: 1.65rem; }
.phone-dialog-number { margin: 22px 0; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); color: var(--primary); font-size: 1.25rem; font-weight: 800; text-align: center; user-select: all; }
.phone-dialog-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.phone-copy-status { min-height: 20px; margin: 11px 0 0; color: var(--success); font-size: .82rem; text-align: center; }

.payment-request-preview { margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--line); }
.payment-request-preview-heading { margin-bottom: 16px; }
.payment-request-preview-grid { display: grid; grid-template-columns: repeat(2,1fr); gap: 14px 20px; margin-bottom: 18px; }
.payment-request-preview-grid span { display: block; margin-bottom: 3px; color: var(--muted); font-size: .7rem; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; }
.payment-request-preview-grid strong { color: var(--navy); font-size: .95rem; overflow-wrap: anywhere; }
.payment-request-preview-link { margin-bottom: 6px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); color: var(--primary); font-size: .82rem; font-weight: 700; word-break: break-all; user-select: all; }
.payment-request-preview-note { min-height: 18px; margin: 0 0 14px; color: var(--success); font-size: .78rem; }
.payment-request-preview-actions { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 16px; }

/* White in both themes, on purpose. A QR code is read by thresholding light
   against dark, so the quiet zone around it has to stay light -- a dark card
   behind dark modules is unscannable, and the failure is silent: the customer
   just points a phone at it and nothing happens. This is the one box in the
   consoles that must not follow the theme. */
.payment-qr-visual { display: grid; width: 200px; margin: 20px auto 0; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: white; place-items: center; }
.payment-qr-visual svg { width: 100%; height: 100%; }
.payment-qr-disclaimer { margin: 10px 0 18px; color: var(--muted); font-size: .74rem; font-weight: 700; text-align: center; text-transform: uppercase; letter-spacing: .04em; }
.payment-qr-details { display: grid; gap: 4px; margin-bottom: 18px; text-align: center; }
.payment-qr-details strong { color: var(--navy); font-size: 1.3rem; }
.payment-qr-details span { color: var(--muted); font-size: .84rem; }
.payment-qr-details .lead-status-pill { justify-self: center; margin-top: 4px; }
.remarks-dialog { width: min(94vw, 650px); max-height: min(88vh, 820px); padding: 0; border: 0; border-radius: var(--radius); background: transparent; box-shadow: 0 24px 70px rgba(23, 34, 30, .28); }
.remarks-dialog::backdrop { background: rgba(23, 34, 30, .56); backdrop-filter: blur(3px); }
.remarks-dialog-card { position: relative; max-height: min(88vh, 820px); padding: 32px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.remarks-dialog-heading { padding-right: 38px; }
.remarks-dialog-heading h2 { margin: 5px 0 6px; font-size: 1.8rem; }
.remarks-dialog-heading p { margin: 0; color: var(--muted); }
.remarks-dialog-heading strong { color: var(--navy); }
.remark-form { margin: 24px 0 28px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--soft); }
.remark-form .field { margin-bottom: 12px; }
.remark-form textarea { background: white; }
/* Five inline slots that read as one field: each keeps its own native placeholder, so the
   watermarks clear independently as they're filled, while the shared border/focus ring
   makes it look and behave like the single textarea it replaced. */
.remark-slots { display: flex; flex-wrap: wrap; align-content: flex-start; gap: 6px; width: 100%; min-height: 96px; padding: 9px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: white; transition: border-color .15s ease, box-shadow .15s ease; }
/* Author `display: flex` above outranks the UA's [hidden] rule, so restate it explicitly —
   without this the requirements box stays on screen after the first remark is saved. */
.remark-slots[hidden] { display: none; }
.remark-slots:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
/* min-width, not just flex-basis: flex-shrink would otherwise squeeze slots narrower than
   their own placeholder and clip it to "[Property Ty". They wrap instead of shrinking. */
.field .remark-slot { flex: 1 1 132px; width: auto; min-width: 132px; min-height: 34px; padding: 5px 9px; border: 1px dashed var(--line); border-radius: var(--radius-sm); background: transparent; color: var(--text); font: inherit; box-shadow: none; }
.field .remark-slot::placeholder { color: var(--muted); opacity: .6; }
.field .remark-slot:hover { border-color: var(--muted); }
.field .remark-slot:focus { border-style: solid; border-color: var(--primary); background: var(--soft); box-shadow: none; outline: none; }
.field.has-error .remark-slots { border-color: var(--danger); }
.field.has-error .remark-slot { border-color: var(--line); }
@media (max-width: 600px) {
  .remark-slots { min-height: 84px; }
}
.remark-form .form-alert { margin-bottom: 12px; }
.remarks-history { border-top: 1px solid var(--line); padding-top: 22px; }
.remarks-history-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.remarks-history-heading h3 { margin: 0; font-size: 1.08rem; }
.remarks-history-heading span { color: var(--muted); font-size: .78rem; font-weight: 700; }
.remarks-timeline { display: grid; }
.remark-item { position: relative; display: grid; grid-template-columns: 38px 1fr; gap: 13px; padding-bottom: 20px; }
.remark-item:not(:last-child)::before { content: ""; position: absolute; width: 1px; top: 36px; bottom: 0; left: 18px; background: var(--line); }
.remark-marker { position: relative; z-index: 1; display: grid; width: 38px; height: 38px; place-items: center; border-radius: 50%; background: #d9ef9f; color: var(--navy); font-size: .78rem; font-weight: 800; }
.remark-content { min-width: 0; padding: 10px 13px; border: 1px solid var(--line); border-radius: var(--radius-md); background: white; }
.remark-meta { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 5px 12px; }
.remark-meta strong { color: var(--navy); font-size: .84rem; }
.remark-meta time { color: var(--muted); font-size: .72rem; }
.remark-content p { margin: 7px 0 0; color: var(--text); font-size: .9rem; white-space: pre-wrap; overflow-wrap: anywhere; }
.remarks-empty { padding: 28px 18px; border: 1px dashed #b8c1bb; border-radius: var(--radius-md); color: var(--muted); text-align: center; }
.remarks-empty strong { display: block; color: var(--navy); }
.remarks-empty p { margin: 4px 0 0; font-size: .86rem; }
.account-section-heading { margin-bottom: 22px; }

/* Profile completion banner + identity documents. Built from existing tokens —
   the warning pair the status pills already use, and the card border/radius. */
.profile-alert { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 16px; padding: 16px 18px; border: 1px solid var(--warning); border-radius: var(--radius); background: var(--warning-bg); }
/* Author `display: flex` outranks the UA [hidden] rule, so restate it. */
.profile-alert[hidden] { display: none; }
.profile-alert-copy strong { display: block; color: var(--navy); font-size: .95rem; }
.profile-alert-copy p { margin: 3px 0 0; color: var(--warning); font-size: .84rem; }
.profile-alert-missing:empty { display: none; }
.profile-alert .button { flex: none; }
.profile-required-copy { margin: 8px 0 22px; color: var(--muted); }
/* Admin user details. Reuses the lead-detail cards; only these few additions. */
tr.is-clickable { cursor: pointer; }
.profile-missing-list { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.profile-missing-label { color: var(--muted); font-size: .72rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.profile-missing-item { padding: 3px 9px; border-radius: 999px; background: var(--warning-bg); color: var(--warning); font-size: .74rem; font-weight: 700; }
.admin-danger-card { border-color: var(--danger); }
.admin-danger-copy { margin: 8px 0 16px; color: var(--muted); font-size: .84rem; }
/* Says plainly that an admin tab is a view, not an editor. */
.lead-readonly-note { margin-bottom: 16px; padding: 10px 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); color: var(--muted); font-size: .82rem; }
.admin-danger-card .lead-delete-button[hidden] { display: none; }

.profile-doc-list { display: grid; gap: 10px; }
.profile-doc { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.profile-doc-info strong { display: block; color: var(--navy); font-size: .9rem; }
.profile-doc-info p { margin: 3px 0 0; color: var(--muted); font-size: .8rem; }
.profile-doc-info p.is-uploaded { color: var(--success); font-weight: 700; }
.profile-doc-actions { display: flex; flex: none; align-items: center; gap: 8px; }
.profile-doc-actions [hidden] { display: none; }

@media (max-width: 600px) {
  .profile-alert { flex-direction: column; align-items: stretch; }
  .profile-alert .button { width: 100%; }
  .profile-doc { flex-direction: column; align-items: stretch; }
  .profile-doc-actions { justify-content: stretch; }
  .profile-doc-actions .button { flex: 1; }
}
.account-section-heading h2 { margin: 4px 0 0; font-size: 1.8rem; }

.admin-login-page { min-height: 100vh; display: grid; place-items: center; padding: 28px; background: var(--soft); }.admin-login-card { width: min(440px,100%); padding: 38px; border: 1px solid var(--line); border-radius: var(--radius); background: white; box-shadow: var(--shadow); }/* The wordmark and the shield are one row. .brand is inline-flex, so left as
   direct children of the card the eyebrow ran onto the same line as the
   wordmark ("STUDIOMAAKRESTRICTED ACCESS") and the 32px margin-bottom that
   was meant to separate them did nothing, because vertical margins on an
   inline-level box are inert. The row owns the gap now. */
.admin-login-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 32px; }.admin-login-card h1 { margin: 8px 0; font-size: 2rem; }.admin-login-card > p { margin-bottom: 24px; color: var(--muted); }.admin-shield { flex: none; display: grid; width: 44px; height: 44px; place-items: center; border-radius: var(--radius-sm); background: var(--primary); color: white; font-weight: 800; }.back-link { display: block; margin-top: 22px; color: var(--muted); text-align: center; font-size: .84rem; }
.admin-layout { min-height: 100vh; display: grid; grid-template-columns: 236px 1fr; background: var(--bg); }
.admin-sidebar { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; padding: 22px 16px; background: var(--sidebar-bg); color: white; }
.admin-sidebar .brand { font-size: 1.02rem; }
.admin-sidebar nav { display: grid; gap: 3px; margin-top: 36px; }
.sidebar-nav-group { margin-top: 22px; padding: 0 13px 8px; color: #59648a; font-size: .68rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; }
.sidebar-nav-link { display: flex; align-items: center; gap: 11px; width: 100%; padding: 9px 12px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--sidebar-text); font-family: inherit; font-size: .92rem; font-weight: 600; text-align: left; text-decoration: none; cursor: pointer; }
.sidebar-nav-link svg { flex: none; width: 18px; height: 18px; color: #5c6889; }
.sidebar-nav-link:hover { background: rgba(255,255,255,.05); color: #e6e9f4; }
.sidebar-nav-link.active, .sidebar-nav-link.is-active { background: var(--sidebar-active-bg); color: white; }
.sidebar-nav-link.active svg, .sidebar-nav-link.is-active svg { color: var(--sidebar-accent); }
/* Leaves the console it sits in (admin -> supervisor, and back again). Set
   apart from the section links above it so the sidebar does not imply that
   clicking it switches an in-page section. */
.sidebar-nav-link-away { margin-top: 6px; padding-top: 13px; border-top: 1px solid rgba(255,255,255,.08); border-radius: 0 0 var(--radius-sm) var(--radius-sm); }
.sidebar-nav-away-icon { margin-left: auto; width: 13px !important; height: 13px !important; opacity: .55; }
.sidebar-nav-link-away:hover .sidebar-nav-away-icon { opacity: 1; }
.sidebar-logout { display: flex; align-items: center; gap: 10px; margin-top: auto; padding: 10px 12px; border: 1px solid rgba(255,255,255,.1); border-radius: var(--radius-sm); background: none; color: var(--sidebar-text); font-weight: 600; cursor: pointer; }
.sidebar-logout:hover { border-color: rgba(255,255,255,.2); color: white; }
.sidebar-logout svg { width: 16px; height: 16px; }

.admin-main { min-width: 0; padding: 30px clamp(20px,4vw,48px) 60px; }
/* The header is the product's name and the signed-in user, nothing else. It
   carried a page title too, which repeated the sidebar's active item and, on a
   detail screen, the name of the thing already on screen below it. With that
   gone the bar is one line tall, so the padding comes down to match. */
.admin-main > header { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding-bottom: 12px; margin-bottom: 16px; border-bottom: 1px solid var(--line); }
.admin-header-left { display: flex; align-items: center; gap: 14px; min-width: 0; }
.admin-menu-toggle { display: none; flex: none; align-items: center; justify-content: center; width: 34px; height: 34px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--muted); cursor: pointer; }
.admin-menu-toggle svg { width: 18px; height: 18px; }
.admin-menu-toggle:hover { border-color: var(--primary); color: var(--navy); }
.admin-menu-toggle[aria-expanded="true"] { border-color: var(--primary); color: var(--navy); background: var(--soft); }/* Admin console + user dashboard: sidebar becomes a dropdown menu opened via the 3-dot
   toggle, main content uses full width. Shared selector list so both dashboards stay on
   the exact same menu implementation rather than maintaining two copies of it. */
body[data-page="admin-dashboard"] .admin-layout,
body[data-page="dashboard"] .admin-layout,
body[data-page="supervisor-dashboard"] .admin-layout { display: block; position: relative; }body[data-page="admin-dashboard"] .admin-menu-toggle,
body[data-page="dashboard"] .admin-menu-toggle,
body[data-page="supervisor-dashboard"] .admin-menu-toggle { display: inline-flex; }body[data-page="admin-dashboard"] .admin-sidebar,
body[data-page="dashboard"] .admin-sidebar,
body[data-page="supervisor-dashboard"] .admin-sidebar { position: absolute; top: 84px; left: clamp(20px,4vw,48px); width: min(258px, calc(100vw - 40px)); max-height: calc(100vh - 110px); height: auto; overflow-x: hidden; overflow-y: auto; align-items: stretch; display: none; flex-direction: column; padding: 16px; border-radius: var(--radius); box-shadow: 0 24px 48px rgba(15,23,42,.28); z-index: 80; }body[data-page="admin-dashboard"] .admin-sidebar.is-open,
body[data-page="dashboard"] .admin-sidebar.is-open,
body[data-page="supervisor-dashboard"] .admin-sidebar.is-open { display: flex; animation: sidebarMenuIn .16s ease; }
@media (prefers-reduced-motion: no-preference) {
  @keyframes sidebarMenuIn { from { opacity: 0; transform: translateY(-4px) scale(.98); } to { opacity: 1; transform: none; } }
}
/* User dashboard's toggle sits at the top-right (next to the account chip) instead of
   admin's top-left, so the dropdown opens from the right edge instead of the left. */
body[data-page="dashboard"] .admin-sidebar { left: auto; right: clamp(20px,4vw,48px); }body[data-page="admin-dashboard"] .admin-sidebar nav,
body[data-page="dashboard"] .admin-sidebar nav,
body[data-page="supervisor-dashboard"] .admin-sidebar nav { display: grid; gap: 3px; margin: 18px 0 0; }body[data-page="admin-dashboard"] .admin-sidebar .sidebar-nav-link,
body[data-page="dashboard"] .admin-sidebar .sidebar-nav-link,
body[data-page="supervisor-dashboard"] .admin-sidebar .sidebar-nav-link { white-space: normal; }body[data-page="admin-dashboard"] .admin-sidebar .brand,
body[data-page="dashboard"] .admin-sidebar .brand,
body[data-page="supervisor-dashboard"] .admin-sidebar .brand { font-size: 1.02rem; }body[data-page="admin-dashboard"] .admin-sidebar .sidebar-logout,
body[data-page="dashboard"] .admin-sidebar .sidebar-logout,
body[data-page="supervisor-dashboard"] .admin-sidebar .sidebar-logout { margin: 18px 0 0; }
/* margin-left:auto rather than relying on the header's space-between: on a
   detail screen the page heading is hidden, leaving this as the only child,
   and space-between puts a lone child at the START. */
.admin-user { display: flex; align-items: center; gap: 10px; margin-left: auto; text-align: right; }
/* Scoped to the name block. Unscoped, this also hit .user-chip — a span —
   and display:block beat its display:grid, so place-items:center did nothing
   and the inherited text-align:right shoved the initial to the circle's edge. */
.admin-user > div strong, .admin-user > div span { display: block; }
.admin-user > div span { color: var(--muted); font-size: .76rem; }
.admin-section { display: none; }.admin-section.active { display: block; }
/* auto-fit rather than a fixed four: the overview now has five cards and the
   stats page has four, and a fixed count leaves one card stranded on its own
   row in whichever grid does not match it. */
/* 170px, not 186px: the admin overview has five cards, and at a 942px grid a
 * 186px floor fitted only four, so the fifth dropped to a row of its own and
 * stood taller than the rest because nothing on that row stretched it. Only
 * widths above 900px use this track list - below that the media queries at the
 * end of the file take over with an explicit two-up, then one-up. */
.metric-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 14px; }
/* The cards are buttons now — they navigate — so the element resets its own
   type styling and gains the affordances a control needs. */
.metric-grid .metric-card { display: flex; width: 100%; flex-direction: column; gap: 12px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); font: inherit; text-align: left; cursor: pointer; transition: border-color .15s ease, transform .15s ease, box-shadow .15s ease; }
.metric-grid .metric-card:hover { border-color: var(--primary); transform: translateY(-2px); }
.metric-grid .metric-card:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
.metric-grid .metric-card > span:first-child { display: flex; align-items: center; justify-content: space-between; color: var(--muted); font-size: .8rem; font-weight: 600; }
.metric-icon { display: grid; width: 32px; height: 32px; place-items: center; border-radius: var(--radius-sm); background: var(--primary-light); color: var(--primary); }
.metric-icon svg { width: 17px; height: 17px; }
.metric-grid strong { display: block; color: var(--navy); font-size: 1.9rem; }
/* The stats page reuses the metric grid, but its tiles are readouts rather than
   navigation — no hover lift, no pointer, nothing that implies a click. */
.metric-grid .stat-tile { display: flex; flex-direction: column; gap: 12px; padding: 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.metric-grid .stat-tile > span:first-child { color: var(--muted); font-size: .8rem; font-weight: 600; }
.metric-grid .stat-tile small { color: var(--muted); font-size: .75rem; }

/* A bar chart drawn with the grid, not a charting library: the page has no
   build step and its content security policy blocks remote scripts, so a CDN
   chart would simply not load. Horizontal bars because city names are words —
   they read straight across, and comparing lengths needs no axis. */
.city-report-card { margin-top: 16px; }
.city-report-note { color: var(--muted); font-size: .78rem; }
.city-chart { display: grid; gap: 10px; margin-top: 6px; }
.city-chart-row { display: grid; grid-template-columns: minmax(96px, 148px) 1fr auto; align-items: center; gap: 12px; }
.city-chart-name { color: var(--navy); font-size: .84rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.city-chart-track { height: 20px; border-radius: var(--radius-sm); background: var(--soft); }
.city-chart-bar { height: 100%; min-width: 3px; border-radius: var(--radius-sm); background: var(--primary); transition: width .3s ease; }
.city-chart-count { min-width: 28px; color: var(--navy); font-size: .84rem; font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }

@media (max-width: 600px) {
  /* The name column stops earning its width on a phone, so the label moves
     above its own bar rather than being squeezed to two letters. */
  .city-chart-row { grid-template-columns: 1fr auto; gap: 4px 10px; }
  .city-chart-name { grid-column: 1 / -1; }
}
/* Time Spent — the User Time Analytics panel.
   Nothing new is invented here: the tiles are .stat-tile, the cards are
   .lead-timeline-card, the table is the console table. What is added is the
   filter bar, the day chart, and the small pieces the table needs (a sort
   affordance, an online dot). Hand-rolled again, for the same reason the city
   chart is: no build step and a CSP that will not load a chart library. */
.table-heading-actions { display: flex; align-items: center; gap: 10px; }
/* .lead-detail-grid is tuned for the lead view's five cards in a
   250px | 1fr | 270px frame. A detail made of two cards would sit in the first
   two tracks and leave the third empty, so a pair shares the row instead. */
.lead-detail-grid.is-pair { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.table-heading-actions .button svg { width: 15px; height: 15px; margin-right: 7px; }

.activity-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-sm); }
.activity-ranges { display: flex; flex-wrap: wrap; gap: 6px; }
.activity-range { min-height: 34px; padding: 6px 13px; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); color: var(--muted); font-size: .82rem; font-weight: 600; cursor: pointer; transition: background .15s ease, border-color .15s ease, color .15s ease; }
.activity-range:hover { border-color: var(--primary); color: var(--primary); }
.activity-range:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
/* aria-pressed is the state, so the style reads from it rather than from a
   class kept in step with it by hand. */
.activity-range[aria-pressed="true"] { border-color: var(--primary); background: var(--primary); color: white; }
.activity-custom { display: flex; align-items: flex-end; gap: 8px; margin-left: auto; padding: 4px 8px; border: 1px solid transparent; border-radius: var(--radius-md); transition: border-color .15s ease, background .15s ease; }
/* A custom range matches none of the chips, so the form shows that it is the
   one in effect — the toolbar should never look as though nothing is chosen. */
.activity-custom.is-active { border-color: var(--primary); background: var(--primary-light); }
.activity-custom label { display: grid; gap: 3px; color: var(--muted); font-size: .7rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.activity-custom input { min-height: 34px; padding: 5px 9px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: white; color: var(--text); font-size: .82rem; font-family: inherit; }
.activity-custom input:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.activity-toolbar-actions { display: flex; gap: 8px; }
.activity-period { margin: 0 0 6px; color: var(--muted); font-size: .8rem; }
/* Said once, plainly, when the range reaches back before anything was being
   recorded — so an empty stretch reads as "not measured" and not as "idle". */
.activity-note { margin: 0 0 14px; padding: 9px 12px; border: 1px solid var(--warning); border-radius: var(--radius-sm); background: var(--warning-bg); color: var(--warning); font-size: .8rem; }

/* Vertical bars: the axis is days, which are short, ordered and numerous, and
   a column per day is how a calendar is read. */
.activity-chart { display: flex; align-items: flex-end; gap: 4px; min-height: 150px; margin-top: 10px; padding-top: 6px; overflow-x: auto; }
.activity-chart .lead-followups-empty { align-self: center; }
.activity-day { display: flex; min-width: 14px; flex: 1 1 0; flex-direction: column; align-items: center; justify-content: flex-end; gap: 6px; height: 140px; }
.activity-day-track { display: flex; width: 100%; max-width: 34px; flex: 1; align-items: flex-end; }
.activity-day-bar { width: 100%; min-height: 2px; border-radius: var(--radius-xs) var(--radius-xs) 0 0; background: var(--primary); transition: height .3s ease; }
.activity-day-bar.is-empty { background: var(--line); }
.activity-day-label { color: var(--muted); font-size: .64rem; font-variant-numeric: tabular-nums; white-space: nowrap; }

.activity-table-heading { margin-top: 22px; }
.activity-search input { min-width: 230px; min-height: 38px; padding: 8px 12px; border: 1px solid var(--line-strong); border-radius: var(--radius-sm); background: white; color: var(--text); font-size: .85rem; font-family: inherit; }
.activity-search input:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
/* A header that sorts is a button, so it is reachable and announced as one.
   It inherits the th's type rather than restating it. */
.activity-sort { padding: 0; border: 0; background: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; }
.activity-sort:hover { color: var(--primary); }
.activity-sort:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.activity-sort::after { content: ""; display: inline-block; width: 0; height: 0; margin-left: 5px; vertical-align: middle; border: 4px solid transparent; }
.activity-sort[data-direction="asc"]::after { border-bottom-color: var(--primary); margin-bottom: 4px; }
.activity-sort[data-direction="desc"]::after { border-top-color: var(--primary); margin-top: 4px; }
.activity-table tbody tr { cursor: pointer; }
.activity-table tbody tr:hover { background: var(--soft); }
.activity-user-cell { display: grid; gap: 1px; }
.activity-user-cell small { color: var(--muted); font-size: .72rem; }
.activity-duration { font-variant-numeric: tabular-nums; font-weight: 700; }
.activity-duration.is-zero { color: var(--muted); font-weight: 500; }
.activity-presence { display: inline-flex; align-items: center; gap: 6px; font-size: .78rem; font-weight: 600; }
.activity-presence::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--muted); }
.activity-presence.is-online { color: var(--success); }
.activity-presence.is-online::before { background: var(--success); }
.activity-pagination { display: flex; align-items: center; justify-content: flex-end; gap: 12px; margin-top: 12px; color: var(--muted); font-size: .8rem; }
/* Author `display` outranks the UA's [hidden] rule, so restate it — it is rendered hidden until there is a second page. */
.activity-pagination[hidden] { display: none; }

@media (max-width: 760px) {
  /* The two date fields share a row and Apply drops below them. A native date
     input has a wide intrinsic size, so min-width:0 is what actually lets the
     pair shrink to the screen instead of pushing the button off the edge. */
  .activity-custom { width: 100%; flex-wrap: wrap; margin-left: 0; padding: 0; }
  .activity-custom label { min-width: 0; flex: 1 1 130px; }
  .activity-custom input { box-sizing: border-box; width: 100%; min-width: 0; }
  .activity-custom .button { flex: 1 0 100%; }
  .activity-toolbar-actions { width: 100%; }
  .activity-toolbar-actions .button { flex: 1; }
  .activity-search { display: block; width: 100%; }
  .activity-search input { box-sizing: border-box; width: 100%; min-width: 0; }
  .activity-table-heading { align-items: stretch; }
  /* The is-active tint needs its padding back once the form is a block of its
     own rather than a strip inside the toolbar row. */
  .activity-custom.is-active { padding: 8px; }
}
.welcome-panel { display: flex; align-items: center; justify-content: space-between; margin-top: 18px; padding: 32px; border-radius: var(--radius); background: linear-gradient(135deg, var(--primary), var(--primary-dark)); color: white; }.welcome-panel h2 { margin: 8px 0; color: white; font-size: 1.5rem; }.welcome-panel p { margin: 0; color: #dbe3ff; }.panel-orb { display: grid; width: 88px; height: 88px; place-items: center; border-radius: 50%; background: rgba(255,255,255,.16); color: white; font-size: 2rem; font-weight: 800; }
.table-heading { display: flex; align-items: end; justify-content: space-between; gap: 20px; margin-bottom: 18px; }.table-heading h2 { margin-bottom: 3px; font-size: 1.3rem; }.table-heading p { margin: 0; color: var(--muted); }.table-heading select { width: auto; min-width: 160px; }
/* position: relative so an absolutely positioned descendant is contained by
   this scroller instead of the document. .sr-only is position: absolute with
   no offsets, so it sits at its static position -- which, inside a table wide
   enough to scroll, is past the right edge of the page. One "Open" label in a
   th was making the whole supervisor console scroll sideways by 70px at
   1024px, with nothing visible out there to explain why. */
.table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
/* Table type lives here, on td, because cells that set none of their own were
 * inheriting the body's 16px/1.6 while their styled neighbours in the same row
 * rendered at .82rem — one row showing two text sizes. 16px in a 70px column
 * also wrapped "Nidhi singh" and "Sep 24, 2026" onto three lines, and that,
 * not the visit cell, was setting the height of every row in the leads table. */
table { width: 100%; border-collapse: collapse; }th, td { padding: 13px 16px; border-bottom: 1px solid var(--line); text-align: left; }td { font-size: .82rem; line-height: 1.45; }th { padding: 11px 16px; background: var(--soft); color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; white-space: nowrap; }
tbody tr:last-child td { border-bottom: 0; }tbody tr:hover td { background: var(--soft); }
.table-person { display: flex; align-items: center; gap: 10px; }
.table-avatar { flex: none; display: grid; width: 34px; height: 34px; place-items: center; border-radius: 50%; background: var(--primary-light); color: var(--primary); font-size: .82rem; font-weight: 800; }
.table-person strong, .table-person span { display: block; }.table-person span { color: var(--muted); font-size: .8rem; }
.enquiry-list { display: grid; gap: 14px; }.enquiry-card { display: grid; grid-template-columns: 1fr auto; gap: 18px; padding: 22px; border: 1px solid var(--line); border-radius: var(--radius); background: white; }.enquiry-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }.enquiry-meta h3 { margin: 0; }.enquiry-meta a { color: var(--primary); }.enquiry-message { margin: 13px 0 0; color: var(--muted); white-space: pre-wrap; }.enquiry-actions { display: flex; align-items: center; gap: 8px; }.status-select { padding: 7px 9px; border: 1px solid var(--line); border-radius: var(--radius-sm); }.delete-button { border: 0; background: none; color: var(--danger); cursor: pointer; }.empty-state { padding: 40px; border: 1px dashed #b8c3d0; border-radius: var(--radius); color: var(--muted); text-align: center; }
.admin-bulk-actions { display: flex; align-items: center; gap: 9px; margin-bottom: 12px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
/* Author `display` outranks the UA's [hidden] rule, so restate it — it is rendered hidden until rows are selected. */
.admin-bulk-actions[hidden] { display: none; }
.admin-bulk-actions > span { margin-right: auto; color: var(--muted); font-size: .8rem; font-weight: 700; }
.admin-bulk-actions select { width: min(280px, 40%); min-height: 42px; margin: 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--text); font-size: .84rem; }
.admin-bulk-actions select:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px rgba(27,107,82,.1); }
.admin-lead-checkbox { width: 17px; height: 17px; accent-color: var(--primary); cursor: pointer; }
.lead-status-pill { display: inline-flex; padding: 4px 9px; border-radius: 999px; background: var(--soft); color: var(--muted); font-size: .72rem; font-weight: 800; }
.lead-status-pill.status-new { background: var(--info-bg); color: var(--info); }
.lead-status-pill.status-contacted { background: var(--warning-bg); color: var(--warning); }
.lead-status-pill.status-qualified { background: var(--qualified-bg); color: var(--qualified); }
.lead-status-pill.status-won { background: var(--success-bg); color: var(--success); }
.lead-status-pill.status-lost { background: var(--danger-bg); color: var(--danger); }
.lead-status-pill.status-created, .lead-status-pill.status-pending { background: var(--info-bg); color: var(--info); }
.lead-status-pill.status-paid { background: var(--success-bg); color: var(--success); }
.lead-status-pill.status-cancelled { background: var(--danger-bg); color: var(--danger); }
.lead-status-pill.status-expired { background: var(--warning-bg); color: var(--warning); }
.lead-status-pill.status-upcoming { background: var(--info-bg); color: var(--info); }
.lead-status-pill.status-overdue { background: var(--danger-bg); color: var(--danger); }
.lead-status-pill.status-completed { background: var(--success-bg); color: var(--success); }
.lead-status-pill.status-open { background: var(--info-bg); color: var(--info); }
.lead-status-pill.status-in-progress { background: var(--warning-bg); color: var(--warning); }
.lead-status-pill.status-resolved { background: var(--success-bg); color: var(--success); }
.lead-unassigned { color: var(--danger); font-size: .78rem; font-weight: 700; }

/* Follow-ups (attached to a remark; shown on the Overview tab and in the leads table) */
.lead-followups-card { margin-top: 20px; }
.lead-followups-list { display: grid; gap: 10px; }
.lead-followups-empty { margin: 0; color: var(--muted); font-size: .84rem; }
.lead-followup-item { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.lead-followup-item.status-overdue { border-color: #e3b7ad; background: var(--danger-bg); }
.lead-followup-item-text { margin: 0; min-width: 0; overflow-wrap: anywhere; color: var(--navy); font-size: .87rem; font-weight: 600; }
.lead-followup-item-meta { display: flex; flex: none; align-items: center; gap: 8px; }
.lead-followup-item-meta time { color: var(--muted); font-size: .76rem; }

.remark-item.has-followup .remark-marker { box-shadow: 0 0 0 2px var(--warning); }
.remark-followup { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 10px; padding: 7px 10px; border-radius: var(--radius-sm); background: var(--warning-bg); }
.remark-followup-label { color: var(--warning); font-size: .64rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.remark-followup-time { color: var(--navy); font-size: .82rem; font-weight: 700; }
.remark-followup.is-overdue .remark-followup-time { color: var(--danger); }
.remark-followup.is-completed { background: var(--success-bg); }
.remark-followup.is-completed .remark-followup-label { color: var(--success); }
.remark-followup-complete { margin-left: auto; }

/* Remarks / Follow up dialog */
.remark-type-options { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-bottom: 16px; }
.follow-up-picker { margin: -4px 0 16px; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.follow-up-options { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.follow-up-quick.is-active { border-color: var(--primary); background: var(--primary); color: white; }
.follow-up-calendar-button { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--muted); cursor: pointer; transition: border-color .15s ease, color .15s ease, background .15s ease; }
.follow-up-calendar-button svg { width: 17px; height: 17px; }
.follow-up-calendar-button:hover { border-color: var(--primary); color: var(--navy); }
.follow-up-calendar-button.is-active { border-color: var(--primary); background: var(--soft); color: var(--navy); }
.follow-up-custom { margin-top: 10px; }
.follow-up-summary { margin: 10px 0 0; color: var(--navy); font-size: .84rem; font-weight: 700; }

/* Workspace (pipeline-stage sidebar + leads table) */
/* 224px, not 250px. The filter rail's widest row ("Site Visit Scheduled" and
   its count) needs 196px and the search placeholder 184px, so 250px was
   carrying ~26px of slack that the leads table next to it did not have -
   at 1440px the table wanted 1148px in 1072px and the Added column fell off
   the right edge. */
.workspace-shell { display: grid; grid-template-columns: 224px minmax(0,1fr); gap: 20px; align-items: start; }
/* The rail is a sidebar beside the table on a desktop, so it needs no button
   to reach it. The toggle below only exists on a narrow screen. */
.workspace-filters-toggle { display: none; }
/* Sticky, and capped to the window it is stuck to.
   Without the cap a rail taller than the viewport has its foot cut off for
   good: being sticky it never scrolls with the page, so at 894px in an 800px
   window the last 186px -- Date added, and before that whatever the last
   group happened to be -- could not be reached by any amount of scrolling.
   It scrolls within itself instead. The 40px is the 20px it sits down from
   the top and the same again left under it.
   No overscroll-behavior here on purpose: when the rail reaches its end the
   wheel has to carry on to the page, which scrolls, which is what sticks the
   rail to the top and brings its foot into view. Containing it would trap the
   scroll over the rail -- the very thing being fixed. */
.workspace-filters { position: sticky; top: 20px; max-height: calc(100vh - 40px); overflow-y: auto; display: flex; flex-direction: column; gap: 16px; padding: 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.workspace-search { position: relative; }
.workspace-search input { width: 100%; min-height: 40px; padding: 9px 12px 9px 34px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--soft); font-size: .85rem; color: var(--text); transition: border-color .15s ease, box-shadow .15s ease, background .15s ease; }
.workspace-search input:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-light); }
.workspace-search svg { position: absolute; left: 10px; top: 50%; width: 15px; height: 15px; color: var(--muted); transform: translateY(-50%); pointer-events: none; }
.workspace-filter-group + .workspace-filter-group { padding-top: 14px; border-top: 1px solid var(--line); }
.workspace-filter-label { display: block; margin-bottom: 7px; color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.workspace-filter-list { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.workspace-filter-item { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 8px 10px; border: 0; border-radius: var(--radius-sm); background: transparent; color: var(--text); font-size: .85rem; font-weight: 600; text-align: left; cursor: pointer; width: 100%; transition: background .15s ease, color .15s ease; }
.workspace-filter-item:hover { background: var(--soft); }
/* The proportional fill behind a pipeline stage: how much of the pipeline is
   sitting in that stage, green while it is within the stage's limit and red
   once it is over. main.js sets --stage-share and data-stage-state; only the
   five stages carry them, so "All leads" and the needs-attention rows draw
   nothing. The fill sits under the label and count rather than beside them, so
   the row keeps its existing layout, type and spacing exactly. */
.workspace-filter-item { position: relative; overflow: hidden; }
.workspace-filter-item > * { position: relative; z-index: 1; }
.workspace-filter-item[data-stage-state]::before {
  content: "";
  position: absolute;
  z-index: 0;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--stage-share, 0%);
  background: var(--stage-bar-ok);
  border-bottom: 2px solid var(--success);
  transition: width .4s ease, background-color .2s ease, border-color .2s ease;
}
.workspace-filter-item[data-stage-state="over"]::before {
  background: var(--stage-bar-over);
  border-bottom-color: var(--danger);
}
/* A bar that animates its width on every re-render is motion nobody asked for. */
@media (prefers-reduced-motion: reduce) {
  .workspace-filter-item[data-stage-state]::before { transition: none; }
}

.workspace-filter-item:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.workspace-filter-item.is-active { background: var(--soft); color: var(--primary); font-weight: 800; }
.workspace-filter-item span:last-child { color: var(--muted); font-size: .76rem; font-weight: 700; }
.workspace-filter-item.is-active span:last-child { color: var(--primary); }

/* The Date added range, beneath the two month shortcuts. It borrows the search
   box's treatment rather than the .field one used inside dialogs, because this
   sits in the filter rail and should read as part of it. */
/* One field per row rather than two side by side: the rail is ~224px, which
   left each date 69px of content box for text that needs 68 -- before the
   native calendar button, which sits inside the field and pushed the year off
   the end. Stacked, each has the full width and reads in any locale. */
.workspace-date-range { display: grid; gap: 8px; margin-top: 9px; }
.workspace-date-field { display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: center; gap: 8px; min-width: 0; }
.workspace-date-field > span { color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.workspace-date-field input {
  width: 100%;
  min-width: 0;
  min-height: 40px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--soft);
  color: var(--text);
  font-size: .82rem;
  font-family: inherit;
  transition: border-color .15s ease, box-shadow .15s ease, background .15s ease;
}
.workspace-date-field input:focus { outline: none; border-color: var(--accent); background: var(--surface); box-shadow: 0 0 0 3px var(--accent-light); }
/* A date input is the first control in this rail with native chrome of its own.
   Without this the calendar it drops down renders light over a dark page --
   the field itself is themed by the rules above, the popup is the browser's. */
body[data-page="dashboard"][data-theme="dark"] .workspace-date-field input,
body[data-page="admin-dashboard"][data-theme="dark"] .workspace-date-field input { color-scheme: dark; }
@media (prefers-color-scheme: dark) {
  body[data-page="dashboard"]:not([data-theme="light"]) .workspace-date-field input,
  body[data-page="admin-dashboard"]:not([data-theme="light"]) .workspace-date-field input { color-scheme: dark; }
}
/* Safari gives a date input its own intrinsic width, which overflows a column
   of this rail; min-width:0 above plus this keeps it inside its track. */
.workspace-date-field input::-webkit-date-and-time-value { text-align: left; }
.workspace-date-clear {
  grid-column: 1 / -1;
  justify-self: start;
  padding: 6px 10px;
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: .78rem;
  font-weight: 700;
  cursor: pointer;
}
.workspace-date-clear:hover { background: var(--soft); color: var(--text); }
/* The grid above would outrank the UA's [hidden] rule. */
.workspace-date-range[hidden] { display: none; }
.workspace-date-clear[hidden] { display: none; }
.workspace-filter-item.is-attention span:last-child { color: var(--danger); }
.stage-hover-tooltip { display: none; position: fixed; z-index: 130; align-items: center; gap: 10px; padding: 8px 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow); white-space: nowrap; }
/* Hover-only devices only — on touch, this never shows, and the existing tap-to-filter
   click behavior is completely untouched (nothing here calls preventDefault). */
@media (hover: hover) and (pointer: fine) {
  .stage-hover-tooltip.is-visible { display: flex; animation: sidebarMenuIn .16s ease; }
}
.stage-hover-stat { display: inline-flex; align-items: center; gap: 5px; color: var(--navy); font-size: .82rem; font-weight: 700; }
.workspace-filter-group select { box-sizing: border-box; width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--text); font-size: .85rem; }

.workspace-main { min-width: 0; }
.workspace-toolbar { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.workspace-toolbar h2 { margin: 0; font-size: 1.28rem; }
.workspace-toolbar p { margin: 3px 0 0; color: var(--muted); font-size: .84rem; }
.workspace-toolbar-actions { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; justify-content: flex-end; }

.workspace-table-wrap { position: relative; overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.workspace-table { width: 100%; border-collapse: collapse; }
.workspace-table th { border-bottom: 1px solid var(--line); }
.workspace-table td { border-bottom: 1px solid var(--line); vertical-align: middle; }
/* A date, an owner's name and a due time are single values: they should push the
 * column wider rather than fold onto a second line. */
.workspace-date-cell, .workspace-owner-cell, .workspace-followup-cell { white-space: nowrap; }
.workspace-date-cell { color: var(--muted); }
.workspace-table tbody tr { cursor: pointer; transition: background .15s; }
.workspace-table tbody tr:hover td { background: var(--soft); }
.workspace-table tbody tr:last-child td { border-bottom: 0; }
.workspace-table td.is-no-nav { cursor: default; }
.payment-actions-cell { display: flex; align-items: center; gap: 6px; }
.payment-action-more { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 38px; height: 38px; padding: 0; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--muted); cursor: pointer; transition: border-color .15s ease, color .15s ease, background .15s ease; }
.payment-action-more svg { width: 16px; height: 16px; }
.payment-action-more:hover { border-color: var(--primary); color: var(--navy); }
.payment-action-more:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.payment-action-more[aria-expanded="true"] { border-color: var(--primary); color: var(--navy); background: var(--soft); }
.payment-action-popover { display: none; position: fixed; z-index: 120; min-width: 200px; padding: 6px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow); }
.payment-action-popover.is-open { display: block; }
.payment-action-popover [data-popover-group] { display: grid; gap: 2px; }
.payment-action-popover [data-popover-group][hidden] { display: none; }
.payment-action-popover-item { display: flex; align-items: center; width: 100%; padding: 9px 10px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font-size: .85rem; font-weight: 600; text-align: left; cursor: pointer; transition: background .15s ease; }
/* Author `display` outranks the UA's [hidden] rule, so restate it — an action the lead's state does not allow is rendered hidden. */
.payment-action-popover-item[hidden] { display: none; }
.payment-action-popover-item:hover { background: var(--soft); }
.payment-action-popover-item:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.payment-action-popover-item-danger { color: var(--danger); }
.payment-action-popover-item-danger:hover { background: var(--danger-bg); }
.lead-ref-code { color: var(--muted); font-size: .72rem; font-weight: 700; }
.workspace-lead-cell { display: flex; align-items: center; gap: 10px; max-width: 210px; }
.workspace-lead-cell .table-avatar { flex: none; }
/* A two-word name folding onto a second line made that row 17px taller than its
 * neighbours, so the rows never lined up. Truncate instead — the full name is on
 * the row's title attribute, and clicking through opens the lead. min-width: 0
 * is what lets a flex item shrink below its content width at all. */
.workspace-lead-name { min-width: 0; }
.workspace-lead-name strong { display: block; overflow: hidden; color: var(--navy); font-size: .87rem; text-overflow: ellipsis; white-space: nowrap; }
.workspace-lead-name span { display: block; overflow: hidden; margin-top: 1px; color: var(--muted); font-size: .74rem; text-overflow: ellipsis; white-space: nowrap; }
.workspace-note-cell { max-width: 190px; overflow: hidden; color: var(--muted); font-size: .82rem; text-overflow: ellipsis; white-space: nowrap; }
/* Site above EC in one cell, each on a single line: label, then date, then time.
 * Stacking those three vertically made the cell six lines tall and contributed
 * to rows that ran 114-157px. The label column is a fixed width so Site and EC
 * line up under each other and the dates form a column you can read straight
 * down. The labels stay short because the column header already says which
 * visits these are. No new type scale - the hierarchy mirrors the lead name
 * and its reference code in the first column. */
.workspace-visit-cell { white-space: nowrap; }
.workspace-visit-block { display: grid; grid-template-columns: 1.9rem auto auto; align-items: baseline; column-gap: 7px; }
.workspace-visit-block + .workspace-visit-block { margin-top: 3px; }
.workspace-visit-label { color: var(--muted); font-size: .66rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.workspace-visit-date { color: var(--navy); font-size: .82rem; font-weight: 700; }
.workspace-visit-time { color: var(--muted); font-size: .78rem; }
.workspace-visit-empty { color: var(--muted); font-size: .82rem; }
.workspace-visit-done { color: var(--success); }
.workspace-empty-row td { padding: 48px 20px; color: var(--muted); text-align: center; }
.workspace-empty-row strong { display: block; margin-bottom: 4px; color: var(--navy); }

/* Lead detail page */
/* nowrap because the label was breaking to "All" / "leads": as a flex
   container the text is an anonymous item that will shrink and wrap, which
   doubled the height of the line for no reason. */
/* A real secondary button now: the classes carry the colour, border, radius and
   hover, so this only places it in the grid and handles the chevron. Declaring
   the look here instead would freeze it — the button system could change and
   this one control would quietly stop matching. */
.lead-detail-back { grid-area: back; justify-self: start; gap: 6px; white-space: nowrap; }
/* The chevron had no width, no height and no CSS sizing it, so it collapsed to
   0x0 and never appeared at all. */
.lead-detail-back svg { width: 15px; height: 15px; flex: none; }
/* Two rows rather than three stacked blocks. The back link and the name share
   the top line, the reference code and the contact details share the one below,
   and the action sits at the end of the top line. Column one sizes to whichever
   of "All leads" or the code badge is wider, so the two rows line up down the
   left edge. */
.lead-detail-header {
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas:
    "back heading actions"
    "code sub     sub";
  align-items: center;
  column-gap: 14px;
  row-gap: 5px;
  padding-bottom: 14px;
  margin-bottom: 18px;
  border-bottom: 1px solid var(--line);
}
.lead-detail-header .lead-detail-heading { grid-area: heading; }
.lead-detail-header .lead-detail-actions { grid-area: actions; }
.lead-detail-header .lead-detail-code { grid-area: code; justify-self: start; }
.lead-detail-header .lead-detail-sub { grid-area: sub; margin: 0; }
/* A user has no reference code, so there is nothing to fill the first cell of
   the second row. Rather than leave a gap where the lead's badge would be, the
   detail line spans the row and starts under the back button. */
.lead-detail-header.is-simple {
  grid-template-areas:
    "back heading actions"
    "sub  sub     sub";
}
.lead-detail-heading { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.lead-detail-heading h1 { margin: 0; font-size: 1.5rem; line-height: 1.25; }
.lead-detail-code { padding: 3px 8px; border-radius: var(--radius-sm); background: var(--soft); color: var(--muted); font-weight: 700; font-size: .72rem; letter-spacing: .02em; }
.lead-detail-sub { margin: 0; color: var(--muted); font-size: .86rem; line-height: 1.4; }
.contact-link { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 2px; cursor: pointer; transition: color .15s ease; }
.contact-link:hover { color: var(--primary); }
.contact-link:focus-visible { outline: none; border-radius: var(--radius-xs); box-shadow: 0 0 0 3px var(--focus-ring); }
.lead-detail-actions { display: flex; align-items: center; gap: 8px; flex: none; flex-wrap: wrap; }

.lead-detail-tabs { display: flex; flex-wrap: wrap; gap: 4px 22px; margin-bottom: 22px; border-bottom: 1px solid var(--line); }
.lead-detail-tab { padding: 0 0 12px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); font-size: .88rem; font-weight: 700; cursor: pointer; transition: color .15s ease, border-color .15s ease; }
.lead-detail-tab:hover { color: var(--text); }
.lead-detail-tab:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); border-radius: var(--radius-xs); }
.lead-detail-tab.is-active { border-bottom-color: var(--primary); color: var(--navy); }
.lead-tab-empty { padding: 60px 24px; border: 1px dashed var(--line); border-radius: var(--radius); background: var(--surface); color: var(--muted); text-align: center; }
.lead-tab-empty strong { display: block; margin-bottom: 6px; color: var(--navy); font-size: 1rem; }
.lead-tab-empty p { margin: 0; }
.lead-tab-action p { margin-bottom: 18px; }
/* Two actions on one tab — Create BOQ and Upload BOQ. A row rather than a
   second block, so neither looks like the afterthought, and wrapping rather
   than shrinking so the labels never truncate on a narrow console. */
.lead-tab-action-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
/* What the uploader accepts, said where the button is rather than only in the
   error you get for guessing wrong. Needs the parent in the selector to beat
   `.lead-tab-action p` above, which is one specificity point heavier. */
.lead-tab-action .lead-tab-action-note { margin: 16px 0 0; font-size: .78rem; }

/* Files tab. Built from the existing tokens — same surface, line, radius and
   type scale as the other lead cards. */
.lead-files-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; margin-bottom: 16px; }
.lead-files-head strong { display: block; color: var(--navy); font-size: 1rem; }
.lead-files-head p { margin: 3px 0 0; color: var(--muted); font-size: .84rem; }
.lead-files-head .button { flex: none; }
.lead-files-hint { margin: 0 0 12px; }
.lead-files-hint:empty { display: none; }

.lead-files-progress { margin-bottom: 14px; padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface); }
.lead-files-progress[hidden] { display: none; }
.lead-files-progress-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 8px; color: var(--muted); font-size: .8rem; font-weight: 700; }
.lead-files-progress-track { height: 6px; border-radius: 999px; background: var(--soft); overflow: hidden; }
.lead-files-progress-bar { width: 0; height: 100%; border-radius: 999px; background: var(--primary); transition: width .18s ease; }

.lead-files-list { display: grid; gap: 10px; }
/* min-width: 0 is what makes the ellipsis below actually happen. A grid item
   defaults to min-width: auto, which is its min-content width — and the name
   inside is white-space: nowrap, so min-content is the WHOLE filename. Without
   this the row refuses to shrink, pushes past the card and scrolls the page
   sideways: "WhatsApp Image 2026-09-15 at 1.38.04 PM.jpeg" took a 375px phone
   out to 499px. */
.lead-files-item { display: flex; min-width: 0; align-items: center; gap: 14px; padding: 14px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.lead-files-badge { display: grid; flex: none; width: 42px; height: 42px; place-items: center; border-radius: var(--radius-md); background: var(--soft); color: var(--muted); font-size: .62rem; font-weight: 800; letter-spacing: .04em; }
/* Type colours reuse the status-pill palette rather than introducing new ones. */
.lead-files-badge.type-pdf { background: var(--danger-bg); color: var(--danger); }
.lead-files-badge.type-csv, .lead-files-badge.type-xlsx, .lead-files-badge.type-xls { background: var(--success-bg); color: var(--success); }
.lead-files-badge.type-jpg, .lead-files-badge.type-jpeg, .lead-files-badge.type-png { background: var(--info-bg); color: var(--info); }
.lead-files-body { min-width: 0; flex: 1; }
/* Long names truncate rather than pushing the menu button off a narrow screen. */
.lead-files-name { display: block; overflow: hidden; color: var(--navy); font-size: .92rem; font-weight: 700; text-overflow: ellipsis; white-space: nowrap; }
.lead-files-meta { margin: 3px 0 0; color: var(--muted); font-size: .78rem; }
.lead-files-menu { display: grid; flex: none; width: 34px; height: 34px; place-items: center; padding: 0; border: 1px solid transparent; border-radius: var(--radius-sm); background: none; color: var(--muted); cursor: pointer; }
.lead-files-menu:hover { border-color: var(--line); background: var(--soft); color: var(--navy); }
.lead-files-menu:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.lead-files-menu svg { width: 18px; height: 18px; }
/* Admin's download affordance: same 34px hit area as the member's menu button. */
.lead-files-download { color: var(--muted); text-decoration: none; }
.lead-files-download:hover { border-color: var(--primary); background: var(--soft); color: var(--primary); }
.lead-files-count { color: var(--muted); font-size: .78rem; font-weight: 700; }
.lead-files-card .lead-files-item { background: var(--surface); }

/* BOQ documents sit under the two buttons rather than under a head bar, so the
   hint and the card need the gap the head bar would have given them. */
.lead-boq-hint { margin: 16px 0 0; }
.lead-boq-card { margin-top: 16px; }
/* Download and delete side by side: same 34px hit areas as the Files tab's
   single button, so a row is the same height either way. */
.lead-files-actions { display: flex; flex: none; align-items: center; gap: 4px; }
.lead-files-remove:hover { border-color: var(--danger); background: var(--danger-bg); color: var(--danger); }

/* Reading a labour sheet into expenses. Built from the same tokens as the CSV
   import dialog next door, which it sits beside in purpose and in shape. */
.lead-files-sheet:hover { border-color: var(--primary); background: var(--soft); color: var(--primary); }
.expense-sheet-dialog { width: min(96vw, 1000px); }
.sheet-import-file { margin: 6px 0 0; color: var(--muted); font-size: .86rem; word-break: break-all; }
.sheet-import-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 10px; margin: 18px 0 0; }
.sheet-import-summary:empty { display: none; }
.sheet-import-stat { padding: 12px 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.sheet-import-stat span { display: block; color: var(--muted); font-size: .74rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.sheet-import-stat strong { display: block; margin-top: 4px; color: var(--navy); font-size: 1rem; }
/* The two that carry the warning: money already counted, and money that is new. */
.sheet-import-stat.is-warn { border-color: var(--warning); background: var(--warning-bg); }
.sheet-import-stat.is-warn strong { color: var(--warning); }
.sheet-import-stat.is-good { border-color: var(--success); background: var(--success-bg); }
.sheet-import-stat.is-good strong { color: var(--success); }
.sheet-import-note { margin: 14px 0 0; color: var(--muted); font-size: .82rem; line-height: 1.55; }
.sheet-import-note:empty { display: none; }
.sheet-import-rows { max-height: 46vh; margin-top: 16px; overflow: auto; border: 1px solid var(--line); border-radius: var(--radius-md); }
.sheet-import-rows[hidden] { display: none; }
.sheet-import-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.sheet-import-table thead th { position: sticky; top: 0; z-index: 1; padding: 10px 12px; background: var(--soft); color: var(--muted); font-size: .72rem; font-weight: 800; letter-spacing: .04em; text-align: left; text-transform: uppercase; }
.sheet-import-table td { padding: 10px 12px; border-top: 1px solid var(--line); vertical-align: top; }
.sheet-import-table .sheet-import-amount { text-align: right; white-space: nowrap; }
.sheet-import-table .sheet-import-date { white-space: nowrap; }
.sheet-import-detail { display: block; color: var(--navy); }
.sheet-import-meta { display: block; margin-top: 2px; color: var(--muted); font-size: .74rem; }
/* A row that looks like money already recorded. Dimmed, not hidden: it is
   still the user's call, and hiding it would make the totals unexplainable. */
.sheet-import-table tr.is-duplicate { background: var(--warning-bg); }
.sheet-import-table tr.is-duplicate .sheet-import-detail { color: var(--muted); }
.sheet-import-skipped { margin-top: 14px; color: var(--muted); font-size: .82rem; }
.sheet-import-skipped[hidden] { display: none; }
.sheet-import-skipped summary { cursor: pointer; font-weight: 700; }
.sheet-import-skipped ul { margin: 8px 0 0; padding-left: 18px; }
.sheet-import-skipped li { margin-bottom: 4px; }

.lead-files-delete-copy { margin: 8px 0 0; color: var(--muted); }
.lead-files-delete-name { font-size: 1rem; word-break: break-all; }
.lead-files-preview-dialog { width: min(94vw, 640px); }
.lead-files-preview-frame { margin: 20px 0; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); text-align: center; }
.lead-files-preview-frame img { max-width: 100%; max-height: min(60vh, 460px); border-radius: var(--radius-sm); }
.lead-files-preview-dialog h2 { overflow: hidden; font-size: 1.2rem; text-overflow: ellipsis; white-space: nowrap; }

@media (max-width: 640px) {
  .lead-files-head { flex-direction: column; align-items: stretch; }
  /* Full-width tap target on a phone. */
  .lead-files-head .button { width: 100%; }
  .lead-files-item { gap: 11px; padding: 12px; }
  .lead-files-badge { width: 38px; height: 38px; }
}
.lead-payments-summary { display: grid; grid-template-columns: repeat(auto-fit,minmax(150px,1fr)); gap: 14px; margin-bottom: 20px; }
.lead-payments-stat { padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow); }
.lead-payments-stat span { display: block; margin-bottom: 8px; color: var(--muted); font-size: .74rem; font-weight: 600; }
.lead-payments-stat strong { color: var(--navy); font-size: 1.3rem; }
.lead-payments-stat strong.is-negative { color: var(--danger); }

/* Site expenses. The form is long enough to need its own rhythm, and the list
   reads as a stack of records rather than a grid — vendor and amount are what
   the eye goes to, with the filing underneath. */
.expense-form-section { display: block; margin: 22px 0 12px; padding-top: 16px; border-top: 1px solid var(--line); color: var(--muted); font-size: .72rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; }
.expense-form-section:first-of-type { margin-top: 10px; padding-top: 0; border-top: 0; }
.expense-form-section em { margin-left: 6px; font-style: normal; font-weight: 600; letter-spacing: 0; text-transform: none; opacity: .75; }
.expense-field-hint { display: block; margin-top: 4px; color: var(--muted); font-size: .76rem; }
.expense-form-footnote { margin: 18px 0 0; color: var(--muted); font-size: .78rem; }
.expense-receipt-drop { display: flex; align-items: center; justify-content: center; min-height: 64px; margin-top: 2px; padding: 14px 16px; border: 1px dashed var(--line-strong, var(--line)); border-radius: var(--radius-sm); background: var(--soft); color: var(--muted); font-size: .84rem; text-align: center; cursor: pointer; transition: border-color .15s ease, color .15s ease; }
.expense-receipt-drop:hover { border-color: var(--primary); color: var(--navy); }
.expense-receipt-drop.has-file { border-style: solid; border-color: var(--primary); color: var(--navy); }

.expense-list { display: grid; gap: 10px; }
.expense-card { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 6px 18px; padding: 15px 17px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.expense-card-vendor { min-width: 0; color: var(--navy); font-size: .97rem; font-weight: 700; }
.expense-card-amount { color: var(--navy); font-size: 1.02rem; font-weight: 700; text-align: right; white-space: nowrap; }
.expense-card-meta { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 4px 10px; color: var(--muted); font-size: .8rem; }
.expense-card-meta span:not(:last-child)::after { content: " ·"; }
.expense-card-receipt { display: inline-flex; align-items: center; gap: 5px; color: var(--primary); font-weight: 600; text-decoration: none; }
.expense-card-receipt:hover { text-decoration: underline; }
@media (max-width: 560px) {
  .expense-card { grid-template-columns: minmax(0,1fr); }
  .expense-card-amount { text-align: left; }
}
.lead-payments-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px; padding: 14px 0; margin-bottom: 24px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.lead-payments-actions-links { display: flex; flex-wrap: wrap; gap: 10px 22px; }
.lead-payments-block { margin-bottom: 20px; }
.lead-payments-block-label { display: block; margin-bottom: 10px; color: var(--muted); font-size: .78rem; font-weight: 700; }
.lead-tab-hint { min-height: 18px; margin: 14px 0 0; color: var(--muted); font-size: .78rem; }

.design-brief-layout { display: grid; grid-template-columns: 220px minmax(0,1fr); gap: 20px; align-items: start; }
.design-brief-nav { position: sticky; top: 20px; display: grid; gap: 2px; padding: 10px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.design-brief-main { min-width: 0; display: grid; gap: 20px; }
.design-brief-main .settings-card { padding: 24px; }
.design-brief-option-row { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 4px; }
.design-brief-option-row .meta-form-option { flex: 1 1 140px; }
.design-brief-option-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px,1fr)); gap: 10px; margin-top: 4px; }
.design-brief-uppercase { text-transform: uppercase; }
.design-brief-billing-heading { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin: 20px 0 4px; }
.field-checkbox { display: inline-flex; align-items: center; gap: 9px; color: var(--navy); font-size: .88rem; font-weight: 600; cursor: pointer; }
.field-checkbox input { width: 17px; height: 17px; margin: 0; accent-color: var(--primary); }

.lead-detail-grid { display: grid; grid-template-columns: 250px minmax(0,1fr) 270px; gap: 20px; align-items: start; }
.lead-timeline-col { display: flex; flex-direction: column; gap: 20px; min-width: 0; }
.lead-timeline-card, .lead-notes-card, .lead-info-card { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.lead-timeline-card { padding: 16px; }
.lead-timeline-heading-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.lead-timeline-heading { color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.text-link-button { padding: 0; border: 0; background: none; color: var(--primary); font-size: .78rem; font-weight: 700; cursor: pointer; transition: color .15s ease; }
.text-link-button:hover { text-decoration: underline; }
.text-link-button:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); border-radius: var(--radius-xs); }
.text-link-button:disabled { color: var(--muted); cursor: not-allowed; }
.text-link-button:disabled:hover { text-decoration: none; }
.lead-timeline-list { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.lead-timeline-step { padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.lead-timeline-step.is-complete { border-color: var(--success); }
.lead-timeline-step.is-current { border-color: var(--accent); background: var(--accent-light); }
.lead-timeline-step-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.lead-timeline-step-head strong { font-size: .85rem; color: var(--navy); }
.lead-timeline-step-status { flex: none; font-size: .64rem; font-weight: 800; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.lead-timeline-step.is-complete .lead-timeline-step-status { color: var(--success); }
.lead-timeline-step.is-current .lead-timeline-step-status { color: var(--accent-dark); }
.lead-timeline-step-meta { margin: 4px 0 0; color: var(--muted); font-size: .72rem; }
/* The design pipeline reuses the project pipeline's step card wholesale; all it
   adds is the Done action. A locked stage keeps its button so the sequence
   reads as a checklist rather than a list that grows a control as you go --
   it is just plainly not pressable. cursor stays 'not-allowed' rather than the
   'wait' .button:disabled uses, because locked is a state, not a delay. */
.lead-timeline-step .design-stage-done { margin-top: 9px; }
/* What a stage recorded, shown on the step it belongs to. Pre-wrap because
   measurements are written room by room and the line breaks are the structure. */
.design-stage-notes { margin: 8px 0 0; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--soft); color: var(--text); font-size: .76rem; line-height: 1.5; white-space: pre-wrap; }
/* Undo sits quietly under a completed stage: it is a correction, not an action
   the pipeline invites. Only ever rendered on the last completed stage. */
.lead-timeline-step .design-stage-undo { margin-top: 8px; padding: 0; font-size: .72rem; }
.lead-timeline-step .design-stage-done:disabled { opacity: .4; cursor: not-allowed; }
.lead-timeline-step [data-design-stage]:not(:disabled) { cursor: pointer; }

.lead-notes-card { display: flex; flex-direction: column; min-height: 420px; }
.lead-notes-header { padding: 12px 18px; border-radius: var(--radius) var(--radius) 0 0; background: var(--primary); color: white; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.lead-notes-header strong { font-weight: 800; font-size: .86rem; }
.lead-notes-header span { color: #c9ccc0; font-size: .64rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; }
.lead-notes-body { flex: 1; padding: 18px; overflow-y: auto; }
.lead-notes-body .remarks-timeline { display: grid; }
.lead-notes-footer { padding: 14px 18px; border-top: 1px solid var(--line); }

.lead-info-card { padding: 18px; display: grid; gap: 14px; }
.lead-info-row span { display: block; margin-bottom: 3px; color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.lead-info-row strong { display: block; color: var(--navy); font-size: .87rem; font-weight: 700; overflow-wrap: anywhere; }
.lead-info-row a.text-link { font-weight: 700; }
/* The design brief, which is four label/value cards rather than a dashboard.
   .lead-detail-grid's 250px/1fr/270px is built for the lead's Overview, where
   the columns hold different kinds of thing; these four are all the same kind
   and one of them holds prose, so equal columns read better and nothing is
   squeezed to 250px. Two stacks at this width, one below 700px. */
.lead-brief-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 20px; align-items: start; }
.lead-brief-col { display: grid; gap: 20px; align-content: start; min-width: 0; }
.lead-brief-grid > .lead-tab-empty { grid-column: 1 / -1; }
/* The gap is what separates one label/value pair from the next: without it a
   value sat flush against the label below it and which belonged to which was
   a guess. It also gives the card's title the space a bare
   .lead-timeline-heading has no margin for. */
.lead-brief-card { display: grid; gap: 14px; align-content: start; }
.lead-info-row select { box-sizing: border-box; width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--navy); font-size: .87rem; font-weight: 700; }
.lead-info-actions { display: flex; gap: 8px; flex-wrap: wrap; }
/* Payments: a real Cashfree request and a demo one must never look alike. */
.payment-mode-notice { margin: 0 0 4px; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--warning-bg); color: var(--warning); font-size: .82rem; }
/* The QR is an SVG from the server; size it here rather than in the document. */
.payment-qr-visual svg { display: block; width: 190px; height: 190px; margin: 0 auto; }
.payment-qr-link { margin: 6px 0 0; color: var(--muted); font-size: .72rem; word-break: break-all; }
.payment-demo-badge { display: inline-block; margin-left: 6px; padding: 1px 7px; border: 1px solid var(--line); border-radius: 999px; background: var(--soft); color: var(--muted); font-size: .68rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; vertical-align: middle; }
.lead-status-pill.status-failed { background: var(--danger-bg); color: var(--danger); }
.lead-status-pill.status-refunded { background: var(--info-bg); color: var(--info); }
.payment-status-facts { display: grid; gap: 10px; margin: 16px 0; }
.payment-status-facts div { display: flex; justify-content: space-between; gap: 14px; padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--soft); }
.payment-status-facts span { color: var(--muted); font-size: .82rem; }
.payment-status-facts strong { color: var(--navy); font-size: .9rem; }
/* The contact row sits in a fixed-width card: an icon with a text label would
   push WhatsApp onto a second line, so the glyph carries it. The accessible
   name lives in aria-label, and title gives sighted users the same words. */
.button-icon-only { padding-left: 11px; padding-right: 11px; }
/* Brand green on the glyph only: the button keeps the chrome its neighbours
   have, and the icon is what makes it recognisable at a glance. */
.icon-whatsapp { width: 20px; height: 20px; flex: none; color: #25d366; }
.button[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.button[aria-disabled="true"]:hover { transform: none; background: white; border-color: var(--line); }
.lead-info-actions-note { margin: 8px 0 0; color: var(--danger); font-size: .8rem; }
.lead-info-actions-note[hidden] { display: none; }

.lead-side-stack { display: grid; gap: 20px; }
.lead-mini-card { padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.lead-mini-card-label { display: block; margin-bottom: 10px; color: var(--muted); font-size: .66rem; font-weight: 800; letter-spacing: .06em; text-transform: uppercase; }
.lead-mini-empty { padding: 14px 10px; border: 1px dashed var(--line); border-radius: var(--radius-sm); color: var(--muted); font-size: .8rem; text-align: center; }

.lead-status-card { padding: 16px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.lead-status-field { margin-top: 10px; }
.lead-status-field label { display: block; margin-bottom: 5px; color: var(--muted); font-size: .74rem; font-weight: 700; }
.lead-status-field select { width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--text); font-size: .86rem; }
.lead-status-field select:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px rgba(35,42,34,.12); }
.lead-site-visit-when { padding: 12px 10px; border: 1px solid var(--success); border-radius: var(--radius-sm); background: var(--success-bg); color: var(--success); font-size: .84rem; font-weight: 800; text-align: center; }
.lead-site-visit-when[hidden] { display: none; }
.lead-status-field input[type="date"], .lead-status-field input[type="time"] { width: 100%; min-height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; color: var(--text); font: inherit; font-size: .86rem; }
.lead-status-field input[type="date"]:focus, .lead-status-field input[type="time"]:focus { border-color: var(--primary); outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.lead-site-visit-save { margin-top: 12px; }
.lead-visit-done { margin-top: 8px; }
/* Finished state: reads as a record, not a button waiting to be pressed. */
.lead-visit-done.is-complete { border-color: var(--success); background: var(--success-bg); color: var(--success); cursor: default; opacity: 1; }
.lead-visit-status { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
/* Author `display: flex` outranks the UA [hidden] rule, so restate it. */
.lead-visit-status[hidden] { display: none; }
.lead-visits-list { display: grid; gap: 10px; }
.lead-visit-item { padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--surface, white); }
.lead-visit-item.status-completed { border-color: var(--success); background: var(--success-bg); }
.lead-visit-item-head { display: flex; align-items: center; gap: 8px; font-size: .9rem; }
.lead-visit-item-mark { display: inline-grid; width: 18px; height: 18px; place-items: center; border-radius: 50%; background: var(--soft); color: var(--muted); font-size: .7rem; font-weight: 800; }
.lead-visit-item.status-completed .lead-visit-item-mark { background: var(--success); color: white; }
.lead-visit-item-meta { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 8px; color: var(--muted); font-size: .8rem; }
.lead-visit-item-done { margin: 8px 0 0; color: var(--success); font-size: .74rem; font-weight: 700; }
.visit-type-toggle { display: flex; gap: 4px; margin-bottom: 14px; padding: 4px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.visit-type-option { flex: 1 1 0; min-width: 0; min-height: 34px; padding: 7px 8px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--muted); font: inherit; font-size: .76rem; font-weight: 800; letter-spacing: .02em; white-space: nowrap; cursor: pointer; transition: background .15s ease, color .15s ease, box-shadow .15s ease; }
.visit-type-option:hover { color: var(--text); }
.visit-type-option:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.visit-type-option.is-active { background: var(--surface); color: var(--primary); box-shadow: 0 1px 2px rgba(35,42,34,.12); }
/* An author `display` on .visit-panel would outrank the UA [hidden] rule, so the hidden
   panel is switched off explicitly rather than relying on the attribute alone. */
.visit-panel[hidden] { display: none; }
.lead-status-hint { min-height: 16px; margin: 10px 0 0; color: var(--success); font-size: .76rem; font-weight: 700; }
.lead-status-hint.is-error { color: var(--danger); }
.lead-temperature-badge { display: inline-flex; align-items: center; gap: 4px; padding: 4px 9px; border-radius: 999px; background: var(--soft); color: var(--text); font-size: .72rem; font-weight: 800; }
.lead-temperature-badge[hidden] { display: none; }
.csv-import-dialog { width: min(96vw, 900px); max-height: 90vh; padding: 0; border: 0; border-radius: var(--radius); background: transparent; box-shadow: 0 24px 70px rgba(23,34,30,.28); }
.csv-import-dialog::backdrop { background: rgba(23,34,30,.56); backdrop-filter: blur(3px); }
.csv-import-card { position: relative; max-height: 90vh; padding: 30px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.csv-import-heading { padding-right: 40px; }
.csv-import-heading h2 { margin: 5px 0 7px; font-size: 1.8rem; }
.csv-import-heading p { margin: 0 0 20px; color: var(--muted); }
.csv-summary { display: grid; grid-template-columns: repeat(4, 1fr); gap: 9px; margin-bottom: 16px; }
/* Author `display` outranks the UA's [hidden] rule, so restate it — it is rendered hidden until an import has run. */
.csv-summary[hidden] { display: none; }
.csv-summary article { padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); }
.csv-summary span { display: block; color: var(--muted); font-size: .7rem; font-weight: 700; text-transform: uppercase; }
.csv-summary strong { display: block; margin-top: 4px; color: var(--navy); font-size: 1.35rem; }
.csv-preview-wrap { max-height: 360px; overflow: auto; }
.csv-preview-wrap td { vertical-align: top; font-size: .8rem; }
.csv-row-result { display: inline-flex; padding: 3px 7px; border-radius: 999px; font-size: .68rem; font-weight: 800; }
.csv-row-result.ready { background: var(--success-bg); color: var(--success); }
.csv-row-result.skipped { max-width: 220px; border-radius: var(--radius-sm); background: var(--danger-bg); color: var(--danger); }
.csv-import-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.meta-sync-dialog { width: min(94vw, 650px); max-height: 90vh; padding: 0; border: 0; border-radius: var(--radius); background: transparent; box-shadow: 0 24px 70px rgba(23,34,30,.28); }
.meta-sync-dialog::backdrop { background: rgba(23,34,30,.56); backdrop-filter: blur(3px); }
.meta-sync-card { position: relative; max-height: 90vh; padding: 30px; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.meta-sync-heading { padding-right: 40px; }
.meta-sync-heading h2 { margin: 5px 0 7px; font-size: 1.8rem; }
.meta-sync-heading p { margin-bottom: 20px; color: var(--muted); }
.meta-connection-status { padding: 14px; border: 1px solid var(--line); border-radius: var(--radius-md); background: var(--soft); color: var(--muted); font-size: .88rem; }
.meta-connection-status.is-connected { border-color: #b8d8c6; background: var(--success-bg); color: var(--success); }
.meta-autosync-note { margin: 8px 0 0; color: var(--muted); font-size: .78rem; }
.meta-autosync-note.is-active { color: var(--success); }
.meta-setup { margin-top: 16px; padding: 18px; border: 1px solid var(--line); border-radius: var(--radius-md); background: white; }
.meta-setup h3 { margin: 0 0 7px; font-size: 1rem; }
.meta-setup p { margin: 0 0 12px; color: var(--muted); font-size: .85rem; }
.meta-setup ul { margin: 0 0 12px; padding-left: 20px; }
.meta-setup li { margin: 6px 0; }
.meta-setup li span { color: var(--muted); font-size: .78rem; }
.meta-setup code { padding: 2px 5px; border-radius: var(--radius-xs); background: var(--soft); color: var(--primary-dark); }
.meta-forms-section { margin-top: 20px; }
.meta-form-list { display: grid; gap: 8px; max-height: 260px; overflow-y: auto; }
.meta-form-option { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: center; padding: 11px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: white; cursor: pointer; transition: border-color .15s ease; }
.meta-form-option:hover { border-color: var(--primary); }
.meta-form-option:has(input:focus-visible) { box-shadow: 0 0 0 3px var(--focus-ring); }
.meta-form-option input { width: 17px; height: 17px; accent-color: var(--primary); }
.meta-form-option strong, .meta-form-option small { display: block; }
.meta-form-option small { color: var(--muted); font-size: .72rem; }
.meta-sync-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }

.not-found { min-height: 70vh; display: grid; place-items: center; padding: 70px 20px; text-align: center; }.not-found span { display: block; color: var(--primary); font-size: 7rem; font-weight: 800; opacity: .18; }.not-found h1 { margin: -18px 0 12px; font-size: 2.7rem; }.not-found p { margin-bottom: 24px; color: var(--muted); }
.site-footer { padding: 52px 0 24px; background: var(--navy); color: #d4ddd9; }.footer-grid { display: grid; grid-template-columns: 1.5fr .5fr .5fr; gap: 44px; }.footer-grid > div:first-child p { max-width: 360px; margin-top: 16px; color: #9eada7; }.footer-grid h3 { margin: 3px 0 12px; color: white; font-size: .88rem; }.footer-grid > div:not(:first-child) a { display: block; margin: 8px 0; color: #aebbb6; }.footer-grid a:hover { color: #d9ef9f; }.footer-bottom { display: flex; justify-content: space-between; margin-top: 42px; padding-top: 18px; border-top: 1px solid #35453e; color: #809089; font-size: .78rem; }

@media (max-width: 900px) {
  .nav-toggle { display: block; }.nav-links { position: absolute; top: 72px; left: 0; right: 0; display: none; padding: 20px; border-bottom: 1px solid var(--line); background: white; box-shadow: var(--shadow); }.nav-links.open { display: grid; }.nav-links .button { width: 100%; }
  .hero-grid, .split, .contact-grid { grid-template-columns: 1fr; }.hero-copy { text-align: center; }.hero-copy > p { margin-inline: auto; }.hero-actions, .trust-row { justify-content: center; }.hero-visual { width: min(500px,100%); margin-inline: auto; }
  .card-grid.three { grid-template-columns: 1fr; }.stats-grid { grid-template-columns: repeat(3,1fr); }.stats-grid blockquote { grid-column: 1 / -1; }
  .process ol { grid-template-columns: repeat(2,1fr); }.auth-shell { grid-template-columns: 1fr; }.auth-intro { min-height: 350px; }.pricing-grid { grid-template-columns: 1fr; max-width: 480px; }.pricing-card.is-featured { transform: none; }
  .dashboard-grid, .lead-workspace { grid-template-columns: 1fr; }.admin-layout { grid-template-columns: 1fr; }.admin-sidebar { position: static; height: auto; flex-direction: row; align-items: center; overflow-x: auto; }.admin-sidebar nav { display: flex; margin: 0 18px; }.sidebar-nav-link { white-space: nowrap; }.sidebar-logout { margin: 0 0 0 auto; }.metric-grid { grid-template-columns: repeat(2, 1fr); }.admin-lead-layout { grid-template-columns: 1fr; }.admin-lead-filters { grid-template-columns: 1fr 1fr; }.admin-lead-filters label:first-child { grid-column: 1 / -1; }
  .workspace-shell { grid-template-columns: 1fr; }.workspace-filters { position: static; }.workspace-filter-list { display: flex; flex-wrap: wrap; gap: 6px; }.workspace-filter-item { width: auto; padding: 7px 11px; border: 1px solid var(--line); border-radius: 999px; }.workspace-filter-item span:last-child { margin-left: 4px; }
  /* Stacked above the table rather than beside it, the rail filled the whole
     first screen: the leads began at 828px of an 812px viewport, so opening
     Leads on a phone showed filters and no leads at all. It folds away behind
     a button instead -- the same move the console already makes with its
     sidebar at this width -- and the button carries a count, so filters that
     are applied are never silently out of sight. */
  .workspace-filters-toggle {
    display: flex;
    align-items: center;
    gap: 9px;
    width: 100%;
    min-height: 44px;
    padding: 10px 14px;
    border: 1px solid var(--line);
    border-radius: var(--radius-sm);
    background: var(--surface);
    color: var(--text);
    font: inherit;
    font-size: .88rem;
    font-weight: 700;
    cursor: pointer;
  }
  .workspace-filters-toggle svg { width: 17px; height: 17px; color: var(--muted); flex: none; }
  .workspace-filters-toggle[aria-expanded="true"] { border-color: var(--primary); background: var(--soft); }
  .workspace-filters-count {
    margin-left: auto;
    min-width: 22px;
    padding: 2px 7px;
    border-radius: 999px;
    background: var(--primary);
    color: white;
    font-size: .74rem;
    font-weight: 800;
    text-align: center;
  }
  .workspace-filters-count[hidden] { display: none; }
  /* --primary is a deep green on a light page and a pale one on a dark page,
     so white sits on it at 11:1 in one theme and 2.16:1 in the other. The
     label takes the dark neutral there instead of the background changing,
     so the badge stays the same green in both. */
  body[data-page="dashboard"][data-theme="dark"] .workspace-filters-count,
  body[data-page="admin-dashboard"][data-theme="dark"] .workspace-filters-count { color: var(--n-50); }
  @media (prefers-color-scheme: dark) {
    body[data-page="dashboard"]:not([data-theme="light"]) .workspace-filters-count,
    body[data-page="admin-dashboard"]:not([data-theme="light"]) .workspace-filters-count { color: var(--n-50); }
  }
  /* Closed by default: the leads are what the screen is for. Opened, it sits
     in the page flow rather than stuck to the window, so it takes its full
     height and scrolls with everything else -- a second scrollbar inside a
     panel you just unfolded is not something to thumb through. */
  .workspace-filters { display: none; max-height: none; overflow-y: visible; }
  .workspace-filters.is-open { display: flex; }
  /* Everything in the rail is tapped with a thumb here. */
  .workspace-filter-item { min-height: 44px; }
  .workspace-search input { min-height: 44px; }
  .workspace-date-field input { min-height: 44px; }
  .workspace-date-clear { min-height: 44px; }
  /* The admin rail's representative dropdown, the one control here that is
     neither a chip nor a date. */
  .workspace-filters select { min-height: 44px; }
  /* Two columns on a tablet, with the wide stack across the top.
     Three stacks in two columns leaves one of them alone in a half-width row
     -- the hole the desktop layout used to have, moved down a breakpoint. One
     column avoids that but wastes the screen: at 768px the member Overview
     became a single 3042px scroll, with cards drawn for 250px stretched to
     707px and a card holding "No follow-ups scheduled." three quarters of a
     metre wide.
     So the stack that holds the wide content spans both columns and is placed
     first, and the two narrow stacks sit side by side underneath it. No hole,
     no stretching, and the page is a third of the height.
     The trade is that this stack comes second in the markup, so on a tablet
     keyboard focus reaches the narrow stacks before the pipeline it sits
     above. No arrangement of three stacks in two columns avoids both that and
     the hole; the hole is the one a user sees.
     .lead-detail-grid.is-pair is more specific and keeps its own auto-fit. */
  .lead-detail-grid { grid-template-columns: 1fr 1fr; }
  .lead-detail-wide { grid-column: 1 / -1; order: -1; }
  .design-brief-layout { grid-template-columns: 1fr; }.design-brief-nav { position: static; display: flex; flex-wrap: wrap; gap: 6px; }
  .crm-hero .crm-hero-layout { grid-template-columns: 1fr; gap: 25px; padding-top: 76px; }.crm-hero-copy { max-width: 690px; margin-inline: auto; }.crm-preview-wrap { width: min(760px, 100%); margin-inline: auto; }.crm-confidence-bar .container { align-items: flex-start; flex-direction: column; gap: 12px; }.crm-bento-large, .crm-bento-wide { grid-template-columns: 1fr; gap: 28px; }.crm-bento-large { padding-bottom: 20px; }.crm-bento-wide { min-height: 440px; }.crm-workflow-grid, .crm-focus-grid { grid-template-columns: 1fr; gap: 55px; }.crm-workflow-copy { max-width: 650px; }.crm-focus-grid { width: min(700px, calc(100% - 40px)); }.crm-contact-visual { order: 2; }.crm-focus-copy { order: 1; }.crm-final-cta { align-items: flex-start; flex-direction: column; }
}

@media (max-width: 600px) {
  .container { width: min(100% - 28px,1120px); }.section { padding: 56px 0; }.hero-grid { min-height: auto; padding: 58px 0; }.hero-copy h1 { font-size: 2.8rem; }.hero-actions { flex-direction: column; gap: 14px; }.hero-visual { height: 300px; }.card-main { width: 220px; }.card-float { right: 12px; bottom: 18px; }
  .stats-grid { grid-template-columns: 1fr; text-align: center; }.stats-grid blockquote { text-align: left; }.cta-panel { align-items: flex-start; flex-direction: column; padding: 30px 24px; }.page-hero { padding: 58px 0; }.service-row { grid-template-columns: 1fr; gap: 12px; padding: 38px 0; }.process ol { grid-template-columns: 1fr; }
  .field-row { grid-template-columns: 1fr; gap: 0; }.form-card, .settings-card { padding: 24px; }.auth-intro { padding: 32px 24px; }.auth-panel { padding: 44px 22px; }.plan-toggle { grid-template-columns: 1fr; }.pricing-toggle { width: 100%; }.pricing-toggle-option { flex: 1; }
  .dashboard-welcome { align-items: flex-start; flex-direction: column; }.dashboard-welcome h1 { font-size: 1.7rem; }.admin-sidebar { padding: 16px 12px; }.admin-sidebar .brand { font-size: 0; }.admin-sidebar nav { margin-inline: 8px; }.sidebar-nav-link { padding: 8px; font-size: .78rem; }.sidebar-nav-link svg { width: 16px; height: 16px; }.admin-main { padding: 22px 14px 40px; }.admin-main > header { flex-wrap: wrap; }.admin-user > div { display: none; }.welcome-panel { padding: 28px; }.panel-orb { display: none; }.table-heading { align-items: flex-start; flex-direction: column; }.enquiry-card { grid-template-columns: 1fr; }.enquiry-actions { justify-content: space-between; }.metric-grid { grid-template-columns: 1fr; }.admin-lead-actions { align-items: stretch; flex-direction: column; }.admin-lead-table select { min-width: 170px; }.admin-leads-heading { align-items: flex-start; flex-direction: column; }.admin-leads-heading-actions { width: 100%; flex-direction: column; }.admin-leads-heading-actions .button { width: 100%; }.admin-lead-filters { grid-template-columns: 1fr; }.admin-lead-filters label:first-child { grid-column: auto; }.admin-bulk-actions { align-items: stretch; flex-direction: column; }.admin-bulk-actions > span { margin: 0; }.admin-bulk-actions select { width: 100%; }.csv-import-card, .meta-sync-card { padding: 26px 16px 18px; }.csv-summary { grid-template-columns: repeat(2,1fr); }.csv-import-actions, .meta-sync-actions { flex-direction: column-reverse; }.csv-import-actions .button, .meta-sync-actions .button { width: 100%; }
  .lead-list-card .card-heading { align-items: flex-start; flex-direction: column; }.lead-selection-actions { align-items: stretch; flex-wrap: wrap; }.lead-selection-actions > span { width: 100%; }.lead-selection-actions .button { flex: 1; }.lead-item { grid-template-columns: auto auto minmax(0, 1fr); }.lead-item-actions { grid-column: 3; align-items: flex-start; flex-direction: row; gap: 12px; }.lead-workspace { margin-bottom: 48px; }
  .workspace-toolbar { flex-direction: column; align-items: stretch; }.workspace-toolbar-actions { justify-content: flex-start; }.workspace-toolbar-actions .button { flex: 1; }.workspace-note-cell { display: none; }
  .lead-detail-header { grid-template-columns: auto 1fr; grid-template-areas: "back back" "heading heading" "code sub" "actions actions"; row-gap: 8px; }.lead-detail-header.is-simple { grid-template-areas: "back back" "heading heading" "sub sub" "actions actions"; }.lead-detail-actions { width: 100%; }.lead-detail-actions .button { flex: 1; }.lead-detail-grid { grid-template-columns: 1fr; }.lead-timeline-col, .lead-notes-card, .lead-info-card { grid-column: auto; }.lead-detail-wide { grid-column: auto; order: 0; }.lead-detail-tabs { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 1px; }.lead-detail-tab { flex: none; white-space: nowrap; }
  .phone-dialog-card { padding: 28px 22px 22px; }.phone-dialog-actions { grid-template-columns: 1fr; }
  .remarks-dialog-card { padding: 28px 20px 20px; }.remark-form { padding: 16px; }.remark-meta { flex-direction: column; }.lead-progress-summary { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }.footer-grid > div:first-child { grid-column: 1 / -1; }.footer-bottom { align-items: flex-start; flex-direction: column; gap: 4px; }
  .brand-product { display: none; }.crm-hero .crm-hero-layout { width: min(100% - 28px, 1240px); padding: 55px 0 70px; }.crm-hero-copy h1 { font-size: 2.8rem; }.crm-hero-copy > p { font-size: 1rem; }.crm-eyebrow { font-size: .66rem; }.crm-demo-link { font-size: .9rem; }.crm-trust-row { justify-content: flex-start; }.crm-preview-wrap { padding-top: 18px; }.crm-app-window { transform: none; }.crm-window-bar { grid-template-columns: 1fr auto; }.crm-window-bar > span { display: none; }.crm-app-body { height: 360px; grid-template-columns: 1fr; }.crm-preview-sidebar { display: none; }.crm-preview-main { padding: 14px; }.crm-kpi-grid { gap: 6px; }.crm-kpi-grid article { padding: 9px 8px; }.crm-kpi-grid strong { font-size: 1rem; }.crm-pipeline { grid-template-columns: repeat(2, 1fr); }.crm-pipeline > section:nth-child(3) { display: none; }.crm-pipeline article { padding: 8px 6px; }.crm-floating-card { display: none; }.crm-confidence-bar div div { flex-wrap: wrap; gap: 8px 12px; }.crm-confidence-bar div div i { display: none; }.crm-confidence-bar div div span { padding: 5px 9px; border: 1px solid var(--line); border-radius: 999px; }.crm-features-section { padding: 72px 0; }.crm-bento-grid { grid-template-columns: 1fr; }.crm-bento-card, .crm-bento-large, .crm-bento-wide { grid-column: auto; min-height: 420px; padding: 24px; }.crm-bento-large { display: block; min-height: 570px; }.crm-source-visual { margin-top: 20px; }.crm-source-visual span { grid-template-columns: 34px 1fr; }.crm-source-visual span small { display: none; }.crm-source-visual span:nth-child(n) { margin-left: 0; margin-right: 0; }.crm-assignment-visual { left: 23px; right: 23px; grid-template-columns: 1fr; }.crm-assignment-visual > i { transform: rotate(90deg); text-align: center; }.crm-bento-card:has(.crm-assignment-visual) { min-height: 500px; }.crm-bento-wide { display: block; min-height: 500px; }.crm-stage-track { grid-template-columns: repeat(2,1fr); margin-top: 35px; }.crm-stage-track span:nth-child(2)::after { display: none; }.crm-stage-track span:nth-child(3)::after { top: -8px; right: 50%; transform: rotate(135deg); }.crm-workflow-section, .crm-focus-section { padding: 78px 0; }.crm-workflow-grid { gap: 40px; }.crm-steps li { grid-template-columns: 43px 1fr; gap: 15px; }.crm-steps li > span { width: 40px; height: 40px; }.crm-focus-grid { width: min(100% - 28px,700px); gap: 48px; }.crm-contact-visual { padding: 20px; }.crm-contact-details { grid-template-columns: 1fr; }.crm-final-cta-section { padding: 40px 0; }.crm-final-cta { padding: 42px 25px; }.crm-final-cta .button { width: 100%; }
}

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; } }

/* ===========================================================================
   CONSOLE REFINEMENT
   ---------------------------------------------------------------------------
   Everything below is presentation. No selector here depends on markup that
   does not already exist, and nothing changes what any control does — the
   sections, the data attributes and the JavaScript that drives them are
   untouched. It is appended rather than threaded through the file above so
   that reverting the look is one contiguous deletion.
   =========================================================================== */

/* --- The rail ------------------------------------------------------------
   Navigation was behind the 3-dot menu at every width, including a 1440px
   desktop. On a screen that wide the menu costs a click to answer "where am
   I", and a persistent rail answers it for free. Below 1200px the dropdown is
   still the right call and is left exactly as it was. */
@media (min-width: 1200px) {body[data-page="admin-dashboard"] .admin-layout,
body[data-page="dashboard"] .admin-layout,
body[data-page="supervisor-dashboard"] .admin-layout {
    position: static;
    display: grid;
    grid-template-columns: 252px minmax(0, 1fr);
  }body[data-page="admin-dashboard"] .admin-menu-toggle,
body[data-page="dashboard"] .admin-menu-toggle,
body[data-page="supervisor-dashboard"] .admin-menu-toggle { display: none; }body[data-page="admin-dashboard"] .admin-sidebar,
body[data-page="dashboard"] .admin-sidebar,
body[data-page="supervisor-dashboard"] .admin-sidebar {
    position: sticky;
    top: 0;
    right: auto;
    left: auto;
    z-index: 20;
    display: flex;
    width: auto;
    height: 100vh;
    max-height: none;
    padding: 24px 14px 18px;
    border-radius: 0;
    box-shadow: none;
    /* The dropdown animates itself in; a rail that is simply there must not. */
    animation: none;
  }body[data-page="admin-dashboard"] .admin-sidebar nav,
body[data-page="dashboard"] .admin-sidebar nav,
body[data-page="supervisor-dashboard"] .admin-sidebar nav { margin-top: 26px; }body[data-page="admin-dashboard"] .admin-sidebar .sidebar-logout,
body[data-page="dashboard"] .admin-sidebar .sidebar-logout,
body[data-page="supervisor-dashboard"] .admin-sidebar .sidebar-logout { margin-top: auto; }
}

/* A gradient rather than a flat fill, and a hairline edge where it meets the
   page, so the rail reads as a surface the content sits beside. */
.admin-sidebar {
  background: linear-gradient(180deg, var(--sidebar-bg) 0%, var(--sidebar-bg-deep) 100%);
  border-right: 1px solid rgba(0,0,0,.18);
}
.admin-sidebar .brand { padding: 0 10px; letter-spacing: .01em; }
.admin-sidebar .brand-mark { box-shadow: 0 2px 8px rgba(0,0,0,.25); }
/* Was #59648a and #5c6889 — blue-greys left behind when the console went
   green, and the last place in the file still wearing the old palette. */
.sidebar-nav-group { color: var(--sidebar-text-dim); }
.sidebar-nav-link {
  position: relative;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  font-size: .89rem;
  transition: background .16s ease, color .16s ease;
}
.sidebar-nav-link svg { color: var(--sidebar-text-dim); transition: color .16s ease; }
.sidebar-nav-link:hover { background: rgba(255,255,255,.06); color: #fff; }
.sidebar-nav-link:hover svg { color: var(--sidebar-accent); }
.sidebar-nav-link:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--sidebar-accent); }
.sidebar-nav-link.active, .sidebar-nav-link.is-active {
  background: var(--sidebar-active-bg);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}
/* A marker on the edge, not just a filled pill: it survives being looked at
   peripherally, which is how a sidebar is usually read. */
.sidebar-nav-link.active::before, .sidebar-nav-link.is-active::before {
  content: "";
  position: absolute;
  left: -28px;
  top: 50%;
  width: 3px;
  height: 20px;
  border-radius: 0 3px 3px 0;
  background: var(--sidebar-accent);
  transform: translateY(-50%);
}
.sidebar-logout { border-color: var(--sidebar-line); transition: background .16s ease, border-color .16s ease, color .16s ease; }
.sidebar-logout:hover { background: rgba(255,255,255,.06); }
.sidebar-logout:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--sidebar-accent); }
@media (min-width: 1200px) {/* Inside the dropdown the marker would hang outside the rounded card. */
  body[data-page="admin-dashboard"] .admin-sidebar nav,
body[data-page="dashboard"] .admin-sidebar nav,
/* Inside the dropdown the marker would hang outside the rounded card. */
  body[data-page="supervisor-dashboard"] .admin-sidebar nav { padding-left: 14px; }
}
@media (max-width: 1199px) {
  .sidebar-nav-link.active::before, .sidebar-nav-link.is-active::before { display: none; }
}

/* --- The bar -------------------------------------------------------------
   Stays with you down a 117-row table, so the account menu and the navigation
   never scroll away. Translucent with a blur rather than solid, so content
   passing underneath reads as passing underneath. */
/* The bar has to bleed to the edges of the main column, which means its
   negative margin must be exactly the column's padding. Writing the figure
   twice is how it went wrong: the padding drops to 14px under 1136px while the
   margin clamped to 20px, and the 6px either side overflowed the page. One
   variable, read by both. */
.admin-main { --main-pad-x: clamp(20px, 4vw, 48px); --main-pad-top: 30px; }
@media (max-width: 1136px) { .admin-main { --main-pad-x: 14px; --main-pad-top: 22px; } }
.admin-main > header {
  position: sticky;
  top: 0;
  z-index: 15;
  margin: calc(var(--main-pad-top) * -1) calc(var(--main-pad-x) * -1) 18px;
  padding: 16px var(--main-pad-x) 14px;
  /* Opaque, not translucent. A blurred 88% bar let the table underneath show
     through as a grey smudge beside the title — which reads as a rendering
     fault rather than as depth. The hairline below is what separates it. */
  background: var(--bg);
  box-shadow: 0 1px 0 var(--line);
}
.admin-main > header .eyebrow { margin-bottom: 0; color: var(--muted); letter-spacing: .14em; }
.admin-user > div strong { font-size: .92rem; letter-spacing: -.01em; }
.user-chip { box-shadow: 0 2px 6px rgba(13,42,33,.18); }
.admin-menu-toggle { transition: background .16s ease, border-color .16s ease, color .16s ease; }

/* --- Cards ---------------------------------------------------------------
   The lift on hover was already here; what it lacked was a shadow that grows
   with it. A card that rises without its shadow changing reads as sliding,
   not lifting. */
.metric-grid { gap: 16px; }
.metric-grid .metric-card, .metric-grid .stat-tile {
  box-shadow: var(--shadow-sm);
  transition: border-color .18s ease, transform .18s ease, box-shadow .18s ease;
}
.metric-grid .metric-card:hover { box-shadow: var(--shadow-md); }
.metric-grid .metric-card:active { transform: translateY(0); box-shadow: var(--shadow-xs); }
.metric-grid .metric-card:hover .metric-icon { background: var(--primary); color: #fff; }
.metric-icon { transition: background .18s ease, color .18s ease; }
/* Figures line up column to column, and stop shifting as a count ticks over,
   because every digit is the same width. */
.metric-grid strong {
  font-size: 2.05rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
  line-height: 1.1;
}
.metric-grid .metric-card > span:first-child, .metric-grid .stat-tile > span:first-child {
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .01em;
}
.lead-timeline-card, .lead-notes-card, .lead-info-card { box-shadow: var(--shadow-sm); }
.lead-timeline-heading { letter-spacing: .07em; }

/* The panel's body copy was #dbe3ff — a pale blue from before the rebrand,
   sitting on a green gradient. */
.welcome-panel {
  position: relative;
  overflow: hidden;
  border: 1px solid var(--green-700);
  box-shadow: var(--shadow-md);
}
.welcome-panel p { color: var(--green-100); }
.welcome-panel > div, .welcome-panel .panel-orb { position: relative; z-index: 1; }
/* A single soft highlight off the top-right corner. Flat gradients read as
   printed; one light source reads as a surface. */
.welcome-panel::after {
  content: "";
  position: absolute;
  top: -58%;
  right: -12%;
  width: 420px;
  height: 420px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 68%);
  pointer-events: none;
}
.panel-orb { border: 1px solid rgba(255,255,255,.18); backdrop-filter: blur(2px); }

/* --- Tables --------------------------------------------------------------
   The header row was the same grey as a hovered row, so scanning down the
   table the eye kept catching it. It gets its own treatment, and rows get a
   marker on the left edge rather than only a fill. */
.table-wrap { box-shadow: var(--shadow-sm); }
th {
  background: linear-gradient(180deg, var(--n-50), var(--n-100));
  color: var(--muted-strong);
  border-bottom: 1px solid var(--line-strong);
}
tbody tr { transition: background .14s ease; }
tbody tr:hover td { background: var(--primary-light); }
.workspace-table tbody tr:hover td { background: var(--primary-light); }
.activity-table tbody tr:hover { background: var(--primary-light); }
/* The marker rides the first cell, so it cannot be clipped by the wrapper's
   rounded corner the way a row-level border would be. */
tbody tr td:first-child { box-shadow: inset 2px 0 0 transparent; transition: box-shadow .14s ease; }
tbody tr:hover td:first-child { box-shadow: inset 2px 0 0 var(--primary); }
/* A row you can open should say so before it is clicked. */
.workspace-table tbody tr:focus-visible, .activity-table tbody tr:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}
/* Counts, durations and money read as columns of figures, not as words. */
.activity-duration, .workspace-filter-count, .city-chart-count { font-variant-numeric: tabular-nums; }

/* --- Pills ---------------------------------------------------------------
   A flat tint with no edge dissolves into a white row. A hairline of the same
   hue gives each one a shape without adding weight. */
.lead-status-pill {
  border: 1px solid transparent;
  padding: 4px 10px;
  letter-spacing: .02em;
  line-height: 1.5;
}
.lead-status-pill.status-new { border-color: var(--info-border); }
.lead-status-pill.status-contacted { border-color: var(--warning-border); }
.lead-status-pill.status-qualified { border-color: var(--qualified-border); }
.lead-status-pill.status-won { border-color: var(--success-border); }
.lead-status-pill.status-lost { border-color: var(--danger-border); }/* --- Controls ------------------------------------------------------------ */
body[data-page="dashboard"] .button,
body[data-page="admin-dashboard"] .button,
body[data-page="admin-login"] .button,
body[data-page="supervisor-dashboard"] .button {
  box-shadow: var(--shadow-xs);
  transition: background .16s ease, border-color .16s ease, box-shadow .16s ease, transform .1s ease;
}body[data-page="dashboard"] .button:hover,
body[data-page="admin-dashboard"] .button:hover,
body[data-page="admin-login"] .button:hover,
body[data-page="supervisor-dashboard"] .button:hover { background: var(--primary-hover); box-shadow: var(--shadow-sm); }/* Presses should feel like presses. 1px is enough to register and small
   enough not to shift the layout around it. */
body[data-page="dashboard"] .button:active,
body[data-page="admin-dashboard"] .button:active,
body[data-page="admin-login"] .button:active,
body[data-page="supervisor-dashboard"] .button:active { transform: translateY(1px); box-shadow: none; }body[data-page="dashboard"] .button-secondary:hover,
body[data-page="admin-dashboard"] .button-secondary:hover,
body[data-page="admin-login"] .button-secondary:hover,
body[data-page="supervisor-dashboard"] .button-secondary:hover { background: var(--primary-light); border-color: var(--primary-border); }
.field input, .field textarea, .field select, .table-heading select {
  transition: border-color .16s ease, box-shadow .16s ease, background .16s ease;
}
.field input:hover, .field textarea:hover, .field select:hover { border-color: var(--n-400); }
.field input:focus, .field textarea:focus, .field select:focus, .table-heading select:focus {
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }

/* --- Motion --------------------------------------------------------------
   Switching sections used to be an instant swap, which on a single-page
   console makes it hard to tell whether anything happened. 200ms of rise is
   enough to say "this is new" and short enough never to be in the way. */
@media (prefers-reduced-motion: no-preference) {
  @keyframes panelIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
  /* `backwards`, not `both`.
     A finished animation filling forwards keeps the value it animated to, and
     a transform animated to `none` computes as matrix(1,0,0,1,0,0) -- the
     identity, but not the keyword. A transform that is not `none` makes the
     element a containing block, and a containing block between a sticky
     element and the viewport is what stops it sticking. The filter rail has
     been position:sticky this whole time and has never once stuck.
     Filling backwards still applies the opening frame before the animation
     runs, which is all `both` was wanted for, and leaves nothing behind. */
  .admin-section.active { animation: panelIn .2s ease backwards; }
  [data-workspace-panel]:not([hidden]) { animation: panelIn .2s ease backwards; }
}

/* --- Chrome --------------------------------------------------------------
   The console's own scrollbars, so a long table does not put a stock grey
   slab down the side of a tuned surface. Firefox takes the two-value form;
   WebKit needs the pseudo-elements. */
body[data-page="dashboard"], body[data-page="admin-dashboard"], body[data-page="supervisor-dashboard"] { scrollbar-color: var(--n-300) transparent; scrollbar-width: thin; }body[data-page="dashboard"] ::-webkit-scrollbar,
body[data-page="admin-dashboard"] ::-webkit-scrollbar,
body[data-page="supervisor-dashboard"] ::-webkit-scrollbar { width: 10px; height: 10px; }body[data-page="dashboard"] ::-webkit-scrollbar-track,
body[data-page="admin-dashboard"] ::-webkit-scrollbar-track,
body[data-page="supervisor-dashboard"] ::-webkit-scrollbar-track { background: transparent; }body[data-page="dashboard"] ::-webkit-scrollbar-thumb,
body[data-page="admin-dashboard"] ::-webkit-scrollbar-thumb,
body[data-page="supervisor-dashboard"] ::-webkit-scrollbar-thumb { border: 3px solid transparent; border-radius: 999px; background: var(--n-300); background-clip: content-box; }body[data-page="dashboard"] ::-webkit-scrollbar-thumb:hover,
body[data-page="admin-dashboard"] ::-webkit-scrollbar-thumb:hover,
body[data-page="supervisor-dashboard"] ::-webkit-scrollbar-thumb:hover { background: var(--n-400); background-clip: content-box; }body[data-page="dashboard"] ::selection,
body[data-page="admin-dashboard"] ::selection,
body[data-page="supervisor-dashboard"] ::selection { background: var(--primary-tint); color: var(--green-900); }

/* --- Loading -------------------------------------------------------------
   A bar where the text will be, rather than the word "Loading…". It shows the
   shape of what is coming, so the page does not appear to jump when the rows
   arrive. Applied by renderers that opt in; everything else still shows text. */
.skeleton {
  display: block;
  height: 10px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--n-100) 25%, var(--n-200) 37%, var(--n-100) 63%);
  background-size: 400% 100%;
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes skeletonSheen { from { background-position: 100% 50%; } to { background-position: 0 50%; } }
  .skeleton { animation: skeletonSheen 1.4s ease infinite; }
}
.skeleton-row td { padding-top: 15px; padding-bottom: 15px; }
.skeleton-row:hover td { background: none; }
.skeleton-row td:first-child { box-shadow: none !important; }

/* --- Pipeline share bars -------------------------------------------------
   The thresholds and the maths are untouched. What changed is that the tint
   was so pale the eye only caught the 2px rule under it, which read as a
   stray underline rather than as a bar reaching a certain distance. A
   half-step more colour and a rounded leading edge make it a bar. Both tints
   still clear AA behind the count in --muted, which is the tightest pairing
   on the row. */
.workspace-filter-item[data-stage-state]::before {
  border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
}

/* --- Time Spent toolbar --------------------------------------------------
   margin-left:auto on the date form claimed every spare pixel, which pushed
   Export and Refresh onto a line of their own while a gap sat beside them.
   Pushing from the LEFT instead keeps the three groups in one row and lets
   them wrap together when the row genuinely runs out. */
.activity-ranges { margin-right: auto; }
/* Its own row, always. The three groups together are wider than the content
   column at any realistic console width, so letting them wrap by chance meant
   the layout changed shape as the window moved. Two deliberate rows —
   presets and actions, then the custom range — hold still. */
.activity-custom { flex-basis: 100%; margin-left: 0; margin-top: 2px; }
@media (max-width: 760px) {
  .activity-ranges { margin-right: 0; }
}

/* --- Dialogs -------------------------------------------------------------
   The native <dialog> already handles focus and the top layer;what it does
   not do is look like it belongs to this console. The backdrop is tinted with
   the darkest green rather than neutral black,
so the page behind it recedes
   into the palette instead of going grey. */
body[data-page="dashboard"] dialog::backdrop,
body[data-page="admin-dashboard"] dialog::backdrop,
body[data-page="supervisor-dashboard"] dialog::backdrop {
  background: rgba(10,43,34,.42);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}body[data-page="dashboard"] dialog,
body[data-page="admin-dashboard"] dialog,
body[data-page="supervisor-dashboard"] dialog { box-shadow: var(--shadow-lg); }
@media (prefers-reduced-motion: no-preference) {
  @keyframes dialogIn { from { opacity: 0; transform: translateY(8px) scale(.985); } to { opacity: 1; transform: none; } }body[data-page="dashboard"] dialog[open],
body[data-page="admin-dashboard"] dialog[open],
body[data-page="supervisor-dashboard"] dialog[open] { animation: dialogIn .18s ease both; }
}

/* --- Headings and empty states -------------------------------------------
   Section headings were the same weight as the body around them, so a page
   opened with nothing obviously at the top of it. Tightening the tracking and
   adding weight gives each screen a clear first line. */
.table-heading h2, .admin-leads-heading h2 { font-size: 1.22rem; font-weight: 800; letter-spacing: -.015em; }
.table-heading p, .admin-leads-heading p { font-size: .86rem; }
.lead-detail-heading h1 { letter-spacing: -.02em; }
/* An empty state is a sentence the reader was not expecting, so it gets room
   rather than being squeezed against the border above it. */
.lead-followups-empty { padding: 4px 0; }
.workspace-empty-row td { font-size: .86rem; }

/* Under 900px the stage filters become pills, and the share bar did not follow
   them: it kept its square leading edge and its 2px rule, so the rule's ends
   were sliced by the pill's curve and showed as a red crescent hanging off the
   bottom-left corner. In pill form the fill takes the pill's own shape and the
   tint alone carries the over/under signal — which is the signal anyway; the
   rule was only ever an underline for the rectangular form. */
@media (max-width: 900px) {
  .workspace-filter-item[data-stage-state]::before {
    border-radius: inherit;
    border-bottom: 0;
  }
}

/* The bar only needs an edge once there is something behind it. Flat at the
   top of the page, lifted the moment anything scrolls under — which is how
   you can tell the page has moved without looking away from what you were
   reading. */
.admin-main > header { transition: box-shadow .18s ease; }
.admin-main > header:not(.is-scrolled) { box-shadow: none; }
.admin-main > header.is-scrolled { box-shadow: 0 1px 0 var(--line), 0 6px 16px -10px rgba(13,42,33,.28); }

/* --- Overview summary ----------------------------------------------------
   The Overview was three cards and a banner on a 900px-tall screen, which left
   most of it empty. These two cards fill it with what is already known — the
   same counts the filter rail shows — rather than with anything invented. */
.overview-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: 16px; margin-top: 16px; align-items: start; }
.overview-card { padding: 18px; }
/* One track divided by flex-grow, so the segments always fill it exactly and
   no rounding is left over at the end. */
.overview-bar { display: flex; overflow: hidden; height: 10px; margin: 14px 0 4px; border-radius: 999px; background: var(--soft); }
.overview-bar-segment { min-width: 3px; transition: flex-grow .3s ease; }
.overview-bar-segment + .overview-bar-segment { border-left: 1px solid var(--surface); }
.overview-bar-segment.is-new { background: var(--info); }
.overview-bar-segment.is-contacted { background: var(--warning); }
.overview-bar-segment.is-qualified { background: var(--qualified); }
.overview-bar-segment.is-won { background: var(--success); }
.overview-bar-segment.is-lost { background: var(--danger); }

.overview-stage-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 2px 14px; margin-top: 10px; }
.overview-stage { display: flex; align-items: center; gap: 9px; width: 100%; padding: 8px 8px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-size: .84rem; text-align: left; cursor: pointer; transition: background .15s ease; }
.overview-stage:hover { background: var(--soft); }
.overview-stage:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.overview-stage-dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.overview-stage.is-new .overview-stage-dot { background: var(--info); }
.overview-stage.is-contacted .overview-stage-dot { background: var(--warning); }
.overview-stage.is-qualified .overview-stage-dot { background: var(--qualified); }
.overview-stage.is-won .overview-stage-dot { background: var(--success); }
.overview-stage.is-lost .overview-stage-dot { background: var(--danger); }
.overview-stage-name { margin-right: auto; font-weight: 600; }
.overview-stage-count { font-weight: 800; font-variant-numeric: tabular-nums; }
/* Fixed width and tabular figures so the percentages form a column rather than
   wandering with the width of the count beside them. */
.overview-stage-share { width: 38px; color: var(--muted); font-size: .76rem; font-variant-numeric: tabular-nums; text-align: right; }

.overview-attention-list { display: grid; gap: 2px; margin-top: 12px; }
.overview-attention-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; width: 100%; padding: 9px 8px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-size: .84rem; font-weight: 600; text-align: left; cursor: pointer; transition: background .15s ease; }
.overview-attention-row:hover { background: var(--soft); }
.overview-attention-row:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--focus-ring); }
.overview-attention-count { color: var(--danger); font-weight: 800; font-variant-numeric: tabular-nums; }
/* Nothing waiting is good news, so it is not shouted in red. */
.overview-attention-row.is-clear .overview-attention-count { color: var(--muted); }

@media (max-width: 900px) {
  .overview-grid { grid-template-columns: 1fr; }
}/* ===========================================================================
   DARK MODE  (console only)
   ---------------------------------------------------------------------------
   The marketing site keeps its own palette and is deliberately untouched: it
   is a brochure with its own art direction,
and nobody reads it at 9pm.

   This is cheap only because of the ramps. Before them,
colour was a thousand
   one-off hex values and a dark theme would have meant finding every one. Now
   a theme is the semantic layer re-pointed at different steps,
so a component
   cannot be missed — there is nowhere else for colour to come from.

   Two ways in,
and the precedence between them matters:
     - data-theme="dark" on <body>,
rendered by the SERVER from a cookie. That
       is what makes the first paint correct: the CSP forbids inline script,
so
       there is no way to set a class before paint from the client,
and doing it
       from main.js would flash white on every load.
     - prefers-color-scheme,
honoured only while no explicit choice exists,
so
       the switch always beats the operating system.
   =========================================================================== */

/* A theme is a different set of steps,
not a different set of rules. */
body[data-page="dashboard"][data-theme="dark"],
body[data-page="admin-dashboard"][data-theme="dark"],
body[data-page="supervisor-dashboard"][data-theme="dark"] {
  /* The neutral ramp, inverted. Not pure black: a near-black with the same
     green lean keeps the brand present and is easier to look at for an hour
     than #000, which makes every edge vibrate. */
  --n-0:   #18211d;
  --n-25:  #141d19;
  --n-50:  #101815;
  --n-100: #1f2b26;
  --n-200: #283530;
  --n-300: #35453e;
  --n-400: #5a6d64;
  --n-500: #7d9187;
  --n-600: #9bada3;
  --n-700: #bccbc3;
  --n-800: #d7e2db;
  --n-900: #e9efea;

  --bg: var(--n-50);
  --surface: var(--n-0);
  --soft: var(--n-100);
  --line: var(--n-200);
  --line-strong: var(--n-300);
  --text: var(--n-900);
  --navy: var(--n-900);
  --muted: var(--n-600);
  --muted-strong: var(--n-700);

  /* #1b6b52 is a dark green. On a dark surface it disappears, so the brand
     moves UP its own ramp rather than changing hue — the same green, lit. */
  --primary: var(--green-300);
  --primary-hover: var(--green-200);
  --primary-dark: var(--green-400);
  --primary-light: #16302a;
  --primary-tint: #1b3b32;
  --primary-border: #2f5a4a;
  --accent: var(--green-300);
  --accent-dark: var(--green-200);
  --accent-light: #16302a;

  /* Status tints invert: a pale wash becomes a deep one, and the text on it
     becomes the light step instead of the dark one. */
  --success: #6cc49f;
  --success-bg: #14302a;
  --success-border: #255b49;
  --qualified: #74c2a3;
  --qualified-bg: #16302b;
  --qualified-border: #2a5c4c;
  --warning: #e3b665;
  --warning-bg: #332a14;
  --warning-border: #5e4c1f;
  --info: #8fb9d1;
  --info-bg: #182831;
  --info-border: #2d4959;
  --danger: #f09a90;
  --danger-bg: #331f1d;
  --danger-border: #5e3330;

  --stage-bar-ok: #1b332c;
  --stage-bar-over: #33211f;

  /* A drop shadow is a light-mode device — it works by darkening a lighter
     surface, and there is nothing darker here to reach. Depth comes from the
     surfaces themselves, so the shadows stay but only as a faint seat. */
  --shadow-xs: 0 1px 2px rgba(0,0,0,.30);
  --shadow-sm: 0 1px 2px rgba(0,0,0,.30), 0 2px 6px -1px rgba(0,0,0,.26);
  --shadow: 0 1px 2px rgba(0,0,0,.28), 0 6px 16px -4px rgba(0,0,0,.34);
  --shadow-md: 0 2px 4px rgba(0,0,0,.28), 0 12px 24px -6px rgba(0,0,0,.40);
  --shadow-lg: 0 8px 20px -6px rgba(0,0,0,.44), 0 24px 48px -12px rgba(0,0,0,.52);
  --focus-ring: rgba(134,188,164,.28);

  /* The rail was already the darkest thing on screen. In dark mode the page
     catches up with it, so it goes one step further to stay a separate plane. */
  --sidebar-bg: #0b1411;
  --sidebar-bg-deep: #070e0c;
  --sidebar-text: #9db7ab;
  --sidebar-text-dim: #7e988c;
  --sidebar-active-bg: var(--green-700);
  --sidebar-line: rgba(255,255,255,.07);
}

/* Follow the operating system until somebody chooses for themselves. The
   :not() is what makes the switch win: once the cookie says "light", this
   whole block stops matching. */
@media (prefers-color-scheme: dark) {body[data-page="dashboard"]:not([data-theme="light"]),
body[data-page="admin-dashboard"]:not([data-theme="light"]),
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) {
    --n-0:   #18211d; --n-25:  #141d19; --n-50:  #101815; --n-100: #1f2b26;
    --n-200: #283530; --n-300: #35453e; --n-400: #5a6d64; --n-500: #7d9187;
    --n-600: #9bada3; --n-700: #bccbc3; --n-800: #d7e2db; --n-900: #e9efea;
    --bg: var(--n-50); --surface: var(--n-0); --soft: var(--n-100);
    --line: var(--n-200); --line-strong: var(--n-300);
    --text: var(--n-900); --navy: var(--n-900);
    --muted: var(--n-600); --muted-strong: var(--n-700);
    --primary: var(--green-300); --primary-hover: var(--green-200);
    --primary-dark: var(--green-400); --primary-light: #16302a;
    --primary-tint: #1b3b32; --primary-border: #2f5a4a;
    --accent: var(--green-300); --accent-dark: var(--green-200); --accent-light: #16302a;
    --success: #6cc49f; --success-bg: #14302a; --success-border: #255b49;
    --qualified: #74c2a3; --qualified-bg: #16302b; --qualified-border: #2a5c4c;
    --warning: #e3b665; --warning-bg: #332a14; --warning-border: #5e4c1f;
    --info: #8fb9d1; --info-bg: #182831; --info-border: #2d4959;
    --danger: #f09a90; --danger-bg: #331f1d; --danger-border: #5e3330;
    --stage-bar-ok: #1b332c; --stage-bar-over: #33211f;
    --shadow-xs: 0 1px 2px rgba(0,0,0,.30);
    --shadow-sm: 0 1px 2px rgba(0,0,0,.30), 0 2px 6px -1px rgba(0,0,0,.26);
    --shadow: 0 1px 2px rgba(0,0,0,.28), 0 6px 16px -4px rgba(0,0,0,.34);
    --shadow-md: 0 2px 4px rgba(0,0,0,.28), 0 12px 24px -6px rgba(0,0,0,.40);
    --shadow-lg: 0 8px 20px -6px rgba(0,0,0,.44), 0 24px 48px -12px rgba(0,0,0,.52);
    --focus-ring: rgba(134,188,164,.28);
    --sidebar-bg: #0b1411; --sidebar-bg-deep: #070e0c;
    --sidebar-text: #9db7ab; --sidebar-text-dim: #7e988c;
    --sidebar-active-bg: var(--green-700); --sidebar-line: rgba(255,255,255,.07);
  }
}

/* Two things the ramps alone cannot carry, because they are written as the
   literal word "white" in rules the marketing site shares.

   --control-bg is the inside of an input, a select, a secondary button: white
   on paper, the raised surface in the dark.
   --on-primary is what sits ON the brand green. White works when the green is
   #1b6b52; against the lit green dark mode uses, white is too close, so the
   label goes dark instead. */
:root { --control-bg: #ffffff; --on-primary: #ffffff; --on-primary-muted: #c9ccc0; }body[data-page="dashboard"][data-theme="dark"],
body[data-page="admin-dashboard"][data-theme="dark"],
body[data-page="supervisor-dashboard"][data-theme="dark"] { --control-bg: var(--n-0); --on-primary: var(--green-900); --on-primary-muted: var(--green-800); }
@media (prefers-color-scheme: dark) {body[data-page="dashboard"]:not([data-theme="light"]),
body[data-page="admin-dashboard"]:not([data-theme="light"]),
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) { --control-bg: var(--n-0); --on-primary: var(--green-900); --on-primary-muted: var(--green-800); }
}

/* Read the token instead of the word. Light mode is unchanged to the pixel —
   --control-bg is #ffffff there, which is what these all said already. */
body[data-page="dashboard"] .field input, body[data-page="admin-dashboard"] .field input, body[data-page="supervisor-dashboard"] .field input,
body[data-page="dashboard"] .field textarea, body[data-page="admin-dashboard"] .field textarea, body[data-page="supervisor-dashboard"] .field textarea,
body[data-page="dashboard"] .field select, body[data-page="admin-dashboard"] .field select, body[data-page="supervisor-dashboard"] .field select,
body[data-page="dashboard"] .table-heading select, body[data-page="admin-dashboard"] .table-heading select, body[data-page="supervisor-dashboard"] .table-heading select,
body[data-page="dashboard"] .button-secondary, body[data-page="admin-dashboard"] .button-secondary, body[data-page="supervisor-dashboard"] .button-secondary,
body[data-page="dashboard"] .admin-menu-toggle, body[data-page="admin-dashboard"] .admin-menu-toggle, body[data-page="supervisor-dashboard"] .admin-menu-toggle,
body[data-page="dashboard"] .admin-bulk-actions select, body[data-page="admin-dashboard"] .admin-bulk-actions select, body[data-page="supervisor-dashboard"] .admin-bulk-actions select,
body[data-page="dashboard"] .lead-info-row select, body[data-page="admin-dashboard"] .lead-info-row select, body[data-page="supervisor-dashboard"] .lead-info-row select,
body[data-page="dashboard"] .workspace-filter-group select, body[data-page="admin-dashboard"] .workspace-filter-group select, body[data-page="supervisor-dashboard"] .workspace-filter-group select,
body[data-page="dashboard"] .activity-custom input, body[data-page="admin-dashboard"] .activity-custom input, body[data-page="supervisor-dashboard"] .activity-custom input,
body[data-page="dashboard"] .activity-search input, body[data-page="admin-dashboard"] .activity-search input, body[data-page="supervisor-dashboard"] .activity-search input,
body[data-page="dashboard"] .lead-status-field select, body[data-page="admin-dashboard"] .lead-status-field select, body[data-page="supervisor-dashboard"] .lead-status-field select,
body[data-page="dashboard"] .lead-status-field input[type="date"], body[data-page="admin-dashboard"] .lead-status-field input[type="date"], body[data-page="supervisor-dashboard"] .lead-status-field input[type="date"],
body[data-page="dashboard"] .lead-status-field input[type="time"], body[data-page="admin-dashboard"] .lead-status-field input[type="time"], body[data-page="supervisor-dashboard"] .lead-status-field input[type="time"],
body[data-page="dashboard"] .remark-form textarea, body[data-page="admin-dashboard"] .remark-form textarea, body[data-page="supervisor-dashboard"] .remark-form textarea,
body[data-page="dashboard"] .remark-slots, body[data-page="admin-dashboard"] .remark-slots, body[data-page="supervisor-dashboard"] .remark-slots,
body[data-page="dashboard"] .remark-content, body[data-page="admin-dashboard"] .remark-content, body[data-page="supervisor-dashboard"] .remark-content,
body[data-page="dashboard"] .settings-card, body[data-page="admin-dashboard"] .settings-card, body[data-page="supervisor-dashboard"] .settings-card,
body[data-page="dashboard"] .follow-up-calendar-button, body[data-page="admin-dashboard"] .follow-up-calendar-button, body[data-page="supervisor-dashboard"] .follow-up-calendar-button,
body[data-page="dashboard"] .payment-action-more, body[data-page="admin-dashboard"] .payment-action-more, body[data-page="supervisor-dashboard"] .payment-action-more,
body[data-page="dashboard"] .phone-dialog-close, body[data-page="admin-dashboard"] .phone-dialog-close, body[data-page="supervisor-dashboard"] .phone-dialog-close,
body[data-page="dashboard"] .lead-delete-button, body[data-page="admin-dashboard"] .lead-delete-button, body[data-page="supervisor-dashboard"] .lead-delete-button,
body[data-page="dashboard"] .meta-form-option, body[data-page="admin-dashboard"] .meta-form-option, body[data-page="supervisor-dashboard"] .meta-form-option,
body[data-page="dashboard"] .meta-setup, body[data-page="admin-dashboard"] .meta-setup, body[data-page="supervisor-dashboard"] .meta-setup,
body[data-page="dashboard"] .form-card, body[data-page="admin-dashboard"] .form-card, body[data-page="supervisor-dashboard"] .form-card {
  background: var(--control-bg);
  color: var(--text);
}
/* Order matters here and I got it wrong once: --on-primary belongs to the
   FILLED button only. Written after the variants, it repainted every secondary
   and the delete button in near-black on a near-black surface -- three
   invisible buttons, one of them "Delete selected". The general rule goes
   first, the variants override it. */
body[data-page="dashboard"] .button, body[data-page="admin-dashboard"] .button, body[data-page="supervisor-dashboard"] .button { color: var(--on-primary); }
body[data-page="dashboard"] .user-chip, body[data-page="admin-dashboard"] .user-chip, body[data-page="supervisor-dashboard"] .user-chip { color: var(--on-primary); }
body[data-page="dashboard"] .button-secondary, body[data-page="admin-dashboard"] .button-secondary, body[data-page="supervisor-dashboard"] .button-secondary { color: var(--primary); }
body[data-page="dashboard"] .lead-delete-button, body[data-page="admin-dashboard"] .lead-delete-button, body[data-page="supervisor-dashboard"] .lead-delete-button { color: var(--danger); border-color: var(--danger-border); }
/* .button-light keeps a fixed lime fill, so like .brand-mark it takes a fixed
   dark label rather than one that follows the theme. */
body[data-page="dashboard"] .button-light, body[data-page="admin-dashboard"] .button-light, body[data-page="supervisor-dashboard"] .button-light { color: var(--green-900); }/* A date or time control draws its own calendar glyph in the OS's colour,
which on a dark field is a black icon on a black background. */
body[data-page="dashboard"][data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="admin-dashboard"][data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="dashboard"][data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator,
body[data-page="admin-dashboard"][data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator,
body[data-page="supervisor-dashboard"][data-theme="dark"] input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="supervisor-dashboard"][data-theme="dark"] input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(.85); }/* The welcome panel is a gradient of the brand green with white on it. In dark
   mode the brand green is the LIT one,
so the gradient would be the brightest
   thing on the screen. It goes back down the ramp. */
body[data-page="dashboard"][data-theme="dark"] .welcome-panel,
body[data-page="admin-dashboard"][data-theme="dark"] .welcome-panel,
body[data-page="supervisor-dashboard"][data-theme="dark"] .welcome-panel {
  background: linear-gradient(135deg, var(--green-800), var(--green-900));
  border-color: var(--green-700);
}body[data-page="dashboard"][data-theme="dark"] ::selection,
body[data-page="admin-dashboard"][data-theme="dark"] ::selection,
body[data-page="supervisor-dashboard"][data-theme="dark"] ::selection { background: var(--green-700); color: #eef6f1; }
@media (prefers-color-scheme: dark) {body[data-page="dashboard"]:not([data-theme="light"]) .welcome-panel,
body[data-page="admin-dashboard"]:not([data-theme="light"]) .welcome-panel,
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) .welcome-panel {
    background: linear-gradient(135deg, var(--green-800), var(--green-900));
    border-color: var(--green-700);
  }body[data-page="dashboard"]:not([data-theme="light"]) ::selection,
body[data-page="admin-dashboard"]:not([data-theme="light"]) ::selection,
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) ::selection { background: var(--green-700); color: #eef6f1; }body[data-page="dashboard"]:not([data-theme="light"]) input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="admin-dashboard"]:not([data-theme="light"]) input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="dashboard"]:not([data-theme="light"]) input[type="time"]::-webkit-calendar-picker-indicator,
body[data-page="admin-dashboard"]:not([data-theme="light"]) input[type="time"]::-webkit-calendar-picker-indicator,
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) input[type="date"]::-webkit-calendar-picker-indicator,
body[data-page="supervisor-dashboard"]:not([data-theme="light"]) input[type="time"]::-webkit-calendar-picker-indicator { filter: invert(.85); }
}

/* The switch itself. Sits beside the account chip in the bar. */
.theme-toggle { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 34px; height: 34px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--control-bg); color: var(--muted); cursor: pointer; transition: background .16s ease, border-color .16s ease, color .16s ease; }
.theme-toggle:hover { border-color: var(--primary); color: var(--text); }
.theme-toggle:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
.theme-toggle svg { width: 17px; height: 17px; }
/* One button, two glyphs: show the thing you would switch TO, which is what
   the control promises. */
.theme-toggle .theme-icon-dark { display: none; }
body[data-theme="dark"] .theme-toggle .theme-icon-dark { display: block; }
body[data-theme="dark"] .theme-toggle .theme-icon-light { display: none; }
@media (prefers-color-scheme: dark) {
  body:not([data-theme="light"]) .theme-toggle .theme-icon-dark { display: block; }
  body:not([data-theme="light"]) .theme-toggle .theme-icon-light { display: none; }
}

/* Two things dark mode exposed that were latent bugs, not dark-mode problems.

   The metric card's footnote had NO colour rule anywhere: it inherited the
   <button> element's default black and happened to sit on a white card. Its
   sibling .stat-tile small was always --muted, so this just matches what it
   should have said all along.

   The brand mark's background is a fixed lime that does not follow the theme,
   so its text cannot follow the theme either -- with color:var(--navy) the "S"
   inverted to near-white on lime and vanished. A fixed background takes a
   fixed foreground. */
.metric-grid .metric-card { color: var(--text); }
.metric-grid .metric-card small { color: var(--muted); }
.brand-mark { color: var(--green-900); }

/* Everything else in the console that paints white onto the brand fill. In
   light mode --on-primary IS white, so none of these change;in dark the fill
   is the lit green and the label goes dark instead. The marketing site's
   equivalents are left alone -- it has no dark mode. */
body[data-page="dashboard"] .activity-range[aria-pressed="true"],
body[data-page="admin-dashboard"] .activity-range[aria-pressed="true"],
body[data-page="dashboard"] .follow-up-quick.is-active,
body[data-page="admin-dashboard"] .follow-up-quick.is-active,
body[data-page="dashboard"] .lead-notes-header,
body[data-page="admin-dashboard"] .lead-notes-header,
body[data-page="dashboard"] .metric-grid .metric-card:hover .metric-icon,
body[data-page="admin-dashboard"] .metric-grid .metric-card:hover .metric-icon,
body[data-page="supervisor-dashboard"] .activity-range[aria-pressed="true"],
body[data-page="supervisor-dashboard"] .follow-up-quick.is-active,
body[data-page="supervisor-dashboard"] .lead-notes-header,
body[data-page="supervisor-dashboard"] .metric-grid .metric-card:hover .metric-icon { color: var(--on-primary); }body[data-page="dashboard"] .lead-notes-header span,
body[data-page="admin-dashboard"] .lead-notes-header span,
body[data-page="supervisor-dashboard"] .lead-notes-header span { color: var(--on-primary-muted); }

/* --- Command palette -----------------------------------------------------
   Sits high rather than centred: the list grows downward as you type, and a
   vertically-centred box would jump every keystroke. */
.command-palette { width: min(560px, calc(100vw - 32px)); max-width: none; margin-top: 12vh; padding: 0; border: 0; border-radius: var(--radius-md); background: none; }
.command-palette-card { overflow: hidden; border: 1px solid var(--line-strong); border-radius: var(--radius-md); background: var(--surface); box-shadow: var(--shadow-lg); }
.command-palette-field { display: flex; align-items: center; gap: 10px; padding: 13px 15px; border-bottom: 1px solid var(--line); }
.command-palette-field svg { flex: none; width: 17px; height: 17px; color: var(--muted); }
/* A bare input: the field around it is the control, so the box itself keeps
   no border, no ring and no background of its own. */
.command-palette-field input { width: 100%; min-height: 0; padding: 0; border: 0; background: none; color: var(--text); font: inherit; font-size: .95rem; outline: none; }
.command-palette-field input::placeholder { color: var(--muted); }
.command-palette kbd { flex: none; padding: 2px 6px; border: 1px solid var(--line); border-radius: var(--radius-xs); background: var(--soft); color: var(--muted); font-family: inherit; font-size: .66rem; font-weight: 700; }
.command-palette-results { max-height: min(50vh, 380px); padding: 6px; overflow-y: auto; }
.command-palette-group { padding: 10px 10px 4px; color: var(--muted); font-size: .64rem; font-weight: 800; letter-spacing: .08em; text-transform: uppercase; }
.command-item { display: flex; align-items: center; gap: 11px; width: 100%; padding: 9px 10px; border: 0; border-radius: var(--radius-sm); background: none; color: var(--text); font: inherit; font-size: .86rem; text-align: left; cursor: pointer; }
.command-item svg { flex: none; width: 16px; height: 16px; color: var(--muted); }
/* Selection is driven from the keyboard, so it is a class rather than :hover —
   the mouse sets the same class on enter, and the two can never disagree about
   which row Enter will open. */
.command-item.is-selected { background: var(--primary-light); }
.command-item.is-selected svg { color: var(--primary); }
.command-item-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.command-item-meta { margin-left: auto; padding-left: 10px; flex: none; color: var(--muted); font-size: .74rem; }
.command-palette-empty { padding: 22px 12px; color: var(--muted); font-size: .86rem; text-align: center; }
.command-palette-foot { display: flex; gap: 16px; padding: 9px 15px; border-top: 1px solid var(--line); background: var(--soft); color: var(--muted); font-size: .7rem; }
.command-palette-foot kbd { margin-right: 3px; }
/* The hint in the top bar. Hidden on touch, where there is no keyboard to
   press and the sentence would be a lie. */
.command-hint { display: none; align-items: center; gap: 7px; padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--control-bg); color: var(--muted); font-size: .76rem; cursor: pointer; transition: border-color .16s ease, color .16s ease; }
.command-hint:hover { border-color: var(--primary); color: var(--text); }
.command-hint:focus-visible { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--focus-ring); }
@media (hover: hover) and (pointer: fine) and (min-width: 860px) { .command-hint { display: inline-flex; } }
@media (prefers-reduced-motion: no-preference) {
  .command-palette[open] { animation: dialogIn .14s ease both; }
}/* The UA stylesheet gives <dialog> its own `color: CanvasText`,
which BREAKS
   inheritance from body: any text inside a dialog with no colour rule of its
   own falls back to the operating system's text colour rather than the app's.
   Nobody saw it in light mode,
where CanvasText is black and --text is
   near-black -- but on a dark card it is black on black,
which is how "Add a
   transaction" came to have an invisible description.
   It is wrong in the other direction too: on a Mac set to dark,
CanvasText is
   WHITE,
so the same paragraphs were white-on-white for anyone running the
   console's light theme under a dark OS. Stating the colour fixes both. */
body[data-page="dashboard"] dialog,
body[data-page="admin-dashboard"] dialog,
body[data-page="supervisor-dashboard"] dialog { color: var(--text); }

/* Project management: the Plan & design sub-tabs and the record form.
   The sub-tabs sit inside a tab panel, so they are the outer tab bar a size
   down rather than a second navigation idiom to learn. */
.lead-detail-subtabs { margin: 14px 0 2px; font-size: .92rem; }
/* .lead-detail-tabs is display:flex, and an author rule beats the UA stylesheet
   rule behind the hidden attribute — so without this the module tabs for every
   section render at once, stacked. */
.lead-detail-tabs[hidden] { display: none; }
.lead-detail-subtabs .lead-detail-tab { padding-bottom: 8px; }

/* Two fields to a row, except the ones the spec marks full width — a title, a
   specification, a decision. One column on a phone, which is where a site
   supervisor actually fills this in. */
[data-pm-fields] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
/* The grid above outranks the UA's [hidden] rule, so restate it — without this
   every module's fields show at once, 207 of them in one dialog. */
[data-pm-fields][hidden] { display: none; }
[data-pm-fields] .field.is-full { grid-column: 1 / -1; }
@media (max-width: 760px) { [data-pm-fields] { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   The supervisor's project workspace.

   A sidebar of sections beside the work, rather than one long row of tabs:
   eleven destinations do not fit across a project detail, and a supervisor
   moves between them all day. Scoped to body[data-page="supervisor-dashboard"]
   so the member and admin consoles are untouched.
--------------------------------------------------------------------------- */
body[data-page="supervisor-dashboard"] .pw-shell {
  display: grid;
  grid-template-columns: 216px minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
body[data-page="supervisor-dashboard"] .pw-sidebar { position: sticky; top: 12px; }

.pw-project-chip {
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 15px;
  margin-bottom: 18px;
  background: var(--soft);
  display: grid;
  gap: 3px;
}
.pw-project-chip .eyebrow { font-size: .62rem; letter-spacing: .09em; }
.pw-project-chip strong { font-size: 1.02rem; line-height: 1.25; }
.pw-project-chip span { color: var(--muted); font-size: .78rem; }
.pw-project-chip .lead-status-pill { justify-self: start; margin-top: 5px; }

.pw-nav { display: grid; gap: 1px; }
.pw-nav-label {
  color: var(--muted);
  font-size: .64rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: 16px 10px 6px;
}
.pw-nav .lead-detail-tab {
  text-align: left;
  width: 100%;
  padding: 9px 11px;
  border-radius: 9px;
  border-bottom: 0;
  font-size: .88rem;
}
.pw-nav .lead-detail-tab:hover { background: var(--soft); }
.pw-nav .lead-detail-tab.is-active { background: var(--accent-soft, var(--soft)); color: var(--text); }

/* The page a section opens on: a title, what it is for, and the one button
   that adds to it. */
.pw-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 18px; margin-bottom: 20px; }
.pw-head h2 { font-size: 1.85rem; margin: 2px 0 6px; letter-spacing: -.02em; }
.pw-head p { color: var(--muted); margin: 0; max-width: 60ch; }

/* The hero on Overview. Deliberately the only place in the console with a
   headline voice: it is the first thing a supervisor sees each morning. */
.pw-hero {
  display: flex; justify-content: space-between; align-items: center; gap: 28px; flex-wrap: wrap;
  border: 1px solid var(--line); border-radius: 16px; padding: 26px 28px; background: var(--soft);
}
.pw-hero h3 { font-size: 1.6rem; line-height: 1.22; margin: 8px 0 10px; letter-spacing: -.02em; }
.pw-hero p { color: var(--muted); margin: 0; }
.pw-hero-aside { text-align: right; min-width: 190px; }
.pw-hero-aside strong { display: block; font-size: 2.6rem; line-height: 1; letter-spacing: -.03em; }
.pw-hero-aside span { color: var(--muted); font-size: .8rem; }
.pw-meter { height: 7px; border-radius: 999px; background: var(--line); overflow: hidden; margin-top: 12px; }
.pw-meter i { display: block; height: 100%; background: var(--success, #4a7); border-radius: 999px; }

/* Six tiles, so the column count has to divide six: auto-fit does not know
   how many children it has and landed on five at 1440px and four at 1024px,
   leaving the last tile -- or two of them -- orphaned on a row of their own.
   Six, three and two all divide evenly, so the count is stated outright. */
.pw-quick { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .pw-quick { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 620px) { .pw-quick { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pw-quick button {
  display: grid; gap: 8px; text-align: left; padding: 15px 16px;
  border: 1px solid var(--line); border-radius: 13px; background: transparent;
  color: var(--text); cursor: pointer; font: inherit; font-weight: 700;
}
.pw-quick button:hover { background: var(--soft); }
.pw-quick .pw-quick-icon { font-size: 1.05rem; color: var(--muted); }

.pw-section-top { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; margin: 26px 0 12px; }
.pw-section-top h3 { font-size: 1.02rem; margin: 0; }
.pw-section-top span { color: var(--muted); font-size: .8rem; }

/* Search, the two filters and Export CSV, above every record table. */
.pw-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin-bottom: 14px; }
.pw-filters input, .pw-filters select { min-width: 170px; }
.pw-filters .pw-filters-end { margin-left: auto; display: flex; align-items: center; gap: 14px; }
.pw-count { color: var(--muted); font-size: .8rem; white-space: nowrap; }

/* The reference prints a short code under each record — SC1, D1, V1 — so a
   row can be named out loud on site. */
.pw-rowcode { display: block; color: var(--muted); font-size: .74rem; margin-top: 3px; }



/* A record opened for reading: label above value, two to a row. */
.pw-detail-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 18px; margin: 16px 0 6px; }
.pw-detail-list > div.is-full { grid-column: 1 / -1; }
.pw-detail-list dt { color: var(--muted); font-size: .72rem; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; margin-bottom: 3px; }
.pw-detail-list dd { margin: 0; white-space: pre-wrap; }
@media (max-width: 760px) { .pw-detail-list { grid-template-columns: 1fr; } }
/* The row's one control: an arrow, not three words. */
.pw-open { min-width: 34px; padding-inline: 10px; font-size: 1rem; line-height: 1; }

/* ---------------------------------------------------------------------------
   The project workspace on a phone.

   This is where it is actually used: a supervisor is standing on the site with
   one hand free, not at a desk. Two things drive the whole of this block.

   A six-column table cannot be made to fit 375px, so below 760px every record
   table becomes a list of cards. The markup does not change -- the table is
   still a table for a screen reader and for the desktop -- but each cell is
   laid out as a labelled line, which is why the renderer writes the column
   heading onto every <td> as data-label.

   And everything you press is at least 44px tall, because the alternative is
   somebody mis-tapping Delete with wet hands.
--------------------------------------------------------------------------- */
@media (max-width: 900px) {
  body[data-page="supervisor-dashboard"] .pw-shell {
    /* minmax(0,…) not 1fr: a bare 1fr floors at the content's min width, which
       a wide table then pushes past the viewport, and the whole page scrolls
       sideways. */
    grid-template-columns: minmax(0, 1fr);
    gap: 10px;
  }
  body[data-page="supervisor-dashboard"] .pw-sidebar { position: static; min-width: 0; }
  body[data-page="supervisor-dashboard"] .pw-main { min-width: 0; }

  /* The sections become a strip you swipe, kept in view rather than collapsed
     behind a menu: a supervisor switches between them constantly. */
  .pw-nav {
    grid-auto-flow: column;
    grid-auto-columns: max-content;
    overflow-x: auto;
    gap: 6px;
    padding-bottom: 8px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .pw-nav::-webkit-scrollbar { display: none; }

  /* Which way there is more. The strip hides its scrollbar, so nothing said
     that eight more destinations sat past the third.
     Drawn as a mask rather than a gradient in the page colour: a mask needs no
     background to match, so it is right in both themes and over the card the
     strip sits on. The script sets the attribute; only the edges that still
     have something beyond them are faded, so at either end the first and last
     destination stay fully legible. */
  .pw-nav[data-scroll-edge~="end"],
  .lead-detail-subtabs[data-scroll-edge~="end"] {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 38px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 38px), transparent);
  }
  .pw-nav[data-scroll-edge~="start"],
  .lead-detail-subtabs[data-scroll-edge~="start"] {
    -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 38px), transparent);
    mask-image: linear-gradient(to left, #000 calc(100% - 38px), transparent);
  }
  .pw-nav[data-scroll-edge~="start"][data-scroll-edge~="end"],
  .lead-detail-subtabs[data-scroll-edge~="start"][data-scroll-edge~="end"] {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 38px, #000 calc(100% - 38px), transparent);
    mask-image: linear-gradient(to right, transparent, #000 38px, #000 calc(100% - 38px), transparent);
  }
  .pw-nav .lead-detail-tab { white-space: nowrap; min-height: 44px; padding: 10px 14px; }
  .pw-nav-label { display: none; }

  .pw-project-chip { margin-bottom: 12px; }
  .pw-head { flex-direction: column; align-items: stretch; }
  .pw-head h2 { font-size: 1.5rem; }
  .pw-head .button { width: 100%; min-height: 46px; }
  .pw-hero { padding: 20px; gap: 16px; }
  .pw-hero-aside { text-align: left; min-width: 0; }
  .pw-hero-aside strong { font-size: 2.1rem; }
}

@media (max-width: 760px) {
  /* Summary cards two across: four in a row at this width leaves each one
     narrower than the number inside it. */
  body[data-page="supervisor-dashboard"] .lead-payments-summary {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .pw-quick { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pw-quick button { min-height: 76px; }

  /* Filters stack and fill the width, so each is a comfortable target and the
     search box is not a sliver. */
  .pw-filters { flex-direction: column; align-items: stretch; gap: 8px; }
  .pw-filters input, .pw-filters select { min-width: 0; width: 100%; min-height: 44px; }
  .pw-filters .pw-filters-end { margin-left: 0; justify-content: space-between; }
  .pw-filters .pw-filters-end button { min-height: 44px; }
  .pw-section-top { flex-wrap: wrap; gap: 4px 12px; }

  /* The module tabs scroll sideways rather than wrapping to four rows. */
  .lead-detail-subtabs {
    display: flex; flex-wrap: nowrap; overflow-x: auto;
    gap: 16px; scrollbar-width: none;
  }
  .lead-detail-subtabs::-webkit-scrollbar { display: none; }
  .lead-detail-subtabs .lead-detail-tab { white-space: nowrap; min-height: 44px; }

  /* --- tables become cards ------------------------------------------------ */
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table-wrap { overflow: visible; }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table,
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table tbody,
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table tr,
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td { display: block; width: auto; }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table thead { display: none; }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table tr {
    position: relative;
    border: 1px solid var(--line);
    border-radius: 13px;
    padding: 14px 15px;
    margin-bottom: 10px;
    background: var(--card, transparent);
  }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td {
    border: 0;
    padding: 0 0 9px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    text-align: right;
  }
  /* The label the renderer copied off the column heading. */
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    text-align: left;
    flex: 0 0 42%;
  }
  /* The first cell is the card's heading, so it keeps no label and sits on its
     own line with the record code beneath it. */
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td:first-child {
    display: block;
    text-align: left;
    font-weight: 700;
    font-size: 1rem;
    padding-right: 54px;
    margin-bottom: 10px;
  }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td:first-child::before { content: none; }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td:first-child .pw-rowcode { font-weight: 600; }
  /* Open sits in the card's top-right corner, where a thumb reaches. */
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td:last-child {
    position: absolute; top: 12px; right: 12px; padding: 0;
  }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td:last-child::before { content: none; }
  body[data-page="supervisor-dashboard"] .pw-main .pw-open { min-height: 40px; min-width: 40px; }
  /* The empty state is one cell, and should not be laid out as a labelled row. */
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td.is-no-nav:only-child {
    display: block; text-align: left; padding: 2px 0;
  }
  body[data-page="supervisor-dashboard"] .pw-main .workspace-table td.is-no-nav:only-child::before { content: none; }

  /* A supervisor taps these outdoors, often one-handed: 34px icon buttons and
     38px chips are below the 44px a thumb reliably hits. */
  body[data-page="supervisor-dashboard"] .theme-toggle,
  body[data-page="supervisor-dashboard"] .admin-menu-toggle { min-width: 44px; min-height: 44px; }
  body[data-page="supervisor-dashboard"] .workspace-filter-item { min-height: 44px; }
  /* The small buttons too: "Add an expense", "Send a payment request" and the
     back control all sat at 39px. Inline text links keep their own size --
     stretching them would break the sentence they sit in. */
  body[data-page="supervisor-dashboard"] .button,
  body[data-page="supervisor-dashboard"] .button-small { min-height: 44px; }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] input[type="search"],
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-search input { min-height: 44px; }

  /* --- the projects list becomes cards too -------------------------------
     It sits outside .pw-main, so it kept the desktop table: 811px of columns
     in a 347px window, and a supervisor had to swipe sideways 464px to read
     the stage of the project they were standing in. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table-wrap { overflow: visible; }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table,
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tbody,
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tr,
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td { display: block; width: auto; }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table thead { display: none; }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tr {
    border: 1px solid var(--line);
    border-radius: 13px;
    padding: 14px 15px;
    margin-bottom: 10px;
    background: var(--card, transparent);
  }
  /* Nothing in this console acts on a selected project -- there are no bulk
     actions on a supervisor's screen -- so on a phone the select box is an
     18px target spending width the project's name needs. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tbody td:first-child { display: none; }
  /* The project's name is the card's heading, so it carries no label. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tbody td:nth-child(2) {
    padding: 0 0 10px;
    border: 0;
  }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td[data-label] {
    border: 0;
    padding: 0 0 9px;
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 14px;
    text-align: right;
  }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td[data-label]::before {
    content: attr(data-label);
    color: var(--muted);
    font-size: .72rem;
    font-weight: 800;
    letter-spacing: .05em;
    text-transform: uppercase;
    text-align: left;
    flex: 0 0 42%;
  }
  /* The visit cell carries two blocks of its own (Site and EC). Spread across
     a labelled row they ran off the right edge, so this one stacks: its label
     on its own line, the two visits beneath it. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td.workspace-visit-cell {
    display: flex;
    flex-wrap: wrap;
    text-align: left;
    gap: 5px 20px;
  }
  /* The label takes a line of its own; the two visits share the next one, and
     wrap to a second when both carry a date. They are appended with no
     whitespace between them, so only flex wrapping can break them -- as
     inline boxes they had no break opportunity and ran off the screen. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td.workspace-visit-cell::before {
    flex: 0 0 100%;
  }
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td.workspace-visit-cell .workspace-visit-block {
    display: grid;
  }
  /* Nothing inside a labelled row may force the card wider than the screen. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table td[data-label] > * { min-width: 0; }

  /* "No leads match" is one cell spanning the row, not a labelled line. */
  body[data-page="supervisor-dashboard"] [data-workspace-panel="leads"] .workspace-table tbody td[colspan] {
    display: block; text-align: left; padding: 2px 0;
  }

  /* Dialogs become sheets: full width, one column, and tall enough to scroll
     rather than trapping the save button off-screen. */
  .expense-dialog { width: 100%; max-width: 100%; margin: 0; border-radius: 16px 16px 0 0; }
  .expense-dialog .csv-import-card { max-height: 92vh; overflow-y: auto; }
  [data-pm-fields] { grid-template-columns: 1fr; }
  .expense-dialog .lead-form-actions { position: sticky; bottom: 0; background: var(--bg); padding-top: 12px; }
  .expense-dialog .lead-form-actions .button { flex: 1; min-height: 46px; }
  .pw-detail-list { grid-template-columns: 1fr; }
}

/* The filter controls sit outside a .field, so they were getting the browser's
   own white box and black text — unreadable in dark mode, on desktop as well
   as on a phone. They take the same treatment every other control does. */
body[data-page="supervisor-dashboard"] .pw-filters input,
body[data-page="supervisor-dashboard"] .pw-filters select {
  min-height: 44px;
  padding: 10px 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  background: var(--control-bg);
  color: var(--text);
  font: inherit;
  outline: none;
}
body[data-page="supervisor-dashboard"] .pw-filters input:focus,
body[data-page="supervisor-dashboard"] .pw-filters select:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
body[data-page="supervisor-dashboard"] .pw-filters input::placeholder { color: var(--muted); }

/* ---------------------------------------------------------------------------
   Financial Report (admin console only)

   Every chart here is inline SVG built in main.js, for the same reason the city
   chart is drawn with the grid: the page has no build step and its content
   security policy blocks remote scripts, so a CDN charting library would simply
   not load. The series colours live here rather than in the script so dark mode
   can lighten the whole set in one place.
   --------------------------------------------------------------------------- */
body[data-page="admin-dashboard"] {
  --finance-s1: #1f7a4d;
  --finance-s2: #3f8fb0;
  --finance-s3: #b2802f;
  --finance-s4: #7c5fa8;
  --finance-s5: #9a5252;
  --finance-s6: #5c7a8a;
}

.finance-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 18px 0 16px; }
.finance-views { display: inline-flex; padding: 3px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--soft); }
.finance-view-tab { padding: 7px 16px; border: 0; border-radius: calc(var(--radius-sm) - 2px); background: none; color: var(--muted); font: inherit; font-size: .84rem; font-weight: 600; cursor: pointer; }
.finance-view-tab:hover { color: var(--text); }
.finance-view-tab.active { background: var(--surface); color: var(--primary); box-shadow: var(--shadow-xs); }
.finance-toolbar-actions { display: flex; align-items: center; gap: 8px; margin-left: auto; }
.finance-stamp { color: var(--muted); font-size: .76rem; }

.finance-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 12px; margin-bottom: 18px; }
.finance-kpi { display: flex; flex-direction: column; gap: 5px; padding: 16px 18px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.finance-kpi-label { color: var(--muted); font-size: .76rem; font-weight: 600; }
.finance-kpi-value { color: var(--navy); font-size: 1.32rem; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.finance-kpi-sub { color: var(--muted); font-size: .73rem; }

.finance-panel { display: grid; gap: 16px; }
/* An author `display` outranks the user agent's [hidden] rule, and the two
   inactive panels are rendered carrying it. Restated here, as everywhere
   else in this file that a hidden element is given a display. */
.finance-panel[hidden] { display: none; }
.finance-row { display: grid; grid-template-columns: minmax(260px, 360px) 1fr; gap: 16px; }
.finance-card { padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); }
.finance-card > header { margin-bottom: 14px; }
.finance-card h3 { margin: 0; color: var(--navy); font-size: .95rem; font-weight: 700; }
.finance-card header p { margin: 3px 0 0; color: var(--muted); font-size: .78rem; }
.finance-card.is-table { padding-bottom: 8px; }
.finance-chart { min-height: 40px; }
.finance-empty, .finance-empty-cell { padding: 18px 0; color: var(--muted); font-size: .82rem; text-align: center; }
.finance-note { margin: 12px 0 0; color: var(--muted); font-size: .76rem; }

/* Donut + legend */
.finance-donut { display: block; width: 100%; max-width: 210px; margin: 0 auto; }
.finance-donut-value { fill: var(--navy); font-size: 21px; font-weight: 700; }
.finance-donut-label { fill: var(--muted); font-size: 10px; }
.finance-legend { display: grid; gap: 8px; margin: 16px 0 0; padding: 0; list-style: none; }
.finance-legend li { display: grid; grid-template-columns: 10px 1fr auto auto; align-items: center; gap: 9px; font-size: .8rem; }
.finance-dot { width: 10px; height: 10px; border-radius: 3px; }
.finance-legend-name { color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.finance-legend-value { color: var(--navy); font-weight: 600; font-variant-numeric: tabular-nums; }
.finance-legend-share { min-width: 44px; color: var(--muted); text-align: right; font-variant-numeric: tabular-nums; }

/* Bar + line plot */
.finance-plot { display: block; width: 100%; height: auto; }
.finance-grid { stroke: var(--line); stroke-width: 1; }
.finance-axis { fill: var(--muted); font-size: 10px; }
.finance-axis-right { text-anchor: start; }
.finance-bar { fill: var(--primary); }
.finance-bar.is-booking { fill: var(--finance-s2); }
.finance-bar-label { fill: var(--muted); font-size: 10px; font-weight: 600; }
.finance-line { fill: none; stroke: var(--finance-s3); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.finance-line-dot { fill: var(--finance-s3); }
.finance-axis-key { margin: 10px 0 0; color: var(--muted); font-size: .73rem; }

/* Horizontal bars */
.finance-hbars { display: grid; gap: 9px; margin: 0; padding: 0; list-style: none; }
.finance-hbars li { display: grid; grid-template-columns: minmax(110px, 170px) 1fr auto auto; align-items: center; gap: 12px; font-size: .82rem; }
.finance-hbars.is-bands li { grid-template-columns: minmax(130px, 190px) 1fr auto; }
.finance-hbar-name { color: var(--navy); font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.finance-hbar-track { height: 18px; border-radius: var(--radius-sm); background: var(--soft); }
.finance-hbar-fill { display: block; height: 100%; min-width: 3px; border-radius: var(--radius-sm); background: var(--primary); }
.finance-hbar-value { min-width: 96px; color: var(--navy); text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; }
.finance-hbar-count { min-width: 30px; color: var(--muted); text-align: right; font-size: .76rem; font-variant-numeric: tabular-nums; }

/* Gantt of payment spans */
.finance-gantt-scale { position: relative; height: 18px; margin-left: 170px; border-bottom: 1px solid var(--line); }
.finance-gantt-tick { position: absolute; top: 0; color: var(--muted); font-size: .68rem; transform: translateX(-50%); }
.finance-gantt { display: grid; gap: 6px; margin: 10px 0 0; padding: 0; list-style: none; }
.finance-gantt li { display: grid; grid-template-columns: 158px 1fr 64px; align-items: center; gap: 12px; }
.finance-gantt-name { color: var(--navy); font-size: .8rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.finance-gantt-track { position: relative; height: 14px; border-radius: var(--radius-sm); background: var(--soft); }
.finance-gantt-bar { position: absolute; top: 2px; height: 10px; min-width: 10px; border-radius: 5px; background: var(--primary); }
/* A client who paid once has no span; a zero-width bar would read as missing. */
.finance-gantt-bar.is-point { width: 10px; background: var(--finance-s2); }
.finance-gantt-value { color: var(--muted); text-align: right; font-size: .74rem; font-variant-numeric: tabular-nums; }

/* Tables */
.finance-table-wrap { overflow-x: auto; }
.finance-table { width: 100%; border-collapse: collapse; font-size: .84rem; }
.finance-table th { padding: 9px 12px; border-bottom: 1px solid var(--line); color: var(--muted); text-align: left; font-size: .7rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; white-space: nowrap; }
.finance-table td { padding: 9px 12px; border-bottom: 1px solid var(--line); color: var(--text); }
.finance-table tbody tr:last-child td { border-bottom: 0; }
.finance-table .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.finance-table .is-strong { color: var(--navy); font-weight: 600; }
.finance-table .is-muted { color: var(--muted); }
.finance-flag { display: inline-block; margin-left: 7px; padding: 1px 7px; border-radius: 999px; background: var(--warning-bg); color: var(--warning); font-size: .66rem; font-weight: 600; }

@media (max-width: 900px) {
  .finance-row { grid-template-columns: 1fr; }
  .finance-gantt-scale { margin-left: 106px; }
  .finance-gantt li { grid-template-columns: 94px 1fr 56px; }
  .finance-hbars li { grid-template-columns: minmax(84px, 120px) 1fr auto auto; }
  .finance-toolbar-actions { margin-left: 0; }
}

/* The series lit for a dark surface. Same six hues, moved up so none of them
   disappears against #18211d — the same move --primary makes. Both selectors,
   because the console honours an explicit choice and the system setting. */
body[data-page="admin-dashboard"][data-theme="dark"] {
  --finance-s1: #4bb37c;
  --finance-s2: #6fb7d6;
  --finance-s3: #ddae5c;
  --finance-s4: #a98fd4;
  --finance-s5: #c98484;
  --finance-s6: #8fadbd;
}
@media (prefers-color-scheme: dark) {
  body[data-page="admin-dashboard"]:not([data-theme="light"]) {
    --finance-s1: #4bb37c;
    --finance-s2: #6fb7d6;
    --finance-s3: #ddae5c;
    --finance-s4: #a98fd4;
    --finance-s5: #c98484;
    --finance-s6: #8fadbd;
  }
}

/* Spending, and the margin it leaves. Spend borrows the warning hue rather
   than a sixth series colour: it is money leaving, and reading it against
   collected at a glance matters more than it matching the donut. */
.finance-bar.is-spent { fill: var(--finance-s5); }
.finance-hbar-fill.is-spent { background: var(--finance-s5); }
.finance-zero { stroke: var(--line-strong); stroke-width: 1; stroke-dasharray: 3 3; }
.finance-line-dot.is-loss { fill: var(--danger); }
.finance-table .is-loss { color: var(--danger); }
.finance-key-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 2px; vertical-align: -1px; }
.finance-key-swatch.is-collected { background: var(--primary); }
.finance-key-swatch.is-spent { background: var(--finance-s5); }
.finance-key-swatch.is-margin { background: var(--finance-s3); }

.finance-splits { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 22px; }
.finance-split-title { margin: 0 0 10px; color: var(--muted); font-size: .72rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; }
.finance-split .finance-hbars li { grid-template-columns: minmax(96px, 1fr) 54px auto; gap: 9px; font-size: .78rem; }
.finance-split .finance-hbar-value { min-width: 72px; }

/* Profit & Loss. Shares the Financial Report's furniture; what is new here is
   the three-way split of revenue and the one figure that may be negative. */
.finance-pie { display: block; width: 100%; max-width: 220px; margin: 0 auto; }
.finance-slice { stroke: var(--surface); stroke-width: 2; }
.finance-slice.is-site, .finance-dot.is-site { fill: var(--finance-s5); background: var(--finance-s5); }
.finance-slice.is-overhead, .finance-dot.is-overhead { fill: var(--finance-s4); background: var(--finance-s4); }
.finance-slice.is-profit, .finance-dot.is-profit { fill: var(--primary); background: var(--primary); }
.finance-hbar-fill.is-overhead { background: var(--finance-s4); }

.finance-step { fill: var(--primary); }
.finance-step.is-revenue { fill: var(--finance-s2); }
.finance-step.is-site { fill: var(--finance-s5); }
.finance-step.is-overhead { fill: var(--finance-s4); }
.finance-step.is-profit { fill: var(--primary); }
.finance-step.is-loss { fill: var(--danger); }

/* The bottom line is the figure people look for, so it is marked rather than
   left to sit among five others that look the same. */
.finance-kpi.is-profit { border-color: var(--primary-border); background: var(--primary-light); }
.finance-kpi.is-profit .finance-kpi-value { color: var(--primary-dark); }
.finance-kpi.is-loss { border-color: var(--danger-border); background: var(--danger-bg); }
.finance-kpi.is-loss .finance-kpi-value { color: var(--danger); }

.finance-row-remove { padding: 3px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: none; color: var(--muted); font: inherit; font-size: .74rem; cursor: pointer; }
.finance-row-remove:hover { border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger); }

/* [hidden] is outranked by an author display, and these panels render with it. */
.finance-panel[data-pnl-panel][hidden] { display: none; }

/* A dialog taller than the window must still reach its own buttons.
   The three short dialogs in this console never hit this; the overhead form
   has seven fields and did -- Add expense sat below the fold with nothing to
   scroll, so the form could be filled in and not submitted. The cap is a
   safety net for every dialog; a short one is under it and looks unchanged. */
.phone-dialog { max-height: 94vh; max-height: 94dvh; }
.phone-dialog-card { max-height: 94vh; max-height: 94dvh; overflow-y: auto; }

/* The overhead form is the tall one, so it is laid out properly rather than
   just allowed to scroll: the heading stays put, the fields scroll between
   it and the buttons, and the buttons stick to the bottom where a thumb
   expects them. overflow:hidden on the card keeps the close button pinned. */
#pnl-expense-dialog .phone-dialog-card { display: flex; flex-direction: column; overflow: hidden; }
#pnl-expense-dialog #pnl-expense-form { flex: 1 1 auto; min-height: 0; overflow-y: auto; }
#pnl-expense-dialog .phone-dialog-actions {
  position: sticky;
  bottom: 0;
  margin-top: 4px;
  padding: 12px 0 2px;
  background: var(--surface);
  /* Nothing should appear to slide under the buttons from below. */
  box-shadow: 0 -8px 12px -8px rgba(13, 42, 33, .18);
}

/* Project P&L. One block per Won client, and a gantt of every job's span.

   The four states a project can be in are a colour each, and "costs not
   recorded" is deliberately one of them: 22 of the 28 jobs on record have no
   site cost typed in, and a reader must be able to tell a job that made 67%
   from a job nobody has costed yet. Grey, not green. */
.project-blocks-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 12px; }
.project-controls { display: flex; flex-wrap: wrap; gap: 8px; }
.project-search input, .project-sort select {
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: .8rem;
}
.project-search input { min-width: 170px; }
.project-search input:focus-visible, .project-sort select:focus-visible { border-color: var(--primary-border); outline: none; }

.project-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(258px, 1fr)); gap: 14px; margin-top: 16px; }
.project-block {
  padding: 16px 18px;
  border: 1px solid var(--line);
  border-left: 3px solid var(--line-strong);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  cursor: pointer;
  transition: border-color .15s ease, box-shadow .15s ease, transform .15s ease;
}
.project-block:hover, .project-block:focus-visible { box-shadow: var(--shadow); outline: none; transform: translateY(-1px); }
.project-block.is-healthy { border-left-color: var(--primary); }
.project-block.is-thin { border-left-color: var(--finance-s3); }
.project-block.is-loss { border-left-color: var(--danger); }
.project-block.is-unknown { border-left-color: var(--line-strong); }

.project-block-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.project-block-who { min-width: 0; }
.project-block-who strong { display: block; color: var(--navy); font-size: .94rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-block-who small { display: block; color: var(--muted); font-size: .74rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.project-health { flex: none; padding: 2px 8px; border-radius: 999px; font-size: .64rem; font-weight: 600; white-space: nowrap; }
.project-health.is-healthy { background: var(--primary-light); color: var(--primary-dark); }
.project-health.is-thin { background: var(--warning-bg); color: var(--warning); }
.project-health.is-loss { background: var(--danger-bg); color: var(--danger); }
.project-health.is-unknown { background: var(--surface-muted, rgba(125, 138, 132, .14)); color: var(--muted); }

/* Two rows filled column first, so each label sits above its own value
   whatever the count -- the same shape the employee cards use. */
.project-block-figures {
  display: grid;
  grid-template-rows: auto auto;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 2px 12px;
  margin: 14px 0 0;
}
.project-block-figures dt { min-width: 0; color: var(--muted); font-size: .68rem; font-weight: 600; white-space: nowrap; }
.project-block-figures dd { min-width: 0; margin: 0; color: var(--navy); font-size: .85rem; font-weight: 650; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.project-block-figures dd.is-loss { color: var(--danger); }

/* What was spent against what was kept, as one bar. Only drawn when the costs
   are actually known: a full green bar on an uncosted job would be the exact
   lie this screen exists to avoid. */
.project-bar { display: flex; height: 6px; margin: 12px 0 0; border-radius: 999px; overflow: hidden; background: var(--line); }
.project-bar-spent { background: var(--finance-s5); }
.project-bar-kept { background: var(--primary); }
.project-bar-kept.is-loss { background: var(--danger); }

.project-block-note { margin: 8px 0 0; color: var(--muted); font-size: .72rem; }
.project-block-note.is-muted { font-style: italic; }
.project-block-foot { display: flex; justify-content: space-between; gap: 10px; margin-top: 10px; color: var(--muted); font-size: .7rem; }

/* The gantt. A lane per project, a bar from its first payment to its last
   movement of money. */
.project-gantt { display: block; width: 100%; }
.project-gantt-lane { fill: var(--line); opacity: .28; }
.project-gantt-row { cursor: pointer; }
.project-gantt-row:hover .project-gantt-lane, .project-gantt-row:focus-visible .project-gantt-lane { opacity: .5; }
.project-gantt-row:focus-visible { outline: none; }
.project-gantt-bar { fill: var(--primary); }
.project-gantt-bar.is-healthy { fill: var(--primary); }
.project-gantt-bar.is-thin { fill: var(--finance-s3); }
.project-gantt-bar.is-loss { fill: var(--danger); }
.project-gantt-bar.is-unknown { fill: var(--line-strong); }
.project-gantt-bar.is-stage { fill: var(--finance-s2); }
.project-gantt-name { fill: var(--text); font-size: 11px; }
.project-gantt-value { fill: var(--muted); font-size: 10.5px; font-variant-numeric: tabular-nums; }
.project-gantt-value.is-pending { font-style: italic; opacity: .75; }

.finance-dot.is-healthy { background: var(--primary); }
.finance-dot.is-thin { background: var(--finance-s3); }
/* The pie's slices carry is-loss as a fill, which leaves a legend dot with no
   background at all -- the swatch was invisible and the key read as three
   colours and one gap. */
.finance-dot.is-loss { background: var(--danger); }
.finance-dot.is-unknown { background: var(--line-strong); }
.finance-dot.is-in { background: var(--primary); }
.finance-dot.is-out { background: var(--finance-s5); }
.finance-legend.is-inline { display: flex; flex-wrap: wrap; gap: 8px 18px; }
.finance-legend.is-inline li { display: flex; align-items: center; gap: 7px; }

/* Money in above the line, money out below it. */
.project-event.is-in { fill: var(--primary); }
.project-event.is-out { fill: var(--finance-s5); }
.project-month.is-in { fill: var(--primary); }
.project-month.is-out { fill: var(--finance-s5); }

.project-detail-head { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 16px; }
/* "All projects" is two words and must stay on one line: wrapped, the button
   grows taller than the heading beside it and the row stops reading as a row. */
.project-detail-head .button { flex: none; white-space: nowrap; }
.project-detail-title { min-width: 0; }
.project-detail-title h3 { margin: 0; color: var(--navy); font-size: 1.1rem; }
.project-detail-title p { margin: 2px 0 0; color: var(--muted); font-size: .78rem; }

/* A label that belongs to a control a sighted reader can already see. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

@media (max-width: 640px) {
  .project-grid { grid-template-columns: 1fr; }
  .project-blocks-head { flex-direction: column; align-items: stretch; }
  .project-search input { width: 100%; }
}

/* Employees. The cards reuse the console's surface and the detail view reuses
   the finance furniture wholesale -- it is the same kind of page, and a second
   set of nearly-identical rules would drift from the first. */
.employee-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 14px; margin-top: 16px; }
.employee-card { padding: 18px 20px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); box-shadow: var(--shadow-sm); cursor: pointer; transition: border-color .15s ease, box-shadow .15s ease; }
.employee-card:hover, .employee-card:focus-visible { border-color: var(--primary-border); box-shadow: var(--shadow); outline: none; }
.employee-card-head { display: flex; align-items: center; gap: 12px; }
.employee-avatar { display: grid; width: 40px; height: 40px; flex: none; place-items: center; border-radius: 50%; background: var(--primary-light); color: var(--primary-dark); font-size: 1.05rem; font-weight: 700; }
.employee-card-who { min-width: 0; }
.employee-card-who strong { display: block; color: var(--navy); font-size: .95rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.employee-card-who small { display: block; color: var(--muted); font-size: .76rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.employee-flag { margin-left: auto; padding: 2px 8px; border-radius: 999px; background: var(--warning-bg); color: var(--warning); font-size: .66rem; font-weight: 600; white-space: nowrap; }
/* A <dl> of label/value pairs. The flow is explicitly two rows filled COLUMN
   first, so each dt sits directly above its own dd whether the card carries
   two stats or three. An auto-fit track list cannot do this: with a zero
   minimum it fits one column per element, which puts every dt and dd on the
   same row on top of each other, and with a fixed count it breaks whenever
   the number of stats changes. */
.employee-card-stats {
  display: grid;
  grid-template-rows: auto auto;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 2px 14px;
  margin: 16px 0 0;
}
.employee-card-stats dt { min-width: 0; color: var(--muted); font-size: .7rem; font-weight: 600; white-space: nowrap; }
.employee-card-stats dd { min-width: 0; margin: 0; color: var(--navy); font-size: .88rem; font-weight: 650; font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.employee-card-note { margin: 12px 0 0; color: var(--muted); font-size: .72rem; }

/* [hidden] is outranked by an author display, and these panels render with it. */
.finance-panel[data-employee-panel][hidden] { display: none; }

/* The HR month. A colour per status, and a blank cell that reads as blank --
   a day nobody marked is not an absence, so it gets no colour at all. */
.hr-month-field { display: inline-flex; align-items: center; gap: 8px; color: var(--muted); font-size: .78rem; font-weight: 600; }
.hr-month-field input { padding: 6px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); color: var(--text); font: inherit; font-size: .82rem; }

.attendance-wrap { overflow-x: auto; }
.attendance-grid { border-collapse: separate; border-spacing: 2px; font-size: .78rem; }
.attendance-grid th { padding: 4px 6px; color: var(--muted); font-size: .66rem; font-weight: 600; text-transform: none; letter-spacing: 0; border: 0; white-space: nowrap; }
.attendance-name-col { position: sticky; left: 0; z-index: 1; min-width: 132px; padding-right: 12px !important; background: var(--surface); color: var(--navy) !important; font-size: .8rem !important; text-align: left; }
.attendance-day-col { display: table-cell; width: 26px; text-align: center; }
.attendance-dow { display: block; opacity: .65; }
.attendance-dom { display: block; font-variant-numeric: tabular-nums; }
.attendance-total-col { padding: 4px 8px; color: var(--navy); font-variant-numeric: tabular-nums; text-align: right; }
.attendance-cell { padding: 0; border: 0; }
.attendance-mark { display: grid; width: 24px; height: 24px; place-items: center; border: 1px solid transparent; border-radius: 5px; background: var(--soft); color: var(--muted); font: inherit; font-size: .68rem; font-weight: 700; cursor: pointer; }
.attendance-mark:hover { border-color: var(--primary); }
.attendance-mark.is-blank { background: transparent; border-color: var(--line); }
.attendance-mark.is-present, .attendance-swatch.is-present, .attendance-choice.is-present { background: var(--success-bg); color: var(--success); }
.attendance-mark.is-absent, .attendance-swatch.is-absent, .attendance-choice.is-absent { background: var(--danger-bg); color: var(--danger); }
.attendance-mark.is-half, .attendance-swatch.is-half, .attendance-choice.is-half { background: var(--warning-bg); color: var(--warning); }
.attendance-mark.is-leave, .attendance-swatch.is-leave, .attendance-choice.is-leave { background: var(--info-bg); color: var(--info); }
.attendance-mark.is-holiday, .attendance-swatch.is-holiday, .attendance-choice.is-holiday { background: var(--primary-light); color: var(--primary-dark); }
.attendance-mark.is-weekoff, .attendance-swatch.is-weekoff, .attendance-choice.is-weekoff { background: var(--soft); color: var(--muted); }

.attendance-legend { display: flex; flex-wrap: wrap; gap: 14px; margin: 14px 0 0; padding: 0; list-style: none; color: var(--muted); font-size: .74rem; }
.attendance-legend li { display: flex; align-items: center; gap: 6px; }
.attendance-swatch { display: grid; width: 20px; height: 20px; place-items: center; border: 1px solid transparent; border-radius: 5px; font-size: .64rem; font-weight: 700; }
.attendance-swatch.is-blank { border-color: var(--line); }

.attendance-choices { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin: 16px 0; }
.attendance-choice { padding: 10px; border: 1px solid transparent; border-radius: var(--radius-sm); font: inherit; font-size: .82rem; font-weight: 600; cursor: pointer; }
.attendance-choice:hover { border-color: var(--primary); }
.attendance-choice.is-chosen { border-color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }

/* Two fields to a row, so a form of six is three rows rather than six and the
   buttons are in reach without scrolling. Falls back to one column on a phone,
   where two number inputs side by side are too narrow to type in. */
.field-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 480px) { .field-pair { grid-template-columns: 1fr; } }
/* A paired dialog needs the width to use the second column. */
#pay-dialog, #pnl-expense-dialog, #employee-add-dialog, #employee-edit-dialog { width: min(94vw, 580px); }

/* Correcting or removing an expense, offered on the card where the mistake is
   visible rather than behind a menu. */
.expense-card-actions { display: flex; gap: 8px; margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--line); }
.expense-card-action { padding: 4px 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: none; color: var(--muted); font: inherit; font-size: .76rem; font-weight: 600; cursor: pointer; }
.expense-card-action:hover { border-color: var(--primary); color: var(--primary); }
.expense-card-action.is-danger:hover { border-color: var(--danger-border); background: var(--danger-bg); color: var(--danger); }
/* The file input is empty while editing, which looks like the bill was lost. */
.expense-receipt-note { margin: 2px 0 8px; color: var(--muted); font-size: .76rem; }

/* Touch targets.
   A text link is only as tall as its text -- 18px for a contact link, 20px for
   a .text-link-button -- under the 24x24 CSS pixels WCAG 2.2 asks for (2.5.8
   Target Size (Minimum)) and far under the 44px Apple and Google recommend.
   Tapping a phone number is one of the things this CRM is for on a phone, so
   these are the targets that matter most.

   The area is grown with a pseudo-element rather than padding, so nothing on
   the page moves, and only vertically: widening a link would have neighbours
   stealing each other's taps.

   Only the links that sit on their own line are grown. The pair in the lead
   header are inline in a wrapping sentence -- "email . phone . Source" -- and
   measuring them showed the phone number already wraps onto a second line
   underneath the email address, so a taller hit area there would put "call"
   under "compose". Those two are reachable with a proper target in the info
   card below, which is where this applies.

   pointer: coarse rather than a width breakpoint, because what decides this is
   the finger, not the screen -- a touch laptop at 1200px needs it too.

   This block is last in the file on purpose: it is all single-class selectors
   that have to beat the base rules above. */
@media (pointer: coarse) {
  .lead-info-row .contact-link, .text-link-button { position: relative; }
  .lead-info-row .contact-link::after, .text-link-button::after {
    content: ''; position: absolute; left: 0; width: 100%;
    top: 50%; transform: translateY(-50%); height: 44px;
  }
  /* Real buttons carrying their own box: these clear WCAG at 34px but are
     still smaller than a fingertip, and raising them moves nothing but their
     own height. */
  .theme-toggle, .admin-menu-toggle { min-width: 44px; min-height: 44px; }
  .visit-type-option { min-height: 44px; }
}
