/* ==========================================================================
   MMG Fuel Tracker, Martin Group design system reskin
   Drop-in stylesheet layer. Plain hand-written CSS, no build step, no framework.

   How to use
   ----------
   1. Replace the existing :root token block with §1 below.
   2. Keep your existing component class names where they already match; where they
      do not, either rename in templates or alias: `.your-class { @ } ` is not a thing
      in plain CSS, so add your selector next to ours, e.g.
        .badge, .status-pill { ... }
   3. §12 is the kiosk block. It is a recolor only: no structural rules in it.
   4. Nothing here needs a webfont. System Helvetica/Arial stack, per brand.

   Accent rule: teal is the only accent. Red means action or damage
   (Erase, Delete permanently, Failed) and nothing else.
   ========================================================================== */

/* Border-box everywhere: percentage flex bases and width:100% controls must
   include their padding/border, or phone layouts (45% two-up tiles) overflow
   and wrap one-per-row (found on iPhone, 2026-08-21). */
*, *::before, *::after { box-sizing: border-box; }

/* ---------------------------------------------------------------- 1. TOKENS */
:root {
  /* Brand */
  --ft-teal: #17A38C;
  --ft-teal-hover: #128A76;
  --ft-teal-deep: #0E7C6B;          /* link tone, meets AA on white */
  --ft-teal-ink: #0A5C50;           /* link hover; text on teal tint (6.9:1, AA) */
  --ft-teal-tint: #E2F3EF;
  --ft-teal-tint-border: #B9E0D7;

  /* Dark chrome (sidebar, kiosk surfaces) */
  --ft-ink: #232B2A;
  --ft-ink-hover: #2E3836;
  --ft-ink-divider: #3A4442;
  --ft-ink-page: #191F1E;           /* kiosk page, one step under the card */
  --ft-ink-text: #B9C2BF;
  --ft-ink-text-strong: #E8ECEA;
  --ft-ink-muted: #7E8A86;
  --ft-ink-label: #6E7A76;

  /* Light surfaces */
  --ft-page: #F4F5F4;
  --ft-card: #FFFFFF;
  --ft-strip: #FAFBFA;              /* card caption strips, disabled fields */
  --ft-thead: #F1F3F2;
  --ft-zebra: #F7F8F8;
  --ft-row-hover: #F6FAF9;

  /* Borders */
  --ft-border: #DDE1DF;
  --ft-border-control: #C9CFCC;
  --ft-border-row: #EEF0EF;

  /* Text */
  --ft-text: #222927;
  --ft-text-2: #5A6461;
  --ft-text-muted: #6B7370;
  --ft-text-faint: #98A09D;
  --ft-text-zero: #C7CCCA;          /* literal zeros and em-dash placeholders */

  /* Status language: red action, amber caution, green good, gray neutral */
  --ft-red: #C0392B;
  --ft-red-tint: #FBEAE7;
  --ft-red-border: #E5C4BE;
  --ft-amber: #A8720A;
  --ft-amber-text: #8A6D1F;
  --ft-amber-tint: #FBF3D9;
  --ft-amber-border: #E8D89A;
  --ft-green: #1E6B34;
  --ft-green-tint: #E3F3E4;
  --ft-green-border: #B5DDB9;
  --ft-neutral: #4A5350;
  --ft-neutral-tint: #ECEEED;

  /* Type */
  --ft-font: Arial, 'Helvetica Neue', Helvetica, sans-serif; /* Arial first: dealer boxes carry broken Helvetica installs (BMW font pack) that render oblique */
  --ft-mono: 'SF Mono', Consolas, 'Courier New', monospace;
  --ft-2xs: 10px;  --ft-xs: 11px;  --ft-sm: 12px;  --ft-base: 13px;
  --ft-md: 14px;   --ft-lg: 16px;  --ft-xl: 19px;  --ft-2xl: 22px;  --ft-3xl: 28px;
  --ft-track-label: 0.5px;
  --ft-track-caps: 1px;
  --ft-track-wide: 2px;

  /* Spacing, radii, density */
  --ft-pad: 24px;                   /* desktop content padding */
  --ft-pad-narrow: 16px;
  --ft-gap: 14px;                   /* between cards and tiles */
  --ft-radius-sm: 3px;
  --ft-radius: 4px;
  --ft-radius-md: 6px;              /* standalone floating cards */
  --ft-radius-pill: 999px;
  --ft-row-h: 34px;
  --ft-row-h-admin: 36px;
  --ft-sidebar-w: 216px;

  /* Effects */
  --ft-shadow-card: 0 2px 10px rgba(0,0,0,0.06);
  --ft-shadow-float: 0 2px 14px rgba(0,0,0,0.14);
  --ft-focus: 0 0 0 2px var(--ft-teal-tint), 0 0 0 3px var(--ft-teal);
  --ft-transition: background-color 80ms linear, color 80ms linear, border-color 80ms linear;
}

/* ------------------------------------------------------------------ 2. BASE */
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ft-page);
  color: var(--ft-text);
  font-family: var(--ft-font);
  font-size: var(--ft-base);
  line-height: 1.5;
}
a { color: var(--ft-teal-deep); text-decoration: none; }
a:hover { color: var(--ft-teal-ink); text-decoration: underline; }
h1 { font-size: var(--ft-xl); font-weight: 700; margin: 0; letter-spacing: -0.1px; }
h2 { font-size: var(--ft-lg); font-weight: 700; margin: 0; }
.ft-mono { font-family: var(--ft-mono); }
.ft-num { font-variant-numeric: tabular-nums; text-align: right; }
.ft-zero, .ft-none { color: var(--ft-text-zero); }
.ft-muted { color: var(--ft-text-muted); }
.ft-meta { font-size: var(--ft-sm); color: var(--ft-text-muted); }
:focus-visible {
  outline: none;
  box-shadow: var(--ft-focus);
  border-radius: var(--ft-radius-sm);
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}

/* ------------------------------------------------- 3. ADMIN SHELL + SIDEBAR */
.ft-app { display: flex; min-height: 100vh; }
.ft-main { flex: 1; min-width: 0; }

.ft-sidebar {
  width: var(--ft-sidebar-w);
  flex: 0 0 var(--ft-sidebar-w);
  background: var(--ft-ink);
  display: flex;
  flex-direction: column;
}
/* White logo plate. The Martin logo is never placed on dark: the word "Group" is
   black. Inside dark chrome it sits on a white plate with a 3px teal rule under it,
   matching the CRM dashboard sidebar. */
.ft-brand {
  background: #FFFFFF;
  padding: 14px 14px 11px;
  border-bottom: 3px solid var(--ft-teal);
}
.ft-brand img { width: 130px; display: block; }
.ft-brand-caption {
  margin-top: 7px;
  font-size: var(--ft-2xs); letter-spacing: var(--ft-track-wide);
  text-transform: uppercase; color: var(--ft-text-2);
}
.ft-nav { padding: 10px 0; display: flex; flex-direction: column; }
.ft-nav-label {
  padding: 14px 14px 6px;
  font-size: var(--ft-2xs); letter-spacing: var(--ft-track-caps);
  text-transform: uppercase; color: var(--ft-ink-label);
}
.ft-nav a {
  padding: 8px 14px;
  font-size: var(--ft-base); color: var(--ft-ink-text);
  border-left: 3px solid transparent;
  transition: var(--ft-transition);
}
.ft-nav a:hover { background: var(--ft-ink-hover); color: var(--ft-ink-text-strong); text-decoration: none; }
.ft-nav a[aria-current="page"] {
  background: var(--ft-ink-hover);
  color: #fff; font-weight: 600;
  border-left-color: var(--ft-teal);
}
.ft-sidebar-foot {
  margin-top: auto;
  border-top: 1px solid var(--ft-ink-divider);
  padding: 12px 14px;
  font-size: var(--ft-sm); color: var(--ft-ink-text);
}
.ft-sidebar-foot .ft-scope { color: var(--ft-ink-muted); font-size: var(--ft-xs); }
/* Sign-out lives in the switcher panel's head pill (§13) — the rail foot no
   longer carries a logout form, so .ft-signout is gone with it. */

/* Hamburger button (docs/mobile-responsive-design-handoff.md §3). In the
   markup at every width, shown only under html.js-nav below 840px. Real
   <button>, pure-CSS icon, focus ring. */
.ft-nav-toggle {
  display: none;                 /* hidden until JS + narrow width (§5) */
  width: 44px; height: 40px; flex: 0 0 44px;
  align-items: center; justify-content: center;
  background: var(--ft-card);
  border: 1px solid var(--ft-border-control);
  border-radius: var(--ft-radius-sm); cursor: pointer;
}
.ft-nav-toggle-bars, .ft-nav-toggle-bars::before, .ft-nav-toggle-bars::after {
  display: block; width: 20px; height: 2px;
  background: var(--ft-text); border-radius: 1px;
}
.ft-nav-toggle-bars { position: relative; }
.ft-nav-toggle-bars::before, .ft-nav-toggle-bars::after { content: ""; position: absolute; left: 0; }
.ft-nav-toggle-bars::before { top: -6px; }
.ft-nav-toggle-bars::after  { top:  6px; }
.ft-nav-toggle:focus-visible { outline: 2px solid var(--ft-teal); outline-offset: 2px; }
.ft-sr {                        /* visually hidden, read by screen readers */
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* Below 900px the sidebar becomes a light sticky top band with chip nav
   (docs/mobile-responsive-design-handoff.md §4 — CRM house pattern). Between
   900 and 840 the full chip set stays visible; below 840 it collapses behind
   the hamburger, so the sticky band costs one short row on phones. Flex
   `order` lays out brand / button / identity / nav regardless of source. */
@media (max-width: 900px) {
  .ft-app { flex-direction: column; }
  .ft-sidebar {
    width: 100%; flex: 0 0 auto;
    position: sticky; top: 0; z-index: 20;
    background: var(--ft-card);              /* dark ink -> white band */
    border-bottom: 1px solid var(--ft-border);
    flex-direction: row; align-items: center; flex-wrap: wrap;
    gap: 8px; padding: 8px var(--ft-pad-narrow);
  }
  .ft-brand { order: 0; padding: 5px 8px; border-bottom: 3px solid var(--ft-teal); border-radius: var(--ft-radius-sm); }
  .ft-brand img { width: 92px; min-width: 80px; }
  .ft-brand-caption { display: none; }
  .ft-nav-toggle { order: 1; margin-left: auto; }
  /* identity flips from light-on-dark to dark-on-light */
  .ft-sidebar-foot {
    order: 2; margin: 0 0 0 auto; border: 0; padding: 0;
    font-size: var(--ft-xs); text-align: right; color: var(--ft-text);
  }
  .ft-sidebar-foot .ft-scope { display: inline; margin-right: 8px; color: var(--ft-text-muted); }
  .ft-nav { order: 3; width: 100%; flex-direction: row; flex-wrap: wrap; gap: 6px; padding: 0; }
  .ft-nav-label { display: none; }
  .ft-nav a {
    border: 1px solid var(--ft-border);
    border-left-width: 3px; border-left-color: transparent;
    border-radius: var(--ft-radius-sm);
    padding: 6px 10px; font-size: var(--ft-sm);
    color: var(--ft-text-muted);
    min-height: 34px; display: flex; align-items: center;
  }
  .ft-nav a:hover, .ft-nav a[aria-current="page"] {
    background: var(--ft-teal-tint); color: var(--ft-text);
    border-left-color: var(--ft-teal);       /* same accent as the desktop rail */
  }
  .ft-nav a[aria-current="page"] { font-weight: 600; }
}

/* Breakpoint 840px is mirrored in nav.js as (min-width: 841px) — move both
   together. Collapse rules are scoped under html.js-nav (stamped inline in
   <head> before first paint): with JS off the class never appears and the
   chip row above stays visible — nobody is stranded behind a dead button. */
@media (max-width: 840px) {
  html.js-nav .ft-sidebar .ft-nav-toggle { display: flex; }
  html.js-nav .ft-sidebar .ft-nav,
  html.js-nav .ft-sidebar .ft-sidebar-foot { display: none; }
  /* Open state: expands the band in place (pushes content down, no overlay),
     vertical list, 40px+ tap targets, scrolls if taller than the screen. */
  html.js-nav .ft-sidebar.is-nav-open .ft-nav {
    display: flex; flex-direction: column; flex-wrap: nowrap;
    gap: 4px; padding: 8px 2px 4px;
    max-height: calc(100vh - 160px); overflow-y: auto;
  }
  html.js-nav .ft-sidebar.is-nav-open .ft-nav a { min-height: 40px; padding: 10px 12px; }
  html.js-nav .ft-sidebar.is-nav-open .ft-sidebar-foot {
    display: block; order: 4; width: 100%; margin: 0;
    padding: 10px 2px 6px; border-top: 1px solid var(--ft-border-row);
    text-align: left;
  }
}

/* ------------------------------------------------- 3b. PHONE, ADMIN CONTENT
   The admin portal is desktop-first, but every page has to survive a phone.
   Wide tables (Reports, Audit, Users) stop being tables at 640px and become one
   card per record: same data, same order, label above value. Render the card list
   from the same row partial so the htmx swap keeps working. */
@media (max-width: 640px) {
  .ft-pagehead { flex-direction: column; gap: 10px; }
  .ft-pagehead-actions { margin-left: 0; width: 100%; }
  .ft-pagehead-actions .ft-btn { flex: 1 1 118px; padding: 11px 12px; font-size: var(--ft-md); }
  .ft-tiles .ft-tile { flex: 1 1 45%; min-width: 140px; }
  .ft-check { min-height: 44px; }
  .ft-form-actions { flex-direction: column; align-items: stretch; gap: 8px; }
  .ft-form-actions .ft-btn { width: 100%; padding: 13px 16px; font-size: 15px; }
  .ft-presets .ft-btn { border-radius: var(--ft-radius-pill); padding: 7px 14px; font-size: var(--ft-base); }
  .ft-table--wide { display: none; }
  .ft-reclist { display: flex; flex-direction: column; gap: 12px; }
  .ft-rec {
    background: var(--ft-card); border: 1px solid var(--ft-border);
    border-radius: var(--ft-radius); padding: 10px 12px;
  }
  .ft-rec-head { display: flex; align-items: center; gap: 8px; }
  .ft-rec-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 12px; margin-top: 10px; }
  .ft-rec-grid .ft-label { font-size: var(--ft-2xs); }
  .ft-rec-foot {
    display: flex; align-items: center; gap: 16px;
    border-top: 1px solid var(--ft-border-row); margin-top: 10px; padding-top: 8px;
    font-size: var(--ft-base);
  }
  .ft-rec-foot .ft-linkbtn { margin-left: auto; }
  /* Sideways-scrolling tables pin their first column while the rest scrolls
     under it (handoff doc §6e). Each row state needs its own opaque
     background — the base td is transparent. */
  .ft-scroll-x .ft-table th:first-child,
  .ft-scroll-x .ft-table td:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--ft-card);
    box-shadow: 1px 0 0 var(--ft-border-row);
  }
  .ft-scroll-x .ft-table thead th:first-child { background: var(--ft-thead); }
  .ft-scroll-x .ft-table tbody tr:nth-child(even) td:first-child { background: var(--ft-zebra); }
  .ft-scroll-x .ft-table--unstriped tbody tr:nth-child(even) td:first-child { background: var(--ft-card); }
  .ft-scroll-x .ft-table tbody tr:hover td:first-child { background: var(--ft-row-hover); }
}
@media (min-width: 641px) { .ft-reclist { display: none; } }

/* ------------------------------------------------------------ 4. PAGE HEADER */
.ft-pagehead {
  background: var(--ft-card);
  border-bottom: 1px solid var(--ft-border);
  padding: 16px var(--ft-pad) 14px;
  display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap;
}
.ft-pagehead-actions { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ft-pagehead .ft-meta { margin-top: 3px; }              /* "Data as of Aug 21, 4:17 PM CT" */
.ft-content { padding: 18px var(--ft-pad) var(--ft-pad); display: flex; flex-direction: column; gap: var(--ft-gap); }
.ft-content--narrow { max-width: 620px; }               /* forms: user, store, settings */
@media (max-width: 640px) {
  .ft-pagehead, .ft-content { padding-left: var(--ft-pad-narrow); padding-right: var(--ft-pad-narrow); }
}

/* -------------------------------------------------------- 5. CARDS + TILES */
.ft-card {
  background: var(--ft-card);
  border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius);
}
.ft-card--float { border-radius: var(--ft-radius-md); box-shadow: var(--ft-shadow-card); }
.ft-card-strip {
  background: var(--ft-strip);
  border-bottom: 1px solid var(--ft-border);
  padding: 8px 12px;
  font-size: var(--ft-xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  color: var(--ft-text-muted);
  display: flex; align-items: center; gap: 10px;
}
.ft-card-strip .ft-strip-note { margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 400; }
.ft-card-body { padding: 12px; }
.ft-card-foot {
  border-top: 1px solid var(--ft-border-row);
  padding: 8px 12px;
  font-size: var(--ft-sm); color: var(--ft-text-muted);
}

.ft-tiles { display: flex; flex-wrap: wrap; gap: var(--ft-gap); }
.ft-tile {
  background: var(--ft-card); border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius);
  padding: 12px 16px; min-width: 168px; flex: 1 1 168px;
}
.ft-tile-label {
  font-size: var(--ft-xs); font-weight: 700; letter-spacing: var(--ft-track-caps);
  text-transform: uppercase; color: var(--ft-text-muted);
}
.ft-tile-value {
  margin-top: 4px;
  font-size: var(--ft-3xl); font-weight: 700; line-height: 1.1;
  font-variant-numeric: tabular-nums;
}
.ft-tile-value--zero { color: var(--ft-text-zero); }
.ft-tile-value--action { color: var(--ft-red); }        /* needs attention > 0, configurable */
.ft-tile-sub { margin-top: 2px; font-size: var(--ft-sm); color: var(--ft-text-muted); }

/* ----------------------------------------------------------------- 6. TABLES
   Three distinct values are required: header, base row, stripe. Stripe any
   table over about 4 rows. Identity columns never wrap and never bare-truncate. */
.ft-table { width: 100%; border-collapse: collapse; font-size: var(--ft-base); }
.ft-table thead th {
  background: var(--ft-thead);
  border-bottom: 1px solid var(--ft-border);
  padding: 7px 10px;
  text-align: left;
  font-size: var(--ft-xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  color: var(--ft-text-muted); white-space: nowrap;
}
.ft-table tbody td {
  background: var(--ft-card);
  border-bottom: 1px solid var(--ft-border-row);
  padding: 7px 10px;
  min-height: var(--ft-row-h);
  vertical-align: middle;
}
.ft-table tbody tr:nth-child(even) td { background: var(--ft-zebra); }
.ft-table tbody tr:hover td { background: var(--ft-row-hover); }
.ft-table tbody tr.is-inactive td { color: var(--ft-text-faint); }
.ft-table .ft-num, .ft-table th.ft-num { text-align: right; font-variant-numeric: tabular-nums; }
.ft-table .ft-identity { white-space: nowrap; font-weight: 600; }
.ft-table .ft-identity--long { font-size: var(--ft-sm); }   /* step down, never wrap */
.ft-table .ft-cell-mono { font-family: var(--ft-mono); font-size: var(--ft-sm); white-space: nowrap; }
.ft-table-empty {
  padding: 28px 12px; text-align: center; color: var(--ft-text-muted); font-size: var(--ft-base);
}
.ft-table-empty b { display: block; color: var(--ft-text); font-size: var(--ft-md); margin-bottom: 2px; }
/* Totals footer (Reports) and the notes above a filtered list. */
.ft-table tfoot td {
  padding: 7px 10px; border-top: 2px solid var(--ft-border);
  background: var(--ft-strip); font-variant-numeric: tabular-nums;
}
.ft-sorted::after { content: " ▾"; color: var(--ft-text-faint); }
@media (max-width: 640px) {
  .ft-table { font-size: var(--ft-sm); }
  .ft-table thead th, .ft-table tbody td, .ft-table tfoot td { padding: 6px 8px; }
}
.ft-report-notes { display: flex; flex-direction: column; gap: 8px; padding: 12px 12px 0; }
.ft-report-totals-gaps { color: var(--ft-text-muted); font-size: var(--ft-sm); font-weight: 400; margin-top: 2px; }
.ft-rec--totals { background: var(--ft-strip); }

/* Audit disclosure row */
.ft-disclose summary { cursor: pointer; color: var(--ft-teal-deep); font-size: var(--ft-sm); }
.ft-disclose summary::marker { color: var(--ft-text-faint); }
.ft-diff { display: flex; gap: 10px; margin-top: 6px; flex-wrap: wrap; }
.ft-diff pre {
  margin: 0; flex: 1 1 220px; max-height: 160px; overflow: auto;
  background: var(--ft-strip); border: 1px solid var(--ft-border-row);
  border-radius: var(--ft-radius-sm); padding: 8px;
  font-family: var(--ft-mono); font-size: var(--ft-sm); color: var(--ft-text-2);
}

/* ------------------------------------------------------------- 7. FILTER BAR
   Must stay a separate region from the results table: htmx swaps rows only. */
.ft-filters {
  background: var(--ft-card);
  border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius);
  padding: 12px;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px 12px; align-items: end;
}
.ft-filters .ft-filter-wide { grid-column: span 2; }
/* Utilization range card: preset / dates / Run on one row (collapses at 560px
   with the rest — keep this ABOVE that media rule so the collapse wins). */
.ft-filters--util { grid-template-columns: auto 1fr auto; max-width: 640px; }
.ft-filters-foot {
  grid-column: 1 / -1;
  display: flex; align-items: center; gap: 14px;
  border-top: 1px solid var(--ft-border-row); padding-top: 10px;
  font-size: var(--ft-sm); color: var(--ft-text-muted);
}
.ft-filters-foot .ft-clear { margin-left: auto; }
@media (max-width: 560px) { .ft-filters { grid-template-columns: 1fr; } }

/* ------------------------------------------------------- 8. FORMS + CONTROLS */
.ft-field { display: flex; flex-direction: column; gap: 5px; }
.ft-label {
  font-size: var(--ft-xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  color: var(--ft-text-muted);
}
.ft-hint { font-size: var(--ft-sm); color: var(--ft-text-muted); }
.ft-error-text { font-size: var(--ft-sm); color: var(--ft-red); }
.ft-input, .ft-select, .ft-textarea {
  font-family: var(--ft-font);
  font-size: var(--ft-base);
  color: var(--ft-text);
  background: var(--ft-card);
  border: 1px solid var(--ft-border-control);
  border-radius: var(--ft-radius);
  padding: 7px 10px;
  width: 100%; box-sizing: border-box;
}
.ft-input:hover, .ft-select:hover { border-color: #B4BCB8; }
.ft-input:disabled, .ft-select:disabled, .ft-textarea:disabled {
  background: var(--ft-strip); color: var(--ft-text-muted);
}
.ft-input.is-error { border-color: var(--ft-red); }
.ft-input--mono { font-family: var(--ft-mono); }
.ft-input--pin { font-family: var(--ft-mono); font-size: var(--ft-lg); letter-spacing: 6px; max-width: 150px; }
.ft-textarea { min-height: 72px; resize: vertical; }
.ft-select { appearance: none; padding-right: 26px;
  background-image: none; }                              /* glyph ▾ supplied in markup */
@media (max-width: 640px) {
  /* iOS Safari zooms any focused field under 16px. Non-negotiable. */
  .ft-input, .ft-select, .ft-textarea { font-size: 16px; }
}

.ft-fieldset {
  border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius);
  padding: 12px; margin: 0;
  background: var(--ft-card);
}
.ft-fieldset > legend {
  padding: 0 6px; margin-left: -6px;
  font-size: var(--ft-xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  color: var(--ft-text-muted);
}
.ft-fieldset--danger { border-color: var(--ft-red-border); background: var(--ft-red-tint); }
.ft-fieldset--danger > legend { color: var(--ft-red); }
.ft-checks { display: grid; gap: 6px; }
.ft-checks--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px 14px; }
@media (max-width: 560px) { .ft-checks--2col { grid-template-columns: 1fr; } }
.ft-check { display: flex; align-items: center; gap: 8px; font-size: var(--ft-base); min-height: 24px; }
.ft-check input { accent-color: var(--ft-teal); width: 15px; height: 15px; }
.ft-presets { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.ft-presets-label { font-size: var(--ft-sm); color: var(--ft-text-muted); }
.ft-form-actions {
  display: flex; align-items: center; gap: 12px;
  padding-top: 4px;
}

/* --------------------------------------------------------------- 9. BUTTONS */
.ft-btn {
  font-family: var(--ft-font); font-size: var(--ft-base); font-weight: 600;
  padding: 7px 14px; border-radius: var(--ft-radius);
  border: 1px solid transparent; background: none; color: var(--ft-text);
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  cursor: pointer; white-space: nowrap; transition: var(--ft-transition);
}
.ft-btn--primary { background: var(--ft-teal); color: #fff; }
.ft-btn--primary:hover { background: var(--ft-teal-hover); }
.ft-btn--secondary { background: var(--ft-card); color: var(--ft-text-2); border-color: var(--ft-border-control); }
.ft-btn--secondary:hover { background: var(--ft-strip); border-color: var(--ft-teal); }
.ft-btn--ghost { color: var(--ft-teal-deep); }
.ft-btn--ghost:hover { background: var(--ft-teal-tint); }
.ft-btn--danger { color: var(--ft-red); border-color: var(--ft-red-border); background: var(--ft-card); }
.ft-btn--danger:hover { background: var(--ft-red); color: #fff; border-color: var(--ft-red); }
.ft-btn--sm { font-size: var(--ft-sm); padding: 5px 10px; }
.ft-btn--big { font-size: 17px; padding: 14px 18px; width: 100%; }
.ft-btn[disabled], .ft-btn[aria-disabled="true"] { opacity: 0.5; cursor: default; }
.ft-linkbtn {                                   /* Erase, in-table destructive */
  background: none; border: 0; padding: 0;
  font: inherit; font-size: var(--ft-sm); color: var(--ft-red);
  cursor: pointer; text-decoration: underline;
}

/* ------------------------------------------------- 10. BADGES, CHIPS, PILLS */
.ft-badge {
  font-size: var(--ft-2xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  padding: 2px 6px; border-radius: var(--ft-radius-sm);
  border: 1px solid var(--ft-border-control);
  background: var(--ft-neutral-tint); color: var(--ft-neutral);
  display: inline-block; white-space: nowrap; vertical-align: middle;
}
.ft-badge--processing { background: var(--ft-neutral-tint); color: var(--ft-neutral); border-color: var(--ft-border-control); }
.ft-badge--processed  { background: var(--ft-green-tint);   color: var(--ft-green);   border-color: var(--ft-green-border); }
.ft-badge--review     { background: var(--ft-amber-tint);   color: var(--ft-amber-text); border-color: var(--ft-amber-border); }
.ft-badge--failed     { background: var(--ft-red-tint);     color: var(--ft-red);     border-color: var(--ft-red-border); }
.ft-badge--teal       { background: var(--ft-teal-tint);    color: var(--ft-teal-deep); border-color: var(--ft-teal-tint-border); }
a.ft-badge--review:hover, a.ft-badge--failed:hover { text-decoration: underline; }

/* Store-code plate. Signature component, kept: monospace tag with a notched
   left edge (dealer plate motif). Recolored from red/black to ink. */
.ft-plate {
  font-family: var(--ft-mono); font-size: var(--ft-2xs); font-weight: 700;
  letter-spacing: 0.5px; text-transform: uppercase;
  background: var(--ft-ink); color: var(--ft-ink-text-strong);
  padding: 2px 7px 2px 11px;
  display: inline-block; white-space: nowrap;
  border-radius: 2px;
  clip-path: polygon(6px 0, 100% 0, 100% 100%, 6px 100%, 0 50%);
}
.ft-plate--all { background: var(--ft-teal); color: #fff; }
.ft-plate--muted { background: var(--ft-neutral-tint); color: var(--ft-text-2); }

/* Permission tag, "deactivated" pill */
.ft-tag {
  font-size: var(--ft-sm);
  border: 1px solid var(--ft-border);
  background: var(--ft-thead); color: var(--ft-text);
  border-radius: var(--ft-radius-pill);
  padding: 2px 9px; display: inline-block; white-space: nowrap;
}
.ft-tag--muted { color: var(--ft-text-faint); background: var(--ft-strip); }
.ft-tag--teal { background: var(--ft-teal-tint); border-color: var(--ft-teal-tint-border); color: var(--ft-teal-deep); font-weight: 600; }
.ft-taglist { display: flex; flex-wrap: wrap; gap: 4px; }
/* "N open flags" beside a receipt on Card reconciliation (2026-10-19): a link
   into the Flags tab, red like the flag it points at. */
a.ft-tag--flag { background: var(--ft-red-tint); border-color: var(--ft-red-border); color: var(--ft-red); font-weight: 600; text-decoration: none; }
a.ft-tag--flag:hover { text-decoration: underline; }

/* Low-confidence field marker on the review form */
.ft-lowconf {
  font-size: var(--ft-2xs); font-weight: 700; letter-spacing: var(--ft-track-label);
  text-transform: uppercase; color: var(--ft-amber-text);
  background: var(--ft-amber-tint); border: 1px solid var(--ft-amber-border);
  border-radius: var(--ft-radius-sm); padding: 1px 5px; margin-left: 6px;
}

/* --------------------------------------------------------------- 11. BANNERS */
.ft-banner {
  border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius);
  padding: 10px 12px;
  font-size: var(--ft-base);
  background: var(--ft-strip);
  display: flex; gap: 10px; align-items: flex-start;
}
.ft-banner b { font-weight: 700; }
.ft-banner--ok    { background: var(--ft-green-tint); border-color: var(--ft-green-border); color: var(--ft-green); }
.ft-banner--warn  { background: var(--ft-amber-tint); border-color: var(--ft-amber-border); color: var(--ft-amber-text); }
.ft-banner--error { background: var(--ft-red-tint);   border-color: var(--ft-red-border);   color: var(--ft-red); }
.ft-banner--info  { background: var(--ft-teal-tint);  border-color: var(--ft-teal-tint-border); color: var(--ft-teal-deep); }
.ft-banner ul { margin: 4px 0 0; padding-left: 18px; }

/* Photo modal (reports) */
.ft-scrim {
  position: fixed; inset: 0; background: rgba(25,31,30,0.62);
  display: flex; align-items: center; justify-content: center; padding: 24px; z-index: 60;
}
.ft-scrim[hidden] { display: none; }
.ft-modal {
  background: var(--ft-card); border-radius: var(--ft-radius-md);
  box-shadow: var(--ft-shadow-float);
  max-width: 560px; width: 100%; max-height: 88vh; display: flex; flex-direction: column;
}
.ft-modal-head {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px; border-bottom: 1px solid var(--ft-border);
}
.ft-modal-head .ft-modal-title { font-weight: 700; font-size: var(--ft-md); }
.ft-modal-close {
  margin-left: auto; background: none; border: 0; cursor: pointer;
  font-size: var(--ft-lg); color: var(--ft-text-muted); line-height: 1;
}
.ft-modal-body { padding: 12px; overflow: auto; background: var(--ft-strip); }

/* ------------------------------------------------------------- 12. KIOSK
   RECOLOR ONLY. No structural changes: same cards, same order, same controls.
   Dark surface retained (it is read on a phone in a service drive at night)
   and mapped onto the system's ink chrome. */
.kiosk {
  background: var(--ft-ink-page);
  color: var(--ft-ink-text-strong);
  min-height: 100vh;
  display: flex; align-items: center; justify-content: center;
  padding: max(18px, env(safe-area-inset-top)) 18px max(18px, env(safe-area-inset-bottom));
  font-family: var(--ft-font);
}
.kiosk-card {
  width: 100%; max-width: 420px;
  background: var(--ft-ink);
  border: 1px solid var(--ft-ink-divider);
  border-top: 3px solid var(--ft-teal);          /* was 4px brand red */
  border-radius: var(--ft-radius-lg, 8px);
  padding: 18px;
}
.kiosk-card--wide { max-width: 560px; }
.kiosk-title { font-size: var(--ft-2xl); font-weight: 700; margin: 0 0 12px; }
.kiosk-plate-white {                             /* white logo callout on the dark card */
  background: #FFFFFF; border-radius: var(--ft-radius);
  border-bottom: 3px solid var(--ft-teal);
  padding: 12px 16px 10px;
  display: flex; flex-direction: column; align-items: center;
}
.kiosk-plate-white img { width: 180px; max-width: 100%; display: block; }
.kiosk-plate-caption {
  margin-top: 7px;
  font-size: var(--ft-2xs); letter-spacing: var(--ft-track-wide);
  text-transform: uppercase; color: var(--ft-text-2);
}
.kiosk-word {                                    /* fallback only, prefer the plate */
  font-size: 20px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase;
  color: var(--ft-ink-text-strong); text-align: center;
}
.kiosk-caption {
  font-size: var(--ft-2xs); letter-spacing: var(--ft-track-wide); text-transform: uppercase;
  color: var(--ft-ink-muted); text-align: center; margin-top: 4px;
}
.kiosk-rule { height: 3px; background: var(--ft-teal); margin: 12px 0 16px; }
.kiosk-label {
  font-size: var(--ft-xs); font-weight: 700; letter-spacing: var(--ft-track-label);
  text-transform: uppercase; color: var(--ft-ink-muted);
}
.kiosk-hint { font-size: var(--ft-sm); color: var(--ft-ink-muted); }
.kiosk-input, .kiosk-select {
  width: 100%; box-sizing: border-box;
  font-family: var(--ft-font); font-size: 16px;   /* never below 16px on phone */
  background: #1B2221; color: var(--ft-ink-text-strong);
  border: 1px solid var(--ft-ink-divider); border-radius: var(--ft-radius);
  padding: 11px 12px;
}
.kiosk-input::placeholder { color: var(--ft-ink-label); }
.kiosk-input:focus-visible, .kiosk-select:focus-visible {
  border-color: var(--ft-teal); box-shadow: 0 0 0 3px rgba(23,163,140,0.35);
}
.kiosk-pin {
  font-family: var(--ft-mono); font-size: 30px; letter-spacing: 14px;
  text-align: center; padding: 14px 12px;
}
/* Large CTA: teal fill with ink text. White on teal is only 2.9:1; ink on teal
   is 5.4:1, so the primary action stays legible in sunlight. Documented
   deviation from the system's white-on-teal button. */
.kiosk-btn {
  width: 100%; box-sizing: border-box;
  font-family: var(--ft-font); font-size: 17px; font-weight: 700;
  padding: 15px 16px; border-radius: var(--ft-radius);
  border: 1px solid transparent; cursor: pointer;
  transition: var(--ft-transition);
}
.kiosk-btn--primary { background: var(--ft-teal); color: #12201D; }
.kiosk-btn--primary:hover { background: #1FB79D; }
.kiosk-btn--secondary { background: transparent; color: var(--ft-ink-text-strong); border-color: var(--ft-ink-text); }
.kiosk-btn--secondary:hover { background: var(--ft-ink-hover); }
.kiosk-btn--ghost { background: none; border: 0; color: var(--ft-ink-muted); font-weight: 600; font-size: var(--ft-md); }
/* Accounting / Admin sign-in on the PIN page: red and nearly as big as
   Continue, because controllers could not find the old ghost link
   (Jeremy 2026-10-22). White on --ft-red is 5.4:1. */
.kiosk-btn--admin {
  display: block; width: 92%; margin: 0 auto;
  background: var(--ft-red); color: #fff;
  font-size: 15px; padding: 12px 16px;
  text-align: center; text-decoration: none;
}
.kiosk-btn--admin:hover { background: #A93226; color: #fff; }
.kiosk-banner {
  border-radius: var(--ft-radius); padding: 10px 12px; font-size: var(--ft-base);
  border: 1px solid; margin-bottom: 12px;
}
.kiosk-banner--ok    { background: rgba(30,107,52,0.18);  border-color: #2F7A46; color: #BFE6C8; }
.kiosk-banner--warn  { background: rgba(168,114,10,0.18); border-color: #8A6D1F; color: #F0DFA8; }
.kiosk-banner--error { background: rgba(192,57,43,0.18);  border-color: #A4453A; color: #F3C8C1; }
/* Kiosk badges: same four colorways, tinted for the dark surface. */
.kiosk-badge {
  font-size: var(--ft-2xs); font-weight: 700; letter-spacing: var(--ft-track-label);
  text-transform: uppercase; padding: 2px 6px; border-radius: var(--ft-radius-sm);
  border: 1px solid; white-space: nowrap;
}
.kiosk-badge--processing { background: rgba(185,194,191,0.14); border-color: #59635F; color: #C5CDCA; }
.kiosk-badge--processed  { background: rgba(30,107,52,0.20);  border-color: #2F7A46; color: #9FD9AE; }
.kiosk-badge--review     { background: rgba(168,114,10,0.20); border-color: #8A6D1F; color: #EBD08A; }
.kiosk-badge--failed     { background: rgba(192,57,43,0.20);  border-color: #A4453A; color: #EFB4AA; }
.kiosk-plate {
  font-family: var(--ft-mono); font-size: var(--ft-2xs); font-weight: 700;
  background: #101614; color: var(--ft-ink-text-strong);
  padding: 2px 7px 2px 11px; border-radius: 2px;
  clip-path: polygon(6px 0, 100% 0, 100% 100%, 6px 100%, 0 50%);
}
.kiosk-row {                                     /* receipts list: card per receipt */
  background: #1B2221; border: 1px solid var(--ft-ink-divider);
  border-radius: var(--ft-radius); padding: 10px 12px;
  display: flex; flex-direction: column; gap: 4px;
}
.kiosk-row:hover { background: #202826; }
.kiosk-row-sub { font-size: var(--ft-sm); color: var(--ft-ink-muted); }
.kiosk-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; }
@media (max-width: 420px) { .kiosk-grid { grid-template-columns: 1fr; } }

/* ==========================================================================
   13. APP ADAPTATIONS (added at intake, 2026-08-21)
   Everything below adapts the packet stylesheet to this app's markup: global
   [hidden], select glyph wrapper, kiosk shell mapping onto body.kiosk, the
   add-to-home-screen banner, capture preview, and small layout helpers the
   templates need. No token or component redefinitions.
   ========================================================================== */
[hidden] { display: none !important; }   /* author display rules never defeat the attribute */

/* Select wrapper: supplies the ▾ glyph the packet expects in markup, once. */
.ft-selectwrap { position: relative; display: block; }
.ft-selectwrap::after {
  content: "▾"; position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  color: var(--ft-text-faint); pointer-events: none; font-size: var(--ft-sm);
}
.kiosk .ft-selectwrap::after { color: var(--ft-ink-muted); }

/* Layout helpers */
.ft-cell-sub { font-size: var(--ft-sm); color: var(--ft-text-muted); font-weight: 400; }
.ft-field-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.ft-datepair { display: flex; align-items: center; gap: 8px; }
.ft-stack { display: flex; flex-direction: column; gap: 14px; }
.ft-scroll-x { overflow-x: auto; }
/* A table that scrolls sideways must not also wrap its cells into tall rows. */
.ft-scroll-x .ft-table th, .ft-scroll-x .ft-table td { white-space: nowrap; }
.ft-actions-inline { display: inline; }
.ft-center-page {                          /* login card page, error pages */
  min-height: 100vh; display: flex; align-items: center; justify-content: center;
  padding: 24px; background: var(--ft-page);
}
.ft-login-card { width: 100%; max-width: 420px; padding: 22px; text-align: center; }
.ft-login-card .ft-brand-plate {
  display: inline-flex; flex-direction: column; align-items: center;
  border-bottom: 3px solid var(--ft-teal); padding-bottom: 10px; margin-bottom: 16px;
}
.ft-login-card .ft-brand-plate img { width: 150px; }
.ft-errorblock { max-width: 420px; margin: 0 auto; text-align: center; }
.ft-errorblock h1 { font-size: var(--ft-2xl); }
.ft-errorblock p { color: var(--ft-text-muted); }

/* Sortable/inactive helpers already covered; audit timestamp column */
.ft-col-when { width: 170px; }

/* --------------------------------------------------------------- KIOSK SHELL
   The app keeps body.kiosk + main.kiosk-shell (v1 structure); map the packet's
   .kiosk rules onto that pair. */
body.kiosk {
  margin: 0;
  background: var(--ft-ink-page); color: var(--ft-ink-text-strong);
  font-family: var(--ft-font);
}
.kiosk-shell {
  min-height: 100dvh;
  display: flex; align-items: center; justify-content: center; flex-direction: column;
  padding: max(18px, env(safe-area-inset-top)) 18px max(18px, env(safe-area-inset-bottom));
}
.kiosk-stack { display: flex; flex-direction: column; gap: 12px; }
.kiosk-form-actions { display: flex; gap: 10px; flex-wrap: wrap; }
.kiosk-form-actions .kiosk-btn { flex: 1 1 130px; width: auto; }
.kiosk-back { display: block; text-align: center; margin-top: 14px; }
.kiosk-signout { text-align: center; margin-top: 14px; }
.kiosk-hub-actions { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.kiosk-welcome { font-size: var(--ft-lg); margin: 0 0 4px; }
.kiosk-meta { font-size: var(--ft-sm); color: var(--ft-ink-muted); margin: 2px 0 12px; }
.kiosk-rows { display: grid; gap: 8px; margin: 12px 0; }
a.kiosk-row { text-decoration: none; color: inherit; }
.kiosk-row-main { display: flex; align-items: center; gap: 8px; }
.kiosk-row-main b { font-size: var(--ft-md); }
.kiosk-row-main .kiosk-badge { margin-left: auto; }
.kiosk-filters { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.kiosk-filters .ft-selectwrap { flex: 1 1 110px; }
.kiosk-filters .kiosk-input[type="search"] { flex: 2 1 140px; width: auto; }
.kiosk-photo summary { cursor: pointer; color: var(--ft-ink-text); font-weight: 600; }
.kiosk-photo img {
  max-width: 100%; border-radius: var(--ft-radius); margin-top: 10px;
  border: 1px solid var(--ft-ink-divider); background: #fff;
}
.kiosk-grid label, .kiosk-stack > label { display: flex; flex-direction: column; gap: 5px; }
.photo-preview { max-height: 220px; max-width: 100%; border-radius: var(--ft-radius); }
.kiosk-store-line { margin: 0; font-size: var(--ft-md); display: flex; align-items: center; gap: 8px; }

/* Add-to-home-screen banner (kiosk PIN screen), ink theme */
.a2hs {
  position: fixed; left: 12px; right: 12px; bottom: max(12px, env(safe-area-inset-bottom));
  background: var(--ft-ink); border: 1px solid var(--ft-ink-divider);
  border-left: 3px solid var(--ft-teal); border-radius: var(--ft-radius-md);
  box-shadow: var(--ft-shadow-float);
  padding: 10px 12px; display: flex; align-items: center; gap: 10px;
  font-size: var(--ft-base); color: var(--ft-ink-text); z-index: 50;
}
.a2hs img { border-radius: 7px; }
.a2hs .kiosk-btn { width: auto; padding: 8px 12px; font-size: var(--ft-base); }
.a2hs-close { background: none; border: 0; color: var(--ft-ink-muted); font-size: var(--ft-lg); cursor: pointer; }

/* Short tables (Stores, 4 rows today) skip the stripe per the table rules. */
.ft-table--unstriped tbody tr:nth-child(even) td { background: var(--ft-card); }
.ft-table--unstriped tbody tr:hover td { background: var(--ft-row-hover); }

/* Kiosk selects: suppress the native arrow so the wrapper's single glyph shows. */
.kiosk-select { appearance: none; padding-right: 26px; }

/* Buttons size border-box so width:100% variants stay inside their card. */
.ft-btn { box-sizing: border-box; }

/* --------------------------------------------- 13. APP SWITCHER (nine dots)
   Estate-wide chrome. Spec: docs/handoffs/switcher-canonical.md — every box,
   colour and behaviour here is a literal from that file, expressed through this
   app's tokens where a token already carries the same value.

   Two mounts, exactly one visible at any width (§2 of the spec):
     .switcher--foot  desktop rail foot, panel opens UPWARD, dark-ink dots
     .switcher--band  <=900px top band, panel opens DOWNWARD right-anchored,
                      light dots; a direct child of .ft-sidebar so it is never
                      hidden behind the hamburger.
   The <details> element IS the position:relative wrapper, and it sits outside
   any overflow scroller — a clipped panel bleeds the page through its tiles.
   ------------------------------------------------------------------------- */

/* Rail pinned to the viewport so the brand plate and the foot (identity + dots)
   never scroll away on a long page; .ft-nav is the internal scroller. */
.ft-sidebar {
  position: sticky; top: 0;
  height: 100vh;
  height: 100dvh;
  /* Sticky makes the rail its own stacking context; without a z-index it paints
     beneath the main pane's sticky first-column cells (z 1), so the switcher
     popover showed table plates through it (Jeremy 2026-09-05). Above content,
     below the modal overlay (60). */
  z-index: 30;
}
.ft-nav { flex: 1; min-height: 0; overflow-y: auto; }

/* Foot becomes ONE row: dots hard against the rail's left edge, identity beside
   them. Divider (border-top) stays from §3. */
.ft-sidebar-foot {
  display: flex; align-items: center; gap: 8px;
  padding: 12px 10px 12px 8px;
}
.ft-identity { min-width: 0; flex: 1; }
.ft-identity-name,
.ft-identity-email { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ft-identity-name { font-weight: 600; color: var(--ft-ink-text-strong); }
.ft-identity-email { margin-top: 2px; font-size: var(--ft-sm); color: var(--ft-ink-muted); }

/* -- trigger -------------------------------------------------------------- */
.switcher { position: relative; flex: none; }
.switcher summary { list-style: none; cursor: pointer; }
.switcher summary::-webkit-details-marker { display: none; }
.switcher-trigger {
  display: flex; align-items: center; justify-content: center;
  padding: 6px;
  border: 1px solid transparent;
  border-radius: var(--ft-radius);
  background: none;
  transition: var(--ft-transition);
}
.switcher-glyph { display: grid; grid-template-columns: repeat(3, 3px); gap: 3px; }
.switcher-glyph span {
  width: 3px; height: 3px;
  border-radius: var(--ft-radius-pill);
  background: currentColor;         /* one colour change recolours all nine */
}
/* Dark ink rail. Rest = the rail's own nav-text weight, never brand teal. */
.switcher--foot .switcher-trigger { color: var(--ft-ink-text); }
.switcher--foot .switcher-trigger:hover,
.switcher--foot[open] .switcher-trigger {
  background: var(--ft-ink-hover); color: var(--ft-ink-text-strong);
}
/* Light band. */
.switcher--band .switcher-trigger { color: var(--ft-text-muted); }
.switcher--band .switcher-trigger:hover,
.switcher--band[open] .switcher-trigger {
  background: var(--ft-row-hover); color: var(--ft-text);
}

/* -- panel ---------------------------------------------------------------- */
.switcher-panel {
  position: absolute;
  width: 268px; padding: 10px;
  background: var(--ft-card);        /* opaque, always */
  border: 1px solid var(--ft-border);
  border-radius: var(--ft-radius-md);
  box-shadow: var(--ft-shadow-float);
  z-index: 40;
  text-align: left;
  line-height: 1.5;
}
.switcher--foot .switcher-panel { bottom: calc(100% + 6px); left: 0; }
.switcher--band .switcher-panel { top: calc(100% + 6px); right: 0; max-width: calc(100vw - 28px); }

/* -- head row: "Switch Sites" + the one sign-out affordance --------------- */
.switcher-head { display: flex; align-items: center; gap: 8px; padding: 0 6px 8px; }
.switcher-head-label {
  min-width: 0; flex: 1;
  font-size: var(--ft-2xs); text-transform: uppercase;
  letter-spacing: var(--ft-track-caps); color: var(--ft-text-muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.switcher-signout { flex: none; display: inline-flex; margin: 0; }
.switcher-signout-btn {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  border: 1px solid var(--ft-teal);
  border-radius: var(--ft-radius-pill);
  background: var(--ft-teal); color: #FFFFFF;
  font-family: inherit; font-size: var(--ft-2xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); line-height: 1.5;
  text-transform: uppercase; white-space: nowrap;
  cursor: pointer;
  transition: var(--ft-transition);
}
.switcher-signout-btn:hover {
  background: var(--ft-teal-deep); border-color: var(--ft-teal-deep); color: #FFFFFF;
}

/* -- tiles ---------------------------------------------------------------- */
.switcher-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.switcher-tile {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 4px;
  border: 1px solid transparent;
  border-radius: var(--ft-radius);
  font-size: var(--ft-xs); text-align: center;
  transition: var(--ft-transition);
}
/* a.* / :hover carry the underline + link-colour kill: the global `a` rules
   would otherwise bleed teal text and an underline into every tile. */
a.switcher-tile { color: var(--ft-text-2); text-decoration: none; }
a.switcher-tile:hover {
  background: var(--ft-row-hover);
  border-color: var(--ft-teal-tint-border);
  color: var(--ft-text);
  text-decoration: none;
}
a.switcher-tile:hover .switcher-icon { color: var(--ft-teal-deep); }
.switcher-tile--current {          /* a <div>: nothing to click, nothing to tab to */
  background: var(--ft-teal-tint);
  border-color: var(--ft-teal-tint-border);
  color: var(--ft-teal-deep);
  font-weight: 600; cursor: default;
}
.switcher-tile--current .switcher-icon { color: var(--ft-teal-deep); }

/* -- groups (spec §5b) ----------------------------------------------------
   A group tile is a <button> that drills the panel into its members. Undo the
   UA button chrome; keep §5's 11px — never the `font` shorthand, which here
   would out-specify .switcher-tile and reset the size. */
button.switcher-tile {
  width: 100%; margin: 0;
  background: none;
  color: var(--ft-text-2);
  font-family: inherit; font-weight: inherit; line-height: 1.5;
  cursor: pointer;
}
/* Holds the current app: the current-tile tint, but still a live button. */
button.switcher-tile--has-current {
  background: var(--ft-teal-tint);
  border-color: var(--ft-teal-tint-border);
  color: var(--ft-teal-deep);
  font-weight: 600;
}
button.switcher-tile--has-current .switcher-icon { color: var(--ft-teal-deep); }
/* Hover beats the tint: more specific, and later. */
button.switcher-tile:hover {
  background: var(--ft-row-hover);
  border-color: var(--ft-teal-tint-border);
  color: var(--ft-text);
}
button.switcher-tile:hover .switcher-icon { color: var(--ft-teal-deep); }
.switcher-cue { margin-left: 2px; }
/* Drilled view: "‹ {group}" stands in for the head label, same look, hugging
   its text so the pill stays hard right. */
.switcher-back {
  min-width: 0; margin: 0 auto 0 0; padding: 0;
  border: 0; background: none;
  font-family: inherit; font-size: var(--ft-2xs); line-height: 1.5;
  text-transform: uppercase; letter-spacing: var(--ft-track-caps);
  color: var(--ft-text-muted); text-align: left;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer;
}
.switcher-back:hover { color: var(--ft-text); }
/* `hidden` must win over the grid's display:grid (views not on show). */
.switcher-panel [hidden] { display: none; }
.switcher-icon {
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  color: var(--ft-text-muted);
  font-size: 13px; font-weight: 700; line-height: 1;   /* letter fallback */
}
.switcher-icon svg { width: 24px; height: 24px; display: block; }
.switcher-name { line-height: 1.2; }
.switcher-badge {
  display: inline-block; margin-top: 2px;
  padding: 2px 6px;
  border-radius: var(--ft-radius-sm);
  font-size: var(--ft-2xs); font-weight: 700;
  letter-spacing: var(--ft-track-label); text-transform: uppercase;
  color: var(--ft-amber-text); background: var(--ft-amber-tint);
  border: 1px solid var(--ft-amber-border);
}

/* -- mount swap ----------------------------------------------------------- */
.switcher--band { display: none; }        /* desktop: the rail foot owns the dots */

@media (max-width: 900px) {
  /* The rail is a sticky band here and has its own sticky behaviour (§3), so the
     desktop viewport pin has to be undone or the band grows to full height. */
  .ft-sidebar { height: auto; }
  .ft-nav { flex: 0 0 auto; overflow-y: visible; }

  .switcher--foot { display: none; }
  /* order 1 alongside .ft-nav-toggle, and earlier in source, so the row reads
     brand · [space] · dots · hamburger — and the dots take over the auto push. */
  .switcher--band { display: block; order: 1; margin-left: auto; }
  .ft-nav-toggle { margin-left: 8px; }

  /* Identity flips to dark-on-light and back to a plain block (dots are hidden
     here, so the foot carries text only). */
  .ft-sidebar-foot { display: block; padding: 0; margin-left: 8px; }
  .ft-identity { flex: none; }
  .ft-identity-name { color: var(--ft-text); }
  .ft-identity-email { margin-top: 0; font-size: var(--ft-xs); color: var(--ft-text-muted); }
}

/* Phones: keep the panel fully on screen. */
@media (max-width: 380px) {
  .switcher--band .switcher-panel { width: 208px; }
  .switcher--band .switcher-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Chrome never prints. */
@media print {
  .switcher { display: none; }
}

/* ------------------------------------------ 14. CARD RECONCILIATION (v2 only)
   Additive layer for /admin/card-recon: the tab strip, the feed-freshness
   strip, the candidate picker, and the suggested-pair list. Colours are the
   existing tokens and badge tones only — no new palette.
   ------------------------------------------------------------------------- */

/* Feed freshness: one plain sentence, then the three windows in words. */
.ft-feedstrip {
  background: var(--ft-card);
  border: 1px solid var(--ft-border);
  border-left: 3px solid var(--ft-teal);
  border-radius: var(--ft-radius);
  padding: 10px 12px;
}
.ft-feedstrip-line { font-size: var(--ft-base); color: var(--ft-text); }
.ft-feedstrip .ft-meta { margin-top: 3px; }

/* Tab strip: links, one per view, each carrying its own count. */
.ft-tabs { display: flex; flex-wrap: wrap; gap: 6px; }
.ft-tab {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 12px; min-height: 34px;
  background: var(--ft-card);
  border: 1px solid var(--ft-border);
  border-bottom-width: 3px; border-bottom-color: var(--ft-border);
  border-radius: var(--ft-radius-sm);
  color: var(--ft-text-2); font-size: var(--ft-base);
  transition: var(--ft-transition);
}
.ft-tab:hover { background: var(--ft-row-hover); color: var(--ft-text); text-decoration: none; }
.ft-tab[aria-current="page"] {
  border-bottom-color: var(--ft-teal);
  color: var(--ft-text); font-weight: 600;
}
.ft-tab-count {
  display: inline-block; min-width: 20px; padding: 1px 6px;
  background: var(--ft-teal-tint); border: 1px solid var(--ft-teal-tint-border);
  border-radius: var(--ft-radius-pill);
  font-size: var(--ft-xs); font-weight: 700; text-align: center;
  color: var(--ft-teal-deep); font-variant-numeric: tabular-nums;
}
.ft-tab-count--zero {
  background: var(--ft-neutral-tint); border-color: var(--ft-border-control);
  color: var(--ft-text-muted); font-weight: 400;
}

/* Summary tab: a one-month dashboard, not a queue. Header row (month select +
   the outward-sending e-mail button), KPI tiles, then one row per store. All
   existing tokens — the only new shape here is the percent bar. */
.ft-summary-head {
  display: flex; align-items: flex-end; gap: 14px; flex-wrap: wrap;
  padding: 12px 12px 0;
}
.ft-summary-month .ft-select { min-width: 180px; }
.ft-summary-scope { display: flex; flex-direction: column; gap: 2px; padding-bottom: 3px; }
.ft-summary-email { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ft-summary-email .ft-btn[disabled] { opacity: 0.55; cursor: not-allowed; }
.ft-tiles--summary { padding: 12px; }
.ft-tiles--summary .ft-tile { min-width: 190px; flex: 1 1 190px; }
.ft-tiles--summary .ft-tile-value { font-size: var(--ft-2xl); }
.ft-summary-notes { padding: 0 12px 12px; display: flex; flex-direction: column; gap: 4px; }
.ft-region--summary .ft-scroll-x { padding: 0 12px; }
.ft-region--summary .ft-reclist { padding: 12px; }

/* The store table. Wider than the viewport on a laptop once the split column is
   in, so the store column pins at every width here (the house rule only pins it
   on phones, §3b) — the row is unreadable without the name in view. */
.ft-scroll-x .ft-table--summary th:first-child,
.ft-scroll-x .ft-table--summary td:first-child {
  position: sticky; left: 0; z-index: 1;
  background: var(--ft-card);
  box-shadow: 1px 0 0 var(--ft-border-row);
}
.ft-scroll-x .ft-table--summary thead th:first-child { background: var(--ft-thead); }
.ft-scroll-x .ft-table--summary tbody tr:nth-child(even) td:first-child { background: var(--ft-zebra); }
.ft-scroll-x .ft-table--summary tbody tr:hover td:first-child { background: var(--ft-row-hover); }
.ft-table--summary .ft-plate { margin-right: 6px; }
.ft-table--summary .ft-tag { margin-left: 6px; }
.ft-sumopen { white-space: nowrap; }
.ft-submuted { display: block; font-size: var(--ft-xs); color: var(--ft-text-muted); font-weight: 400; }

/* Total row: the house highlight tone, and it stays highlighted through the
   stripe and the hover (both target td, so this has to as well). */
.ft-table--summary tbody tr.ft-sumtotal td,
.ft-table--summary tbody tr.ft-sumtotal:nth-child(even) td,
.ft-table--summary tbody tr.ft-sumtotal:hover td,
.ft-scroll-x .ft-table--summary tbody tr.ft-sumtotal td:first-child,
.ft-scroll-x .ft-table--summary tbody tr.ft-sumtotal:hover td:first-child {
  background: var(--ft-green-tint);
}
.ft-table--summary tbody tr.ft-sumtotal td {
  font-weight: 700;
  border-top: 1px solid var(--ft-green-border);
  border-bottom: 0;
}

/* Percent reconciled: a short bar plus the number. The bar is a reading aid —
   the number is the value, so it never appears without one. Teal at 95+,
   amber 80-95, red below: the app's existing status language. */
.ft-pct { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.ft-pctbar {
  display: inline-block; width: 56px; height: 6px;
  background: var(--ft-neutral-tint);
  border-radius: var(--ft-radius-pill);
  overflow: hidden;
}
.ft-pctbar-fill { display: block; height: 100%; border-radius: var(--ft-radius-pill); background: var(--ft-neutral); }
.ft-pctnum { font-size: var(--ft-sm); font-weight: 700; font-variant-numeric: tabular-nums; }
.ft-pct--good .ft-pctbar-fill { background: var(--ft-teal); }
.ft-pct--good .ft-pctnum { color: var(--ft-teal-deep); }
.ft-pct--warn .ft-pctbar-fill { background: var(--ft-amber); }
.ft-pct--warn .ft-pctnum { color: var(--ft-amber-text); }
.ft-pct--bad .ft-pctbar-fill { background: var(--ft-red); }
.ft-pct--bad .ft-pctnum { color: var(--ft-red); }

/* Split bar (plan 2026-09-22-store-reconciliation-signoff §3): the segments are
   coloured by KIND, not by tone. Teal = automatic (matcher + AI reviewer),
   slate = manual (matched or resolved by store staff), the neutral track = still
   open. Only the outer track is rounded (overflow clips the segments), so two
   segments meet on a straight edge. The number keeps the tone colours above. */
.ft-pctbar--split { display: inline-flex; width: 72px; }
.ft-pctbar-auto, .ft-pctbar-manual { display: block; height: 100%; flex: none; }
.ft-pctbar-auto { background: var(--ft-teal); }
.ft-pctbar-manual { background: var(--ft-neutral); }
.ft-pctlegend {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  padding: 0 12px 8px;
  font-size: var(--ft-xs); color: var(--ft-text-muted);
}
.ft-pctlegend > span { display: inline-flex; align-items: center; gap: 6px; }
.ft-swatch {
  display: inline-block; width: 12px; height: 8px;
  border-radius: var(--ft-radius-sm);
}
.ft-swatch--auto { background: var(--ft-teal); }
.ft-swatch--manual { background: var(--ft-neutral); }
.ft-swatch--open { background: var(--ft-neutral-tint); box-shadow: inset 0 0 0 1px var(--ft-border-control); }

/* Month status column: the Complete / Re-opened badge with its sub-line, or
   the Mark complete button. Kept on one line so the column stays narrow. */
.ft-sumstatus { white-space: nowrap; }
.ft-sumstatus .ft-submuted { margin-top: 2px; }
.ft-tile-of { font-size: var(--ft-md); font-weight: 400; color: var(--ft-text-muted); }

/* Resolve block in the one-charge panel: reason, note and the button on one
   row where there is room; the note takes the slack and wraps under on a
   phone. The refusal banner sits on top of the fields. */
.ft-picker-resolve {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 12px; padding-top: 10px;
  border-top: 1px solid var(--ft-border-row);
}
.ft-picker-resolve--only { margin-top: 0; padding-top: 0; border-top: 0; }
.ft-resolve-fields { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; }
.ft-resolve-fields .ft-select { min-width: 220px; }
.ft-resolve-fields .ft-textarea { flex: 1 1 280px; min-width: 0; min-height: 38px; }
.ft-resolve-error { margin: 0; }

/* Neutral in-table text button. .ft-linkbtn is red because it means damage
   (Erase); Unlink / Reopen are reversible, so they read as
   links, not as destruction. */
.ft-linkbtn--plain { color: var(--ft-teal-deep); }
.ft-linkbtn--plain:hover { color: #0A5C50; }

/* In-table action cells: the row's buttons stay on one line. Both of them open
   the shared panel above the table, so nothing wide ever lives in this cell
   (an expander here pushed its select and button past the table's right edge —
   caught in the 1440px render, 2026-09-02). */
.ft-recon-actions { white-space: nowrap; }
.ft-recon-actions .ft-btn, .ft-recon-actions .ft-linkbtn { vertical-align: middle; }
.ft-recon-actions .ft-btn + .ft-btn { margin-left: 4px; }

/* Candidate picker (htmx fragment) and the suggested list share the row look. */
.ft-picker {
  border: 1px solid var(--ft-teal-tint-border);
  border-radius: var(--ft-radius);
  background: var(--ft-teal-tint);
  margin: 12px 12px 0;
}
.ft-picker-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px;
  border-bottom: 1px solid var(--ft-teal-tint-border);
}
.ft-picker-merchant { color: var(--ft-text-2); min-width: 0; }
.ft-picker-head .ft-modal-close { margin-left: auto; }
.ft-picker-body { padding: 10px; background: var(--ft-card); border-radius: 0 0 var(--ft-radius) var(--ft-radius); }
.ft-picker-search { display: flex; flex-direction: column; gap: 4px; margin: 6px 0 10px; }
.ft-picker-search .ft-input { max-width: 280px; }

.ft-cand {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 0;
  border-top: 1px solid var(--ft-border-row);
}
.ft-cand:first-of-type { border-top: 0; }
.ft-cand-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; min-width: 0; flex: 1; }
.ft-cand-main .ft-meta { min-width: 0; }
/* Matcher-reason and "total $X → $Y on match" tags wrap instead of pushing the
   page sideways at phone width. */
.ft-cand-main .ft-tag, .ft-sugg .ft-tag { white-space: normal; max-width: 100%; overflow-wrap: anywhere; }
.ft-cand-actions { display: flex; gap: 6px; margin-left: auto; }

.ft-sugglist { display: flex; flex-direction: column; gap: 10px; padding: 12px; }
.ft-sugg { border: 1px solid var(--ft-border); border-radius: var(--ft-radius); background: var(--ft-card); }
.ft-sugg-head {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 10px; background: var(--ft-strip);
  border-bottom: 1px solid var(--ft-border-row);
}
.ft-sugg-merchant { color: var(--ft-text-2); min-width: 0; }
.ft-sugg-head .ft-badge { margin-left: auto; }
.ft-sugg-cands { padding: 4px 10px; }
.ft-sugg-foot { padding: 8px 10px; border-top: 1px solid var(--ft-border-row); }

/* Amount-correction warning on a candidate: the receipt total and the charge
   disagree, so matching rewrites the receipt total from the card. Amber, not
   teal - it is a change the reviewer is agreeing to, not a reassurance. */
.ft-tag--fix {
  background: var(--ft-amber-tint);
  border-color: var(--ft-amber-border);
  color: var(--ft-amber-text);
  font-weight: 600;
}

/* AI review layer (plan D8). The model's words are always a SEPARATE line from
   the matcher's reasons pill: the pill is mechanical fact (amount, date, brand),
   this is an opinion, and a reviewer has to be able to tell them apart at a
   glance. Muted text, no colour of its own - the badge and the confidence pill
   carry the tone, existing tokens only. */
.ft-ainote {
  display: block; width: 100%;
  margin-top: 3px;
  color: var(--ft-text-2); font-size: var(--ft-sm); line-height: 1.4;
}
.ft-ainote-tag {
  display: inline-block; margin-right: 5px; padding: 0 5px;
  border: 1px solid var(--ft-teal-tint-border); border-radius: var(--ft-radius-pill);
  background: var(--ft-teal-tint); color: var(--ft-teal-deep);
  font-size: var(--ft-2xs); font-weight: 700; letter-spacing: var(--ft-track-label);
}
.ft-ainote .ft-tag { margin-left: 6px; }
.ft-sugg-ainote { padding: 6px 10px 0; }

/* Confidence pill on an AI link. Teal, like every other "this is linked" cue -
   it reports how sure the model was, it does not ask for anything. */
.ft-tag--ai {
  background: var(--ft-teal-tint);
  border-color: var(--ft-teal-tint-border);
  color: var(--ft-teal-deep);
  font-weight: 600; font-variant-numeric: tabular-nums;
}

/* AI tab: two rows per match. The main row loses its bottom rule so the reason
   line beneath reads as part of the same record; the reason cell wraps (the
   scroll-x table is nowrap by default) and the pair shares one stripe/hover. */
.ft-table--airows tbody tr.ft-airow-main td { border-bottom: 0; padding-bottom: 4px; }
.ft-table--airows tbody tr.ft-airow-why td { padding-top: 0; }
.ft-scroll-x .ft-table--airows td.ft-airow-why-cell {
  white-space: normal; color: var(--ft-text-2); line-height: 1.45; max-width: 900px;
}
.ft-table--airows td.ft-airow-why-cell .ft-label { margin-right: 6px; }
.ft-table--airows tbody tr.ft-airow--alt td,
.ft-scroll-x .ft-table--airows tbody tr.ft-airow--alt td:first-child { background: var(--ft-zebra); }
.ft-table--airows tbody tr.ft-airow-main:hover td,
.ft-table--airows tbody tr.ft-airow-main:hover + tr.ft-airow-why td,
.ft-scroll-x .ft-table--airows tbody tr.ft-airow-main:hover td:first-child,
.ft-scroll-x .ft-table--airows tbody tr.ft-airow-main:hover + tr.ft-airow-why td:first-child { background: var(--ft-row-hover); }

/* Card mappings: a form in a table. Its controls keep their own width and the
   table scrolls sideways on a phone rather than squeezing the selects to a
   sliver (caught in the 390px render, 2026-09-02). */
.ft-table--cardmap { min-width: 780px; }
.ft-table--cardmap .ft-select { min-width: 220px; }
.ft-table--cardmap .ft-input { min-width: 200px; }

/* Read-only lists (cards mapped to a store). */
.ft-plainlist { margin: 0; padding-left: 18px; }
.ft-plainlist li { margin: 2px 0; }

/* Kiosk (dark) card-charge panel on the receipt detail. */
.kiosk-panel {
  border: 1px solid var(--ft-ink-divider);
  border-left: 3px solid var(--ft-teal);
  border-radius: var(--ft-radius);
  padding: 8px 10px; margin-bottom: 14px;
  background: rgba(23,163,140,0.08);
}
.kiosk-panel-line { color: var(--ft-ink-text-strong); font-size: var(--ft-md); }
.kiosk-fromcard {
  display: inline-block; margin-left: 6px; padding: 1px 5px;
  border: 1px solid #2F7A46; border-radius: var(--ft-radius-sm);
  background: rgba(30,107,52,0.20); color: #9FD9AE;
  font-size: var(--ft-2xs); font-weight: 700; letter-spacing: var(--ft-track-label);
  text-transform: uppercase;
}

@media (max-width: 640px) {
  /* Tabs stay one scrolling row rather than a stack of blocks. */
  .ft-tabs { flex-wrap: nowrap; overflow-x: auto; padding-bottom: 2px; }
  .ft-tab { flex: 0 0 auto; }
  .ft-picker { margin: 12px 0 0; }
  .ft-cand { align-items: flex-start; }
  .ft-cand-actions { margin-left: 0; width: 100%; }
  .ft-cand-actions .ft-btn { flex: 1 1 auto; }
  .ft-sugglist { padding: 12px 0; }
  .ft-recon-actions { white-space: normal; }
  /* Summary on a phone: tiles stack one per row, the header controls go full
     width, and the store table has already become the card list (§3b). */
  .ft-summary-head { flex-direction: column; align-items: stretch; gap: 10px; }
  .ft-summary-email { margin-left: 0; }
  .ft-summary-email .ft-btn { flex: 1 1 auto; }
  .ft-tiles--summary .ft-tile { flex: 1 1 100%; min-width: 0; }
}

/* Card strip notes that carry a link (added with the 2026-10-12 homepage; the
   homepage itself moved to scorecard.css, other pages' strips still use it). */
.ft-card-strip .ft-strip-note a { font-weight: 600; }

/* ---- flags (2026-10-12) ---- */
/* Flags tab (/admin/flags): four filters on one row, the rule id as a mono
   prefix, the trip numbers as muted tags under the one-line summary. Existing
   tokens and badge tones only. */
.ft-filters--flags { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) { .ft-filters--flags { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ft-filters--flags { grid-template-columns: 1fr; } }
.ft-flag-rule { font-family: var(--ft-mono); font-weight: 700; color: var(--ft-text-2); }
.ft-flag-summary { color: var(--ft-text); line-height: 1.4; }
.ft-flag-facts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.ft-flag-fills { margin-top: 2px; }
.ft-flag-fills a { white-space: nowrap; }
.ft-flag-cleared { margin-top: 4px; line-height: 1.4; }
.ft-table--flags .ft-flag-what { min-width: 260px; }
.ft-table--flags .ft-flag-subject { min-width: 120px; }
.ft-table--flags .ft-flag-rulecell,
.ft-table--flags .ft-flag-period,
.ft-table--flags .ft-flag-status { white-space: nowrap; }
/* The long text cells wrap even inside .ft-scroll-x (whose nowrap would push
   Status/Clear off the right edge at 1440). Needs the td + double class to win. */
.ft-table.ft-table--flags td.ft-flag-what,
.ft-table.ft-table--flags td.ft-flag-subject { white-space: normal; }
.ft-flag-status .ft-recon-actions { margin-top: 6px; }
.ft-picker-body > .ft-flag-summary + .ft-meta { margin-top: 4px; }
.ft-picker-body > .ft-picker-resolve--only { margin-top: 12px; }

/* ---- kiosk: company vehicle choice + soft stock # check (2026-10-12) ---- */
/* Shown only while the service-vehicle switch is on (plan 2026-10-03 §13).
   Two large tap targets side by side; the picked one carries the teal edge. */
.kiosk-choice { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.kiosk-choice label {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 48px; padding: 8px 10px; box-sizing: border-box; text-align: center;
  background: #1B2221; border: 1px solid var(--ft-ink-divider); border-radius: var(--ft-radius);
  font-size: 16px; font-weight: 600; color: var(--ft-ink-text-strong); cursor: pointer;
}
.kiosk-choice input { accent-color: var(--ft-teal); width: 18px; height: 18px; margin: 0; flex: none; }
.kiosk-choice label:has(input:checked) { border-color: var(--ft-teal); box-shadow: 0 0 0 1px var(--ft-teal); }
.kiosk-choice label:has(input:disabled) { opacity: 0.5; cursor: not-allowed; }
.kiosk-stockhint { margin: 0; }
/* ---- unit activity (2026-10-12, plan 2026-10-03 Phase 4) ---- */
/* Six filter controls: three per row on a laptop, two at 900, one at 560. */
.ft-filters--units { grid-template-columns: repeat(3, minmax(0, 1fr)); }
@media (max-width: 900px) { .ft-filters--units { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .ft-filters--units { grid-template-columns: 1fr; } }
.ft-units-flagged { align-self: center; }
.ft-units-hint { color: var(--ft-text-faint); }
@media (max-width: 640px) { .ft-units-hint { display: none; } }
.ft-table--units .ft-units-groups th {
  background: var(--ft-card); border-bottom: 0; padding-bottom: 0;
  color: var(--ft-text-2); text-align: center;
}
.ft-table--units .ft-units-groups th.ft-units-group { border-bottom: 2px solid var(--ft-border); }
.ft-table--units .ft-units-start { border-left: 1px solid var(--ft-border-row); }
.ft-table--units .ft-units-identity { min-width: 140px; }
.ft-units-nowrap { white-space: nowrap; }
.ft-table--units tfoot td {
  background: var(--ft-thead); border-top: 1px solid var(--ft-border);
  padding: 7px 10px; font-variant-numeric: tabular-nums;
}
.ft-unit-flags { font-weight: 600; color: var(--ft-red); white-space: nowrap; }
.ft-units-recid { min-width: 0; overflow-wrap: anywhere; }
.ft-units-phonetotal { padding: 0 2px; }
.ft-tile-value a { color: inherit; }
.ft-unit-lastfill { white-space: nowrap; }
@media (max-width: 640px) { .ft-unit-lastfill { font-size: var(--ft-lg); } }

/* Admin receipt page (/admin/receipts/{id}, ruling f-receiptpage) */
.ft-rcpt-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.ft-rcpt-layout { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: var(--ft-gap); align-items: start; }
.ft-rcpt-thumb { display: block; }
.ft-rcpt-thumb img { display: block; width: 100%; max-height: 420px; object-fit: contain; background: var(--ft-strip); border: 1px solid var(--ft-border); border-radius: var(--ft-radius-sm); }
.ft-rcpt-photo-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.ft-rcpt-fields { display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 12px 16px; margin: 0; }
.ft-rcpt-field { min-width: 0; }
.ft-rcpt-field dd { margin: 2px 0 0; overflow-wrap: anywhere; }
.ft-rcpt-field .ft-hint { display: block; }
.ft-rcpt-sub { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--ft-border-row); }
.ft-rcpt-list { list-style: none; margin: 0; padding: 0; }
.ft-rcpt-list > li { padding: 10px 0; border-bottom: 1px solid var(--ft-border-row); overflow-wrap: anywhere; }
.ft-rcpt-list > li:last-child { border-bottom: 0; }
.ft-rcpt-list .ft-diff pre { white-space: pre-wrap; }
@media (max-width: 840px) { .ft-rcpt-layout { grid-template-columns: 1fr; } }
@media (max-width: 640px) {
  .ft-rcpt-fields { grid-template-columns: 1fr 1fr; }
  .ft-rcpt-photo-actions .ft-btn { min-height: 44px; padding: 11px 12px; }
  .ft-rcpt-list a { display: inline-block; min-height: 44px; line-height: 44px; }
}
@media (max-width: 380px) { .ft-rcpt-fields { grid-template-columns: 1fr; } }

/* Settings page: sections, sub-headings, per-section Save (round 3, b-settings) */
.ft-settings-section { scroll-margin-top: 12px; }
.ft-settings-jump { margin-bottom: 2px; }
.ft-settings-subhead {
  margin: 0; padding-top: 10px;
  border-top: 1px solid var(--ft-border-row);
  font-size: var(--ft-sm); font-weight: 700; color: var(--ft-text);
}
.ft-card-body > .ft-stack:first-child > .ft-settings-subhead { border-top: 0; padding-top: 0; }
.ft-settings-section .ft-card-foot.ft-form-actions { justify-content: flex-end; }

/* Flags: money strip, age, investigation (round 3, b-flaglist / d-investigate) */
.ft-flags-money { padding: 12px 16px; border-bottom: 1px solid var(--ft-border); display: flex; flex-direction: column; gap: 6px; }
.ft-flags-money-total { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }
.ft-flags-money-total .ft-num { font-size: var(--ft-xl); font-weight: 700; color: var(--ft-text); }
.ft-flags-money-lines { display: flex; flex-wrap: wrap; gap: 4px; }
.ft-flag-age { white-space: nowrap; }
.ft-flag-investigating { margin-top: 4px; }
.ft-flag-investigating-pill { margin-left: 4px; white-space: nowrap; }
.ft-flags-new { align-self: end; }

/* Flag pills (2026-10-19, president: the gray-on-gray chips were illegible).
   One tint per kind of number, dark text, every pair AA (>= 4.5:1, computed
   on the pill's own background): dollars amber + body text, bold (13.4:1) -
   the number a flag is about; gallons teal tint + teal ink (6.9:1); fill and
   charge counts neutral tint + neutral (6.8:1); context numbers white +
   text-2 (6.1:1). The strip's rule chips are teal tint + body text (12.9:1),
   the store chips neutral tint + body text (12.7:1). No admin dark theme. */
.ft-tag.ft-chip--usd   { background: var(--ft-amber-tint); border-color: var(--ft-amber-border); color: var(--ft-text); font-weight: 700; font-variant-numeric: tabular-nums; }
.ft-tag.ft-chip--gal   { background: var(--ft-teal-tint); border-color: var(--ft-teal-tint-border); color: var(--ft-teal-ink); font-weight: 600; font-variant-numeric: tabular-nums; }
.ft-tag.ft-chip--count { background: var(--ft-neutral-tint); border-color: var(--ft-border-control); color: var(--ft-neutral); font-weight: 600; }
.ft-tag.ft-chip--other { background: var(--ft-card); border-color: var(--ft-border-control); color: var(--ft-text-2); }
.ft-tag.ft-chip--rule  { background: var(--ft-teal-tint); border-color: var(--ft-teal-tint-border); color: var(--ft-text); }
.ft-tag.ft-chip--store { background: var(--ft-neutral-tint); border-color: var(--ft-border-control); color: var(--ft-text); }
.ft-chip-rule { font-family: var(--ft-mono); font-weight: 700; color: var(--ft-teal-ink); }
.ft-flag-fill { white-space: nowrap; }
.ft-flag-photo { font-size: var(--ft-sm); font-weight: 600; }
.ft-flag-subject .ft-flag-photo { margin-left: 6px; }

/* Weekly "This week" tables (review hop #3): the long text cells wrap inside
   .ft-scroll-x (whose nowrap clipped them at phone width under the pinned
   first column); td + double class to win. Under 640px the store name goes,
   the code plate stays. */
.ft-table.ft-table--weekly td.ft-weekly-wrap { white-space: normal; min-width: 12rem; }
.ft-table.ft-table--weekly td.ft-weekly-flag { white-space: normal; min-width: 7rem; max-width: 12rem; }
@media (max-width: 640px) {
  .ft-table--weekly .ft-weekly-storename { display: none; }
}

.ft-units-search { grid-column: 1 / -1; }
