/* ============================================================================
   PACRON — component stylesheet
   ----------------------------------------------------------------------------
   WHAT  The CONSULATE components this application needs: the crown, the queue
         band, the page header, the canvas, the white box, section header
         bands, control strips, data grids, field rows and pagination.

   WHY   CONSULATE is a Locked design system. It ships tokens and a written
         specification, not a stylesheet, so each product writes the component
         rules itself against the shared tokens. These rules are transcribed
         from 01-CONSULATE-DESIGN-SYSTEM.md and consulate-reference.html.

   HOW   Every value below is a token from tokens.css. No raw hex, anywhere.
         Load-bearing rules, from 01 section 2:
           1. border-radius is 0 everywhere, forever.
           2. Two border weights only: 2px container, 1px item.
           3. A heading is a FILLED BAND, never floating bold text.
           4. Shadow belongs to the record window and the confirm only.
           5. Status colour is TEXT ONLY. No chips, badges, pills or fills.
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; border-radius: var(--radius); }

body {
  font-family: var(--font);
  font-size: var(--t-body);
  color: var(--c-ink);
  background: var(--c-canvas);
}

button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
a { color: var(--c-link); text-decoration: underline; }
:focus-visible { outline: var(--focus-ring); outline-offset: var(--focus-offset); }

.app { min-height: 100vh; display: flex; flex-direction: column; }

/* ---------- CROWN ---------------------------------------------------------
   84px total: a 44px identity row and a 40px object-tab row. The active tab
   is 42px tall so it runs 2px past the crown's own border and merges into the
   white band below. That square notch is the signature form. ------------- */
.crown { background: var(--c-crown); border-bottom: 2px solid var(--c-crown-border); flex: none; }
.crown-r1 { height: var(--h-crown-row1); display: flex; align-items: center; padding: 0 var(--gutter); }
.crest {
  width: 26px; height: 26px; background: var(--c-gold); color: var(--c-ink-invert);
  display: grid; place-items: center; font-size: 12px; font-weight: 700; flex: none;
}
.wordmark {
  font-size: var(--t-wordmark); font-weight: 700; letter-spacing: 1.2px;
  color: var(--c-ink-invert); margin-left: 12px;
}
.crown-rule { width: 1px; height: 18px; background: var(--c-crown-rule); margin: 0 14px; }
.desk { font-size: var(--t-secondary); color: var(--c-crown-ink); }
.spacer { flex: 1; }
.util { margin-left: 20px; font-size: 12px; display: flex; align-items: center; gap: 8px; }
.util a { color: var(--c-ink-invert); }
.util .sep { color: var(--c-crown-rule); text-decoration: none; }

/* Card t_20aff642. The Margin lines tickbox sits in the crown's own utility
   row, so it needs the crown's secondary ink colour rather than .tickbox's
   ordinary one, which is tuned for the white canvas below. */
.navtoggle { display: inline-flex; align-items: center; }
.util .tickbox { color: var(--c-crown-ink); font-size: 12px; }
.util .tickbox input { margin: 0; }

.crown-r2 { height: var(--h-crown-row2); display: flex; align-items: stretch; padding: 0 var(--gutter); }
.otab {
  padding: 0 22px; display: grid; place-items: center;
  font-size: var(--t-tab-object); font-weight: 600; color: var(--c-crown-ink);
  text-decoration: none;
}
.otab:hover { background: var(--c-crown-hover); color: var(--c-ink-invert); }
.otab.on {
  background: var(--c-surface); color: var(--c-crown); font-weight: 700;
  height: 42px; align-self: flex-start; position: relative; z-index: 2;
}
.otab.off { color: var(--c-crown-rule); cursor: default; }
.otab.off:hover { background: none; color: var(--c-crown-rule); }

/* ---------- QUEUE TAB BAND ------------------------------------------------
   Level 2 navigation. Every queue visible at rest with a live count. A count
   of zero prints as nothing at all. ------------------------------------- */
.qband {
  height: var(--h-queue-band); background: var(--c-surface);
  border-bottom: 1px solid var(--c-border-container);
  display: flex; align-items: stretch; padding: 0 var(--gutter); flex: none;
}
.qtab {
  padding: 0 18px; display: flex; align-items: center; gap: 6px;
  font-size: var(--t-tab-queue); font-weight: 600; color: var(--c-ink-2);
  border-bottom: 3px solid transparent; text-decoration: none;
}
.qtab .n { font-weight: 400; color: var(--c-ink-3); }
.qtab:hover { color: var(--c-ink); }
.qtab.on { color: var(--c-ink); font-weight: 700; border-bottom-color: var(--c-gold); }

/* ---------- EVIDENCE DROPDOWN + CONFIDENCE SEGMENTED CONTROL ---------------
   Card t_833ba0b1 gave the evidence ladder its own qband, wrapped onto
   however many rows ten tabs needed, with the observed/derived toggle in a
   qband of its own underneath. Card t_db4ba6b4 puts both on the one queue
   band: a <select> (which cannot wrap the way tabs did, so it never needs
   to) beside a segmented control. Two qbands become one. */
.evidenceband { height: auto; min-height: var(--h-queue-band); align-items: center; gap: 14px; padding: 6px var(--gutter); }
.evidenceband-note { border-bottom: 1px solid var(--c-border-container); }

/* The confidence toggle. Same CONSULATE grammar as .atabs - a 2px container
   border, 1px dividers between segments, the active segment a filled band,
   zero border-radius throughout this design - just sized to sit inline
   beside the dropdown instead of spanning the page. */
.seg { display: inline-flex; border: 2px solid var(--c-border-container); height: var(--h-input); flex: none; }
.segopt {
  display: flex; align-items: center; gap: 6px; padding: 0 14px;
  font-size: var(--t-tab-queue); font-weight: 600; color: var(--c-ink-2);
  text-decoration: none; border-right: 1px solid var(--c-border-item);
}
.segopt:last-child { border-right: none; }
.segopt .n { font-weight: 400; color: var(--c-ink-3); }
.segopt:hover { background: var(--c-band-header); color: var(--c-ink); }
.segopt.on { background: var(--c-crown); color: var(--c-ink-invert); }
.segopt.on .n { color: var(--c-crown-ink); }

/* ---------- ASSUMPTIONS TABS — card t_5491e45c ----------------------------
   The Assumptions screen splits into two tabs that hold DIFFERENT KINDS of
   content - arithmetic on one, genuine judgement calls on the other - so
   this does not reuse the .qtab underline idiom above, which switches
   between slices of the SAME list. Filled colour bands instead, the same
   grammar as every section heading (.strip) on this screen: the active tab
   is a filled band, not a highlighted line. Two border weights - a 2px
   container border around the whole strip, a 1px item border between the
   two tabs - and zero border-radius, like everywhere else in this design. */
.atabs {
  display: flex; border: 2px solid var(--c-border-container);
  border-bottom: none; flex: none;
}
.atab {
  flex: 1; padding: 12px 18px; text-align: center;
  font-size: var(--t-header); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; text-decoration: none;
  background: var(--c-band-service); color: var(--c-ink-2);
  border-right: 1px solid var(--c-border-item);
}
.atab:last-child { border-right: none; }
.atab .n {
  font-weight: 400; text-transform: none; letter-spacing: normal;
  margin-left: 6px; color: var(--c-ink-3);
}
.atab:hover { background: var(--c-band-header); color: var(--c-ink); }
.atab.on { background: var(--c-crown); color: var(--c-ink-invert); }
.atab.on .n { color: var(--c-crown-ink); }
.atab-note .note { font-style: italic; color: var(--c-ink-2); }

/* ---------- PAGE HEADER ---------------------------------------------------- */
.phead {
  min-height: var(--h-page-header); background: var(--c-surface);
  border-bottom: 1px solid var(--c-border-container);
  display: flex; align-items: center; padding: 8px var(--gutter); gap: 12px; flex: none;
}
.ptile {
  width: 32px; height: 32px; background: var(--c-crown); color: var(--c-ink-invert);
  display: grid; place-items: center; font-size: 16px; font-weight: 700; flex: none;
}
.eyebrow {
  font-size: var(--t-eyebrow); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; color: var(--c-ink-3);
}
.h1line { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
h1 { font-size: var(--t-h1); font-weight: 700; }
.countline { font-size: var(--t-secondary); color: var(--c-ink-2); }
.countline .good { color: var(--c-good); font-weight: 700; }

.btn {
  height: var(--h-button); padding: 0 16px; font-size: var(--t-body);
  background: var(--c-surface); border: 1px solid var(--c-border-control);
  display: grid; place-items: center; text-decoration: none; color: var(--c-ink);
}
.btn.primary {
  background: var(--c-crown); color: var(--c-ink-invert);
  border-color: var(--c-crown); font-weight: 600;
}

/* ---------- CANVAS + BOX --------------------------------------------------
   The whole product is ONE white rectangle on a tinted field. Never put
   content directly on the canvas. ---------------------------------------- */
.canvas { flex: 1; padding: 16px var(--gutter); }

/* Card t_68799fdd. Set on <body> by an inline script the instant the tiers-
   by-distance page decides it has a scroll offset to restore, and taken off
   again by app.js once that offset has been applied — so the page never
   paints at the top before jumping to where the reader actually was. */
.restoring-scroll { visibility: hidden; }

.box {
  background: var(--c-surface); border: 2px solid var(--c-border-container);
  display: flex; flex-direction: column; margin-bottom: 16px;
}

/* A heading is a filled band. Section strips use --c-band-header; column
   headers, group headers and pagination use --c-band-service. */
.strip {
  min-height: var(--h-section-strip); background: var(--c-band-header);
  display: flex; align-items: center; gap: 10px; padding: 0 var(--pad-box);
  font-size: var(--t-header); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; color: var(--c-ink-on-band);
}
.strip .strip-note {
  font-size: var(--t-secondary); font-weight: 400; text-transform: none;
  letter-spacing: normal; color: var(--c-ink-2); margin-left: auto;
}
.ghead {
  min-height: var(--h-group-header); background: var(--c-band-service);
  display: flex; align-items: center; padding: 4px var(--pad-box);
  font-size: 12px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.6px; color: var(--c-ink-2);
}

/* ---------- CONTROL STRIP (filters) --------------------------------------- */
.cstrip {
  min-height: var(--h-control-strip); display: flex; align-items: center;
  gap: 10px; flex-wrap: wrap; padding: 6px var(--pad-box);
  border-bottom: 1px solid var(--c-border-item);
}
.cstrip label { font-size: var(--t-control); color: var(--c-ink-2); }
.cstrip .fieldgroup { display: flex; align-items: center; gap: 6px; }
/* The standard-vs-custom filter is the only MULTI-select control in the
   product, so its four tick boxes are enclosed in a 1px item border to read
   as one control rather than four loose ones. No new border weight, no
   radius: the same grammar as everything else. */
.cstrip .clsfilter {
  border: 1px solid var(--c-border-item); padding: 3px 8px; gap: 10px;
  background: var(--c-band-service);
}
.cstrip .clsfilter .tickbox { font-weight: 600; color: var(--c-ink); }
.sel, .inp {
  height: var(--h-input); border: 1px solid var(--c-border-control);
  background: var(--c-surface); padding: 0 8px;
  font-size: var(--t-control); font-weight: 600; color: var(--c-ink);
  font-family: var(--font);
}
.inp { font-weight: 400; }
/* Long customer names must not stretch the control strip off the page. */
.sel { max-width: 220px; }
.go {
  height: var(--h-input); padding: 0 16px; background: var(--c-gold);
  color: var(--c-ink-invert); font-size: var(--t-secondary); font-weight: 700;
}

/* ---------- THE CHECKBOX DROPDOWN — card t_4adc06ee ------------------------
   Joe: "Maybe the standard-or-custom and cost-of column should also be this
   new idea of having a dropdown with checkboxes next to it." Built once here
   and used for every checkbox-group filter on /items, /margin-lines and
   /tier-distance - freight type, custom cost, tier, evidence level, distance.

   The browser's own <details>/<summary>, the same idiom .disc already uses,
   so it needs no script to open or close and stays keyboard-operable. The
   closed <summary> ALWAYS states where the filter stands - "Tiers: all" or
   "Tiers: 3 of 6" - computed server-side from the filter actually in force,
   never from an unsubmitted tick, so it is correct with JavaScript off too.

   THE BODY FLOWS IN-DOCUMENT, THE SAME WAY .disc-body ALREADY DOES - it does
   NOT float over the page. That was tried first and measured to be a genuine
   defect rather than a style choice: with ten filters now on one control
   strip, the strip wraps onto a second line at ordinary widths, and a
   floating panel opening below a first-line control sits directly on top of
   whatever the SECOND line holds underneath it - on the margin grid, that is
   the Go button itself, so a reader who opened the Tier dropdown could no
   longer reach Go without first closing it again. Letting the open dropdown
   grow the control strip's own height instead - exactly what .disc already
   does elsewhere on every one of these screens - pushes the wrapped line
   below it down instead of covering it, which cannot happen regardless of
   how many filters wrap or how narrow the window is.

   No box-shadow: rule 4 in tokens.css reserves that for exactly two surfaces,
   and this dropdown is not one of them. The 2px container border is what
   gives the open list its edge instead. -------------------------------- */
.ddfilter { display: inline-flex; align-items: flex-start; gap: 6px; }
.ddown { }
.ddown > summary.ddsum {
  height: var(--h-input); border: 1px solid var(--c-border-control);
  background: var(--c-surface); padding: 0 10px; display: flex;
  align-items: center; gap: 6px; white-space: nowrap; cursor: pointer;
  list-style: none; font-size: var(--t-control); font-weight: 600;
  color: var(--c-ink); font-family: var(--font);
}
.ddown > summary.ddsum::-webkit-details-marker { display: none; }
.ddown > summary.ddsum::after { content: "\25BE"; color: var(--c-ink-3); font-size: 10px; }
.ddown[open] > summary.ddsum { border-color: var(--c-crown); }
.ddown[open] > summary.ddsum::after { content: "\25B4"; }
.ddown > summary.ddsum:focus-visible {
  outline: var(--focus-ring); outline-offset: var(--focus-offset);
}
.ddown-body {
  margin-top: 2px;
  min-width: 220px; max-width: 340px; max-height: 240px; overflow-y: auto;
  background: var(--c-surface); border: 2px solid var(--c-border-container);
  padding: 8px 10px; display: flex; flex-direction: column; gap: 6px;
}
.ddown-body .tickbox { font-weight: 400; color: var(--c-ink); white-space: nowrap; }
/* The per-group clear. Only ever rendered when that one group is actually
   filtering - see web/templates/_furniture.html's checkbox_dropdown() macro -
   so its presence on screen already means something without reading its
   text. The word "Clear" sits beside the circular-arrow icon rather than the
   icon alone, because a bare circular arrow reads as "reload the page" to a
   lot of people; Joe picked this icon off a sheet of five. */
.ddclear {
  display: inline-flex; align-items: center; gap: 3px;
  font-size: var(--t-control); font-weight: 600; color: var(--c-link);
  text-decoration: underline; white-space: nowrap;
}
.ddclear-icon { font-size: 12px; text-decoration: none; }
/* "Clear all filters", plain text at the end of the row, visible only when
   at least one filter anywhere on the screen is on - see any_filters_on() in
   web/app.py. */
.clearall { font-size: var(--t-control); font-weight: 600; color: var(--c-link); }

/* ---------- DATA GRID -----------------------------------------------------
   No zebra striping and no vertical column rules: both were considered and
   removed by the design system. Rows are 44px on purpose. ---------------- */
.grid { width: 100%; border-collapse: collapse; }
.grid thead th {
  height: var(--h-column-header); background: var(--c-band-service);
  font-size: var(--t-column); font-weight: 700; color: var(--c-ink-2);
  text-align: left; padding: 0 10px; white-space: nowrap;
}
.grid tbody td {
  height: var(--h-row); padding: 4px 10px; font-size: var(--t-body);
  border-bottom: 1px solid var(--c-border-item); vertical-align: middle;
}
.grid tbody tr:hover { background: var(--c-band-service); }
.grid .r { text-align: right; font-variant-numeric: tabular-nums; }
.grid .strongcell { font-weight: 600; }
.grid td.sub { font-size: var(--t-secondary); color: var(--c-ink-2); }
.grid .this-line td { background: var(--c-band-header); font-weight: 600; }

/* ---------- SELECT ALL, IN THE TABLE HEADER — card t_b2f5c626 -------------
   WHAT  The tick column's header cell: a "Select all" tickbox with its label,
         and under it the running count of how many rows are ticked.

   WHY   Joe: "when you click Select All, actually selects all that is on the
         screen." Putting it at the top of the column of ticks is what makes
         that self-evident — a box at the head of a column can only mean the
         column beneath it. The old control floated above the capacity dropdown
         and had to be read to be understood.

         The count matters because the capacity gaps screen no longer shows a
         confirmation before it writes. How many rows are about to be acted on
         has to be legible at the moment the button is pressed, not after.

   HOW   The column is widened from the 28px a bare tickbox needed to fit the
         two words beside it, and the label wraps the tickbox so clicking
         either works. The header cell is `white-space: normal` because the
         grid's default nowrap would otherwise force the count onto the same
         line as the label. Nothing here changes the sticky header: the cell is
         still a plain `th` inside `.tablescroll`, so the rule at the foot of
         this file still pins it.
   -------------------------------------------------------------------------- */
.grid thead th.tickcol {
  width: 86px;
  white-space: normal;
  line-height: 1.25;
  vertical-align: middle;
}
.grid thead th.tickcol .tickall {
  display: flex; align-items: center; gap: 5px;
  font-size: var(--t-column); font-weight: 700; color: var(--c-ink-2);
  cursor: pointer;
}
.grid thead th.tickcol .tickall-count {
  display: block;
  font-size: var(--t-secondary); font-weight: 700; color: var(--c-crown);
}

/* ---------- PRODUCT GROUPING INSIDE ONE PANE — card t_e1bd743a -------------
   WHAT  The heading row that names a product on the tiers-by-distance report,
         and the totals row at the foot of a summary table.

   WHY   That report is read product by product, and each product carries its
         own tiers and its own distance bands underneath it. Drawing one table
         per product would have given the page a scrolling pane and a sticky
         header per product; one table with a filled heading row keeps a single
         pane, a single column header and one reachable sideways scrollbar.

   HOW   A heading is a FILLED BAND in this design system, so the row takes the
         section-header fill and the rule above it is the container weight —
         the heavier of the two — because it separates products rather than
         rows. No radius, no third border weight, no new colour: both rules use
         tokens that were already here. */
.grid tbody tr.prodhead td {
  background: var(--c-band-header);
  border-top: 2px solid var(--c-border-container);
  font-weight: 600;
}
.grid tbody tr.prodhead:hover td { background: var(--c-band-header); }
.grid tbody tr.prodhead .sub { font-weight: 400; }

.grid tfoot tr.totalrow td {
  background: var(--c-band-service);
  border-top: 2px solid var(--c-border-container);
  font-weight: 700;
}

/* Status colour is TEXT ONLY, and it is spent sparingly.
   A negative true margin is the exception worth colouring, so it prints in
   --c-urgent. An ordinary positive margin stays in ordinary ink: a column of
   green numbers is noise, and it would spend the one signal the eye has on
   the rows that are fine. --c-good is reserved for a single terminal
   statement - the coverage headline, and the margin on a drill-down. */
.pos { color: var(--c-good); }
.neg { color: var(--c-urgent); }
.grid .pos { color: var(--c-ink); }
.muted { color: var(--c-ink-3); }
.note { font-size: var(--t-secondary); color: var(--c-ink-2); padding: 10px var(--pad-box); }
.note.tight { padding: 6px var(--pad-box); }
.derived { font-size: var(--t-eyebrow); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; color: var(--c-urgent); }
.actual { font-size: var(--t-eyebrow); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; color: var(--c-ink-3); }

/* ---------- PAGINATION ----------------------------------------------------- */
.pag {
  min-height: var(--h-pagination); border-top: 2px solid var(--c-border-container);
  background: var(--c-band-service); display: flex; align-items: center;
  gap: 6px; flex-wrap: wrap; padding: 4px var(--pad-box);
  font-size: 12px; color: var(--c-ink-2);
}
.pg {
  border: 1px solid var(--c-border-control); background: var(--c-surface);
  padding: 3px 9px; font-size: 12px; font-variant-numeric: tabular-nums;
  text-decoration: none; color: var(--c-ink);
}
.pg.on { background: var(--c-crown); color: var(--c-ink-invert); border-color: var(--c-crown); font-weight: 700; }
.pagination-count { margin-right: 8px; }

/* ---------- FIELD ROWS (component library 5.1) ----------------------------
   Label column 180px, 13px/400, RIGHT-ALIGNED, 12px gutter. The label is not
   above the value; that is Dynamics inheritance and it is deliberate. ---- */
.fields { padding: 0 var(--pad-box); }
.c-field {
  display: flex; align-items: baseline; min-height: 34px; padding: 6px 0;
  border-bottom: 1px solid var(--c-border-field);
}
.c-field:last-child { border-bottom: none; }
.c-field__label {
  width: 220px; margin-right: 12px; flex: none; text-align: right;
  font-size: 13px; font-weight: 400; color: var(--c-ink-2);
}
.c-field__value { flex: 1 1 auto; font-size: var(--t-body); }
.c-field__value .big { font-size: 15px; font-weight: 700; }
.c-help { font-size: 13px; color: var(--c-ink-3); }

/* ---------- ARITHMETIC BLOCK ----------------------------------------------
   The sum, shown as a sum. There is no monospace anywhere in this product,
   so the working is set in the product face with tabular figures. ------- */
.sum { padding: 10px var(--pad-box); }
.sum .line { display: flex; align-items: baseline; gap: 10px; padding: 6px 0;
  border-bottom: 1px solid var(--c-border-field); flex-wrap: wrap; }
.sum .line:last-child { border-bottom: none; }
.sum .lbl { width: 220px; flex: none; text-align: right; font-size: 13px; color: var(--c-ink-2); }
.sum .calc { font-size: var(--t-body); font-variant-numeric: tabular-nums; }
.sum .calc .eq { font-weight: 700; }
.sum .why { font-size: 13px; color: var(--c-ink-3); width: 100%; padding-left: 232px; }

/* ---------- TWO COLUMNS OF BOXES ------------------------------------------ */
.cols { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.cols > * { flex: 1 1 420px; min-width: 0; }

.breadcrumb { font-size: var(--t-secondary); color: var(--c-ink-2); }
.breadcrumb a { color: var(--c-link); }

/* ---------- PHASE 2 COMPONENTS --------------------------------------------
   Everything below is built from the same tokens and the same five rules as
   the components above: no radius, two border weights, headings are filled
   bands, no shadow outside the record window, and status colour is text only.
   Nothing here introduces a chip, a pill or a coloured row. -------------- */

/* A refusal is a heading band like any other heading band. The only thing
   that marks it out is the ink, because status colour in CONSULATE is text. */
.strip.refused { color: var(--c-overdue); }
.bigrefusal { font-size: 15px; font-weight: 700; color: var(--c-ink); }

/* ---------- ITEMS SCREEN --------------------------------------------------
   Rows here are taller than a normal 44px data row because each one carries
   two editable values, both of their originals, and an audit trail. The row
   height token still governs the minimum; the content decides the rest. */
.grid.items tbody td { vertical-align: top; padding-top: 10px; padding-bottom: 10px; }
.grid.items tbody tr:hover { background: none; }

.valuenow { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
/* "your correction" is a sentence fragment in accent ink, not a badge. */
.yours {
  font-size: var(--t-eyebrow); font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.7px; color: var(--c-gold); margin-left: 8px;
}
.grid td .sub { font-size: var(--t-secondary); color: var(--c-ink-2); }
.grid td .sub.warn { color: var(--c-ink-3); }

/* An edit control sits inside the cell it edits, on its own line. */
.editrow { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-top: 8px; }
.editrow .go:disabled,
.editrow .inp:disabled { opacity: 0.45; cursor: not-allowed; }
.tickbox { font-size: var(--t-control); color: var(--c-ink-2); display: flex; align-items: center; gap: 4px; }
.btn.small { height: var(--h-input); padding: 0 12px; font-size: var(--t-secondary); }

/* ---------- ASSUMPTIONS ---------------------------------------------------
   A field row per rule. The label column carries the rule's own title, so it
   is a little wider than the standard 220px and reads left-aligned. */
.c-field.assumption { align-items: flex-start; padding: 10px 0; }
.c-field.assumption .c-field__label {
  width: 280px; text-align: left; font-weight: 700; color: var(--c-ink);
}
.c-field.assumption .c-field__label .sub {
  font-size: var(--t-eyebrow); font-weight: 400; color: var(--c-ink-3);
  text-transform: uppercase; letter-spacing: 0.7px;
}
.ruledetail { margin-top: 6px; }

/* ---------- PHASE 3: THE QUESTION BOX -------------------------------------
   Same five rules as everything above: no radius, two border weights,
   headings are filled bands, no shadow outside the record window, status
   colour is text only. Nothing here is a chat bubble — an answer is rendered
   in the product's own field rows, arithmetic blocks and data grids, because
   the answer IS the product's data and should look like it. */

/* The question field is the one control on the page, so it takes the room the
   filter controls elsewhere have to share. */
.askfield { flex: 1 1 520px; }
.askfield .inp { width: 100%; min-width: 240px; }

/* The example questions and the follow-ups are a plain list of links. They are
   not buttons: pressing one is asking a question, which is navigation. */
.asklist { padding-left: 18px; margin-top: 6px; }
.asklist li { padding: 3px 0; }

/* The fact packet, printed in full. Whitespace is preserved because it is JSON
   and its shape carries meaning, but the face is the product's own: there is
   no monospace font anywhere in this product and this is not the exception. */
.packet {
  font-family: var(--font);
  font-size: 12px;
  line-height: 1.5;
  color: var(--c-ink-2);
  background: var(--c-band-service);
  border-top: 1px solid var(--c-border-item);
  padding: 12px var(--pad-box);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 460px;
  overflow: auto;
}

/* ---------- SCREEN 8: THE RAW TABLE BROWSER --------------------------------
   Built from the same five rules as everything above. Nothing new is
   invented here: the grid is the product's grid, the filter row sits inside
   the column-header band because it belongs to the columns, and the only
   genuinely new thing is horizontal scrolling — a table with 32 columns has
   to go somewhere, and the alternative is hiding columns, which is exactly
   what this screen must not do. */

/* The table picker holds every table in the database, so it needs more room
   than the 220px a filter select gets. */
.sel.wide { max-width: 420px; }

/* The capacity dropdown on the gaps screen. Card t_046c6208 change 2 put the
   code, its description from Pacron's capacity sheet and its units per truck
   in every option, which is a long line; at 420px the description was cut off
   at the very moment it was added, which would have defeated the point of the
   change. */
.sel.widest { max-width: 640px; }

/* One table may be wider than the screen. The box does not scroll; the grid
   inside it does, so the section band, the control strip and the pagination
   all stay put. The rules that make that pane work — the fixed height, the
   column header that stays put, the second scrollbar above it — are shared by
   every screen and live in the SCROLLING TABLE PANE section at the foot of
   this file. */

/* Column headings carry the real database name under the readable one. The
   heading is a sort link, so it is underlined like every other link in the
   product. */
.grid.raw { --rawhead-h: 46px; }
.grid.raw thead th {
  vertical-align: top; padding-top: 6px; padding-bottom: 6px;
  /* A fixed height, not `auto`, because the filter row underneath is pinned
     at exactly this offset when the pane is scrolled. See the SCROLLING TABLE
     PANE section at the foot of this file. */
  height: var(--rawhead-h);
}
.grid.raw thead th a { color: var(--c-ink-2); }
.colname {
  font-size: var(--t-eyebrow); font-weight: 400; color: var(--c-ink-3);
  text-transform: none; letter-spacing: normal; margin-top: 2px;
}
.sortmark { color: var(--c-gold); font-weight: 700; }

/* The filter row is part of the column-header band, not part of the data. */
.grid.raw .filterrow td {
  background: var(--c-band-service); height: auto; padding: 4px 6px;
  border-bottom: 1px solid var(--c-border-container); white-space: nowrap;
}
.sel.tiny, .inp.tiny { height: 24px; font-size: 12px; padding: 0 4px; }
.sel.tiny { max-width: 118px; }
.inp.tiny { width: 118px; }

/* Raw rows are single-line so a wide table stays scannable. The full text of
   anything trimmed is in the cell's tooltip. */
.grid.raw tbody td {
  height: auto; padding: 7px 10px; white-space: nowrap;
  max-width: 520px; overflow: hidden; text-overflow: ellipsis;
}
.grid.raw tbody td.r { font-variant-numeric: tabular-nums; }

/* A numeric column's heading is right-aligned, so its filter control belongs
   under the heading rather than at the far left of the same cell. */
.grid.raw .filterrow td.r { text-align: right; }

/* ---------- SCREEN 8: THE COLUMN PICKER -----------------------------------
   Same five rules as everything else. The picker is part of the page, not a
   drawer and not a modal, because CONSULATE has neither. It is a list of
   items, so it gets the 1px item border and nothing heavier. */

.picker {
  max-height: 460px; overflow-y: auto;
  border-bottom: 1px solid var(--c-border-container);
}
.pickrow {
  display: flex; align-items: center; gap: 10px;
  padding: 5px var(--pad-box);
  border-bottom: 1px solid var(--c-border-field);
  font-size: var(--t-secondary);
}
.pickrow:last-child { border-bottom: none; }
/* A column that is currently out of the way is shown in secondary ink while
   "Show hidden" is on, so the eye can tell it from the ones already in play.
   Status colour in CONSULATE is text, never a fill, so this is ink only. */
.pickrow.was-hidden .pickname { color: var(--c-ink-3); }
.pickname { font-weight: 600; min-width: 220px; }
.picktype { color: var(--c-ink-3); font-size: var(--t-eyebrow);
  text-transform: uppercase; letter-spacing: 0.7px; min-width: 190px; }
.picknote { color: var(--c-ink-2); }

/* The filter list for columns that are not in the grid. Same controls as the
   inline filter row, laid out as a wrapping list rather than a table row. */
.offfilters {
  display: flex; flex-wrap: wrap; gap: 8px 16px;
  padding: 8px var(--pad-box);
  border-bottom: 1px solid var(--c-border-item);
}
.offrow { display: flex; align-items: center; gap: 6px; }
.offname { font-size: var(--t-control); color: var(--c-ink-2); font-weight: 600; }

/* A statement that something is affecting the numbers off screen. Status
   colour is TEXT ONLY - no fill, no chip, no coloured row. */
.warnline { color: var(--c-overdue); }
.warnline strong { color: var(--c-overdue); }

/* The list of reasons a save was refused - card t_68f81c25. One line per
   fault, each naming the exact numbers that are wrong. Status colour is TEXT
   ONLY, in keeping with the rule above: no fill, no chip, no coloured row. */
.reasons { margin: 6px 0 0; padding-left: 18px; }
.reasons li { margin: 3px 0; }

.sep-dot { color: var(--c-ink-3); }

/* ---------- BREADCRUMB TRAIL (change 2) -----------------------------------
   WHAT  The row of clickable steps across the top of every entity screen,
         sitting between the page header and the canvas.
   WHY   The client asked to walk down from an order line into a Bill of
         Lading, an item, a capacity record, a salesperson or a price tier and
         climb back out the way he came. The trail is the path he actually
         took, so it has to sit where a path belongs: above the content, on
         every one of those screens, at rest.
   HOW   Built from the tokens like everything else. It is a service band, the
         same pale surface the pagination and the column headers use, with a
         1px item rule under it. No radius, no chip, no fill behind the
         current step - the step you are standing on is simply heavier ink,
         because in CONSULATE state is expressed as type, never as colour. */
.crumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0 8px;
  padding: 7px var(--pad-box);
  background: var(--c-band-service);
  border-bottom: 1px solid var(--c-border-item);
  font-size: var(--t-secondary);
}
.crumbs .crumb { color: var(--c-ink-2); }
.crumbs a.crumb { color: var(--c-link); }
.crumbs .crumb.on { color: var(--c-ink); font-weight: 700; }
.crumb-sep { color: var(--c-ink-3); }

/* A step in the address that could not be used says so, in the same service
   band, in status ink. Never a fill, and it never repeats the bad text back. */
.crumb-note {
  padding: 6px var(--pad-box);
  background: var(--c-band-service);
  border-bottom: 1px solid var(--c-border-item);
  font-size: var(--t-secondary);
  color: var(--c-overdue);
}

/* The "open the thing this figure came from" link that sits in a heading
   band. It is a link in a band, so it inherits the band's type and only the
   colour changes. */
.strip-note a { color: var(--c-link); }

/* ---------- SCROLLING TABLE PANE ------------------------------------------
   WHAT  Turns any data table wrapped in `.tablescroll` into a pane with its
         own scrollbars: the column header stops at the top of the pane and
         stays there while the rows slide underneath it, and a horizontal
         scrollbar sits at the foot of the pane instead of at the foot of the
         page. `app.js` adds a second horizontal scrollbar directly above the
         pane so sideways scrolling is also reachable from the top row.

   WHY   The client asked for exactly this. On a wide table — the source-table
         browser can be thirty-odd columns — he lost the column heading as
         soon as he scrolled, so he could no longer tell which column he was
         reading, and the only way to go left or right was to scroll past
         several hundred rows to reach the bottom of the page. Both of those
         are the page scrolling when the TABLE should have been scrolling.

   HOW   Three parts, all CSS, none of them a JavaScript table library:
           1. `.tablescroll` gets a height ceiling and `overflow: auto`, which
              makes it a scroll container in both directions. The rows scroll
              inside it; the section band, the control strip and the
              pagination around it never move.
           2. `position: sticky; top: 0` on every header cell pins the header
              to the top of that pane. Sticky is pinned on the TOP axis only,
              so when the pane is scrolled sideways the header travels with
              the columns and stays over its own data. That is the whole
              reason for using sticky rather than a floating copy of the row.
           3. A sticky cell is painted over live rows, so it needs a solid
              fill of its own or the text underneath shows through it. Every
              header cell gets the service band colour explicitly, and its
              bottom rule is drawn as an inset shadow because a collapsed
              table border belongs to the table, not to the cell, and would
              be left behind when the cell sticks.

         The ceiling is expressed against the viewport so the pane is as tall
         as the screen allows, minus the crown, the queue band, the page
         header and the box furniture above it. Nothing is clipped: everything
         the pane cannot show is reachable by scrolling the pane, and when the
         pane runs out of rows the wheel carries on scrolling the page as
         usual.
   -------------------------------------------------------------------------- */
.tablescroll {
  overflow: auto;
  max-height: calc(100vh - 240px);
  /* A sideways flick on a trackpad must not be read as a "go back" gesture
     once the pane has run out of columns. Vertical chaining is deliberately
     left alone so the page still scrolls on when the rows run out. */
  overscroll-behavior-x: contain;
}

.tablescroll > .grid > thead > tr > th,
.tablescroll > .grid > thead > tr > td {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--c-band-service);
  box-shadow: inset 0 -1px 0 var(--c-border-item);
}

/* The source-table browser is the one grid with TWO header rows: the column
   names and, under them, the filter controls that belong to those columns.
   Both stick. The filter row stops one header's height down, which is why
   `.grid.raw thead th` is given a fixed height rather than `auto`. */
.tablescroll > .grid.raw > thead > tr.filterrow > td {
  top: var(--rawhead-h);
  z-index: 1;
  box-shadow: inset 0 -1px 0 var(--c-border-container);
}

/* ---------- THE SECOND HORIZONTAL SCROLLBAR -------------------------------
   WHAT  A thin scrollbar-only strip that `app.js` inserts immediately above a
         pane whose table is wider than the pane.

   WHY   The pane's own horizontal scrollbar is at the FOOT of the pane, which
         is a screen away. The client's complaint was precisely that he should
         not have to travel to the bottom of the rows to go left and right, so
         there is a second one at the top, where he is already looking.

   HOW   An empty strip with `overflow-x: auto` and one child rail set to the
         table's own width, so the browser draws a real scrollbar of the right
         proportion. `app.js` keeps its scroll position and the pane's in step
         both ways. It is decoration in the accessibility sense — the pane is
         still scrollable on its own — so it is hidden from screen readers and
         it simply never appears if JavaScript is off.
   -------------------------------------------------------------------------- */
.topscroll {
  overflow-x: auto;
  overflow-y: hidden;
  height: 16px;
  background: var(--c-band-service);
  border-bottom: 1px solid var(--c-border-item);
}
.topscroll-rail { height: 1px; }

/* ---------- THE SCROLLBARS THEMSELVES --------------------------------------
   WHAT  Draws the scrollbars on the table panes, and on the strip above them,
         as permanently visible grey bars in the product's own palette.

   WHY   Several browsers now default to an OVERLAY scrollbar: an outline that
         floats over the content, takes up no room and fades away when you
         stop scrolling. That is the wrong behaviour for this screen — a bar
         you cannot see is a bar the client cannot find, and the whole point of
         the change is that he can see, at a glance, that the table goes
         further left and right than the window does. Asking for a classic
         scrollbar makes the strip above the table honest: its bar shows both
         where he is in the table and how much of it he is looking at.

   HOW   `scrollbar-width` and `scrollbar-color` are the standard properties;
         the `::-webkit-scrollbar` rules do the same job in Chrome and Edge,
         where naming the pseudo-element is also what switches the overlay
         scrollbar off. Both are built from existing tokens: the track is the
         service band the column header sits on and the bar is the control
         border grey, so nothing new enters the palette and nothing gains a
         radius or a shadow.
   -------------------------------------------------------------------------- */
.tablescroll, .topscroll {
  scrollbar-width: auto;
  scrollbar-color: var(--c-border-control) var(--c-band-service);
}
.tablescroll::-webkit-scrollbar,
.topscroll::-webkit-scrollbar { width: 14px; height: 14px; }
.tablescroll::-webkit-scrollbar-track,
.topscroll::-webkit-scrollbar-track { background: var(--c-band-service); }
.tablescroll::-webkit-scrollbar-thumb,
.topscroll::-webkit-scrollbar-thumb {
  background: var(--c-border-control);
  border: 3px solid var(--c-band-service);
}
.tablescroll::-webkit-scrollbar-corner,
.topscroll::-webkit-scrollbar-corner { background: var(--c-band-service); }

/* ---------- DISCLOSURE — card t_90896ad6 -----------------------------------
   WHAT  The little arrow that folds an explanation away, leaving a one-line
         headline that still carries the meaning. Built on the browser's own
         <details>/<summary>, styled into the CONSULATE language.

   WHY   Joe: "there's a lot of words there... maybe it should be a little
         arrow where you can click and see what's under that." The words are
         WHY the client can trust the number, so none of them are deleted -
         they are folded. Fewer words at rest, not fewer words.

   HOW   No radius, no shadow, no animation - just show and hide. The marker
         is a plain triangle drawn in text, rotated 90 degrees when open, so
         no image and no icon font enters the product. The headline reads at
         --t-secondary in secondary ink like every other note on these
         screens, and the folded body is set off by a single 1px item-weight
         rule on its left edge, which is the existing grammar for "these are
         items inside something", not a new one.

         The default browser marker is switched off in both dialects
         (list-style on the summary, and the WebKit pseudo-element) so there
         is never a second arrow beside ours.
   -------------------------------------------------------------------------- */
.disc { margin: 0; }
.disc + .disc { margin-top: 2px; }

.disc > summary.disc-head {
  list-style: none;
  cursor: pointer;
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-size: var(--t-secondary);
  color: var(--c-ink-2);
  padding: 4px 0;
}
.disc > summary.disc-head::-webkit-details-marker { display: none; }
.disc > summary.disc-head:hover { color: var(--c-ink); }
.disc > summary.disc-head:focus-visible {
  outline: var(--focus-ring);
  outline-offset: var(--focus-offset);
}

/* The marker. A text triangle, so it inherits ink and size and needs no asset.
   `flex: none` keeps it from being squeezed when the headline wraps. */
.disc > summary.disc-head::before {
  content: "\25B8";
  flex: none;
  color: var(--c-ink-3);
  font-size: 11px;
  line-height: 1.4;
  transform: translateY(-1px);
}
.disc[open] > summary.disc-head::before { content: "\25BE"; }
.disc[open] > summary.disc-head { color: var(--c-ink); font-weight: 600; }

/* The folded half. Indented past the marker and ruled on the left so it reads
   as belonging to the headline above it rather than as the next paragraph. */
.disc-body {
  font-size: var(--t-secondary);
  color: var(--c-ink-2);
  border-left: 1px solid var(--c-border-item);
  padding: 2px 0 6px 12px;
  margin: 0 0 0 5px;
}
.disc-body p { margin: 0 0 6px 0; }
.disc-body p:last-child { margin-bottom: 0; }

/* A disclosure sitting inside a .note block must not inherit the note's own
   padding a second time, or every folded section would step further right
   than the sentence above it. */
.note > .disc, .note > .disc-body { padding-left: 0; }

/* ---------- THE TIERS-BY-DISTANCE GRID — card t_0f3ca42b --------------------
   WHAT  The grid the client drew: the price tiers across the top with Outlier
         and Total beside them, the distance bands down the side, and inside
         every box a stack of figures — Margin %, Revenue, Orders, Quantity —
         with the names of those figures printed ONCE in a narrow gutter at the
         left edge of the row rather than repeated inside all seven boxes.

   WHY   The screen this replaced was a list of 2,356 rows repeating "Tier 1 …
         Tier 5" under every distance band. The client: "the tiers are gonna be
         the columns … and then on the side you're gonna have the distance …
         you made everything in rows."

         The gutter is what makes a box readable without a label in it. Every
         box on a row holds the same lines in the same order, so once the eye
         has read "Margin %, Revenue, Orders, Quantity" down the left edge it
         can read the numbers straight across without re-reading a word.

   HOW   Nothing new enters the palette and nothing gains a radius. The stacked
         lines inside a box are plain blocks at the secondary type size with a
         fixed line height, so a box for a tier a product never shipped in —
         which prints an em dash on every line — is exactly as tall as the box
         beside it and the rows stay level.

         Rows are `height: auto` here, unlike every other grid in the product:
         a box holding four figures cannot fit the fixed 44px data row, and
         forcing it would clip the fourth line. The 44px minimum is kept, so a
         one-figure grid looks like every other table on the screen.

         The Total column is separated by the CONTAINER border weight — the
         heavier of the two — because it is a different kind of thing from the
         tier columns beside it, not another tier. That is the existing
         grammar, not a new one, and no third weight is introduced.
   -------------------------------------------------------------------------- */
.grid.tdgrid tbody td { height: auto; min-height: var(--h-row); vertical-align: top;
  padding-top: 8px; padding-bottom: 8px; }
.grid.tdgrid thead th { vertical-align: bottom; }

/* One figure inside a box, and one label in the gutter. Both use the same line
   height so the labels sit exactly on their numbers. */
.grid.tdgrid .mline {
  font-size: var(--t-body); line-height: 20px; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.grid.tdgrid .mline.none { color: var(--c-ink-3); }
.grid.tdgrid .mlabel {
  font-size: var(--t-control); color: var(--c-ink-2); text-align: left;
  font-variant-numeric: normal;
}

/* The whole box is the link to the order lines behind it, so the click target
   is the figures rather than a word beside them. It is still a link, so it is
   still underlined — on hover only, because seven underlined boxes on every
   row would be a wall of rules. */
.grid.tdgrid a.cellwrap { display: block; color: var(--c-ink); text-decoration: none; }
.grid.tdgrid a.cellwrap:hover { text-decoration: underline; color: var(--c-link); }

/* The two left-hand columns are given fixed widths so the gutter sits at the
   LEFT EDGE of the row, right beside the band name, rather than being pushed
   across the page by a long item description. Everything left over goes to the
   tier columns, whose figures are right-aligned and so stay level whatever
   width they end up at. */
.grid.tdgrid .tdname { width: 300px; max-width: 300px; }
.grid.tdgrid .tdname .sub { white-space: normal; }
.grid.tdgrid .tdgutter { width: 118px; white-space: nowrap; }
.grid.tdgrid .tdband { padding-left: 34px; color: var(--c-ink-2); font-weight: 600; }
.grid.tdgrid .tdtotal { border-left: 2px solid var(--c-border-container); }

/* The fold control on a product's summary line. It is a form button because it
   WRITES — the open products are remembered against the reader — so it must
   not be a link the browser may prefetch. It is drawn as the triangle the
   disclosures elsewhere in the product use, and nothing else. */
.grid.tdgrid .foldform { display: inline; }
.grid.tdgrid .fold {
  border: 1px solid var(--c-border-control); background: var(--c-surface);
  color: var(--c-ink-2); font-family: var(--font); font-size: 12px;
  width: 22px; height: 22px; line-height: 1; padding: 0; margin-right: 6px;
  vertical-align: baseline;
}
.grid.tdgrid .fold:hover { background: var(--c-band-service); color: var(--c-ink); }

/* ---------- THE SIGN-IN SCREENS — card t_81a598e6 --------------------------
   WHAT  The login screen, the "forgotten your password" screen and the
         "choose a password" screen. One box, centred on the canvas, carrying
         the crest and almost nothing else.

   WHY   Joe asked for "a regular login screen — username and password", and
         the card's design rule was that it must look like it belongs to this
         application: same crest, same palette, almost no words. So these
         screens use the same navy, the same cyan crest tile, the same square
         corners and the same two border weights as everything else. They do
         NOT use the crown, because the crown is a navigation bar for screens
         a stranger may not see.

   HOW   Every value below is a token. No raw hex, no radius, no third border
         weight — the same rules that govern the rest of this file. The box is
         2px --c-border-container because it is a container, and the strip
         across its top is the crown navy, so the login screen reads as the
         top of the application rather than as a different product.
   -------------------------------------------------------------------------- */
.gatepage {
  min-height: 100vh; background: var(--c-canvas);
  display: flex; align-items: center; justify-content: center;
  padding: var(--gutter);
}
.gatebox {
  width: 380px; max-width: 100%;
  background: var(--c-surface); border: 2px solid var(--c-border-container);
}
.gatecrown {
  height: var(--h-crown-row1); background: var(--c-crown);
  border-bottom: 2px solid var(--c-crown-border);
  display: flex; align-items: center; padding: 0 var(--pad-box);
}
.gateform { padding: var(--pad-window); }
.gatelabel {
  display: block; font-size: var(--t-control); color: var(--c-ink-2);
  margin-bottom: 4px;
}
.gateinp { width: 100%; margin-bottom: 14px; }
.gatego { width: 100%; margin-top: 4px; }
/* Status colour is TEXT ONLY here, exactly as everywhere else in the product:
   no fill, no chip, no coloured row. */
.gateproblem {
  font-size: var(--t-body); font-weight: 700; color: var(--c-urgent);
  margin-bottom: 14px;
}
.gatenote { font-size: var(--t-body); color: var(--c-ink); margin-bottom: 14px; }
.gatehelp { font-size: var(--t-secondary); color: var(--c-ink-2); margin-top: 14px; }

/* Sign out sits in the crown's utility row, so it is drawn as one of that
   row's small white links rather than as a button — but it IS a button,
   because signing out is a POST and must not be a link a browser may
   prefetch or another site may embed. */
.signout {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--font); font-size: 12px; color: var(--c-ink-invert);
  text-decoration: underline;
}
.signout:hover { color: var(--c-gold); }
