/* Pro-Fit CRM design system.
   Structure and component shapes are carried over from prototype/honeys-crm.html.
   The palette is not: it is rebuilt on the two printed brand colours.

   BRAND
     #004A51  deep      --accent-2
     #18978D  teal      --brand-teal, large fills only
     #12766E  teal dark --accent, the only teal allowed to carry small text
   There is no amber and no orange in this brand, so the prototype's --energy
   token is gone. Every neutral below is a desaturated derivative of the deep.

   ONE FUNCTIONAL COLOUR IS NOT BRAND: --bad. A missed five minute standard has to
   read as wrong at a glance and no shade of teal does that. It is used only for
   error and overdue states, never for decoration. "Warn" is the deep brand colour
   rather than amber, and every state carries a text label as well as a colour, so
   nothing in this interface is distinguished by hue alone.

   CONTRAST, measured against the real background each token sits on:
     text on surface 16.5:1, text-2 8.0:1, text-3 on surface-2 4.9:1,
     accent on surface 5.5:1, accent-ink on accent 5.5:1, bad on surface 7.2:1.
   White on --brand-teal is 3.6:1, which is why --brand-teal fills bars and the
   26px brand mark and never sets body text.

   No webfonts: system stack only, so the app has no external network call. */

:root {
  --bg: #F1F5F4;
  --surface: #FFFFFF;
  --surface-2: #E8EFEE;
  --surface-3: #DCE6E4;
  --line: #D3DEDC;
  --line-strong: #B4C4C1;
  --text: #0F2225;
  --text-2: #3F5457;
  --text-3: #546B6E;

  --brand-teal: #18978D;
  --accent: #12766E;
  --accent-2: #004A51;
  --accent-ink: #FFFFFF;
  --accent-soft: #DCEDEB;

  --good: #12766E;
  --good-soft: #DCEDEB;
  --warn: #004A51;
  --warn-soft: #DEE8E9;
  --bad: #A32B20;
  --bad-soft: #F8E4E1;

  --shadow: 0 1px 2px rgba(15, 34, 37, .06), 0 8px 24px -12px rgba(15, 34, 37, .2);
  --radius: 12px;
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --display: var(--sans);
  --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
  --rail-w: 216px;

  /* Type scale. The old sheet set sizes ad hoc, so headings and body sat too
     close and everything read as one weight. A 1.2 ratio keeps a dense tool
     readable without shouting. */
  --fs-micro: 11px;
  --fs-small: 12.5px;
  --fs-body:  14px;
  --fs-lead:  16px;
  --fs-h3:    18px;
  --fs-h2:    22px;
  --fs-h1:    27px;
  --fs-metric: clamp(26px, 2.6vw, 34px);
  --fs-hero:   clamp(28px, 3.1vw, 40px);

  /* Spacing. One rhythm, so cards and rails line up down the page. */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 24px; --sp-6: 32px; --sp-7: 48px;

  --radius-sm: 8px;
  --radius-lg: 18px;
  --radius-pill: 999px;

  /* Elevation. Flat by default: a data tool with a shadow on every card reads
     as noise. Level 2 is for things that genuinely float. */
  --e1: 0 1px 2px rgba(15, 34, 37, .05);
  --e2: 0 2px 4px rgba(15, 34, 37, .06), 0 12px 28px -14px rgba(15, 34, 37, .28);

  /* Glass. Used in exactly one place, the estimator price, because glass needs a
     vivid ground to read as glass and a data table is not one. */
  --glass-ground: linear-gradient(135deg, #12766E 0%, #00363B 100%);
  --glass-tint: rgba(0, 40, 44, .18);
  --glass-edge: rgba(255, 255, 255, .25);
  --glass-blur: blur(14px) saturate(160%);
  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0A1112;
    --surface: #111A1B;
    --surface-2: #182325;
    --surface-3: #202D2F;
    --line: #233133;
    --line-strong: #35474A;
    --text: #E3EDEC;
    --text-2: #A6B9BA;
    --text-3: #8AA0A2;
    --brand-teal: #4FC3B8;
    --accent: #4FC3B8;
    --accent-2: #7FD8CE;
    --accent-ink: #062725;
    --accent-soft: #0D2C2B;
    --good: #4FC3B8;
    --good-soft: #0D2C2B;
    --warn: #9FD3D6;
    --warn-soft: #14282A;
    --bad: #F0A79B;
    --bad-soft: #2C1512;
    --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 28px -14px rgba(0, 0, 0, .75);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #0A1112;
  --surface: #111A1B;
  --surface-2: #182325;
  --surface-3: #202D2F;
  --line: #233133;
  --line-strong: #35474A;
  --text: #E3EDEC;
  --text-2: #A6B9BA;
  --text-3: #8AA0A2;
  --brand-teal: #4FC3B8;
  --accent: #4FC3B8;
  --accent-2: #7FD8CE;
  --accent-ink: #062725;
  --accent-soft: #0D2C2B;
  --good: #4FC3B8;
  --good-soft: #0D2C2B;
  --warn: #9FD3D6;
  --warn-soft: #14282A;
  --bad: #F0A79B;
  --bad-soft: #2C1512;
  --shadow: 0 1px 2px rgba(0, 0, 0, .45), 0 10px 28px -14px rgba(0, 0, 0, .75);
  color-scheme: dark;
}

/* ---------------- base ---------------- */
* { box-sizing: border-box; }

html, body { max-width: 100%; overflow-x: hidden; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

h1, h2, h3, h4 { font-family: var(--display); margin: 0; letter-spacing: -.01em; text-wrap: balance; }
p { margin: 0; }
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent); }
img, svg, canvas { max-width: 100%; }
[hidden] { display: none !important; }

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

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

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ---------------- shell ---------------- */
.app { display: grid; grid-template-columns: var(--rail-w) 1fr; min-height: 100vh; }

.rail {
  background: var(--surface);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 14px 10px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
  min-width: 0;
}

.brand { display: flex; align-items: center; gap: 9px; padding: 4px 8px 14px; }
.mark {
  width: 28px; height: 28px; border-radius: 8px;
  background: var(--brand-teal); color: #FFFFFF;
  display: grid; place-items: center;
  font-family: var(--display); font-weight: 700; font-size: 13px; letter-spacing: .02em;
  flex: none;
}
:root[data-theme="dark"] .mark,
:root:not([data-theme="light"]) .mark { color: var(--accent-ink); }
.brand b { font-family: var(--display); font-size: 16px; font-weight: 700; letter-spacing: -.02em; display: block; }
.brand small {
  display: block; color: var(--text-3); font-size: 10px;
  letter-spacing: .1em; text-transform: uppercase; font-weight: 700; margin-top: -1px;
}

.nav { display: flex; flex-direction: column; gap: 1px; }
.navgroup {
  font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--text-3); font-weight: 700; padding: 15px 10px 5px;
}
.navgroup.first { padding-top: 2px; }
.nav button {
  display: flex; align-items: center; gap: 9px; width: 100%; text-align: left;
  background: none; border: 0; padding: 9px 10px; border-radius: 8px;
  color: var(--text-2); cursor: pointer; font-weight: 600; font-size: 13.5px;
  min-width: 0;
}
.nav button:hover { background: var(--surface-2); color: var(--text); }
.nav button[aria-current="page"] { background: var(--accent-soft); color: var(--accent-2); }
.nav button .lab { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav .ico {
  width: 17px; height: 17px; flex: none;
  stroke: currentColor; fill: none; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round;
}
.nav .cnt {
  margin-left: auto; font-family: var(--mono); font-size: 11px; font-weight: 700;
  color: var(--accent-2); background: var(--accent-soft);
  border-radius: 20px; padding: 0 6px; line-height: 17px; flex: none;
}
.rail-foot {
  margin-top: auto; padding: 12px 8px 2px; border-top: 1px solid var(--line);
  color: var(--text-3); font-size: 11.5px; display: flex; flex-direction: column; gap: 6px;
}
.rail-foot button {
  background: none; border: 0; color: var(--text-3); cursor: pointer;
  padding: 3px 0; font-size: 11.5px; text-align: left; font-weight: 600;
}
.rail-foot button:hover { color: var(--text); }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  display: flex; align-items: center; gap: 10px; padding: 13px 24px;
  border-bottom: 1px solid var(--line); background: var(--surface);
  position: sticky; top: 0; z-index: 20; flex-wrap: wrap; min-width: 0;
}
.topbar .titles { min-width: 0; flex: 1 1 220px; }
.topbar h1 { font-size: 20px; font-weight: 700; }
.topbar #viewSub { color: var(--text-3); font-size: 12.5px; }
.topbar .tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.search { position: relative; }
.search input {
  width: 210px; max-width: 46vw; padding: 7px 10px 7px 30px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg);
}
.search svg {
  position: absolute; left: 9px; top: 9px; width: 15px; height: 15px;
  stroke: var(--text-3); fill: none; stroke-width: 1.8; pointer-events: none;
}

.actorpick { display: flex; align-items: center; gap: 6px; }
.actorpick select {
  padding: 6px 8px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--bg); font-size: 12.5px; font-weight: 600; max-width: 150px;
}
.actorpick.unconfirmed select { border-color: var(--bad); }
.av {
  width: 26px; height: 26px; border-radius: 50%; background: var(--accent-soft); color: var(--accent-2);
  display: grid; place-items: center; font-size: 10.5px; font-weight: 700; flex: none;
  font-family: var(--display);
}

.storestate {
  font-size: 11.5px; color: var(--text-2); background: var(--surface-2);
  border-radius: 20px; padding: 3px 10px; white-space: nowrap; font-weight: 600;
}
.savepip { font-size: 11px; color: var(--text-3); font-family: var(--mono); min-width: 52px; }

.view { padding: 24px 26px 44px; flex: 1; min-width: 0; }
.view[hidden] { display: none !important; }

/* Permanent, not dismissible, when nothing is being written anywhere. */
.nopersist {
  background: var(--bad-soft); color: var(--bad); font-weight: 600; font-size: 12.5px;
  padding: 9px 24px; border-bottom: 1px solid var(--line);
}

/* ---------------- generic components ---------------- */
.btn {
  border: 1px solid var(--line-strong); background: var(--surface);
  padding: 8px 13px; border-radius: 8px; cursor: pointer; font-weight: 600; font-size: 13px;
  display: inline-flex; align-items: center; gap: 6px;
}
.btn:hover { border-color: var(--text-3); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover:not(:disabled) { background: var(--accent-2); border-color: var(--accent-2); color: #FFFFFF; }
:root[data-theme="dark"] .btn.primary:hover:not(:disabled),
:root:not([data-theme="light"]) .btn.primary:hover:not(:disabled) { color: var(--accent-ink); }
.btn.ghost { border-color: transparent; background: none; color: var(--text-2); }
.btn.ghost:hover { background: var(--surface-2); color: var(--text); }
.btn.danger { border-color: var(--bad); color: var(--bad); }
.btn.sm { padding: 5px 10px; font-size: 12px; }

.seg { display: flex; background: var(--surface-2); border-radius: 8px; padding: 2px; gap: 2px; }
.seg button {
  border: 0; background: none; padding: 6px 11px; border-radius: 6px; cursor: pointer;
  font-size: 12.5px; font-weight: 600; color: var(--text-2);
}
.seg button[aria-pressed="true"] { background: var(--surface); color: var(--text); box-shadow: 0 1px 2px rgba(0, 0, 0, .12); }

.panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.panel > header { display: flex; align-items: baseline; gap: 8px; padding: 14px 18px 12px; border-bottom: 1px solid var(--line); flex-wrap: wrap; }
.panel > header h2 { font-size: 14.5px; font-weight: 700; }
.panel > header .hint { font-size: 12px; color: var(--text-3); margin-left: auto; }
.panel .body { padding: 16px 18px 18px; }
.panel + .panel { margin-top: 16px; }

.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(176px, 1fr)); gap: 14px; }
.kpi {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 15px 17px 16px; display: flex; flex-direction: column; gap: 3px; min-width: 0;
}
.kpi .lab { font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.kpi .val { font-family: var(--display); font-size: 27px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.kpi .note { font-size: 12px; color: var(--text-2); }

.grid2 { display: grid; grid-template-columns: 1.35fr 1fr; gap: 16px; margin-top: 16px; align-items: start; min-width: 0; }
.colstack { display: flex; flex-direction: column; gap: 16px; min-width: 0; }
@media (max-width: 1080px) { .grid2 { grid-template-columns: 1fr; } }

.pill {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11.5px; font-weight: 600;
  padding: 2px 9px; border-radius: 20px; white-space: nowrap;
}
.pill.good { background: var(--good-soft); color: var(--good); }
.pill.warn { background: var(--warn-soft); color: var(--warn); }
.pill.bad { background: var(--bad-soft); color: var(--bad); }
.pill.neutral { background: var(--surface-2); color: var(--text-2); }
.pill.accent { background: var(--accent-soft); color: var(--accent-2); }
.pill .g { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }

.tag {
  font-size: 10.5px; font-weight: 600; padding: 1px 7px; border-radius: 5px;
  background: var(--surface-2); color: var(--text-2); border: 1px solid var(--line);
}
.chip {
  font-size: 11.5px; padding: 3px 9px; border-radius: 20px;
  background: var(--surface-2); border: 1px solid var(--line); cursor: pointer;
}
.chip:hover { border-color: var(--line-strong); }
.empty { color: var(--text-3); font-size: 12.5px; }
.banner {
  display: flex; gap: 9px; align-items: center; padding: 10px 14px; border-radius: 9px;
  background: var(--warn-soft); color: var(--warn); font-size: 12.5px; margin-bottom: 14px; font-weight: 600;
}
.banner.bad { background: var(--bad-soft); color: var(--bad); }
.disclaimer { font-size: 11.5px; color: var(--text-3); margin-top: 8px; max-width: 62ch; }

.toolbar { display: flex; gap: 8px; align-items: center; margin-bottom: 14px; flex-wrap: wrap; }
.toolbar select, .toolbar input[type="text"], .toolbar input[type="search"] {
  padding: 7px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
}

/* forms */
.fields { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
.fields.one { grid-template-columns: 1fr; }
.f { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.f > span, .f > label { font-size: 11.5px; color: var(--text-3); font-weight: 600; }
.f input, .f select, .f textarea {
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--bg); width: 100%;
}
.f input:hover, .f select:hover { border-color: var(--line-strong); }
.f textarea { resize: vertical; min-height: 64px; font-family: var(--sans); }
.f.mono input { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.check { display: flex; align-items: flex-start; gap: 9px; padding: 9px 0; border-top: 1px solid var(--line); }
.check:first-of-type { border-top: 0; }
.check input { margin-top: 3px; width: 16px; height: 16px; accent-color: var(--accent); flex: none; }
/* The name and its hint stack. Left inline they ran together, so every consent
   control read as one unbroken string of words. */
.check > span { min-width: 0; }
.check .t { display: block; font-size: 13px; font-weight: 600; }
.check .d { display: block; font-size: 11.5px; color: var(--text-3); margin-top: 1px; }
.f.is-off { opacity: .5; }
.f .ro {
  padding: 8px 10px; border: 1px dashed var(--line); border-radius: 8px;
  background: var(--surface-2); color: var(--text-2); font-size: 13px;
}
.f .ro-note { font-size: 11px; color: var(--text-3); }
.actorpick #actorConfirm { white-space: nowrap; }
/* A select sizes itself to its widest option, so a long price book line pushed it
   past the viewport on a phone. Nothing in a toolbar may be wider than its row. */
.toolbar > * { min-width: 0; max-width: 100%; }
.toolbar select { max-width: 100%; }

.readout {
  display: flex; flex-wrap: wrap; gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden; margin-top: 12px;
}
.readout > div { flex: 1 1 112px; background: var(--surface-2); padding: 10px 12px; min-width: 0; }
.readout .k { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.readout .v { font-family: var(--mono); font-size: 15px; margin-top: 1px; font-variant-numeric: tabular-nums; }

/* tables: the only element allowed to scroll sideways, and only inside its wrapper */
.tablewrap {
  overflow-x: auto; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); -webkit-overflow-scrolling: touch;
}
table { border-collapse: collapse; width: 100%; }
.tablewrap table { min-width: 880px; }
th {
  text-align: left; font-size: 10px; letter-spacing: .09em; text-transform: uppercase;
  color: var(--text-3); font-weight: 700; padding: 11px 14px;
  border-bottom: 1px solid var(--line); white-space: nowrap; background: var(--surface);
}
td { padding: 12px 14px; border-bottom: 1px solid var(--line); vertical-align: middle; font-size: 13px; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: var(--surface-2); }
td.num { font-family: var(--mono); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
td .co { font-weight: 600; }
td .sm { font-size: 11.5px; color: var(--text-3); }

/* board */
.board { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; align-items: flex-start; }
.col {
  flex: 0 0 266px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); display: flex; flex-direction: column; max-height: calc(100vh - 200px);
}
.col.over { outline: 2px dashed var(--accent); outline-offset: -2px; }
.col > header { padding: 11px 13px 8px; display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.col h3 { font-size: 12.5px; font-weight: 700; }
.col header .std { font-family: var(--mono); font-size: 10px; color: var(--text-3); display: block; font-weight: 400; width: 100%; }
.col .n { font-family: var(--mono); font-size: 11px; color: var(--text-3); }
.col .sum { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--text-2); font-variant-numeric: tabular-nums; }
.stagebar { height: 3px; border-radius: 2px; margin: 0 13px; background: var(--brand-teal); }
.cards { padding: 10px; display: flex; flex-direction: column; gap: 9px; overflow-y: auto; }
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  padding: 11px 12px; box-shadow: 0 1px 1px rgba(15, 34, 37, .04); text-align: left; width: 100%;
}
.card:hover { border-color: var(--line-strong); }
.card.dragging { opacity: .45; }
.card .co { font-weight: 700; font-size: 13.5px; line-height: 1.3; }
.card .addr { font-size: 11.5px; color: var(--text-3); margin-top: 1px; }
.card .row { display: flex; align-items: center; gap: 6px; margin-top: 8px; flex-wrap: wrap; }
.card .val { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }
.card .foot {
  display: flex; align-items: center; gap: 6px; margin-top: 9px; padding-top: 8px;
  border-top: 1px solid var(--line); font-size: 11.5px; color: var(--text-3);
}
.card .av { width: 20px; height: 20px; font-size: 9.5px; }
.card .sla { font-family: var(--mono); font-size: 10.5px; padding: 1px 6px; border-radius: 5px; }
.card .sla.ok { background: var(--good-soft); color: var(--good); }
.card .sla.miss { background: var(--bad-soft); color: var(--bad); }
.card .sla.wait { background: var(--warn-soft); color: var(--warn); }
.due { margin-left: auto; font-family: var(--mono); font-size: 11px; }
.due.over { color: var(--bad); font-weight: 600; }

/* the five minute rule strip */
.golden {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap; background: var(--surface);
  border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--radius); padding: 13px 17px; margin-bottom: 16px;
}
.golden .rule { font-family: var(--display); font-weight: 600; font-size: 13.5px; }
.golden .rule em { font-style: normal; color: var(--accent); font-weight: 700; }
.golden .clock { margin-left: auto; display: flex; gap: 16px; align-items: center; }
.golden .clock div { text-align: right; }
.golden .clock .k { font-size: 10px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.golden .clock .v { font-family: var(--mono); font-size: 14px; font-variant-numeric: tabular-nums; }

/* ---------------- drawer ---------------- */
#scrim {
  position: fixed; inset: 0; background: rgba(6, 18, 20, .45); z-index: 40;
  opacity: 0; pointer-events: none; transition: opacity .18s;
}
#scrim.on { opacity: 1; pointer-events: auto; }
.drawer {
  position: fixed; top: 0; right: 0; height: 100vh; width: min(580px, 100vw);
  background: var(--surface); border-left: 1px solid var(--line); z-index: 50;
  transform: translateX(102%); transition: transform .22s ease;
  display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.drawer.on { transform: none; }
.drawer[hidden] { display: none !important; }
#drawerHead { padding: 16px 18px 13px; border-bottom: 1px solid var(--line); }
#drawerHead .top { display: flex; align-items: flex-start; gap: 10px; }
#drawerHead h2 { font-size: 18px; font-weight: 700; flex: 1; min-width: 0; }
#drawerHead .ref { font-family: var(--mono); font-size: 11.5px; color: var(--text-3); }
#drawerHead .meta { display: flex; gap: 7px; flex-wrap: wrap; margin-top: 9px; align-items: center; }
#drawerTabs { display: flex; gap: 2px; padding: 0 14px; border-bottom: 1px solid var(--line); overflow-x: auto; }
#drawerTabs button {
  background: none; border: 0; padding: 10px 12px; cursor: pointer; font-weight: 600;
  font-size: 13px; color: var(--text-3); border-bottom: 2px solid transparent; white-space: nowrap;
}
#drawerTabs button[aria-selected="true"] { color: var(--text); border-bottom-color: var(--accent); }
#drawerBody { overflow-y: auto; padding: 14px 16px 44px; flex: 1; }
#drawerBody section { background: var(--surface-2); border-radius: var(--radius); padding: 14px 15px; margin-bottom: 14px; }
#drawerBody h3 {
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--text-3);
  font-weight: 700; margin: 0 0 11px; padding-bottom: 8px; border-bottom: 1px solid var(--line);
}
#drawerBody .f input, #drawerBody .f select, #drawerBody .f textarea { background: var(--surface); }
#drawerBody .readout { background: var(--line); }
#drawerBody .readout > div { background: var(--surface); }

/* ---------------- toasts, modal, errors ---------------- */
.toasts {
  position: fixed; right: 18px; bottom: 18px; display: flex; flex-direction: column;
  gap: 9px; z-index: 60; width: min(340px, calc(100vw - 36px));
}
.toast {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: 10px; box-shadow: var(--shadow); padding: 11px 13px; animation: pop .18s ease-out;
}
.toast.urgent { border-left-color: var(--bad); }
.toast .h { font-family: var(--display); font-weight: 700; font-size: 13px; }
.toast .b { font-size: 12.5px; color: var(--text-2); margin-top: 2px; }
.toast .a { display: flex; gap: 6px; margin-top: 9px; flex-wrap: wrap; }
.toast .x { position: absolute; }
@keyframes pop { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }

.modal {
  position: fixed; inset: 0; z-index: 70; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: rgba(6, 18, 20, .55);
}
.modal[hidden] { display: none !important; }
.sheet {
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  width: min(520px, 100%); max-height: 88vh; display: flex; flex-direction: column; box-shadow: var(--shadow);
}
.sheet > header { padding: 16px 18px 12px; border-bottom: 1px solid var(--line); }
.sheet > header h2 { font-size: 17px; font-weight: 700; }
.sheet .ibody { padding: 16px 18px; overflow-y: auto; }
.sheet > footer { padding: 12px 18px; border-top: 1px solid var(--line); display: flex; gap: 8px; justify-content: flex-end; }

/* Shown by the shell when a feature module throws or has not been written yet.
   One broken module must never blank the application. */
.modpanel {
  background: var(--surface); border: 1px solid var(--line-strong); border-left: 3px solid var(--bad);
  border-radius: var(--radius); padding: 18px 20px; max-width: 62ch;
}
.modpanel h2 { font-size: 16px; font-weight: 700; margin-bottom: 6px; }
.modpanel p { font-size: 13px; color: var(--text-2); margin-bottom: 8px; max-width: 60ch; }
.modpanel pre {
  font-family: var(--mono); font-size: 11.5px; color: var(--text-2); background: var(--surface-2);
  border-radius: 8px; padding: 10px 12px; overflow-x: auto; margin: 0; white-space: pre-wrap; word-break: break-word;
}

/* ---------------- responsive ----------------
   Verified at 1440, 1024, 834 and 390. 834 is the in-home iPad and is a hard
   client requirement, so the rail collapses to a horizontal strip above it. */
@media (max-width: 1024px) {
  :root { --rail-w: 188px; }
  .view { padding: 20px 20px 40px; }
  .topbar { padding: 12px 20px; }
}

@media (max-width: 900px) {
  /* Rows are named explicitly: a one-column grid with min-height 100vh would
     otherwise split the viewport evenly and leave the collapsed rail floating in
     half a screen of nothing. */
  .app { grid-template-columns: 1fr; grid-template-rows: auto 1fr; }
  .rail {
    position: static; height: auto; flex-direction: row; align-items: center;
    overflow-x: auto; border-right: 0; border-bottom: 1px solid var(--line); padding: 8px 10px;
  }
  .brand { padding: 0 12px 0 4px; flex: none; }
  .nav { flex-direction: row; gap: 4px; }
  .nav button { width: auto; white-space: nowrap; padding: 8px 11px; }
  .navgroup { display: none; }
  .rail-foot { display: none; }
  .view { padding: 16px 16px 40px; }
  .topbar { padding: 12px 16px; }
  .nopersist { padding: 9px 16px; }
  .drawer { width: 100vw; }
}

@media (max-width: 560px) {
  .topbar { gap: 8px; }
  .topbar .tools { width: 100%; }
  .search { flex: 1 1 auto; }
  .search input { width: 100%; max-width: none; }
  .fields { grid-template-columns: 1fr; }
  .kpis { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
  .view { padding: 14px 14px 36px; }
  .col { flex-basis: 82vw; }
  .toasts { right: 12px; left: 12px; width: auto; }
}

@media print {
  .rail, .topbar, .drawer, #scrim, .toasts, .modal { display: none !important; }
  body { background: #FFFFFF; }
  .app { display: block; }
}

/* ---- estimator and price card -------------------------------------------
   The estimator is the tool a salesperson holds in a customer's living room,
   so the price is deliberately the largest thing on the screen and the gate
   sits directly under it rather than below a scroll. */
.est-in .f { margin-bottom: 12px; }
.chiprow { display: flex; flex-wrap: wrap; gap: 6px; }
.chiprow .chip { cursor: pointer; border: 1px solid var(--line); background: var(--surface); }
.chiprow .chip.is-on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); font-weight: 600; }
.est-out .eyebrow { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); font-weight: 700; margin: 0 0 4px; }
.est-figure { font-family: var(--display); font-size: clamp(28px, 4vw, 42px); font-weight: 700; letter-spacing: -.03em; line-height: 1.05; margin: 0 0 6px; font-variant-numeric: tabular-nums; }
.est-figure .to { font-size: .4em; font-weight: 500; color: var(--text-3); letter-spacing: 0; }
.est-sub { margin: 0 0 12px; color: var(--text-2); font-size: 13.5px; }
.est-lines { width: 100%; border-collapse: collapse; font-size: 13.5px; margin-bottom: 12px; }
.est-lines td { padding: 7px 0; border-bottom: 1px solid var(--line); }
.est-lines td.n { text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
.est-gate { border: 1px dashed var(--line-strong); border-radius: var(--radius); padding: 10px 12px; background: var(--surface-2); }
.est-gate.is-ok { border-style: solid; border-color: var(--accent); background: var(--accent-soft); }
.est-gate .check { border-top: 0; padding: 0; font-weight: 600; font-size: 13.5px; }
.est-gate p { margin: 6px 0 0 25px; font-size: 11.5px; color: var(--text-3); }
.est-actions { display: flex; gap: 8px; margin-top: 12px; }
.est-actions .btn[disabled] { opacity: .45; cursor: not-allowed; }
.est-notes { margin: 12px 0 0; padding-left: 18px; }
.est-notes li { margin-bottom: 4px; }
.est-out.is-empty { color: var(--text-3); }

.card-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; align-items: start; }
/* Without this a grid track is min-content wide, so a table that will not fit
   pushes the whole page past the viewport, and body{overflow-x:hidden} then clips
   it with no scrollbar to reach it with. */
.card-grid > * { min-width: 0; }
.card-grid .wide { grid-column: 1 / -1; }
@media (max-width: 1080px) { .card-grid { grid-template-columns: 1fr; } }

/* Inside a card the wrapper is a scroll container and nothing else: the card
   already draws the border and the background. */
.card .tablewrap { border: 0; background: none; border-radius: 0; }
.card .tablewrap + .cat { margin-top: 18px; }
.card .tablewrap table { min-width: 0; }
.card .tablewrap table.tbl { min-width: 320px; }
/* The generic th is a nowrap uppercase column heading. A .tbl row header is a
   label with a sentence of help under it, so it has to wrap: left nowrap its
   min-content width pushed the Now and Change columns off the card entirely. */
.tbl th[scope="row"] {
  white-space: normal; text-transform: none; letter-spacing: normal;
  font-size: 13px; color: var(--text); background: none; padding: 9px 10px 9px 0;
}
.tbl th[scope="row"] small { white-space: normal; max-width: 46ch; }
.tbl thead th { padding: 9px 10px 9px 0; background: none; }
.tbl td { padding: 9px 0 9px 10px; }
.tbl td.n, .tbl th.n { white-space: nowrap; }
.tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
.tbl th, .tbl td { padding: 8px 6px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.tbl th[scope="row"] { font-weight: 600; }
.tbl th[scope="row"] small { display: block; font-weight: 400; color: var(--text-3); font-size: 11.5px; margin-top: 2px; }
.tbl td.n, .tbl th.n { text-align: right; font-variant-numeric: tabular-nums; }
.tbl td.u { color: var(--text-3); font-size: 11.5px; white-space: nowrap; }
.tbl input { width: 92px; padding: 5px 7px; border: 1px solid var(--line); border-radius: 6px; background: var(--bg); text-align: right; font-variant-numeric: tabular-nums; }
.knobs td.n:first-of-type { color: var(--text-2); font-weight: 600; }
.cat { font-size: 11px; letter-spacing: .07em; text-transform: uppercase; color: var(--text-3); margin: 16px 0 4px; }
.warn-inline { font-size: 12px; color: var(--warn); background: var(--warn-soft); border-radius: 8px; padding: 8px 10px; margin: 0 0 10px; }
.muted { color: var(--text-3); font-size: 12.5px; margin: 0 0 12px; }

/* ============================================================================
   Visual system pass, 5 September 2026.

   Reference: three CRM dashboards on Dribbble that all converge on the same
   shape. A tight KPI row where every metric carries a delta against its target,
   one dominant chart, a narrower supporting column, and heavy restraint: one
   accent, everything else neutral. Our palette is already two teals, so the
   restraint is free.

   The previous dashboard failed on density rather than taste. Five large cards
   each saying "no data" and a metrics table written in full sentences read as
   documentation, not as something you scan on a Monday morning.
   ========================================================================== */

/* ---- KPI row: smaller, tighter, and each one carries its delta ---- */
.kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); gap: var(--sp-3); }
/* There are five headline numbers, and auto-fit left the fifth stranded alone on
   its own row at tablet width, which reads as a mistake rather than a layout.
   Three then two is deliberate and looks it. 834px is the client's iPad, so this
   is the width that matters most. */
@media (max-width: 1180px) and (min-width: 561px) {
  .kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 560px) { .kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.kpi { padding: var(--sp-4); gap: var(--sp-1); border-radius: var(--radius); box-shadow: var(--e1); }
.kpi .lab { font-size: var(--fs-micro); letter-spacing: .06em; text-transform: uppercase; color: var(--text-3); font-weight: 700; }
.kpi .val { font-size: var(--fs-metric); font-weight: 700; letter-spacing: -.02em; line-height: 1.05; font-variant-numeric: tabular-nums; }
.kpi .note { font-size: var(--fs-small); color: var(--text-3); }
.kpi .val.is-empty { font-size: var(--fs-h3); font-weight: 600; color: var(--text-3); letter-spacing: 0; }

/* The delta chip. Never colour alone: every chip carries an arrow and a word,
   so it survives greyscale and colour blindness. */
.delta { display: inline-flex; align-items: center; gap: 4px; font-size: var(--fs-micro);
  font-weight: 700; padding: 2px 7px; border-radius: var(--radius-pill); white-space: nowrap; }
.delta.up   { background: var(--good-soft); color: var(--good); }
.delta.down { background: var(--bad-soft);  color: var(--bad); }
.delta.flat { background: var(--surface-2); color: var(--text-3); }

/* ---- Type rhythm ---- */
.view h2 { font-size: var(--fs-h2); letter-spacing: -.015em; }
.view h3 { font-size: var(--fs-h3); letter-spacing: -.01em; }
.card > h2:first-child, .card > h3:first-child { margin-top: 0; }

/* ---- The estimator hero. The one place glass belongs. -------------------
   Glass reads as glass only over a vivid ground, so the price sits on a teal
   gradient rather than on the page. The number is display scale and white,
   which clears contrast on both ends of the gradient.

   The gradient runs #12766E to #00363B rather than starting on the brand teal
   #18978D, and that is a contrast decision rather than a taste one: measured
   against the light end, white 11px sat at 2.91:1 and white 14px at 3.14:1,
   both short of 4.5. Darkening the light stop fixes the whole surface instead
   of shrinking or repositioning the text. The pane tint is a dark scrim rather
   than the usual white one for the same reason: on a light ground a white tint
   raises luminance exactly where the small text needs it lowered. */
.est-hero { position: relative; border-radius: var(--radius-lg); overflow: hidden;
  background: var(--glass-ground); padding: var(--sp-5); color: #fff; box-shadow: var(--e2); }
.est-hero::before { content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 90% at 12% 0%, rgba(255,255,255,.22), transparent 60%); pointer-events: none; }
.est-pane { position: relative; z-index: 1; border-radius: var(--radius);
  background: var(--glass-tint); border: 1px solid var(--glass-edge);
  -webkit-backdrop-filter: var(--glass-blur); backdrop-filter: var(--glass-blur);
  box-shadow: inset 0 4px 4px rgba(255,255,255,.30), inset 0 -1px 2px rgba(0,0,0,.10);
  padding: var(--sp-4) var(--sp-5); }
.est-hero .eyebrow { color: rgba(255,255,255,.82); }
.est-hero .est-figure { font-size: var(--fs-hero); color: #fff; margin: 2px 0 6px; text-wrap: balance; }
.est-hero .est-figure .to { color: rgba(255,255,255,.72); }
.est-hero .est-sub { color: rgba(255,255,255,.88); font-size: var(--fs-body); margin: 0; }

/* Blur is a progressive enhancement, never a dependency. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .est-pane { background: rgba(0, 58, 63, .55); }
}
@media (prefers-reduced-transparency: reduce) {
  .est-pane { background: rgba(0, 58, 63, .62); -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* ---- Sparkline / trend strip ---- */
.trend { display: flex; align-items: flex-end; gap: 3px; height: 34px; margin-top: var(--sp-2); }
.trend i { flex: 1; background: var(--accent-soft); border-radius: 2px 2px 0 0; min-height: 2px; }
.trend i.on { background: var(--brand-teal); }
