/* =====================================================================
   SiteFlow Services Ltd — Field Operations demo
   1. Design tokens
   2. Reset & base
   3. Layout shell (sidebar, topbar, page head)
   4. Primitives (buttons, forms, badges, chips, cards)
   5. Tables, filters, pagination
   6. Overlays (modal, drawer, popover, toast, menus)
   7. Views (dashboard, schedule, map, field mode, detail pages)
   8. Responsive
   9. Print
   ===================================================================== */

/* ============================ 1. TOKENS ============================= */
:root {
  color-scheme: light;

  /* Neutral / surface */
  --bg:            #f4f2ec;
  --surface:       #ffffff;
  --surface-2:     #faf9f5;
  --surface-3:     #efece4;
  --surface-sunk:  #e9e5db;
  --border:        #e0dbcf;
  --border-strong: #c9c2b1;
  --overlay:       rgba(24, 30, 26, .48);

  /* Text */
  --text:    #1d241f;
  --text-2:  #545e56;
  --text-3:  #7c857d;
  --text-inv:#ffffff;

  /* Navigation (deep forest) */
  --nav-bg:        #1b2a21;
  --nav-bg-2:      #16221b;
  --nav-border:    #2b3d31;
  --nav-text:      #c3cfc6;
  --nav-text-dim:  #8ea094;
  --nav-active-bg: #27402f;
  --nav-active-bar:#7cc48a;

  /* Brand + status */
  --accent:        #2f6b45;
  --accent-hover:  #275a3a;
  --accent-soft:   #e6f0e8;
  --accent-text:   #1f4c31;

  --ok:        #2c7a4d;
  --ok-soft:   #e3f1e7;
  --ok-text:   #1d5636;

  --warn:      #a8690a;
  --warn-soft: #fbeed6;
  --warn-text: #7a4c05;

  --info:      #1d6493;
  --info-soft: #e2eef7;
  --info-text: #144a6e;

  --danger:      #b02a21;
  --danger-soft: #fbe6e3;
  --danger-text: #83201a;

  --neutral-soft: #ebe8e0;
  --neutral-text: #4c554e;

  --purple:      #61469b;
  --purple-soft: #ece7f7;
  --purple-text: #47327a;

  /* Shape & motion */
  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;
  --r-lg: 12px;
  --r-pill: 999px;

  --sh-1: 0 1px 2px rgba(24, 30, 26, .06), 0 1px 3px rgba(24, 30, 26, .05);
  --sh-2: 0 2px 6px rgba(24, 30, 26, .07), 0 6px 16px rgba(24, 30, 26, .07);
  --sh-3: 0 10px 34px rgba(24, 30, 26, .17);

  --ff: "Segoe UI", Roboto, -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --ff-mono: ui-monospace, "Cascadia Mono", Consolas, "SF Mono", Menlo, monospace;

  --sidebar-w: 244px;
  --sidebar-w-collapsed: 68px;
  --topbar-h: 60px;
  --gutter: 24px;

  --focus: 0 0 0 2px var(--surface), 0 0 0 4px #3d8b5c;
  --dur: 160ms;
}

[data-theme="dark"] {
  color-scheme: dark;

  --bg:            #10150f;
  --surface:       #1a201b;
  --surface-2:     #1f2620;
  --surface-3:     #262e27;
  --surface-sunk:  #151b16;
  --border:        #303a32;
  --border-strong: #46524a;
  --overlay:       rgba(6, 10, 7, .66);

  --text:   #e8ece8;
  --text-2: #a9b4ac;
  --text-3: #808c84;

  --nav-bg:        #131b15;
  --nav-bg-2:      #0f1611;
  --nav-border:    #253026;
  --nav-text:      #b7c4bb;
  --nav-text-dim:  #7e8c83;
  --nav-active-bg: #22332a;
  --nav-active-bar:#7cc48a;

  --accent:       #4f9a6b;
  --accent-hover: #5cad79;
  --accent-soft:  #1e3126;
  --accent-text:  #9ad5ae;

  --ok:        #4f9a6b;
  --ok-soft:   #1c3125;
  --ok-text:   #93d3aa;

  --warn:      #d69a3c;
  --warn-soft: #362a15;
  --warn-text: #f0c383;

  --info:      #4f95c8;
  --info-soft: #16293a;
  --info-text: #97c6e6;

  --danger:      #d9645a;
  --danger-soft: #3a1f1c;
  --danger-text: #f0a49c;

  --neutral-soft: #2a322c;
  --neutral-text: #b3bdb5;

  --purple:      #9985d1;
  --purple-soft: #272042;
  --purple-text: #c3b4ec;

  --sh-1: 0 1px 2px rgba(0,0,0,.4);
  --sh-2: 0 2px 6px rgba(0,0,0,.4), 0 8px 20px rgba(0,0,0,.32);
  --sh-3: 0 12px 40px rgba(0,0,0,.6);

  --focus: 0 0 0 2px var(--surface), 0 0 0 4px #6fbf8b;
}

/* ============================ 2. RESET ============================= */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--ff);
  font-size: 14px;
  line-height: 1.5;
  color: var(--text);
  background: var(--bg);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

body.is-locked { overflow: hidden; }

h1, h2, h3, h4, h5, p, figure, ul, ol, dl, dd { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: var(--accent-text); }
table { border-collapse: collapse; width: 100%; }
img, svg { display: block; max-width: 100%; }
:where(input, select, textarea, button, a, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--focus);
  border-radius: var(--r-sm);
}
.svg-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
  position: absolute; left: 8px; top: -60px; z-index: 200;
  background: var(--accent); color: #fff; padding: 10px 16px;
  border-radius: var(--r-md); font-weight: 600; text-decoration: none;
  transition: top var(--dur);
}
.skip-link:focus { top: 8px; }

.icon { width: 18px; height: 18px; flex: none; }
.icon--sm { width: 14px; height: 14px; }
.icon--lg { width: 22px; height: 22px; }

.mono { font-family: var(--ff-mono); font-size: .92em; letter-spacing: -.01em; }
.num  { font-variant-numeric: tabular-nums; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wrap-any { overflow-wrap: anywhere; word-break: break-word; }

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

/* ============================ 3. SHELL ============================= */
.app {
  display: grid;
  grid-template-columns: var(--sidebar-w) minmax(0, 1fr);
  min-height: 100vh;
}
.app.is-collapsed { grid-template-columns: var(--sidebar-w-collapsed) minmax(0, 1fr); }

.app__main {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 100vh;
}

/* ---- Sidebar ---- */
.sidebar {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  background: linear-gradient(180deg, var(--nav-bg) 0%, var(--nav-bg-2) 100%);
  border-right: 1px solid var(--nav-border);
  color: var(--nav-text);
  z-index: 60;
}
.sidebar__brand {
  display: flex; align-items: center; gap: 8px;
  height: var(--topbar-h);
  padding: 0 12px 0 14px;
  border-bottom: 1px solid var(--nav-border);
}
.brand {
  display: flex; align-items: center; gap: 10px;
  text-decoration: none; color: inherit; min-width: 0; flex: 1;
  border-radius: var(--r-sm); padding: 4px;
}
.brand__mark { flex: none; }
.brand__mark-bg   { fill: #24382b; }
.brand__mark-roof { stroke: #7cc48a; }
.brand__mark-posts{ stroke: #cfe7d5; }
.brand__mark-rail { stroke: #7cc48a; }
.brand__text { display: flex; flex-direction: column; min-width: 0; }
.brand__name { font-size: 16px; font-weight: 700; letter-spacing: -.015em; color: #fff; line-height: 1.15; }
.brand__name-accent { color: #7cc48a; }
.brand__sub { font-size: 10.5px; text-transform: uppercase; letter-spacing: .1em; color: var(--nav-text-dim); }

.sidebar .sidebar__close { display: none; color: var(--nav-text); }

.sidebar__nav { flex: 1; overflow-y: auto; padding: 14px 10px 10px; }
.sidebar__group-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .11em;
  color: var(--nav-text-dim); padding: 12px 10px 6px; font-weight: 600;
}
.sidebar__nav > .sidebar__group-label:first-child { padding-top: 0; }
.nav-list { display: flex; flex-direction: column; gap: 1px; }
.nav-item {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  width: 100%; min-height: 40px; padding: 8px 10px;
  border-radius: var(--r-md);
  color: var(--nav-text); font-size: 13.5px; font-weight: 500;
  text-align: left;
  transition: background var(--dur), color var(--dur);
}
.nav-item:hover { background: rgba(255,255,255,.06); color: #fff; }
.nav-item.is-active { background: var(--nav-active-bg); color: #fff; font-weight: 600; }
.nav-item.is-active::before {
  content: ""; position: absolute; left: -10px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px; border-radius: 0 3px 3px 0; background: var(--nav-active-bar);
}
.nav-item__label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nav-item__badge {
  flex: none; min-width: 20px; height: 18px; padding: 0 6px;
  border-radius: var(--r-pill); background: rgba(255,255,255,.14);
  font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; color: #e6efe8;
}
.nav-item__badge:empty { display: none; }
.nav-item__badge.is-alert { background: var(--danger); color: #fff; }

.sidebar__foot { padding: 10px; border-top: 1px solid var(--nav-border); display: grid; gap: 8px; }
/* Who built the demo — sits at the foot of the sidebar. */
.demo-by {
  display: flex; gap: 10px; align-items: flex-start; text-decoration: none;
  background: rgba(255,255,255,.05); border: 1px solid var(--nav-border);
  border-radius: var(--r-md); padding: 10px; color: var(--nav-text);
  transition: background var(--dur), border-color var(--dur);
}
.demo-by:hover { background: rgba(255,255,255,.09); border-color: #3d5a48; }
.demo-by__mark {
  flex: none; width: 30px; height: 30px; border-radius: var(--r-sm);
  display: grid; place-items: center; background: var(--nav-active-bar);
  color: #12291c; font-size: 11px; font-weight: 800;
}
.demo-by__text { display: grid; gap: 1px; min-width: 0; }
.demo-by__label { font-size: 10px; text-transform: uppercase; letter-spacing: .09em; color: var(--nav-text-dim); }
.demo-by__name { font-size: 13px; font-weight: 700; color: #fff; display: flex; align-items: center; gap: 5px; }
.demo-by__name .icon { color: var(--nav-text-dim); }
.demo-by:hover .demo-by__name .icon { color: var(--nav-active-bar); }
.demo-by__tag { font-size: 11px; line-height: 1.35; color: var(--nav-text); }
.demo-by__meta { font-size: 10.5px; color: var(--nav-text-dim); margin-top: 3px; }
/* Field mode and theme live here once the topbar sheds them on mobile. Kept to
   a single row so the nav list above loses as little scroll room as possible. */
.sidebar__utils { display: none; gap: 8px; }
.sidebar__util {
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 44px; padding: 8px 10px; border-radius: var(--r-md);
  border: 1px solid var(--nav-border); background: rgba(255,255,255,.05);
  color: var(--nav-text); font-size: 12.5px; font-weight: 600;
  transition: background var(--dur), color var(--dur);
}
.sidebar__util:hover { background: rgba(255,255,255,.1); color: #fff; }
/* Label tracks the icon, which shows the current theme, not the action. The
   action stays on the button's aria-label. */
[data-theme="light"] .theme-word-dark  { display: none; }
[data-theme="dark"]  .theme-word-light { display: none; }

.sidebar__collapse,
.sidebar__reset {
  display: flex; align-items: center; gap: 10px; width: 100%;
  min-height: 40px; padding: 8px 10px; border-radius: var(--r-md);
  color: var(--nav-text-dim); font-size: 12.5px; text-align: left;
}
.sidebar__collapse:hover,
.sidebar__reset:hover { background: rgba(255,255,255,.06); color: #fff; }
.sidebar__reset:hover .icon { color: var(--danger); }

.app.is-collapsed .brand__text,
.app.is-collapsed .nav-item__label,
.app.is-collapsed .nav-item__badge,
.app.is-collapsed .sidebar__group-label,
.app.is-collapsed .demo-by__text,
.app.is-collapsed .sidebar__collapse-label,
.app.is-collapsed .sidebar__reset-label { display: none; }
.app.is-collapsed .sidebar__brand { justify-content: center; padding: 0; }
.app.is-collapsed .brand { justify-content: center; }
.app.is-collapsed .nav-item { justify-content: center; padding: 8px; }
.app.is-collapsed .demo-by { justify-content: center; padding: 8px; }
.app.is-collapsed .sidebar__collapse,
.app.is-collapsed .sidebar__reset { justify-content: center; }
.app.is-collapsed .sidebar__collapse .icon { transform: rotate(180deg); }

.sidebar-backdrop {
  position: fixed; inset: 0; background: var(--overlay); z-index: 55;
  animation: fade var(--dur) ease;
}
@keyframes fade { from { opacity: 0 } to { opacity: 1 } }

/* ---- Topbar ---- */
.topbar {
  position: sticky; top: 0; z-index: 50;
  display: flex; align-items: center; gap: 12px;
  height: var(--topbar-h); padding: 0 var(--gutter);
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.topbar .topbar__menu { display: none; }
.topbar__actions { display: flex; align-items: center; gap: 6px; margin-left: auto; }

.global-search { position: relative; flex: 1; max-width: 460px; }
.global-search__icon {
  position: absolute; left: 11px; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none;
}
.global-search__input {
  width: 100%; height: 38px; padding: 0 40px 0 36px;
  background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--r-md); color: var(--text);
}
.global-search__input::placeholder { color: var(--text-3); }
.global-search__input:focus { background: var(--surface); border-color: var(--accent); }
.global-search__kbd {
  position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  font-family: var(--ff-mono); font-size: 11px; color: var(--text-3);
  border: 1px solid var(--border); border-radius: var(--r-xs);
  padding: 1px 5px; background: var(--surface);
}

.search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 70;
  max-height: min(60vh, 460px); overflow-y: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-3); padding: 6px;
}
.search-results__group { padding: 8px 10px 4px; font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .09em; color: var(--text-3); }
.search-result {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 8px 10px; border-radius: var(--r-md); text-align: left;
}
.search-result:hover, .search-result.is-active { background: var(--surface-3); }
.search-result__ic { color: var(--text-3); }
.search-result__main { min-width: 0; flex: 1; }
.search-result__title { display: block; font-weight: 600; font-size: 13px; overflow-wrap: anywhere; }
.search-result__meta { display: block; font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; }
.search-results__empty { padding: 18px 12px; text-align: center; color: var(--text-2); }

.icon-btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: var(--r-md);
  color: var(--text-2); transition: background var(--dur), color var(--dur);
}
.icon-btn:hover { background: var(--surface-3); color: var(--text); }
.icon-btn__dot {
  position: absolute; top: 7px; right: 7px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--danger); border: 2px solid var(--surface);
}
.icon-btn__dot[hidden] { display: none; }

[data-theme="light"] .icon-theme-dark { display: none; }
[data-theme="dark"]  .icon-theme-light { display: none; }

.user-btn {
  display: flex; align-items: center; gap: 8px; padding: 4px 8px 4px 4px;
  border-radius: var(--r-md); min-height: 40px;
}
.user-btn:hover { background: var(--surface-3); }
.user-btn__text { display: flex; flex-direction: column; align-items: flex-start; line-height: 1.25; }
.user-btn__name { font-size: 13px; font-weight: 600; }
.user-btn__role { font-size: 11px; color: var(--text-3); }
.avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 50%;
  background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; flex: none;
}
.avatar--lg { width: 40px; height: 40px; font-size: 14px; }
.avatar--sm { width: 26px; height: 26px; font-size: 10.5px; }

/* ---- Page head ---- */
.page-head {
  padding: 16px var(--gutter) 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
}
.breadcrumbs__list { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 12px; color: var(--text-3); }
.breadcrumbs__list li { display: flex; align-items: center; gap: 6px; }
.breadcrumbs__list li + li::before { content: "/"; color: var(--border-strong); }
.breadcrumbs__link { color: var(--text-2); text-decoration: none; border-radius: var(--r-xs); }
.breadcrumbs__link:hover { color: var(--accent-text); text-decoration: underline; }
.page-head__row {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; padding: 6px 0 16px; flex-wrap: wrap;
}
.page-title { font-size: 21px; font-weight: 700; letter-spacing: -.02em; }
.page-sub { font-size: 13px; color: var(--text-2); margin-top: 2px; max-width: 72ch; }
.page-head__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.page-body { flex: 1; padding: var(--gutter); min-width: 0; }
.app-foot {
  padding: 14px var(--gutter) 22px;
  border-top: 1px solid var(--border);
  color: var(--text-3); font-size: 11.5px;
}
.app-foot p { max-width: 110ch; }

/* ========================= 4. PRIMITIVES =========================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: 38px; padding: 0 14px;
  border: 1px solid transparent; border-radius: var(--r-md);
  font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background var(--dur), border-color var(--dur), color var(--dur);
}
.btn--primary { background: var(--accent); color: #fff; }
.btn--primary:hover { background: var(--accent-hover); }
.btn--secondary { background: var(--surface); border-color: var(--border-strong); color: var(--text); }
.btn--secondary:hover { background: var(--surface-3); }
.btn--ghost { color: var(--text-2); }
.btn--ghost:hover { background: var(--surface-3); color: var(--text); }
.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { filter: brightness(1.08); }
.btn--link { color: var(--accent-text); text-decoration: underline; min-height: 0; padding: 0; font-weight: 600; }
.btn--sm { min-height: 32px; padding: 0 10px; font-size: 12.5px; }
.btn--xs { min-height: 26px; padding: 0 8px; font-size: 12px; }
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.btn--icon { padding: 0; width: 38px; }

.btn-group { display: inline-flex; border: 1px solid var(--border-strong); border-radius: var(--r-md); overflow: hidden; background: var(--surface); }
.btn-group button {
  min-height: 36px; padding: 0 12px; font-size: 12.5px; font-weight: 600; color: var(--text-2);
  border-right: 1px solid var(--border);
}
.btn-group button:last-child { border-right: 0; }
.btn-group button:hover { background: var(--surface-3); }
.btn-group button[aria-pressed="true"] { background: var(--accent); color: #fff; }

.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field__label { font-size: 12px; font-weight: 600; color: var(--text-2); }
.field__label .req { color: var(--danger); }
.field__hint { font-size: 11.5px; color: var(--text-3); }
.field__error { font-size: 11.5px; color: var(--danger-text); display: flex; align-items: center; gap: 5px; font-weight: 600; }
.field__error[hidden] { display: none; }
.input, .select, .textarea {
  width: 100%; min-height: 38px; padding: 8px 10px;
  background: var(--surface); border: 1px solid var(--border-strong);
  border-radius: var(--r-md); color: var(--text);
}
.textarea { min-height: 84px; resize: vertical; }
.select {
  appearance: none; padding-right: 30px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237c857d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 9 7 6 7-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 8px center; background-size: 15px;
}
/* Native date/time controls size themselves from their internal edit field and
   come out ~2px taller than every other control, which knocks filter rows off
   a shared baseline. Pin the box so they match .input/.select exactly. */
.input[type="date"], .input[type="time"] { height: 38px; }
.input:focus, .select:focus, .textarea:focus { border-color: var(--accent); }
.input.is-invalid, .select.is-invalid, .textarea.is-invalid { border-color: var(--danger); background: var(--danger-soft); }
.input::placeholder, .textarea::placeholder { color: var(--text-3); }
/* Buttons that sit in a filter grid cell alongside inputs. Default .btn height
   already matches .input/.select at both breakpoints; stretching them across the
   cell keeps the row on one baseline and one right-hand edge. */
.field__actions { display: flex; align-items: stretch; gap: 8px; flex-wrap: wrap; }
.field__actions .btn { flex: 1 1 auto; }
.field--check { flex-direction: row; align-items: center; gap: 9px; }
.check { width: 18px; height: 18px; accent-color: var(--accent); flex: none; cursor: pointer; }

.card {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.card__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 14px 16px; border-bottom: 1px solid var(--border); flex-wrap: wrap;
}
.card__title { font-size: 14px; font-weight: 700; letter-spacing: -.01em; display: flex; align-items: center; gap: 8px; }
.card__sub { font-size: 12px; color: var(--text-3); font-weight: 400; }
.card__body { padding: 16px; }
.card__body--flush { padding: 0; }
/* A flush body drops its padding so rows can run edge to edge, but a bare
   empty-state line still needs the padding back or it sits on the borders. */
.card__body--flush > p, .panel__body--flush > p { padding: 12px 16px; margin: 0; }
.card__foot { padding: 12px 16px; border-top: 1px solid var(--border); background: var(--surface-2); border-radius: 0 0 var(--r-lg) var(--r-lg); }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: var(--r-pill);
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
  background: var(--neutral-soft); color: var(--neutral-text);
  border: 1px solid transparent;
}
.badge__glyph { font-size: 10px; font-weight: 800; letter-spacing: .04em; }
.badge .icon { width: 12px; height: 12px; }
.badge--ok      { background: var(--ok-soft);      color: var(--ok-text); }
.badge--warn    { background: var(--warn-soft);    color: var(--warn-text); }
.badge--info    { background: var(--info-soft);    color: var(--info-text); }
.badge--danger  { background: var(--danger-soft);  color: var(--danger-text); }
.badge--purple  { background: var(--purple-soft);  color: var(--purple-text); }
.badge--accent  { background: var(--accent-soft);  color: var(--accent-text); }
.badge--neutral { background: var(--neutral-soft); color: var(--neutral-text); }
.badge--outline { background: transparent; border-color: var(--border-strong); color: var(--text-2); }

.dot-status { width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block; }

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 6px 4px 10px; border-radius: var(--r-pill);
  background: var(--accent-soft); color: var(--accent-text);
  font-size: 12px; font-weight: 600; border: 1px solid transparent;
}
.chip__x {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; color: inherit;
}
.chip__x:hover { background: rgba(0,0,0,.1); }

.kv { display: grid; grid-template-columns: minmax(110px, 38%) 1fr; gap: 6px 14px; font-size: 13px; }
.kv dt { color: var(--text-3); font-size: 12px; }
.kv dd { color: var(--text); font-weight: 500; overflow-wrap: anywhere; }

.stack { display: grid; gap: 16px; }
.stack--sm { gap: 10px; }
.grid { display: grid; gap: 16px; }
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.inline { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.muted { color: var(--text-3); }
.small { font-size: 12px; }
.strong { font-weight: 700; }
.hr { height: 1px; background: var(--border); border: 0; margin: 14px 0; }

.callout {
  display: flex; gap: 10px; padding: 11px 13px;
  border-radius: var(--r-md); border: 1px solid var(--border);
  background: var(--surface-2); font-size: 12.5px; color: var(--text-2);
}
.callout .icon { color: var(--text-3); margin-top: 1px; }
.callout--warn { background: var(--warn-soft); border-color: transparent; color: var(--warn-text); }
.callout--warn .icon { color: var(--warn-text); }
.callout--danger { background: var(--danger-soft); border-color: transparent; color: var(--danger-text); }
.callout--danger .icon { color: var(--danger-text); }
.callout--info { background: var(--info-soft); border-color: transparent; color: var(--info-text); }
.callout--info .icon { color: var(--info-text); }
.callout strong { color: inherit; }

.empty {
  display: grid; justify-items: center; gap: 8px; padding: 40px 20px; text-align: center;
}
.empty__ic {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  background: var(--surface-3); color: var(--text-3);
}
.empty__ic .icon { width: 22px; height: 22px; }
.empty__title { font-weight: 700; font-size: 14px; }
.empty__body { font-size: 12.5px; color: var(--text-2); max-width: 44ch; }

.progress { height: 6px; border-radius: var(--r-pill); background: var(--surface-sunk); overflow: hidden; }
.progress__bar { height: 100%; border-radius: var(--r-pill); background: var(--accent); }
.progress__bar--warn { background: var(--warn); }
.progress__bar--danger { background: var(--danger); }

/* overflow-y must be hidden, not visible: a visible overflow-y next to an auto
   overflow-x computes to auto, and the tabs' -1px bottom margin overflows the
   strip by exactly 1px, which raised a vertical scrollbar beside the tabs. */
.tabs { display: flex; gap: 2px; border-bottom: 1px solid var(--border); overflow-x: auto; overflow-y: hidden; scrollbar-width: thin; }
.tab {
  position: relative; padding: 10px 13px; min-height: 42px;
  font-size: 13px; font-weight: 600; color: var(--text-2); white-space: nowrap;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.tab:hover { color: var(--text); background: var(--surface-2); }
.tab[aria-selected="true"] { color: var(--accent-text); border-bottom-color: var(--accent); }
.tab__count { font-size: 11px; color: var(--text-3); margin-left: 4px; }


/* ==================== 5. TABLES, FILTERS, PAGING ==================== */
.tablekit { display: grid; gap: 12px; }

.tablekit__bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.tablekit__search { position: relative; flex: 1 1 220px; min-width: 180px; max-width: 340px; }
.tablekit__search .icon {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--text-3); pointer-events: none;
}
.tablekit__search input { padding-left: 34px; }
.tablekit__count { font-size: 12.5px; color: var(--text-2); margin-left: 8px; margin-right: auto; }
.tablekit__count strong { color: var(--text); }
.tablekit__bar-actions { display: flex; gap: 8px; flex-wrap: wrap; }

.filter-btn-count {
  display: inline-grid; place-items: center; min-width: 18px; height: 18px;
  padding: 0 5px; border-radius: var(--r-pill);
  background: var(--accent); color: #fff; font-size: 11px; font-weight: 700;
}

.filters {
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface-2); padding: 14px;
}
.filters[hidden] { display: none; }
.filters__grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.filters__foot {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 12px; border-top: 1px dashed var(--border);
}
.filters__foot-label { font-size: 12px; color: var(--text-3); font-weight: 600; }
.chips { display: flex; gap: 6px; flex-wrap: wrap; }

.table-wrap {
  position: relative;
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface);
  overflow: auto;
  max-height: 68vh;
}
.table-wrap--short { max-height: 420px; }
.data-table { min-width: 100%; font-size: 13px; }
.data-table th, .data-table td {
  padding: 9px 12px; text-align: left; vertical-align: middle;
  border-bottom: 1px solid var(--border); white-space: nowrap;
}
.data-table thead th {
  position: sticky; top: 0; z-index: 3;
  background: var(--surface-3); color: var(--text-2);
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .045em;
  border-bottom: 1px solid var(--border-strong);
  padding: 0;
}
.data-table thead th .th-static { display: block; padding: 9px 12px; }
.data-table tbody tr:last-child td { border-bottom: 0; }
.data-table tbody tr.is-clickable { cursor: pointer; }
.data-table tbody tr.is-clickable:hover { background: var(--surface-2); }
.data-table tbody tr:focus-visible { outline: none; box-shadow: inset 0 0 0 2px var(--accent); }
.data-table td.cell-wrap { white-space: normal; min-width: 190px; max-width: 320px; overflow-wrap: anywhere; }
.data-table td.cell-num, .data-table th.cell-num .th-static { text-align: right; }
.data-table th.cell-num .th-btn { justify-content: flex-end; text-align: right; }
.data-table .cell-num { font-variant-numeric: tabular-nums; }

.data-table th.col-sticky, .data-table td.col-sticky {
  position: sticky; left: 0; z-index: 2; background: var(--surface);
  box-shadow: 1px 0 0 var(--border);
}
.data-table thead th.col-sticky { z-index: 4; background: var(--surface-3); }
.data-table tbody tr:hover td.col-sticky { background: var(--surface-2); }

.th-btn {
  display: flex; align-items: center; gap: 6px; width: 100%;
  padding: 9px 12px; min-height: 38px;
  font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit;
  text-align: left;
}
.th-btn:hover { background: var(--surface-sunk); color: var(--text); }
.sort-ic { flex: none; width: 11px; height: 14px; color: currentColor; }
.sort-ic .up, .sort-ic .down { opacity: .38; }
th[aria-sort="ascending"]  .sort-ic .up   { opacity: 1; }
th[aria-sort="ascending"]  .sort-ic .down { opacity: .18; }
th[aria-sort="descending"] .sort-ic .down { opacity: 1; }
th[aria-sort="descending"] .sort-ic .up   { opacity: .18; }
th[aria-sort="ascending"] .th-btn, th[aria-sort="descending"] .th-btn { color: var(--accent-text); }

.row-actions-cell { text-align: right; padding-right: 8px !important; width: 46px; }
.rowmenu-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: var(--r-sm); color: var(--text-3);
}
.rowmenu-btn:hover { background: var(--surface-3); color: var(--text); }

.menu {
  position: fixed; z-index: 210; min-width: 196px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--sh-3); padding: 5px;
}
.menu__item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 8px 10px; min-height: 38px; border-radius: var(--r-sm);
  font-size: 13px; text-align: left; color: var(--text);
}
.menu__item:hover { background: var(--surface-3); }
.menu__item .icon { color: var(--text-3); }
.menu__item--danger { color: var(--danger-text); }
.menu__item--danger .icon { color: var(--danger-text); }
.menu__sep { height: 1px; background: var(--border); margin: 4px 0; }

.record-cards { display: none; gap: 10px; }
.record-card {
  border: 1px solid var(--border); border-radius: var(--r-md);
  background: var(--surface); padding: 12px; display: grid; gap: 8px;
  width: 100%; text-align: left;
}
.record-card__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.record-card__id { font-family: var(--ff-mono); font-size: 12px; color: var(--text-3); }
.record-card__title { font-weight: 700; font-size: 13.5px; overflow-wrap: anywhere; }
.record-card__grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 7px 12px; }
.record-card__k { font-size: 10.5px; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); }
.record-card__v { font-size: 12.5px; font-weight: 500; overflow-wrap: anywhere; }
.record-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }

.pager { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pager__row { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.pager__info { font-size: 12.5px; color: var(--text-2); }
.pager__size { display: flex; align-items: center; gap: 7px; font-size: 12.5px; color: var(--text-2); }
.pager__size select { min-height: 34px; padding: 4px 26px 4px 8px; font-size: 12.5px; width: auto; }
.pager__nav { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.pager__btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 36px; height: 36px; padding: 0 8px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface); color: var(--text-2); font-size: 13px; font-weight: 600;
}
.pager__btn:hover:not([disabled]) { background: var(--surface-3); color: var(--text); }
.pager__btn[disabled] { opacity: .4; cursor: not-allowed; }
.pager__btn[aria-current="page"] { background: var(--accent); border-color: var(--accent); color: #fff; }
.pager__ellipsis { padding: 0 4px; color: var(--text-3); }

/* ========================= 6. OVERLAYS ============================= */
.popover-host { position: relative; }
.popover {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 120;
  min-width: 240px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); padding: 6px;
}
.popover--wide { width: min(360px, calc(100vw - 24px)); }
.popover__head { display: flex; align-items: center; justify-content: space-between; padding: 8px 10px 6px; }
.popover__title { font-size: 13px; font-weight: 700; }
.popover__user { display: flex; gap: 10px; align-items: center; padding: 10px; border-bottom: 1px solid var(--border); margin-bottom: 4px; }
.popover__user-name { font-weight: 700; font-size: 13px; }
.popover__user-mail { font-size: 11.5px; color: var(--text-3); overflow-wrap: anywhere; }
.popover__menu { display: grid; gap: 1px; }
.popover__item {
  display: flex; align-items: center; gap: 9px; width: 100%;
  padding: 9px 10px; min-height: 42px; border-radius: var(--r-sm); font-size: 13px; text-align: left;
}
.popover__item:hover { background: var(--surface-3); }
.popover__item .icon { color: var(--text-3); }
.popover__item--danger { color: var(--danger-text); }
.popover__item--danger .icon { color: var(--danger-text); }

.notif-list { max-height: 60vh; overflow-y: auto; display: grid; gap: 2px; }
.notif { display: flex; gap: 10px; width: 100%; text-align: left; padding: 10px; border-radius: var(--r-md); }
.notif:hover { background: var(--surface-3); }
.notif__ic { width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; flex: none; }
.notif__ic--warn { background: var(--warn-soft); color: var(--warn-text); }
.notif__ic--danger { background: var(--danger-soft); color: var(--danger-text); }
.notif__ic--info { background: var(--info-soft); color: var(--info-text); }
.notif__ic--ok { background: var(--ok-soft); color: var(--ok-text); }
.notif__title { display: block; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.notif__body { display: block; font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; margin-top: 1px; }
.notif__time { display: block; font-size: 11px; color: var(--text-3); margin-top: 3px; }
.notif.is-unread .notif__title::after {
  content: ""; display: inline-block; width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent); margin-left: 6px; vertical-align: middle;
}

.scrim {
  position: fixed; inset: 0; z-index: 150; background: var(--overlay);
  display: flex; align-items: center; justify-content: center; padding: 24px;
  animation: fade var(--dur) ease;
}
.modal {
  width: min(640px, 100%); max-height: calc(100vh - 48px);
  display: flex; flex-direction: column;
  background: var(--surface); border-radius: var(--r-lg);
  box-shadow: var(--sh-3); border: 1px solid var(--border);
  animation: pop var(--dur) ease;
}
.modal--lg { width: min(900px, 100%); }
.modal--sm { width: min(440px, 100%); }
@keyframes pop { from { opacity: 0; transform: translateY(8px) scale(.99) } to { opacity: 1; transform: none } }
.modal__head { display: flex; align-items: flex-start; gap: 12px; padding: 16px 16px 12px; border-bottom: 1px solid var(--border); }
.modal__title { font-size: 16px; font-weight: 700; letter-spacing: -.015em; }
.modal__sub { font-size: 12.5px; color: var(--text-2); margin-top: 2px; }
.modal__close { margin-left: auto; flex: none; }
.modal__body { padding: 16px; overflow-y: auto; flex: 1; }
.modal__foot {
  display: flex; align-items: center; justify-content: flex-end; gap: 8px;
  padding: 12px 16px; border-top: 1px solid var(--border);
  background: var(--surface-2); border-radius: 0 0 var(--r-lg) var(--r-lg); flex-wrap: wrap;
}
.modal__foot--split { justify-content: space-between; }

.form-grid { display: grid; gap: 14px; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-grid--1 { grid-template-columns: 1fr; }
.form-grid .span-2 { grid-column: 1 / -1; }

.drawer-scrim {
  position: fixed; inset: 0; z-index: 140; background: var(--overlay);
  display: flex; justify-content: flex-end; animation: fade var(--dur) ease;
}
.drawer {
  width: min(900px, 100%); height: 100%;
  background: var(--surface); border-left: 1px solid var(--border);
  display: flex; flex-direction: column; box-shadow: var(--sh-3);
  animation: slide-in var(--dur) ease;
}
@keyframes slide-in { from { transform: translateX(24px); opacity: .6 } to { transform: none; opacity: 1 } }
/* Padded on all four sides so badges never sit flush on the divider. Tabs, when
   present, are pulled back down so they still meet the border as designed. */
.drawer__head { padding: 14px 18px; border-bottom: 1px solid var(--border); }
.drawer__head .drawer__tabs { margin-bottom: -14px; }
.drawer__top { display: flex; align-items: flex-start; gap: 12px; }
.drawer__eyebrow { font-family: var(--ff-mono); font-size: 12px; color: var(--text-3); }
.drawer__title { font-size: 17px; font-weight: 700; letter-spacing: -.015em; overflow-wrap: anywhere; }
.drawer__meta { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 7px; align-items: center; }
.drawer__actions { margin-left: auto; display: flex; gap: 6px; align-items: center; flex: none; }
.drawer__tabs { margin-top: 12px; }
.drawer__body { flex: 1; overflow-y: auto; padding: 18px; background: var(--surface-2); }
.drawer__foot {
  display: flex; gap: 8px; padding: 12px 18px; border-top: 1px solid var(--border);
  background: var(--surface); flex-wrap: wrap; align-items: center;
}

.toast-root {
  position: fixed; z-index: 300; right: 18px; bottom: 18px;
  display: flex; flex-direction: column; gap: 8px; pointer-events: none;
  width: min(370px, calc(100vw - 24px));
}
.toast {
  display: flex; align-items: flex-start; gap: 10px; pointer-events: auto;
  background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--r-md); box-shadow: var(--sh-3); padding: 11px 12px;
  animation: toast-in 200ms ease;
}
@keyframes toast-in { from { opacity: 0; transform: translateY(10px) } to { opacity: 1; transform: none } }
.toast--ok     { border-left-color: var(--ok); }
.toast--warn   { border-left-color: var(--warn); }
.toast--danger { border-left-color: var(--danger); }
.toast--info   { border-left-color: var(--info); }
.toast__ic { flex: none; margin-top: 1px; }
.toast--ok .toast__ic { color: var(--ok); }
.toast--warn .toast__ic { color: var(--warn); }
.toast--danger .toast__ic { color: var(--danger); }
.toast--info .toast__ic { color: var(--info); }
.toast__title { font-size: 13px; font-weight: 700; }
.toast__body { font-size: 12.5px; color: var(--text-2); overflow-wrap: anywhere; }
.toast__x { margin-left: auto; flex: none; color: var(--text-3); padding: 2px; border-radius: var(--r-xs); }
.toast__x:hover { color: var(--text); }

/* =========================== 7. VIEWS ============================== */

/* ---- Dashboard ---- */
/* 230px min keeps the 12-card overview on 4 columns at laptop widths (4/4/4)
   instead of 5/5/2, which left a two-card hole on the last row. */
.kpi-grid { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.kpi {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); padding: 13px 14px; display: grid; gap: 6px;
  box-shadow: var(--sh-1); text-align: left; width: 100%;
}
button.kpi:hover { border-color: var(--border-strong); background: var(--surface-2); }
.kpi__top { display: flex; align-items: center; gap: 8px; }
.kpi__ic {
  width: 28px; height: 28px; border-radius: var(--r-sm); display: grid; place-items: center; flex: none;
  background: var(--surface-3); color: var(--text-2);
}
.kpi__ic--ok { background: var(--ok-soft); color: var(--ok-text); }
.kpi__ic--warn { background: var(--warn-soft); color: var(--warn-text); }
.kpi__ic--danger { background: var(--danger-soft); color: var(--danger-text); }
.kpi__ic--info { background: var(--info-soft); color: var(--info-text); }
.kpi__ic--purple { background: var(--purple-soft); color: var(--purple-text); }
.kpi__label { font-size: 12px; color: var(--text-2); font-weight: 600; }
.kpi__value { font-size: 25px; font-weight: 700; letter-spacing: -.025em; line-height: 1.1; font-variant-numeric: tabular-nums; }
.kpi__meta { font-size: 11.5px; color: var(--text-3); display: flex; align-items: center; gap: 5px; }
.kpi__meta .icon { width: 13px; height: 13px; }
.kpi__meta--warn { color: var(--warn-text); font-weight: 600; }
.kpi__meta--danger { color: var(--danger-text); font-weight: 600; }
.kpi__meta--ok { color: var(--ok-text); font-weight: 600; }

.dash-cols { display: grid; gap: 16px; grid-template-columns: minmax(0, 1.55fr) minmax(0, 1fr); align-items: stretch; }
.dash-cols--even { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* Paired cards share one height so the row has no ragged edge, but their
   contents keep their natural size — charts, bars and timelines are never
   stretched to fill. Long lists scroll at a cap instead of setting a height the
   card beside them cannot match. */
.dash-cols > .card { display: flex; flex-direction: column; }
.dash-cols > .card > .card__body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.dash-cols > .card > .card__body > * { flex: none; }
.dash-cols .attention-list, .dash-cols .feed { max-height: 360px; align-content: start; overflow-y: auto; }

.attention-list { display: grid; }
.attention {
  display: flex; align-items: flex-start; gap: 11px; width: 100%; text-align: left;
  padding: 11px 16px; border-bottom: 1px solid var(--border);
}
.attention:last-child { border-bottom: 0; }
.attention:hover { background: var(--surface-2); }
.attention__ic { width: 28px; height: 28px; border-radius: var(--r-sm); display: grid; place-items: center; flex: none; }
.attention__main { min-width: 0; flex: 1; }
.attention__title { display: block; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.attention__meta { display: block; font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; margin-top: 2px; }
.attention__go { color: var(--text-3); flex: none; align-self: center; }

.chart { width: 100%; overflow: visible; }
.chart-axis { font-size: 10.5px; fill: var(--text-3); }
.chart-grid-line { stroke: var(--border); stroke-width: 1; }
.chart-area { fill: url(#areaGrad); }
.chart-line { fill: none; stroke: var(--accent); stroke-width: 2.2; stroke-linejoin: round; stroke-linecap: round; }
.chart-line--alt { stroke: var(--info); stroke-dasharray: 4 3; }
.chart-dot { fill: var(--surface); stroke: var(--accent); stroke-width: 2; }
.chart-hit { fill: transparent; cursor: pointer; }
.chart-hit:hover + .chart-dot, .chart-hit:focus-visible + .chart-dot { stroke-width: 3.4; }
.chart-bar { fill: var(--accent); }
.chart-bar--muted { fill: var(--border-strong); }

.chart-wrap { position: relative; }
.chart-tip {
  position: absolute; z-index: 9; pointer-events: none;
  background: var(--nav-bg); color: #fff; border-radius: var(--r-sm);
  padding: 7px 9px; font-size: 11.5px; box-shadow: var(--sh-2);
  transform: translate(-50%, -114%); white-space: nowrap; line-height: 1.4;
}
.chart-tip[hidden] { display: none; }
.chart-tip strong { display: block; font-size: 12px; }
.chart-legend { display: flex; gap: 14px; flex-wrap: wrap; font-size: 12px; color: var(--text-2); }
.chart-legend span { display: inline-flex; align-items: center; gap: 6px; }
.legend-swatch { width: 10px; height: 10px; border-radius: 2px; flex: none; }

.statbars { display: grid; gap: 9px; }
.statbar { display: grid; grid-template-columns: 1fr auto; gap: 4px 10px; align-items: center; }
.statbar__label { font-size: 12.5px; display: flex; align-items: center; gap: 7px; min-width: 0; }
.statbar__label span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.statbar__val { font-size: 12.5px; font-weight: 700; font-variant-numeric: tabular-nums; }
.statbar__track { grid-column: 1 / -1; height: 7px; border-radius: var(--r-pill); background: var(--surface-sunk); overflow: hidden; }
.statbar__fill { height: 100%; border-radius: var(--r-pill); }

.funnel { display: grid; gap: 8px; }
.funnel__step { display: grid; gap: 5px; }
.funnel__row { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.funnel__bar { height: 26px; border-radius: var(--r-sm); background: var(--accent); display: flex; align-items: center; padding: 0 8px; color: #fff; font-size: 11.5px; font-weight: 700; min-width: 42px; }
.funnel__drop { font-size: 11px; color: var(--text-3); }

.mini-timeline { display: grid; gap: 8px; }
.mini-tl-row { display: grid; grid-template-columns: 92px 1fr; gap: 10px; align-items: center; }
.mini-tl-name { font-size: 12px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mini-tl-track { position: relative; height: 26px; background: var(--surface-sunk); border-radius: var(--r-sm); overflow: hidden; }
/* Block, not flex: text-overflow is ignored on a flex container, which hard-cut
   the job label mid-glyph on short blocks. line-height centres it in the track. */
.mini-tl-block {
  position: absolute; top: 3px; bottom: 3px; border-radius: var(--r-xs);
  font-size: 10.5px; font-weight: 700; color: #fff; line-height: 20px;
  padding: 0 5px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
.mini-tl-now { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--danger); z-index: 2; }
.mini-tl-scale { display: flex; justify-content: space-between; font-size: 10.5px; color: var(--text-3); padding-left: 102px; }

.feed { display: grid; }
.feed__item { display: flex; gap: 11px; padding: 11px 16px; border-bottom: 1px solid var(--border); }
.feed__item:last-child { border-bottom: 0; }
.feed__ic { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; flex: none; background: var(--surface-3); color: var(--text-2); }
.feed__text { font-size: 12.5px; min-width: 0; }
.feed__text strong { font-weight: 600; }
.feed__time { font-size: 11px; color: var(--text-3); margin-top: 1px; }

.weather {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 13px 14px; border-radius: var(--r-md);
  background: var(--info-soft); color: var(--info-text);
}
.weather__ic { flex: none; }
.weather__title { font-weight: 700; font-size: 13px; }
.weather__body { font-size: 12.5px; }
.weather__days { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.weather__day {
  background: var(--surface); border-radius: var(--r-sm); padding: 5px 8px;
  font-size: 11.5px; color: var(--text-2); text-align: center; min-width: 62px;
}
.weather__day b { display: block; color: var(--text); font-size: 12px; }

/* ---- Schedule board ---- */
.sched-toolbar {
  display: flex; align-items: center; gap: 10px 12px; flex-wrap: wrap;
  padding: 12px 14px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.sched-date { font-size: 14px; font-weight: 700; min-width: 190px; flex: 0 1 auto; }
.sched-date small { display: block; font-size: 11.5px; font-weight: 500; color: var(--text-3); }
.sched-toolbar__right {
  margin-left: auto; display: flex; gap: 8px; align-items: center;
  flex-wrap: wrap; justify-content: flex-end;
}
/* every control in the bar shares one height so the row reads as a single strip */
.sched-toolbar .btn,
.sched-toolbar .select,
.sched-toolbar .input,
.sched-toolbar .btn-group button { height: 38px; min-height: 38px; }
.sched-toolbar .btn-group { align-self: center; }
.sched-toolbar .tablekit__search { flex: 1 1 200px; min-width: 170px; max-width: 260px; }
.sched-toolbar .select { max-width: 190px; }

.sched-layout { display: grid; grid-template-columns: minmax(0, 1fr) 290px; gap: 16px; align-items: start; }

.sched-board {
  border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); overflow: hidden; box-shadow: var(--sh-1);
}
.sched-scroll { overflow-x: auto; overflow-y: hidden; }
.sched-inner { min-width: 940px; --res-w: 178px; }
.sched-headrow {
  display: grid; grid-template-columns: var(--res-w) minmax(0, 1fr);
  border-bottom: 1px solid var(--border-strong); background: var(--surface-3);
  position: sticky; top: 0; z-index: 6;
}
.sched-headrow__res {
  padding: 8px 12px; font-size: 11.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-2); border-right: 1px solid var(--border);
  position: sticky; left: 0; background: var(--surface-3); z-index: 2;
  display: flex; align-items: center;
}
.sched-times { display: grid; }
.sched-time { padding: 8px 6px; font-size: 11px; color: var(--text-2); font-weight: 600; border-left: 1px solid var(--border); text-align: center; }
.sched-time:first-child { border-left: 0; }
.sched-time small { display: block; font-weight: 400; color: var(--text-3); font-size: 10px; }
.sched-time.is-today { color: var(--accent-text); background: var(--accent-soft); }

.sched-row { display: grid; grid-template-columns: var(--res-w) minmax(0, 1fr); border-bottom: 1px solid var(--border); }
.sched-row:last-child { border-bottom: 0; }
.sched-res {
  padding: 10px 12px; border-right: 1px solid var(--border);
  position: sticky; left: 0; background: var(--surface); z-index: 2;
  display: grid; gap: 3px; align-content: start;
}
.sched-res__name { font-size: 13px; font-weight: 700; display: flex; align-items: center; gap: 7px; }
.sched-res__swatch { width: 9px; height: 9px; border-radius: 2px; flex: none; }
.sched-res__meta { font-size: 11.5px; color: var(--text-3); }
.sched-res__cap { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--text-2); }
.sched-res__cap .progress { flex: 1; height: 5px; }

.sched-track {
  position: relative; min-height: 84px; padding: 5px 0;
  background-image: repeating-linear-gradient(to right, var(--border) 0 1px, transparent 1px var(--slot-w, 12.5%));
}
.sched-track.is-dropzone { background-color: var(--accent-soft); }
.sched-slot { position: absolute; top: 0; bottom: 0; }
.sched-slot.is-over { background: var(--accent-soft); box-shadow: inset 0 0 0 2px var(--accent); border-radius: var(--r-sm); }
.sched-now { position: absolute; top: 0; bottom: 0; width: 2px; background: var(--danger); z-index: 5; pointer-events: none; }
.sched-now::before {
  content: "now"; position: absolute; top: -1px; left: 3px; font-size: 9.5px; font-weight: 700;
  color: #fff; background: var(--danger); padding: 0 4px; border-radius: 0 3px 3px 0;
}

.job-block {
  position: absolute; overflow: hidden;
  border-radius: var(--r-sm); border: 1px solid var(--border-strong);
  border-left: 3px solid var(--accent);
  background: var(--surface-2); padding: 5px 7px;
  display: grid; gap: 1px; align-content: start;
  text-align: left; cursor: grab; min-width: 62px;
  line-height: 1.35;
  box-shadow: var(--sh-1);
}
.job-block:hover { background: var(--surface); box-shadow: var(--sh-2); z-index: 4; }
.job-block.is-dragging { opacity: .45; cursor: grabbing; }
.job-block__id { font-family: var(--ff-mono); font-size: 10px; color: var(--text-3); display: flex; align-items: center; gap: 4px; }
.job-block__cust { font-size: 11.5px; font-weight: 700; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-block__desc { font-size: 11px; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.job-block__meta { font-size: 10.5px; color: var(--text-3); display: flex; gap: 1px 6px; flex-wrap: wrap; }
.job-block__meta > span { white-space: nowrap; }
.job-block__flags { display: flex; gap: 3px; position: absolute; top: 4px; right: 4px; }
.job-block__flag { width: 15px; height: 15px; border-radius: 3px; display: grid; place-items: center; }
.job-block__flag .icon { width: 11px; height: 11px; }
.job-block__flag--warn { background: var(--warn-soft); color: var(--warn-text); }
.job-block__flag--danger { background: var(--danger-soft); color: var(--danger-text); }
.job-block__flag--info { background: var(--info-soft); color: var(--info-text); }
.job-block--urgent { border-left-color: var(--danger); }
.job-block--survey { border-left-color: var(--purple); }
.job-block--maintenance { border-left-color: var(--info); }
.job-block--install { border-left-color: var(--accent); }
.job-block--repair { border-left-color: var(--warn); }
.job-block.has-conflict { outline: 2px dashed var(--danger); outline-offset: -2px; }
.job-block--compact .job-block__desc, .job-block--compact .job-block__meta { display: none; }

.sched-track--week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); background-image: none; padding: 0; }
.week-cell { border-left: 1px solid var(--border); padding: 5px; display: flex; flex-direction: column; gap: 5px; min-height: 92px; }
.week-cell:first-child { border-left: 0; }
.week-cell.is-over { background: var(--accent-soft); box-shadow: inset 0 0 0 2px var(--accent); }
.week-cell.is-weekend { background: var(--surface-2); }
.week-cell .job-block { position: static; min-width: 0; }

.sched-side { display: grid; gap: 16px; align-content: start; }
.tray { display: grid; gap: 8px; padding: 12px; max-height: 420px; overflow-y: auto; }
.tray-card {
  border: 1px solid var(--border); border-left: 3px solid var(--warn);
  border-radius: var(--r-sm); background: var(--surface-2); padding: 9px 10px;
  display: grid; gap: 3px; text-align: left; width: 100%; cursor: grab;
}
.tray-card:hover { background: var(--surface); }
.tray-card__row { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.tray-card__id { font-family: var(--ff-mono); font-size: 10.5px; color: var(--text-3); }
.tray-card__title { font-size: 12.5px; font-weight: 700; overflow-wrap: anywhere; }
.tray-card__meta { font-size: 11.5px; color: var(--text-2); overflow-wrap: anywhere; }
/* Badges are inline-flex, so a literal space between them collapses to nothing
   once the row wraps. Any container of stacked badges uses this instead. */
.badge-row { display: flex; flex-wrap: wrap; align-items: center; gap: 5px; }
.tray-card__actions { display: flex; gap: 6px; margin-top: 4px; }

.conflict-list { display: grid; gap: 8px; padding: 12px; }

.agenda { display: none; }
.agenda__controls { display: grid; gap: 12px; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
.agenda__group { display: grid; gap: 8px; }
.agenda__daylabel { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em; color: var(--text-3); padding-top: 6px; }
.agenda-card {
  border: 1px solid var(--border); border-left: 3px solid var(--accent);
  border-radius: var(--r-md); background: var(--surface); padding: 12px;
  display: grid; gap: 7px; width: 100%; text-align: left;
}
.agenda-card--urgent { border-left-color: var(--danger); }
.agenda-card__time { font-size: 12px; font-weight: 700; color: var(--accent-text); display: flex; align-items: center; gap: 6px; }
.agenda-card__title { font-size: 13.5px; font-weight: 700; overflow-wrap: anywhere; }
.agenda-card__meta { font-size: 12px; color: var(--text-2); display: grid; gap: 3px; }
.agenda-card__foot { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }

/* ---- Map ---- */
.map-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 16px; align-items: stretch; }
.map-frame {
  position: relative; border: 1px solid var(--border); border-radius: var(--r-lg);
  background: var(--surface); overflow: hidden; box-shadow: var(--sh-1);
}
.map-svg { display: block; width: 100%; height: auto; background: var(--map-bg, #eef1e8); touch-action: pan-y; }
[data-theme="dark"] .map-svg { --map-bg: #161d18; }
.map-land { fill: var(--map-land, #e7ece0); }
[data-theme="dark"] .map-land { fill: #1b241d; }
.map-urban { fill: var(--map-urban, #dfe5d6); stroke: var(--map-urban-s, #cfd7c3); stroke-width: 1; }
[data-theme="dark"] .map-urban { fill: #222c24; stroke: #2c382e; }
.map-green { fill: var(--map-green, #d7e6cd); }
[data-theme="dark"] .map-green { fill: #1f2c21; }
.map-water { fill: var(--map-water, #c3d8e4); }
[data-theme="dark"] .map-water { fill: #1c2b34; }
.map-road { stroke: var(--map-road, #ffffff); fill: none; stroke-linecap: round; stroke-linejoin: round; }
[data-theme="dark"] .map-road { stroke: #333f36; }
.map-road--major { stroke-width: 7; }
.map-road--minor { stroke-width: 3.4; }
.map-road-case { stroke: var(--map-road-case, #d5dbcb); fill: none; stroke-linecap: round; stroke-linejoin: round; }
[data-theme="dark"] .map-road-case { stroke: #232e26; }
.map-label { font-size: 11px; font-weight: 600; fill: var(--text-2); pointer-events: none; }
.map-label--water { fill: var(--info); font-style: italic; font-weight: 500; }
.map-zone { fill: var(--accent); opacity: .07; stroke: var(--accent); stroke-width: 1.4; stroke-dasharray: 6 5; }
.map-zone-label { font-size: 10.5px; fill: var(--accent-text); font-weight: 700; letter-spacing: .06em; pointer-events: none; }

.map-marker { cursor: pointer; }
.map-marker__pin { stroke: #fff; stroke-width: 1.6; }
[data-theme="dark"] .map-marker__pin { stroke: #10150f; }
.map-marker__glyph { font-size: 10px; font-weight: 800; fill: #fff; text-anchor: middle; pointer-events: none; }
.map-marker.is-selected .map-marker__pin { stroke: var(--text); stroke-width: 2.4; }
.map-marker:focus-visible { outline: none; }
.map-marker:focus-visible .map-marker__pin { stroke: var(--accent); stroke-width: 3; }
.map-marker__halo { fill: none; stroke-width: 2; opacity: .5; }
.map-depot { fill: var(--nav-bg); stroke: #fff; stroke-width: 1.6; }
.map-crew__body { fill: var(--info); stroke: #fff; stroke-width: 1.5; }

.map-overlay { position: absolute; left: 12px; top: 12px; display: grid; gap: 8px; max-width: 220px; }
.map-panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--sh-2); padding: 10px 12px;
}
.map-panel__title { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--text-3); margin-bottom: 7px; }
.map-legend { display: grid; gap: 5px; font-size: 12px; }
.map-legend__row { display: flex; align-items: center; gap: 7px; }
.map-legend__key {
  width: 17px; height: 17px; border-radius: 50%; display: grid; place-items: center; flex: none;
  color: #fff; font-size: 9px; font-weight: 800;
}
.map-toggles { display: grid; gap: 7px; }
.map-toggle { display: flex; align-items: center; gap: 8px; font-size: 12.5px; cursor: pointer; min-height: 26px; }

.map-preview {
  position: absolute; right: 12px; bottom: 12px; width: min(300px, calc(100% - 24px));
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-md); box-shadow: var(--sh-3); padding: 12px; display: grid; gap: 8px;
}
.map-preview__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; }
.map-note { font-size: 11.5px; color: var(--text-3); padding: 8px 12px; border-top: 1px solid var(--border); background: var(--surface-2); }

.map-side-list { display: grid; align-content: start; overflow-y: auto; }

/* Side panel runs the full height of the map column rather than stopping short.
   The card is taken out of flow so a long job list cannot stretch the grid row —
   the map column alone sets the height, the card fills it, the list scrolls. */
.map-layout > .stack { align-content: start; }
.map-layout > .sched-side { align-content: stretch; position: relative; }
.map-layout > .sched-side > .card { position: absolute; inset: 0; display: flex; flex-direction: column; min-height: 0; }
.map-layout > .sched-side > .card > .card__body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.map-layout > .sched-side .map-side-list { flex: 1; min-height: 0; }
.map-side-item {
  display: flex; gap: 10px; align-items: flex-start; width: 100%; text-align: left;
  padding: 10px 12px; border-bottom: 1px solid var(--border);
}
.map-side-item:last-child { border-bottom: 0; }
.map-side-item:hover, .map-side-item.is-active { background: var(--surface-2); }
.map-side-item__key {
  width: 20px; height: 20px; border-radius: 50%; flex: none; display: grid; place-items: center;
  color: #fff; font-size: 9.5px; font-weight: 800;
}

/* ---- Detail pages / drawer content ---- */
/* Stretch, so a short card (an empty "Active enquiries", say) ends level with
   the card beside it instead of leaving a gap under it. */
.detail-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); align-items: stretch; }
.panel { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-md); }
.panel__head { padding: 11px 14px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; }
.panel__title { font-size: 12.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em; color: var(--text-2); }
.panel__body { padding: 14px; }
.panel__body--flush { padding: 0; }

.tl { display: grid; gap: 0; }
.tl__item { display: grid; grid-template-columns: 26px 1fr; gap: 11px; padding-bottom: 14px; position: relative; }
.tl__item:last-child { padding-bottom: 0; }
.tl__item::before {
  content: ""; position: absolute; left: 12.5px; top: 26px; bottom: 0; width: 1px; background: var(--border);
}
.tl__item:last-child::before { display: none; }
.tl__ic { width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: var(--surface-3); color: var(--text-2); z-index: 1; }
.tl__ic .icon { width: 14px; height: 14px; }
.tl__ic--ok { background: var(--ok-soft); color: var(--ok-text); }
.tl__ic--warn { background: var(--warn-soft); color: var(--warn-text); }
.tl__ic--info { background: var(--info-soft); color: var(--info-text); }
.tl__ic--danger { background: var(--danger-soft); color: var(--danger-text); }
.tl__body { min-width: 0; padding-top: 2px; }
.tl__title { font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.tl__meta { font-size: 11.5px; color: var(--text-3); }
.tl__text { font-size: 12.5px; color: var(--text-2); margin-top: 3px; overflow-wrap: anywhere; }

.checklist { display: grid; gap: 2px; }
.checklist__item {
  display: flex; align-items: flex-start; gap: 10px; padding: 9px 10px;
  border-radius: var(--r-sm); width: 100%; text-align: left; min-height: 44px;
}
.checklist__item:hover { background: var(--surface-2); }
.checklist__box {
  width: 20px; height: 20px; border-radius: var(--r-xs); border: 1.6px solid var(--border-strong);
  display: grid; place-items: center; flex: none; margin-top: 1px; color: transparent;
}
.checklist__item.is-done .checklist__box { background: var(--accent); border-color: var(--accent); color: #fff; }
.checklist__item.is-done .checklist__label { color: var(--text-3); text-decoration: line-through; }
.checklist__label { display: block; font-size: 13px; overflow-wrap: anywhere; }
.checklist__meta { display: block; font-size: 11px; color: var(--text-3); margin-top: 2px; overflow-wrap: anywhere; }

.photo-grid { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); }
.photo {
  border: 1px solid var(--border); border-radius: var(--r-sm); overflow: hidden;
  background: var(--surface-3); display: grid; gap: 0;
}
.photo__img {
  aspect-ratio: 4 / 3; display: grid; place-items: center; color: var(--text-3);
  background: repeating-linear-gradient(45deg, var(--surface-3) 0 8px, var(--surface-sunk) 8px 16px);
}
.photo__cap { padding: 6px 8px; font-size: 11px; color: var(--text-2); border-top: 1px solid var(--border); background: var(--surface); overflow-wrap: anywhere; }
.photo__cap b { display: block; color: var(--text); font-size: 11.5px; }

.doc-row { display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-bottom: 1px solid var(--border); }
.doc-row:last-child { border-bottom: 0; }
.doc-row__ic { width: 30px; height: 30px; border-radius: var(--r-sm); background: var(--surface-3); color: var(--text-2); display: grid; place-items: center; flex: none; }
.doc-row__main { min-width: 0; flex: 1; }
.doc-row__name { display: block; font-size: 12.5px; font-weight: 600; overflow-wrap: anywhere; }
.doc-row__meta { display: block; font-size: 11px; color: var(--text-3); margin-top: 1px; }

.stat-row { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 7px 0; border-bottom: 1px dashed var(--border); font-size: 13px; }
.stat-row:last-child { border-bottom: 0; }
.stat-row__label { color: var(--text-2); }
.stat-row__val { font-weight: 700; font-variant-numeric: tabular-nums; }
.stat-row--total { border-top: 1.5px solid var(--border-strong); border-bottom: 0; padding-top: 10px; margin-top: 4px; font-size: 14px; }

.line-editor { display: grid; gap: 8px; }
.line-row {
  display: grid; gap: 8px; align-items: end;
  grid-template-columns: minmax(0, 2.2fr) 74px 96px 96px 40px;
  padding: 9px; border: 1px solid var(--border); border-radius: var(--r-sm); background: var(--surface-2);
}
.line-row__total { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; padding-bottom: 9px; }

/* ---- Quotation / invoice line groups ----
   Replaces the per-line .line-row box. One bordered container per KIND
   (Labour, Materials, …) rather than one per line, so a group reads as a
   single object in the drawer instead of a card inside a card inside a card.
   Read-only quotes get .qtable (no inputs at all); drafts get .qedit. */
.qlines { display: grid; gap: 16px; }
.qlines__block { min-width: 0; }
.qlines__cap {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  margin-bottom: 7px;
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .05em; color: var(--text-2);
}
.qlines__cap-note { font-size: 11.5px; font-weight: 500; text-transform: none; letter-spacing: 0; color: var(--text-3); }
.qlines__group { border: 1px solid var(--border); border-radius: var(--r-md); background: var(--surface); overflow: hidden; }
.qlines--optional .qlines__group { background: var(--surface-2); }
.qlines--optional .qtable td { color: var(--text-2); }
.qlines__foot { margin-top: 4px; }

.qtable { width: 100%; font-size: 13px; }
.qtable th, .qtable td { padding: 9px 12px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: top; }
.qtable tbody tr:last-child td { border-bottom: 0; }
.qtable thead th {
  background: var(--surface-3); color: var(--text-2);
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .045em;
  border-bottom: 1px solid var(--border-strong); white-space: nowrap;
}
.qtable .cell-num, .qtable th.cell-num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.qtable__amt { font-weight: 700; }
.qtable td:first-child { overflow-wrap: anywhere; }

/* Each kind is its own table, so auto layout sized every group's columns
   independently and the Amount column landed on a different x in each one.
   Fixed widths line all the groups up into one readable column of money. */
.qtable--lines { table-layout: fixed; }
.qtable--lines th:nth-child(2), .qtable--lines td:nth-child(2) { width: 88px; }
.qtable--lines th:nth-child(3), .qtable--lines td:nth-child(3) { width: 96px; }
.qtable--lines th:nth-child(4), .qtable--lines td:nth-child(4) { width: 116px; }
.qtable--lines th:nth-child(5), .qtable--lines td:nth-child(5) { width: 130px; }

.qedit { display: grid; }
.qedit__head, .qedit__row {
  display: grid; gap: 8px; align-items: center;
  grid-template-columns: minmax(0, 2.2fr) 78px 96px 100px 92px 40px;
  padding: 8px 10px;
}
.qedit__head {
  background: var(--surface-3); color: var(--text-2);
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .045em;
  border-bottom: 1px solid var(--border-strong);
}
/* Only the Amount column is right-aligned — the other four sit above text
   inputs, whose values render left, and a right-aligned header over a
   left-aligned value reads as a misalignment. */
.qedit__head span:nth-child(5) { text-align: right; }
.qedit__row { border-bottom: 1px solid var(--border); }
.qedit__row:last-child { border-bottom: 0; }
.qedit__cell { min-width: 0; }
.qedit__lab { display: none; font-size: 11px; font-weight: 600; color: var(--text-3); margin-bottom: 3px; }
.qedit__amt { font-weight: 700; text-align: right; font-variant-numeric: tabular-nums; }
.qedit .input { width: 100%; }

/* ---- Field mode ----
   NB: this block is `.fieldmode`, never `.field` — `.field` is the form-field
   component defined above and the two must not collide.

   Stacking scale (keep in sync — anything that opens ON TOP of field mode
   must sit above 130):
     50  topbar          55  nav backdrop     60  sidebar
     70  search results  120 popovers         130 FIELD MODE
     140 drawer scrim    150 modal scrim      200 skip link
     210 action menus    300 toasts
*/
.fieldmode {
  position: fixed; inset: 0; z-index: 130; background: var(--bg);
  display: flex; flex-direction: column; overflow: hidden;
}
.fieldmode[hidden] { display: none; }
.fieldmode__head {
  background: var(--nav-bg); color: #fff; padding: 12px 16px;
  display: flex; align-items: center; gap: 12px; flex: none;
}
.fieldmode__brand { font-size: 14px; font-weight: 700; display: flex; align-items: center; gap: 8px; }
.fieldmode__brand small { display: block; font-size: 10.5px; font-weight: 500; color: var(--nav-text-dim); }
.fieldmode__head .icon-btn { color: #fff; }
.fieldmode__head .icon-btn:hover { background: rgba(255,255,255,.12); }
.fieldmode__exit { margin-left: auto; }
.fieldmode__banner { background: var(--warn-soft); color: var(--warn-text); font-size: 11.5px; padding: 7px 16px; text-align: center; flex: none; }
.fieldmode__body { flex: 1; overflow-y: auto; padding: 14px; }
.fieldmode__inner { max-width: 640px; margin: 0 auto; display: grid; gap: 14px; }
.fieldmode__tabs { display: flex; gap: 6px; background: var(--surface-3); padding: 4px; border-radius: var(--r-md); }
.fieldmode__tab { flex: 1; min-height: 40px; border-radius: var(--r-sm); font-size: 12.5px; font-weight: 600; color: var(--text-2); }
.fieldmode__tab[aria-selected="true"] { background: var(--surface); color: var(--text); box-shadow: var(--sh-1); }

.field-job { display: grid; gap: 12px; }
.field-hero { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; }
.field-hero__top { padding: 14px; display: grid; gap: 8px; }
.field-hero__eyebrow { font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em; color: var(--accent-text); }
.field-hero__title { font-size: 17px; font-weight: 700; letter-spacing: -.015em; overflow-wrap: anywhere; }
.field-hero__addr { font-size: 13px; color: var(--text-2); overflow-wrap: anywhere; }
.field-map {
  height: 132px; position: relative; border-top: 1px solid var(--border); border-bottom: 1px solid var(--border);
}
.field-map svg { width: 100%; height: 100%; }
.field-map__tag {
  position: absolute; left: 10px; bottom: 8px; background: var(--surface);
  border-radius: var(--r-sm); padding: 3px 7px; font-size: 10.5px; color: var(--text-3);
  border: 1px solid var(--border);
}
.field-actions { display: grid; gap: 8px; grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 12px; }
.field-actions .btn { min-height: 46px; }
.field-actions .span-2 { grid-column: 1 / -1; }

.timer {
  display: flex; align-items: center; gap: 12px; padding: 14px;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
}
.timer__display { font-family: var(--ff-mono); font-size: 27px; font-weight: 700; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.timer__label { font-size: 11.5px; color: var(--text-3); }
.timer__btns { margin-left: auto; display: flex; gap: 7px; }
.timer__btns .btn { min-height: 44px; min-width: 44px; }

/* Signature surface. The ink colour is baked into the exported PNG, so the pad
   keeps the SAME sage-green paper and deep-forest ink in both themes — and the
   saved image is replayed on that same green via .signature-img below, so it
   always looks exactly as it was drawn. Ink #123024 on #dcebdd is ~13:1. */
:root { --sig-paper: #dcebdd; --sig-rule: #a9c9ae; --sig-edge: #8bb192; }
.sig-pad {
  border: 1.6px dashed var(--sig-edge); border-radius: var(--r-md);
  background: var(--sig-paper)
    linear-gradient(to bottom, transparent calc(100% - 42px), var(--sig-rule) calc(100% - 42px), var(--sig-rule) calc(100% - 41px), transparent calc(100% - 41px))
    no-repeat;
  touch-action: none; width: 100%; height: 160px; display: block;
  cursor: crosshair;
}
.sig-pad:focus-visible { border-color: var(--accent); }
.signature-img {
  margin-top: 10px; max-width: 260px; width: 100%;
  background: var(--sig-paper); border: 1px solid var(--sig-edge);
  border-radius: var(--r-sm);
}
.signature-img--wide { max-width: 100%; }
.sig-foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 8px; flex-wrap: wrap; }

/* ---- misc view pieces ---- */
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-bottom: 10px; }
.section-head h2 { font-size: 15px; font-weight: 700; letter-spacing: -.01em; }
.section-head p { font-size: 12.5px; color: var(--text-3); }

.matrix-table td.matrix-cell { text-align: center; }
.matrix-yes { color: var(--ok); }
.matrix-no { color: var(--border-strong); }

.avail-grid { display: grid; grid-template-columns: 150px repeat(7, minmax(38px, 1fr)); gap: 3px; min-width: 520px; }
.avail-head { font-size: 10.5px; text-transform: uppercase; letter-spacing: .05em; color: var(--text-3); text-align: center; font-weight: 700; padding-bottom: 4px; }
.avail-name { font-size: 12.5px; font-weight: 600; display: flex; align-items: center; gap: 7px; overflow: hidden; }
.avail-cell {
  height: 30px; border-radius: var(--r-xs); display: grid; place-items: center;
  font-size: 10px; font-weight: 700; background: var(--surface-3); color: var(--text-3);
}
.avail-cell--on { background: var(--ok-soft); color: var(--ok-text); }
.avail-cell--off { background: var(--surface-sunk); color: var(--text-3); }
.avail-cell--leave { background: var(--warn-soft); color: var(--warn-text); }
.avail-cell--part { background: var(--info-soft); color: var(--info-text); }

.print-only { display: none; }

/* =========================== 8. RESPONSIVE ========================= */

/* Small laptop 1024–1366 */
@media (max-width: 1366px) {
  :root { --gutter: 18px; --sidebar-w: 216px; }
  .data-table th, .data-table td { padding: 7px 10px; }
  .kpi__value { font-size: 22px; }
  .sched-layout { grid-template-columns: minmax(0, 1fr) 260px; }
  .map-layout { grid-template-columns: minmax(0, 1fr) 280px; }
}

@media (max-width: 1180px) {
  .dash-cols { grid-template-columns: minmax(0, 1fr); }
  .dash-cols--even { grid-template-columns: minmax(0, 1fr); }
  .sched-layout { grid-template-columns: minmax(0, 1fr); }
  .map-layout { grid-template-columns: minmax(0, 1fr); }
  /* Stacked below the map, so there is no column height to match — back in flow
     and capped again. */
  .map-layout > .sched-side > .card { position: static; }
  .map-layout > .sched-side .map-side-list { flex: 0 1 auto; max-height: 520px; }
}

/* Tablet and below — off-canvas navigation */
@media (max-width: 1023px) {
  :root { --gutter: 16px; }
  .app { grid-template-columns: minmax(0, 1fr); }
  .app.is-collapsed { grid-template-columns: minmax(0, 1fr); }
  .sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; width: 280px;
    transform: translateX(-100%); transition: transform var(--dur) ease;
    box-shadow: var(--sh-3);
  }
  .app.nav-open .sidebar { transform: none; }
  .app.is-collapsed .sidebar { width: 280px; }
  .app.is-collapsed .brand__text,
  .app.is-collapsed .nav-item__label,
  .app.is-collapsed .nav-item__badge,
  .app.is-collapsed .sidebar__group-label,
  .app.is-collapsed .demo-by__text,
  .app.is-collapsed .sidebar__collapse-label,
  .app.is-collapsed .sidebar__reset-label { display: revert; }
  .app.is-collapsed .nav-item { justify-content: flex-start; padding: 8px 10px; }
  .app.is-collapsed .sidebar__brand { justify-content: space-between; padding: 0 12px 0 14px; }
  .app.is-collapsed .brand { justify-content: flex-start; }
  .app.is-collapsed .demo-by { justify-content: flex-start; padding: 10px; }
  .sidebar .sidebar__close { display: inline-flex; }
  .sidebar__collapse { display: none; }
  .topbar .topbar__menu { display: inline-flex; }
  .topbar__field span { display: none; }
  .topbar__field { width: 38px; padding: 0; }
  .user-btn__text { display: none; }
  .nav-item { min-height: 44px; }
  .table-wrap { max-height: none; }
  .detail-grid { grid-template-columns: minmax(0, 1fr); }
}

/* Mobile */
@media (max-width: 767px) {
  :root { --gutter: 12px; --topbar-h: 56px; }
  body { font-size: 14px; }
  .page-head__row { align-items: flex-start; flex-direction: column; gap: 10px; }
  .page-head__actions { width: 100%; }
  .page-head__actions .btn { flex: 1; }
  .page-title { font-size: 19px; }
  .global-search { max-width: none; }
  .global-search__kbd { display: none; }
  .topbar { gap: 8px; padding: 0 12px; }

  /* Six controls do not fit 390px. Field mode and the theme toggle move to the
     sidebar foot; the bell and avatar stay because both carry live state. */
  .topbar__field, #themeToggle { display: none; }
  .sidebar__utils { display: flex; }

  /* Keep the close button beside the title. It used to be forced to width:100%,
     which — .drawer__top being nowrap — crushed the title to zero width. */
  .drawer__top { flex-wrap: wrap; }
  .drawer__top > :first-child { flex: 1 1 200px; min-width: 0; }
  .drawer__actions { flex-wrap: wrap; justify-content: flex-end; }

  /* Anchored to the bell, a 360px popover starts off-screen left. Pin it to the
     viewport instead. */
  .popover--wide {
    position: fixed; left: 12px; right: 12px; width: auto; max-width: none;
    top: calc(var(--topbar-h) + 6px);
  }

  /* Lead with the map, not with 560px of selects. The filter card and the map
     share .stack; .sched-side is hidden at this width. */
  .map-layout > .stack > .map-frame { order: -1; }

  /* The toolbar already drives the agenda and offers more than these do. */
  .agenda__controls,
  .sched-toolbar .btn-group[aria-label="Board view"] { display: none; }

  /* Inner scrollers fight the thumb; let these run their natural length. */
  .dash-cols .attention-list, .dash-cols .feed { max-height: none; overflow-y: visible; }

  /* Scoped to the tablekit: this swap exists so list views show .record-cards
     instead of a table. Drawer-hosted tables (job materials, supplier orders,
     invoice variations) are not part of that swap and must keep rendering —
     unscoped, this rule blanked all three on mobile. */
  .tablekit .table-wrap { display: none; }
  .tablekit .record-cards { display: grid; }
  .tablekit__search { max-width: none; flex-basis: 100%; }
  .tablekit__count { width: 100%; }
  .filters__grid { grid-template-columns: minmax(0, 1fr); }
  .pager { flex-direction: column; align-items: stretch; gap: 10px; }
  .pager__nav { justify-content: center; }
  .pager__row { justify-content: space-between; gap: 10px; }

  .scrim { padding: 0; align-items: flex-end; }
  .modal { width: 100%; max-height: 100vh; height: 100%; border-radius: 0; border: 0; }
  .modal__foot { border-radius: 0; }
  .form-grid { grid-template-columns: minmax(0, 1fr); }
  .line-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .line-row .span-2 { grid-column: 1 / -1; }

  /* Quotation lines stack rather than scroll. A five-column table at 390px is
     unreadable, and a drawer is the worst place to hide content behind a
     horizontal scroller. Description leads; qty/unit/rate collapse onto one
     grey meta line; the amount sits right. */
  .qtable thead { display: none; }
  .qtable, .qtable tbody, .qtable tr, .qtable td { display: block; }
  /* The desktop column widths would otherwise box the stacked cells — the
     Amount cell stayed 130px and stopped aligning to the row's right edge.
     :nth-child(n) is here to match the specificity of the rules above; a bare
     `td` selector loses to `td:nth-child(5)` and the widths survive. */
  .qtable--lines { table-layout: auto; }
  .qtable--lines th:nth-child(n), .qtable--lines td:nth-child(n) { width: auto; }
  .qtable tr { padding: 10px 12px; border-bottom: 1px solid var(--border); }
  .qtable tbody tr:last-child { border-bottom: 0; }
  .qtable td { padding: 0; border-bottom: 0; }
  .qtable td:first-child { font-weight: 600; margin-bottom: 3px; }
  .qtable td[data-label="Qty"], .qtable td[data-label="Unit"], .qtable td[data-label="Rate"] {
    display: inline; font-size: 12px; color: var(--text-3); text-align: left;
  }
  .qtable td[data-label="Unit"]::before { content: " "; }
  .qtable td[data-label="Rate"]::before { content: " × "; }
  .qtable td[data-label="Amount"] { text-align: right; margin-top: 2px; }

  .qedit__head { display: none; }
  .qedit__row { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: end; padding: 12px 10px; }
  .qedit__cell--desc { grid-column: 1 / -1; }
  .qedit__lab { display: block; }
  .qedit__amt { grid-column: 1 / 2; align-self: center; text-align: left; }
  .qedit__row .icon-btn { grid-column: 2 / 3; justify-self: end; }

  .drawer { width: 100%; border-left: 0; }
  .drawer__body { padding: 12px; }

  .toast-root { left: 12px; right: 12px; bottom: 12px; width: auto; }

  .sched-board { display: none; }
  .sched-side { display: none; }
  .agenda { display: grid; gap: 14px; }
  .sched-layout { grid-template-columns: minmax(0, 1fr); }

  .map-overlay { position: static; max-width: none; padding: 10px; }
  .map-preview { position: static; width: auto; margin: 10px; }
  .kpi__value { font-size: 21px; }
  .kpi-grid { grid-template-columns: repeat(auto-fit, minmax(148px, 1fr)); }
  .mini-tl-row { grid-template-columns: 74px 1fr; }
  .mini-tl-scale { padding-left: 84px; }
  .field-actions { grid-template-columns: minmax(0, 1fr); }
  .app-foot { font-size: 11px; }
}

/* KPI tiles and record-card fields stay two-up here — at 390px there is room,
   and one-up made Reports 7.6 screens tall. The .kpi-grid auto-fit rule above
   drops to a single column on its own below ~320px. */
@media (max-width: 420px) {
  .btn-group button { padding: 0 9px; font-size: 12px; }
}

/* ============================ 9. PRINT ============================= */
@media print {
  :root { --gutter: 0; }
  body { background: #fff; color: #000; font-size: 11pt; }
  .sidebar, .sidebar-backdrop, .topbar, .page-head__actions, .app-foot,
  .toast-root, .drawer-scrim, .field, .tablekit__bar, .filters, .pager,
  .record-cards, .row-actions-cell, .no-print { display: none !important; }
  .app { display: block; }
  .page-body { padding: 0; }
  .print-only { display: block; }
  .card, .panel, .table-wrap { border: 1px solid #bbb; box-shadow: none; break-inside: avoid; }
  .table-wrap { max-height: none; overflow: visible; }
  .data-table th { background: #eee !important; color: #000; }
  .print-doc { padding: 0; }
  .print-doc__head { display: flex; justify-content: space-between; gap: 24px; border-bottom: 2px solid #000; padding-bottom: 12px; margin-bottom: 16px; }
  .print-doc__brand { font-size: 20pt; font-weight: 700; }
  .print-doc h2 { font-size: 13pt; margin: 14px 0 6px; }
  a { text-decoration: none; color: #000; }
}

/* ==================== 10. LATE ADDITIONS ========================== */

/* Mobile record-card open target */
.record-card__open {
  display: grid; gap: 2px; text-align: left; min-width: 0; flex: 1;
  border-radius: var(--r-sm); padding: 2px;
}
.record-card__open:hover .record-card__title { text-decoration: underline; }

/* Let drops land on the row track rather than on the block being dragged */
.sched-board.is-dragging .job-block { pointer-events: none; }
.sched-board.is-dragging .sched-slot,
.sched-board.is-dragging .week-cell { pointer-events: auto; }

/* Printable documents are built on demand and hidden on screen */
.print-doc { display: none; }
@media print {
  body.printing .app,
  body.printing .fieldmode,
  body.printing #drawerRoot,
  body.printing #modalRoot { display: none !important; }
  body.printing .print-doc { display: block !important; padding: 0; }
  body.printing .print-doc table { width: 100%; margin-bottom: 10px; font-size: 10pt; }
  body.printing .print-doc th, body.printing .print-doc td { border: 1px solid #999; padding: 5px 7px; text-align: left; }
}

/* Chart focus states */
.chart-hit:focus-visible, .chart-bar:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* Field mode agenda cards are buttons */
button.agenda-card { cursor: pointer; }
button.agenda-card:hover { border-color: var(--border-strong); background: var(--surface-2); }
button.agenda-card .agenda-card__meta { display: grid; gap: 3px; }
button.agenda-card .agenda-card__foot { display: flex; gap: 6px; flex-wrap: wrap; }

/* Keep long select values from stretching toolbars */
.sched-toolbar__right .select { max-width: 200px; }

/* Availability legend spacing inside the crews view */
.avail-grid + .small { margin-top: 8px; }

/* Ensure sticky first column stays legible on hover in dark mode */
[data-theme="dark"] .data-table tbody tr:hover td.col-sticky { background: var(--surface-2); }

/* ================= 11. OVERFLOW GUARDS ============================ */
/* Flex and grid children default to min-width:auto, which lets wide
   content push the page wider than the viewport. */
.topbar, .global-search, .global-search__input { min-width: 0; }
.card, .panel, .card__body, .card__head,
.stack > *, .grid > *, .detail-grid > *, .dash-cols > *,
.sched-layout > *, .map-layout > *, .kpi-grid > *, .tablekit > * { min-width: 0; }
.scroll-x { overflow-x: auto; max-width: 100%; }
.section-head { min-width: 0; }
.attention__main, .search-result__main, .doc-row__main { min-width: 0; }

@media (max-width: 480px) {
  .user-btn { padding: 4px; }
  .user-btn .icon--sm { display: none; }
  .topbar { gap: 6px; }
  .topbar__actions { gap: 2px; }
  .icon-btn { width: 36px; }
}

/* ============= 12. TOUCH TARGET SIZING (tablet & mobile) ========== */
@media (max-width: 1023px) {
  .btn { min-height: 44px; }
  .btn--sm { min-height: 40px; }
  .btn--xs { min-height: 36px; }
  .btn--link { min-height: 0; }
  .icon-btn { width: 44px; height: 44px; }
  .topbar__field { width: 44px; }
  .rowmenu-btn { width: 44px; height: 44px; }
  .pager__btn { min-width: 44px; height: 44px; }
  .pager__size select { min-height: 44px; }
  .input, .select, .textarea { min-height: 44px; }
  .input[type="date"], .input[type="time"] { height: 44px; }
  .textarea { min-height: 96px; }
  .chip { padding: 6px 6px 6px 12px; }
  .chip__x { width: 24px; height: 24px; }
  .popover__item, .menu__item { min-height: 44px; }
  .tab { min-height: 46px; }
  .fieldmode__tab { min-height: 46px; }
  .checklist__item { min-height: 48px; }
  .timer__btns .btn { min-height: 48px; min-width: 48px; }
  .map-toggle { min-height: 40px; }
  .btn-group button { min-height: 44px; }
  .th-btn { min-height: 44px; }
}

/* ---- schedule toolbar: stack the control group below the date at narrow widths ---- */
@media (max-width: 1180px) {
  .sched-toolbar__right { margin-left: 0; width: 100%; justify-content: flex-start; }
}
@media (max-width: 640px) {
  .sched-toolbar .tablekit__search { flex-basis: 100%; max-width: none; }
  .sched-toolbar .select { max-width: none; flex: 1 1 140px; }
  .sched-date { min-width: 0; }
}

/* ---- pointer-driven board drag ---------------------------------- */
.job-block, .tray-card {
  -webkit-user-drag: none; user-select: none; -webkit-user-select: none;
}
.drag-ghost {
  z-index: 400; pointer-events: none; opacity: .95;
  transform: translate(-50%, -50%); box-shadow: var(--sh-3);
  border-color: var(--accent); cursor: grabbing;
}
body.is-dragging-board { cursor: grabbing; }
body.is-dragging-board * { cursor: grabbing !important; }
.sched-board.is-dragging .job-block { pointer-events: none; }
.sched-board.is-dragging .sched-slot,
.sched-board.is-dragging .week-cell { pointer-events: auto; }
.tray.is-over { outline: 2px dashed var(--accent); outline-offset: -4px; border-radius: var(--r-md); }

/* ---- "built by" card inside the About dialog ---------------------- */
.about-by {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 14px; margin-top: 4px;
  background: var(--accent-soft); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: var(--r-md);
}
.about-by__mark {
  flex: none; width: 38px; height: 38px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--accent); color: #fff; font-size: 13px; font-weight: 800;
}
.about-by__label {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .09em; color: var(--accent-text);
}
.about-by__name { font-size: 15px; font-weight: 700; letter-spacing: -.01em; margin-top: 1px; }
.about-by__body { font-size: 12.5px; color: var(--text-2); margin-top: 7px; }
.about-by__links {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px;
  margin-top: 11px; font-size: 12.5px; font-weight: 600;
}
.about-by__links a, .about-by__links span { display: inline-flex; align-items: center; gap: 6px; }
.about-by__links a { color: var(--accent-text); }
.about-by__links span { color: var(--text-2); }
.about-by__links .icon { color: var(--accent); }

@media (max-width: 520px) {
  .about-by { flex-direction: column; }
}
