/* ============================================================
   AQUIFER CRM — refined-financial design system (light + dark)
   Bespoke. Navy + teal. Tabular numerals. Quiet depth.
   ============================================================ */
:root {
  --navy-900:#0B1F3A; --navy-800:#102A4C; --navy-700:#163358; --navy-600:#1B3A6B;
  --teal-600:#0891b2; --teal-500:#06b6d4; --teal-400:#22d3ee;  /* cyan ramp to match the neon-cyan logo (2026-07-01) */
  --green:#16A34A; --green-soft:#DCFCE7;
  --amber:#D97706; --amber-soft:#FEF3C7;
  --red:#DC2626;   --red-soft:#FEE2E2;
  --blue:#2563EB;  --blue-soft:#DBEAFE;
  --violet:#7C3AED;--violet-soft:#EDE9FE;

  --r-sm:7px; --r:10px; --r-lg:14px; --r-xl:20px; --r-full:999px;
  --font:'Inter',system-ui,-apple-system,sans-serif;
  --num:'Inter',system-ui; /* tabular via font-feature-settings */
  --ease:cubic-bezier(.16,1,.3,1);
  --maxw:1320px;
}

/* ---- Light (default) ---- */
[data-theme="light"]{
  --bg:#F3F6FB; --bg-grad:radial-gradient(1200px 600px at 80% -10%, #E9F2F1 0%, transparent 60%);
  --surface:#FFFFFF; --surface-2:#F8FAFC; --surface-3:#F1F5F9;
  --line:#E6EBF2; --line-2:#EDF1F7;
  /* MAP INK. The state border used to be --line on --surface-3 land: #E6EBF2 on #F1F5F9, about
     1.05:1, which is a line nobody can see. States read as absent and the map looked like it was
     missing half the country. These are separate tokens because a map border needs more contrast
     than a card divider and should not drag every rule on the page with it. */
  --lm-land:#F1F5F9; --lm-border:#8FA5C0; --lm-border-2:#BECCDC;
  /* Roads read as a warm layer against the cool land, the way every road map has done it
     since paper, so a highway is never mistaken for a boundary. */
  --lm-road-i:#D9A441; --lm-road-u:#D9B877; --lm-road-s:#CFCBBE; --lm-road-ink:#8A6A1F;
  --ink:#0E1B2E; --ink-2:#3D4D63; --muted:#6B7B92; --faint:#9AA8BC;
  --brand:#0B1F3A; --accent:#0891b2; --accent-ink:#0e7490; --accent-rgb:34,211,238;
  --shadow-sm:0 1px 2px rgba(13,30,55,.05), 0 1px 3px rgba(13,30,55,.04);
  --shadow:0 4px 14px rgba(13,30,55,.07), 0 2px 6px rgba(13,30,55,.04);
  --shadow-lg:0 18px 50px rgba(13,30,55,.12);
  --side-bg:#0B1F3A; --side-ink:#CAD6E6; --side-ink-2:#8298B7; --side-line:rgba(255,255,255,.08); --side-active:rgba(255,255,255,.06);
  --chart-grid:#EDF1F7;
}
/* ---- Dark ---- */
[data-theme="dark"]{
  --bg:#070D17; --bg-grad:radial-gradient(1200px 600px at 80% -10%, rgba(var(--accent-rgb),.07) 0%, transparent 60%);
  --surface:#0E1828; --surface-2:#0B1422; --surface-3:#142235;
  --line:#1C2A40; --line-2:#172339;
  --lm-land:#142235; --lm-border:#4E6B92; --lm-border-2:#2E4668;
  --lm-road-i:#8A6A28; --lm-road-u:#6B5628; --lm-road-s:#3E4354; --lm-road-ink:#C9A961;
  --ink:#E7EDF6; --ink-2:#AEBCD0; --muted:#7C8DA6; --faint:#56657E;
  --brand:#E7EDF6; --accent:#22d3ee; --accent-ink:#67e8f9; --accent-rgb:34,211,238;
  --shadow-sm:0 1px 2px rgba(0,0,0,.4); --shadow:0 6px 20px rgba(0,0,0,.45); --shadow-lg:0 24px 60px rgba(0,0,0,.6);
  --side-bg:#0A101D; --side-ink:#AEBCD0; --side-ink-2:#62748F; --side-line:rgba(255,255,255,.06); --side-active:rgba(255,255,255,.05);
  --chart-grid:#172339;
}

/* ============================================================
   WHITE-LABEL BRANDS — one codebase, branded by hostname/?brand
   Aquifer = navy + teal (default, above). AAG's own brands are
   themed here; a third-party tenant's palette is part of its
   identity and lives in brands/<key>.css, staged into
   brand-theme.css for that tenant's site alone. Do not add a
   tenant block to this file: this sheet ships to every host.
   Overriding --teal-* recolors the hardcoded chart/indicator teal.
   ============================================================ */
/* 0030 (dashboard.0030.io) = the 0030.io identity (rethemed 2026-09-30 to match 0030.io and the
   0030 console): light-first, ink #0A2540, indigo #635BFF, the 0030.io wordmark in Plus Jakarta Sans
   800 with the .io in indigo 600, Inter for everything else. The sidebar is 0030.io's deep ink.
   Locked 2026-09-30; do not revert to the dark-and-gold or the cyan/navy skin. See status/AAG_STATUS.md. */
[data-brand="zerothirty"][data-theme="light"]{
  --bg:#F6F9FC; --bg-grad:radial-gradient(1200px 600px at 80% -10%, rgba(99,91,255,.07) 0%, transparent 60%);
  --line:#E3E8EE; --line-2:#EDF1F6;
  --ink:#0A2540; --ink-2:#425466; --muted:#617388; --faint:#9AA8BC;
  --brand:#0A2540; --accent:#635BFF; --accent-ink:#4B44D6; --accent-rgb:99,91,255;
  --teal-600:#0C9A8C; --teal-500:#0FB5A4; --teal-400:#3FCFC0;
  --side-bg:#0A2540; --side-ink:#C9D3E3; --side-ink-2:#8A9BB8; --side-line:rgba(255,255,255,.08); --side-active:rgba(99,91,255,.22);
  --chart-grid:#EDF1F6;
}
[data-brand="zerothirty"][data-theme="dark"]{
  --bg:#061829; --bg-grad:radial-gradient(1200px 600px at 80% -10%, rgba(99,91,255,.10) 0%, transparent 60%);
  --surface:#0B2036; --surface-2:#09192B; --surface-3:#10294A;
  --line:#1C3352; --line-2:#152A45;
  --lm-land:#10294A; --lm-border:#4F6A90; --lm-border-2:#2B4466;
  --ink:#F6F9FC; --ink-2:#C2CEDD; --muted:#8A9BB8; --faint:#5A6E8C;
  --brand:#F6F9FC; --accent:#8C85FF; --accent-ink:#B4AFFF; --accent-rgb:140,133,255;
  --teal-600:#0FB5A4; --teal-500:#3FCFC0; --teal-400:#00D4FF;
  --side-bg:#061829; --side-ink:#C2CEDD; --side-ink-2:#6F84A3; --side-line:rgba(255,255,255,.06); --side-active:rgba(140,133,255,.18);
  --chart-grid:#152A45;
}
/* The 0030.io wordmark, as text: 0030<em>.io</em>, exactly the live site's .mark rule. Set as text
   rather than an image because an image cannot load the face. On the sidebar's deep ink the numerals
   are white and the suffix a lighter indigo; on a white card they are the site's own ink and indigo. */
.brand__wm{font-family:'Plus Jakarta Sans',ui-sans-serif,system-ui,-apple-system,sans-serif;font-weight:800;font-size:22px;letter-spacing:-.03em;line-height:1;color:#fff;white-space:nowrap;overflow:hidden}
.brand__wm em{font-style:normal;font-weight:600;letter-spacing:-.02em;color:#A5A0FF}
.aq-auth__brand .brand__wm{font-size:30px;color:#0A2540}
.aq-auth__brand .brand__wm em{color:#635BFF}
[data-theme="dark"] .aq-auth__brand .brand__wm{color:#F6F9FC}
[data-theme="dark"] .aq-auth__brand .brand__wm em{color:#A5A0FF}
/* wordmark logo (white-label brands with an image mark) */
.brand__logo{height:24px;width:auto;max-width:158px;display:block}
/* A LOGO THAT CANNOT BE READ ON THE SURFACE BEHIND IT SITS ON A PLATE (brand.js measures it and sets
   data-plate). The padding is always there and cancelled by the negative margin, so a logo does not move
   when a plate switches on; only the background changes. White behind a dark logo, near-black behind a
   light one. */
.brand__plate{display:inline-flex;align-items:center;flex:0 0 auto;padding:4px 8px;margin:-4px -8px;border-radius:8px;transition:background-color .15s var(--ease)}
.brand__plate[data-plate="light"]{background:#fff}
.brand__plate[data-plate="dark"]{background:#0F172A}
/* A lead's source that nobody has confirmed: a small dashed tag, quiet enough to sit on every row of a big book. */
.srcflag{display:inline-block;font-size:10px;font-weight:600;line-height:1;padding:2px 6px;margin-left:4px;border-radius:var(--r-full);border:1px dashed var(--line);color:var(--faint);vertical-align:1px;white-space:nowrap}
/* Settings, Lead sources: one name per row. */
.ls-row{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 0;border-top:1px solid var(--line)}
.ls-row b{font-weight:600;overflow-wrap:anywhere}
/* Settings, Branding: the live preview. A mock sidebar and a mock light page, side by side, each with the logo as it will really be shown. */
.br-prev{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.br-prev__pane{border:1px solid var(--line);border-radius:var(--r);padding:16px 14px;min-height:78px;display:flex;flex-direction:column;gap:10px;justify-content:center;overflow:hidden}
.br-prev__pane .brand__logo{height:24px;width:auto;max-width:150px}
.br-prev__cap{font-size:10.5px;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:var(--faint);margin-bottom:6px}
@media (max-width:520px){ .br-prev{grid-template-columns:1fr} }

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
/* Default size for hydrated <i> icons used outside a sized context. Every
   context rule (.nav__link i, .btn i, .kpi__ic i, swatches, …) is more specific
   and overrides this, so it only catches bare inline icons (e.g. Tools views). */
i{width:16px;height:16px;flex:0 0 16px}
html{-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
body{font-family:var(--font);background:var(--bg);background-image:var(--bg-grad);background-attachment:fixed;color:var(--ink);font-size:14px;line-height:1.5;min-height:100vh}
.num,td.n,.stat__val,.kpi__val{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1,"cv01" 1}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;background:none;border:none;color:inherit}
::selection{background:rgba(var(--accent-rgb),.22)}
h1,h2,h3,h4{letter-spacing:-.01em;line-height:1.2}

/* ============ APP SHELL ============ */
/* clip horizontal overflow at the document root so nothing can produce a page-level
   side-scroll on mobile; overflow-x:clip (not hidden) does NOT break the sticky topbar.
   Inner scrollers (.tbl-wrap, .kanban) keep their own overflow-x:auto. */
html{overflow-x:clip}
/* HIDDEN UNTIL SOMEBODY IS SIGNED IN. boot.js decides which of the public screens to show and
   calls hideApp(), but that only runs once boot.js has loaded and parsed. Until then the shell
   was painted: a merchant opening a signing link on a slow connection saw the operator's full
   navigation — every screen of an ISO's CRM — flash past before the page they were sent to.
   Shown again by showApp(), which is the same moment the app was ever meant to appear. */
.app{display:none;grid-template-columns:248px 1fr;min-height:100vh;max-width:100%;overflow-x:clip}
/* Onboarding review gate — full-screen wizard, no CRM chrome, until we approve/unlock. */
body.aq-gate .app{grid-template-columns:1fr}
body.aq-gate .sidebar,body.aq-gate .topbar{display:none}
body.aq-gate .view{max-width:920px;margin:0 auto;padding:28px 20px 96px}
/* During onboarding, the wizard's own "Chat with us" button is the single support entry —
   hide the operator chat-widget FAB so the two don't overlap. */
body.aq-gate .aqcw-fab,body.aq-gate .aqcw{display:none!important}
/* Onboarding on phones: the two-column grid collapses to one, which stacks the 240px
   step-rail (all 12 steps) ABOVE the wizard and eats the whole first screen. Collapse the
   rail to just its progress bar — the wizard card header already names the current step and
   the footer shows "Step N of 12". (Overrides the inline position:sticky on #obRail.) */
@media (max-width:720px){
  #obRail{position:static!important;top:auto!important;padding:12px 14px}
  #obRail .bar{margin-bottom:0!important}
  #obRail [data-go-step]{display:none}
}
.main{display:flex;flex-direction:column;min-width:0}

/* ---- Sidebar ---- */
.sidebar{background:var(--side-bg);color:var(--side-ink);display:flex;flex-direction:column;position:sticky;top:0;height:100vh;border-right:1px solid var(--side-line)}
.brand{display:flex;align-items:center;gap:11px;padding:20px 20px 16px}
.brand__mark{width:30px;height:30px;display:block;filter:drop-shadow(0 2px 6px rgba(0,0,0,.3))}
.brand__name{font-weight:800;font-size:18px;letter-spacing:-.02em;color:#fff}
.nav{flex:1;overflow-y:auto;padding:6px 12px}
.nav__section{font-size:10px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--side-ink-2);padding:16px 12px 7px}
.nav__link{display:flex;align-items:center;gap:11px;padding:9px 12px;border-radius:var(--r-sm);color:var(--side-ink);font-weight:500;font-size:13.5px;transition:all .15s var(--ease);cursor:pointer;position:relative}
.nav__link i{width:18px;height:18px;flex:0 0 18px;opacity:.85}
.nav__link em{margin-left:auto;font-style:normal;font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--side-ink-2);border:1px solid var(--side-line);padding:1px 6px;border-radius:var(--r-full)}
.nav__link:hover{background:var(--side-active);color:#fff}
.nav__link.is-active{background:var(--side-active);color:#fff}
.nav__link.is-active::before{content:'';position:absolute;left:-12px;top:8px;bottom:8px;width:3px;border-radius:0 3px 3px 0;background:var(--teal-500)}
.nav__link.is-active i{opacity:1;color:var(--teal-400)}
.nav__link.is-soon{opacity:.5;cursor:default}
.nav__link.is-soon:hover{background:none;color:var(--side-ink)}
/* inline-accordion nav */
.nav__solo{margin-bottom:2px}
.nav__group{margin-top:1px}
.nav__parent{display:flex;align-items:center;gap:11px;width:100%;padding:9px 12px;border:0;background:none;border-radius:var(--r-sm);color:var(--side-ink);font-weight:600;font-size:13.5px;cursor:pointer;transition:all .15s var(--ease);font-family:inherit;text-align:left}
.nav__parent>i:first-child{width:18px;height:18px;flex:0 0 18px;opacity:.85}
.nav__parent:hover{background:var(--side-active);color:#fff}
.nav__chev{width:15px;height:15px;margin-left:auto;opacity:.55;transition:transform .2s var(--ease)}
.nav__group.is-open>.nav__parent .nav__chev{transform:rotate(90deg)}
/* The active GROUP needs to read as active too, not just its child. This was a colour
   change only, so on a long nav the section you are in was easy to lose: the child link had a
   full background and its parent had almost nothing. Now the parent carries a muted version of
   the same treatment, so the trail from section to page is visible at a glance. */
.nav__group.is-active>.nav__parent{color:#fff;background:color-mix(in srgb, var(--side-active) 55%, transparent)}
.nav__group.is-active>.nav__parent .nav__chev{opacity:1}
.nav__group.is-active>.nav__parent>i:first-child{opacity:1;color:var(--teal-400)}
.nav__children{overflow:hidden;max-height:0;transition:max-height .22s var(--ease);margin-left:21px;border-left:1px solid var(--side-line);padding-left:4px}
.nav__group.is-open>.nav__children{max-height:560px}
.nav__children .nav__link{padding:8px 12px;font-size:13px}
.nav__children .nav__link.is-active::before{left:-5px}
.sidebar__foot{padding:12px}
.orgcard{background:var(--side-active);border:1px solid var(--side-line);border-radius:var(--r);padding:11px 13px}
.orgcard__title{font-weight:700;font-size:13px;color:#fff}
.orgcard__sub{font-size:11px;color:var(--side-ink-2);margin-top:1px}

/* ---- Topbar ---- */
.topbar{height:62px;display:flex;align-items:center;gap:14px;padding:0 26px;background:color-mix(in srgb, var(--surface) 78%, transparent);backdrop-filter:saturate(180%) blur(12px);border-bottom:1px solid var(--line);position:sticky;top:0;z-index:30}
/* THE MENU BUTTON IS ALWAYS SHOWN, BECAUSE IT ALWAYS DOES SOMETHING NOW. It used to be hidden
   above 1000px and only opened an off-canvas drawer below it, so on a desktop it was either absent
   or, when something showed it, a control that darkened the screen and moved nothing. Reported
   twice. On a wide screen it now collapses the sidebar, which is what a person pressing it expects,
   and on a narrow one it still opens the drawer. */
.topbar__menu{display:grid}
/* Collapsed rail: the grid column goes to zero and the sidebar stops taking part in layout, so the
   content reflows into the space rather than being covered by it. Desktop only; below 1000px the
   sidebar is already an overlay and this would fight the drawer. */
@media (min-width:1001px){
  /* THE SIDEBAR STAYS IN THE GRID, IT JUST GOES TO ZERO WIDTH. `display:none` removes it as a grid
     ITEM, so the main column becomes the first item and lands in the 0fr track: the whole app
     rendered as a narrow strip down the left with the rest of the screen empty. Keeping it as an
     item and clipping its contents is what actually collapses a two-column grid. */
  .app.is-collapsed{grid-template-columns:0 1fr}
  .app.is-collapsed .sidebar{overflow:hidden;border-right:0}
}
.search{flex:1;max-width:440px;display:flex;align-items:center;gap:9px;background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-sm);padding:0 11px;height:38px;color:var(--muted);transition:border-color .15s,box-shadow .15s}
.search:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px rgba(var(--accent-rgb),.12)}
.search i{width:16px;height:16px}
.search input{flex:1;background:none;border:none;outline:none;color:var(--ink);font-size:13.5px;text-overflow:ellipsis}
.search input::placeholder{color:var(--faint)}
.search kbd{font-family:var(--font);font-size:11px;font-weight:600;color:var(--faint);border:1px solid var(--line);border-radius:5px;padding:1px 6px;background:var(--surface)}
.topbar__right{margin-left:auto;display:flex;align-items:center;gap:8px}
/* Comms shortcuts. FAILS CLOSED: hidden until app.js confirms an operator, because the
   merchant portal reuses this same header and must never be offered CRM routes. */
/* Matches the merchant preview card in portal.js on purpose: same card, same pill, same
   sentence, so the two previews read as one feature with two subjects rather than as two
   different mechanisms that happen to look alike. */
.viewas-bar{margin-bottom:16px;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.topbar__comms{display:none;align-items:center;gap:8px}
.topbar__comms.is-on{display:flex}
/* The shortcuts stand down only when the header genuinely runs out of room.
   This was tied to the 1000px drawer breakpoint, which is far too early: a laptop window
   that is merely not maximised sits under 1000px, so the feature vanished on the machine it
   was built for and looked like it had never shipped. Three 34px buttons fit long before
   700px; below that the search needs the space and the same channels are one tap away in
   the drawer. */
@media (max-width:700px){ .topbar__comms.is-on{display:none} }
.iconbtn.is-locked{opacity:.5}
.iconbtn{width:38px;height:38px;border-radius:var(--r-sm);display:grid;place-items:center;color:var(--ink-2);border:1px solid transparent;position:relative;transition:all .15s}
.iconbtn:hover{background:var(--surface-3);color:var(--ink)}
.iconbtn i{width:18px;height:18px}
.iconbtn .dot{position:absolute;top:9px;right:10px;width:7px;height:7px;border-radius:50%;background:var(--red);border:2px solid var(--surface)}
.avatar{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;font-weight:700;font-size:12px;color:#fff;background:linear-gradient(135deg,var(--navy-600),var(--teal-600));margin-left:4px;flex:0 0 auto;aspect-ratio:1}
/* Current-workspace badge: the data's tenant, stated next to the brand skin. */
.wsbadge{display:flex;align-items:center;gap:6px;height:30px;padding:0 10px;border-radius:999px;border:1px solid var(--line);background:var(--surface-2);color:var(--ink-2);font-size:12px;font-weight:600;max-width:190px;transition:all .15s}
.wsbadge:hover{background:var(--surface-3);color:var(--ink)}
.wsbadge i{width:13px;height:13px;flex:0 0 auto}
.wsbadge__name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
@media (max-width:720px){.wsbadge{max-width:120px}}

/* ---- View canvas ---- */
/* full-width content: fill the page like the topbar (no centered max-width cap,
   which left a blank gutter on wide monitors) */
.view{flex:1;padding:26px;width:100%}
.page-head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:22px;flex-wrap:wrap}
.page-head h1{font-size:25px;font-weight:800;letter-spacing:-.025em}
.page-head .sub{color:var(--muted);font-size:13.5px;margin-top:3px}
.page-head__actions{display:flex;gap:9px;align-items:center}

/* ============ PRIMITIVES ============ */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-sm)}
.card--pad{padding:20px 22px}
.card__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line)}
.card__title{font-size:14px;font-weight:700}
.card__sub{font-size:12px;color:var(--muted);font-weight:500}
.grid{display:grid;gap:16px}
.g-2{grid-template-columns:repeat(2,1fr)} .g-3{grid-template-columns:repeat(3,1fr)} .g-4{grid-template-columns:repeat(4,1fr)}
.row{display:flex;gap:16px;flex-wrap:wrap}
.spread{display:flex;align-items:center;justify-content:space-between;gap:12px}

.btn{display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 15px;border-radius:var(--r-sm);font-size:13px;font-weight:600;border:1px solid var(--line);background:var(--surface);color:var(--ink);white-space:nowrap;flex:0 0 auto;transition:all .15s var(--ease)}
.btn:hover{background:var(--surface-3);border-color:var(--line)}
.btn i{width:15px;height:15px}
.btn--primary{background:var(--navy-900);border-color:var(--navy-900);color:#fff}
[data-theme="dark"] .btn--primary{background:var(--teal-600);border-color:var(--teal-600);color:#04201d}
/* variant buttons must re-assert their fill on hover — the generic .btn:hover sets a
   near-white bg (--surface-3), which would leave white label text invisible. */
.btn--primary:hover{background:var(--navy-800);border-color:var(--navy-800);color:#fff;filter:none}
[data-theme="dark"] .btn--primary:hover{background:var(--teal-500);border-color:var(--teal-500);color:#04201d}
.btn--accent{background:var(--teal-600);border-color:var(--teal-600);color:#fff}
.btn--accent:hover{background:var(--teal-500);border-color:var(--teal-500);color:#fff;filter:none}
.btn--ghost{border-color:transparent;background:transparent;color:var(--ink-2)}
.btn--ghost:hover{background:var(--surface-3)}
.btn--sm{height:32px;padding:0 11px;font-size:12.5px}

/* Pills / badges */
.pill{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;font-weight:600;padding:3px 9px;border-radius:var(--r-full);line-height:1.4;white-space:nowrap}
.pill .d{width:6px;height:6px;border-radius:50%;background:currentColor}
.pill--green{color:var(--green);background:var(--green-soft)} .pill--amber{color:var(--amber);background:var(--amber-soft)}
.pill--red{color:var(--red);background:var(--red-soft)} .pill--blue{color:var(--blue);background:var(--blue-soft)}
.pill--violet{color:var(--violet);background:var(--violet-soft)} .pill--gray{color:var(--muted);background:var(--surface-3)}
/* WHO THE REP CALLS AS (views/leads.js, views/phone.js; 2026-09-28). Neutral on purpose: never a
   stage color and never the accent, which already mean something on every screen. The default
   company is muted because most leads carry it; any other stands out, because that is the lead where
   saying the wrong name costs something. The dot is the company's own color, when one is set. */
.pill--callas{background:transparent;border:1px solid var(--faint);color:var(--ink-2);font-weight:700;font-size:11px;padding:1px 8px;vertical-align:middle}
.pill--callas.is-default{border-color:var(--line);color:var(--muted);font-weight:600}
.pill--callas__dot{width:7px;height:7px;border-radius:50%;flex:none}
/* A company's own color is often dark; on the dark theme a hairline keeps the dot from vanishing. */
[data-theme="dark"] .pill--callas__dot{box-shadow:0 0 0 1px var(--faint)}
.callas-head{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:6px}
.callas-head .pill--callas{font-size:11.5px;padding:2px 9px}
/* .mfield sets width:100%, so the picker states both classes to sit beside the search box. */
.mfield.callas-filter{height:36px;width:auto;max-width:100%;padding:0 30px 0 10px;font-size:13px;flex:0 1 auto}
.card__head>.callas-filter{margin-right:auto}
/* The dialer's card: which company this call is, above everything a rep reads before dialing. */
.callas-line{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:10px;font-size:13px;color:var(--ink)}
.callas-line b{font-weight:800}
.callas-note{margin-top:10px;padding:8px 11px;border:1px solid var(--line);border-left:3px solid var(--ink-2);border-radius:var(--r-sm);background:var(--surface);font-size:12.5px;line-height:1.5;color:var(--ink)}
.callas-note b{font-weight:800}
/* Settings, Calling as: one row per company, stacked on a phone rather than panned. */
.ci-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr) 300px;gap:10px 18px;align-items:start;padding:14px 0;border-top:1px solid var(--line)}
.ci-row.is-archived .ci-main,.ci-row.is-archived .ci-facts{opacity:.6}
.ci-facts{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px 14px;font-size:12.5px}
.ci-facts>div>span{display:block;color:var(--muted);font-size:11px;font-weight:600;margin-bottom:2px}
.ci-facts>div>b{display:block;font-weight:600;color:var(--ink-2);overflow-wrap:anywhere}
.ci-actions{display:flex;flex-wrap:wrap;gap:6px;justify-content:flex-end;max-width:300px}
@media (max-width:900px){ .ci-row{grid-template-columns:minmax(0,1fr)} .ci-facts{grid-template-columns:repeat(2,minmax(0,1fr))} .ci-actions{justify-content:flex-start;max-width:none} }
@media (max-width:480px){ .ci-facts{grid-template-columns:minmax(0,1fr)} }
[data-theme="dark"] .pill--green{background:rgba(22,163,74,.16)} [data-theme="dark"] .pill--amber{background:rgba(217,119,6,.16)}
[data-theme="dark"] .pill--red{background:rgba(220,38,38,.16)} [data-theme="dark"] .pill--blue{background:rgba(37,99,235,.18)}
[data-theme="dark"] .pill--violet{background:rgba(124,58,237,.2)}
.chip{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;color:var(--ink-2);background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-full);padding:4px 11px;cursor:pointer}
.chip.is-on{color:var(--accent-ink);background:rgba(var(--accent-rgb),.1);border-color:rgba(var(--accent-rgb),.3)}

/* KPI stat */
.kpi{padding:18px 20px 38px;display:flex;flex-direction:column;gap:11px;position:relative;overflow:hidden}
.kpi__top{display:flex;align-items:center;justify-content:space-between}
.kpi__label{font-size:12.5px;font-weight:600;color:var(--muted)}
.kpi__ic{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;color:var(--accent);background:rgba(var(--accent-rgb),.11)}
.kpi__ic i{width:17px;height:17px}
.kpi__val{font-size:27px;font-weight:800;letter-spacing:-.03em}
.kpi__delta{font-size:12px;font-weight:600;display:inline-flex;align-items:center;gap:4px;position:relative;z-index:1}
.kpi__delta.up{color:var(--green)} .kpi__delta.down{color:var(--red)}
.kpi__delta i{width:13px;height:13px}
.kpi__spark{position:absolute;right:0;bottom:0;left:0;height:30px;opacity:.85;pointer-events:none}

/* ============ TABLES ============ */
.tbl-wrap{overflow-x:auto}
table.tbl{width:100%;border-collapse:separate;border-spacing:0;font-size:13px}
.tbl thead th{text-align:left;font-size:11px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);padding:11px 16px;border-bottom:1px solid var(--line);white-space:nowrap;position:sticky;top:0;background:var(--surface)}
.tbl tbody td{padding:13px 16px;border-bottom:1px solid var(--line-2);vertical-align:middle}
.tbl tbody tr{transition:background .12s}
.tbl tbody tr:hover{background:var(--surface-2)}
.tbl tbody tr:last-child td{border-bottom:none}
.tbl td.n,.tbl th.n{text-align:right;font-variant-numeric:tabular-nums}
.tbl .lead{font-weight:600;color:var(--ink)}
.tbl .sub{font-size:11.5px;color:var(--muted)}
.cellrow{display:flex;align-items:center;gap:11px}
.mlogo{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font-weight:700;font-size:12px;color:#fff;flex:0 0 32px}
.linklike{color:var(--accent-ink);font-weight:600;cursor:pointer}
.linklike:hover{text-decoration:underline}

/* progress / bars */
.bar{height:7px;border-radius:var(--r-full);background:var(--surface-3);overflow:hidden;min-width:80px}
.bar > i{display:block;height:100%;border-radius:var(--r-full);background:linear-gradient(90deg,var(--teal-600),var(--teal-400))}
.minibars{display:flex;align-items:flex-end;gap:3px;height:30px}
.minibars > i{width:6px;border-radius:2px;background:var(--surface-3)}
.minibars > i.on{background:var(--teal-500)}

/* misc */
.muted{color:var(--muted)} .faint{color:var(--faint)} .strong{font-weight:700}
.up{color:var(--green)} .down{color:var(--red)}
.divider{height:1px;background:var(--line);margin:0}
.empty{padding:40px;text-align:center;color:var(--muted)}
.section-title{font-size:12px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);margin:6px 0 12px}
.legend{display:flex;gap:16px;flex-wrap:wrap;font-size:12px;color:var(--muted)}
.legend span{display:inline-flex;align-items:center;gap:6px}
.legend i{width:9px;height:9px;border-radius:2px}

/* segmented control */
.seg{display:inline-flex;background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-sm);padding:3px}
.seg button{padding:5px 12px;border-radius:6px;font-size:12.5px;font-weight:600;color:var(--muted)}
.seg button.is-on{background:var(--surface);color:var(--ink);box-shadow:var(--shadow-sm)}

/* attention list */
.att{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--line-2)}
.att:last-child{border-bottom:none}
.att__ic{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:0 0 34px}
.att__ic i{width:16px;height:16px}
.att__body{min-width:0;flex:1}
.att__t{font-weight:600;font-size:13px}
.att__s{font-size:12px;color:var(--muted)}

/* ============ RESPONSIVE ============ */
@media (max-width:1000px){
  .app{grid-template-columns:1fr}
  .sidebar{position:fixed;left:0;top:0;z-index:60;width:248px;transform:translateX(-100%);transition:transform .25s var(--ease)}
  .sidebar.is-open{transform:none;box-shadow:var(--shadow-lg)}
  .topbar__menu{display:grid}
  .g-4{grid-template-columns:repeat(2,1fr)} .g-3{grid-template-columns:1fr} .g-2{grid-template-columns:1fr}
}
@media (max-width:560px){ .g-4{grid-template-columns:1fr} .view{padding:18px} .search kbd{display:none} }

/* ---- phones (<=720px): collapse desktop multi-column layouts so nothing forces
        a horizontal page scroll. Tables already sit in .tbl-wrap (overflow-x:auto)
        and boards in .kanban (overflow-x:auto), so those scroll inside themselves. ---- */
@media (max-width:720px){
  /* Collapse EVERY content grid (class-based .g-2/3/4, bare .grid, and inline
     grid-template-columns) to a single column. Use minmax(0,1fr) NOT 1fr: a plain
     1fr track = minmax(auto,1fr) whose `auto` floor is the child's min-content, so
     a wide child (a chart, an SVG, a .tbl-wrap table) blows the column — and the
     page — past the viewport (the real iOS side-swipe cause). minmax(0,1fr) lets
     the column shrink below that, and min-width:0 lets the children shrink too, so
     inner scrollers (.tbl-wrap / .kanban) handle their own overflow. */
  .view .grid,
  [style*="grid-template-columns"]{ grid-template-columns:minmax(0,1fr) !important; }
  .view .grid > *{ min-width:0; }
  /* topbar: tighten chrome + let the search shrink instead of pushing the row past
     the viewport. The injected Operator/Merchant-view toggle is a desktop-only
     convenience (it doesn't shrink, so it overflowed the row on phones). */
  .topbar{ padding:0 14px; gap:10px; }
  .portal-toggle{ display:none; }
  .search{ min-width:0; }
  .search input{ min-width:0; }
  /* page-head action clusters wrap onto their own line instead of overflowing */
  .page-head__actions{ flex-wrap:wrap; }
  .page-head h1{ font-size:22px; }
  .tbl-wrap{ -webkit-overflow-scrolling:touch; }
  /* Mobile audit 2026-07-02: tables PAN, they don't CRUSH. Body cells keeping
     natural width (nowrap) lets .tbl-wrap's overflow-x actually engage instead of
     every column word-wrapping into 6-line rubble. */
  .tbl tbody td{ white-space:nowrap; }
  /* ...except a lead's name line, which carries who the rep calls as and the scanned pill. Kept on
     one line, those two pushed each other past the screen edge; here the pills drop under the name
     and the first column stays on screen, while the columns after it still pan. */
  .tbl .lead.lead--tags{ white-space:normal; min-width:150px; max-width:calc(100vw - 150px); }
  .tbl .lead.lead--tags .pill{ white-space:nowrap; margin-top:3px; }
  /* ...and an inbound code's company choices, which with five companies ran a row of checkboxes
     far past the screen: they wrap inside the cell, each box kept with its name. */
  .tbl .code-callsas{ white-space:normal; min-width:170px; max-width:calc(100vw - 120px); }
  .tbl .code-callsas label{ white-space:nowrap; }
  /* ...and scroll shadows so a cut-off table reads as "swipe me", not "broken".
     Cover gradients scroll with the content; shadow layers stay attached. */
  .tbl-wrap{
    background:
      linear-gradient(90deg, var(--surface) 30%, rgba(255,255,255,0)) left/40px 100% no-repeat local,
      linear-gradient(270deg, var(--surface) 30%, rgba(255,255,255,0)) right/40px 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, rgba(11,31,58,.16), transparent) left/14px 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, rgba(11,31,58,.16), transparent) right/14px 100% no-repeat scroll;
  }
}

.scrim{position:fixed;inset:0;background:rgba(7,13,23,.45);z-index:55;opacity:0;pointer-events:none;transition:opacity .2s}
.scrim.is-on{opacity:1;pointer-events:auto}

/* ---- slide-over drawer ---- */
.drawer{position:fixed;right:0;top:0;height:100vh;width:420px;max-width:92vw;background:var(--surface);border-left:1px solid var(--line);box-shadow:var(--shadow-lg);z-index:60;transform:translateX(100%);transition:transform .26s var(--ease);display:flex;flex-direction:column}
.drawer.is-open{transform:none}
.drawer__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:20px 22px;border-bottom:1px solid var(--line)}
.drawer__body{padding:22px;overflow-y:auto;flex:1}

/* A drawer that can also open as a large window: window.aqRecordPanel in app.js, opt-in per panel
   ([data-rp] marks one that opted in; nothing here touches a drawer that did not). The window is
   the same element as the side panel, so nothing is rendered or wired twice.
   The window needs room both ways. Below 560px wide the side panel is already most of the screen,
   and below 500px tall (a phone held sideways) a window would show a strip a few lines deep where
   the side panel gets the full height; in both cases the control is hidden and the side panel is
   used whatever was stored. The window never exceeds 94vw. */
.drawer__tools{display:flex;align-items:center;gap:2px;flex:0 0 auto}
.rp-x{display:none}
.drawer[data-rp]:focus{outline:none}
/* The page behind does not scroll while one is open. On the root, because the document is what
   scrolls here; as a selector rather than a class set in script, so a view repainted under an open
   panel cannot leave the page locked. */
html:has(.drawer[data-rp].is-open){overflow:hidden;scrollbar-gutter:stable}
@media (min-width:560px) and (min-height:500px){
  .rp-x{display:grid}
  /* Above the chat launcher (70), which would otherwise sit on the window's corner. */
  .scrim.scrim--float{z-index:71}
  .drawer.drawer--float{top:0;right:0;bottom:0;left:0;margin:auto;width:min(760px,94vw);max-width:none;
    height:min(90vh,920px);border:1px solid var(--line);border-radius:var(--r-xl);overflow:hidden;z-index:72;
    transform:translateY(10px) scale(.985);opacity:0;visibility:hidden;pointer-events:none;
    transition:opacity .18s var(--ease),transform .18s var(--ease),visibility 0s linear .18s}
  .drawer.drawer--float.is-open{transform:none;opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s}
  .drawer--float .drawer__head{padding:18px 24px}
  .drawer--float .drawer__body{padding:22px 28px}
}
/* COLUMNS, so the brief is on screen the moment the window opens. The markup is
     .drawer__body.rp-cols > .rp-col (who they are, how to reach them)
                          + .rp-rest > .rp-col (the brief) + .rp-col (stage, log a visit, activity)
   and in the side panel all of it is plain blocks, so the side panel's layout is what it was.
   Each column scrolls by itself, so reading a long brief never moves the number off the screen.

   TWO from 720px (an iPad mini upright and up; each column is then about as wide as the side
   panel's content on a phone): the record on the left; the brief and then the call actions on the
   right, in the order a call happens. */
@media (min-width:720px) and (min-height:500px){
  .drawer.drawer--float.drawer--cols{width:min(1000px,94vw)}
  .drawer--float .drawer__body.rp-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    padding:0;overflow:hidden;min-height:0}
  .drawer--float .rp-cols > *{overflow-y:auto;overscroll-behavior:contain;min-height:0;padding:22px 24px}
  .drawer--float .rp-cols > * + *{border-left:1px solid var(--line)}
  .drawer--float .rp-cols .rp-col:empty{display:none}
  .drawer--float .rp-rest > .rp-col:not(:empty) + .rp-col{margin-top:22px}
  /* Each column starts at its top edge, not wherever the running page would have put it. */
  .drawer--float .rp-cols > .rp-col > :first-child,
  .drawer--float .rp-rest > .rp-col:first-child > :first-child,
  .drawer--float .rp-rest > .rp-col:empty + .rp-col > :first-child{margin-top:0 !important}
}
/* THREE from 1200px, once each can be as wide as the side panel's own content (about 350px): the
   brief gets a column of its own, so the outcome buttons sit at the top of the third instead of
   under the brief. A lead with no brief gets two. */
@media (min-width:1200px) and (min-height:500px){
  .drawer.drawer--float.drawer--cols{width:min(1180px,94vw)}
  .drawer--float .drawer__body.rp-cols{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr)}
  .drawer--float .rp-cols > .rp-rest{display:contents}
  .drawer--float .rp-rest > .rp-col{overflow-y:auto;overscroll-behavior:contain;min-height:0;padding:22px 24px;
    border-left:1px solid var(--line)}
  .drawer--float .rp-rest > .rp-col:not(:empty) + .rp-col{margin-top:0}
  .drawer--float .rp-cols .rp-col > :first-child{margin-top:0 !important}
}

/* A merchant record is a PAGE, not a 420px column.
   Requested after seeing the reference dashboard: opening a client should give you the whole
   record at once, rather than a strip you scroll while the list sits uselessly behind it.
   Implemented as a modifier on the existing drawer so every handler, the splits loader, the
   KYC loader and the value panel keep working untouched. Only the container changes.
   The sidebar is 248px and the topbar 62px, matching .app and .topbar above; if either
   changes, these two numbers move with it.
   Below 900px it falls back to the side panel, where a full-width takeover and a drawer are
   the same thing anyway. */
@media (min-width:900px){
  .drawer.drawer--page{right:0;left:248px;width:auto;max-width:none;top:62px;
    height:calc(100vh - 62px);border-left:0;border-top:1px solid var(--line);
    transform:translateY(12px);opacity:0;pointer-events:none;
    transition:opacity .18s var(--ease),transform .18s var(--ease)}
  .drawer.drawer--page.is-open{transform:none;opacity:1;pointer-events:auto}
  .drawer--page .drawer__head{padding:18px 30px;justify-content:flex-start;gap:20px}
  /* Back belongs before the title on a page, the way it does on any record screen. The head is
     flex with the title first, so this reorders without touching the markup the drawer shares
     with its side-panel variant. */
  .drawer--page .drawer__head #mClose{order:-1}
  /* Full width, but the text still has a measure. A key/value row stretched across 1600px is
     harder to read than the drawer was, which would miss the point of the change. The measure
     is now kept by SPLITTING the record into two columns rather than by capping the page and
     leaving the right half of a wide screen blank, which is what a 1080px cap did here. */
  .drawer--page .drawer__body{padding:24px 30px;max-width:1600px}
}
/* The merchant record. One column on a laptop, two once there is room for two readable ones.
   1180px is where 2 x 520 plus the gap and the page padding first fits inside the content area
   next to a 248px sidebar; below it a second column would be too narrow to read. */
.mdet{display:grid;grid-template-columns:minmax(0,1fr);gap:26px;align-items:start}
@media(min-width:1180px){ .mdet{grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);gap:38px} }
.mdet__main,.mdet__side{min-width:0}
.mini{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r);padding:11px 13px;display:flex;flex-direction:column;gap:5px}
.mini span{font-size:11.5px;color:var(--muted);font-weight:500}
.mini b{font-size:16px;font-weight:700}
.kv{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid var(--line-2);font-size:13px}
.kv:last-child{border-bottom:none}
.kv span{color:var(--muted)}
.kv b{font-weight:600}

/* ---- kanban (pipeline) ---- */
.kanban{display:grid;grid-template-columns:repeat(5,minmax(192px,1fr));gap:14px;overflow-x:auto;padding-bottom:6px}
.kcol{background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-lg);padding:12px}
.kcol__head{display:flex;align-items:center;justify-content:space-between;padding:2px 4px}
.kcol__title{font-size:12.5px;font-weight:700;display:flex;align-items:center;gap:7px}
.kcol__count{font-size:11px;font-weight:700;color:var(--muted);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-full);padding:1px 8px}
.kcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r);padding:11px 12px;margin-bottom:9px;box-shadow:var(--shadow-sm);cursor:pointer;transition:all .15s var(--ease)}
.kcard:hover{box-shadow:var(--shadow);transform:translateY(-1px)}
.kcard[draggable="true"]{cursor:grab}
.kcard.is-dragging{opacity:.4;cursor:grabbing}
.kcol.drop-on{outline:2px dashed rgba(var(--accent-rgb),.55);outline-offset:-3px}
.kcard__name{font-weight:600;font-size:12.5px;display:flex;align-items:center;gap:8px}
.kcard__meta{display:flex;align-items:center;justify-content:space-between;gap:8px}
@media(max-width:1000px){.kanban{grid-template-columns:repeat(5,minmax(180px,1fr))}}
/* ---- collapsible board (leads + deals): flex variant so a column can shrink ---- */
.kanban--flex{display:flex;flex-wrap:nowrap;grid-template-columns:none}
.kanban--flex .kcol{flex:0 0 200px;display:flex;flex-direction:column;transition:flex-basis .18s var(--ease)}
.kcol__min{margin-left:6px;width:24px;height:24px;flex:0 0 24px;display:grid;place-items:center;border:0;background:none;color:var(--muted);cursor:pointer;border-radius:6px;transition:transform .18s var(--ease),background .15s}
.kcol__min:hover{background:var(--surface);color:var(--ink)}
.kcol__min i{width:14px;height:14px}
.kcol.is-collapsed{flex:0 0 46px;cursor:pointer}
.kcol.is-collapsed .kcol__sub,.kcol.is-collapsed .kcard,.kcol.is-collapsed .empty{display:none}
.kcol.is-collapsed .kcol__head{flex-direction:column;align-items:center;gap:10px;padding-top:4px}
.kcol.is-collapsed .kcol__title{writing-mode:vertical-rl;transform:rotate(180deg);white-space:nowrap}
.kcol.is-collapsed .kcol__min{transform:rotate(180deg)}
/* ---- flashcard grid (List / Card / Board "Card" view) ---- */
.fgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(244px,1fr));gap:14px}
.fcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-sm);padding:16px;cursor:pointer;transition:box-shadow .15s var(--ease),transform .15s var(--ease);display:flex;flex-direction:column;gap:11px}
.fcard:hover{box-shadow:var(--shadow);transform:translateY(-2px)}
.fcard__top{display:flex;align-items:center;gap:10px}
.fcard__name{font-weight:700;font-size:14px;line-height:1.25}
.fcard__sub{font-size:11.5px;color:var(--muted)}
.fcard__row{display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:12.5px}
.fcard__row .lbl{color:var(--muted);font-size:11.5px}
/* ---- "coming soon" treatment (reuses the nav .is-soon idea on buttons + a corner badge) ---- */
.btn.is-soon{opacity:.6;cursor:default;background:var(--surface-3);border-color:var(--line);color:var(--muted)}
.btn.is-soon:hover{background:var(--surface-3);border-color:var(--line)}
.card.is-soon{opacity:.72}
.badge-soon{display:inline-flex;align-items:center;font-size:10.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-full);padding:2px 9px}

/* ---- org tree (agents) ---- */
.tree{display:flex;flex-direction:column;gap:10px}
.tcard{display:flex;align-items:center;gap:12px;padding:11px 13px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-sm);transition:all .15s;cursor:pointer}
.tcard:hover{box-shadow:var(--shadow);border-color:rgba(var(--accent-rgb),.35)}
.tchildren{margin:10px 0 0 21px;padding-left:18px;border-left:2px solid var(--line);display:flex;flex-direction:column;gap:10px}

/* ---- toast (action feedback) ---- */
/* ABOVE THE MODAL, BECAUSE THAT IS WHERE IT IS USED. At z-index 120 the toast sat UNDER the
   modal's backdrop, which is both dark and blurred, so a validation message raised from inside
   a dialog — "Who is signing? Enter the signer's name" — was unreadable at the very moment it
   had to be read. Every toast a modal raises is about that modal. */
.toast-wrap{position:fixed;right:20px;bottom:20px;z-index:400;display:flex;flex-direction:column;gap:9px;pointer-events:none}
.toast{display:flex;align-items:center;gap:11px;background:var(--surface);color:var(--ink);border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r);box-shadow:var(--shadow-lg);padding:11px 15px;min-width:210px;max-width:340px;transform:translateY(10px);opacity:0;transition:opacity .18s var(--ease),transform .18s var(--ease)}
.toast.is-in{opacity:1;transform:translateY(0)}
.toast i{width:17px;height:17px;color:var(--accent);flex:0 0 17px}
.toast__t{font-size:13px;font-weight:700;line-height:1.25}
.toast__sub{font-size:11.5px;font-weight:500;color:var(--muted);margin-top:1px}

/* agent rows are clickable */
.tbl tr.is-click{cursor:pointer}
.tbl tr.is-click:hover{background:var(--surface-2)}
.kv--click{cursor:pointer;border-radius:7px;margin:0 -8px;padding-left:8px;padding-right:8px;transition:background .12s}
.kv--click:hover{background:var(--surface-2)}

/* ---- statement analyzer ---- */
.field{display:flex;flex-direction:column;gap:6px;margin-bottom:13px}
.field>label{font-size:11px;font-weight:700;color:var(--muted);letter-spacing:.04em;text-transform:uppercase}
.inp{display:flex;align-items:center;gap:8px;height:40px;padding:0 12px;background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-sm);transition:border-color .15s,box-shadow .15s}
.inp:focus-within{border-color:var(--accent);box-shadow:0 0 0 3px rgba(var(--accent-rgb),.13)}
.inp .pre{color:var(--faint);font-size:13.5px;font-weight:600}
.inp input{flex:1;min-width:0;background:none;border:none;outline:none;color:var(--ink);font-size:14px;font-weight:600;font-variant-numeric:tabular-nums}
/* Selects matched to the rest of the page. Without appearance:none a <select> renders the host
   OS control, which is why dropdowns read as system UI next to our own inputs. The chevron is
   drawn with a mask so it takes its color from the theme instead of being baked into the asset.
   The option LIST itself is drawn by the OS and cannot be styled; only the closed control can.
   locked 2026-08-25; do not drop appearance:none - see status/AAG_STATUS.md */
.inp select{flex:1;min-width:0;background:none;border:none;outline:none;color:var(--ink);font-family:inherit;font-size:14px;font-weight:600;appearance:none;-webkit-appearance:none;cursor:pointer;padding-right:18px}
.inp:has(select){position:relative}
.inp:has(select)::after{content:'';position:absolute;right:12px;top:50%;transform:translateY(-50%);width:10px;height:6px;pointer-events:none;background-color:var(--faint);-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/10px 6px no-repeat;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center/10px 6px no-repeat}
/* The option list follows the page theme where the browser honors it (Chrome/Edge). */
.inp select option{background:var(--surface-2,#fff);color:var(--ink)}
.dropzone{display:flex;align-items:center;gap:12px;border:1.5px dashed var(--line);border-radius:var(--r);padding:14px 16px;cursor:pointer;transition:all .15s;color:var(--muted);margin-bottom:16px}
.dropzone:hover{border-color:var(--accent);background:var(--surface-2);color:var(--ink-2)}
.dropzone i{width:22px;height:22px;flex:0 0 22px;color:var(--accent)}
.an-hero{background:linear-gradient(135deg,var(--side-bg),color-mix(in srgb,var(--side-bg) 78%, var(--accent)));color:#fff;border-radius:var(--r-lg);padding:22px 24px}
.an-hero .big{font-size:38px;font-weight:800;letter-spacing:-.02em;line-height:1;font-variant-numeric:tabular-nums}
.an-hero .lbl{font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;opacity:.7}
.feebar{display:flex;height:34px;border-radius:8px;overflow:hidden;border:1px solid var(--line);background:var(--surface-3)}
.feebar>div{display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;color:#fff;min-width:0;white-space:nowrap;overflow:hidden}
.feeleg{display:flex;flex-wrap:wrap;gap:16px;margin-top:11px}
.feeleg span{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--muted)}
.feeleg b{color:var(--ink);font-variant-numeric:tabular-nums}
.feeleg i{width:11px;height:11px;border-radius:3px;display:inline-block;flex:0 0 11px}
.cmp{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.cmp__col{border:1px solid var(--line);border-radius:var(--r);padding:14px 16px;background:var(--surface)}
.cmp__col.is-win{border-color:color-mix(in srgb,var(--accent) 55%, var(--line));background:color-mix(in srgb,var(--accent) 6%, var(--surface))}
@media(max-width:900px){.cmp{grid-template-columns:1fr}}

/* ---- modal ---- */
.modal-back{position:fixed;inset:0;background:rgba(7,13,23,.5);backdrop-filter:saturate(140%) blur(3px);z-index:200;display:flex;align-items:center;justify-content:center;padding:20px;opacity:0;transition:opacity .18s var(--ease)}
.modal-back.is-in{opacity:1}
.modal{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);width:100%;max-width:500px;max-height:88vh;display:flex;flex-direction:column;transform:translateY(14px) scale(.98);transition:transform .2s var(--ease)}
.modal-back.is-in .modal{transform:none}
.modal__head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:17px 20px;border-bottom:1px solid var(--line)}
.modal__title{font-weight:800;font-size:16px;letter-spacing:-.01em}
.modal__x{width:32px;height:32px}
.modal__body{padding:18px 20px;overflow-y:auto}
.modal__foot{display:flex;justify-content:flex-end;gap:8px;padding:14px 20px;border-top:1px solid var(--line)}
.mlabel{display:block;font-size:11px;font-weight:700;color:var(--muted);letter-spacing:.04em;text-transform:uppercase;margin:0 0 6px}
.mfield{width:100%;height:40px;padding:0 12px;background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-sm);color:var(--ink);font-size:14px;font-family:var(--font);font-weight:500;outline:none;transition:border-color .15s,box-shadow .15s}
textarea.mfield{height:auto;min-height:96px;padding:10px 12px;resize:vertical;line-height:1.5}
.mfield:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(var(--accent-rgb),.13)}
.mrow+.mrow{margin-top:14px}
/* first-run tip "don't show again" footer affordance */
.tip-dismiss{display:flex;align-items:center;gap:8px;margin-top:16px;font-size:12.5px;color:var(--muted);cursor:pointer;user-select:none}
.tip-dismiss input{width:15px;height:15px;cursor:pointer;accent-color:var(--accent)}

/* ---- global search dropdown ---- */
.search{position:relative}
.srch-pop{position:absolute;top:calc(100% + 8px);left:0;right:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-lg);padding:6px;z-index:60;display:none;max-height:60vh;overflow-y:auto}
.srch-pop.is-in{display:block}
/* Wide enough to read a business, a person and an email on one line, never wider than the screen. */
.srch-pop{min-width:min(440px,calc(100vw - 32px))}
.srch-row{display:flex;align-items:center;gap:11px;padding:9px 10px;border-radius:8px;cursor:pointer}
.srch-row:hover{background:var(--surface-2)}
.srch-row.is-sel{background:var(--surface-2);box-shadow:inset 0 0 0 1px rgba(var(--accent-rgb),.35)}
.srch-logo i{width:14px;height:14px}
.srch-logo{width:30px;height:30px;flex:0 0 30px;border-radius:7px;color:#fff;font-size:11px;font-weight:700;display:flex;align-items:center;justify-content:center}
.srch-main{flex:1;min-width:0}
.srch-label{font-size:13px;font-weight:600;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.srch-sub{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.srch-type{font-size:10px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--accent);background:rgba(var(--accent-rgb),.1);padding:3px 8px;border-radius:100px;flex:0 0 auto}
.srch-empty{padding:16px;text-align:center;font-size:13px;color:var(--muted)}

/* ---- profile menu ---- */
.pmenu{position:absolute;right:0;top:50px;min-width:230px;background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-lg);padding:6px;z-index:60;display:none;cursor:default;text-align:left}
.pmenu.is-in{display:block}
.pmenu__id{padding:8px 10px 6px}
.pmenu__name{font-size:13px;font-weight:700;color:var(--ink)}
.pmenu__email{font-size:11.5px;color:var(--muted);margin-top:1px}
.pmenu__label{padding:4px 10px 2px;font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
/* Instant-rebate gate: lapsed workspace greys its nav. The Dashboard link stays
   at full strength because that is where the activation-code field lives. */
body.aq-lapsed .nav__link:not([data-route="dashboard"]){opacity:.45}
body.aq-lapsed .nav__group{opacity:.75}
.pmenu__item[aria-current="true"]{color:var(--ink);font-weight:700}
.pmenu__item[aria-current="true"] i{color:var(--brand,var(--ink))}
.pmenu__sep{height:1px;background:var(--line);margin:6px 4px}
.pmenu__item{display:flex;align-items:center;gap:10px;width:100%;padding:9px 10px;border-radius:7px;font-size:13px;font-weight:500;color:var(--ink-2);text-align:left}
.pmenu__item:hover{background:var(--surface-2);color:var(--ink)}
.pmenu__item i{width:15px;height:15px;color:var(--muted)}

/* ---- auth / login screen ---- */
/* THIS OVERLAY CARRIES LONG FORMS, NOT JUST THE LOGIN CARD. It was written for sign-in,
   which is four fields and always fits, so it centred its card in a fixed viewport with no
   way to scroll. Seven screens use it, and three of them are the ones a merchant sees with
   no account: #apply-session asks a question per mapped box — twenty-two on the 0030 form —
   and #sign and #apply are no shorter. Everything below the fold was unreachable: not
   clipped visibly, simply gone, with no scrollbar to suggest otherwise. Reported from the
   merchant link, where the only way to read the form was to zoom the browser to 25%.

   overflow-y:auto makes the overlay itself scroll. align-items:flex-start stops a card
   taller than the viewport being centred, which pushes its top edge off-screen above — the
   failure that makes a too-tall centred box unscrollable even once scrolling is allowed.
   margin:auto keeps a short card centred, so sign-in looks exactly as it did. */
.aq-auth{position:fixed;inset:0;z-index:300;display:flex;align-items:flex-start;justify-content:center;overflow-y:auto;-webkit-overflow-scrolling:touch;padding:24px;background:radial-gradient(900px 520px at 82% -8%, color-mix(in srgb,var(--accent) 24%, transparent) 0%, transparent 56%), radial-gradient(760px 620px at 6% 112%, color-mix(in srgb,var(--accent) 16%, transparent) 0%, transparent 55%), linear-gradient(158deg, var(--side-bg) 0%, color-mix(in srgb,var(--side-bg) 80%, #000) 100%)}
.aq-auth__card{width:100%;max-width:400px;margin:auto;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:34px 32px}
/* A phone is where a merchant opens the link an agent texted them. The 32px side padding
   plus the overlay's own 24px left barely half the screen for the field itself. */
@media (max-width:560px){
  .aq-auth{padding:12px}
  .aq-auth__card{padding:22px 16px;border-radius:var(--r)}
}
.aq-auth__brand{display:flex;align-items:center;gap:10px;margin-bottom:22px}
.aq-auth__brand img{height:30px;width:auto;max-width:170px}
.aq-auth__mark{width:34px;height:34px;border-radius:9px;background:var(--side-bg);color:#fff;display:grid;place-items:center;font-weight:800;font-size:18px}
.aq-auth__name{font-weight:800;font-size:19px;letter-spacing:-.02em;color:var(--ink)}
.aq-auth__h{font-size:21px;font-weight:800;letter-spacing:-.02em;color:var(--ink)}
.aq-auth__sub{font-size:13px;color:var(--muted);margin:5px 0 22px}
.aq-auth__lbl{display:block;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted);margin:0 0 6px}
.aq-auth__inp{width:100%;height:44px;padding:0 13px;background:var(--surface-3);border:1px solid var(--line);border-radius:var(--r-sm);color:var(--ink);font-size:14.5px;font-family:var(--font);outline:none;margin-bottom:15px;transition:border-color .15s,box-shadow .15s}
.aq-auth__inp:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(var(--accent-rgb),.14)}
.aq-auth__err{background:var(--red-soft);color:var(--red);border-radius:var(--r-sm);padding:9px 12px;font-size:12.5px;font-weight:600;margin-bottom:13px}
.aq-auth__btn{width:100%;height:44px;border-radius:var(--r-sm);background:var(--accent);color:#fff;font-weight:700;font-size:14px;border:0;cursor:pointer;transition:filter .15s,opacity .15s}
.aq-auth__btn:hover{filter:brightness(1.06)}
.aq-auth__btn:disabled{opacity:.7;cursor:default}
/* passkey (Face ID / Touch ID) sign-in: secondary button + divider */
.aq-auth__or{display:flex;align-items:center;gap:10px;color:var(--faint);font-size:12px;font-weight:600;margin:16px 0}
.aq-auth__or::before,.aq-auth__or::after{content:'';flex:1;height:1px;background:var(--line)}
.aq-auth__btn--ghost{background:transparent;color:var(--ink);border:1px solid var(--line);display:flex;align-items:center;justify-content:center;gap:9px}
.aq-auth__foot{margin-top:18px;text-align:center;font-size:13px;color:var(--muted)}
.aq-auth__foot a{color:var(--accent);font-weight:600;text-decoration:none;cursor:pointer}
.aq-auth__foot a:hover{text-decoration:underline}
.aq-auth__btn--ghost:hover{background:var(--surface-3);filter:none}
.aq-auth__btn--ghost svg{width:18px;height:18px;flex:0 0 18px}
/* password show/hide */
.aq-auth__pw{position:relative}
.aq-auth__pw .aq-auth__inp{padding-right:44px}
.aq-auth__eye{position:absolute;right:8px;top:22px;transform:translateY(-50%);width:30px;height:30px;display:grid;place-items:center;background:transparent;border:0;border-radius:7px;color:var(--faint);cursor:pointer}
.aq-auth__eye:hover{color:var(--muted);background:var(--surface-3)}
.aq-auth__eye.is-on{color:var(--accent)}
.aq-auth__eye svg{width:18px;height:18px}
/* remember / forgot + terms rows */
.aq-auth__row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:2px 0 12px;font-size:12.5px;flex-wrap:wrap}
.aq-auth__check{display:flex;align-items:center;gap:7px;color:var(--muted);cursor:pointer;user-select:none}
.aq-auth__check input{width:15px;height:15px;cursor:pointer;accent-color:var(--accent)}
.aq-auth__link{color:var(--accent);font-weight:600;text-decoration:none;cursor:pointer;white-space:nowrap}
.aq-auth__link:hover{text-decoration:underline}
.aq-auth__note{background:var(--surface-3);color:var(--muted);border:1px solid var(--line);border-radius:var(--r-sm);padding:9px 12px;font-size:12.5px;line-height:1.5;margin-bottom:12px}
/* two login buttons */
.aq-auth__btns{display:flex;gap:10px}
.aq-auth__btns .aq-auth__btn{flex:1}

/* ===== Merchant Portal: CRM↔Merchant toggle + merchant-mode chrome ===== */
.portal-toggle{margin-left:auto}
.portal-brand{display:flex;flex-direction:column;line-height:1.1;margin-right:auto}
.portal-brand__name{font-weight:800;font-size:15px;color:var(--ink)}
.portal-brand__tag{font-size:11px;color:var(--muted);font-weight:600}
/* The merchant portal now uses the normal two-column app shell; portal-shell.js
   repopulates the sidebar with the merchant nav (Overview / Transactions / …). */
.psplit{display:grid;grid-template-columns:2fr 1fr;gap:16px;margin-bottom:16px;align-items:start}
.psplit--even{grid-template-columns:1fr 1fr}
@media(max-width:900px){.psplit,.psplit--even{grid-template-columns:1fr}}
/* Merchant notification dropdown (topbar bell) */
.mnotif{position:fixed;z-index:200;width:330px;max-width:calc(100vw - 24px);background:var(--surface);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-lg);overflow:hidden}
.mnotif__head{padding:12px 15px;font-weight:700;font-size:13px;border-bottom:1px solid var(--line)}
.mnotif__item{display:flex;gap:11px;align-items:flex-start;padding:11px 15px;border-bottom:1px solid var(--line)}
.mnotif__item:last-child{border-bottom:0}
.mnotif__ic{width:30px;height:30px;border-radius:8px;display:grid;place-items:center;flex:0 0 auto}
.mnotif__ic i{width:16px;height:16px}
.mnotif__t{font-size:13px;font-weight:600}
.mnotif__s{font-size:12px;color:var(--muted);margin-top:2px;line-height:1.4}
.mnotif__empty{padding:24px 15px;text-align:center;color:var(--muted);font-size:13px}
/* Money-flow donut interactivity (hover an arc or legend row to focus it) */
.mf-arc{transition:opacity .16s ease,stroke-width .16s ease;cursor:pointer}
.mf-svg:hover .mf-arc{opacity:.34}
.mf-svg:hover .mf-arc:hover{opacity:1;stroke-width:26}
.mf-svg.mf-dim .mf-arc{opacity:.34}
.mf-svg.mf-dim .mf-arc.mf-on{opacity:1;stroke-width:26}
.mf-leg{cursor:default;transition:background .15s}
.mf-leg:hover{background:rgba(var(--accent-rgb),.09)}

/* ===== Help center articles (Penumbra-style expandable) ===== */
.help-art{transition:border-color .15s,box-shadow .15s}
.help-art:hover{border-color:rgba(var(--accent-rgb),.42)}
.help-art.is-open{border-color:rgba(var(--accent-rgb),.55)}
.help-chev{color:var(--muted);transition:transform .2s ease;flex:0 0 auto}
.help-art.is-open .help-chev{transform:rotate(180deg)}
.help-art .faq-a p{margin:0 0 9px}
.help-art .faq-a p:last-child{margin-bottom:0}
.help-art .faq-a ul{margin:0 0 9px;padding-left:18px;display:flex;flex-direction:column;gap:5px}
.help-art .faq-a b{color:var(--ink)}

/* ===== Calendar (My Office) ===== */
.cal-head{display:grid;grid-template-columns:repeat(7,1fr);gap:6px;margin-bottom:6px}
.cal-dow{font-size:10.5px;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--faint);text-align:center;padding:2px 0}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:6px}
.cal-cell{min-height:92px;background:var(--surface-2);border:1px solid var(--line);border-radius:var(--r-sm);padding:6px 7px;display:flex;flex-direction:column;gap:3px;overflow:hidden}
.cal-cell--off{background:transparent;border-color:transparent}
.cal-cell--today{border-color:rgba(var(--accent-rgb),.5);box-shadow:0 0 0 1px rgba(var(--accent-rgb),.3) inset}
.cal-num{font-size:12px;font-weight:700;color:var(--ink-2)}
.cal-cell--today .cal-num{color:var(--accent-ink);width:21px;height:21px;display:grid;place-items:center;background:var(--accent);color:#fff;border-radius:50%;font-size:11px}
.cal-ev{font-size:10.5px;font-weight:600;padding:2px 6px;border-radius:5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:5px}
.cal-ev .d{width:5px;height:5px;border-radius:50%;flex:0 0 5px}
.cal-more{font-size:10px;font-weight:600;color:var(--muted);padding-left:2px}
@media(max-width:900px){.cal-cell{min-height:64px}.cal-ev{font-size:9.5px}}

/* ===== Tasks (My Office) ===== */
.task-row{display:flex;align-items:center;gap:13px;padding:13px 4px;border-bottom:1px solid var(--line-2)}
.task-row:last-child{border-bottom:none}
.task-check{width:22px;height:22px;flex:0 0 22px;border:2px solid var(--line);border-radius:6px;display:grid;place-items:center;color:#fff;transition:all .15s}
.task-check:hover{border-color:var(--accent)}
.task-check.on{background:var(--accent);border-color:var(--accent)}
.task-check i{width:14px;height:14px}
.task-main{flex:1;min-width:0}
.task-title{font-weight:600;font-size:13.5px;color:var(--ink)}
.task-row.is-done .task-title{text-decoration:line-through;color:var(--faint)}
.task-due{font-size:12px;font-weight:600;color:var(--muted);min-width:84px;text-align:right}
.task-due.over{color:var(--red)}

/* ===== Comms hub (email / chat / notifications) ===== */
.cm{display:grid;border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface);min-height:560px}
.cm--email{grid-template-columns:184px 326px 1fr}
.cm--chat{grid-template-columns:264px 1fr}
.cm__rail{border-right:1px solid var(--line);background:var(--surface-2);overflow-y:auto;padding:10px}
.cm__list{border-right:1px solid var(--line);overflow-y:auto}
.cm__pane{overflow-y:auto;padding:22px 24px;display:flex;flex-direction:column;min-width:0}
.cm-folder{display:flex;align-items:center;gap:10px;padding:9px 11px;border-radius:var(--r-sm);font-size:13px;font-weight:500;color:var(--ink-2);cursor:pointer}
.cm-folder:hover{background:var(--surface-3)}
.cm-folder.is-on{background:rgba(var(--accent-rgb),.1);color:var(--accent-ink)}
.cm-folder i{width:16px;height:16px}
.cm-folder em{margin-left:auto;font-style:normal;font-size:11px;font-weight:700;color:var(--muted)}
.cm-mail{padding:12px 14px;border-bottom:1px solid var(--line-2);cursor:pointer}
.cm-mail:hover{background:var(--surface-2)}
.cm-mail.is-on{background:rgba(var(--accent-rgb),.07)}
.cm-mail.unread .cm-mail__from{font-weight:800}
.cm-mail.unread .cm-mail__subj{color:var(--ink);font-weight:600}
.cm-mail__top{display:flex;justify-content:space-between;gap:8px}
.cm-mail__from{font-size:13px;font-weight:600;color:var(--ink)}
.cm-mail__time{font-size:11px;color:var(--faint);white-space:nowrap}
.cm-mail__subj{font-size:12.5px;color:var(--ink-2);margin-top:2px}
.cm-mail__prev{font-size:11.5px;color:var(--muted);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cm-filed{display:inline-flex;align-items:center;gap:5px;font-size:10.5px;font-weight:700;color:var(--accent-ink);background:rgba(var(--accent-rgb),.12);border-radius:var(--r-full);padding:2px 8px;margin-top:6px}
.cm-filed i{width:11px;height:11px}
.chat-sec{font-size:10px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);padding:12px 10px 5px}
.chat-ch{display:flex;align-items:center;gap:9px;padding:8px 10px;border-radius:var(--r-sm);font-size:13px;font-weight:500;color:var(--ink-2);cursor:pointer}
.chat-ch:hover{background:var(--surface-3)}
.chat-ch.is-on{background:rgba(var(--accent-rgb),.1);color:var(--accent-ink)}
.chat-ch i{width:15px;height:15px;color:var(--muted)}
.chat-ch .dotu{margin-left:auto;width:7px;height:7px;border-radius:50%;background:var(--accent);flex:0 0 7px}
.chat-thread{display:flex;flex-direction:column;min-height:0}
.chat-head{display:flex;align-items:center;gap:10px;padding:13px 18px;border-bottom:1px solid var(--line)}
.chat-body{flex:1;overflow-y:auto;padding:18px;display:flex;flex-direction:column;gap:10px;min-height:300px}
.chat-msg{max-width:74%;padding:9px 13px;border-radius:12px;font-size:13px;line-height:1.5}
.chat-msg.in{align-self:flex-start;background:var(--surface-2);border:1px solid var(--line);border-bottom-left-radius:4px}
.chat-msg.out{align-self:flex-end;background:rgba(var(--accent-rgb),.13);border-bottom-right-radius:4px}
.chat-msg__who{font-size:11px;font-weight:700;color:var(--muted);margin-bottom:3px}
.chat-msg__time{font-size:10px;color:var(--faint);margin-top:3px;text-align:right}
.chat-composer{border-top:1px solid var(--line);padding:12px 14px;display:flex;gap:10px;align-items:center}
.notif{display:flex;align-items:flex-start;gap:13px;padding:13px 6px;border-bottom:1px solid var(--line-2);cursor:pointer}
.notif:last-child{border-bottom:none}
.notif:hover{background:var(--surface-2)}
.notif.unread{background:rgba(var(--accent-rgb),.05)}
.notif__ic{width:34px;height:34px;border-radius:9px;display:grid;place-items:center;flex:0 0 34px}
.notif__ic i{width:16px;height:16px}
.notif__b{flex:1;min-width:0}
.notif__t{font-weight:600;font-size:13px}
.notif__s{font-size:12px;color:var(--muted);margin-top:1px}
.notif__time{font-size:11px;color:var(--faint);white-space:nowrap;margin-left:auto;padding-left:8px}
.notif__dot{width:8px;height:8px;border-radius:50%;background:var(--accent);flex:0 0 8px;margin-top:6px}
@media(max-width:1000px){.cm--email,.cm--chat{grid-template-columns:1fr}.cm__rail,.cm__list{max-height:240px}}

/* ===== Interactivity affordances (clickable cards / rows) ===== */
.kpi.is-click{cursor:pointer;transition:transform .14s var(--ease),box-shadow .14s var(--ease),border-color .14s var(--ease)}
.kpi.is-click:hover{transform:translateY(-2px);box-shadow:var(--shadow);border-color:rgba(var(--accent-rgb),.45)}
.att.is-click{cursor:pointer;border-radius:8px;margin-left:-8px;margin-right:-8px;padding-left:8px;padding-right:8px;transition:background .12s var(--ease)}
.att.is-click:hover{background:var(--surface-2)}
.dash-row{cursor:pointer;border-radius:8px;transition:background .12s var(--ease)}
.dash-row:hover{background:var(--surface-2)}
.cal-ev{cursor:pointer;transition:filter .12s var(--ease)}
.cal-ev:hover{filter:brightness(.94)}
.cal-more{cursor:pointer;transition:color .12s var(--ease)}
.cal-more:hover{color:var(--accent)}
.task-row.is-click{cursor:pointer;border-radius:8px;margin-left:-6px;margin-right:-6px;padding-left:10px;padding-right:10px;transition:background .12s var(--ease)}
.task-row.is-click:hover{background:var(--surface-2)}

/* ===== Dialpad (Phone) ===== */
.dialpad{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.dialkey{height:48px;border-radius:var(--r-sm);border:1px solid var(--line);background:var(--surface-2);font-size:18px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;transition:all .12s var(--ease)}
.dialkey:hover{background:var(--surface-3);border-color:rgba(var(--accent-rgb),.4)}
.dialkey:active{transform:scale(.96)}

/* ===== Integration cards — uniform app-marketplace grid (Settings + Marketplace) ===== */
.intg-card{display:flex;flex-direction:column;height:100%;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px 18px 15px;transition:box-shadow .14s var(--ease),border-color .14s var(--ease),transform .14s var(--ease)}
.intg-card.is-click{cursor:pointer}
.intg-card.is-click:hover{border-color:rgba(var(--accent-rgb),.45);box-shadow:var(--shadow);transform:translateY(-2px)}
.intg-card.is-soon{opacity:.74}
.intg-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px;margin-bottom:13px}
.intg-logo{width:46px;height:46px;flex:0 0 46px;border-radius:11px;display:grid;place-items:center;position:relative;overflow:hidden}
.intg-logo i{width:24px;height:24px}
.intg-badge{font-size:11px;font-weight:600;color:var(--muted);background:var(--surface-3);padding:3px 9px;border-radius:999px;display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.intg-badge--on{color:var(--green);background:rgba(22,163,74,.12)}
.intg-badge--on .d{width:6px;height:6px;border-radius:50%;background:var(--green)}
.intg-name{font-size:15px;font-weight:700;letter-spacing:-.01em;color:var(--ink)}
.intg-cat{font-size:12px;color:var(--muted);margin-top:2px}
.intg-desc{font-size:12.5px;color:var(--muted);line-height:1.45;margin-top:9px;display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:36px}
.intg-foot{margin-top:auto;padding-top:13px}
.intg-action{font-size:12.5px;font-weight:700;color:var(--accent-ink)}
.intg-card.is-soon .intg-action{display:none}
/* real brand logo: fades in over the icon tile only after it successfully loads
   (.is-on added by onload). On error the img removes itself; the icon tile stays. */
.intg-logo-pic{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;padding:7px;background:#fff;border-radius:inherit;opacity:0;transition:opacity .18s ease}
.intg-logo-pic.is-on{opacity:1}

/* ===== Dashboard — customizable masonry widget board (true zero blank space) =====
   CSS multi-column packs variable-height widgets tight with NO vertical gaps (unlike
   CSS grid, which aligns to rows and leaves holes when row-mates differ in height).
   The board is drawn in SEGMENTS (views/dashboard.js renderGrid): a full-width widget
   (data-w=12) is a block of its own directly in .dash-grid, and each run of widgets
   between two of them is its own .dash-cols multi-column block. NO column-span: WebKit
   paints a spanning widget that follows other widgets over its neighbours (2026-09-28).
   Phone width drops multi-column altogether for one plain flex column. */
.dash-grid{display:block}
.dash-cols{column-count:2;column-gap:16px;column-fill:balance}
.dwidget{break-inside:avoid;-webkit-column-break-inside:avoid;page-break-inside:avoid;margin:0 0 16px;position:relative;width:100%}
@media (min-width:1480px){ .dash-cols{column-count:3} }
@media (max-width:760px){ .dash-cols{column-count:auto;display:flex;flex-direction:column} .dash-cols>.dwidget{min-width:0} }
/* A run shorter than the columns takes only as many columns as it has cards (data-n, set by
   renderGrid), so one card between two full-width ones fills its row instead of sitting in a
   third of it beside empty space. Higher specificity than the width rules above, on purpose. */
.dash-cols[data-n="1"]{column-count:1}
.dash-cols[data-n="2"]{column-count:2}
/* edit chrome */
.dash-grid[data-edit="on"] .dwidget{outline:1px dashed var(--line);outline-offset:3px;border-radius:var(--r-lg);cursor:grab}
.dash-grid[data-edit="on"] .dwidget:active{cursor:grabbing}
.dwidget.is-dragging{opacity:.4;cursor:grabbing}
/* Insertion caret. Nothing reorders mid-drag, so this is the only feedback the gesture
   gives, and it sits in the 16px gutter between tiles. */
.dwidget.dw-drop-before::before,
.dwidget.dw-drop-after::after{content:"";position:absolute;left:0;right:0;height:3px;
  background:var(--accent);border-radius:2px;z-index:4;pointer-events:none}
.dwidget.dw-drop-before::before{top:-9px}
.dwidget.dw-drop-after::after{bottom:-9px}
.dw-grip{display:inline-grid;place-items:center;width:28px;height:28px;border-radius:var(--r-sm);
  background:var(--surface);border:1px solid var(--line);box-shadow:var(--shadow-sm);
  color:var(--faint);cursor:grab}
.dw-grip i{width:14px;height:14px}
.dw-tools{position:absolute;top:8px;right:8px;display:none;gap:4px;z-index:3}
.dash-grid[data-edit="on"] .dw-tools{display:inline-flex}
/* Customizing never navigates (dashboard.js follow()), so a card's own header links are inert while
   the tools sit over them; hide them rather than leave a covered link that does nothing. */
.dash-grid[data-edit="on"] .dwidget .card__head>a.linklike,.dash-grid[data-edit="on"] .dwidget .spread>a.linklike{visibility:hidden}
.dw-tools button{width:28px;height:28px;border-radius:var(--r-sm);background:var(--surface);border:1px solid var(--line);display:grid;place-items:center;box-shadow:var(--shadow-sm);cursor:pointer;color:var(--ink)}
.dw-tools button:hover{background:var(--surface-3)}
.dw-tools i{width:14px;height:14px}
.dash-add{display:none;gap:8px;flex-wrap:wrap;margin-top:16px;align-items:center}
.dash-add.is-on{display:flex}

/* ===== Dashboard: Needs you, the leads widget, count tiles, "Also here" (2026-09-28) =====
   Existing tokens only, so every brand and both themes carry through. .att is reused for the
   Needs-you rows, but as grid cells: the list-row divider and the hover bleed (negative margins)
   belong to a single-column list and look ragged in a grid, so both are undone here. */
.dash-needs{margin-bottom:16px}
.dash-needs:empty{display:none}
.needs{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px}
.needs .att,.needs .att.is-click{border:1px solid var(--line);border-radius:var(--r);margin:0;padding:10px 12px;background:var(--surface-2);min-height:44px}
.needs .att:last-child{border-bottom:1px solid var(--line)}
.needs .att.is-click:hover{background:var(--surface-3);border-color:rgba(var(--accent-rgb),.4)}
.att__ic--accent{color:var(--accent-ink);background:rgba(var(--accent-rgb),.13)}
@media (max-width:560px){ .needs{grid-template-columns:minmax(0,1fr)} }
.dash-skel{height:44px;border-radius:var(--r);background:var(--surface-3);margin-top:8px}
.dl-body{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:22px;align-items:start}
.dash-bar{padding:4px 8px;margin:0 -8px 4px}
.dash-bar .spread{margin-bottom:5px !important}
/* .sub is only styled inside a page head or a table; the dashboard's own secondary lines need it too. */
.dash-grid .sub,.dash-needs .sub,.dash-also .sub,.set-banner .sub{font-size:12.5px;color:var(--muted)}
.dl-counters{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
.dl-tiles{display:grid;grid-template-columns:repeat(auto-fit,minmax(96px,1fr));gap:10px}
/* A tile's label wraps rather than ending in an ellipsis: "Scanned this week" and "Unopened 3+ days"
   were cut to "Scanned this ..." at common widths. The number sits at the foot, so tiles side by side
   keep their numbers on one line whatever their labels do. */
.dstat{min-width:0;justify-content:space-between}
.dstat span{line-height:1.3;overflow-wrap:break-word}
.dstat.is-click{cursor:pointer;transition:border-color .12s var(--ease),background .12s var(--ease)}
.dstat.is-click:hover{border-color:rgba(var(--accent-rgb),.45);background:var(--surface-3)}
.dstat--red b{color:var(--red)} .dstat--amber b{color:var(--amber)} .dstat--accent b{color:var(--accent-ink)}
.dstat--blue b{color:var(--blue)} .dstat--green b{color:var(--green)}
@media (max-width:760px){ .dl-body{grid-template-columns:minmax(0,1fr);gap:16px} }
.dash-also{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;margin:4px 0 8px;font-size:13px}
.dash-grid [role="link"]:focus-visible,.dash-needs [role="link"]:focus-visible,.dash-also [role="link"]:focus-visible{outline:2px solid rgba(var(--accent-rgb),.6);outline-offset:2px}
/* The line above a list a dashboard card opened: what it is filtered to, and the way out. */
.set-banner{display:flex;align-items:center;flex-wrap:wrap;gap:8px;padding:10px 14px;margin:0 0 12px;border:1px solid rgba(var(--accent-rgb),.35);background:rgba(var(--accent-rgb),.07);border-radius:var(--r);font-size:13px}
.set-banner i{width:15px;height:15px;color:var(--accent-ink);flex:none}
.set-banner__clear{background:none;border:0;padding:0;font:inherit;font-size:13px}

/* ===== Payments Engine cockpit — full-width stack + a manually-balanced 2-col band ===== */
.eng-stack{display:flex;flex-direction:column;gap:16px}
.eng-cols{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
.eng-col{display:flex;flex-direction:column;gap:16px;min-width:0}
@media (max-width:820px){ .eng-cols{grid-template-columns:1fr} }

/* ===== Add-on features shown greyed + locked (2026-07-01) ===== */
.nav__link.is-locked{opacity:.5}
.nav__link.is-locked .nav__lock{margin-left:auto;flex:0 0 auto;width:auto;height:auto;display:inline-flex;align-items:center;opacity:.8}
.is-locked-view{position:relative;min-height:440px}
.is-locked-view > :not(.lockcard){opacity:.4;pointer-events:none;filter:grayscale(.55);user-select:none}
.lockcard{position:absolute;inset:0;display:flex;justify-content:center;align-items:flex-start;padding-top:76px;z-index:40}
.lockcard__box{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:26px 30px;max-width:390px;text-align:center;box-shadow:0 26px 64px rgba(0,0,0,.22)}
.lockcard__ic{display:inline-grid;place-items:center;width:52px;height:52px;border-radius:14px;background:rgba(var(--accent-rgb),.14);color:var(--accent);margin-bottom:12px}
.lockcard__box h3{margin:0 0 6px;font-size:18px;font-weight:800;color:var(--ink)}
.lockcard__box p{margin:0 0 16px;font-size:13.5px;color:var(--muted);line-height:1.55}

/* Catalog cards. The image box keeps a fixed aspect so a grid of products with mixed
   uploads does not turn into a ragged column of different heights. */
.cat__card{overflow:hidden;display:flex;flex-direction:column}
.cat__img{aspect-ratio:16/9;background:var(--surface-3,#f4f4f2);display:flex;align-items:center;justify-content:center;overflow:hidden}
.cat__ph{color:var(--muted,#6b6a64);opacity:.55}

/* ===== Lead map =========================================================================
   Structural only, and deliberately so: every colour here is a token, so the map takes each
   tenant's theme rather than carrying one. A brand value written into this shared file ships that
   brand's identity to every other tenant's bundle, which has happened here before. */
.lm__bar{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:12px}
.lm__chk{display:flex;align-items:center;gap:6px;font-size:13px;color:var(--muted)}
.lm__count{margin-left:auto}
.lm__wrap{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:16px;align-items:start}
@media (max-width:980px){.lm__wrap{grid-template-columns:1fr}}
.lm__map{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  overflow:hidden;min-height:320px;display:flex;align-items:center;justify-content:center}
.lm__svg{width:100%;height:auto;display:block}
.lm__msg{padding:60px 20px;text-align:center}

/* The outline is background, not content: it must never compete with a pin for attention. */
/* THE OUTLINE IS BACKGROUND, NOT THE SUBJECT. This read `var(--ghost)`, which is not a token in
   this stylesheet at all: only `.btn--ghost` exists as a class. An invalid fill in SVG is ignored
   and the default applies, so every state painted solid BLACK and the map became a silhouette with
   the pins lost on top of it. Use tokens that exist, and check. */
/* EVERY STROKE IN THE MAP IS non-scaling-stroke. The SVG is zoomed by moving its viewBox, and a
   stroke-width is a USER unit, so without this a 2.5px label halo becomes 100px on screen at deep
   zoom. That is what turned the city names into white blobs that painted over their neighbours and
   left "Arcad" and "Gl" behind. It is also why the pin outline is not sized in the markup: CSS
   beats a presentation attribute in SVG, so a stroke-width attribute divided by the zoom is
   silently overridden by any rule here. Set stroke widths HERE, and let this keep them honest.
   Locked 2026-09-10; do not revert to per-render arithmetic. */
.lm__land{fill:var(--lm-land);stroke:none}
.lm__ground{fill:var(--lm-land);stroke:none}
.lm__state{fill:none;stroke:var(--lm-border);stroke-width:1.6;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.lm__county{fill:none;stroke:var(--lm-border-2);stroke-width:1;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.lm__road{fill:none;stroke-linejoin:round;stroke-linecap:round;vector-effect:non-scaling-stroke}
.lm__road--i{stroke:var(--lm-road-i);stroke-width:1.7}
.lm__road--us{stroke:var(--lm-road-u);stroke-width:1.2}
.lm__road--st{stroke:var(--lm-road-s);stroke-width:.9}

.lm__pin{cursor:pointer}
/* The soft ring that means "town centre, not a doorway". Same colour as the pin, so it reads as
   the pin's own uncertainty rather than as a second mark, and it never borrows the background. */
.lm__fuzz{opacity:.22}
.lm__dot{stroke:var(--surface);stroke-width:1.5;vector-effect:non-scaling-stroke;transition:transform .12s var(--ease)}
.lm__pin:hover .lm__dot{transform:scale(1.14)}
.lm__pin.is-on .lm__dot{stroke:var(--ink);stroke-width:2.5;vector-effect:non-scaling-stroke}
.lm__n{fill:#fff;font-size:11px;font-weight:700;font-family:var(--num);pointer-events:none}

.lm__side{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}
.lm__sideh{padding:12px 16px;border-bottom:1px solid var(--line);font-weight:600}
.lm__leads{max-height:420px;overflow:auto}
.lm__lead{display:flex;align-items:center;gap:8px;width:100%;padding:10px 16px;background:none;
  border:0;border-bottom:1px solid var(--line);text-align:left;cursor:pointer;font:inherit;color:var(--ink)}
.lm__lead:hover{background:var(--surface-2)}
.lm__leadn{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lm__sw{width:8px;height:8px;border-radius:var(--r-full);flex:none}
.lm__unp{padding:14px 16px;border-top:1px solid var(--line)}
.lm__unph{font-weight:600;margin-bottom:4px}

/* Lead map, phase 2: the toggle, the legend-as-control, the fan-out and the footer. */
.lm__toggle{display:inline-flex;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.lm__tg{padding:6px 14px;background:none;border:0;font:inherit;font-size:13px;color:var(--muted);cursor:pointer}
.lm__tg.is-on{background:var(--ink);color:var(--surface)}
.lm__legend{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.lm__key{display:inline-flex;align-items:center;gap:6px;padding:4px 10px;border:1px solid var(--line);
  border-radius:var(--r-full);background:var(--surface);font:inherit;font-size:12px;color:var(--ink);cursor:pointer}
.lm__key.is-off{opacity:.4}
.lm__key b{font-family:var(--num)}
/* A hollow pin is a town-centre pin. It is the only visual difference between knowing the doorway
   and knowing the town, so it must stay visible in both themes. */
/* SOLID IS A STREET MATCH, HOLLOW IS A TOWN CENTRE, and the difference has to survive at 6px.
   A hollow pin gets a thicker ring and a page-coloured centre rather than `fill:none`, because
   `none` let the map show through and the two read the same from any distance. */
.lm__dot{stroke-width:1.5;vector-effect:non-scaling-stroke;transition:transform .12s var(--ease)}
.lm__tether{stroke:var(--line);stroke-width:1;vector-effect:non-scaling-stroke}
.lm__foot{margin-top:12px;text-align:right}
.lm__lead.is-on{background:var(--surface-3)}

/* Field: territories and the visit log. */
.fld__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
.fld__t{padding:14px}
.fld__zips{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.fld__zip{font-family:var(--num);font-size:12px;padding:2px 7px;border:1px solid var(--line);
  border-radius:var(--r-sm);color:var(--muted)}
.fld__v{display:flex;gap:10px;align-items:flex-start;padding:12px 16px;border-bottom:1px solid var(--line)}
.fld__v:last-child{border-bottom:0}
.fld__dot{width:9px;height:9px;border-radius:var(--r-full);margin-top:5px;flex:none}
.fld__vh{font-weight:600;font-size:14px}

/* Log a visit, from the lead drawer. Sized for a thumb: this is used standing outside a building,
   not at a desk, so the targets are deliberately larger than the surrounding buttons. */
.lv__row{margin-top:2px}
.lv__b{padding:8px 12px;min-height:36px}
.lv__b:disabled{opacity:.5;cursor:default}

/* Map navigation. Controls are visible rather than discovered: a map that only responds to gestures
   nobody was told about reads as a static picture, which is exactly how this one was reported. */
.lm__map{position:relative}
.lm__svg{cursor:grab;touch-action:none}
.lm__svg.is-dragging{cursor:grabbing}
.lm__card{position:absolute;left:12px;top:12px;z-index:3;width:246px;max-width:calc(100% - 88px);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);
  box-shadow:0 8px 24px rgba(0,0,0,.12);padding:12px 12px 10px}
.lm__cardx{position:absolute;right:6px;top:4px;border:0;background:none;cursor:pointer;
  font-size:18px;line-height:1;color:var(--muted);padding:2px 6px}
.lm__cardx:hover{color:var(--ink)}
.lm__cardst{display:flex;align-items:center;gap:6px;font-size:12px;margin-bottom:4px}
/* Capitalise the STATUS only. On the whole row it also hit the plain-English meaning, so
   "close to a decision" came out as "Close To A Decision", which reads like a slogan. */
.lm__cardst b{text-transform:capitalize}
.lm__cardn{font-weight:650;font-size:14px;line-height:1.25;margin-bottom:2px}
.lm__cardm{font-size:12px;color:var(--ink-2);margin-top:6px}
.lm__cardp{margin-top:8px;padding-top:8px;border-top:1px solid var(--line);font-size:11px;line-height:1.45}
.lm__cardb{display:flex;gap:6px;margin-top:10px}
.lm__attrib{position:absolute;right:8px;bottom:6px;z-index:2;font-size:10px;line-height:1.4;
  color:var(--muted);background:color-mix(in srgb,var(--surface) 82%,transparent);
  padding:2px 6px;border-radius:4px;pointer-events:none;max-width:60%;text-align:right}
.lm__zoom{position:absolute;right:12px;top:12px;display:flex;flex-direction:column;gap:4px;z-index:2}
.lm__z{width:30px;height:30px;display:flex;align-items:center;justify-content:center;cursor:pointer;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--r-sm);
  color:var(--ink);font:inherit;font-size:15px;line-height:1;box-shadow:var(--shadow-sm)}
.lm__z:hover{background:var(--surface-2)}
/* Labels never intercept a drag, and never invert when the map is dragged under them. */
.lm__lbl{pointer-events:none;user-select:none}
.lm__lbl--city{fill:var(--ink-2);paint-order:stroke;stroke:var(--surface);stroke-width:2.5;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.lm__citydot{fill:var(--muted);opacity:.55}
.lm__nomark{fill:#fff;opacity:.95;pointer-events:none}
.lm__lbl--city.is-mid{fill:var(--ink);opacity:.92}
.lm__lbl--city.is-major{fill:var(--ink);font-weight:600;letter-spacing:.01em}
.lm__lbl--city.is-primary{fill:var(--ink);font-weight:700;letter-spacing:.015em}
.lm__lbl--near{fill:var(--muted);letter-spacing:.03em;text-transform:uppercase;font-weight:600;opacity:.8}
.lm__lbl--road{fill:var(--lm-road-ink);font-weight:600;letter-spacing:.01em;paint-order:stroke;stroke:var(--lm-land);stroke-width:2.5;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.lm__lbl--state{fill:var(--muted);letter-spacing:.04em;text-transform:uppercase;font-weight:600}
.lm__lbl--town{fill:var(--ink-2);font-weight:600}


/* A build newer than this tab has shipped. Deliberately an offer, not a refresh: a surprise
   reload mid-application would be a worse bug than the stale code it fixes. */
.aq-stale{position:fixed;left:50%;transform:translateX(-50%);bottom:18px;z-index:9999;
  display:flex;align-items:center;gap:12px;padding:10px 12px 10px 16px;
  background:var(--surface);color:var(--ink);border:1px solid var(--line);
  border-radius:var(--r-lg);box-shadow:0 10px 30px rgba(0,0,0,.18);font-size:13px}
.aq-stale button{border:0;border-radius:6px;padding:6px 12px;font:inherit;font-weight:600;
  cursor:pointer;background:var(--ink);color:var(--surface)}
.aq-stale button:hover{opacity:.88}

/* ===== Support session banner =============================================================
   Somebody from the platform team is signed in here AS one of this workspace's people. The bar says
   so on every screen, cannot be dismissed, and is deliberately NOT the brand's colour: a fixed amber
   that no tenant theme overrides, so nobody mistakes the session for an ordinary sign-in.

   IT TAKES ITS OWN HEIGHT IN THE FLOW (sticky, not fixed) and the pieces that stick to the top of the
   viewport move down by exactly that much, so nothing on a screen is hidden behind it. */
body.aq-support{--aq-sup-h:40px}   /* the fallback; support-session.js sets the measured height, which wraps on a phone */
.aq-support-bar{position:sticky;top:0;z-index:100000;min-height:40px;display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:6px 16px;
  padding:7px 14px;background:#b45309;color:#fff;font:500 13px/1.35 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;
  box-shadow:0 2px 8px rgba(0,0,0,.25)}
.aq-support-bar__text{min-width:0;overflow-wrap:anywhere}
.aq-support-bar__end{flex:0 0 auto;border:1px solid rgba(255,255,255,.85);background:transparent;color:#fff;border-radius:6px;
  padding:4px 12px;font:inherit;font-weight:700;cursor:pointer}
.aq-support-bar__end:hover{background:#fff;color:#7c2d12}
body.aq-support .sidebar{top:var(--aq-sup-h);height:calc(100vh - var(--aq-sup-h))}
body.aq-support .topbar{top:var(--aq-sup-h)}
body.aq-support .drawer{top:var(--aq-sup-h);height:calc(100vh - var(--aq-sup-h))}
@media (max-width:760px){
  .aq-support-bar{font-size:12px;padding:6px 12px;justify-content:space-between}
}

/* ===== Site survey =======================================================================
   Filled in on a phone, at a door, which is what every rule below is for.

   IT DOES NOT USE `.kv`, DELIBERATELY. That class is `display:flex` with the label and value on
   one line, which is right for a label and a SHORT VALUE and wrong for a full-width input: at
   390px it squeezed the address field to half the screen and clipped both textareas mid-sentence.
   Widening `.kv` itself would have been the cheap fix and the wrong one, because every other
   screen in this app uses it and a global change means re-checking all of them.

   Stacked by default, side by side from 760px up. A phone is a different layout, not a narrower
   copy of the desktop one. */
.sv__field{display:flex;flex-direction:column;gap:6px;padding:10px 0;border-bottom:1px solid var(--line-2);font-size:13px}
.sv__field:last-child{border-bottom:none}
.sv__field > span{color:var(--muted)}
.sv__field .inp,.sv__field textarea.inp,.sv__field select.inp{width:100%;box-sizing:border-box}
/* A textarea is not 40px tall. `.inp` fixes the height for single-line fields, so it is released
   here or the notes box shows one and a half lines of a four-line answer. */
.sv__field textarea.inp{height:auto;min-height:96px;padding:10px 12px;line-height:1.5;font:inherit;resize:vertical}

/* THUMB-SIZED, AND EVEN. `flex:1` splits the three findings equally so "N/A" is as easy to hit as
   "Yes", and 44px is the smallest target Apple's own guidance accepts. Before this, the longest
   label wrapped inside its own button. */
.sv__seg{width:100%}
.sv__seg button{flex:1;min-height:44px;white-space:nowrap}
.sv__check{padding:12px 0;border-bottom:1px solid var(--line-2)}
.sv__check:last-child{border-bottom:none}
.sv__checkLabel{margin-bottom:8px}

@media (min-width:760px){
  .sv__field{flex-direction:row;align-items:center;justify-content:space-between;gap:12px}
  .sv__field > span{flex:0 0 160px}
  .sv__field .inp,.sv__field textarea.inp,.sv__field select.inp{max-width:60%}
  .sv__check{display:flex;align-items:center;justify-content:space-between;gap:16px}
  .sv__checkLabel{margin-bottom:0}
  .sv__seg{width:auto;flex:0 0 240px}
}
