/* =========================================================================
   request.css — the triage page

   What lives here: the page's two columns, the items table's own column widths,
   the promotion-side parts (the substitute picker, the refusal reasons), and —
   the largest part of it — the PER-LINE TRIAGE CONTROL: five states, three
   verbs, the card that changes a decision already taken, the partial-hold
   dialog and the notice that goes up when a hold comes off.

   The five states are `requested` and `question` (the client's, and what
   "undecided" means), then `hold`, `rejected` and `ignored` (the rep's three
   verdicts). Only `hold` puts a line on the quote, and only `hold` carries a
   quantity of its own. The rules below are written in that order: the row's
   own recessive states first, then the control in the last column, then the
   card it opens, then the two dialogs behind it.
   ========================================================================= */

/* ---- Page shape: the items, and nothing beside them ----------------------
   ONE COLUMN. The rail held a status card and the notes; the status is now the
   chip in the page header and the per-line quote reference on the rows, and the
   notes open from the header. Nothing is left to stand beside the items.

   BUT THE PAGE IS STILL HELD TO A MEASURE. Given the whole 1440 the product
   column absorbs every pixel the other five do not want — about 500 of them —
   and a product name floats alone in the middle of an empty band. The cap is
   the old layout's own total, so the table is exactly as wide as it was.

   THE HEADER TAKES THE SAME CAP. Capping only the card left the title, the
   chips and the two marks running to an edge the work below them stopped short
   of, which reads as a page that failed to fill rather than one with a measure. */
.rq-layout, .page-header { max-width: 1180px; }

/* ---- A line the rep has answered -----------------------------------------
   A rejected line stays on the record — the client asked for it and the reason
   belongs next to it — and stops competing for attention. An ignored one
   recedes FURTHER, and that is deliberate: a rejection is a decision the client
   is holding a copy of and may come back on, an ignored line is one nobody
   outside this page knows about. It is the quietest row on the request.

   The decision column is exempt from the dimming in both cases. It is the one
   thing on a recessive row that still has to be legible and pressable, because
   changing your mind is what it is there for. */
tr.rq-line--rejected > td:not(.col-decide) { opacity: .62; }
tr.rq-line--ignored  > td:not(.col-decide) { opacity: .48; }
tr.rq-line--rejected .col-total,
tr.rq-line--ignored  .col-total { text-decoration: line-through; }

/* ---- Per-line decision: the three verbs ----------------------------------
   A ROW WAITING ON A DECISION SHOWS THE DECISION, not a badge you have to press
   to find one — the whole job on this page is answering these rows, and a
   control that has to be opened before it can be seen makes the job two presses
   long instead of one. Once the row is answered the buttons give the place back
   to a badge, which is what the column has always held.

   SPELLED OUT, and the width comes from somewhere: Format / Finish moved under
   the product name and handed this column its 145px, which is what a text
   button can be afforded on. Icon-only asked the rep to know that a padlock
   meant reserve and a struck eye meant say nothing — on the one control the
   page exists for, that is a riddle to solve before the work starts.

   THREE PEERS, THREE SEPARATE BUTTONS. The segmented group read as one control
   with three settings; the verbs are not settings of anything, so the panel
   behind them is gone and each stands on its own.

   Nothing starts chosen, and nothing is coloured until it is. Hold used to wear
   the primary fill at rest, which made the row look answered before anyone had
   read it and made blue mean "press here" on a page where blue means nothing of
   the kind. Each verb keeps its own colour for the moment it is pressed or
   pointed at, and rests in plain control grey. */
/* Format and finish, printed under what it describes. It sits a step below the
   material's own line — origin is what the stone IS, the spec is what was asked
   of it — and it is the line allowed to wrap when the column runs short. */
.rq-items .col-prod .rq-spec { color: var(--color-text-muted); }

/* ---- When the line was asked for -----------------------------------------
   Quiet, and it does not wrap: the page merges asks that arrived weeks apart,
   so the date is what separates a row sitting since July from one that came in
   this morning — but it is a fact about the row, not the row's subject, so it
   reads in the same ink as the meta lines beside it. */
.rq-items .col-date { color: var(--color-text-muted); font-size: 11px; white-space: nowrap; }

/* ---- The line that names its piece ---------------------------------------
   In front of the material line, where the piece reference it is about is
   printed, and only where the client pointed at a specific slab. The generic
   ask — any
   piece of this material — carries no mark: most asks are generic, so marking
   them put a glyph on every row and the pair read as a column of product icons
   rather than as a distinction. A fingerprint is the mark because that is what
   it says: this exact one. The full sentence is on the title and the
   aria-label, so the mark is never the only place it is said. */
.rq-kindico {
  display: inline-flex; align-items: center; vertical-align: -2px;
  margin-right: 4px; color: var(--color-info);
}
.rq-kindico svg { width: 13px; height: 13px; stroke-width: 2; }

/* ---- The band that separates one kind of ask from another ----------------
   Quote lines, samples and holds sit in one table because they are one client's
   outstanding asks, but they are answered three different ways — so a band says
   which is which and what its rows are for. Quieter than the table head above
   it: this is a divider inside a list, not a second header for it. */
/* The band spans every column, which makes it the row's last cell — and the
   platform right-aligns a last cell, because that is where figures belong. This
   one is a heading, so it is pulled back to the left the columns start at. */
.rq-items tbody tr.rq-band td {
  padding: 16px 12px 5px; text-align: left;
  background: none; border-bottom: 1px solid var(--color-border);
}
.rq-items tbody tr.rq-band:first-child td { padding-top: 4px; }
.rq-band-h {
  display: block; font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.06em; color: var(--color-text);
}
.rq-band-s { display: block; margin-top: 2px; font-size: 11px; color: var(--color-text-muted); }

/* The empty state, and the count on each dispatch button --------------------
   A line that has been sent leaves the table, so both of these are states the
   page reaches by being worked rather than by being loaded. */
.rq-items tbody td.rq-empty {
  padding: 26px 12px; text-align: center;
  font-size: 13px; color: var(--color-text-muted);
}
/* How many lines the press is about to send, set into the button's own label —
   the reading that makes it obvious the button does not need a finished list,
   only a chosen one. */
.rq-go-n { font-weight: 700; }
.rq-go-n:not(:empty) { margin-left: 1px; }

/* ---- The dispatch, at the head of the list -------------------------------
   The two presses sit beside Ask Client a Question, on the card's own header
   row: dispatching is what the list is for, and under the table it fell below
   the fold on any client with a dozen open lines. `display: contents` dissolves
   the wrapper the script writes into, so its buttons are laid out by the row
   itself and wrap with the rest of it rather than forming a block of their own. */
.rq-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
/* The question, above the panel rather than inside it — a column flex item that
   takes only its own width and sits at the right edge, so it lands over the
   dispatch buttons without joining their row. Hidden it costs nothing: a
   display:none flex item draws no gap. */
.rq-ask-out { align-self: flex-end; }
#rq-decide { display: contents; }
/* The counts close the table they are a reading of — held, already quoted, and
   what the held ones come to — opposite the line count. */
.rq-foot-count { justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* The notes mark in the page header: the icon, with how many there are set
   into its corner. A request with none shows the mark bare — a nought is a
   figure the eye stops on to read, and it says nothing. */
/* The mark is grey, not ink. A pen-and-notebook glyph in full text colour was
   the heaviest thing in the header cluster — blacker than the play beside it and
   denser than any label on the page — and weight here reads as urgency the notes
   do not have. Muted, with a plain note for a shape. Hover still takes it to the
   primary, so the button answers the pointer like every other one. */
.rq-notes-btn { position: relative; color: var(--color-text-muted); }
.rq-notes-n {
  position: absolute; top: -5px; right: -5px;
  min-width: 16px; height: 16px; padding: 0 4px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 7px; font-size: 10px; font-weight: 700; line-height: 1;
  background: var(--color-primary); color: #fff;
}

.rq-decide-cell { display: flex; justify-content: flex-end; align-items: center; gap: 6px; }
.rq-dec { display: inline-flex; gap: 5px; }
.rq-dec button {
  height: 30px; padding: 0 9px; gap: 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-control);
  border: 1px solid var(--color-control-border); border-radius: 6px;
  color: var(--color-text-muted);
  font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap;
  cursor: pointer;
  transition: background 120ms, color 120ms, border-color 120ms;
}
.rq-dec button svg { width: 14px; height: 14px; }
.rq-dec button[data-decide="hold"]:hover {
  background: var(--color-success-50); border-color: var(--color-success); color: var(--color-success-ink);
}
.rq-dec button[data-decide="rejected"]:hover {
  background: var(--color-danger-50); border-color: var(--color-danger); color: var(--color-danger-ink);
}
/* Ignore has no colour of its own to reach for — it is the silent one — so it
   darkens instead. The ground stays a control ground either way; a button that
   went white here would be a white box on a white cell. */
.rq-dec button[data-decide="ignored"]:hover {
  border-color: var(--color-text-muted); color: var(--color-text);
}

/* Releasing a hold is housekeeping, not a failure — the slabs simply go back on
   the market. `.confirm-thumb` is hardcoded to the danger ground in app.css for
   the destructive dialogs that share it, so this one overrides to the informational
   family rather than announcing a routine release in red. */
#modal-hold-released .confirm-thumb {
  background: var(--color-info-50);
  border-color: var(--color-info-50);
  color: var(--color-info);
}

/* The client asked something about this line. It is not one of the three — a
   question is theirs, and the three verbs are ours — so it stands BEFORE them
   rather than among them, and it is the only thing on the page that says a
   question is out on this row. */
.rq-dec-q {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 18px; height: 18px; border-radius: 5px;
  font-size: 11px; font-weight: 700;
  background: var(--color-warn-50); color: var(--color-warn-ink);
  border: 1px solid color-mix(in oklab, var(--color-warn) 34%, var(--color-warn-50));
  cursor: default;
}

/* THE BADGE IS A BUTTON. Once the row is answered it is what stands in the
   decision column, and pressing it opens the card that changes the answer — a
   hover border is the only tell that it is pressable, which is right for
   something rarer than the first decision. */
.rq-mat-status { cursor: pointer; line-height: inherit; }
.rq-mat-status:hover { border-color: currentColor; }
.rq-mat-status svg { width: 10px; height: 10px; }

/* The row's own actions — substitute, ask — which are edits to the line rather
   than verdicts on it. Sized down to what the column has left after the three
   verbs and the "?" chip have taken theirs. */
.rq-row-menu { display: inline-flex; flex: none; }
.rq-row-menu__btn {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 24px; height: 26px; padding: 0;
  background: none; border: 0; border-radius: 5px;
  color: var(--color-text-subtle); cursor: pointer;
  transition: background 120ms, color 120ms;
}
.rq-row-menu__btn svg { width: 15px; height: 15px; }
.rq-row-menu__btn:hover { background: var(--color-control); color: var(--color-text); }

/* ---- The card that changes a decision already taken ----------------------
   IT ESCAPES THE TABLE, and it has to. Both this and the row menu hang off the
   LAST column of a table inside `.table-wrap`, which is `overflow-x: auto` with
   `overflow-y: hidden` — an absolutely positioned card would be cut off at the
   height of the table, and on a one-line request almost all of it would be. So
   it is `position: fixed` and placed by `rqPop()` in the page's script, to the
   trigger's LEFT where the row has room: the columns to its right are an edge.

   It is a card, not a menu: the material's name over the moves, and under each
   move a line saying what it does, at a pace a decision deserves. Opened and
   closed by the same `.dropdown-menu.open` every menu on the portal uses; only
   the place and the shape are overridden here. 7px is the house radius ceiling.
   */
.rq-step { display: inline-flex; flex: none; min-width: 0; }
.dropdown-menu.rq-pop { position: fixed; top: 0; left: 0; right: auto; border-radius: 7px; }
.dropdown-menu.rq-step-pop { width: 276px; padding: 14px 12px 8px; text-align: left; cursor: default; }
.dropdown-menu.rq-row-pop { min-width: 210px; }
.rq-step-head {
  display: flex; flex-direction: column; gap: 2px;
  padding: 0 6px 10px; margin-bottom: 6px;
  border-bottom: 1px solid var(--color-border);
}
.rq-step-name { font-size: 13px; font-weight: 600; }
.rq-step-sub { font-size: 11px; color: var(--color-text-subtle); }
.rq-step-opt {
  display: flex; align-items: center; gap: 12px; width: 100%;
  padding: 9px 6px; border: 0; border-radius: 5px; background: none;
  font: inherit; text-align: left; color: var(--color-text); cursor: pointer;
  transition: background-color 120ms;
}
.rq-step-opt:hover { background: var(--color-primary-50); }
.rq-step-opt--no:hover { background: var(--color-danger-50); }
/* The verb is a glyph in its own small box, on the control ground (memory §13). */
.rq-step-ico {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 28px; height: 28px; border-radius: 5px;
  background: var(--color-control); color: var(--color-text-muted);
}
.rq-step-ico svg { width: 15px; height: 15px; }
.rq-step-opt--no .rq-step-ico { color: var(--color-danger); }
.rq-step-txt { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1 1 auto; }
.rq-step-l { font-size: 13px; font-weight: 600; }
.rq-step-opt--no .rq-step-l { color: var(--color-danger); }
.rq-step-h { font-size: 11px; color: var(--color-text-subtle); }
/* THE ONE THE ROW IS ALREADY IN. The card shows all three and says which is
   taken, rather than listing only the moves available from where the row stood
   and leaving the reader to infer the rest from what was missing. It goes onto
   the control ground rather than a tint, because a tint here would read as the
   hover state of whichever option is under the pointer. */
.rq-step-opt--on { background: var(--color-control); }
.rq-step-opt--on .rq-step-ico { background: var(--color-surface); }
.rq-step-on { flex: none; width: 15px; height: 15px; color: var(--color-success); }
/* Undoing is not a fourth verdict, so it is set apart from the three by a rule
   and reads a step quieter than them. */
.rq-step-clear {
  margin-top: 6px; padding-top: 12px;
  border-top: 1px solid var(--color-border); border-radius: 0;
}
.rq-step-clear .rq-step-l { font-weight: 500; color: var(--color-text-muted); }

/* ---- How much of the ask is being held -----------------------------------
   The field, the unit it counts in and what the client asked for read as one
   sentence across one line — "4 slabs of 6 asked for" — which is what a label
   above the box and a hint below it would take three lines to say. */
.rq-hold-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rq-hold-unit { font-size: 13px; font-weight: 600; }
.rq-hold-of { font-size: 12px; color: var(--color-text-muted); }
/* A disabled button says no without saying why, and the why is different at
   each end of the range — so the refusal stands with the number that caused it. */
.rq-hold-warn { margin: 8px 0 0; font-size: 11px; color: var(--color-danger); }
/* A number of slabs and the word for them — both sized to what they hold, so
   the pair reads as one phrase instead of two boxes stretched across the dialog. */
.rq-num-in { width: auto; max-width: 96px; flex: 0 0 auto; }

/* ---- Which bundle, and which end -----------------------------------------
   The picker that turns a held NUMBER into held STONE. It opens with nothing
   chosen, per the standing rule for every picker on the platform, and the ends
   only appear once a bundle is chosen — an end with no bundle behind it is not
   a thing anyone can press meaningfully. */
.rq-pick-hint { margin: 0 0 8px; font-size: 11px; color: var(--color-text-muted); }
.rq-pick-list { display: flex; flex-direction: column; gap: 8px; }
/* Nothing on this dialog sits on the dialog's own white (§13), so the bundle
   takes the control ground and the slab chips on it invert back to white. */
.rq-pick {
  background: var(--color-control);
  border: 1px solid var(--color-border-strong);
  border-radius: 7px;
  overflow: hidden;
  transition: border-color 120ms;
}
.rq-pick:hover { border-color: var(--color-primary); }
.rq-pick--on { border-color: var(--color-primary); background: var(--color-primary-50); }
/* THE PRESS COVERS THE WHOLE CARD, heading and sequence together. The strip used
   to sit outside this button, which left the numbers — the biggest thing in the
   card — dead to a click, and a rep who pressed them concluded the dialog was
   broken. Everything but the two end buttons is inside it now. */
.rq-pick-main {
  display: flex; flex-direction: column; gap: 7px;
  width: 100%; padding: 9px 11px; text-align: left;
  background: none; border: 0; cursor: pointer;
  font-family: inherit; color: var(--color-text);
}
/* Reference, then specification, then what is left — one row, read left to
   right, with the count last because it is the figure the eye compares down
   the list. */
.rq-pick-head { display: flex; align-items: baseline; gap: 10px; width: 100%; }
/* The same row when there is nothing to press: a line that named its bundle has
   already answered both of this dialog's questions, so the bundle is shown
   rather than offered. It keeps the layout and drops the hand cursor and the
   hover — a control that does not react is worse than plain text, because the
   rep spends a click finding out. */
.rq-pick-main--fixed { cursor: default; }
/* The press shows itself before it is made. A border that shifts colour is too
   small a move for a card this size — "where am I supposed to click" was the
   first thing this dialog was asked — so the ground under the pointer lifts too.
   A chosen card already carries that tint and does not need it twice. */
.rq-pick:not(.rq-pick--on) .rq-pick-main:hover {
  background: color-mix(in oklab, var(--color-primary) 8%, var(--color-control));
}
.rq-pick-ref { font-size: 13px; font-weight: 600; display: flex; align-items: center; gap: 6px; }
/* The bundle the client themselves named, where the supplier lets them name
   one. It is a flag, not a selection: the rep still has to press the row. */
.rq-pick-asked {
  font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em;
  padding: 1px 5px; border-radius: 7px;
  background: var(--color-info-50); color: var(--color-info-ink);
}
.rq-pick-spec { font-size: 11px; color: var(--color-text-muted); flex: 1; min-width: 0; }
.rq-pick-free { font-size: 11px; color: var(--color-text-muted); white-space: nowrap; }
.rq-pick-free strong { color: var(--color-text); }
/* The sequence, drawn. A bundle is an ORDER before it is a count, and the run
   about to be taken is shown filled in place — which is the only way the rule
   about ends explains itself without a paragraph. */
.rq-pick-seq { display: flex; flex-wrap: wrap; gap: 3px; }
.rq-slab {
  min-width: 22px; padding: 2px 4px; text-align: center;
  font-size: 11px; font-variant-numeric: tabular-nums;
  border-radius: 7px;
  background: var(--color-surface);
  border: 1px solid var(--color-control-border);
  color: var(--color-text-muted);
}
/* Gone is not a state of the hold, it is a fact about the yard — so it recedes
   rather than alarms, and the eye counts past it to the run that is left. */
.rq-slab--gone {
  background: var(--color-control); border-style: dashed;
  color: var(--color-text-subtle); text-decoration: line-through;
}
.rq-slab--on {
  background: var(--color-success-50); border-color: var(--color-success);
  color: var(--color-success-ink); font-weight: 600;
}
/* The piece the client pointed at, marked in the sequence rather than only named
   in the header. A ring rather than a fill, so it survives the run being lit
   green over the top of it — the two facts are independent and the rep needs
   both: this is what was asked for, and this is what is about to be reserved. */
.rq-slab--asked { border-color: var(--color-info); box-shadow: 0 0 0 2px var(--color-info-50); }
/* TWO BUTTONS, AND NO THIRD. The rule that a bundle breaks only from an end is
   enforced by there being no control that would break it. */
.rq-pick-ends {
  display: flex; gap: 8px; padding: 9px 11px;
  border-top: 1px solid var(--color-control-border);
}
.rq-end {
  flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 2px;
  padding: 7px 10px; text-align: left;
  background: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: 7px;
  font-family: inherit; color: var(--color-text);
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.rq-end:hover:not(:disabled) { border-color: var(--color-primary); }
.rq-end--on { background: var(--color-primary-50); border-color: var(--color-primary); }
/* An end too short for the ask is not hidden — the rep needs to know the stone
   is there and why it will not answer, so the reason replaces the range. */
.rq-end:disabled { cursor: not-allowed; opacity: 0.55; }
.rq-end-w { font-size: 13px; font-weight: 600; }
.rq-end-r { font-size: 11px; color: var(--color-text-muted); font-variant-numeric: tabular-nums; }
/* What the press is about to reserve, beside the button that reserves it. */
.rq-pick-sum { margin-right: auto; font-size: 12px; color: var(--color-text-muted); }
.rq-pick-empty { margin: 0; font-size: 12px; color: var(--color-text-muted); }

/* ---- Which quote the held lines land on ----------------------------------
   One container, one quote — so the figure that decides this is how full each
   open box already is, and it is drawn rather than said. */
.rq-dest-list { display: flex; flex-direction: column; gap: 8px; }
.rq-dest {
  display: flex; align-items: center; gap: 14px;
  width: 100%; padding: 10px 12px; text-align: left;
  background: var(--color-control);
  border: 1px solid var(--color-border-strong);
  border-radius: 7px;
  font-family: inherit; color: var(--color-text);
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.rq-dest:hover { border-color: var(--color-primary); }
.rq-dest--on { background: var(--color-primary-50); border-color: var(--color-primary); }
.rq-dest-main { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.rq-dest-no { font-size: 13px; font-weight: 600; }
.rq-dest-sub { font-size: 11px; color: var(--color-text-muted); }
/* The fill reads number-first then label, tight, like every other stat on the
   platform — never the figure pushed to one edge and its word to the other. */
.rq-dest-fill { display: flex; flex-direction: column; gap: 3px; width: 132px; flex: none; }
.rq-dest-bar {
  display: flex; height: 6px; border-radius: 7px; overflow: hidden;
  background: var(--color-surface);
  border: 1px solid var(--color-control-border);
}
.rq-dest-bar-now { background: var(--color-text-muted); }
/* What THIS request would add, in the colour of a thing being reserved, so the
   two parts of the bar answer two different questions. */
.rq-dest-bar-add { background: var(--color-success); }
.rq-dest-pct { font-size: 11px; color: var(--color-text-muted); }
.rq-dest-pct strong { color: var(--color-text); }
.rq-dest-by { font-size: 10px; color: var(--color-text-subtle); }
/* A box these lines would overfill is still offered and still says so —
   splitting a load across boxes is the Container Planner's job, not a refusal
   this dialog is entitled to make. */
.rq-dest--over .rq-dest-bar-add { background: var(--color-warn); }
.rq-dest--over .rq-dest-by { color: var(--color-warn-ink); font-weight: 600; }

/* The press that carries the held lines to a quote. Larger than the outline
   buttons beside it because it is the only thing on the bar that leaves. */

/* ---- Who else was waiting on it ------------------------------------------
   The queue behind a hold that has just come off. It is the answer rather than
   an offer to go and find it: the merged page ended this dialog with a button
   into the Stock module's demand panel, and there is no such panel here. */
.rq-int-list { display: flex; flex-direction: column; gap: 6px; margin-top: 14px; }
/* Name over specification, not name and specification at opposite edges: the
   two are one entry, and the qualifier goes UNDER the value it qualifies. The
   box takes the control ground because the dialog behind it is white (§13). */
.rq-int-row {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 10px; border-radius: 7px;
  background: var(--color-control);
  border: 1px solid var(--color-control-border);
}
.rq-int-who { font-size: 13px; font-weight: 600; }
.rq-int-spec { font-size: 11px; color: var(--color-text-muted); }

/* What the refusal dialog is about to do, said before a reason is picked. */
.rq-dec-scope { margin: 0 0 10px; font-size: 12px; color: var(--color-text-muted); }

/* What the footer is about to carry, in words, before the button is pressed. */
.rq-carry { margin-right: auto; font-size: 13px; color: var(--color-text-muted); }
.rq-carry strong { color: var(--color-text); }

/* ---- Substitute picker ---------------------------------------------------
   Opens showing every alternative on the promotion, with none of them chosen.
   A picker that has already answered itself is not offering a choice, and the
   one product the operator must NOT pick by accident is the one that was out
   of stock in the first place. */
.rq-sub-list { display: flex; flex-direction: column; gap: 6px; }
.rq-sub-opt {
  display: flex; align-items: center; gap: 10px;
  width: 100%; padding: 10px 12px; text-align: left;
  background: var(--color-control);
  border: 1px solid var(--color-border-strong);
  border-radius: 7px;
  font-family: inherit; font-size: 13px; color: var(--color-text);
  cursor: pointer;
  transition: background 120ms, border-color 120ms;
}
.rq-sub-opt .cell-stack { flex: 1; min-width: 0; }
.rq-sub-opt:hover { border-color: var(--color-primary); }
.rq-sub-opt[aria-pressed="true"] {
  background: var(--color-primary-50);
  border-color: var(--color-primary);
}
.rq-sub-price { font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- The two page columns ------------------------------------------------
   An `fr` track will not shrink below its content's min-content width, so the
   items table's own min-width and the four-control decision row were each
   holding their column open wider than its share — the pair added up past the
   right edge of the page and the notes card was cut off there. minmax(0, …)
   puts the 1:2 ratio back in charge of the width. Anything still too wide for
   the column it lands in scrolls inside its own box, which is what .table-wrap
   and .rq-stepper were already built to do. */
.cols-1-2 { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }


/* ---- Line items — columns addressed by class, never by position ----------
   The same table renders with and without the two money columns: a sample or
   a hold carries no price, and dropping a column must not move the ones that
   stay. Product absorbs whatever the pinned columns leave, in both shapes.

   Measured headlessly at min-content / max-content across all twenty-one
   requests; the comment on each line is measured → preferred / floor. The
   table sits in two thirds of the page, not the whole of it — 756px of content
   at a 1440 screen — so each column carries a floor UNDER its preferred width
   as well: the preferred width is what it takes when there is room, the floor
   is what it will not go below when there is not. The floors add up to what
   .rq-items--decide asks for, which is what makes the six-column shape fit a
   1440 screen without the box scrolling sideways.

   Format / Finish is gone as a column: it prints in the product cell's sub line
   instead, and its 145px went to the decision. It never described anything the
   product cell was not already describing, and standing in its own column it
   made the rep's one real job the narrowest thing on the row. */
.rq-items { table-layout: auto; min-width: 691px; max-width: 1947px; }
/* The date: "Aug 29, 2026" at 11px, plus the table's own 12px of padding each
   side. Pinned rather than absorbing, because it is the same string on every
   row and a column that never varies should never move. */
.rq-items thead th.col-date  { width: 96px; min-width: 88px; }
.rq-items thead th.col-prod  { width: 100%; }                                  /* absorber — 175 min → 293 max */
.rq-items thead th.col-qty   { width: 108px; min-width:  96px; }               /*  90 → 90 */
.rq-items thead th.col-price { width: 140px; min-width: 112px; }               /* 110 → 175 unstacked */
.rq-items thead th.col-total { width: 106px; min-width:  94px; }               /*  88 → 88 */
/* Sixth column, and only on an open request — a fixed shape, so it is pinned
   like the other non-absorbing ones and wide enough that "YOUR DECISION" keeps
   to one line. The table's min-width rises with it; without that the absorber
   pays for the column.

   MEASURED, not chosen — read off getBoundingClientRect at 1440, not eyeballed.
   The three text buttons come to 220px (64 + 73 + 73 on two 5px gaps), the row's own menu is
   another 24 at a 6px gap, and a line carrying a question puts an 18px "?" chip
   in front of the lot at another 6px gap. The CELL adds the table's own 12px of
   padding each side. The floor below is set against the ordinary row — a
   question row overflows it by the width of the chip, which is the one case
   this column is allowed to push the table sideways. */
.rq-items thead th.col-decide { width: 308px; min-width: 300px; }
.rq-items--decide { min-width: 861px; }

/* ---- The totals block ----------------------------------------------------
   The footer is not three more rows of the table — it is what the rows above
   add up to — so it closes the table on the same band its header opens it
   with, behind a full-width rule rather than the per-column marks the item
   rows carry.

   It also needs its own padding: every .data-table padding rule names thead or
   tbody, so tfoot cells were falling back to the UA's own and the figures sat
   a pad-width RIGHT of the line totals directly above them. --table-pad-x puts
   the two columns back on one edge. */
.rq-items tfoot td {
  padding: 7px var(--table-pad-x);
  background: var(--color-table-head);
  vertical-align: middle;
}
/* The label rides tight against its figure: the pad between the two columns is
   the whole reason a total read as a label stranded from its number. */
.rq-items tfoot td:first-child { padding-right: 0; }
/* The bar that closes the items off sits ABOVE the first total, not below the
   last item: a rule under the last row would read as that row's own boundary. */
.rq-items tfoot tr:first-child td {
  border-top: 2px solid var(--color-border-strong);
  padding-top: 11px;
}
/* A lighter one over the figure that is actually being agreed to, so the grand
   total is not just the third row of a stack. */
.rq-items tfoot tr:last-child td {
  border-top: 1px solid var(--color-border-strong);
  padding-bottom: 11px;
}

/* ---- Editable quantity ---------------------------------------------------
   The quantity is the one figure on this page an operator corrects before the
   request becomes a quote, so it is the one cell that is a field. Only the
   number is: the unit drops to the sub-line with the coverage figure, because
   a field wide enough to edit plus a "pallets" label beside it does not fit the
   96px this column is floored at — and that floor is what keeps the six-column
   shape off a horizontal scrollbar at 1440.

   Capped at four digits ("400 sqft" is the largest quantity the catalog makes)
   and right-aligned by the .num cell it sits in, so the figure keeps the same
   edge as the prices below it. Its ground is --color-control like every other
   field; a white box would sit invisibly on the white card. */
.rq-items .rq-qty__n {
  width: 100%;
  max-width: 66px;
  padding: 5px 8px;
  text-align: right;
}
/* Unit and coverage on one subtle line under the field — "slabs · 68 sqft".
   The cell is nowrap, so this is what the column's 108px is spent on. */
.rq-items .rq-qty__s {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  color: var(--color-text-subtle);
}
/* An open-ended quantity ("25+ slabs") has no single number to edit, so it
   stays the text it always was rather than becoming a field that lies. */
.rq-items .rq-qty__flat { font-weight: 500; }
/* WHAT THE CLIENT ORIGINALLY ASKED FOR, shown only once the field above no
   longer says it. The quantity is editable, so correcting six to two otherwise
   erases the only record of the six on the page. It reads as the client's
   figure — the same subtle grey as the unit line, struck the way a superseded
   number is struck two columns to the right — not as a decision the rep made,
   which is what the green line under it is for. */
.rq-items .rq-qty__o {
  display: block;
  margin-top: 3px;
  font-size: 11px;
  color: var(--color-text-subtle);
  text-decoration: line-through;
}
.rq-items .rq-qty__o[hidden] { display: none; }
/* WHAT THE REP IS HOLDING OUT OF THE ASK, and the last line of the cell because
   it is the only one that is not the client's. It appears only on a PARTIAL
   hold — "holding 6 of 6" is noise — and it takes the hold's own green and a
   little weight rather than the subtle grey the derived readings sit in,
   because it is a decision rather than a consequence of one, and it is the
   number the money beside it was written from. 11px, one step under the 12px of
   the field above it. */
.rq-items .rq-qty__h {
  display: block;
  margin-top: 3px;
  font-size: 11px; font-weight: 600;
  color: var(--color-success-ink);
}
.rq-items .rq-qty__h[hidden] { display: none; }

/* Unit price with a discount — list price struck through, sold price in accent */
.rq-list { text-decoration: line-through; color: var(--color-text-subtle); font-weight: 400; margin-right: 5px; }
/* In the line-item table the struck list price takes its own line above the
   figure that replaced it, rather than sitting beside it. Side by side the two
   figures were the widest thing in the column by 60px, and that width was
   being taken from the product name and the format beside it — for a price
   nobody is being charged. */
.col-price .rq-list { display: block; margin-right: 0; font-size: 11px; }
/* And the same again in the Line Total column, for the same measured reason. On
   a PARTIAL hold that cell carries two figures — what the whole ask came to,
   struck, and the money actually being held — and side by side they are 155px in
   a 106px column: the table stopped fitting its own scroller and grew a
   horizontal bar at 1440. Stacked, the struck figure costs a line instead of the
   product name's width, which is the trade this page has already made once. */
.col-total .rq-list { display: block; margin-right: 0; font-size: 11px; }
.rq-sold { color: var(--color-primary-700); font-weight: 700; }

/* ---- Decline reasons -----------------------------------------------------
   Four mutually exclusive reasons as loose chips, deliberately NOT the
   .subtabs--choice segmented control: that is a two-column grid meant for a
   Yes/No pair, and four options inside its bordered track render as a boxed
   2x2 that reads as two choices rather than four. Dropping the track leaves
   four separate things, which is what they are.

   Each chip sits on the control ground with a real border — the modal is
   white, and a near-white chip on white was the whole of the readability
   complaint. The chosen one goes solid rather than tinted, so which reason is
   selected survives a glance. */
.rq-reasons { display: flex; flex-wrap: wrap; gap: 8px; }
.rq-reason {
  font: inherit; font-size: 13px; font-weight: 500; line-height: 1.2;
  padding: 8px 14px; cursor: pointer;
  color: var(--color-text);
  background: var(--color-control);
  border: 1px solid var(--color-control-border);
  border-radius: 7px;
}
.rq-reason:hover { border-color: var(--color-primary); color: var(--color-primary-700); }
.rq-reason.active {
  background: var(--color-primary); border-color: var(--color-primary);
  color: #fff; font-weight: 600;
}

/* ---- PDF export ----------------------------------------------------------
   The same artwork the catalog toolbar uses (img/ExportPDF.png), at the same
   34px. Carried on a bare button rather than a .btn-outline: the mark is drawn
   with its own edges, so a button box around it reads as a border on a border.
   Sized here rather than inline, which is where the catalog still does it. */
.pdf-export {
  display: inline-flex; align-items: center;
  padding: 0; background: none; border: 0; cursor: pointer;
}
.pdf-export img { display: block; height: 34px; width: auto; }

/* BELOW 1400 THE VERB IS DRAWN, NOT SAID. The three words are what makes this
   column 300px, and 300px is what pins the table at 777 — wider than the card it
   sits in on any screen under about 1400, so the row scrolled sideways and the
   rep lost the end of its own decision. The glyphs stay, and every one of them
   keeps the aria-label and the title that say the word in full, so nothing is
   lost but the width. Above 1400 the words are back, because that is where they
   fit. */
@media (max-width: 1400px) {
  .rq-dec button > span { display: none; }
  .rq-dec button { padding: 0 7px; }
  .rq-items thead th.col-decide { width: 160px; min-width: 150px; }
  .rq-items--decide { min-width: 711px; }
}

/* AND BELOW 1250 THE NUMBERS GIVE TOO. Icon verbs alone still leave the table
   wider than the card between about 1100 and 1230 — the sidebar is open and the
   page is narrow. The three numeric columns come down to what their figures
   actually measure. The product column is left to wrap: forcing it onto one
   line with an ellipsis RAISES its minimum rather than lowering it, because a
   nowrap cell measures the whole string. */
@media (max-width: 1250px) {
  .rq-items thead th.col-qty   { width: 86px; min-width: 84px; }
  .rq-items thead th.col-price { width: 98px; min-width: 96px; }
  .rq-items thead th.col-total { width: 86px; min-width: 84px; }
  .rq-items--decide { min-width: 644px; }
}
