/* ============================================================================
 * samen_ui.css — the Samen product-UI design tokens + component classes.
 *
 * Extracted verbatim (cleaned + organized) from the three approved mockups:
 *   _mockup-samen-ui.html        (operator masked impersonation)
 *   _mockup-samen-aggregate.html (token-blind aggregate / MRR)
 *   _mockup-samen-broker.html    (tenant broker dashboard + settlement reshape)
 *
 * This is the single design source of truth for the Samen UI kit. The HEEx
 * function components in DriftwoodWeb.UIKit render markup that consumes these
 * classes. Any vertical (driftwood / demo / pawchart) that serves this file and
 * uses the kit components inherits the identical look.
 *
 * SHARED across all consumers — do NOT vertical-specialize here. Per-page one-off
 * overrides belong in the page, not this shared token file.
 *
 * Home / extractability: ADR-008 places the kit in driftwood-local now, noted as
 * extractable to a shared `samen_ui` path-dep lib once a second consumer adopts it
 * (Rule-of-Three). When that happens this file moves to that lib's priv/static.
 * ========================================================================== */

/* ---------------------------------------------------------------------------
 * Self-hosted webfonts (T131) — ZERO external CDN. The former
 *   the former Google Fonts stylesheet import (Inter + JetBrains Mono)
 * was a framework-wide external font fetch on EVERY page (IP leak, breaks
 * offline / air-gapped self-hosting, third-party runtime dependency) and violated
 * this codebase's no-external-CDN invariant. Replaced with local @font-face rules
 * whose src points at the Latin-subset VARIABLE woff2, served SAME-ORIGIN as
 * a SEPARATE static file under /assets/fonts/ (T133) rather than a base64 data:
 * URI, so the stylesheet stays small and the fonts cache independently — still
 * ZERO external CDN (same-origin only, resolves identically air-gapped). One
 * variable file per family covers every weight (400-700); OFL + provenance in fonts/.
 * ------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/Inter-latin.var.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 100 800;
  font-display: swap;
  src: url('/assets/fonts/JetBrainsMono-latin.var.woff2') format('woff2');
}

/* ---------------------------------------------------------------------------
 * Design tokens (the mockups' :root)
 * ------------------------------------------------------------------------- */
:root {
  --canvas: #F4F4F6;
  --panel: #FBFBFC;
  --card: #FFFFFF;
  --ink: #191A20;
  --muted: #6A6B77;
  --faint: #9A9BA6;
  --line: #EBEBEF;
  --line2: #E3E3E8;
  --brand: #3B4CCA;
  --brand-wash: #EEF0FD;
  --red: #C4443B;
  --red-wash: #FBECEA;
  --amber: #9A6A15;
  --amber-wash: #FBF1DE;
  --green: #1E7A45;
  --green-wash: #E7F3EB;
  --violet: #6D45C4;
  --violet-wash: #F1ECFB;
  --mono: 'JetBrains Mono', ui-monospace, monospace;
}

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

body {
  font-family: 'Inter', -apple-system, sans-serif;
  background: var(--canvas);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  letter-spacing: -0.006em;
}

svg { display: block; }

/* ---------------------------------------------------------------------------
 * App shell — sidebar + main grid
 * ------------------------------------------------------------------------- */
.app {
  display: grid;
  grid-template-columns: 252px 1fr;
  height: 100vh;
  padding: 10px;
  gap: 10px;
}

/* ---------------------------------------------------------------------------
 * Sidebar
 * ------------------------------------------------------------------------- */
.side {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  padding: 14px 12px;
  overflow-y: auto;
  overflow-x: hidden;
  max-height: 100vh;
  position: sticky;
  top: 16px;
}
.ws { display: flex; align-items: center; gap: 10px; padding: 8px 8px 10px; }
.ws .logo {
  width: 32px; height: 32px; border-radius: 9px;
  background: linear-gradient(150deg, #3B4CCA, #5B6BE0);
  flex-shrink: 0; display: grid; place-items: center;
  color: #fff; font-weight: 700; font-size: 15px;
  box-shadow: 0 1px 2px rgba(20, 25, 90, .25);
}
.ws .who { min-width: 0; }
.ws .who b { display: block; font-weight: 600; font-size: 13.5px; letter-spacing: -0.01em; }
.ws .who span { display: block; font-size: 11.5px; color: var(--faint); }
.ws .col { margin-left: auto; color: var(--faint); font-size: 15px; }

.search {
  display: flex; align-items: center; gap: 8px;
  margin: 2px 4px 14px; padding: 8px 10px;
  background: var(--card); border: 1px solid var(--line2);
  border-radius: 9px; color: var(--faint); font-size: 13px;
}
.search .kbd {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px;
  color: var(--faint); border: 1px solid var(--line2);
  border-radius: 5px; padding: 1px 5px;
}

.grp {
  font-size: 10.5px; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--faint); padding: 12px 10px 6px;
}
.nav a {
  display: flex; align-items: center; gap: 10px;
  padding: 7px 10px; border-radius: 8px;
  color: var(--muted); text-decoration: none;
  font-weight: 450; font-size: 13.5px; position: relative;
}
.nav a .i { width: 16px; height: 16px; flex-shrink: 0; color: var(--faint); }
.nav a:hover { background: #F1F1F4; }
.nav a.on {
  background: var(--card); border: 1px solid var(--line2);
  color: var(--ink); font-weight: 550;
  box-shadow: 0 1px 1px rgba(0, 0, 0, .02);
}
.nav a.on .i { color: var(--brand); }
.nav a .cnt { margin-left: auto; font-size: 11px; color: var(--faint); font-family: var(--mono); }
.nav a .dot { margin-left: auto; width: 6px; height: 6px; border-radius: 50%; background: var(--green); }

.nav { flex: 1; overflow-y: auto; }

.side .foot {
  margin-top: auto; padding: 10px; border-top: 1px solid var(--line);
  display: flex; align-items: center; gap: 9px;
}
.side .foot .av {
  width: 26px; height: 26px; border-radius: 50%;
  background: #DFE1EC; flex-shrink: 0;
  display: grid; place-items: center;
  font-size: 11px; font-weight: 600; color: #4A4C66;
}
.side .foot .m { min-width: 0; }
.side .foot .m b { display: block; font-size: 12px; font-weight: 550; }
.side .foot .m span { display: block; font-size: 10.5px; color: var(--faint); }

/* ---------------------------------------------------------------------------
 * Main panel + topbar
 * ------------------------------------------------------------------------- */
.main { background: var(--card); border: 1px solid var(--line); border-radius: 14px; overflow: auto; }
.top { padding: 22px 30px 0; }
.crumb {
  display: flex; align-items: center; gap: 8px;
  color: var(--faint); font-size: 12.5px; margin-bottom: 12px;
}
.crumb .sep { opacity: .5; }
.head { display: flex; align-items: flex-start; gap: 16px; }
.head h1 { font-size: 27px; font-weight: 650; letter-spacing: -0.025em; }
.head .actions { margin-left: auto; display: flex; gap: 8px; }

/* ---------------------------------------------------------------------------
 * Buttons
 * ------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border-radius: 9px;
  font-size: 13px; font-weight: 550;
  border: 1px solid var(--line2); background: var(--card);
  color: var(--ink); cursor: pointer; letter-spacing: -0.01em;
}
.btn .i { width: 15px; height: 15px; color: var(--muted); }
.btn.primary { background: #1B1C22; color: #fff; border-color: #1B1C22; }
.btn.primary .i { color: #fff; }

/* ---------------------------------------------------------------------------
 * Banner: masked impersonation (mask-bar)
 * ------------------------------------------------------------------------- */
.mask-bar {
  margin: 18px 30px 0; display: flex; align-items: center; gap: 12px;
  padding: 11px 15px; border-radius: 11px;
  background: var(--brand-wash); border: 1px solid #DCE0FA;
}
.mask-bar .ic {
  width: 30px; height: 30px; border-radius: 8px;
  background: #fff; border: 1px solid #DCE0FA;
  display: grid; place-items: center; color: var(--brand); flex-shrink: 0;
}
.mask-bar .tx { font-size: 12.5px; color: #37407A; line-height: 1.4; }
.mask-bar .tx b { font-weight: 650; color: #28306B; }
.mask-bar .chip {
  margin-left: auto; font-family: var(--mono); font-size: 11px; color: #37407A;
  background: #fff; border: 1px solid #DCE0FA; border-radius: 7px;
  padding: 5px 9px; white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Banner: token-blind aggregate (tb-bar)
 * ------------------------------------------------------------------------- */
.tb-bar {
  margin: 18px 30px 0; display: flex; align-items: center; gap: 12px;
  padding: 11px 15px; border-radius: 11px;
  background: var(--green-wash); border: 1px solid #CBE7D5;
}
.tb-bar .ic {
  width: 30px; height: 30px; border-radius: 8px;
  background: #fff; border: 1px solid #CBE7D5;
  display: grid; place-items: center; color: var(--green); flex-shrink: 0;
}
.tb-bar .tx { font-size: 12.5px; color: #215938; line-height: 1.4; }
.tb-bar .tx b { font-weight: 650; color: #164026; }
.tb-bar .chip {
  margin-left: auto; font-family: var(--mono); font-size: 11px; color: #215938;
  background: #fff; border: 1px solid #CBE7D5; border-radius: 7px;
  padding: 5px 9px; white-space: nowrap;
}

/* ---------------------------------------------------------------------------
 * Tabs
 * ------------------------------------------------------------------------- */
.tabs {
  display: flex; gap: 4px; padding: 20px 30px 0;
  border-bottom: 1px solid var(--line); margin-top: 18px;
}
.tabs a {
  display: flex; align-items: center; gap: 7px;
  padding: 9px 12px 13px; color: var(--muted);
  text-decoration: none; font-size: 13.5px; font-weight: 500;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tabs a .i { width: 15px; height: 15px; }
.tabs a.on { color: var(--ink); font-weight: 600; border-bottom-color: var(--ink); }

/* ---------------------------------------------------------------------------
 * Content wrap + group title
 * ------------------------------------------------------------------------- */
.wrap { padding: 22px 30px 30px; }
.gtitle { display: flex; align-items: center; gap: 9px; margin: 10px 2px 12px; }
.gtitle h3 { font-size: 14.5px; font-weight: 600; letter-spacing: -0.01em; }
.gtitle .n {
  font-size: 11px; font-weight: 600; color: var(--muted);
  background: #F1F1F4; border-radius: 20px; padding: 2px 8px;
}
.gtitle .lane { font-size: 12px; color: var(--faint); }
.gtitle .filt { margin-left: auto; }

/* ---------------------------------------------------------------------------
 * Board (generic grouped columns — Samen.UI.board/1; G1 kanban first client)
 * Horizontal, per-column-bounded lanes. Bounded horizontal scroll (value-blind,
 * like .table-scroll) so a wide board never breaks the page layout.
 * ------------------------------------------------------------------------- */
.board {
  display: flex; gap: 14px; align-items: flex-start;
  overflow-x: auto; padding-bottom: 8px;
}
.bcol {
  flex: 0 0 300px; max-width: 300px;
  background: var(--card); border: 1px solid var(--line2); border-radius: 12px;
  display: flex; flex-direction: column; max-height: 100%;
}
.bcol-h {
  display: flex; align-items: center; gap: 9px;
  padding: 12px 14px; border-bottom: 1px solid var(--line);
}
.bcol-t { font-size: 13.5px; font-weight: 600; letter-spacing: -0.01em; }
.bcol-n {
  font-size: 11px; font-weight: 600; color: var(--muted);
  background: #F1F1F4; border-radius: 20px; padding: 2px 8px;
}
.bcol-body { display: flex; flex-direction: column; gap: 8px; padding: 12px; overflow-y: auto; }
.bcard {
  border: 1px solid var(--line); border-radius: 10px; background: var(--bg);
  padding: 10px 12px;
}
.bcard .opp-row { display: flex; flex-direction: column; gap: 6px; }
.bcard .opp-meta { display: flex; align-items: center; gap: 8px; }
.bcol-empty { font-size: 12px; color: var(--faint); padding: 6px 2px; }
.bcol-more {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; border-top: 1px solid var(--line);
}
.bcol-more-n { font-size: 11.5px; color: var(--faint); }
.bcol-more-btn { margin-left: auto; font-size: 12px; padding: 4px 10px; }

/* ---------------------------------------------------------------------------
 * Calendar (generic month grid — Samen.UI.calendar/1; G2 first client)
 * A day-keyed %Samen.Web.Board{} laid out as a 6-week grid. Per-day-bounded
 * events + a "+N more" overflow; prev/next month are real <a href> links
 * (the no-JS navigation floor), never JS-only.
 * ------------------------------------------------------------------------- */
.cal {
  background: var(--card); border: 1px solid var(--line2); border-radius: 12px;
  overflow: hidden;
}
.cal-h {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.cal-title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.cal-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  font-size: 18px; line-height: 1; color: var(--muted); text-decoration: none;
  background: var(--bg);
}
.cal-nav:hover { border-color: var(--line2); color: var(--fg); }
.cal-nav-off { opacity: 0.35; }
.cal-wd {
  display: grid; grid-template-columns: repeat(7, 1fr);
  border-bottom: 1px solid var(--line);
}
.cal-wd-c {
  padding: 8px 10px; font-size: 11px; font-weight: 600; color: var(--faint);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.cal-week { display: grid; grid-template-columns: repeat(7, 1fr); }
.cal-cell {
  min-height: 104px; border-right: 1px solid var(--line); border-bottom: 1px solid var(--line);
  padding: 6px 7px; display: flex; flex-direction: column; gap: 5px; overflow: hidden;
}
.cal-week > .cal-cell:last-child { border-right: none; }
.cal-out { background: var(--bg); }
.cal-out .cal-daynum { color: var(--faint); }
.cal-today .cal-daynum {
  background: var(--accent, #17A06E); color: #fff; border-radius: 20px;
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
}
.cal-cell-h { display: flex; align-items: center; justify-content: space-between; }
.cal-daynum { font-size: 12px; font-weight: 600; color: var(--muted); }
.cal-cell-n {
  font-size: 10.5px; font-weight: 600; color: var(--muted);
  background: #F1F1F4; border-radius: 20px; padding: 1px 7px;
}
.cal-events { display: flex; flex-direction: column; gap: 4px; overflow-y: auto; }
.cal-ev {
  border: 1px solid var(--line); border-radius: 7px; background: var(--card);
  padding: 4px 7px; font-size: 11.5px;
}
.cal-ev .opp-ev { display: flex; flex-direction: column; gap: 3px; }
.cal-ev .opp-ev-meta { display: flex; align-items: center; gap: 6px; }
.cal-ev-name { font-weight: 500; }
.cal-cell-empty { font-size: 11px; color: var(--faint); }
.cal-more { font-size: 10.5px; color: var(--faint); padding: 1px 2px; }

@media (max-width: 720px) {
  .cal-cell { min-height: 72px; }
  .cal-wd-c { padding: 6px 4px; font-size: 10px; }
}

/* ---------------------------------------------------------------------------
 * Gantt / timeline (generic horizontal view — Samen.UI.gantt/1; G3 first client)
 * A lane-keyed %Samen.Web.Board{} whose rows are BARS positioned by a start..end
 * range. left/width are server-computed % (no-JS layout); a NULL end is a point
 * marker (min-width), never an infinite bar; prev/next are real <a href> links.
 * The whole layout scrolls horizontally inside its own track (never the page).
 * ------------------------------------------------------------------------- */
.gantt {
  background: var(--card); border: 1px solid var(--line2); border-radius: 12px;
  overflow: hidden;
}
.gantt-h {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.gantt-title { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; }
.gantt-nav {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  font-size: 18px; line-height: 1; color: var(--muted); text-decoration: none;
  background: var(--bg);
}
.gantt-nav:hover { border-color: var(--line2); color: var(--fg); }
.gantt-nav-off { opacity: 0.35; }

/* label gutter + track: lanes share a fixed header column and a positioned track. */
.gantt-axis, .gantt-lane {
  display: grid; grid-template-columns: 180px 1fr; align-items: stretch;
}
.gantt-axis { border-bottom: 1px solid var(--line); background: var(--bg); }
.gantt-axis-h { border-right: 1px solid var(--line); }
.gantt-axis-track { position: relative; height: 30px; overflow: hidden; }
.gantt-tick {
  position: absolute; top: 0; transform: translateX(-50%);
  padding: 8px 4px 0; font-size: 10.5px; font-weight: 600; color: var(--faint);
  white-space: nowrap; text-transform: uppercase; letter-spacing: 0.03em;
}
.gantt-tick:first-child { transform: none; }
.gantt-tick:last-child { transform: translateX(-100%); }

.gantt-lanes { display: flex; flex-direction: column; }
.gantt-lane { border-bottom: 1px solid var(--line); min-height: 46px; }
.gantt-lane:last-child { border-bottom: none; }
.gantt-lane-h {
  display: flex; align-items: center; gap: 8px; padding: 8px 12px;
  border-right: 1px solid var(--line); font-size: 12.5px; font-weight: 600; color: var(--fg);
}
.gantt-lane-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gantt-lane-n {
  font-size: 10.5px; font-weight: 600; color: var(--muted);
  background: #F1F1F4; border-radius: 20px; padding: 1px 7px;
}
.gantt-lane-track {
  position: relative; padding: 6px 0; min-height: 46px; overflow: hidden;
}
.gantt-bar {
  position: absolute; box-sizing: border-box; min-width: 8px; height: 22px;
  margin-top: 4px; border: 1px solid var(--line2); border-radius: 6px;
  background: var(--card); overflow: hidden;
}
.gantt-bar-point {
  width: 12px !important; border-radius: 50%; background: var(--accent, #17A06E);
  border-color: var(--accent, #17A06E);
}
.gantt-bar-in {
  display: flex; align-items: center; gap: 6px; height: 100%;
  padding: 0 7px; font-size: 11px; white-space: nowrap;
}
.gantt-bar-point .gantt-bar-in { padding: 0; overflow: hidden; }
.gantt-now {
  position: absolute; top: 0; bottom: 0; width: 2px; margin-left: -1px;
  background: var(--accent, #17A06E); opacity: 0.55; z-index: 1;
}
.gantt-lane-empty {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  font-size: 11px; color: var(--faint);
}
.gantt-more {
  position: absolute; right: 8px; bottom: 3px; font-size: 10.5px; color: var(--faint);
}
.gantt-empty { padding: 18px; font-size: 12px; color: var(--faint); text-align: center; }

@media (max-width: 720px) {
  .gantt-axis, .gantt-lane { grid-template-columns: 110px 1fr; }
  .gantt-lane-h { padding: 6px 8px; font-size: 11.5px; }
}

/* ---------------------------------------------------------------------------
 * Card + data table
 * ------------------------------------------------------------------------- */
.card {
  border: 1px solid var(--line2); border-radius: 12px;
  overflow: hidden; margin-bottom: 26px; background: var(--card);
}
table { width: 100%; border-collapse: collapse; }
thead th {
  text-align: left; font-size: 11.5px; font-weight: 550; color: var(--faint);
  padding: 11px 16px; border-bottom: 1px solid var(--line);
  letter-spacing: .01em; white-space: nowrap;
}
tbody td {
  padding: 13px 16px; border-bottom: 1px solid var(--line);
  font-size: 13.5px; vertical-align: middle;
}
tbody tr:last-child td { border-bottom: none; }
tbody tr:hover { background: #FCFCFD; }
td.right { text-align: right; }

/* ---------------------------------------------------------------------------
 * Subject cell (avatar + name)
 * ------------------------------------------------------------------------- */
.drv { display: flex; align-items: center; gap: 11px; }
.drv .av {
  width: 28px; height: 28px; border-radius: 50%; flex-shrink: 0;
  display: grid; place-items: center; font-size: 0;
  background: #E6E7EF; position: relative;
}
.drv .av::after {
  content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: repeating-linear-gradient(115deg, #D3D5E4 0 5px, #DEE0EC 5px 10px);
}
.drv .nm { font-weight: 550; letter-spacing: .02em; color: #454652; }
.mono { font-family: var(--mono); font-size: 12.5px; letter-spacing: .02em; }
.masked { color: #8C8D99; letter-spacing: .12em; }
.carrier { color: var(--muted); }

/* ---------------------------------------------------------------------------
 * Pills (status badges): ok / warn / bad / info / mut
 * ------------------------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; font-weight: 550; padding: 3px 10px;
  border-radius: 100px; white-space: nowrap; line-height: 1.5;
}
.pill .d { width: 6px; height: 6px; border-radius: 50%; }
.pill.ok { background: var(--green-wash); color: var(--green); }
.pill.ok .d { background: var(--green); }
.pill.warn { background: var(--amber-wash); color: var(--amber); }
.pill.warn .d { background: var(--amber); }
.pill.bad { background: var(--red-wash); color: var(--red); }
.pill.bad .d { background: var(--red); }
.pill.info { background: var(--violet-wash); color: var(--violet); }
.pill.info .d { background: var(--violet); }
.pill.mut { background: #F1F1F4; color: var(--muted); }
.pill.mut .d { background: var(--faint); }

/* ---------------------------------------------------------------------------
 * Progress bar
 * ------------------------------------------------------------------------- */
.prog { display: flex; align-items: center; gap: 10px; min-width: 120px; }
.prog .track { flex: 1; height: 5px; border-radius: 100px; background: #EDEDF1; overflow: hidden; }
.prog .fill { height: 100%; border-radius: 100px; }
.prog .pct { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; width: 64px; text-align: right; }

/* Health bar variant (aggregate plane) — thicker track, brand fill default */
.bar { display: flex; align-items: center; gap: 10px; min-width: 120px; }
.bar .track { flex: 1; height: 6px; border-radius: 100px; background: #EDEDF1; overflow: hidden; }
.bar .fill { height: 100%; border-radius: 100px; background: var(--brand); }
.bar .pct { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
 * Reveal chip (per-subject unmask control)
 * ------------------------------------------------------------------------- */
.rev {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--faint);
  border: 1px solid var(--line2); border-radius: 7px;
  padding: 4px 9px; background: var(--card); cursor: pointer;
}
.rev .i { width: 13px; height: 13px; }

/* ---------------------------------------------------------------------------
 * Metric cards
 * ------------------------------------------------------------------------- */
.metrics { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; padding: 18px 30px 0; }
.metric { border: 1px solid var(--line2); border-radius: 12px; padding: 15px 17px; background: var(--card); }
.metric .k {
  font-size: 11.5px; color: var(--faint); font-weight: 500;
  display: flex; align-items: center; gap: 6px; margin-bottom: 9px;
}
.metric .k .i { width: 13px; height: 13px; }
.metric .v {
  font-size: 25px; font-weight: 650; letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums; display: flex; align-items: baseline; gap: 8px;
}
.metric .v .delta { font-size: 12px; font-weight: 600; }
.metric .up { color: var(--green); }
.metric .down { color: var(--red); }
.metric .sub { margin-top: 9px; font-size: 11.5px; color: var(--faint); }
.metric .spark { margin-top: 11px; display: flex; align-items: flex-end; gap: 3px; height: 24px; }
.metric .spark i { flex: 1; background: #E4E7FB; border-radius: 2px 2px 0 0; }
.metric .spark i.hi { background: var(--brand); }

.num { font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------------------------------
 * k-anonymity suppression footnote (aggregate plane)
 * ------------------------------------------------------------------------- */
.supp {
  display: flex; align-items: center; gap: 9px;
  padding: 13px 16px; color: var(--faint);
  font-size: 12.5px; font-style: italic;
}
.supp .lk { width: 14px; height: 14px; }

/* ---------------------------------------------------------------------------
 * Split layout (loads table + settlement reshape card)
 * ------------------------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1fr 340px; gap: 20px; align-items: start; }

/* ---------------------------------------------------------------------------
 * Settlement reshape card (settle)
 * ------------------------------------------------------------------------- */
.settle { border: 1px solid var(--line2); border-radius: 12px; background: var(--card); overflow: hidden; }
.settle .sh { padding: 14px 18px; border-bottom: 1px solid var(--line); display: flex; align-items: center; gap: 9px; }
.settle .sh b { font-size: 14px; font-weight: 600; }
.settle .sh .tag {
  margin-left: auto; font-family: var(--mono); font-size: 10.5px; color: var(--brand);
  background: var(--brand-wash); border: 1px solid #DCE0FA; border-radius: 6px; padding: 3px 7px;
}
.settle .row { display: flex; align-items: center; justify-content: space-between; padding: 10px 18px; font-size: 13px; }
.settle .row .lab { color: var(--muted); }
.settle .row .lab i { font-style: normal; font-family: var(--mono); font-size: 11px; color: var(--faint); margin-left: 6px; }
.settle .row .val { font-family: var(--mono); font-size: 13px; font-variant-numeric: tabular-nums; }
.settle .row.neg .val { color: var(--red); }
.settle .row.net { border-top: 1px solid var(--line); background: #FAFBFD; padding: 14px 18px; }
.settle .row.net .lab { color: var(--ink); font-weight: 600; font-family: inherit; font-size: 13.5px; }
.settle .row.net .val { font-weight: 700; font-size: 15px; color: var(--green); }
.settle .foot2 { padding: 11px 18px; border-top: 1px solid var(--line); font-size: 11.5px; color: var(--faint); line-height: 1.5; }

/* ---------------------------------------------------------------------------
   Object-unfurl card (ADR-012 §4.4) — the masking-aware-per-viewer live card.
   A %Masked{} value renders "••••" verbatim (no CSS knows or cares).
   --------------------------------------------------------------------------- */
.obj-card { display: inline-flex; gap: 10px; align-items: flex-start; max-width: 340px;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px;
  background: #FAFBFD; vertical-align: top; }
.obj-card-avatar { flex: 0 0 auto; width: 28px; height: 28px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--green); color: #fff; font-weight: 700; font-size: 13px; }
.obj-card-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.obj-card-kicker { font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
  color: var(--faint); font-weight: 600; }
.obj-card-title { font-size: 13.5px; font-weight: 650; color: var(--ink); line-height: 1.25; }
.obj-card-link { color: var(--ink); text-decoration: none; }
.obj-card-link:hover { text-decoration: underline; }
.obj-card-badges { display: inline-flex; gap: 5px; flex-wrap: wrap; margin-top: 2px; }
.obj-card-fields { display: flex; flex-direction: column; gap: 1px; margin-top: 3px; }
.obj-card-field { display: inline-flex; gap: 6px; font-size: 12px; }
.obj-card-field-label { color: var(--faint); min-width: 52px; }
.obj-card-field-value { color: var(--ink2, #475569); }
.obj-card-na { background: #FBFBFB; border-style: dashed; align-items: center; color: var(--faint); }
.obj-na-icon { font-size: 13px; }
.obj-na-text { font-size: 12.5px; }

/* ---------------------------------------------------------------------------
   Cross-plane realtime chat (ADR-012 §6) — append-only. Masking-safe: every PII
   value is the resolver's already-resolved field, so a %Masked{} renders •••• .
   --------------------------------------------------------------------------- */
.chat-layout { display: flex; gap: 18px; align-items: flex-start; }
.chat-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 12px; }
.chat-aside { flex: 0 0 240px; }
.chat-messages { display: flex; flex-direction: column; gap: 10px; }
.chat-msg { background: #fff; border: 1px solid var(--line, #E7E9EE); border-radius: 10px;
  padding: 10px 12px; max-width: 560px; }
.chat-msg-mine { align-self: flex-end; background: #F3F8F5; }
.chat-msg-head { display: flex; gap: 8px; align-items: center; margin-bottom: 4px; }
.chat-msg-handle { font-size: 12.5px; font-weight: 650; color: var(--ink); }
.chat-msg-body { font-size: 13.5px; color: var(--ink2, #475569); line-height: 1.4; white-space: pre-wrap; }
.chat-msg-unfurls { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.chat-composer { display: flex; gap: 8px; }
.chat-composer input { flex: 1 1 auto; padding: 9px 11px; border: 1px solid var(--line, #E7E9EE);
  border-radius: 8px; font-size: 13.5px; }
.chat-roster { display: flex; flex-direction: column; gap: 6px; }
.chat-roster-row { display: flex; gap: 8px; align-items: center; font-size: 13px; }
.chat-roster-dot { width: 8px; height: 8px; border-radius: 50%; background: #CBD5E1; flex: 0 0 auto; }
.chat-roster-dot.online { background: var(--green, #17A06E); }
.chat-roster-handle { font-weight: 600; color: var(--ink); }
.chat-identity-chip { font-size: 12px; color: var(--faint); }
/* Inbox identity controls (ADR-012 §5 write side) — the tenant setting + new-conversation opt-in. */
.chat-settings, .chat-new { padding: 16px 18px; }
.chat-switch { display: flex; gap: 9px; align-items: center; font-size: 13px; color: var(--ink2, #475569); cursor: pointer; }
.chat-switch input { width: 15px; height: 15px; flex: 0 0 auto; }
.chat-new form { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.chat-new input[type="text"] { width: 100%; padding: 9px 11px; border: 1px solid var(--line, #E7E9EE);
  border-radius: 8px; font-size: 13.5px; }
.chat-flash { background: #F3F8F5; border: 1px solid var(--green, #17A06E); color: #14532d;
  padding: 9px 13px; border-radius: 8px; font-size: 13px; margin-bottom: 14px; }
.side-min { padding: 14px 16px; display: flex; flex-direction: column; gap: 2px; }
.side-min b { font-size: 14px; color: var(--ink); }
.side-min span { font-size: 11px; color: var(--faint); text-transform: uppercase; letter-spacing: .05em; }

/* Workspace switcher (ADR-013 §5.1) — the sidebar chevron becomes a real tenant picker.
   Plain native <details> disclosure so it works on the dead render with no JS hook. */
.ws-switcher { margin-left: auto; position: relative; }
.ws-switcher > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; gap: 4px;
  color: var(--faint); font-size: 12px; padding: 3px 6px; border-radius: 7px;
  border: 1px solid transparent; user-select: none;
}
.ws-switcher > summary::-webkit-details-marker { display: none; }
.ws-switcher > summary:hover { background: var(--card); border-color: var(--line2); color: var(--ink); }
.ws-switcher-name { max-width: 120px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 550; }
.ws-switcher-chevron { font-size: 14px; line-height: 1; }
.ws-switcher[open] > summary { background: var(--card); border-color: var(--line2); color: var(--ink); }
.ws-switcher-menu {
  position: absolute; top: calc(100% + 6px); left: 0; min-width: 220px; z-index: 40;
  background: #fff; border: 1px solid var(--line2); border-radius: 10px; padding: 6px;
  box-shadow: 0 12px 30px rgba(20, 22, 30, 0.14);
}
.ws-switcher-group {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--faint);
  padding: 6px 8px 4px;
}
/* S7: each workspace row is a zero-JS POST <form><button> (the switch is a session write,
   so it rides a CSRF-protected POST, not a forgeable GET). The button restyles to the
   exact anchor look so the menu renders unchanged. */
.ws-switcher-form { margin: 0; }
.ws-switcher-item {
  display: block; width: 100%; text-align: left; padding: 8px 10px; border-radius: 7px;
  font-size: 13px; font-family: inherit; background: none; border: 0; cursor: pointer;
  color: var(--ink); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.ws-switcher-item:hover { background: var(--card); }
.ws-switcher-item.on { background: #EEF1FC; color: #3B4CCA; font-weight: 600; }
.ws-switcher-sep { height: 1px; background: var(--line); margin: 6px 4px; }
.ws-switcher-ops { color: var(--muted); font-weight: 550; }

/* Operator sidebar "act as a tenant →" launcher (ADR-013 §5.1 — the down path). */
.op-act-as { padding: 8px 10px 4px; }
.op-act-as .grp {
  font-size: 10px; text-transform: uppercase; letter-spacing: .06em; color: var(--faint);
  padding: 4px 4px 6px;
}
.op-act-as .ws-switcher { margin-left: 0; }
.op-act-as .ws-switcher > summary { border: 1px solid var(--line2); background: var(--card); justify-content: space-between; }
.op-act-as .ws-switcher-name { max-width: 150px; }

/* T116 / P9-F3 — the PLANE-LEGIBILITY BADGE. A persistent chrome element at the top of every
 * shared main pane that answers "which plane / whose org." Glyph discipline: a doc/org glyph
 * for the tenant plane, a SHIELD glyph for operator presence (operator plane + acting-as
 * crossing) — so the two planes are distinguishable by SHAPE, not only colour, even where the
 * sidebar glyph LETTER collides (uxwalk's pixel-identical "S", P9-F1). Colour is driven by
 * [data-plane]/[data-crossing]. */
.plane-badge {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 8px 13px; border-radius: 10px; font-size: 13px; margin: 14px;
  border: 1px solid transparent;
}
.plane-badge .pb-glyph-wrap { display: inline-flex; flex: 0 0 auto; }
.plane-badge .pb-glyph { width: 17px; height: 17px; }
.plane-badge .pb-name { flex: 1 1 auto; }
.plane-badge .pb-name b { font-weight: 650; }
.plane-badge .pb-pill {
  flex: 0 0 auto; font-size: 11px; font-weight: 600; letter-spacing: .01em;
  padding: 2px 9px; border-radius: 999px; white-space: nowrap;
}

/* Tenant plane — calm green (data in the clear, you're on your own org). */
.plane-badge.plane-tenant { background: #EBF7F0; border-color: #BFE3CF; color: #1E7A45; }
.plane-badge.plane-tenant .pb-pill { background: #D6EFE0; color: #146138; }

/* Operator plane — indigo (masked, cross-tenant SaaS staff). */
.plane-badge.plane-operator { background: #EEF1FC; border-color: #C7CFF3; color: #2C378F; }
.plane-badge.plane-operator .pb-pill { background: #DBE1F8; color: #26307C; }

/* "You are viewing <tenant> · Return to <operator>" crossing marker (ADR-013 §5.3, T116). The
 * dangerous operator→tenant crossing — amber, strong, unmistakable. Keeps the `.acting-as-bar`
 * contract for backwards compatibility. */
.plane-badge.plane-crossing, .acting-as-bar {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  background: #FDF3E3; border: 1px solid #F0D28C; color: #8A5A11;
  padding: 9px 14px; border-radius: 10px; font-size: 13px; margin: 14px;
}
.acting-as-tx { flex: 1 1 auto; }
.acting-as-tx b { font-weight: 650; }
.acting-as-return { color: #B4690E; text-decoration: none; font-weight: 600; white-space: nowrap; }
.acting-as-return:hover { text-decoration: underline; }

/* ===========================================================================
 * WS-E E6 — Responsive kit pass (ADR-030) + shipped-surface styling.
 *
 * SCOPE (RP-RE-3 structural guard): this section is CSS-only. It restyles the
 * shared kit — the `.app` shell, `.side` drawer, `.card`/table scroll, the ⌘K
 * palette (`.cmdk*`), the per-list `search_box` (`.search`/`.search-input`),
 * and the `skeleton/1` primitive. It NEVER touches value resolution: a
 * %Samen.Masked{} renders `••••` at every breakpoint because masking lives in
 * the value layer, not here (design §1.5 / AC-G20-2).
 * ========================================================================= */

/* --- ⌘K command palette (E4.3 surface — shipped without styling; dressed here) --- */
.pane { padding: 22px 30px 30px; }
.cmdk {
  max-width: 640px; margin: 0 auto;
  background: var(--card); border: 1px solid var(--line2);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 10px 30px rgba(20, 22, 30, .08);
}
.cmdk-form { padding: 4px; border-bottom: 1px solid var(--line); }
.cmdk-input {
  width: 100%; border: 0; outline: none; background: transparent;
  padding: 14px 16px; font-size: 15px; color: var(--ink);
  font-family: inherit; letter-spacing: -0.01em;
}
.cmdk-input::placeholder { color: var(--faint); }
.cmdk-results { list-style: none; max-height: 60vh; overflow-y: auto; }
.cmdk-hit {
  display: flex; align-items: center; gap: 12px;
  padding: 11px 16px; border-bottom: 1px solid var(--line);
  cursor: pointer;
}
.cmdk-hit:last-child { border-bottom: none; }
.cmdk-hit:hover { background: #FCFCFD; }
.cmdk-kind {
  flex: 0 0 auto; font-size: 10.5px; font-weight: 600; letter-spacing: .04em;
  text-transform: uppercase; color: var(--brand);
  background: var(--brand-wash); border: 1px solid #DCE0FA;
  border-radius: 6px; padding: 3px 8px;
}
.cmdk-label { min-width: 0; font-size: 13.5px; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmdk-empty { padding: 22px 16px; color: var(--faint); font-size: 13px; text-align: center; }

/* --- per-list search box (E4.3 / carry b): the .search slot as a real form --- */
.search form, form.search { display: contents; }
.search .search-input {
  flex: 1 1 auto; min-width: 0; border: 0; outline: none;
  background: transparent; font: inherit; font-size: 13px;
  color: var(--ink); padding: 0;
}
.search .search-input::placeholder { color: var(--faint); }
.search .i { width: 15px; height: 15px; flex-shrink: 0; color: var(--faint); }

/* --- skeleton loading primitive (E6.2) + shimmer keyframes --- */
@keyframes samen-shimmer {
  0% { background-position: -320px 0; }
  100% { background-position: 320px 0; }
}
.skeleton { display: flex; flex-direction: column; gap: 12px; padding: 8px 2px; }
.skeleton-row { display: flex; align-items: center; gap: 12px; }
.skeleton-line {
  height: 12px; border-radius: 6px; flex: 1 1 auto;
  background: linear-gradient(90deg, #EDEDF1 25%, #F5F5F8 50%, #EDEDF1 75%);
  background-size: 640px 100%;
  animation: samen-shimmer 1.3s ease-in-out infinite;
}
.skeleton-line.narrow { flex: 0 0 22%; }
.skeleton-line.avatar { flex: 0 0 28px; height: 28px; border-radius: 50%; }
@media (prefers-reduced-motion: reduce) {
  .skeleton-line { animation: none; }
}

/* --- responsive data_table variant: bounded horizontal scroll (never clips a cell) --- */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* --- off-canvas sidebar drawer scaffold (kit affordance; pure-CSS checkbox toggle) --- */
.nav-toggle-cb { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.nav-hamburger {
  display: none; position: fixed; top: 16px; left: 16px; z-index: 50;
  width: 40px; height: 40px; border-radius: 10px; cursor: pointer;
  background: var(--panel); border: 1px solid var(--line2);
  align-items: center; justify-content: center; color: var(--ink);
  box-shadow: 0 1px 3px rgba(20, 22, 30, .1);
}
.nav-hamburger .i { width: 18px; height: 18px; }
.nav-scrim {
  display: none; position: fixed; inset: 0; z-index: 44;
  background: rgba(15, 16, 24, .38);
}

/* ---------------------------------------------------------------------------
 * Breakpoint 1 — tablet (≤ 860px): the two-pane grid stays but tightens.
 * ------------------------------------------------------------------------- */
@media (max-width: 860px) {
  .app { grid-template-columns: 216px 1fr; padding: 8px; gap: 8px; }
  .metrics { grid-template-columns: repeat(2, 1fr); }
  .split { grid-template-columns: 1fr; }
  .top, .wrap, .pane { padding-left: 20px; padding-right: 20px; }
}

/* ---------------------------------------------------------------------------
 * Breakpoint 2 — mobile (≤ 560px): single column; sidebar becomes an
 * off-canvas drawer behind the hamburger; tables scroll; metrics stack.
 * ------------------------------------------------------------------------- */
@media (max-width: 560px) {
  .app { grid-template-columns: 1fr; height: auto; min-height: 100vh; padding: 0; gap: 0; }
  .main { border-radius: 0; border: none; }

  /* Sidebar slides in from the left; hidden until the checkbox is toggled. */
  .side {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 46;
    width: 272px; max-width: 86vw; border-radius: 0;
    transform: translateX(-104%);
    transition: transform .22s ease;
    box-shadow: 0 0 40px rgba(20, 22, 30, .18);
  }
  .nav-toggle-cb:checked ~ .side { transform: translateX(0); }
  .nav-toggle-cb:checked ~ .nav-scrim { display: block; }
  .nav-hamburger { display: inline-flex; }

  /* Give the main pane room for the fixed hamburger. */
  .top { padding-top: 66px; }

  .metrics { grid-template-columns: 1fr; padding-left: 16px; padding-right: 16px; }
  .top, .wrap, .pane { padding-left: 16px; padding-right: 16px; }
  .head h1 { font-size: 22px; }
  .mask-bar, .tb-bar, .tabs { margin-left: 16px; margin-right: 16px; }
  .tabs { padding-left: 4px; padding-right: 4px; overflow-x: auto; }

  /* Tables never clip: horizontal scroll inside their own container. */
  .card { overflow-x: auto; }
  .cmdk { margin: 0; box-shadow: none; }
}

/* -------------------------------------------------------------------------
 * Gallery (generic responsive card grid — Samen.UI.gallery/1; G5 first client)
 * A keyset-bounded %Samen.Web.Page{} laid out as cards. Prev/next are real
 * <a href> links (?after=<id> keyset cursor); an optional Load-more button is a
 * JS enhancement layered on top. A dumb renderer — masking is the resolver's.
 * ------------------------------------------------------------------------- */
.gallery { display: flex; flex-direction: column; gap: 12px; }
.gallery-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.gcard {
  display: flex; align-items: flex-start; gap: 12px;
  background: var(--card); border: 1px solid var(--line2); border-radius: 12px;
  padding: 14px; min-width: 0;
}
.gcard-media { flex: 0 0 auto; }
.gcard-mono {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 10px;
  background: var(--brand-wash); color: var(--brand);
  font-size: 13px; font-weight: 700; letter-spacing: 0.02em;
}
.gcard-body { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.gcard-name { font-size: 13.5px; font-weight: 600; letter-spacing: -0.01em; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gcard-sub { font-size: 12.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gcard-title { font-size: 11.5px; color: var(--faint); }
.gcard-email { font-size: 11.5px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.gallery-footer { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.gallery-page-link { text-decoration: none; }
.gallery-page-off { opacity: 0.4; pointer-events: none; }
.gallery-page-size { font-size: 12px; color: var(--muted); margin-left: auto; }

/* -------------------------------------------------------------------------
 * Tree (generic hierarchical nodes — Samen.UI.tree/1; G6 first client)
 * A depth-bounded, cycle-safe, per-parent-bounded %Samen.Web.Tree{} rendered as
 * nested <ul>/<details>. A loaded subtree collapses via native <details> (no
 * JS). A truncated node (depth/budget) offers a real ?focus=<id> drill-in link
 * (the no-JS floor); a :cycle node is an inert marker. A dumb renderer.
 * ------------------------------------------------------------------------- */
.tree {
  background: var(--card); border: 1px solid var(--line2); border-radius: 12px;
  padding: 10px 12px; overflow-x: auto;
}
.tree-lvl { list-style: none; margin: 0; padding: 0; }
.tree-lvl .tree-lvl { margin-left: 18px; border-left: 1px solid var(--line); padding-left: 8px; }
.tree-node { margin: 0; }
.tree-det > summary { list-style: none; cursor: pointer; }
.tree-det > summary::-webkit-details-marker { display: none; }
.tree-row {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 6px; border-radius: 8px; min-height: 30px;
}
.tree-row:hover { background: var(--brand-wash); }
.tree-twist {
  flex: 0 0 auto; width: 10px; height: 10px; position: relative;
}
.tree-det > summary .tree-twist::before {
  content: "▸"; position: absolute; left: -1px; top: -3px;
  font-size: 10px; color: var(--faint); transition: transform .15s ease;
}
.tree-det[open] > summary .tree-twist::before { transform: rotate(90deg); }
.tree-twist-leaf::before { content: "•"; position: absolute; left: 0; top: -6px; color: var(--line2); }
.tree-label { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tree-task-name { font-size: 12.5px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tree-more { margin: 2px 0 4px 18px; font-size: 11.5px; color: var(--faint); }
.tree-drill {
  font-size: 11.5px; color: var(--brand); text-decoration: none; font-weight: 600;
}
.tree-drill:hover { text-decoration: underline; }
.tree-cycle { font-size: 11px; color: var(--red); font-weight: 600; }
.tree-cyc { opacity: 0.75; }
.tree-empty { font-size: 12.5px; color: var(--faint); padding: 6px 4px; }
.tree-focus-note { font-size: 12.5px; color: var(--muted); margin: 0 0 10px; }

/* ── Charts + dashboard (G8, T56) ───────────────────────────────────────── */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.dash-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 14px; margin: 16px 0;
}
.dash-tile {
  background: var(--card, #fff); border: 1px solid var(--line, #E7E7EC);
  border-radius: 12px; padding: 14px 16px; min-width: 0;
}
.dash-tile.span-2 { grid-column: span 2; }
.dash-tile-title { font-size: 12px; font-weight: 600; color: var(--muted); margin: 0 0 10px; }
@media (max-width: 900px) {
  .dash-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dash-tile.span-2 { grid-column: span 2; }
}
@media (max-width: 560px) {
  .dash-grid { grid-template-columns: 1fr; }
  .dash-tile.span-2 { grid-column: span 1; }
}
.chart { margin: 0; min-width: 0; }
.chart-title { font-size: 12.5px; font-weight: 600; color: var(--ink, #1b1c22); margin: 0 0 8px; }
.chart-svg { width: 100%; height: auto; display: block; }
.chart-svg-pie { width: 130px; height: 130px; flex-shrink: 0; }
.chart-axis { stroke: var(--line, #E7E7EC); stroke-width: 1; }
.chart-xlabel { font-size: 9px; fill: var(--muted); }
.chart-bar-rect { rx: 2; }
.chart-donut-hole { fill: var(--card, #fff); }
.chart-empty { font-size: 12.5px; color: var(--faint, #9a9ba5); padding: 12px 4px; }
.chart-pie-wrap { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.chart-legend { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.chart-legend-item { display: flex; align-items: center; gap: 7px; font-size: 12px; }
.chart-swatch { width: 10px; height: 10px; border-radius: 2px; flex-shrink: 0; }
.chart-legend-label { color: var(--ink, #1b1c22); }
.chart-legend-val { color: var(--muted); margin-left: auto; white-space: nowrap; }
.chart-data { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; }
.chart-data th, .chart-data td { text-align: left; padding: 4px 6px; border-bottom: 1px solid var(--line, #E7E7EC); }
.chart-data td { text-align: right; font-variant-numeric: tabular-nums; }

/* Map view (G7, T55) — self-contained SVG basemap + projected pins. No external tiles/CDN. */
.geo-map { margin: 0; min-width: 0; }
.geo-map-title { font-size: 12.5px; font-weight: 600; color: var(--ink, #1b1c22); margin: 0 0 8px; }
.geo-map-canvas { width: 100%; border: 1px solid var(--line, #E7E7EC); border-radius: 6px; overflow: hidden; }
.geo-map-svg { width: 100%; height: auto; display: block; }
.geo-map-ocean { fill: var(--surface, #f4f6fb); }
.geo-land { fill: var(--line, #d7dbe6); stroke: var(--muted, #9a9ba5); stroke-width: 0.4; stroke-linejoin: round; }
.geo-map-tiles { image-rendering: auto; }
.geo-marker-dot { fill: #ef4444; stroke: #fff; stroke-width: 0.6; }
.geo-map-notice { font-size: 12px; color: var(--muted); margin: 0 0 8px; }
.geo-map-capped { font-size: 12px; color: var(--faint, #9a9ba5); margin: 8px 0 0; }
.geo-map-data { width: 100%; border-collapse: collapse; font-size: 12px; margin-top: 8px; }
.geo-map-data th, .geo-map-data td { text-align: left; padding: 4px 6px; border-bottom: 1px solid var(--line, #E7E7EC); }
.geo-map-data td { text-align: right; font-variant-numeric: tabular-nums; }

/* Global input height — taller inputs for better usability */
input[type="text"], input[type="email"], input[type="password"], input[type="number"], input[type="url"], input[type="tel"], input[type="search"], input[type="date"], select, textarea {
  min-height: 42px;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.5;
}
