/* Tend National Dashboard
   Palette provenance: the sequential ramp and the categorical mark colours were
   validated with the dataviz skill's validate_palette.js, not eyeballed.
     light sequential (ordinal, surface #F4EFE8) ... ALL CHECKS PASS
     light marks (--pairs all, surface #F4EFE8)  ... ALL CHECKS PASS
     dark  sequential (ordinal, surface #1F2422) ... ALL CHECKS PASS
     dark  marks (--pairs all, surface #1F2422)  ... ALL CHECKS PASS
   Brand: Arial throughout; Fog / Mist / Tide / Earth / Meadow / Honey / Terra. */

/* This rule is the reason three separate elements would not hide when the code
   set `hidden` on them. The user agent's `[hidden] { display: none }` has the
   same specificity as any single class selector, and an author rule beats the
   user agent at equal specificity — so every class in this file that sets
   `display` silently defeats `hidden` on its own elements. It cost us the deals
   pane covering the map and the account menu that would not close. One rule,
   stated once, ends the whole class of bug: nothing below can un-hide an
   element by accident. */
[hidden] { display: none !important; }

:root {
  color-scheme: light;

  --fog:    #F4EFE8;
  --earth:  #5C7A6E;
  --mist:   #B8D4D0;
  --tide:   #7AABB5;
  --meadow: #A8C5A0;
  --honey:  #F5C455;
  --terra:  #C8684A;

  --surface-0: #EDE7DE;
  --surface-1: #F4EFE8;
  --surface-2: #FFFCF7;
  --border:    #DCD3C6;
  --border-2:  #C9BEAD;

  --text-primary:   #1C231F;
  --text-secondary: #56605A;
  --text-muted:     #7C857E;

  /* Sequential ramp - one hue, light to dark. */
  --seq-1: #7FADBA;
  --seq-2: #5F95A6;
  --seq-3: #457C8E;
  --seq-4: #2E6376;
  --seq-5: #1A4A5C;
  --seq-null: #D8D1C6;

  /* Categorical marks - fixed order, assigned by entity, never by rank. */
  --mark-nhs:      #2a78d6;
  --mark-indie:    #C8684A;
  --mark-charity:  #4a3aa7;

  /* Charity relationship. Two identity hues only - engaged and lapsed - with
     fill state carrying the ladder (filled = live customer, ring = in play or
     merely contacted) and grey reserved for the null case. Two hues rather
     than four because a map is an all-pairs surface: any two markers can sit
     side by side, and no ordering of four purples clears the normal-vision
     separation floor in dark mode. Validated with the palette checker in both
     modes: worst all-pairs dE 31.4 light, 19.8 dark, all six checks pass. */
  --rel-engaged: #4a3aa7;
  --rel-lapsed:  #C8684A;
  --rel-none:    #9AA39D;

  --accent: var(--earth);
  --cta:    var(--honey);
  --shadow: 0 1px 2px rgba(28,35,31,.06), 0 8px 24px rgba(28,35,31,.07);
}

:root[data-theme="dark"] {
  color-scheme: dark;
  --surface-0: #171B19;
  --surface-1: #1F2422;
  --surface-2: #262C29;
  --border:    #353C38;
  --border-2:  #47504B;

  --text-primary:   #F2EFE9;
  --text-secondary: #B9C0BA;
  --text-muted:     #8B948D;

  --seq-1: #37697C;
  --seq-2: #4A8296;
  --seq-3: #5F9BB0;
  --seq-4: #7CB6C9;
  --seq-5: #A3D2E0;
  --seq-null: #333A36;

  --mark-nhs:     #3987e5;
  --mark-indie:   #d95926;
  --mark-charity: #199e70;

  /* Dark steps are chosen against the dark surface, not lightened from the
     light ones. */
  --rel-engaged: #9583D8;
  --rel-lapsed:  #CF7A58;
  --rel-none:    #79837C;

  --accent: #A8C5A0;
  --shadow: 0 1px 2px rgba(0,0,0,.3), 0 8px 24px rgba(0,0,0,.35);
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  margin: 0;
  font-family: Arial, Helvetica, sans-serif;
  background: var(--surface-1);
  color: var(--text-primary);
  font-size: 14px;
  line-height: 1.45;
}

h1, h2, h3 { margin: 0; font-weight: 700; }

/* ------------------------------------------------------------- top bar */
.topbar {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 12px 20px;
  background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 12px; }
.brand__mark {
  width: 26px; height: 26px; border-radius: 50%;
  background: radial-gradient(circle at 32% 30%, var(--mist), var(--tide) 62%, var(--earth));
  flex: none;
}
.brand h1 { font-size: 16px; letter-spacing: .01em; }
.brand__sub { margin: 1px 0 0; font-size: 11.5px; color: var(--text-muted); max-width: 62ch; }

.topbar__controls { display: flex; align-items: flex-end; gap: 10px; }
.ctl { display: flex; flex-direction: column; gap: 3px; }
.ctl > span, .field > span {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-muted); font-weight: 700;
}

select, input[type="search"], input[type="text"], textarea {
  font-family: inherit; font-size: 13px;
  padding: 6px 8px;
  background: var(--surface-1);
  color: var(--text-primary);
  border: 1px solid var(--border-2);
  border-radius: 6px;
}
select:focus-visible, input:focus-visible, textarea:focus-visible, button:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 1px;
}

.btn {
  font-family: inherit; font-size: 13px; font-weight: 700;
  padding: 7px 12px; border-radius: 6px; cursor: pointer;
  border: 1px solid var(--border-2); background: var(--surface-1); color: var(--text-primary);
}
.btn--cta { background: var(--cta); border-color: #E0AF3C; color: #2B2412; }
.btn--ghost { background: transparent; }
.btn--sm { padding: 4px 8px; font-size: 12px; }
.btn--danger { color: var(--terra); border-color: var(--border); background: transparent; }

/* -------------------------------------------------------------- layout */
.layout {
  display: grid;
  grid-template-columns: 300px minmax(0,1fr) 0;
  height: calc(100vh - 59px);
  transition: grid-template-columns .18s ease;
}
.layout.is-detail-open { grid-template-columns: 300px minmax(0,1fr) 400px; }

.rail, .detail {
  overflow-y: auto; overflow-x: hidden;
  background: var(--surface-2);
  border-right: 1px solid var(--border);
}
.detail { border-right: 0; border-left: 1px solid var(--border); }
.layout:not(.is-detail-open) .detail { display: none; }

.panel { padding: 14px 16px; border-bottom: 1px solid var(--border); }
.panel__h {
  font-size: 11px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-muted); margin-bottom: 10px;
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
}
.field { display: flex; flex-direction: column; gap: 3px; margin-bottom: 10px; }
.field input, .field select { width: 100%; }
.hint { font-size: 11.5px; color: var(--text-muted); margin: 6px 0 0; }
.check { display: flex; align-items: center; gap: 8px; padding: 3px 0; font-size: 13px; cursor: pointer; }

.pill {
  font-size: 11px; font-weight: 700; padding: 1px 7px; border-radius: 999px;
  background: var(--surface-0); color: var(--text-secondary); letter-spacing: 0;
  text-transform: none;
}

/* ---------------------------------------------------------------- map */
.mapwrap { position: relative; }
#map { position: absolute; inset: 0; background: var(--surface-0); }
.mapnote {
  position: absolute; left: 10px; bottom: 10px; z-index: 500;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 6px; padding: 6px 10px; font-size: 11px; color: var(--text-secondary);
  max-width: 46ch; box-shadow: var(--shadow);
}

/* ------------------------------------------------------------- legend */
.legend { margin-top: 12px; }
.legend__title { font-size: 11.5px; font-weight: 700; margin-bottom: 5px; }
.legend__scale { display: flex; gap: 2px; margin-bottom: 4px; }
.legend__swatch { height: 12px; flex: 1; border-radius: 2px; }
.legend__ends { display: flex; justify-content: space-between; font-size: 11px; color: var(--text-muted); }
.legend__keys { margin-top: 10px; display: flex; flex-direction: column; gap: 5px; }
.legend__key { display: flex; align-items: center; gap: 7px; font-size: 12px; color: var(--text-secondary); }
.legend__dot { width: 11px; height: 11px; flex: none; }
.legend__dot--circle { border-radius: 50%; }
.legend__dot--square { border-radius: 2px; }
.legend__dot--diamond { border-radius: 1px; transform: rotate(45deg); }
.legend__dot--square { border-radius: 2px; }

.buildtag {
  display: inline-block; margin-left: 6px; padding: 0 5px; border-radius: 4px;
  background: var(--surface-0); color: var(--text-muted); font-size: 10px;
  font-variant-numeric: tabular-nums;
}

.netchecks { display: flex; flex-direction: column; gap: 2px; }
.netchecks .legend__dot { margin-left: 2px; }

/* Deal outcome is a STATE, not a series identity, so it uses status colours
   with the label always present - never colour alone. */
.stagechip {
  display: inline-block; font-size: 10.5px; font-weight: 700; line-height: 1.3;
  padding: 2px 7px; border-radius: 999px; white-space: nowrap;
  background: var(--surface-0); color: var(--text-secondary);
  border: 1px solid var(--border);
}
/* Pipeline stage colour.
   Stages are ORDINAL, not categorical - swapping "Quote Provided" and "New
   Lead" would change the meaning - so the nine open stages take one hue in
   monotone lightness steps and the reader sees the progression in the colour.
   The three outcomes are STATUS and take reserved, distinct hues; they are
   never reused for a stage.

   Every value here was computed in OKLab and run through the dataviz
   validator rather than picked by eye. Light mode passes lightness band, CVD
   separation (all pairs, deuteranopia and protanopia at severity 1.0),
   normal-vision separation and 3:1 contrast on Fog; dark mode has its own
   steps validated against the dark surface, not an automatic flip - and its
   ramp runs dark to light, because on a dark surface "further along" has to
   read as "more present". The chips always carry their stage name, so colour
   is never the only channel.

   The one deliberate failure: "parked" sits below the chroma floor, i.e. it
   reads as grey. That is the intended meaning - a parked deal should recede -
   and the label says "Parked" regardless. */
.stagechip--s1 { background: #70B6C4; }
.stagechip--s2 { background: #66ABB9; }
.stagechip--s3 { background: #5BA0AE; }
.stagechip--s4 { background: #5096A3; }
.stagechip--s5 { background: #458B99; }
.stagechip--s6 { background: #3B818E; }
.stagechip--s7 { background: #2F7784; }
.stagechip--s8 { background: #246D79; }
.stagechip--s9 { background: #16636F; }
.stagechip--s1, .stagechip--s2, .stagechip--s3, .stagechip--s4 { color: #10333A; }
.stagechip--s5, .stagechip--s6, .stagechip--s7, .stagechip--s8, .stagechip--s9 { color: #FFFFFF; }
.stagechip--won    { background: #00964A; color: #FFFFFF; border-color: transparent; }
.stagechip--lost   { background: #DA5801; color: #FFFFFF; border-color: transparent; }
.stagechip--parked { background: #5B5752; color: #FFFFFF; border-color: transparent; }
.stagechip--open   { background: #458B99; color: #FFFFFF; border-color: transparent; }
:root[data-theme="dark"] .stagechip--s1 { background: #0D646C; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--s2 { background: #217078; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--s3 { background: #307D85; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--s4 { background: #3E8992; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--s5 { background: #4C969F; color: #08272B; }
:root[data-theme="dark"] .stagechip--s6 { background: #59A4AC; color: #08272B; }
:root[data-theme="dark"] .stagechip--s7 { background: #67B1B9; color: #08272B; }
:root[data-theme="dark"] .stagechip--s8 { background: #74BEC7; color: #08272B; }
:root[data-theme="dark"] .stagechip--s9 { background: #82CCD5; color: #08272B; }
:root[data-theme="dark"] .stagechip--won  { background: #0E8C41; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--lost { background: #D45003; color: #FFFFFF; }
:root[data-theme="dark"] .stagechip--parked { background: #8F8C85; color: #14100C; }
:root[data-theme="dark"] .stagechip--open { background: #4C969F; color: #08272B; }

.netgroup { margin-bottom: 12px; }
.netgroup__h {
  display: flex; align-items: center; gap: 7px; font-size: 12px; font-weight: 700;
  margin-bottom: 4px;
}

/* ------------------------------------------------------------ results */
.results { display: flex; flex-direction: column; gap: 2px; max-height: 380px; overflow-y: auto; }
.results--compact { max-height: 220px; }
.row {
  /* minmax(0,1fr) rather than 1fr. A bare 1fr has an automatic minimum of the
     content's own min-content width, so a long buyer name in the auto column
     squeezed the title column to nothing - and with overflow-wrap: anywhere on
     the title, that renders one letter per line. */
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto; gap: 8px; align-items: center;
  padding: 7px 8px; border-radius: 6px; cursor: pointer;
  background: transparent; border: 0; text-align: left; font: inherit; color: inherit; width: 100%;
}
.row:hover { background: var(--surface-0); }
.row:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.row__locate {
  border: 1px solid transparent; background: transparent; color: var(--text-muted);
  cursor: pointer; font-size: 13px; line-height: 1; padding: 3px 5px; border-radius: 5px;
  opacity: 0; transition: opacity .12s;
}
.row:hover .row__locate, .row__locate:focus-visible { opacity: 1; }
.row__locate:hover { color: var(--text-primary); border-color: var(--border-2); }
.leaflet-marker-icon.is-pinged > span,
.leaflet-marker-icon.is-pinged span { box-shadow: 0 0 0 4px rgba(74, 58, 167, .35); }
.row.is-active { background: var(--surface-0); box-shadow: inset 2px 0 0 var(--accent); }
.row > span:first-child { min-width: 0; }
.row__name { display: block; font-size: 12.5px; font-weight: 700; line-height: 1.25; overflow-wrap: anywhere; }
.row__meta {
  display: block; font-size: 11px; color: var(--text-muted);
  min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Rows whose two halves are both long - a notice title and the buyer that
   issued it, a headline and its date - stack instead of competing for a
   400px panel. */
.row--stack { display: block; }
.row--stack .row__name { margin-bottom: 2px; }
.row--stack .row__meta { white-space: normal; overflow: visible; }
.row__val { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.row__swatch { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 5px; vertical-align: 1px; }
.empty { font-size: 12px; color: var(--text-muted); padding: 6px 2px; }

/* ------------------------------------------------------------- detail */
.detail__empty { padding: 28px 20px; color: var(--text-muted); font-size: 13px; }
.detail__head { padding: 16px 18px 12px; border-bottom: 1px solid var(--border); position: relative; }
.detail__close { position: absolute; top: 12px; right: 12px; }
.detail__eyebrow {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-muted); font-weight: 700;
}
.detail__title { font-size: 16px; margin: 3px 0 6px; padding-right: 34px; }
.chips { display: flex; flex-wrap: wrap; gap: 5px; }
.chip {
  font-size: 11px; padding: 2px 8px; border-radius: 999px;
  background: var(--surface-0); color: var(--text-secondary); border: 1px solid var(--border);
}
.chip--sector { border-color: transparent; color: #fff; }

.section { padding: 20px 18px 16px; border-bottom: 1px solid var(--border); }
/* Section headings do the navigating in a long detail panel, so they read as
   dividers rather than as labels: larger, in body colour rather than muted,
   and sitting on a rule that spans the panel. */
.section__h {
  font-size: 14px; text-transform: uppercase; letter-spacing: .10em;
  color: var(--text-primary); font-weight: 700;
  margin: 0 0 12px; padding-bottom: 8px;
  border-bottom: 2px solid var(--accent);
  display: flex; align-items: baseline; gap: 8px;
}
.section__h .pill { margin-left: auto; }

/* --------------------------------------------------------- stat tiles */
.tiles { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.tile {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 8px; padding: 9px 10px;
}
.tile__label { font-size: 11px; color: var(--text-secondary); line-height: 1.25; min-height: 2.5em; }
.tile__value {
  font-size: 21px; font-weight: 700; font-variant-numeric: tabular-nums;
  letter-spacing: -.01em; margin-top: 2px;
}
.tile__delta { font-size: 11px; font-weight: 700; margin-top: 1px; }
.tile__delta--up   { color: #2E7D4F; }
.tile__delta--down { color: var(--terra); }
.tile__delta--flat { color: var(--text-muted); }
.tile__info {
  border: 1px solid var(--border-2); background: transparent; color: var(--text-muted);
  width: 15px; height: 15px; border-radius: 50%; font-size: 10px; font-weight: 700;
  line-height: 1; cursor: pointer; margin-left: 5px; padding: 0; vertical-align: 1px;
  font-family: Georgia, serif; font-style: italic;
}
.tile__info:hover { color: var(--text-primary); border-color: var(--text-secondary); }

/* ------------------------------------------------------- trend charts */
.chart { margin-top: 7px; }
.chart--empty { font-size: 11px; color: var(--text-muted); padding: 8px 0; }
.chart__svg { display: block; width: 100%; height: 46px; cursor: crosshair; touch-action: none; }
.chart__svg:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.chart__hair { stroke: var(--border-2); stroke-width: 1; vector-effect: non-scaling-stroke; }
.chart__cmp {
  stroke: var(--text-muted); stroke-width: 1; opacity: .45;
  vector-effect: non-scaling-stroke; stroke-dasharray: 3 3;
}
.chart__readout {
  min-height: 15px; margin-top: 3px; font-size: 11px; color: var(--text-secondary);
  display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap;
}
.chart__val { font-size: 12px; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.chart__month { color: var(--text-muted); }
.chart__vs { font-variant-numeric: tabular-nums; color: var(--text-muted); }
.chart__vs.is-good { color: #2E7D4F; }
.chart__vs.is-bad  { color: var(--terra); }
:root[data-theme="dark"] .chart__vs.is-good { color: #6FBF8E; }
.chart__gapnote { font-size: 10.5px; color: var(--text-muted); margin-top: 1px; }

.defbox {
  grid-column: 1 / -1; margin-top: 8px; padding: 10px 12px;
  background: var(--surface-1); border: 1px solid var(--border);
  border-left: 3px solid var(--tide); border-radius: 0 8px 8px 0; font-size: 12px;
}
.defbox p { margin: 5px 0 0; color: var(--text-secondary); }
.defbox__den { font-style: italic; }
.defbox__close { margin-top: 8px; }

/* ---------------------------------------------------------------- tabs */
.tabs { display: flex; gap: 2px; margin-bottom: 8px; }
.tabs button {
  flex: 1; font: inherit; font-size: 12px; font-weight: 700; padding: 5px 8px;
  background: var(--surface-1); color: var(--text-secondary);
  border: 1px solid var(--border); border-radius: 6px; cursor: pointer;
}
.tabs button.is-on { background: var(--surface-0); color: var(--text-primary); border-color: var(--border-2); }
.hint--tight { margin: 0 0 8px; }

/* ------------------------------------------------------- data updating */
.upd {
  margin-top: 8px; padding: 9px 11px; font-size: 12px;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: 8px;
}
.upd--ok  { border-left: 3px solid var(--meadow); }
.upd--err { border-left: 3px solid var(--terra); }
.upd__log {
  margin-top: 6px; font-size: 11px; color: var(--text-secondary);
  max-height: 150px; overflow-y: auto; font-variant-numeric: tabular-nums;
}
.upd__log div { padding: 1px 0; }
.upd__spin {
  width: 14px; height: 14px; border-radius: 50%;
  border: 2px solid var(--border-2); border-top-color: var(--tide);
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .upd__spin { animation-duration: 3s; } }
.flash {
  position: fixed; left: 50%; bottom: 22px; transform: translateX(-50%) translateY(8px);
  z-index: 1200; max-width: 52ch;
  background: var(--surface-2); color: var(--text-primary);
  border: 1px solid var(--border-2); border-left: 3px solid var(--honey);
  border-radius: 8px; padding: 9px 13px; font-size: 12.5px;
  box-shadow: var(--shadow); opacity: 0; pointer-events: none;
  transition: opacity .18s, transform .18s;
}
.flash.is-on { opacity: 1; transform: translateX(-50%) translateY(0); }
@media (prefers-reduced-motion: reduce) { .flash { transition: none; } }

.chart__cmp {
  stroke: var(--text-muted); stroke-width: 1; opacity: .5;
  vector-effect: non-scaling-stroke; stroke-dasharray: 3 3;
}

.upd code { font-size: 11px; background: var(--surface-0); padding: 1px 4px; border-radius: 3px; }

.hero { font-size: 48px; font-weight: 700; line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }

/* -------------------------------------------------------------- table */
table.tbl { width: 100%; border-collapse: collapse; font-size: 12px; }
.tbl th {
  text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-muted); font-weight: 700; padding: 4px 6px 4px 0;
  border-bottom: 1px solid var(--border);
}
.tbl td { padding: 5px 6px 5px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.tbl td.num, .tbl th.num {
  text-align: right; font-variant-numeric: tabular-nums;
  padding-right: 0; padding-left: 10px; white-space: nowrap;
}
.tbl tr:last-child td { border-bottom: 0; }
.tbl a { color: var(--text-primary); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }

.note {
  background: var(--surface-1); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px 10px; margin-bottom: 7px; font-size: 12.5px;
}
.note__meta { font-size: 10.5px; color: var(--text-muted); margin-top: 5px; display: flex; justify-content: space-between; gap: 8px; }
textarea { width: 100%; min-height: 62px; resize: vertical; }
.taglist { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 8px; }
.tag {
  font-size: 11.5px; padding: 2px 6px 2px 9px; border-radius: 999px;
  background: var(--mist); color: #14312F; display: inline-flex; align-items: center; gap: 4px;
}
:root[data-theme="dark"] .tag { background: #2C4A47; color: #DDEEEC; }
.tag button { border: 0; background: transparent; cursor: pointer; color: inherit; font-size: 13px; line-height: 1; padding: 0 3px; }
.inline-form { display: flex; gap: 6px; }
.inline-form input { flex: 1; }
.stack { display: flex; flex-direction: column; gap: 8px; }
.caveat {
  font-size: 11.5px; color: var(--text-secondary);
  background: var(--surface-1); border-left: 3px solid var(--honey);
  padding: 7px 10px; border-radius: 0 6px 6px 0; margin-top: 10px;
}

/* -------------------------------------------------------- map tooltip */
.leaflet-tooltip.tt {
  background: var(--surface-2); color: var(--text-primary);
  border: 1px solid var(--border-2); border-radius: 6px;
  box-shadow: var(--shadow); font-family: Arial, Helvetica, sans-serif;
  font-size: 12px; padding: 6px 9px;
}
.leaflet-tooltip.tt::before { display: none; }
.tt__name { font-weight: 700; }
.tt__val { font-variant-numeric: tabular-nums; }
.tt__sub { color: var(--text-muted); font-size: 11px; }
.leaflet-container { font-family: Arial, Helvetica, sans-serif; background: var(--surface-0); }
:root[data-theme="dark"] .leaflet-tile { filter: invert(1) hue-rotate(180deg) brightness(.92) contrast(.9); }
.leaflet-control-attribution {
  background: var(--surface-2) !important; color: var(--text-muted) !important; font-size: 10px;
}
.leaflet-control-attribution a { color: var(--text-secondary) !important; }

/* ---------------------------------------------------------------- workforce
   Qualified and trainee staff stacked, four ESR releases. Trainee sits on top
   in the CTA colour because it is the part that moves and the part that
   matters: a service losing its pipeline loses capacity a year later. */
.tiles--3 { grid-template-columns: 1fr 1fr 1fr; }
.wfbar {
  position: relative; height: 88px; margin: 10px 0 2px;
  border-bottom: 1px solid var(--border);
}
.wfbar__col { position: absolute; top: 0; bottom: 0; display: flex; flex-direction: column; }
.wfbar__stack {
  flex: 1; display: flex; flex-direction: column; justify-content: flex-end;
  margin: 0 4px; min-width: 0;
}
.wfbar__q { background: var(--tide); border-radius: 0 0 2px 2px; }
.wfbar__t { background: var(--honey); border-radius: 2px 2px 0 0; }
.wfbar__x {
  font-size: 10px; color: var(--text-muted); text-align: center;
  padding-top: 3px; letter-spacing: .02em;
}
.wfkey {
  display: inline-block; width: 9px; height: 9px; border-radius: 2px;
  margin: 0 4px 0 0; vertical-align: baseline;
}
.wfkey--q { background: var(--tide); }
.wfkey--t { background: var(--honey); margin-left: 10px; }
.tbl--kv th { font-weight: 500; color: var(--text-secondary); text-align: left; }
.tbl--kv .tbl__rule th, .tbl--kv .tbl__rule td { border-top: 1px solid var(--border); font-weight: 600; }
.warn {
  margin: 0 0 10px; padding: 8px 10px; font-size: 12px; line-height: 1.45;
  background: var(--surface-2); border-left: 3px solid var(--terra);
  border-radius: 0 6px 6px 0; color: var(--text-secondary);
}
.wfrow { display: flex; align-items: baseline; gap: 8px; }
.wfrow__num { margin-left: auto; font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------------ recent contact
   Direction is carried by an arrow and a colour, not colour alone: inbound is
   the interesting case and needs to survive a monochrome print and a reader
   who cannot separate the two hues. */
.tbl--mail td { vertical-align: top; }
.mail__dir { width: 22px; padding-right: 0; }
.mail__date { white-space: nowrap; color: var(--text-muted); font-size: 11px; }
.dirchip {
  display: inline-block; width: 18px; height: 18px; line-height: 18px;
  text-align: center; border-radius: 5px; font-size: 12px;
  border: 1px solid var(--border);
}
.dirchip--in  { background: var(--meadow); color: #21301F; border-color: transparent; }
.dirchip--out { background: var(--surface-2); color: var(--text-muted); }
:root[data-theme="dark"] .dirchip--in { background: #2C5540; color: #C6E6CE; }

/* ------------------------------------------------- charity relationship key */
.relkey { display: flex; flex-wrap: wrap; gap: 4px 12px; margin-top: 8px; }
.relkey__item { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-secondary); }
.relkey__n { color: var(--text-muted); font-variant-numeric: tabular-nums; }
.relswatch {
  width: 11px; height: 11px; border-radius: 50%; box-sizing: border-box; flex: none;
}
.relswatch--customer  { background: var(--rel-engaged); box-shadow: 0 0 0 2px var(--surface-2); }
.relswatch--in_play   { background: transparent; border: 3px solid var(--rel-engaged); }
.relswatch--lapsed    { background: transparent; border: 3px solid var(--rel-lapsed); }
.relswatch--contacted { background: var(--rel-none); border: 2px solid var(--rel-engaged); }
.relswatch--none      { background: transparent; border: 2px solid var(--rel-none); opacity: .8; }
.relchip {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11px;
  padding: 3px 9px 3px 7px; border-radius: 999px;
  border: 1px solid var(--border); background: var(--surface-2); color: var(--text-secondary);
}

/* ------------------------------------------------------------ deal editing */
.tbl--deals select, .tbl--deals input {
  width: 100%; font: inherit; font-size: 12px; padding: 4px 6px;
  background: var(--surface-1); color: var(--text-primary);
  border: 1px solid var(--border); border-radius: 6px;
}
.tbl--deals input { text-align: right; font-variant-numeric: tabular-nums; }
.tbl--deals select:focus, .tbl--deals input:focus {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.dealsave { display: flex; align-items: center; gap: 10px; margin-top: 10px; flex-wrap: wrap; }
.row--static { cursor: default; }
code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 11px;
  background: var(--surface-2); padding: 1px 4px; border-radius: 4px;
}

/* -------------------------------------------------- contract diary and news */
.diary {
  display: flex; align-items: baseline; gap: 14px; margin: 0 0 12px;
  padding: 10px 12px; border-radius: 8px; background: var(--surface-2);
  border-left: 4px solid var(--border-2);
}
/* Urgency is a sequential idea, so it is one hue getting darker, with the text
   carrying the actual band name — never colour alone. */
.diary--now   { border-left-color: var(--terra); }
.diary--soon  { border-left-color: var(--honey); }
.diary--watch { border-left-color: var(--tide); }
.diary--later { border-left-color: var(--border-2); }
.diary__when {
  font-size: 18px; font-weight: 700; color: var(--text-primary);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.diary__what { font-size: 12px; color: var(--text-secondary); }
.tbl--diary td { vertical-align: top; }
.newslist { list-style: none; margin: 0 0 10px; padding: 0; }
.newslist li { padding: 6px 0; border-bottom: 1px solid var(--border); font-size: 12px; }
.newslist li:last-child { border-bottom: 0; }
.newslist a { display: block; color: var(--text-primary); text-decoration: none; }
.newslist a:hover { text-decoration: underline; }
.btn--on { background: var(--honey); color: #2A2416; border-color: transparent; }

/* ------------------------------------------------------------- account menu */
.whoami { position: relative; }
.whomenu {
  position: absolute; right: 0; top: calc(100% + 6px); z-index: 900;
  min-width: 190px; padding: 5px; border-radius: 10px;
  background: var(--surface-1); border: 1px solid var(--border);
  box-shadow: 0 10px 30px rgb(0 0 0 / .18);
  display: flex; flex-direction: column;
}
.whomenu button, .whomenu a {
  appearance: none; background: none; border: 0; text-align: left;
  font: inherit; font-size: 12px; color: var(--text-primary);
  padding: 8px 10px; border-radius: 7px; cursor: pointer; text-decoration: none;
}
.whomenu button:hover, .whomenu a:hover { background: var(--surface-2); }

.modal {
  border: 1px solid var(--border); border-radius: 14px; padding: 0;
  background: var(--surface-1); color: var(--text-primary);
  width: min(94vw, 560px); box-shadow: 0 24px 60px rgb(0 0 0 / .3);
}
.modal::backdrop { background: rgb(0 0 0 / .45); }
.modal__in { padding: 20px 22px 22px; }
.modal__in h3 { margin: 0 0 4px; font-size: 15px; }
.modal__in label { display: block; margin: 12px 0 0; font-size: 12px; color: var(--text-secondary); }
.modal__in input, .modal__in select {
  width: 100%; box-sizing: border-box; margin-top: 5px; padding: 8px 10px;
  font: inherit; font-size: 13px; border-radius: 8px;
  border: 1px solid var(--border-2); background: var(--surface-0); color: var(--text-primary);
}
.modal__row { display: flex; gap: 8px; align-items: center; margin-top: 18px; flex-wrap: wrap; }
.modal__row .btn { flex: none; }
.people { margin-top: 4px; }
.people__row {
  display: flex; align-items: center; gap: 10px; padding: 9px 0;
  border-bottom: 1px solid var(--border); font-size: 12px;
}
.people__row:last-child { border-bottom: 0; }
.people__who { flex: 1; min-width: 0; }
.people__who strong { display: block; font-weight: 600; }
.people__row.is-off { opacity: .55; }
/* Update output. Monospace because it is a transcript of a terminal, and
   scrollable because a rollback produces more of it than a success does. */
.updatelog {
  margin-top: 8px; padding: 8px 10px; max-height: 220px; overflow: auto;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: 6px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; line-height: 1.5; white-space: pre-wrap; word-break: break-word;
  color: var(--text-secondary);
}
.badge {
  font-size: 10px; letter-spacing: .04em; text-transform: uppercase;
  padding: 2px 7px; border-radius: 999px; border: 1px solid var(--border);
  color: var(--text-secondary); background: var(--surface-2);
}
.badge--admin { background: var(--meadow); color: #21301F; border-color: transparent; }

/* The enrolment QR. Sized generously — a code that has to be scanned from a
   phone held at arm's length is not the place to save 40 pixels. */
.tfqr {
  display: grid; place-items: center; margin: 14px 0;
  padding: 14px; background: #fff; border: 1px solid var(--border); border-radius: 10px;
}
.tfqr svg { width: 190px; height: 190px; }
[data-theme="dark"] .tfqr { background: #fff; }

/* ------------------------------------------------------------------ probe */
.probe__brief { font-size: 13px; line-height: 1.55; }
.probe__brief h4 { margin: 14px 0 4px; }
.probe__brief p { margin: 0 0 8px; }
.probe__brief ul { margin: 0 0 10px; padding-left: 1.05rem; }
.probe__brief li { margin-bottom: 3px; }
.probe__sources { margin: 10px 0; font-size: 12px; }
.probe__sources summary { cursor: pointer; color: var(--text-secondary); }
.probe__sources ol { margin: 8px 0 0; padding-left: 1.3rem; }
.probe__sources li { margin-bottom: 4px; word-break: break-word; }
.probe__sources a { color: var(--tide); }

/* A control that is still live but no longer colours the map. Dimmed rather
   than hidden: hiding it would lose the reader's place in a long list, and
   leaving it bright would imply it still drives the shading. */
.ctl.is-muted { opacity: .5; }
.ctl.is-muted select { border-style: dashed; }

/* ------------------------------------------------------------- view tabs */
.viewtabs {
  position: absolute; top: 10px; left: 10px; z-index: 600;
  display: flex; gap: 2px; padding: 3px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: var(--shadow);
}
.viewtabs button {
  font: inherit; font-size: 12px; font-weight: 700; cursor: pointer;
  padding: 5px 12px; border: 0; border-radius: 6px;
  background: transparent; color: var(--text-secondary);
}
.viewtabs button.is-on { background: var(--surface-0); color: var(--text-primary); }
/* Leaflet puts its zoom control in the same corner, so it moves down rather
   than sitting underneath a tab bar the reader cannot see past. */
.mapwrap .leaflet-top.leaflet-left { margin-top: 44px; }

/* ----------------------------------------------------------------- deals */
.deals {
  position: absolute; inset: 0; z-index: 500;
  display: flex; flex-direction: column;
  background: var(--surface-1); padding: 52px 18px 0;
}
/* Hiding is handled once, at the top of this file, by `[hidden]`. */
.deals__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; }
.tabs--sm button { font-size: 12px; padding: 4px 10px; }
.deals__plot { flex: 1; min-height: 0; overflow: auto; padding: 10px 0 4px; }
.deals__foot {
  border-top: 1px solid var(--border); padding: 10px 0 14px;
  display: flex; gap: 26px; flex-wrap: wrap; align-items: baseline;
}
.stat { display: flex; flex-direction: column; gap: 1px; }
.stat__v { font-size: 19px; font-weight: 700; letter-spacing: -0.01em; }
.stat__k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .07em; color: var(--text-muted); font-weight: 700; }
.stat__n { font-size: 11px; color: var(--text-muted); }
.dchart { width: 100%; display: block; }
.dchart text { font-family: Arial, Helvetica, sans-serif; }
.dchart .lbl { font-size: 11px; fill: var(--text-secondary); }
.dchart .val { font-size: 11px; fill: var(--text-muted); }
.dchart .ax { stroke: var(--border); stroke-width: 1; }
.dchart .mark { cursor: pointer; }
.dchart .mark:hover { stroke: var(--text-primary); stroke-width: 2; }
.dtip {
  position: fixed; z-index: 900; pointer-events: none; max-width: 30ch;
  background: var(--surface-2); border: 1px solid var(--border-2); border-radius: 6px;
  padding: 6px 9px; font-size: 11.5px; box-shadow: var(--shadow); color: var(--text-primary);
}
.dtip strong { display: block; }
.dtip span { color: var(--text-muted); }

/* A heading INSIDE a section. The probe was reusing .section__h for these,
   which gave a sub-heading the full divider treatment - uppercase, 2px rule,
   no top margin - so "IN THE NEWS" arrived hard against the paragraph above it
   and read as a new section rather than part of one. */
.section__sub {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--text-muted); font-weight: 700;
  margin: 18px 0 6px; padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.section__sub:first-child { margin-top: 0; }

/* ------------------------------------------------------- section foldouts */
/* Unity calls these foldouts; on the web the same control is a disclosure.
   Deliberately not an accordion — opening one does not close the others,
   because on a long panel someone may well want workforce and procurement
   open together and everything between them shut. */
.section > .section__h { cursor: pointer; user-select: none; }
.section > .section__h::after {
  content: ""; margin-left: auto; flex: none;
  width: 7px; height: 7px;
  border-right: 2px solid var(--text-muted);
  border-bottom: 2px solid var(--text-muted);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .15s ease;
}
/* A pill already claims margin-left:auto, so the arrow needs its own spacing
   when both are present. */
.section__h .pill + * { margin-left: 0; }
.section.is-folded > .section__h::after { transform: rotate(-45deg) translate(-1px, 1px); }
.section > .section__h:hover::after { border-color: var(--text-primary); }
.section.is-folded > *:not(.section__h) { display: none; }
.section.is-folded > .section__h { margin-bottom: 0; }
.section > .section__h:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* Invisible, full-viewport, directly beneath an open menu. Dismissing a menu
   should not depend on a click event surviving its journey to a listener —
   Leaflet stops propagation on the map, and that is exactly where a person
   clicks to get rid of it. */
.scrim { position: fixed; inset: 0; z-index: 890; background: transparent; }
.whomenu { z-index: 900; }

/* --------------------------------------------------------------- the tour */
.tour { position: fixed; inset: 0; z-index: 1200; background: rgb(0 0 0 / .38); }
/* A hole cut over the thing being described, using an enormous outward shadow
   rather than an overlay with a literal hole — one element, no clipping, and
   it follows the element if the layout moves. */
.tour__spot {
  position: fixed; border-radius: 10px; pointer-events: none;
  box-shadow: 0 0 0 9999px rgb(0 0 0 / .38), 0 0 0 3px var(--honey);
  transition: all .25s ease;
}
.tour.has-spot { background: transparent; }
.tour__card {
  position: fixed; width: min(92vw, 420px);
  background: var(--surface-1); border: 1px solid var(--border-2);
  border-radius: 12px; padding: 18px 20px 14px; box-shadow: 0 18px 50px rgb(0 0 0 / .3);
}
.tour__card h3 { font-size: 16px; margin: 0 0 8px; }
.tour__card p { font-size: 13px; line-height: 1.5; margin: 0 0 8px; color: var(--text-secondary); }
.tour__card strong { color: var(--text-primary); }
.tour__step {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: var(--text-muted); font-weight: 700; margin-bottom: 4px;
}
.tour__row { display: flex; align-items: center; gap: 8px; margin-top: 14px; }
.tour__dots { display: flex; gap: 5px; margin-left: auto; margin-right: 4px; }
.tour__dot { width: 6px; height: 6px; border-radius: 50%; background: var(--border-2); }
.tour__dot.is-on { background: var(--accent); }

/* ------------------------------------------------- staleness banner & warnings */
/* Amber, not red, and dismissible. Stale data is a fact to act on, not an
   emergency, and a warning that cannot be dismissed gets ignored instead. */
.banner {
  padding: 10px 18px; font-size: 13px; line-height: 1.5;
  background: var(--honey); color: #2A2416;
  border-bottom: 1px solid var(--border-2);
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.banner .btn { margin-left: auto; }
.hint--warn { color: var(--terra); font-weight: 600; }

/* By owner. One block per person: a bar showing their share of open pipeline,
   segmented by stage in the same ordinal ramp the pipeline view uses, then
   their deals. The 2px gaps between segments are the spacer the mark spec
   asks for - without them two adjacent stage steps merge into one block. */
.owners { display: flex; flex-direction: column; gap: 22px; }
.owner__h { display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 6px; }
.owner__name { font-weight: 700; font-size: 15px; }
.owner__meta { color: var(--text-muted); font-size: 13px; }
.owner__bar { background: var(--surface-0); border-radius: 5px; overflow: hidden; }
.owner__track { display: flex; gap: 2px; height: 16px; min-width: 2px; }
.owner__seg { display: block; min-width: 2px; border-radius: 2px; }
.owner__seg:first-child { border-radius: 4px 2px 2px 4px; }
.owner__seg:last-child  { border-radius: 2px 4px 4px 2px; }
.tbl--owner { margin-top: 8px; }
.tbl--owner td { padding: 5px 8px; }
.tbl--owner tr { cursor: pointer; }
.tbl--owner tr:hover { background: var(--surface-0); }

/* Stage key. The ordinal ramp segments bars in two views, so identity is never
   carried by colour alone - the guidance is explicit that a legend is present
   whenever more than one series shares a chart. */
.stagekey { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0 0 12px;
  font-size: 12px; color: var(--text-muted); }
.stagekey__i { display: inline-flex; align-items: center; gap: 5px; }
.stagekey__dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }

/* A mark you can open. The outline on focus matters more than the hover: these
   are reachable by keyboard, so the focus ring is the only thing telling a
   keyboard user where they are. */
.mark--hit { cursor: pointer; }
.mark--hit:hover { filter: brightness(1.08); }
.mark--hit:focus-visible, .owner__seg:focus-visible {
  outline: 2px solid var(--text); outline-offset: 2px; }
.owner__seg { cursor: pointer; }
.owner__seg:hover { filter: brightness(1.08); }
