/* ============================================================================
   Conquer Freight — CN design system
   ----------------------------------------------------------------------------
   Ports the Conquer Nation Warehouse (Lime_Inbound) look to Conquer Freight:
   dark navy chrome (sidebar + header) wrapping LIGHT content on slate-50.

   WHY THIS IS A SEPARATE FILE, AND WHY EVERYTHING IS SCOPED TO .cf-app
   -------------------------------------------------------------------
   driver.html is deliberately OUT of scope — drivers keep the dark phone UI.
   Every component in cf-shared.css reads var(--cf-*) off :root, so flipping
   those tokens to light would silently re-theme the driver app too. Instead:

     • cf-shared.css :root is left byte-for-byte alone (driver keeps dark)
     • this file is only linked by office pages, so the driver downloads 0 bytes
     • the light palette is applied by RE-DECLARING the same --cf-* tokens on
       .cf-app, so existing .cf-btn/.cf-input/.cf-tile markup re-themes itself
       without any page having to rewrite its class names.

   Rule: never add a selector here that can match outside .cf-app.

   Values are lifted verbatim from the warehouse app (Tailwind v4, no config
   file — see frontend/src/index.css and components/ManagerSidebar.tsx there).
   ========================================================================== */

/* Form controls do not inherit font-family from an ancestor; everything else in
   the office app picks up Instrument Sans through --cf-font below. driver.html
   never loads this file and keeps the system stack it has always used. */
.cf-app input, .cf-app select, .cf-app textarea, .cf-app button {
  font-family: var(--sans);
}
.cf-app {
  /* ── DESIGN TOKENS ────────────────────────────────────────────────────────
     One accent, one ink scale, five status pairs. Everything else is derived.

     The old palette had six accent colours competing at once (cyan actions,
     navy headings, plus saturated green/amber/red for status AND for numbers),
     which is what made the app read as unpolished: nothing was emphasised
     because everything was. Now: ONE accent for action, near-black ink for all
     text and metrics, and the status colours used ONLY for status - never for
     decoration or for a number that is merely large.

     The --cn-* names below are kept because ~130 places still reference them.
     They are now aliases onto the new scale rather than a Tailwind slate ramp,
     so remapping here re-themes every component that goes through a token.
     Hardcoded literals in page <style> blocks are being migrated separately. */

  /* Surface & ink */
  --ink:        #101725;   /* all body text, headings, and every metric */
  --ink-2:      #6B7488;   /* secondary text, labels, helper copy */
  --ink-3:      #8C95A6;   /* placeholder, disabled, empty-cell em-dash, zeros */
  --canvas:     #F4F5F7;   /* page background */
  --card:       #FFFFFF;
  --hairline:   #E3E6EC;   /* dividers and card borders */
  --control-bd: #DDE1E8;   /* input and secondary-button borders */
  --chrome:     #0C1220;   /* sidebar + top bar */
  --chrome-2:   #141C2E;

  /* The one accent */
  --accent:       #2F5BD7;
  --accent-hover: #23459F;
  --accent-ring:  rgba(47, 91, 215, .30);   /* 2px focus ring, everywhere */
  --accent-soft:  #E4EAFA;                  /* tinted band: the row being edited */

  /* Status — background / foreground. Status only, never decoration. */
  --st-new-bg:       #E4EAFA;  --st-new-fg:       #1B4DA8;
  --st-motion-bg:    #FBF1E2;  --st-motion-fg:    #B08000;
  --st-done-bg:      #E8F1EC;  --st-done-fg:      #1B6B4A;
  --st-risk-bg:      #FCE9DD;  --st-risk-fg:      #A33208;
  --st-neutral-bg:   #F0F1F5;  --st-neutral-fg:   #6B7488;

  /* Geometry */
  /* Every identifier and quantity in a TMS is meant to be compared down a
     column — container numbers, counts, money, times. A proportional face makes
     that comparison harder than it needs to be, so one mono face carries all of
     them. System stack only: no webfont, no extra request. */
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --sans: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Arial, sans-serif;
  --r-control: 6px;
  --r-card:    10px;
  --r-badge:   999px;       /* status badges ONLY */
  --sp-1: 4px; --sp-2: 8px; --sp-3: 12px; --sp-4: 16px; --sp-6: 24px; --sp-8: 32px;
  --row-h:     44px;        /* table rows, single line */
  --ctl-h:     36px;        /* default control height */
  --ctl-h-sm:  32px;        /* toolbars and table rows */
  --content-max: 1440px;

  /* Elevation — exactly one shadow, for popovers and menus. Cards use borders. */
  --shadow-pop: 0 4px 16px rgba(10, 31, 51, .10);

  /* ── Legacy aliases ───────────────────────────────────────────────────────
     Kept so existing selectors keep working; each now points at the new scale. */
  --cn-cyan:        var(--accent);
  --cn-cyan-hover:  var(--accent-hover);
  --cn-navy:        var(--ink);        /* headings are ink now, not blue */
  --cn-navy-hover:  var(--ink);
  --cn-chrome:      var(--chrome);
  --cn-chrome-2:    var(--chrome-2);

  --cn-slate-50:  var(--canvas);
  --cn-slate-100: var(--st-neutral-bg);
  --cn-slate-200: var(--hairline);
  --cn-slate-300: var(--control-bd);
  --cn-slate-400: var(--ink-3);
  --cn-slate-500: var(--ink-2);
  --cn-slate-600: var(--ink-2);
  --cn-slate-700: var(--ink);
  --cn-slate-800: var(--ink);

  /* Cards no longer carry a shadow - they use a hairline border. */
  --cn-shadow-card: none;
  --cn-shadow-flat: none;
  --cn-shadow-cta:  none;
  --cn-shadow-cta-h:none;

  --cn-sidebar-w:   224px;   /* 16px back to the content */
  --cn-sidebar-w-c: 64px;
  --cn-header-h:    56px;   /* was 64px; the spec calls for a tighter top bar */

  /* ── Component tokens (read by every cf-* class in cf-shared.css) ───────── */
  --cf-bg:          var(--canvas);
  --cf-surface:     var(--card);
  --cf-surface-2:   var(--st-neutral-bg);
  --cf-text:        var(--ink);
  --cf-text-dim:    var(--ink-2);
  --cf-border:      var(--hairline);
  --cf-accent:      var(--accent);
  --cf-accent-hover:var(--accent-hover);
  --cf-radius:      var(--r-card);
  --cf-shadow:      none;

  /* cf-shared.css sets every component's font from --cf-font. Overriding the
     token here re-faces all of them at once, which is the same trick this file
     already uses for the light palette — and it is why a separate font-family
     rule did not take: this declaration sits in the same block and later. */
  --cf-font: var(--sans);

  background: var(--cn-slate-50);
  color: var(--cn-slate-800);
  font-family: var(--cf-font);
  -webkit-font-smoothing: antialiased;
  margin: 0;
  min-height: 100vh;
}

/* The shell is a flex row: sidebar rail | (header + scrolling content) */
.cf-app { display: flex; }

/* ══ SIDEBAR ══════════════════════════════════════════════════════════════ */
.cf-app .cn-side {
  background: var(--cn-chrome);
  color: #fff;
  border-right: 1px solid rgba(255,255,255,.05);
  width: var(--cn-sidebar-w);
  flex-shrink: 0;
  position: sticky; top: 0; align-self: flex-start;
  height: 100vh;
  display: flex; flex-direction: column;
  transition: width .2s ease-out;
  z-index: 40;
}
.cf-app.cn-collapsed .cn-side { width: var(--cn-sidebar-w-c); }

.cf-app .cn-side-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 0 14px;
  border-bottom: 1px solid rgba(255,255,255,.06);
  height: var(--cn-header-h);      /* exactly matches the top bar, so the two
                                      align across the chrome seam */
  min-height: var(--cn-header-h);
}
.cf-app .cn-side-brand img { height: 24px; width: auto; flex-shrink: 0; opacity: .95; }
.cf-app .cn-side-brand .cn-brand-text { min-width: 0; }
.cf-app .cn-side-brand .cn-brand-name {
  font-size: 13.5px; font-weight: 600; letter-spacing: .01em;
  color: #fff;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  line-height: 1.25;
}
.cf-app .cn-side-brand .cn-brand-sub {
  font-family: var(--mono);
  font-size: 10px; text-transform: uppercase; letter-spacing: .14em;
  color: rgba(255,255,255,.40); white-space: nowrap; line-height: 1.3;
}
.cf-app .cn-side-brand .cn-side-toggle { margin-left: auto; }
.cf-app.cn-collapsed .cn-side-brand .cn-side-toggle { margin-left: 0; }
.cf-app.cn-collapsed .cn-side-brand .cn-brand-text { display: none; }

/* The rail is grouped now, so each group carries its own caps label and the
   old single "MODULES" row has nothing left to say. The collapse button it used
   to hold moved up into the brand block. */
.cf-app .cn-nav-group { margin-bottom: 14px; }
.cf-app .cn-nav-glabel {
  font-size: 10px; font-weight: 600; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255,255,255,.34); padding: 8px 10px 6px; white-space: nowrap;
}
/* Collapsed, a caps label has no room; a hairline keeps the grouping legible. */
.cf-app.cn-collapsed .cn-nav-glabel {
  color: transparent; padding: 6px 0 5px; margin: 0 12px;
  border-top: 1px solid rgba(255,255,255,.10); font-size: 0; line-height: 0;
}
.cf-app.cn-collapsed .cn-nav-group:first-child .cn-nav-glabel { border-top: none; }

.cf-app .cn-side-toggle {
  background: none; border: none; color: rgba(255,255,255,.45);
  cursor: pointer; padding: 4px; border-radius: 6px; line-height: 0;
  font-family: inherit;
}
.cf-app .cn-side-toggle:hover { background: rgba(255,255,255,.08); color: #fff; }

.cf-app .cn-side-nav { flex: 1; overflow-y: auto; padding: 0 8px 12px; }
.cf-app .cn-side-nav::-webkit-scrollbar { width: 6px; }
.cf-app .cn-side-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 3px; }

.cf-app .cn-nav-item {
  position: relative;
  display: flex; align-items: center; gap: 11px;
  padding: 0 10px; margin: 1px 0; height: 36px;
  border-radius: var(--sp-2);
  /* Was rgba(255,255,255,.68), which against the navy chrome reads as
     blue-grey rather than white and made the whole rail look like one flat
     colour. Near-white text is the single biggest change here. */
  color: rgba(255,255,255,.86);
  font-size: 13.5px; font-weight: 500;
  text-decoration: none;
  white-space: nowrap; overflow: hidden;
  transition: background .12s, color .12s, padding-left .12s;
}
/* Hover brightens the label, brings the icon to full strength and nudges the
   row 2px right - small, but it makes the rail feel like it responds. */
.cf-app .cn-nav-item:hover {
  background: rgba(255,255,255,.07); color: #fff; text-decoration: none;
  padding-left: 12px;
}
.cf-app .cn-nav-item:hover svg { opacity: 1; }
.cf-app .cn-nav-item svg { width: 16px; height: 16px; flex-shrink: 0; opacity: .62; transition: opacity .12s; }
.cf-app .cn-nav-item .cn-nav-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Mono, because these are quantities and they should line up down the rail
   rather than jitter with the label above. Empty when the count is zero: an
   empty queue should read as quiet, not as a "0" asking to be looked at. */
.cf-app .cn-nav-count {
  font-family: var(--mono); font-size: 11px; font-weight: 500;
  color: rgba(255,255,255,.42); flex: none; font-variant-numeric: tabular-nums;
}
.cf-app .cn-nav-item.active .cn-nav-count { color: rgba(255,255,255,.78); }
.cf-app.cn-collapsed .cn-nav-count { display: none; }
/* Active: a neutral raised panel plus the accent bar. An accent-tinted
   background was tried first and made the rail MORE monochrome-blue, not less -
   the accent should appear once, as the 2px bar, not as a wash behind white
   text. */
.cf-app .cn-nav-item.active {
  background: rgba(255,255,255,.13); color: #fff; font-weight: 600;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.06);
}
.cf-app .cn-nav-item.active svg { opacity: 1; }
.cf-app .cn-nav-item.active:hover { background: rgba(255,255,255,.16); padding-left: 10px; }
/* 2px accent bar on the active row, flush to the sidebar edge. */
.cf-app .cn-nav-item.active::before {
  content: ''; position: absolute; left: -8px; top: 50%;
  transform: translateY(-50%);
  width: 2px; height: 22px; background: var(--accent);
  border-radius: 0 2px 2px 0;
}
/* The rail used to be a flat list with a hairline dropped on the 7th row to
   fake a division. Real groups replaced it, and nth-child(7) now lands on an
   arbitrary row, so it is gone. */
/* Give the rail a touch of depth so it does not read as one flat field. */
.cf-app .cn-side { box-shadow: inset -1px 0 0 rgba(255,255,255,.06); }
.cf-app.cn-collapsed .cn-nav-item { justify-content: center; padding: 9px 0; }
.cf-app.cn-collapsed .cn-nav-item .cn-nav-text { display: none; }

/* Identity moved out of the header and down here. It is looked at almost never
   and was occupying the most valuable strip on the screen. */
.cf-app .cn-side-user {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-top: 1px solid rgba(255,255,255,.08);
  flex-shrink: 0;
}
.cf-app .cn-side-user .cn-avatar {
  width: 28px; height: 28px; font-size: 12px; font-weight: 600;
  background: rgba(255,255,255,.10); color: #E7EBF2; flex: none;
}
.cf-app .cn-side-who { flex: 1; min-width: 0; }
.cf-app .cn-side-name {
  font-size: 12.5px; font-weight: 600; color: #E7EBF2; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cf-app .cn-side-role {
  font-family: var(--mono); font-size: 10px; letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.38); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cf-app .cn-side-out {
  background: none; border: none; font-family: inherit; cursor: pointer;
  font-size: 11.5px; font-weight: 500; color: rgba(255,255,255,.50);
  padding: 4px 6px; border-radius: 5px; flex: none;
}
.cf-app .cn-side-out:hover { color: #fff; background: rgba(255,255,255,.10); }
.cf-app.cn-collapsed .cn-side-who,
.cf-app.cn-collapsed .cn-side-out { display: none; }
.cf-app.cn-collapsed .cn-side-user { justify-content: center; padding: 12px 0; }

.cf-app .cn-side-foot {
  /* Said "Dispatch" on every page regardless of section - decoration, not
     information. Hidden rather than removed from cf-shell.js. */
  display: none;
  padding: 10px 14px; border-top: 1px solid rgba(255,255,255,.06);
  font-size: 10px; text-transform: uppercase; letter-spacing: .16em;
  color: rgba(255,255,255,.30); white-space: nowrap; overflow: hidden;
}

/* ══ MAIN COLUMN + HEADER ═════════════════════════════════════════════════ */
.cf-app .cn-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }

/* The header went light. Dark navy top + dark navy rail meant the two pieces of
   chrome competed and the page proper began a long way down; a quiet light bar
   lets the rail be the only dark thing and hands the width back to the work.
   The page title moved into a breadcrumb, since a heading already sits on every
   page and having it twice was redundancy, not orientation. */
.cf-app .cn-header {
  position: sticky; top: 0; z-index: 30;
  height: var(--cn-header-h); flex-shrink: 0;
  background: rgba(247, 248, 249, .88);
  -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--hairline);
  color: var(--ink);
  display: flex; align-items: center; gap: 14px;
  padding: 0 22px;
}
.cf-app .cn-crumbs { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.cf-app .cn-crumb {
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--ink-3); white-space: nowrap;
}
.cf-app .cn-crumb-sep { color: var(--control-bd); font-size: 12px; }
.cf-app .cn-crumb-page {
  font-size: 13px; font-weight: 600; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.cf-app .cn-header-spacer { flex: 1; }
.cf-app .cn-header-rule { width: 1px; height: 20px; background: var(--hairline); flex: none; }

.cf-app .cn-search-btn {
  display: flex; align-items: center; gap: 10px;
  height: 32px; padding: 0 10px 0 12px; width: 268px; max-width: 34vw;
  border: 1px solid var(--control-bd); border-radius: 8px; background: var(--card);
  color: var(--ink-3); font: inherit; font-size: 12.5px; cursor: pointer;
  transition: border-color .12s, color .12s;
}
.cf-app .cn-search-btn:hover { border-color: var(--ink-3); color: var(--ink-2); }
.cf-app .cn-search-btn span { flex: 1; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cf-app .cn-kbd {
  font-family: var(--mono); font-size: 10.5px; color: var(--ink-3);
  border: 1px solid var(--hairline); border-radius: 4px; padding: 3px 5px; flex: none;
}
.cf-app .cn-header-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }

/* The burger only exists on the mobile drawer breakpoint. */
.cf-app .cn-burger { color: var(--ink-2); border: none; background: none; }

/* Alerts. cf-overlay owns the bell and its counting; this is only its shape
   inside the shell header. The count keeps the inline display cf-overlay sets,
   so an empty queue shows no badge at all. */
.cf-app .cn-alerts-pill {
  position: relative; display: flex; align-items: center; gap: 7px;
  height: 32px; padding: 0 11px; border-radius: 8px; cursor: pointer;
  font-size: 12.5px; font-weight: 500; color: var(--ink-2);
  transition: background .12s, color .12s;
}
.cf-app .cn-alerts-pill:hover { background: var(--st-neutral-bg); color: var(--ink); }
.cf-app .cn-alerts-pill svg { width: 15px; height: 15px; }
.cf-app .cn-alerts-word { white-space: nowrap; }
.cf-app .cn-alerts-n {
  display: none; align-items: center; justify-content: center;
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  color: var(--st-risk-fg); background: var(--st-risk-bg);
  border-radius: 20px; padding: 3px 7px; line-height: 1;
}
@media (max-width: 700px) { .cf-app .cn-alerts-word { display: none; } }

/* ══ ⌘K ═══════════════════════════════════════════════════════════════════ */
.cf-app .cn-pal-scrim {
  position: fixed; inset: 0; z-index: 200; background: rgba(10, 31, 51, .34);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  display: flex; align-items: flex-start; justify-content: center;
  padding: 12vh 16px 16px;
}
.cf-app .cn-pal {
  width: 100%; max-width: 560px; background: var(--card);
  border: 1px solid var(--hairline); border-radius: 12px;
  box-shadow: 0 24px 64px rgba(10, 31, 51, .28); overflow: hidden;
}
.cf-app .cn-pal-input {
  width: 100%; border: none; outline: none; background: none;
  padding: 16px 18px; font: inherit; font-size: 15px; color: var(--ink);
  border-bottom: 1px solid var(--hairline);
}
.cf-app .cn-pal-results { max-height: 52vh; overflow-y: auto; }
.cf-app .cn-pal-hint { padding: 22px 18px; color: var(--ink-3); font-size: 13px; }
.cf-app .cn-pal-group {
  font-size: 10px; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  color: var(--ink-3); padding: 12px 18px 5px;
}
.cf-app .cn-pal-row {
  display: flex; align-items: baseline; gap: 10px; padding: 8px 18px;
  text-decoration: none; color: var(--ink); font-size: 13.5px;
}
.cf-app .cn-pal-row:hover { background: var(--accent-soft); text-decoration: none; color: var(--ink); }
.cf-app .cn-pal-mono { font-family: var(--mono); font-size: 12.5px; font-weight: 600; }
.cf-app .cn-pal-sub {
  color: var(--ink-3); font-size: 12px; margin-left: auto; text-align: right;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 55%;
}

.cf-app .cn-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  background: rgba(255,255,255,.10);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.20);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 700; color: #fff;
}
.cf-app .cn-chip {
  display: inline-flex; align-items: center; gap: 7px;
  border-radius: 999px;
  background: rgba(255,255,255,.08);
  border: 1px solid rgba(255,255,255,.15);
  padding: 6px 14px;
  font-size: 13px; font-weight: 500; color: #fff;
  cursor: pointer; font-family: inherit; text-decoration: none;
  transition: background .12s, border-color .12s;
}
.cf-app .cn-chip:hover { background: rgba(255,255,255,.15); border-color: rgba(255,255,255,.30); text-decoration: none; color: #fff; }
.cf-app .cn-user-name { font-size: 13px; color: rgba(255,255,255,.75); }

/* Content well — 1700px cap matches the warehouse app */
.cf-app .cn-body { flex: 1; overflow-y: auto; }
.cf-app .cn-wrap { max-width: 1700px; margin: 0 auto; padding: 24px 20px 40px; width: 100%; }

/* ══ PAGE HEADER ═════════════════════════════════════════════════════════════
   The old header cost roughly a third of the viewport: a pill repeating what
   the top bar already says, a 28px blue title, and a subtitle - three stacked
   blocks before any data. Now one row: 22px ink title with the description
   beside it. The eyebrow pill is gone rather than restyled; the top bar is the
   only place a section needs naming. Hidden rather than deleted from 13 pages,
   so no page markup has to change. */
.cf-app .cn-eyebrow { display: none; }

.cf-app h1.cn-title {
  display: block;
  margin: 0 0 6px; font-size: 27px; font-weight: 600;
  letter-spacing: -.02em; color: var(--ink);
}
.cf-app .cn-sub {
  display: block; margin: 0;
  color: var(--ink-2); font-size: 13.5px; font-weight: 400;
}
/* Figures inside a page subtitle are read, not skimmed past — the reference sets
   them in mono so "12 drivers, 31 moves, $4,125" scans as three quantities. */
.cf-app .cn-sub b, .cf-app .cn-sub .num { font-family: var(--mono); font-weight: 500; color: var(--ink-2); }
/* The two inline elements above need a block to sit in and a gap after them.
   :has() lets us space the row without touching page markup. */
.cf-app .cn-sub::after { content: ''; display: block; height: var(--sp-5); }

/* ══ CARDS / PANELS ═══════════════════════════════════════════════════════ */
.cf-app .cn-card {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: none;          /* cards use a border, never a shadow */
  padding: 20px;
}
.cf-app .cn-panel {
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 12px;
  box-shadow: none;
  overflow: hidden;
  margin-bottom: 16px;
}
/* A section header is a line of writing, not a title bar. The tinted strip with
   11px uppercase letters tracked out to .18em was louder than most of the
   content under it, and stacked three or four to a screen it read as chrome
   rather than as headings. A plain sentence-case heading with its explanation
   beside it, on the same white as the panel, gets out of the way. */
.cf-app .cn-panel-head {
  background: transparent;
  border-bottom: none;
  padding: 15px 18px 0;
  display: flex; align-items: baseline; gap: 12px;
}
.cf-app .cn-panel-head h2, .cf-app .cn-panel-head h3 {
  margin: 0; font-size: 14px; font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--ink);
}
.cf-app .cn-panel-head .panel-sub {
  font-size: 12px; color: var(--ink-3); text-transform: none; letter-spacing: 0;
}
.cf-app .cn-panel-body { padding: 16px 18px 18px; }

/* KPI tile */
.cf-app .cn-kpi { background:#fff; border:1px solid var(--cn-slate-200); border-radius:12px;
  box-shadow: var(--cn-shadow-card); padding: 14px 16px; }
.cf-app .cn-kpi-label { font-size: 10.5px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .16em; color: var(--cn-slate-500); }
.cf-app .cn-kpi-value { font-size: 28px; font-weight: 700; color: var(--cn-navy); line-height: 1.15; margin-top: 4px; }
.cf-app .cn-kpi-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin-bottom: 18px; }

/* ══ TABLES ═══════════════════════════════════════════════════════════════ */
/* No zebra striping — the warehouse app uses hairlines only. */
/* ══ TABLES ══════════════════════════════════════════════════════════════════
   Rows were wrapping to three lines (a route like "Long Beach -> Los Angeles"
   would break), numbers were proportional so columns did not line up, and
   headers wrapped too. Fixed rows, tabular figures and ellipsis instead of
   wrapping make a table scannable by eye down a column. */
.cf-app .cn-table-wrap { overflow-x: auto; }
.cf-app table.cn-table {
  width: 100%; border-collapse: collapse;
  font-size: 14px; background: var(--card);
  /* Every number, date and count aligns by digit. */
  font-variant-numeric: tabular-nums;
}
.cf-app table.cn-table thead th {
  position: sticky; top: 0; z-index: 2;
  box-sizing: border-box;      /* header survives a long scroll */
  background: var(--canvas);
  border-bottom: 1px solid var(--hairline);
  padding: 0 14px; height: var(--ctl-h-sm); text-align: left;
  font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .08em;
  color: var(--ink-2);
  white-space: nowrap;                        /* "CREATED BY" stays on one line */
}
.cf-app table.cn-table tbody td {
  box-sizing: border-box;
  height: var(--row-h);                       /* 44px, single line */
  padding: 0 14px;
  border-top: 1px solid var(--hairline);
  color: var(--ink);
  vertical-align: middle;
  white-space: nowrap;                        /* ellipsis, never a 3-line row */
  overflow: hidden; text-overflow: ellipsis;
  max-width: 340px;
}
/* No zebra striping: the hairline is the separator. Hover is a quiet neutral,
   not a blue wash. */
.cf-app table.cn-table tbody tr:hover td { background: var(--canvas); }

.cf-app table.cn-table td.num, .cf-app table.cn-table th.num {
  text-align: right; font-variant-numeric: tabular-nums;
  font-family: inherit;    /* numbers are not code; only IDs get the mono face */
}
/* Mono is reserved for identifiers - container, control and licence numbers. */
.cf-app table.cn-table td.mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 500; font-size: 13px; letter-spacing: -.01em;
}
.cf-app table.cn-table a { color: var(--ink); font-weight: 500; }
.cf-app table.cn-table a:hover { color: var(--accent); text-decoration: underline; }

/* Row actions: one visible, the rest behind a hover menu, so a row is not a
   wall of buttons. Revealed on hover and on keyboard focus within the row. */
.cf-app table.cn-table .row-acts { opacity: 0; transition: opacity .1s; }
.cf-app table.cn-table tbody tr:hover .row-acts,
.cf-app table.cn-table tbody tr:focus-within .row-acts { opacity: 1; }

/* An empty cell is an em-dash in ink-3, not in full ink. */
.cf-app .cn-null { color: var(--ink-3); }

/* ══ PILLS / BADGES ═══════════════════════════════════════════════════════ */
.cf-app .cn-pill {
  display: inline-block; padding: 2px 9px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .12em;
  background: var(--cn-slate-100); color: var(--cn-slate-700);
  white-space: nowrap;
}
.cf-app .cn-pill-ok      { background:#d1fae5; color:#065f46; }
.cf-app .cn-pill-warn    { background:#fef3c7; color:#92400e; }
.cf-app .cn-pill-danger  { background:#fee2e2; color:#991b1b; }
.cf-app .cn-pill-info    { background: rgba(0,147,208,.15); color: var(--cn-navy); }
.cf-app .cn-pill-indigo  { background:#e0e7ff; color:#3730a3; }
.cf-app .cn-pill-violet  { background:#ede9fe; color:#5b21b6; }
.cf-app .cn-pill-teal    { background:#ccfbf1; color:#115e59; }

/* ══ BUTTONS ══════════════════════════════════════════════════════════════
   The legacy .cf-btn is re-themed by the token swap above; these are the
   CN-native shapes (pill CTA with the cyan glow).                          */
.cf-app .cn-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  background: var(--cn-cyan); color: #fff;
  border: none; border-radius: 999px;
  padding: 9px 22px;
  font-family: inherit; font-size: 14px; font-weight: 600;
  cursor: pointer; text-decoration: none;
  box-shadow: var(--cn-shadow-cta);
  transition: background .15s, box-shadow .15s;
}
.cf-app .cn-btn:hover { background: var(--cn-cyan-hover); box-shadow: var(--cn-shadow-cta-h); text-decoration: none; color:#fff; }
.cf-app .cn-btn:disabled { opacity: .5; cursor: not-allowed; box-shadow: none; }
.cf-app .cn-btn-sm { padding: 6px 16px; font-size: 13px; }

.cf-app .cn-btn-navy { background: var(--cn-navy); box-shadow: 0 8px 24px -4px rgba(27,70,118,.45); }
.cf-app .cn-btn-navy:hover { background: var(--cn-navy-hover); }

.cf-app .cn-btn-outline {
  background: #fff; color: var(--cn-slate-700);
  border: 1px solid var(--cn-slate-300); border-radius: 6px;
  padding: 7px 13px; font-size: 14px; font-weight: 500;
  box-shadow: none;
}
.cf-app .cn-btn-outline:hover { background: var(--cn-slate-50); color: var(--cn-navy); box-shadow: none; }

.cf-app .cn-btn-danger { background:#dc2626; border-radius:6px; box-shadow:none; padding:7px 13px; font-weight:700; }
.cf-app .cn-btn-danger:hover { background:#b91c1c; box-shadow:none; }

/* Icon-only ghost button */
.cf-app .cn-icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 6px;
  background: none; border: 1px solid transparent; color: var(--cn-slate-400);
  cursor: pointer; font-family: inherit;
}
.cf-app .cn-icon-btn:hover { background: var(--cn-slate-100); color: var(--cn-navy); }
.cf-app .cn-icon-btn.danger:hover { background:#fef2f2; color:#dc2626; border-color:#fecaca; }

/* ══ FORMS ════════════════════════════════════════════════════════════════ */
.cf-app .cn-label {
  display: block; margin-bottom: 5px;
  font-size: 10.5px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .16em; color: var(--cn-slate-500);
}
.cf-app .cn-input, .cf-app .cn-select, .cf-app .cn-textarea {
  width: 100%;
  background: #fff; color: var(--cn-slate-800);
  border: 1px solid var(--cn-slate-300); border-radius: 6px;
  padding: 8px 11px;
  font-family: inherit; font-size: 14px;
  transition: border-color .15s, box-shadow .15s;
}
.cf-app .cn-input:focus, .cf-app .cn-select:focus, .cf-app .cn-textarea:focus {
  outline: none; border-color: var(--cn-cyan);
  box-shadow: 0 0 0 3px rgba(0,147,208,.20);
}
.cf-app .cn-input::placeholder { color: var(--cn-slate-400); }

/* Filter/toolbar row above a table */
.cf-app .cn-filters {
  background: #fff; border: 1px solid var(--cn-slate-200); border-radius: 12px;
  box-shadow: 0 1px 2px 0 rgba(15,23,42,.04), 0 4px 12px -6px rgba(15,23,42,.08);
  padding: 12px 14px; margin-bottom: 16px;
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
}
.cf-app .cn-filters .spacer { flex: 1; }

/* ══ ALERTS / TOASTS ══════════════════════════════════════════════════════ */
.cf-app .cn-alert { border-radius: 6px; padding: 10px 13px; font-size: 14px; margin-bottom: 14px; border: 1px solid; }
.cf-app .cn-alert-error   { background:#fef2f2; border-color:#fecaca; color:#b91c1c; }
.cf-app .cn-alert-success { background:#ecfdf5; border-color:#a7f3d0; color:#065f46; }
.cf-app .cn-alert-info    { background: rgba(0,147,208,.05); border-color: rgba(0,147,208,.25); color: var(--cn-navy); }
.cf-app .cn-alert-warn    { background:#fffbeb; border-color:#fcd34d; color:#92400e; }

/* Re-theme the legacy .cf-alert for light backgrounds (it was built for dark) */
.cf-app .cf-alert { border-left-width: 4px; border-left-style: solid; }
.cf-app .cf-alert-error   { background:#fef2f2; color:#b91c1c; border-color:#dc2626; }
.cf-app .cf-alert-success { background:#ecfdf5; color:#065f46; border-color:#059669; }
.cf-app .cf-alert-info    { background: rgba(0,147,208,.08); color: var(--cn-navy); border-color: var(--cn-cyan); }
.cf-app .cf-alert-warn    { background:#fffbeb; color:#92400e; border-color:#f59e0b; }

/* ══ MODALS ═══════════════════════════════════════════════════════════════ */
.cf-app .cn-modal-bg, .cn-modal-bg {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(15,23,42,.60); backdrop-filter: blur(4px);
}
.cn-modal {
  background: #fff; color: var(--cn-slate-800, #1e293b);
  border-radius: 12px; box-shadow: 0 25px 50px -12px rgba(0,0,0,.25);
  width: 100%; max-width: 520px; max-height: 90vh; overflow-y: auto;
  padding: 22px;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.cn-modal h3 { margin: 0 0 8px; font-size: 18px; font-weight: 700; color: #1B4676; }

/* ══ TABS ═════════════════════════════════════════════════════════════════ */
.cf-app .cn-tabs { display: flex; align-items: center; gap: 6px; border-bottom: 1px solid var(--cn-slate-200); margin-bottom: 16px; }
.cf-app .cn-tab {
  background: none; border: none; border-bottom: 2px solid transparent;
  padding: 9px 15px; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 600;
  color: var(--cn-slate-600);
}
.cf-app .cn-tab:hover { color: var(--cn-navy); }
.cf-app .cn-tab.active { border-bottom-color: var(--cn-cyan); color: var(--cn-navy); }

/* ══ TOASTS + CONFIRM ═════════════════════════════════════════════════════
   Created by cf-shell.js (cfToast / cfConfirm). These are NOT scoped to
   .cf-app because both attach to document.body, which is where .cf-app itself
   lives — scoping them under it would still match, but keeping them free of it
   means a page can use them before the shell has finished building.          */
.cf-toasts {
  position: fixed; right: 20px; bottom: 20px; z-index: 2000;
  display: flex; flex-direction: column; gap: 8px;
  max-width: min(380px, calc(100vw - 40px));
  pointer-events: none;
}
/* SCOPED to .cf-toasts on purpose. cf-overlay.js runs its OWN alert stack whose
   cards also carry .cf-toast, inside a container with id="cf-toasts" rather than
   this class. An unscoped `.cf-toast { opacity: 0 }` therefore reached into that
   stack and held every alert card invisible — the cards were all present and
   correct, at zero opacity, waiting for an .in class that only cfToast() adds.
   Two toast systems shared one class name; only this one gets these rules. */
.cf-toasts .cf-toast {
  pointer-events: auto; cursor: pointer;
  background: #fff; color: #1e293b;
  border: 1px solid #e2e8f0; border-left: 4px solid #64748b;
  border-radius: 8px; padding: 11px 14px;
  font-size: 14px; line-height: 1.4;
  /* Several converted messages are multi-line summaries (e.g. the bulk-delete
     cascade list). textContent preserves the \n, so honour it rather than
     collapsing the bullets onto one wrapped line. */
  white-space: pre-line;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  box-shadow: 0 8px 24px -6px rgba(15,23,42,.22), 0 1px 2px rgba(15,23,42,.06);
  opacity: 0; transform: translateY(8px);
  transition: opacity .18s ease-out, transform .18s ease-out;
}
.cf-toasts .cf-toast.in { opacity: 1; transform: translateY(0); }
.cf-toasts .cf-toast-success { border-left-color: #059669; }
.cf-toasts .cf-toast-error   { border-left-color: #dc2626; }
.cf-toasts .cf-toast-warn    { border-left-color: #f59e0b; }
.cf-toasts .cf-toast-info    { border-left-color: #0093D0; }

.cf-confirm-bg {
  position: fixed; inset: 0; z-index: 2100;
  background: rgba(15,23,42,.6); backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center; padding: 20px;
}
.cf-confirm {
  background: #fff; border-radius: 12px; padding: 22px;
  width: 100%; max-width: 420px;
  box-shadow: 0 25px 50px -12px rgba(0,0,0,.25);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
}
.cf-confirm h3 { margin: 0 0 8px; font-size: 17px; font-weight: 700; color: #1B4676; }
.cf-confirm p  { margin: 0 0 18px; font-size: 14px; color: #475569; line-height: 1.5; white-space: pre-line; }
.cf-confirm-actions { display: flex; gap: 8px; justify-content: flex-end; }
.cf-confirm-input {
  width: 100%; box-sizing: border-box; margin: -6px 0 18px;
  border: 1px solid #cbd5e1; border-radius: 6px; padding: 9px 11px;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 14px; color: #1e293b; background: #fff;
}
.cf-confirm-input:focus { outline: none; border-color: #0093D0; box-shadow: 0 0 0 3px rgba(0,147,208,.2); }
.cf-confirm-actions .cn-btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }

/* ══ MISC ═════════════════════════════════════════════════════════════════ */
.cf-app .cn-empty { text-align: center; color: var(--cn-slate-500); padding: 48px 16px; font-size: 14px; }
/* cf-shared.css sets `a { color: var(--cf-accent) }` for the driver app. In the
   office shell that turned every link accent-blue, including the sidebar, which
   is why the rail read as one flat colour. Body links are ink; only the ones
   that should look like links get the accent. */
.cf-app a { color: var(--ink); }
/* No `.cn-side a` rule here on purpose: at (0,2,1) it outranks
   `.cf-app .cn-nav-item` (0,2,0) and would override the nav's own colour. */
.cf-app a:hover { color: var(--accent); }
.cf-app h2, .cf-app h3 { color: var(--cn-navy); letter-spacing: -.01em; }

/* ══ RESPONSIVE ═══════════════════════════════════════════════════════════
   Under 1024px the rail becomes an overlay drawer instead of eating width. */
@media (max-width: 1024px) {
  .cf-app .cn-side {
    position: fixed; left: 0; top: 0; bottom: 0;
    transform: translateX(-100%);
    transition: transform .2s ease-out;
    box-shadow: 0 0 40px rgba(0,0,0,.4);
  }
  .cf-app.cn-drawer-open .cn-side { transform: translateX(0); }
  .cf-app.cn-collapsed .cn-side { width: var(--cn-sidebar-w); }
  .cf-app .cn-scrim {
    position: fixed; inset: 0; background: rgba(15,23,42,.5); z-index: 35;
  }
  .cf-app .cn-wrap { padding: 18px 14px 32px; }
  .cf-app h1.cn-title { font-size: 22px; }
}
@media (min-width: 1025px) {
  .cf-app .cn-burger { display: none; }
  .cf-app .cn-scrim  { display: none; }
}


/* ══ FOCUS ═══════════════════════════════════════════════════════════════════
   One visible focus treatment on every interactive element: a 2px accent ring
   at 35% opacity. Keyboard users previously got the browser default, which the
   dark chrome swallowed entirely. :focus-visible so a mouse click does not
   leave a ring behind. */
.cf-app a:focus-visible,
.cf-app button:focus-visible,
.cf-app input:focus-visible,
.cf-app select:focus-visible,
.cf-app textarea:focus-visible,
.cf-app [tabindex]:focus-visible {
  outline: 2px solid var(--accent-ring);
  outline-offset: 2px;
  border-radius: var(--r-control);
}
/* Inside the dark sidebar the accent ring is too low-contrast; brighten it. */
.cf-app .cn-side a:focus-visible,
.cf-app .cn-side button:focus-visible {
  outline-color: rgba(255,255,255,.55);
}

/* ══ BUTTONS ═════════════════════════════════════════════════════════════════
   One filled primary per view; everything else recedes. Heights are fixed so a
   toolbar reads as one row rather than a ragged line of differently sized pills.
   Destructive is never filled and never large - see .btn-danger-bulk on the
   shipments page for the pattern. */
.cf-app .cn-btn,
.cf-app .cn-btn-outline,
.cf-app .cn-btn-danger {
  height: var(--ctl-h); padding: 0 16px;
  border-radius: var(--r-control);
  font-size: 13px; font-weight: 500;
  box-shadow: none;                    /* no CTA glow on any button */
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
}
.cf-app .cn-btn-sm { height: var(--ctl-h-sm); padding: 0 12px; font-size: 13px; }
.cf-app .cn-btn:hover { box-shadow: none; }

/* Secondary: white with a hairline, not a tinted fill. */
.cf-app .cn-btn-outline {
  background: var(--card); color: var(--ink);
  border: 1px solid var(--control-bd);
}
.cf-app .cn-btn-outline:hover { background: var(--canvas); color: var(--ink); }

/* Destructive: quiet danger text, and it never out-shouts the primary. */
.cf-app .cn-btn-danger {
  background: none; border: none; color: var(--st-risk-fg); padding: 0 12px;
}
.cf-app .cn-btn-danger:hover { background: var(--st-risk-bg); }

/* Inputs and selects match button geometry so toolbars line up. */
.cf-app input[type=text], .cf-app input[type=search], .cf-app input[type=date],
.cf-app input[type=number], .cf-app select, .cf-app textarea {
  border-radius: var(--r-control);
  border: 1px solid var(--control-bd);
  font-size: 13px; color: var(--ink); background: var(--card);
}
.cf-app input[type=text], .cf-app input[type=search], .cf-app input[type=date],
.cf-app input[type=number], .cf-app select { height: var(--ctl-h); }
.cf-app ::placeholder { color: var(--ink-3); }

/* ══ ROW ACTIONS ═════════════════════════════════════════════════════════════
   One visible action, the rest in a menu that appears on hover or keyboard
   focus. The old column stacked three buttons and was 238px wide, which pushed
   the DRIVER and STATUS columns off the right edge - so the action column was
   costing more information than it provided. */
.cf-app table.cn-table td:last-child {
  text-align: right; white-space: nowrap; overflow: visible;
  position: sticky; right: 0; background: var(--card);
}
.cf-app table.cn-table tbody tr:hover td:last-child { background: var(--canvas); }
.cf-app table.cn-table th:last-child { position: sticky; right: 0; background: var(--canvas); }

.cf-app .row-primary {
  height: 28px; padding: 0 12px;
  border: 1px solid var(--control-bd); background: var(--card);
  border-radius: var(--r-control);
  font: 500 12.5px/1 inherit; color: var(--ink);
  cursor: pointer;
}
.cf-app .row-primary:hover { background: var(--canvas); border-color: var(--ink-3); }

.cf-app .row-acts { position: relative; display: inline-block; margin-left: var(--sp-1); }
.cf-app .row-more {
  width: 28px; height: 28px; line-height: 1;
  border: 1px solid transparent; background: none; color: var(--ink-2);
  border-radius: var(--r-control); cursor: pointer; font-size: 15px;
}
.cf-app .row-more:hover { background: var(--st-neutral-bg); color: var(--ink); }

.cf-app .row-menu {
  display: none; position: absolute; right: 0; top: calc(100% + 4px);
  min-width: 190px; padding: var(--sp-1);
  background: var(--card); border: 1px solid var(--hairline);
  border-radius: var(--r-card);
  box-shadow: var(--shadow-pop);          /* the one shadow in the system */
  z-index: 30; text-align: left;
}
.cf-app .row-acts:hover .row-menu,
.cf-app .row-acts:focus-within .row-menu { display: block; }
.cf-app .row-menu button {
  display: block; width: 100%; text-align: left;
  height: var(--ctl-h-sm); padding: 0 10px;
  border: none; background: none; cursor: pointer;
  font: 400 13px/1 inherit; color: var(--ink);
  border-radius: var(--r-control);
}
.cf-app .row-menu button:hover { background: var(--canvas); }
.cf-app .row-menu button.danger { color: var(--st-risk-fg); }
.cf-app .row-menu button.danger:hover { background: var(--st-risk-bg); }

/* ══ SIDEBAR TEXT COLOUR ═════════════════════════════════════════════════════
   The nav labels rendered accent-blue against the navy chrome, which is what
   made the whole rail read as one flat colour. The label is a <span> inside the
   <a>, so it was inheriting the anchor's colour - and the anchor's colour was
   losing a cascade fight that was not worth bisecting further (getComputedStyle
   reports a fixed value for link colours to prevent :visited history sniffing,
   so it could not be measured reliably either).

   Colouring the span directly sidesteps inheritance entirely and is honest
   about what it is doing: these labels are chrome text, not links. */
.cf-app .cn-side .cn-nav-item .cn-nav-text { color: rgba(255,255,255,.88); }
.cf-app .cn-side .cn-nav-item:hover .cn-nav-text { color: #fff; }
.cf-app .cn-side .cn-nav-item.active .cn-nav-text { color: #fff; }

/* Icons are inline SVG using currentColor, so they need the same treatment. */
.cf-app .cn-side .cn-nav-item svg { color: rgba(255,255,255,.75); }
.cf-app .cn-side .cn-nav-item:hover svg,
.cf-app .cn-side .cn-nav-item.active svg { color: #fff; }

/* Brand block, same reason. */
.cf-app .cn-side-brand .cn-brand-name { color: rgba(255,255,255,.92); }
/* .45 alpha on the navy rail measured 4.37:1 - under AA for 11px text, and this
   is the product's own name. */
.cf-app .cn-side-brand .cn-brand-sub  { color: rgba(255,255,255,.62); }

/* ── Editable table row ────────────────────────────────────────────────────
   The row being edited turns into inputs in place, so the number you are
   correcting stays where you were already looking. It gets a tinted band and
   a left marker so it is obvious which row is live while the rest of the week
   stays readable around it. */
.cf-app .row-actions { white-space: nowrap; display: flex; gap: 4px; align-items: center; }

.cf-app tr.row-editing > td {
  background: var(--accent-soft);
  border-top: 1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
  padding-top: 8px; padding-bottom: 8px;
  vertical-align: top;
}
.cf-app tr.row-editing > td:first-child { box-shadow: inset 3px 0 0 var(--accent); }

/* Inputs inside a row are denser than form inputs - a table row cannot afford
   the usual vertical rhythm without pushing the rest of the week off screen. */
.cf-app tr.row-editing .cn-input {
  padding: 4px 6px; font-size: 12px; height: auto; min-width: 0;
}
.cf-app .cn-btn.sm { padding: 4px 10px; font-size: 12px; }

/* ═══════════════════════════════════════════════════════════════════════════
   SHARED COMPONENTS
   ═══════════════════════════════════════════════════════════════════════════
   Added so ten office pages stop each inventing their own version of the same
   four things. Everything below is on the --ink/--card/--hairline token set and
   is safe on a light page; the older .cn-chip and .cn-avatar are built out of
   rgba(255,255,255,…) for the dark nav rail and cannot be reused out here.
   ─────────────────────────────────────────────────────────────────────────── */

/* Icons. cf-icons.js emits these stroked in currentColor, so an icon inherits
   the colour and weight of whatever contains it. */
.cf-app .cf-ic { flex-shrink: 0; vertical-align: -0.18em; }
.cf-app .cn-btn .cf-ic,
.cf-app .cn-btn-outline .cf-ic,
.cf-app .cn-btn-navy .cf-ic,
.cf-app .cn-btn-danger .cf-ic { margin-right: 6px; vertical-align: -0.2em; }
.cf-app .cn-icon-btn .cf-ic { margin: 0; vertical-align: middle; }

/* ── Stat card ──────────────────────────────────────────────────────────────
   A tinted icon square, one number, one label. Promoted out of the dashboard
   because every page that opens with counts wants exactly this. The tint
   carries state so the number does not have to be read to know if it is good. */
.cf-app .cn-stats {
  display: grid; gap: var(--sp-3);
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
  margin: 0 0 var(--sp-4);
}
.cf-app .cn-stat {
  background: var(--card); border: 1px solid var(--hairline);
  border-radius: var(--r-card); padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.cf-app .cn-stat.is-link { cursor: pointer; }
.cf-app .cn-stat.is-link:hover { border-color: var(--control-bd); background: #FCFDFE; }
.cf-app .cn-stat-ico {
  width: 34px; height: 34px; border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.cf-app .cn-stat-v {
  font-size: 26px; font-weight: 700; line-height: 1;
  color: var(--ink); letter-spacing: -0.01em; font-variant-numeric: tabular-nums;
}
.cf-app .cn-stat-v.is-zero { color: var(--ink-3); font-weight: 600; }
.cf-app .cn-stat-l {
  font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--ink-2);
}
.cf-app .cn-stat-f { font-size: 12px; color: var(--ink-2); }

/* Status tints. Paired so a background never appears without its readable
   foreground — the two are one decision, not two. */
.cf-app .t-new    { background: var(--st-new-bg);     color: var(--st-new-fg); }
.cf-app .t-motion { background: var(--st-motion-bg);  color: var(--st-motion-fg); }
.cf-app .t-done   { background: var(--st-done-bg);    color: var(--st-done-fg); }
.cf-app .t-flat   { background: var(--st-neutral-bg); color: var(--st-neutral-fg); }
.cf-app .t-risk   { background: var(--st-risk-bg);    color: var(--st-risk-fg); }

/* ── Status badge ───────────────────────────────────────────────────────────
   A tint carrying dark text, with a border. NOT white-on-solid: on a white
   page a saturated fill reads as a button, something to press, and these are
   labels. Sentence case rather than the old all-caps-with-letterspacing, which
   at 10.5px was shouting a word the reader already expected. */
.cf-app .cn-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: var(--r-badge);
  font-size: 11.5px; font-weight: 700; line-height: 1.35;
  white-space: nowrap; border: 1px solid transparent;
  background: var(--st-neutral-bg); color: var(--st-neutral-fg);
  border-color: var(--hairline);
}
.cf-app .cn-badge.is-new    { background: var(--st-new-bg);    color: var(--st-new-fg);    border-color: #C6DAFA; }
.cf-app .cn-badge.is-motion { background: var(--st-motion-bg); color: var(--st-motion-fg); border-color: #F2DBAB; }
.cf-app .cn-badge.is-done   { background: var(--st-done-bg);   color: var(--st-done-fg);   border-color: #BCE3D0; }
.cf-app .cn-badge.is-risk   { background: var(--st-risk-bg);   color: var(--st-risk-fg);   border-color: #F3C6C2; }
.cf-app .cn-badge .cf-ic { margin: 0; }

/* ── Initials ───────────────────────────────────────────────────────────────
   Colour derived from the name, so a person keeps the same swatch everywhere
   and a list of fourteen drivers can be scanned instead of read. */
.cf-app .cn-ini {
  width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10.5px; font-weight: 700; letter-spacing: .02em; flex-shrink: 0;
}
.cf-app .cn-ini.lg { width: 34px; height: 34px; font-size: 12.5px; }

/* ── Segmented filter ───────────────────────────────────────────────────────
   Counts live ON the segment. A filter that does not say how many it will show
   makes you click it to find out, and clicking is how you lose your place. */
.cf-app .cn-seg { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.cf-app .cn-seg > button {
  display: inline-flex; align-items: center; gap: 7px;
  height: 34px; padding: 0 12px;
  background: var(--card); color: var(--ink-2);
  border: 1px solid var(--hairline); border-radius: var(--r-badge);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  white-space: nowrap;
}
.cf-app .cn-seg > button:hover { border-color: var(--control-bd); color: var(--ink); }
.cf-app .cn-seg > button.on {
  background: var(--accent-soft); color: var(--accent);
  border-color: var(--accent);
}
.cf-app .cn-seg .n {
  font-size: 11.5px; font-weight: 700; padding: 1px 6px;
  border-radius: var(--r-badge);
  background: var(--st-neutral-bg); color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.cf-app .cn-seg > button.on .n { background: #fff; color: var(--accent); }

/* ── Ranked rows ────────────────────────────────────────────────────────────
   Scaled to the list's own largest value, so one dominant row cannot squash
   the rest into invisibility. */
.cf-app .cn-rows { display: flex; flex-direction: column; }
.cf-app .cn-rows .r {
  display: grid; grid-template-columns: 26px 1fr 72px;
  align-items: center; gap: var(--sp-3);
  padding: 9px 0; border-bottom: 1px solid var(--hairline);
}
.cf-app .cn-rows .r:last-child { border-bottom: 0; }
.cf-app .cn-rows .r.no-av { grid-template-columns: 1fr 72px; }
.cf-app .cn-rows .r-name { font-size: 13.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cf-app .cn-rows .r-num  { font-size: 13.5px; font-weight: 700; color: var(--ink); text-align: right; font-variant-numeric: tabular-nums; }
.cf-app .cn-rows .r-bar  { grid-column: 2 / -1; height: 4px; border-radius: 999px; background: var(--st-neutral-bg); overflow: hidden; margin-top: -4px; }
.cf-app .cn-rows .r.no-av .r-bar { grid-column: 1 / -1; }
.cf-app .cn-rows .r-fill { height: 100%; border-radius: 999px; background: var(--accent); }

/* ── Attention band ─────────────────────────────────────────────────────────
   For the one thing on a page that is not a statistic. Absent when there is
   nothing to act on, rather than showing a reassuring green nothing. */
.cf-app .cn-attn {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-4);
  background: var(--st-risk-bg); color: var(--st-risk-fg);
  border: 1px solid #F0C9C9; border-radius: var(--r-card);
  margin: 0 0 var(--sp-4);
}
.cf-app .cn-attn.is-motion { background: var(--st-motion-bg); color: var(--st-motion-fg); border-color: #F2DBAB; }
.cf-app .cn-attn-n    { font-size: 22px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
.cf-app .cn-attn-copy { flex: 1; min-width: 0; font-size: 13.5px; line-height: 1.4; }
.cf-app .cn-attn-go {
  flex-shrink: 0; font-size: 13px; font-weight: 700; color: inherit;
  text-decoration: none; background: #fff; cursor: pointer;
  border: 1px solid currentColor; border-radius: var(--r-control); padding: 7px 12px;
}
.cf-app .cn-attn-go:hover { opacity: .82; }

/* ── Empty state ────────────────────────────────────────────────────────────
   A shape rather than a sentence. Seen most often by someone who has just
   filtered too hard, so it says what to do next. */
.cf-app .cn-blank { text-align: center; padding: 48px 24px; }
.cf-app .cn-blank-ico {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; margin-bottom: 12px; border-radius: 50%;
  background: var(--canvas); border: 1px solid var(--hairline); color: var(--ink-3);
}
.cf-app .cn-blank-h { font-size: 15.5px; font-weight: 700; color: var(--ink); margin-bottom: 5px; }
.cf-app .cn-blank-p { font-size: 13px; color: var(--ink-2); line-height: 1.5; max-width: 34ch; margin: 0 auto; }

/* ── Search fields ──────────────────────────────────────────────────────────
   Several pages put a 🔍 in the placeholder text, which meant the affordance
   disappeared the moment someone typed - exactly when they might want to see
   that this field is a search. A background image instead: no DOM change, no
   per-page wrapper, and it stays put while you type.

   The glyph is an inline data URI rather than cf-icons.js because a background
   image cannot inherit currentColor; --ink-3 is the right weight for an
   affordance that should not compete with what you typed. */
.cf-app input[type="search"],
.cf-app .cn-input.search,
.cf-app input.search {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none' stroke='%238B949E' stroke-width='1.7' stroke-linecap='round'%3E%3Ccircle cx='9' cy='9' r='4.8'/%3E%3Cpath d='M12.6 12.6l3.6 3.6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: 9px 50%;
  background-size: 16px 16px;
  padding-left: 31px;
}
/* Chrome draws its own clear button on type=search; keep it from colliding. */
.cf-app input[type="search"]::-webkit-search-cancel-button { margin-left: 4px; }
