/* Martin Group, CRM Dashboard.
   Hand-written from design_handoff_internet_crm_reporting/design_system tokens.
   No framework, no webfonts, no icon font. Desktop-first at 1360-1440px. */

/* ---------------------------------------------------------------- tokens */
:root {
  /* Brand */
  --mg-teal: #17A38C;
  --mg-teal-hover: #128A76;
  --mg-teal-deep: #0E7C6B;
  --mg-teal-tint: #E2F3EF;
  --mg-teal-soft: #9DC6BE;

  /* Dark chrome */
  --mg-ink: #232B2A;
  --mg-ink-hover: #2E3836;
  --mg-ink-divider: #33403D;
  --mg-ink-label: #8A9391;

  /* Surfaces */
  --mg-page: #F4F5F4;
  --mg-card: #FFFFFF;
  --mg-strip: #FAFBFA;
  --mg-table-head: #F1F3F2;
  --mg-zebra: #F7F8F8;
  --mg-row-hover: #F6FAF9;

  /* Borders */
  --mg-border: #DDE1DF;
  --mg-border-control: #C9CFCC;
  --mg-border-row: #EEF0EF;

  /* Text */
  --mg-text: #222927;
  --mg-text-2: #5A6461;
  --mg-text-muted: #6B7370;
  --mg-text-faint: #98A09D;
  --mg-text-zero: #C7CCCA;

  /* Status */
  --mg-red: #C0392B;
  --mg-red-tint: #FBEAE7;
  --mg-red-border: #EFC7C0;
  --mg-amber: #A8720A;
  --mg-amber-text: #8A6D1F;
  --mg-amber-tint: #FBF3D9;
  --mg-amber-border: #E8D89A;
  --mg-green: #1E6B34;
  --mg-green-tint: #E6F2E9;
  --mg-green-border: #C4DFCC;

  /* Type */
  --font-sans: Helvetica, Arial, sans-serif;

  /* Density */
  --sidebar-w: 216px;
  --row-h: 34px;
  --row-h-admin: 36px;
}

/* ------------------------------------------------------------ base reset */
* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  background: var(--mg-page);
  color: var(--mg-text);
  font-family: var(--font-sans);
  font-size: 13px;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--mg-teal-deep); text-decoration: none; }
a:hover { color: var(--mg-teal-hover); }

.tnum { font-variant-numeric: tabular-nums; }
.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;
}

/* --------------------------------------------------------------- app shell */
.app { display: flex; min-height: 100vh; background: var(--mg-page); }

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--mg-ink);
  display: flex;
  flex-direction: column;
}

.logo-plate {
  background: var(--mg-card);
  padding: 14px 16px;
  border-bottom: 3px solid var(--mg-teal);
}
.logo-plate img { display: block; width: 150px; min-width: 110px; }
.brand-caption {
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--mg-text-muted);
  margin-top: 6px;
}

/* The mobile menu button. Hidden at every width until app/static/nav.js marks
   the sidebar collapsible AND the narrow breakpoint applies, so the desktop
   chrome is untouched and a JS failure leaves the full nav in place. */
.nav-toggle {
  display: none;
  width: 44px;
  height: 40px;
  flex: 0 0 44px;
  align-items: center;
  justify-content: center;
  background: var(--mg-card);
  border: 1px solid var(--mg-border-control);
  border-radius: 3px;
  cursor: pointer;
}
.nav-toggle-bars,
.nav-toggle-bars::before,
.nav-toggle-bars::after {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--mg-text);
  border-radius: 1px;
}
.nav-toggle-bars { position: relative; }
.nav-toggle-bars::before, .nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.nav-toggle-bars::before { top: -6px; }
.nav-toggle-bars::after { top: 6px; }
.nav-toggle:focus-visible { outline: 2px solid var(--mg-teal); outline-offset: 2px; }

/* Rooftop names ship in both forms; the short code appears only on mobile. */
.s-abbr { display: none; }

.nav { padding: 14px 0; display: flex; flex-direction: column; }
.nav-item {
  display: block;
  padding: 9px 16px;
  font-size: 13px;
  color: var(--mg-text-zero);
  border-left: 3px solid transparent;
  background: transparent;
  text-decoration: none;
  transition: background-color 80ms linear, color 80ms linear;
}
.nav-item:hover { background: var(--mg-ink-hover); color: #FFFFFF; }
.nav-item.is-active {
  background: var(--mg-ink-hover);
  color: #FFFFFF;
  font-weight: bold;
  border-left-color: var(--mg-teal);
}
.nav-item.is-disabled { color: #6E7A76; cursor: default; }
.nav-item.is-disabled:hover { background: transparent; color: #6E7A76; }
.nav-label {
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--mg-ink-label);
  padding: 20px 16px 6px;
}

.sidebar-footer {
  margin-top: auto;
  padding: 16px;
  border-top: 1px solid var(--mg-ink-divider);
}
.sidebar-user { font-size: 13px; font-weight: bold; color: #FFFFFF; }
.sidebar-scope { font-size: 11px; color: var(--mg-ink-label); margin-top: 2px; }
.signout-form { margin: 10px 0 0; }
.signout {
  background: none;
  border: 0;
  padding: 0;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--mg-text-zero);
  text-decoration: underline;
  cursor: pointer;
}
.signout:hover { color: #FFFFFF; }

.main { flex: 1; min-width: 0; }

/* ------------------------------------------------------------ page header */
.page-header {
  background: var(--mg-card);
  border-bottom: 1px solid var(--mg-border);
  padding: 18px 24px 14px;
}
.page-header-top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
}
.page-title { font-size: 19px; font-weight: 700; color: var(--mg-text); }
.page-meta {
  font-size: 12px;
  color: var(--mg-text-muted);
  margin-top: 5px;
  line-height: 17px;
}
.page-meta b { color: var(--mg-text); }
.page-actions { display: flex; gap: 8px; align-items: center; flex-shrink: 0; }

/* --------------------------------------------------------------- controls */
.btn {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: bold;
  border-radius: 3px;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 80ms linear, border-color 80ms linear;
}
.btn-primary {
  background: var(--mg-teal);
  border: 1px solid var(--mg-teal);
  color: #FFFFFF;
  padding: 8px 14px;
}
.btn-primary:hover { background: var(--mg-teal-hover); border-color: var(--mg-teal-hover); color: #FFFFFF; }
.btn-secondary {
  background: var(--mg-card);
  border: 1px solid var(--mg-border-control);
  color: var(--mg-text);
  padding: 7px 11px;
}
.btn-secondary:hover { background: var(--mg-strip); color: var(--mg-text); }
.btn-block { display: block; width: 100%; text-align: center; padding: 9px 14px; }

select, input[type="text"], input[type="email"], input[type="number"], input[type="time"] {
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--mg-text);
  background: var(--mg-card);
  border: 1px solid var(--mg-border-control);
  border-radius: 3px;
  padding: 7px 9px;
}
select { padding-right: 6px; }
input::placeholder { color: var(--mg-text-faint); }
input:focus, select:focus, .btn:focus {
  outline: none;
  border-color: var(--mg-teal);
  box-shadow: 0 0 0 2px var(--mg-teal-tint);
}

.field { display: block; }
.field-label {
  display: block;
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
}
.field-label + select,
.field-label + input { margin-top: 5px; width: 100%; }

/* Report subscription toggles on the user cards (2026-08-20). The list can run
   to 31 boxes, so it scrolls inside the card instead of pushing the save button
   off the page; the other-stores block stays collapsed until it is opened. */
.subs-field { margin-top: 2px; }
.subs-section { margin-top: 6px; }
.subs-heading {
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
  margin-top: 6px;
}
.subs-band { margin: 4px 0 4px 8px; }
.subs-band-name { font-size: 11px; font-weight: bold; color: var(--mg-text); }
.subs-toggle { display: block; line-height: 1.5; }
.subs-name { color: var(--mg-text); }
.subs-edition { color: var(--mg-text-faint); }
.subs-other {
  margin-top: 8px;
  max-height: 260px;
  overflow-y: auto;
  border-top: 1px solid var(--mg-border-row);
  padding-top: 6px;
}
.subs-other > summary {
  font-size: 11px;
  font-weight: bold;
  cursor: pointer;
  color: var(--mg-text);
}

/* Users-table filter bar (2026-08-20). Inside the USERS card, above the table:
   a plain GET form, so it is styled like the card forms rather than like the
   reporting .filterbar in the page header. The count line under it is where
   both the server's "Showing N of M" and the script's live count land, so it
   holds its own row whether or not it has text. */
.user-filter {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  align-items: flex-end;
  margin: 0;
  padding: 12px 24px 0;
}
.user-filter-field { display: block; }
.user-filter-field select, .user-filter-field input { min-width: 190px; }
.user-filter-search input { min-width: 230px; }
.user-filter-toggle { white-space: nowrap; padding-bottom: 5px; }
.user-filter .btn { padding: 6px 14px; }
.user-filter-count { padding: 8px 24px 0; font-size: 11px; color: var(--mg-text-muted); }

/* -------------------------------------------------------------- filterbar */
.filterbar {
  display: flex;
  gap: 14px;
  margin-top: 14px;
  flex-wrap: wrap;
  align-items: center;
}
.filter {
  display: flex;
  gap: 6px;
  align-items: center;
}
.filter-form { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; margin: 0; }
.filter-label { font-size: 10px; letter-spacing: 0.5px; color: var(--mg-text-muted); }
.filter-value { font-size: 13px; font-weight: bold; color: var(--mg-text); }
.filter select { font-size: 12px; padding: 4px 6px; max-width: 220px; }
.glyph { color: var(--mg-text-faint); font-size: 11px; }
.period-form { display: flex; gap: 8px; align-items: center; margin: 0; }

/* ------------------------------------------------------------------ tiles */
.tile-row {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  padding: 18px 24px 4px;
}
.tile {
  flex: 1 1 180px;
  min-width: 180px;
  background: var(--mg-card);
  border: 1px solid var(--mg-border);
  border-radius: 4px;
  padding: 14px 16px;
}
.tile-label {
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
}
.tile-value {
  font-size: 28px;
  font-weight: 700;
  line-height: 32px;
  margin-top: 4px;
  font-variant-numeric: tabular-nums;
  color: var(--mg-text);
}
.tile-delta { font-size: 11px; margin-top: 4px; color: var(--mg-text-muted); }
.tile-delta.is-good { color: var(--mg-green); }
.tile-delta.is-bad { color: var(--mg-red); }

/* value status colors, shared by tiles and table cells */
.v-ok { color: var(--mg-text); }
.v-watch { color: var(--mg-amber); }
.v-action { color: var(--mg-red); }
.v-base { color: var(--mg-text-muted); }
.v-zero { color: var(--mg-text-zero); }
.v-pending { color: var(--mg-text-faint); }
.v-good { color: var(--mg-green); }
.tile-value.v-ok { color: var(--mg-green); }

/* ------------------------------------------------------------------ pages */
.content {
  padding: 14px 24px 24px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.row-2 { display: flex; gap: 14px; flex-wrap: wrap; }
/* Stacked cards inside a column separate with the same 14px the .content
   flow puts between the ranking card and this row (Jeremy, 2026-08-13). */
.col-wide { flex: 1 1 520px; min-width: 460px; display: flex; flex-direction: column; gap: 14px; }
.col-narrow { flex: 1 1 340px; min-width: 320px; display: flex; flex-direction: column; gap: 14px; }

/* ------------------------------------------------------------------ cards */
.card {
  background: var(--mg-card);
  border: 1px solid var(--mg-border);
  border-radius: 4px;
  min-width: 0;
}
.card-strip {
  background: var(--mg-strip);
  border-bottom: 1px solid var(--mg-border);
  padding: 10px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.card-title {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
}
.card-note { font-size: 11px; color: var(--mg-text-faint); }
.card-footnote {
  padding: 11px 16px;
  font-size: 12px;
  color: var(--mg-text-muted);
  line-height: 17px;
}
.card-footnote b { color: var(--mg-text); }
.card-body { padding: 14px 16px; }
.card-form { display: flex; flex-direction: column; gap: 12px; }

.note-block {
  padding: 12px 16px;
  border-bottom: 1px solid var(--mg-border-row);
}
.note-block:last-child { border-bottom: 0; }
.note-title { font-size: 13px; font-weight: bold; color: var(--mg-text); }
.note-text {
  font-size: 12px;
  color: var(--mg-text-muted);
  margin-top: 3px;
  line-height: 17px;
}

/* Notes read as a row of blocks when the card is full width (pacing, bottom). */
.note-grid { display: flex; flex-wrap: wrap; }
.note-grid .note-block {
  flex: 1 1 260px;
  border-bottom: 0;
  border-right: 1px solid var(--mg-border-row);
}
.note-grid .note-block:last-child { border-right: 0; }

.empty-state {
  padding: 18px 16px;
  font-size: 13px;
  color: var(--mg-text-faint);
  line-height: 19px;
}

/* ----------------------------------------------------------------- charts */
/* Three single-series SVG line charts, server rendered (app/ui.py line_chart).
   Each scales to its column: the SVG carries a viewBox and no width, so 100%
   width with auto height keeps the point markers circular at any size. */
.chart-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 14px 16px;
}
.chart { flex: 1 1 280px; min-width: 0; }
.chart-title {
  font-size: 12px;
  font-weight: bold;
  color: var(--mg-text);
  margin-bottom: 4px;
}
.trend-chart { display: block; width: 100%; height: auto; overflow: visible; }
.tc-point { cursor: default; }

/* Hover layer (app/static/trend-chart.js): one crosshair and one tooltip for
   all three charts, created on demand and positioned in page coordinates. */
.tc-tip {
  position: absolute;
  z-index: 20;
  background: var(--mg-ink);
  color: #FFFFFF;
  font-size: 11px;
  line-height: 15px;
  padding: 4px 7px;
  border-radius: 3px;
  pointer-events: none;
  white-space: nowrap;
  transform: translate(-50%, -100%);
}

/* ---------------------------------------------------------------- callout */
.callout {
  background: var(--mg-red-tint);
  border: 1px solid var(--mg-red-border);
  border-radius: 4px;
  padding: 12px 16px;
}
.callout-heading {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-red);
}
.callout-text {
  font-size: 13px;
  color: var(--mg-text);
  margin-top: 5px;
  line-height: 19px;
}

.notice {
  border: 1px solid var(--mg-border);
  background: var(--mg-strip);
  border-radius: 4px;
  padding: 10px 16px;
  font-size: 13px;
  color: var(--mg-text-muted);
}
.notice.is-good { background: var(--mg-green-tint); border-color: var(--mg-green-border); color: var(--mg-green); }
.notice.is-bad { background: var(--mg-red-tint); border-color: var(--mg-red-border); color: var(--mg-red); }

/* ----------------------------------------------------------------- badges */
.badge {
  display: inline-block;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.5px;
  padding: 2px 6px;
  border-radius: 3px;
  white-space: nowrap;
  /* A badge longer than its column must clip inside its own cell, never run
     into the neighbor (user-admin status bug, Jeremy 2026-08-20). */
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  box-sizing: border-box;
  vertical-align: top;
  color: var(--mg-text-muted);
  background: var(--mg-table-head);
  border: 1px solid var(--mg-border);
}
.badge-ok { color: var(--mg-green); background: var(--mg-green-tint); border-color: var(--mg-green-border); }
.badge-watch { color: var(--mg-amber-text); background: var(--mg-amber-tint); border-color: var(--mg-amber-border); }
.badge-action { color: var(--mg-red); background: var(--mg-red-tint); border-color: var(--mg-red-border); }
.badge-base { color: var(--mg-text-muted); background: var(--mg-table-head); border-color: var(--mg-border); }
.badge-zero { color: var(--mg-text-zero); background: var(--mg-table-head); border-color: var(--mg-border); }
.badge-pending { color: var(--mg-text-faint); background: var(--mg-strip); border-color: var(--mg-border); }

/* ------------------------------------------------------------ grid tables */
/* gt-compact: the standard grid table at reduced density, for the narrow-
   column widgets (email blast availability). Same zebra, header and status
   vocabulary - only the row height, type size and cell padding shrink. */
.gt-compact .gt-row { min-height: 28px; font-size: 12px; }
.gt-compact .gt-row > div { padding: 3px 8px; }
.gt-compact .gt-head > div { padding: 6px 8px; }
.gt-compact .badge { font-size: 8px; padding: 1px 6px; }
.gt-scroll { overflow-x: auto; }
.gt-head,
.gt-row,
.gt-foot {
  display: grid;
  align-items: center;
  /* THE STRIPING FIX (audit A3, 2026-08-01). Without this the row BOX is the
     width of the scroller's viewport while its tracks overflow, so the zebra
     stripe, the status tints, the highlight column and the row border all stop
     painting where the scroll starts. min-content is the sum of the track
     minimums - every track this table writes has a FIXED minimum (a px width or
     a minmax() lower bound), so the value is identical for the head, every row
     and the footer, and the columns cannot drift apart. Unconditional on
     purpose: it is broken on a narrow DESKTOP window too. Where nothing
     overflows, min-content is smaller than the box and this changes nothing. */
  min-width: min-content;
}
.gt-head {
  background: var(--mg-table-head);
  border-bottom: 1px solid var(--mg-border);
  font-size: 10px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
}
.gt-head > div { padding: 8px 8px; }
.gt-head > div:first-child { padding-left: 12px; }
.gt-head > div:last-child { padding-right: 12px; }

.gt-row {
  min-height: var(--row-h);
  border-bottom: 1px solid var(--mg-border-row);
  font-size: 13px;
  background: var(--mg-card);
  transition: background-color 80ms linear;
}
.gt-row.is-zebra { background: var(--mg-zebra); }
.gt-row:hover { background: var(--mg-row-hover); }
.gt-row > div { padding: 6px 8px; }
.gt-row > div:first-child { padding-left: 12px; }
.gt-row > div:last-child { padding-right: 12px; }

.gt-foot {
  min-height: var(--row-h-admin);
  background: var(--mg-strip);
  font-size: 13px;
  font-weight: 700;
}
.gt-foot > div { padding: 8px 8px; }
.gt-foot > div:first-child {
  padding-left: 12px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  color: var(--mg-text-muted);
}
.gt-foot > div:last-child { padding-right: 12px; }

.gt-r { text-align: right; font-variant-numeric: tabular-nums; }
.gt-l { text-align: left; }
.gt-first { font-weight: bold; }
.gt-first a { font-weight: bold; color: var(--mg-teal-deep); }
.gt-first a:hover { text-decoration: underline; }
.gt-strong { font-weight: bold; }
/* Full ink, not gray (Jeremy, 2026-08-20): benchmark and comparison values
   were unreadable at the old --mg-text-zero. Muted cells now differ from
   normal ones only by weight, never by legibility. */
.gt-muted { color: var(--mg-text); }
.gt-secondary { color: var(--mg-text-2); }
.gt-sub {
  display: block;
  font-size: 11px;
  color: var(--mg-text-faint);
  margin-top: 2px;
}
.gt-link { font-size: 12px; text-decoration: underline; }

/* decision columns: ui.column(..., highlight=True). A tint plus weight on the
   whole column, head and footer included. Deliberately quiet - it must not read
   as a status colour. */
.gt-hl { background: var(--mg-teal-tint); font-weight: bold; }
.gt-head > .gt-hl { background: var(--mg-teal-tint); color: var(--mg-teal-deep); }

/* sortable headers (app/static/sort.js) */
.gt-sort { cursor: pointer; user-select: none; }
.gt-sort:hover { color: var(--mg-text); background: var(--mg-border-row); }
.gt-sort:focus-visible { outline: 2px solid var(--mg-teal); outline-offset: -2px; }
.gt-arrow {
  display: inline-block;
  margin-left: 4px;
  font-size: 9px;
  color: var(--mg-teal-deep);
}
/* Until sort.js writes a glyph the arrow span is empty, and an empty
   inline-block still WRAPS alone in a tight column - which floated the header
   text onto a centered two-line box and broke the header baseline (seen on the
   compact availability widget, 2026-08-13). Hidden while empty costs nothing:
   the glyph's arrival makes it non-empty and visible again. */
.gt-arrow:empty { display: none; }

/* admin lists sit a little taller */
.gt-admin .gt-row { min-height: var(--row-h-admin); }
.gt-admin .gt-row > div { padding: 7px 8px; }
.gt-admin .gt-row > div:first-child { padding-left: 12px; }
.gt-admin .gt-row > div:last-child { padding-right: 12px; }

/* in-row numeric inputs (thresholds) */
.gt-edit .gt-row { min-height: 40px; }
.gt-edit .gt-row > div { padding: 5px 8px; }
.gt-edit .gt-row > div:first-child { padding-left: 12px; }
.num-input {
  width: 72px;
  min-width: 62px;
  text-align: right;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
  padding: 5px 9px;
}
.num-good { color: var(--mg-green); }
.num-watch { color: var(--mg-amber); }
.cell-input { display: flex; justify-content: flex-end; }
.action-text { font-size: 12px; font-weight: bold; color: var(--mg-red); }

/* Subsection heading rows inside a grid table (B6-7, 2026-08-02). A store name
   stated ONCE above its own leads, spanning the full table width rather than
   sitting in a repeated first column. width: min-content + min-width: 100%
   keeps the band as wide as the scrolled content (a block's own min-content is
   only its longest word), so it never ends mid-table on a scrolling table. */
.gt-group {
  width: min-content;
  min-width: 100%;
  box-sizing: border-box;
  padding: 8px 12px 6px;
  font-size: 11px;
  font-weight: bold;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: var(--mg-teal-deep);
  background: var(--mg-strip);
  border-top: 1px solid var(--mg-border);
  border-bottom: 1px solid var(--mg-border-row);
}
/* :first-of-type is per element TYPE (every child here is a div), so it can
   never match the first band; the adjacent-sibling form is what works. */
.gt-head + .gt-group { border-top: none; }
/* The lead rows read as belonging to the heading above them. */
.gt-grouped > .gt-row > div:first-child { padding-left: 28px; }

/* trend table: historical months read progressively lighter, MTD is bold */
.trend-m0, .trend-m1 { color: #8A9391; }
.trend-m2, .trend-m3 { color: var(--mg-text-muted); }
.trend-m4, .trend-m5 { color: var(--mg-text-2); }
.trend-table .gt-row > div:nth-child(2),
.trend-table .gt-row > div:nth-child(3) { color: #8A9391; }
.trend-table .gt-row > div:nth-child(4),
.trend-table .gt-row > div:nth-child(5) { color: var(--mg-text-muted); }
.trend-table .gt-row > div:nth-child(6) { color: var(--mg-text-2); }
.trend-table .gt-row > div:nth-child(7) { font-weight: bold; color: var(--mg-text); }
.trend-table .gt-row { min-height: var(--row-h-admin); }

/* -------------------------------------------------------------- bar cells */
.bar-track {
  height: 8px;
  background: var(--mg-teal-tint);
  border-radius: 4px;
  overflow: hidden;
}
.bar-fill { height: 100%; background: var(--mg-teal); }
.bar-teal { background: var(--mg-teal); }
.bar-amber { background: var(--mg-amber); }
.bar-red { background: var(--mg-red); }
.bar-green { background: var(--mg-green); }
.bar-soft { background: var(--mg-teal-soft); }
.bar-deep { background: var(--mg-teal-deep); }
.bar-gray { background: var(--mg-text-zero); }

/* band rows: label, bar, value, note */
.band {
  padding: 10px 16px;
  border-bottom: 1px solid var(--mg-border-row);
  display: flex;
  align-items: center;
  gap: 12px;
}
.band:last-of-type { border-bottom: 1px solid var(--mg-border-row); }
.band.is-zebra { background: var(--mg-zebra); }
.band-label {
  width: 118px;
  flex: 0 0 118px;
  font-size: 13px;
  font-weight: bold;
  color: var(--mg-text);
}
.band-label a { font-weight: bold; }
.band-bar { flex: 1; min-width: 0; }
.band-bar .bar-track { height: 10px; border-radius: 5px; background: var(--mg-table-head); }
.band-value {
  width: 62px;
  flex: 0 0 62px;
  text-align: right;
  font-size: 14px;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
}
.band-count {
  width: 60px;
  flex: 0 0 60px;
  text-align: right;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
  color: var(--mg-text-2);
}
.band-note {
  width: 96px;
  flex: 0 0 96px;
  text-align: right;
  font-size: 11px;
  color: var(--mg-text-faint);
}
.band-note-wide { width: 118px; flex: 0 0 118px; font-size: 12px; color: var(--mg-text-muted); }

/* stacked band (name over bar), used for flagged-store lists */
.band-stack {
  padding: 11px 16px;
  border-bottom: 1px solid var(--mg-border-row);
  display: flex;
  align-items: center;
  gap: 12px;
}
.band-stack:hover { background: var(--mg-row-hover); }
.band-stack.is-zebra { background: var(--mg-zebra); }
.band-stack-main { flex: 1; min-width: 0; }
.band-stack-name { font-size: 13px; font-weight: bold; color: var(--mg-teal-deep); }
.band-stack-main .bar-track { margin-top: 6px; }
.band-stack-value {
  width: 62px;
  flex: 0 0 62px;
  text-align: right;
  font-size: 15px;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
}

/* funnel steps */
.funnel-step {
  padding: 12px 16px;
  border-bottom: 1px solid var(--mg-border-row);
}
.funnel-step.is-zebra { background: var(--mg-zebra); }
.funnel-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.funnel-label { font-size: 13px; font-weight: bold; }
.funnel-right { display: flex; align-items: baseline; gap: 10px; }
.funnel-note { font-size: 12px; color: var(--mg-text-muted); }
.funnel-value { font-size: 17px; font-weight: bold; font-variant-numeric: tabular-nums; }
.funnel-step .bar-track {
  height: 10px;
  border-radius: 5px;
  margin-top: 7px;
  background: var(--mg-table-head);
}

/* label/value pair rows (CRM hygiene) */
.pair {
  padding: 12px 16px;
  border-bottom: 1px solid var(--mg-border-row);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
}
.pair:last-of-type { border-bottom: 1px solid var(--mg-border-row); }
.pair-label { font-size: 13px; font-weight: bold; }
.pair-note { font-size: 11px; color: var(--mg-text-faint); margin-top: 3px; }
.pair-right { text-align: right; }
.pair-value { font-size: 19px; font-weight: bold; font-variant-numeric: tabular-nums; }
.pair-prior { font-size: 11px; color: var(--mg-text-muted); margin-top: 2px; }

/* ------------------------------------------------------------ login page */
.login-page {
  min-height: 100vh;
  background: var(--mg-page);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.login-card {
  width: 360px;
  max-width: 100%;
  background: var(--mg-card);
  border: 1px solid var(--mg-border);
  border-radius: 4px;
}
.login-card .logo-plate { border-radius: 4px 4px 0 0; }
.login-body { padding: 20px 20px 18px; }
.login-title { font-size: 19px; font-weight: 700; }
.login-text { font-size: 13px; color: var(--mg-text-muted); margin-top: 6px; line-height: 19px; }
.login-error {
  margin-top: 14px;
  padding: 10px 12px;
  background: var(--mg-red-tint);
  border: 1px solid var(--mg-red-border);
  border-radius: 3px;
  font-size: 12px;
  color: var(--mg-red);
  line-height: 17px;
}
.login-actions { margin-top: 16px; }
.login-footnote {
  padding: 12px 20px 16px;
  border-top: 1px solid var(--mg-border-row);
  font-size: 11px;
  color: var(--mg-text-faint);
  line-height: 16px;
}

/* ------------------------------------------------------------- responsive */
@media (max-width: 900px) {
  .app { flex-direction: column; }
  .sidebar {
    width: 100%;
    flex: 0 0 auto;
    position: sticky;
    top: 0;
    z-index: 5;
    background: var(--mg-card);
    border-bottom: 1px solid var(--mg-border);
  }
  .nav { flex-direction: row; flex-wrap: wrap; padding: 8px 12px; gap: 6px; }
  .nav-item {
    border: 1px solid var(--mg-border);
    border-left-width: 3px;
    border-left-color: transparent;
    border-radius: 3px;
    padding: 6px 10px;
    color: var(--mg-text-muted);
  }
  .nav-item:hover, .nav-item.is-active {
    background: var(--mg-teal-tint);
    color: var(--mg-text);
    border-left-color: var(--mg-teal);
  }
  .nav-label { padding: 8px 12px 0; color: var(--mg-text-muted); }
  .sidebar-footer { border-top: 1px solid var(--mg-border-row); }
  .sidebar-user { color: var(--mg-text); }
  .sidebar-scope { color: var(--mg-text-muted); }
  .signout { color: var(--mg-teal-deep); }
  .signout:hover { color: var(--mg-teal-hover); }
}

/* ---- 840px: the nav collapses behind the menu button (audit A1) ----------
   Nine links plus the ADMIN group wrap to ~150px of chrome at phone width.
   Brand and button share one row; the menu EXPANDS the sticky band in place,
   so the page never shifts sideways, and sign-out plus the scope line ride
   inside it. Scoped to html.js-nav, stamped by an INLINE head script in
   base.html BEFORE first paint - a deferred class add painted the full
   nine-link nav for a frame on every phone load (review, 2026-08-02). With JS
   off the class never appears and the nav renders uncollapsed. nav.js still
   adds .has-nav-toggle at init as the button's live marker.
   Breakpoint 840px is mirrored in nav.js (min-width: 841px) - move both. */
@media (max-width: 840px) {
  html.js-nav .sidebar .logo-plate {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 10px 12px;
  }
  html.js-nav .sidebar .logo-plate img { width: 122px; min-width: 100px; }
  html.js-nav .sidebar .brand-caption { margin-top: 4px; }
  html.js-nav .sidebar .nav-toggle { display: flex; }

  html.js-nav .sidebar .nav,
  html.js-nav .sidebar .sidebar-footer { display: none; }

  html.js-nav .sidebar.is-nav-open .nav {
    display: flex;
    flex-direction: column;
    flex-wrap: nowrap;
    gap: 4px;
    padding: 8px 10px 4px;
    max-height: calc(100vh - 160px);
    overflow-y: auto;
  }
  html.js-nav .sidebar.is-nav-open .nav-item {
    display: flex;
    align-items: center;
    min-height: 40px;
    padding: 10px 12px;
  }
  html.js-nav .sidebar.is-nav-open .nav-label { padding: 10px 12px 2px; }
  html.js-nav .sidebar.is-nav-open .sidebar-footer { display: block; padding: 12px; }
  html.js-nav .sidebar.is-nav-open .signout { min-height: 32px; }
}

/* ---- 640px: phone layout (audit A2, A4, A5, A6) -------------------------- */
@media (max-width: 640px) {
  /* Rooftop names become their short codes (app/metrics/names.py). Both forms
     are in the DOM; only the visible one changes. */
  .s-full { display: none; }
  .s-abbr { display: inline; }

  /* Table tracks tighten. These custom properties are read by the inline
     grid-template-columns the grid_table macro writes. */
  .gt-scroll {
    --gt-first-wide-min: 104px;
    --gt-first-min: 84px;
    --gt-col-min: 72px;
  }
  /* The store column stays put while the numbers scroll under it. Its
     background is inherited from the row, so zebra, hover and the footer strip
     all carry through. */
  .gt-scroll > .gt-head > div:first-child,
  .gt-scroll > .gt-row > div:first-child,
  .gt-scroll > .gt-foot > div:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: inherit;
    box-shadow: 1px 0 0 var(--mg-border-row);
  }

  /* Header: title block over the actions, nothing side by side, no page-body
     horizontal scroll at 390px. */
  .page-header { padding: 12px 14px 10px; }
  .page-header-top { flex-direction: column; align-items: stretch; gap: 10px; }
  .page-title { font-size: 17px; }
  .page-meta { font-size: 11px; line-height: 16px; }
  .page-actions { flex-wrap: wrap; gap: 8px; }
  .period-form { flex: 1 1 100%; }
  .period-form select { width: 100%; min-height: 40px; font-size: 14px; }
  .page-actions .btn {
    flex: 1 1 100%;
    min-height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  /* Filter bar: one control per row, full-width tap targets. */
  .filterbar { margin-top: 10px; gap: 10px; }
  .filter-form { flex-direction: column; align-items: stretch; gap: 10px; width: 100%; }
  .filter { flex-direction: column; align-items: stretch; gap: 4px; }
  .filter select {
    width: 100%;
    max-width: none;
    min-height: 40px;
    font-size: 14px;
    padding: 8px 9px;
  }

  /* Users filter: one control per row, full-width tap targets. */
  .user-filter { flex-direction: column; align-items: stretch; gap: 8px; padding: 10px 12px 0; }
  .user-filter-field select, .user-filter-field input,
  .user-filter-search input { min-width: 0; width: 100%; min-height: 40px; font-size: 14px; }
  .user-filter-count { padding: 8px 12px 0; }

  /* Tiles: 2-up, tighter, smaller value type. Order is unchanged. */
  .tile-row { padding: 12px 12px 2px; gap: 8px; }
  .tile { flex: 1 1 calc(50% - 4px); min-width: 0; padding: 10px 11px; }
  .tile-label { font-size: 9px; letter-spacing: 0.5px; }
  .tile-value { font-size: 21px; line-height: 25px; }
  .tile-delta { font-size: 10px; }

  /* Vertical compression. Section order is untouched. */
  .content { padding: 10px 12px 18px; gap: 10px; }
  .row-2 { gap: 10px; }
  .col-wide, .col-narrow { flex: 1 1 100%; min-width: 0; gap: 10px; }
  .card-strip { padding: 8px 12px; }
  .card-body { padding: 10px 12px; }
  .card-footnote { padding: 9px 12px; font-size: 11px; line-height: 16px; }
  .note-block, .funnel-step, .pair { padding: 10px 12px; }
  .note-grid .note-block {
    flex: 1 1 100%;
    border-right: 0;
    border-bottom: 1px solid var(--mg-border-row);
  }
  .note-grid .note-block:last-child { border-bottom: 0; }
  .empty-state { padding: 14px 12px; }

  /* Band rows: the name takes its own line so the bar, count and value fit
     without pushing the card (and therefore the body) sideways. */
  .band { padding: 8px 12px; gap: 8px; flex-wrap: wrap; row-gap: 4px; }
  .band-label { flex: 1 1 100%; width: auto; }
  .band-bar { flex: 1 1 90px; }
  .band-count { flex: 0 0 46px; width: 46px; }
  .band-value { flex: 0 0 56px; width: 56px; }
  .band-note { flex: 0 0 auto; width: auto; text-align: right; }
  .band-stack { padding: 9px 12px; gap: 8px; }
  .band-note-wide { flex: 0 0 92px; width: 92px; font-size: 11px; }

  /* Charts stack full width; the viewBox does the scaling (~120px tall). */
  .chart-row { padding: 10px 12px; gap: 12px; }
  .chart { flex: 1 1 100%; }
}
