/* UKCS Group CRM — design system.
   =================================================================

   Brand confirmed by Jake, 14 August 2026: **white and UKCS blue**, from the
   group logo. So this is now light-first — the opposite of the ACSL CRM, and
   the opposite of the placeholder this replaces.

   #2b3b7d confirmed by Jake as correct, 20 August 2026.

   Note: that is the screen value. If a print piece ever needs a Pantone, it is
   a separate number and a conversion — do not read one off this hex.

   Division colours are Jake's own values, stored per division in the database
   (divisions.accent) — these are only the fallbacks.
   ================================================================= */

:root {
  color-scheme: light;

  /* The one brand value. Everything else is derived from it. */
  --brand-blue:      #2b3b7d;
  --brand-blue-dark: #1f2c60;
  --brand-blue-lift: #6c82d6;   /* legible on dark surfaces */

  /* Surfaces — white first, as asked. */
  --bg:        #ffffff;
  --bg-2:      #f6f8fc;
  --surface:   #ffffff;
  --surface-2: #f8fafd;
  --surface-3: #eef2f9;
  --border:    #dde3ee;
  --border-2:  #c2cbdd;

  --text:  #16192a;
  --muted: #545d78;
  --dim:   #838CA5;

  --accent:      var(--brand-blue);
  --accent-2:    var(--brand-blue-dark);
  --accent-ink:  #ffffff;
  --accent-soft: rgba(43, 59, 125, 0.09);
  --ring:        var(--brand-blue);

  /* Status. Darkened for white — the dark-mode greens and ambers fail
     contrast on a white background. */
  --good:    #15803d;
  --warn:    #b45309;
  --bad:     #b91c1c;
  --info:    #1d4ed8;
  --neutral: #64748b;

  /* Division tints. Jake's values, 14 Aug 2026. Overridden per division from
     the database at render time; these are the fallbacks. */
  --div-ukcs:      #2b3b7d;   /* the brand blue */
  --div-festivals: #2a7d3c;   /* Festival Green */
  --div-packaging: #ff7c5b;   /* BP Orange */

  /* Section hues — see app/core/sections.py for why these and not others.
     Section colour is chrome (where you are); division colour is data (whose
     record this is). They never appear in the same place, which is what stops
     Finance-green and Festivals-green from being mistaken for each other. */
  --sec-home:      #2b3b7d;
  --sec-customers: #0b63ce;
  --sec-sales:     #4338ca;
  --sec-comms:     #a21caf;
  --sec-catalogue: #0e7490;
  --sec-suppliers: #0f766e;
  --sec-purchasing:#3f6212;
  --sec-stock:     #a16207;
  --sec-production:#c2410c;
  --sec-despatch:  #7c2d12;
  --sec-finance:   #15803d;
  --sec-review:    #9f1239;
  --sec-admin:     #475569;

  --radius:    14px;
  --radius-sm: 9px;
  --radius-xs: 6px;
  --ease: cubic-bezier(.22,.61,.36,1);
  --shadow: 0 8px 28px rgba(22,25,42,.10);
  --shadow-sm: 0 1px 4px rgba(22,25,42,.07);

  --font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-display: 'Space Grotesk', var(--font-body);
  --font-mono: ui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace;

  --sidebar-w: 248px;
  --topbar-h: 58px;
}

/* Dark. Still shipped — warehouse screens, and evening use. The navy is
   unreadable as an accent on near-black, so the lifted blue takes over;
   BP Orange is left alone because it already reads on both. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --bg:        #0b0e18;
  --bg-2:      #101524;
  --surface:   #151b2c;
  --surface-2: #1b2236;
  --surface-3: #222c44;
  --border:    #2a3450;
  --border-2:  #3b4770;

  --text:  #eef1f8;
  --muted: #99a3bd;
  --dim:   #67718f;

  --accent:      var(--brand-blue-lift);
  --accent-2:    #8497e0;
  --accent-ink:  #0b0e18;
  --accent-soft: rgba(108, 130, 214, 0.16);
  --ring:        var(--brand-blue-lift);

  --good:    #4ade80;
  --warn:    #fbbf24;
  --bad:     #f87171;
  --info:    #60a5fa;
  --neutral: #8b95ab;

  --div-ukcs:      #6c82d6;
  --div-festivals: #4ea866;
  --div-packaging: #ff7c5b;


  /* Lifted for near-black. The light values are 4.5:1 on white and roughly
     2:1 on #0b0e18, which is unreadable — these are the same hues rebuilt
     against the dark surface, not the same numbers reused. */
  --sec-home:      #6d87e8;
  --sec-customers: #5ab0f5;
  --sec-sales:     #c0a3fb;
  --sec-comms:     #e97ff2;
  --sec-catalogue: #4ec7e0;
  --sec-suppliers: #35c7bd;
  --sec-purchasing:#a8cf52;
  --sec-stock:     #e8bb45;
  --sec-production:#fa8b5c;
  --sec-despatch:  #cf9179;
  --sec-finance:   #4fd287;
  --sec-review:    #fb7f92;
  --sec-admin:     #94a3b8;

  --shadow: 0 8px 28px rgba(0,0,0,.45);
  --shadow-sm: 0 2px 8px rgba(0,0,0,.3);
}

/* Following the device, when the device is dark. */
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    color-scheme: dark;
    --bg:        #0b0e18;
    --bg-2:      #101524;
    --surface:   #151b2c;
    --surface-2: #1b2236;
    --surface-3: #222c44;
    --border:    #2a3450;
    --border-2:  #3b4770;
    --text:  #eef1f8;
    --muted: #99a3bd;
    --dim:   #67718f;
    --accent:      var(--brand-blue-lift);
    --accent-2:    #8497e0;
    --accent-ink:  #0b0e18;
    --accent-soft: rgba(108, 130, 214, 0.16);
    --ring:        var(--brand-blue-lift);
    --good: #4ade80;
    --warn: #fbbf24;
    --bad:  #f87171;
    --info: #60a5fa;
    --div-ukcs:      #6c82d6;
    --div-festivals: #4ea866;
    --div-packaging: #ff7c5b;

    /* Lifted for near-black. The light values are 4.5:1 on white and roughly
       2:1 on #0b0e18, which is unreadable — these are the same hues rebuilt
       against the dark surface, not the same numbers reused. */
    --sec-home:      #6d87e8;
    --sec-customers: #5ab0f5;
    --sec-sales:     #c0a3fb;
    --sec-comms:     #e97ff2;
    --sec-catalogue: #4ec7e0;
    --sec-suppliers: #35c7bd;
    --sec-purchasing:#a8cf52;
    --sec-stock:     #e8bb45;
    --sec-production:#fa8b5c;
    --sec-despatch:  #cf9179;
    --sec-finance:   #4fd287;
    --sec-review:    #fb7f92;
    --sec-admin:     #94a3b8;
    --shadow: 0 8px 28px rgba(0,0,0,.45);
    --shadow-sm: 0 2px 8px rgba(0,0,0,.3);
  }
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 14px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 600;
  margin: 0;
  letter-spacing: -0.01em;
}

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

/* ── Shell ─────────────────────────────────────────────────────────── */

.shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--bg-2);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--border);
}
.brand .mark {
  width: 30px; height: 30px;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  color: var(--accent-ink);
  display: grid; place-items: center;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 13px;
  flex: 0 0 30px;
}
.brand .name { font-family: var(--font-display); font-weight: 600; font-size: 14px; }
.brand .env { font-size: 11px; color: var(--dim); text-transform: uppercase; letter-spacing: .06em; }

.nav { padding: 10px 8px; flex: 1; }
.nav a {
  display: flex; align-items: center; gap: 9px;
  padding: 7px 10px;
  border-radius: var(--radius-sm);
  color: var(--muted);
  font-size: 13px;
  text-decoration: none;
}
.nav a:hover { background: var(--surface); color: var(--text); text-decoration: none; }
.nav a.active { background: var(--accent-soft); color: var(--accent); font-weight: 500; }
.nav a .ico { width: 16px; text-align: center; opacity: .85; font-size: 13px; }
.nav a .count {
  margin-left: auto;
  background: var(--accent); color: var(--accent-ink);
  border-radius: 20px; padding: 0 6px; font-size: 11px; font-weight: 600;
}
.nav-label {
  font-size: 10.5px; text-transform: uppercase; letter-spacing: .09em;
  color: var(--dim); padding: 14px 10px 5px; font-weight: 600;
}
.nav-group > summary { list-style: none; cursor: pointer; }
.nav-group > summary::-webkit-details-marker { display: none; }

.sidebar-foot {
  padding: 12px 14px;
  border-top: 1px solid var(--border);
  font-size: 12px;
  color: var(--muted);
}
.sidebar-foot .who { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.avatar {
  width: 28px; height: 28px; border-radius: 50%;
  display: grid; place-items: center;
  border: 1.5px solid var(--border-2);
  font-size: 11px; font-weight: 600;
  flex: 0 0 28px;
}
.avatar.sm {
  width: 20px; height: 20px; flex: 0 0 20px; font-size: 9px;
  display: inline-grid; vertical-align: -4px; margin-right: 5px;
}

/* Share-of-turnover bar on the sales performance table. A proportion is read
   faster as a length than as a percentage, and the tint is the person's own
   accent so a row is identifiable before it is read. */
.share {
  height: 6px; border-radius: 3px;
  background: var(--surface-2); border: 1px solid var(--border);
  overflow: hidden; margin-top: 4px;
}
.share i { display: block; height: 100%; min-width: 2px; }

/* An overstated figure, said in the same breath as the figure. */
.warn-note { color: var(--warn); }

/* A queued draft, shown exactly as it would go out. Monospace and preserved
   whitespace on purpose: an approval given against reflowed, prettified text
   is an approval of something other than what gets sent. */
pre.draft {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 12.5px; line-height: 1.65;
  white-space: pre-wrap; word-break: break-word;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px 18px; margin: 4px 0 16px;
  max-height: 60vh; overflow-y: auto;
  color: var(--text);
}

/* The theme switch. Sits with the account links because that is where
   somebody looks for a preference, and it is the one preference worth reaching
   in a single click — a warehouse screen at 6am and a laptop at noon want
   different answers. */
.foot-row { display: flex; align-items: center; gap: 8px; }
.foot-row > span:first-child { flex: 1; min-width: 0; }
.theme-btn {
  flex: 0 0 26px;
  width: 26px; height: 26px;
  display: grid; place-items: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-xs);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  font-family: inherit;
}
.theme-btn:hover { border-color: var(--border-2); color: var(--text); }

.sidebar-foot .name { color: var(--text); font-weight: 500; }
.sidebar-foot .role { color: var(--dim); font-size: 11px; }

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

.topbar {
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px;
  border-bottom: 1px solid var(--border);
  background: var(--bg);
  position: sticky; top: 0; z-index: 20;
}
.topbar h1 { font-size: 16px; }
.topbar .sub { color: var(--dim); font-size: 12.5px; }
.topbar .spacer { flex: 1; }

.searchbtn {
  display: flex; align-items: center; gap: 8px;
  background: var(--surface); border: 1px solid var(--border);
  color: var(--muted);
  border-radius: var(--radius-sm);
  padding: 6px 10px; font-size: 12.5px; cursor: pointer;
  font-family: inherit;
}
.searchbtn:hover { border-color: var(--border-2); color: var(--text); }
kbd {
  font-family: var(--font-mono); font-size: 10.5px;
  background: var(--surface-3); border: 1px solid var(--border);
  border-radius: 4px; padding: 1px 4px; color: var(--dim);
}

.content { padding: 20px; flex: 1; }

/* ── Sections ──────────────────────────────────────────────────────────
   A quiet colour per part of the business, so somebody four screens deep can
   tell Sales from Stock without stopping to read the heading. Defined in
   app/core/sections.py; painted here.

   Deliberately restrained. Colour lands on the furniture — the sidebar group
   markers, the active nav item, the rail under the top bar, a wash at the head
   of the page. It never lands on a row, a figure or a status badge, because
   those already carry meaning of their own and a second colour system on top
   of them would fight it.

   Colour is never the only signal. The top bar names the section in words as
   well, so this works for a colour-blind user and for anyone who has not yet
   learned which green is Finance.
   ------------------------------------------------------------------------ */

:root { --section: var(--accent); }

[data-section="home"]       { --section: var(--sec-home); }
[data-section="review"]     { --section: var(--sec-review); }
[data-section="customers"]  { --section: var(--sec-customers); }
[data-section="sales"]      { --section: var(--sec-sales); }
[data-section="production"] { --section: var(--sec-production); }
[data-section="catalogue"]  { --section: var(--sec-catalogue); }
[data-section="suppliers"]  { --section: var(--sec-suppliers); }
[data-section="purchasing"] { --section: var(--sec-purchasing); }
[data-section="stock"]      { --section: var(--sec-stock); }
[data-section="despatch"]   { --section: var(--sec-despatch); }
[data-section="comms"]      { --section: var(--sec-comms); }
[data-section="finance"]    { --section: var(--sec-finance); }
[data-section="admin"]      { --section: var(--sec-admin); }

/* The sidebar is the legend. Every group carries its own marker all the time,
   not only when active — that is what lets someone learn the palette by using
   the thing, and what makes "which section am I in" answerable by comparison
   rather than by memory. */
.nav-label {
  display: flex;
  align-items: center;
  gap: 7px;
}
.nav-sec .nav-label::before,
.nav-label.mixed::before {
  content: "";
  width: 3px;
  height: 10px;
  border-radius: 2px;
  background: var(--section);
  opacity: .5;
  flex: 0 0 3px;
}

/* The group you are in: marker solid, label in its own colour. `:has` is not
   supported everywhere — where it is missing the label simply stays muted,
   which is the current design, so nothing breaks. */
.nav-sec:has(a.active) .nav-label { color: var(--section); }
.nav-sec:has(a.active) .nav-label::before { opacity: 1; height: 12px; }

/* Links with no heading above them — Dashboard, Sales performance, and the
   boards. The boards are the reason this exists: they sit under one
   "Pipelines" heading but belong to four different sections, so the heading
   cannot colour them and each has to say for itself that the Orders board is
   Sales and the Production board is not. Same 3px bar as the group markers,
   so it reads as the same language rather than a second one. */
.nav-sec.solo > a::before {
  content: "";
  width: 3px;
  height: 13px;
  border-radius: 2px;
  background: var(--section);
  opacity: .45;
  flex: 0 0 3px;
}
.nav-sec.solo > a.active::before { opacity: 1; }

/* "Pipelines" is the one heading that is not a single section. It gets a
   neutral marker rather than borrowing a colour it has no claim to — the four
   links underneath carry the real ones. */
.nav-label.mixed::before { background: var(--border-2); opacity: 1; }

.nav-sec a:hover {
  background: color-mix(in srgb, var(--section) 7%, var(--surface));
  color: var(--text);
}
.nav-sec a.active {
  background: color-mix(in srgb, var(--section) 12%, transparent);
  color: var(--section);
  font-weight: 500;
  box-shadow: inset 2px 0 0 var(--section);
}
.nav-sec a.active .ico { opacity: 1; }
.nav-sec a .count { background: var(--section); }

/* The rail. Two pixels under the top bar, fading out to the right so it reads
   as a tint on the chrome rather than a second border competing with the one
   already there. */
.topbar::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -1px;
  height: 2px;
  background: linear-gradient(
    90deg,
    var(--section),
    color-mix(in srgb, var(--section) 22%, transparent) 55%,
    transparent);
}

.sec-chip {
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .07em;
  white-space: nowrap;
  color: var(--section);
  background: color-mix(in srgb, var(--section) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--section) 26%, transparent);
  border-radius: 999px;
  padding: 3px 9px;
}

/* The wash. 4% at the top of the page, gone by 240px. Enough that two screens
   side by side are obviously different; not enough to read as a coloured page
   or to touch the contrast of anything sitting on it. */
.main {
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--section) 4%, transparent),
    transparent 240px);
}

/* The wordmark follows the section too, so the one fixed point in the window
   confirms it. Restrained to the sub-line: the name stays brand blue, because
   that is the logo and it is not ours to recolour. */
.shell[data-section] .wm-sub { color: color-mix(in srgb, var(--section) 62%, var(--dim)); }

@media (max-width: 860px) {
  /* The heading is the thing that has to survive a narrow window. */
  .sec-chip { display: none; }
}

@media print {
  .topbar::after, .main { background: none; }
}

/* ── Cards, tables ─────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
}
.card + .card { margin-top: 16px; }
.card-head {
  display: flex; align-items: center; gap: 10px;
  padding: 13px 16px; border-bottom: 1px solid var(--border);
}
/* Panel headings carry the section colour too — "Sales this month", "Waiting
   for you", "Recent activity". Ben's ask, 3 September 2026.

   Text plus a 5% wash on the head bar rather than one or the other: the wash
   makes the heading read as a band across the top of the card at a glance,
   the colour makes it legible as a heading close up. Every section colour is
   at least 4.7:1 on the card surface in both themes, so this is a tint, not a
   contrast cost — see tests/test_you_can_tell_which_section_you_are_in.py. */
.card-head { background: color-mix(in srgb, var(--section) 5%, transparent); }
.card-head h2 { font-size: 14px; color: var(--section); }
.card-head .spacer { flex: 1; }
.card-body { padding: 16px; }

.blurb {
  color: var(--muted); font-size: 12.5px;
  padding: 10px 16px; background: var(--surface-2);
  border-bottom: 1px solid var(--border);
}

/* Wide content scrolls inside its own container — the page body must never
   scroll horizontally. */
.table-wrap { overflow-x: auto; }

table.grid { width: 100%; border-collapse: collapse; font-size: 13px; }
table.grid th {
  text-align: left; font-weight: 600; font-size: 11px;
  text-transform: uppercase; letter-spacing: .06em;
  color: var(--dim);
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
  position: sticky; top: 0; background: var(--surface); z-index: 1;
}
table.grid th a { color: inherit; }
table.grid td {
  padding: 9px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: top;
}
table.grid tbody tr:hover { background: var(--surface-2); }
table.grid tbody tr:last-child td { border-bottom: 0; }
table.grid td.num { text-align: right; font-variant-numeric: tabular-nums; }
table.grid .muted { color: var(--dim); }

.empty {
  padding: 40px 20px; text-align: center; color: var(--dim);
}
.empty h3 { color: var(--muted); font-size: 14px; margin-bottom: 6px; }

/* ── Buttons, chips, badges ────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; gap: 7px;
  background: var(--accent); color: var(--accent-ink);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  padding: 7px 13px; font-size: 13px; font-weight: 500;
  cursor: pointer; font-family: inherit;
  text-decoration: none;
}
.btn:hover { background: var(--accent-2); text-decoration: none; }
.btn.ghost { background: transparent; border-color: var(--border-2); color: var(--text); }
.btn.ghost:hover { background: var(--surface-2); }
.btn.danger { background: var(--bad); color: #fff; }
.btn.sm { padding: 4px 9px; font-size: 12px; }
.btn:disabled { opacity: .45; cursor: not-allowed; }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; border-radius: 20px;
  font-size: 11px; font-weight: 500;
  background: var(--surface-3); color: var(--muted);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.badge.good { color: var(--good); border-color: color-mix(in srgb, var(--good) 35%, transparent); background: color-mix(in srgb, var(--good) 12%, transparent); }
.badge.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 35%, transparent); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.badge.bad  { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 35%, transparent);  background: color-mix(in srgb, var(--bad) 12%, transparent); }
.badge.info { color: var(--info); border-color: color-mix(in srgb, var(--info) 35%, transparent); background: color-mix(in srgb, var(--info) 12%, transparent); }

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

/* Maturity banner. Saying "Module 02 fills this" on an empty screen is the
   difference between a client reading it as staged and reading it as broken. */
.maturity {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 16px;
  font-size: 12.5px;
  background: color-mix(in srgb, var(--info) 9%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--info) 25%, transparent);
  color: var(--muted);
}
.maturity b { color: var(--info); font-weight: 600; }

/* ── Forms ─────────────────────────────────────────────────────────── */

.fields { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 14px; }
.field { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.field.wide { grid-column: 1 / -1; }
.field .lbl { font-size: 12px; color: var(--muted); font-weight: 500; }
.field .help { font-size: 11.5px; color: var(--dim); line-height: 1.45; }
.field .req { color: var(--bad); }

input[type=text], input[type=email], input[type=url], input[type=tel],
input[type=number], input[type=date], input[type=datetime-local],
input[type=password], select, textarea {
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  color: var(--text);
  padding: 7px 10px;
  font-size: 13px;
  font-family: inherit;
  width: 100%;
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
textarea { min-height: 84px; resize: vertical; }
input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); }

.check { flex-direction: row; align-items: center; gap: 8px; }

.form-actions {
  display: flex; gap: 10px; align-items: center;
  padding: 14px 16px; border-top: 1px solid var(--border);
  background: var(--surface-2);
}
.form-actions .spacer { flex: 1; }

/* ── Board ─────────────────────────────────────────────────────────── */

.board { display: flex; gap: 12px; overflow-x: auto; padding-bottom: 8px; align-items: flex-start; }
.board-col {
  flex: 0 0 268px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  display: flex; flex-direction: column;
  max-height: calc(100vh - 190px);
}
.board-col.terminal { opacity: .82; }
.board-col-head {
  padding: 10px 12px; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 8px;
}
.board-col-head .t { font-weight: 600; font-size: 12.5px; }
.board-col-head .n { color: var(--dim); font-size: 11.5px; }
.board-col-head .sum { margin-left: auto; font-size: 11.5px; color: var(--muted); font-variant-numeric: tabular-nums; }
.board-conv {
  font-size: 10.5px; color: var(--dim);
  padding: 4px 12px; border-bottom: 1px solid var(--border);
}
.board-cards { padding: 8px; overflow-y: auto; display: flex; flex-direction: column; gap: 7px; flex: 1; min-height: 60px; }
.board-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: 9px 10px;
  cursor: grab;
  font-size: 12.5px;
}
.board-card:hover { border-color: var(--border-2); }
.board-card.dragging { opacity: .4; }
.board-card .t { font-weight: 500; margin-bottom: 3px; display: block; color: var(--text); }
.board-card .m { color: var(--dim); font-size: 11.5px; display: flex; align-items: center; gap: 6px; }
.board-cards.over { background: var(--accent-soft); border-radius: var(--radius-sm); }

/* ── Timeline ──────────────────────────────────────────────────────── */

.timeline { display: flex; flex-direction: column; }
.tl-item { display: flex; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--border); }
.tl-item:last-child { border-bottom: 0; }
.tl-ico {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--surface-3); border: 1px solid var(--border);
  display: grid; place-items: center; font-size: 11px;
  flex: 0 0 26px; color: var(--muted);
}
.tl-body { flex: 1; min-width: 0; }
.tl-body .w { font-size: 12.5px; }
.tl-body .when { color: var(--dim); font-size: 11px; }
.tl-body .sum { color: var(--muted); font-size: 12.5px; margin-top: 2px; }

/* ── Detail layout ─────────────────────────────────────────────────── */

.detail { display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1080px) { .detail { grid-template-columns: 1fr; } }

.kv { display: grid; grid-template-columns: 150px 1fr; gap: 8px 14px; font-size: 13px; }
.kv dt { color: var(--muted); font-size: 12px; }
.kv dd { margin: 0; word-break: break-word; }

/* ── Command palette ───────────────────────────────────────────────── */

.palette-backdrop {
  position: fixed; inset: 0; background: rgba(0,0,0,.55);
  display: none; z-index: 100;
}
.palette-backdrop.open { display: block; }
.palette {
  position: fixed; top: 14vh; left: 50%; transform: translateX(-50%);
  width: min(640px, 92vw);
  background: var(--surface); border: 1px solid var(--border-2);
  border-radius: var(--radius); box-shadow: var(--shadow);
  display: none; z-index: 101; overflow: hidden;
}
.palette.open { display: block; }
.palette input {
  border: 0; border-bottom: 1px solid var(--border);
  border-radius: 0; padding: 14px 16px; font-size: 15px;
  background: transparent;
}
.palette input:focus { box-shadow: none; border-color: var(--border); }
.palette .results { max-height: 52vh; overflow-y: auto; }
.palette .res {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 16px; cursor: pointer; font-size: 13px;
  border-bottom: 1px solid var(--border);
}
.palette .res:last-child { border-bottom: 0; }
.palette .res.sel, .palette .res:hover { background: var(--accent-soft); }
.palette .res .k {
  font-size: 10.5px; color: var(--dim); text-transform: uppercase;
  letter-spacing: .05em; margin-left: auto; white-space: nowrap;
}
.palette .res .sub { color: var(--dim); font-size: 11.5px; }
.palette .hint { padding: 8px 16px; font-size: 11px; color: var(--dim); border-top: 1px solid var(--border); }

/* ── Alerts, toast ─────────────────────────────────────────────────── */

.alert {
  padding: 10px 14px; border-radius: var(--radius-sm);
  margin-bottom: 14px; font-size: 13px;
  border: 1px solid var(--border);
  background: var(--surface);
}
.alert.success { border-color: color-mix(in srgb, var(--good) 40%, transparent); color: var(--good); background: color-mix(in srgb, var(--good) 10%, transparent); }
.alert.error   { border-color: color-mix(in srgb, var(--bad) 40%, transparent);  color: var(--bad);  background: color-mix(in srgb, var(--bad) 10%, transparent); }
.alert.warn    { border-color: color-mix(in srgb, var(--warn) 40%, transparent); color: var(--warn); background: color-mix(in srgb, var(--warn) 10%, transparent); }

.toast {
  position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%) translateY(20px);
  background: var(--surface-3); border: 1px solid var(--border-2);
  color: var(--text); padding: 10px 16px; border-radius: var(--radius-sm);
  font-size: 13px; box-shadow: var(--shadow);
  opacity: 0; pointer-events: none; transition: all .22s var(--ease); z-index: 200;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── Filter bar, pagination ────────────────────────────────────────── */

.filters { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; padding: 11px 16px; border-bottom: 1px solid var(--border); }
.filters input, .filters select { width: auto; min-width: 130px; }
.filters .grow { flex: 1; min-width: 180px; }

.pager { display: flex; align-items: center; gap: 12px; padding: 11px 16px; border-top: 1px solid var(--border); font-size: 12.5px; color: var(--muted); }
.pager .spacer { flex: 1; }

/* ── Stat tiles ────────────────────────────────────────────────────── */

.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; margin-bottom: 16px; }
.stat {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 14px 16px;
}
.stat .n { font-family: var(--font-display); font-size: 24px; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat .l { color: var(--muted); font-size: 12px; margin-top: 2px; }
.stat .s { color: var(--dim); font-size: 11px; margin-top: 4px; }

/* ── Login ─────────────────────────────────────────────────────────── */

.login-wrap { min-height: 100vh; display: grid; place-items: center; padding: 20px; }
.login {
  width: min(380px, 100%);
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 26px; box-shadow: var(--shadow);
}
.login .brand { border: 0; padding: 0 0 18px; }

/* ── Access matrix ─────────────────────────────────────────────────── */

.matrix { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.matrix th, .matrix td { padding: 7px 9px; border: 1px solid var(--border); text-align: center; }
.matrix th:first-child, .matrix td:first-child { text-align: left; }
.matrix select { padding: 3px 6px; font-size: 12px; min-width: 84px; }
.matrix .area-help { color: var(--dim); font-size: 11px; font-weight: 400; display: block; }

/* ── Responsive ────────────────────────────────────────────────────── */

@media (max-width: 860px) {
  .sidebar { position: fixed; left: -100%; z-index: 60; transition: left .2s var(--ease); box-shadow: var(--shadow); }
  .sidebar.open { left: 0; }
  .fields { grid-template-columns: 1fr; }
  .content { padding: 14px; }
  .menu-btn { display: inline-flex !important; }
}
.menu-btn { display: none; }

@media print {
  .sidebar, .topbar, .form-actions, .filters, .pager { display: none !important; }
  .content { padding: 0; }
  .card { border: 1px solid #ccc; }
}

/* ── Wordmark ──────────────────────────────────────────────────────────
   Type, standing in for the supplied logo. Set tight and heavy to match the
   group mark; the sub-line is letter-spaced the way the logo sets "GROUP".
   Replace with the real asset when it lands — see templates/base.html. */

.brand { flex-direction: column; align-items: flex-start; gap: 4px; }
.wordmark { display: flex; flex-direction: column; line-height: 1; }
.wm-name {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: -0.02em;
  color: var(--accent);
}
.wm-sub {
  font-size: 8.5px;
  letter-spacing: .34em;
  color: var(--dim);
  margin-top: 3px;
  padding-left: 2px;
}
.env-badge {
  font-size: 9.5px;
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--dim);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
}
.login .brand { align-items: center; margin-bottom: 6px; }
