/* Masters Telecom — public quote app
 * Design system extracted verbatim from Pete's two rep-facing configurators
 * (docs/superpowers/specs/2026-07-17-design-system-extraction.md). Flat,
 * dense, B2B — no gradients, no drop shadows (the one "shadow" anywhere is
 * the inset selected-option ring). Montserrat is self-hosted below so this
 * page never adds an external origin (CSP stays default-src 'self').
 */

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/montserrat-400.woff2") format("woff2");
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/montserrat-600.woff2") format("woff2");
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/montserrat-700.woff2") format("woff2");
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 800;
  font-display: swap;
  src: url("/fonts/montserrat-800.woff2") format("woff2");
}

:root {
  --navy: #1A2B62;
  --adr: #4194BC;
  --accent-strong: #2f789c;
  --lt: #A0C6DB;
  --muted: #5f6470;
  --ink: #20263a;
  --line: #e3e8f0;
  --surface: #f4f7fb;
  --white: #fff;
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --control-min: 44px;
}

* { box-sizing: border-box; }

/* Task 43: several elements below are toggled purely via the `hidden`
 * attribute (app.js sets `.hidden = true/false`, never a class) AND also
 * carry their own `display:flex` rule for when they're shown (#composer,
 * #transcript). Author-stylesheet rules always beat the browser's built-in
 * `[hidden] { display: none }` UA rule regardless of selector specificity,
 * so without this reset an element with both `hidden` set AND an ID rule
 * that declares `display` would render anyway — a real bug, caught live in
 * the Browser pane (task-43 verification): the composer showed BEFORE
 * Turnstile verification. This one rule must stay ahead of every other
 * selector in this file that sets `display` on an element toggled by
 * `hidden`. */
[hidden] { display: none !important; }

body {
  margin: 0;
  font-family: "Montserrat", "Helvetica Neue", Arial, sans-serif;
  line-height: 1.4;
  color: var(--ink);
  background: var(--surface);
  -webkit-font-smoothing: antialiased;
  font-size: var(--text-base);
}

h1, h2, h3, h4, p, ul, figure { margin: 0; }

/* ---------------------------------------------------------------- header */
.top {
  background: var(--navy);
  color: var(--white);
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 20px;
  padding: 18px 32px;
}
.top img { height: 30px; display: block; }
.top .t h1 {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--white);
}
.top .t h1 span { color: var(--lt); }
.top .t .sub {
  font-size: var(--text-sm);
  color: var(--lt);
  margin-top: 2px;
}

/* ------------------------------------------------------------ main grid */
.wrap {
  max-width: 1180px;
  margin: 0 auto;
  padding: 22px 32px 60px;
  display: grid;
  grid-template-columns: 1fr 360px;
  gap: 26px;
  align-items: start;
}
.sum { position: sticky; top: 18px; }

/* Desktop: the rail is always visible, so the mobile handle is not needed. */
.quote-bar { display: none; }

@media (prefers-reduced-motion: reduce) {
  .quote-bar-caret { transition: none; }
}

/* ------------------------------------------------------------ step card */
.step {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 15px 17px;
  margin-bottom: 13px;
}
.step h2 {
  display: flex;
  align-items: center;
  gap: 9px;
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--navy);
  margin-bottom: 3px;
}
.step h2 .num {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white);
  font-size: var(--text-sm);
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}
.hint {
  font-size: var(--text-sm);
  color: var(--muted);
  margin: 0 0 10px;
}
/* Only the hint directly under a step's own h2 is indented to clear the
 * number circle — hints nested deeper (inside the degraded-mode wizard's
 * .q question blocks) keep the plain unindented rule above. */
.step > h2 + .hint { margin-left: 29px; }

.q { margin-bottom: 10px; }
.q .qlabel { font-size: var(--text-sm); font-weight: 700; color: var(--navy); margin: 0 0 4px; }

/* ---------------------------------------------------------- option grid */
.opts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}
.opt {
  display: block;
  position: relative;
  width: 100%;
  text-align: left;
  background: var(--white);
  border: 1.5px solid var(--line);
  border-radius: 8px;
  padding: 9px 11px;
  font-family: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color .12s ease, background-color .12s ease;
  min-height: var(--control-min);
}
.opt:hover:not(:disabled) { border-color: var(--adr); }
.opt[aria-pressed="true"] {
  border-color: var(--adr);
  background: #eef6fb;
  box-shadow: inset 0 0 0 1px var(--adr);
  padding-right: 34px;
}
.opt[aria-pressed="true"]::after {
  content: "✓";
  position: absolute;
  top: 8px;
  right: 10px;
  color: var(--navy);
  font-size: var(--text-sm);
  font-weight: 800;
}
.opt:disabled {
  opacity: 1;
  background: #f4f5f8;
  border-color: #cdd3df;
  cursor: not-allowed;
}
.opt .on { display: block; font-size: var(--text-sm); font-weight: 700; color: var(--navy); }
.opt .od { display: block; font-size: var(--text-sm); color: var(--muted); margin-top: 2px; line-height: 1.4; }
.opt:disabled .on { color: #535b6c; }
.opt:disabled .od { color: #656d7d; font-weight: 600; }

/* ------------------------------------------------------------------ chip */
.chip {
  display: inline-flex;
  align-items: center;
  background: #eef6fb;
  border: 1px solid var(--lt);
  color: var(--navy);
  border-radius: 20px;
  padding: 3px 10px;
  font-size: var(--text-sm);
  font-weight: 600;
}
.chip b { font-weight: 800; }
/* Task 35: EOL-check status badge for an active/still-sold model — same
 * chip shape, colored with the .ok callout's palette (a status SEVERITY
 * cue, not a new component). eos/eol/discontinued reuse the full .warn/
 * .conf callouts as-is rather than a second chip variant. */
.chip.ok { background: #eef6f0; border-color: #2e7d32; color: #14501a; }

/* -------------------------------------------------------------- callouts
 * Four flavors, one shared shape — square left edge, rounded right, a 3px
 * colored left border reading as a flush accent tab. */
.warn, .conf, .ok, .why {
  border-radius: 0 6px 6px 0;
  padding: 10px 12px;
  font-size: var(--text-sm);
  margin-top: 10px;
}
.warn { background: #fff6e8; border-left: 3px solid #d98c2b; color: #7a4d10; padding: 7px 10px; line-height: 1.35; }
.warn b { color: #5c3a0c; }
.conf { background: #fbeeee; border-left: 3px solid #C0504D; color: #7a2d2b; font-size: var(--text-sm); }
.conf b { color: #9a3b39; }
.ok { background: #eef6f0; border-left: 3px solid #2e7d32; color: #1b5e20; padding: 7px 10px; line-height: 1.35; }
.ok b { color: #14501a; }
.why { background: #eef6fb; border-left: 3px solid var(--adr); color: #3d4453; padding: 11px 13px; }
.why h4 {
  text-transform: uppercase;
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: .05em;
  color: var(--navy);
  margin-bottom: 6px;
}
.why ul { list-style: none; padding: 0; margin: 0; }
.why li { position: relative; padding-left: 12px; margin-bottom: 4px; font-size: var(--text-sm); line-height: 1.5; }
.why li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 8px;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--adr);
}
/* Numbered lists from renderProse. The .why li rule above draws a teal dot
   via ::before for bullet lists; an <ol> needs its own counter instead, and
   must suppress that dot or every item renders BOTH a number and a dot. */
.why ol { list-style: decimal; padding: 0 0 0 18px; margin: 0; }
.why ol li { padding-left: 0; }
.why ol li::before { content: none; }
/* --------------------------------------------------------------- landing
 * Task 43 (decision #4): one big input + tappable example prompts, shown
 * once between Turnstile verification and the first message sent. */
.landing-h {
  font-size: 16px;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--navy);
  margin-bottom: 3px;
}
#landing-chips { margin-top: 10px; }

/* --------------------------------------------------------- task-first home */
.task-home {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 18px;
  margin-bottom: 13px;
}
.task-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
body.speedfusion-available .task-grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.task-card {
  position: relative;
  width: 100%;
  min-height: 112px;
  padding: 15px 42px 15px 15px;
  border: 2px solid var(--line);
  border-radius: 9px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.task-card:hover { border-color: var(--accent-strong); background: #f5fafd; }
.task-card[aria-pressed="true"] {
  border-color: var(--accent-strong);
  background: #eef6fb;
  box-shadow: inset 0 0 0 1px var(--accent-strong);
}
.task-card[aria-pressed="true"]::after {
  content: "✓";
  position: absolute;
  top: 14px;
  right: 15px;
  color: var(--navy);
  font-size: var(--text-base);
  font-weight: 800;
}
.task-title {
  display: block;
  color: var(--navy);
  font-size: var(--text-base);
  font-weight: 800;
  line-height: 1.35;
}
.task-detail {
  display: block;
  margin-top: 5px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.45;
}
.quote-finder { margin-top: 0; }
.quote-finder-selected {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
}
.quote-finder-selected-copy { min-width: 0; }
.quote-finder-selected-copy .opt-kicker { margin: 0 0 2px; }
.quote-finder-selected-copy > p:last-child {
  color: var(--ink);
  font-weight: 700;
  overflow-wrap: anywhere;
}
.quote-finder-selected .btn { flex: none; }
.catalog-search-row {
  display: flex;
  align-items: stretch;
  gap: 8px;
}
.catalog-search-row input { flex: 1; min-width: 0; }
.catalog-search-row .btn { flex: none; }
.search-status {
  min-height: 1.45em;
  margin: 9px 0 5px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.45;
}
.search-status[data-tone="error"] { color: #9a3b39; font-weight: 600; }
.catalog-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 7px;
  margin-top: 7px;
}
.catalog-option {
  position: relative;
  display: block;
  width: 100%;
  min-height: var(--control-min);
  padding: 11px 40px 11px 12px;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
  overflow-wrap: anywhere;
}
.catalog-option:hover,
.catalog-option.is-active {
  border-color: var(--accent-strong);
  background: #f5fafd;
}
.catalog-option.is-active::after {
  content: "→";
  position: absolute;
  top: 10px;
  right: 13px;
  color: var(--navy);
  font-size: var(--text-lg);
  font-weight: 800;
}
.catalog-title,
.catalog-sku,
.catalog-meta,
.catalog-exact,
.catalog-lifecycle,
.catalog-reason { display: block; }
.catalog-title { color: var(--navy); font-size: var(--text-sm); font-weight: 800; }
.catalog-sku { margin-top: 2px; color: var(--ink); font-size: var(--text-sm); font-weight: 700; }
.catalog-meta,
.catalog-lifecycle { margin-top: 3px; color: var(--muted); font-size: var(--text-sm); line-height: 1.4; }
.catalog-exact { margin-top: 4px; color: var(--navy); font-size: var(--text-sm); font-weight: 700; }
.variant-section {
  margin-top: 14px;
  padding-top: 13px;
  border-top: 1px solid var(--line);
}
.variant-section h3 { color: var(--navy); font-size: var(--text-base); }
.variant-section > .hint { margin-top: 3px; }
.variant-option[aria-disabled="true"] {
  border-style: dashed;
  background: var(--surface);
  cursor: not-allowed;
}
.catalog-reason { margin-top: 5px; color: #9a3b39; font-size: var(--text-sm); font-weight: 700; }
.catalog-empty {
  margin-top: 10px;
  padding: 11px 12px;
  border-left: 3px solid var(--adr);
  background: #eef6fb;
}
.catalog-empty > p { font-size: var(--text-sm); line-height: 1.45; }
.catalog-fallback-buttons { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.catalog-fallback-buttons .linkish { margin-top: 0; }
#catalog-lifecycle-result { margin-top: 10px; }

/* A .chip made clickable (design-spec topOffersPattern's own suggested
 * hybrid: the package-picker's CLICK behavior, styled as the pill). Every
 * other .chip in this system stays a plain non-interactive <span> — only
 * this modifier turns one into a real control. */
.chip.prompt {
  cursor: pointer;
  font-family: inherit;
  border-style: solid;
  min-height: var(--control-min);
}
.chip.prompt:hover { background: var(--accent-strong); border-color: var(--accent-strong); color: #fff; }

/* ------------------------------------------------------------ transcript
 * Task 43: assistant turns are .why teal panels (prose) + any typed cards;
 * user turns are plain right-aligned bubbles in the same type scale — no
 * new visual language, per the binding note. */
#transcript { display: flex; flex-direction: column; gap: 14px; margin-bottom: 14px; }
.turn.user { display: flex; justify-content: flex-end; }
.turn.assistant { display: flex; flex-direction: column; gap: 8px; }
.bubble {
  max-width: 80%;
  background: var(--navy);
  color: var(--white);
  border-radius: 10px;
  padding: 9px 13px;
  font-size: 0.9375rem;
  line-height: 1.45;
  white-space: pre-wrap;
}
.turn.assistant .why { margin-top: 0; }
.why p { font-size: 0.9375rem; line-height: 1.5; white-space: pre-wrap; }
.turn.assistant .cards { display: flex; flex-direction: column; gap: 10px; }

/* Inline email moment (decision #13b) — a .why panel with an email field,
 * appended right after the assistant turn that first needed one. */
/* Persistent "talk to a human" block in the rail. */
.rep {
  margin-top: 14px;
  padding: 11px 13px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
}
.rep h4 {
  margin: 0 0 4px;
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--navy);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.rep p { margin: 0 0 2px; font-size: var(--text-sm); color: #4a5163; }
.rep a { color: var(--accent-strong); text-decoration: underline; font-weight: 600; overflow-wrap: anywhere; }
.rep a:hover { text-decoration: underline; }

/* Visually hidden but still announced by screen readers — for labels whose
   text would be redundant sighted but which inputs must have programmatically. */
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* The email gate's decline path. Deliberately quiet next to the primary
   Continue action, but a real focusable button — not a bare <span>. */
.linkish {
  display: inline-flex;
  align-items: center;
  margin-top: 8px;
  padding: 2px 0;
  background: none;
  border: 0;
  color: var(--accent-strong);
  font: inherit;
  font-size: var(--text-sm);
  text-decoration: underline;
  cursor: pointer;
  min-height: var(--control-min);
}
.linkish:hover { color: var(--navy); }
.linkish:disabled {
  background: transparent;
  border-color: transparent;
  color: #656d7d;
}

/* Disabled controls must LOOK disabled. The composer and the rail's +/-/x
   are disabled while the email gate is open, but rendered identically to
   their active state, so on mobile they simply appeared unresponsive. */
.btn:disabled,
button:disabled,
textarea:disabled {
  opacity: 1;
  cursor: not-allowed;
}
.btn:disabled,
button:disabled {
  background: #e8ebf2;
  border-color: #c7cedb;
  color: #596274;
}
textarea:disabled { opacity: .7; }

.email-gate { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.email-gate input { flex: 1; min-width: 10em; margin: 0; }
.email-gate .btn { flex: none; }

/* --------------------------------------------------------------- composer */
#composer { display: flex; flex-wrap: wrap; gap: 8px; align-items: flex-end; margin-top: 4px; }
#composer textarea { flex: 1; margin: 0; resize: vertical; }
#composer .btn { flex: none; }

/* ------------------------------------------------------------- BOM card */
.card {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 13px;
}
.card h3 {
  background: var(--navy);
  color: var(--white);
  text-transform: uppercase;
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: .07em;
  padding: 9px 14px;
}
.bom { list-style: none; padding: 11px 14px; margin: 0; }
.bom li {
  position: relative;
  padding: 3px 0 3px 16px;
  font-size: var(--text-sm);
  line-height: 1.35;
}
.bom li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 7px;
  width: 6px;
  height: 6px;
  border-radius: 1px;
  background: var(--adr);
}
.bom li.sub { color: var(--muted); font-size: var(--text-sm); }
.bom li.sub::before { background: var(--lt); }
.bom li.empty { color: var(--muted); font-style: italic; padding-left: 0; }
.bom li.empty::before { content: none; }

/* ----------------------------------------------------------- price card */
.price {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  margin-bottom: 13px;
}
.price .ph {
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 9px 14px;
  font-size: var(--text-sm);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--navy);
}
.price .ph em {
  font-style: normal;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted);
  font-size: var(--text-sm);
}
.price .pb { padding: 13px 14px; }
.price .cap {
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--muted);
  margin-bottom: 4px;
}
.price .big {
  font-size: 29px;
  font-weight: 800;
  letter-spacing: -.02em;
  color: var(--navy);
  line-height: 1;
}
.price .big small { font-size: var(--text-sm); font-weight: 700; color: var(--muted); }

.row { display: flex; justify-content: space-between; gap: 8px; font-size: var(--text-sm); padding: 2.5px 0; }
/* The price is the row's final DIRECT child. Install metadata contains nested
   spans of its own; a descendant selector also styled the final .line-desc as
   though it were the price, making the card's mandatory overage copy bold
   navy while the rail rendered the same shared markup normally. */
.row > span:last-child { font-weight: 700; color: var(--navy); }
.row.tot { border-top: 1px solid var(--line); margin-top: 6px; padding-top: 7px; font-weight: 800; }
.row.tot span { font-weight: 800; color: var(--navy); }

.price.feature { border: 2px solid var(--adr); }
.price.feature .ph { background: var(--accent-strong); color: var(--white); }
.price.feature .ph em { color: var(--white); }
.price.feature.is-superseded {
  border-color: #aab2c0;
  background: #f6f7f9;
}
.price.feature.is-superseded .ph {
  background: #697386;
}
.price.feature.is-superseded .pb { color: #555e6e; }
.estimate-history-label {
  margin: 0;
  padding: 7px 14px;
  border-bottom: 1px solid #cdd3df;
  background: #eceff3;
  color: #40495a;
  font-size: var(--text-sm);
  font-weight: 700;
}

/* ------------------------------------------------- Own-it vs Lease split
 * The purchase total needs more room than the monthly lease figure. A
 * weighted grid reserves a real column for the literal "or" divider so the
 * three values cannot paint over one another in the 360px desktop rail. */
.price .split {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) 28px minmax(92px, .75fr);
  align-items: center;
  gap: 6px;
}
.price .split > div { min-width: 0; }
.price .split .or {
  align-self: center;
  text-align: center;
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--muted);
}

/* ------------------------------------------------------------ device card
 * A bespoke read-only info card (chat device/comparison/EOL-option cards —
 * Task 43 removed the catalog-browse qty stepper + "Add to build" row that
 * used to live here; these cards are informational only now, built from
 * the same tokens/type-scale/border language as the rest of the system). */
.device {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 12px 14px;
  margin-bottom: 10px;
}
.device h3 { font-size: var(--text-base); font-weight: 700; color: var(--navy); text-transform: none; letter-spacing: 0; background: none; padding: 0; }
.device p { font-size: var(--text-sm); color: var(--muted); margin-top: 4px; }
.device .device-sku { color: var(--ink); font-weight: 600; overflow-wrap: anywhere; }
.device ul { list-style: none; padding: 0; margin: 8px 0 0; }
.device ul li { position: relative; padding-left: 12px; font-size: var(--text-sm); color: var(--muted); margin-bottom: 3px; }
.device ul li::before { content: ""; position: absolute; left: 0; top: 6px; width: 5px; height: 5px; background: var(--adr); }
.device-price-panel {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 3px;
  min-width: 0;
  width: 100%;
  margin-top: 10px;
  padding: 11px 12px;
  border: 1px solid var(--line);
  border-left: 5px solid #8a98a8;
  border-radius: 7px;
  background: #f7f9fb;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.device-price-label {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 800;
  letter-spacing: .02em;
}
.device-price-value {
  color: var(--navy);
  font-size: clamp(1.2rem, 2.8vw, 1.55rem);
  font-weight: 900;
  line-height: 1.15;
}
.device-price-context {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 500;
  line-height: 1.35;
}
.device-price-panel[data-state="ready"] {
  border-left-color: var(--accent-strong);
  background: #f1f8fb;
}
.device-price-panel[data-state="pending"],
.device-price-panel[data-state="calculating"] {
  border-left-color: #8a98a8;
}
.device-price-panel[data-state="calculating"] .device-price-value {
  color: var(--muted);
}
.device-price-panel[data-state="unavailable"] {
  border-left-color: #737c87;
  background: #f5f6f7;
}
.device-price-panel.is-compact {
  margin: 0;
  padding: 8px 9px;
  border-left-width: 4px;
}
.device-price-panel.is-compact .device-price-value {
  font-size: var(--text-base);
}
.device-price-panel.is-compact .device-price-context {
  font-size: var(--text-sm);
}

/* ------------------------------------------------------- comparison card
 * Task 43: a "comparison" chat card is a small grid of the same .device
 * tiles above — same .opts responsive grid rule the rest of the system
 * already uses, no new layout primitive. */
.compare-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 8px;
}
.compare-grid .device { margin-bottom: 0; }

.pricing-result-card {
  min-width: 0;
  padding: 14px;
  border: 2px solid var(--accent-strong);
  border-radius: 10px;
  background: #f7fbfe;
}
.pricing-result-heading h3 { margin: 2px 0 0; color: var(--navy); }
.pricing-result-items { display: grid; gap: 10px; margin-top: 10px; }
.pricing-result-item {
  display: grid;
  grid-template-columns: minmax(130px, .8fr) minmax(0, 1.2fr);
  gap: 12px;
  align-items: start;
  min-width: 0;
  padding-top: 10px;
  border-top: 1px solid var(--line);
}
.pricing-result-item:first-child { padding-top: 0; border-top: 0; }
.pricing-result-identity { min-width: 0; overflow-wrap: anywhere; }
.pricing-result-identity strong { display: block; color: var(--navy); }
.pricing-result-context {
  margin-top: 10px;
  color: var(--muted);
  font-size: var(--text-sm);
}
.pricing-result-history {
  margin-bottom: 8px;
  color: var(--muted);
  font-weight: 800;
}
.pricing-result-card:is(.is-superseded, .is-withdrawn) {
  border-color: var(--line);
  background: #f5f6f7;
}

/* --------------------------------------------- complete family option card
 * Unlike a comparison card, this disclosure can carry every reviewed SKU in
 * a large family. The scroll region bounds expanded families on desktop and
 * mobile while native <details>/<summary> preserves keyboard operation. */
.family-options {
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}
.family-options > summary {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: 48px;
  padding: 10px 42px 10px 14px;
  color: var(--navy);
  font-weight: 700;
  cursor: pointer;
}
.family-options > summary::after {
  content: "+";
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 20px;
}
.family-options[open] > summary::after { content: "\2212"; }
.family-options > summary small {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 400;
}
.family-pricing-note {
  margin: 0 10px 8px;
  padding: 8px 10px;
  border-left: 3px solid var(--adr);
  background: #eef6fb;
  color: #3d4453;
  font-size: var(--text-sm);
  line-height: 1.4;
}
.family-options-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 8px;
  max-height: 70vh;
  overflow-y: auto;
  padding: 0 10px 10px;
  overscroll-behavior: contain;
}
.family-options-grid .device { margin-bottom: 0; }

/* ---------------------------------------------------- "Your quote" rail
 * Task 43: the sidebar line-item row gained minimal +/-/remove affordances
 * (decision #1) alongside the existing item text — same small square
 * outlined-button treatment on all three, distinguished only by symbol. */
.build-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  font-size: var(--text-sm);
  padding: 4px 0;
}
.build-line > .line-main:first-child { min-width: 0; overflow-wrap: anywhere; }
/* Part number, secondary to the model name. Deliberately quiet: the buyer
   is usually non-technical, so the SKU is for disambiguating two lines of
   the same family and for quoting a part number to a rep — not the primary
   identity of the line. */
.line-sku { display: block; font-size: var(--text-sm); color: var(--muted); letter-spacing: .01em; }

/* Replacement-option card: says what it is and carries the part number, so
   it still reads as a real recommendation when there is no spec-match
   reasoning to list. */
.opt-kicker {
  margin: 0 0 2px;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent-strong);
}
.opt-sku { margin: 2px 0 0; font-size: var(--text-sm); color: var(--muted); }
.build-line .line-actions { display: flex; flex: none; gap: 4px; }
.build-line .line-btn,
.build-line .remove {
  flex: none;
  background: transparent;
  color: var(--muted);
  border: 1px solid var(--line);
  border-radius: 6px;
  width: 32px;
  height: 32px;
  line-height: 1;
  font-family: inherit;
  cursor: pointer;
  font-size: var(--text-sm);
}
.build-line .line-btn:hover { color: var(--navy); border-color: var(--adr); }
.build-line .remove:hover { color: #9a3b39; border-color: #9a3b39; }
.build-line .refused-reason { display: block; color: #9a3b39; font-size: var(--text-sm); margin-top: 2px; }

/* An install line carries more than a name and a price: what the price
   covers (.line-terms) and what the technician actually does, including any
   metered rate (.line-desc). Both sit under the SKU as quiet secondary text
   — the line's identity is still its name and its total.
   FINAL REVIEW FIX 3: top-level rules, no longer scoped to .build-line. The
   quote CARD renders the same two spans inside a .row, and a rail-scoped rule
   would have put the markup in the DOM and styled none of it. Nothing else in
   this sheet uses either class, so widening the selector changes the rail's
   rendering not at all. */
.line-terms { display: block; font-size: var(--text-sm); color: var(--muted); margin-top: 2px; }
.line-desc { display: block; font-size: var(--text-sm); color: var(--ink); line-height: 1.4; margin-top: 3px; }

/* Provenance chips: lines the app added FOR you. Copied from the two
   configurators, where nothing arrives in the total unannounced. .chip is
   the pill (see above); .auto is only the strip that holds them. */
.auto { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 9px; }

/* --------------------------------------------------------------- buttons */
.btn {
  display: inline-block;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  border-radius: 7px;
  padding: 9px;
  border: 1px solid var(--navy);
  background: var(--navy);
  color: var(--white);
  cursor: pointer;
  text-decoration: none;
  text-align: center;
  min-height: var(--control-min);
}
.btn.alt { background: var(--white); color: var(--navy); }
.btn:hover:not(:disabled) { background: #101d47; border-color: #101d47; }
.btn.alt:hover:not(:disabled), .btn.quote-tertiary:hover:not(:disabled) {
  background: #eef6fb;
  border-color: var(--navy);
  color: var(--navy);
}
.btn:active:not(:disabled) { background: #0b1538; border-color: #0b1538; }
.btn.alt:active:not(:disabled), .btn.quote-tertiary:active:not(:disabled) {
  background: #dbeaf3;
  border-color: var(--navy);
  color: var(--navy);
}
.btn[aria-busy="true"] { cursor: progress; border-style: double; opacity: .8; }
.btn[data-state="success"] { border-color: #2e7d32; }
.btn[data-state="error"] { border-color: #9a3b39; }
.quote-empty {
  background: #eef6fb;
  border-left: 3px solid var(--adr);
  border-radius: 0 6px 6px 0;
  padding: 10px 12px;
  margin-top: 10px;
}
.quote-empty p { font-size: var(--text-sm); line-height: 1.45; }
.actions { display: grid; grid-template-columns: 1fr; gap: 8px; margin-top: 10px; }
.quote-tertiary { background: transparent; color: var(--navy); }
.quote-status { min-height: 1.45em; margin-top: 8px; font-size: var(--text-sm); }
.quote-status:empty { min-height: 0; margin-top: 0; }
.quote-status[data-tone="success"] { color: #1b5e20; }
.quote-status[data-tone="error"] { color: #9a3b39; }
.deferred-review { margin-top: 0; }

/* --------------------------------------------------------------- form ui */
label { display: block; font-size: var(--text-sm); margin: 8px 0 4px; }
input, select, textarea {
  font-family: inherit;
  font-size: var(--text-base);
  padding: 8px 10px;
  border: 1.5px solid var(--line);
  border-radius: 7px;
  width: 100%;
  background: var(--white);
  color: var(--ink);
  min-height: var(--control-min);
}
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 3px solid var(--adr);
  outline-offset: 2px;
}
textarea { min-height: 5.5em; resize: vertical; }

.pick {
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 9px 11px;
  margin-top: 8px;
  font-size: var(--text-sm);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.pick b { color: var(--navy); }

.form-error { color: #9a3b39; font-weight: 700; font-size: var(--text-sm); }
.note { font-size: var(--text-sm); color: var(--muted); line-height: 1.45; padding: 0 2px; margin-top: 10px; }

/* "Quoted as" — the answered steps, echoed into the rail. */
#quoted-as { margin-top: 12px; }
#quoted-as h4 {
  font-size: var(--text-sm); font-weight: 700; color: var(--navy);
  text-transform: uppercase; letter-spacing: .04em; margin-bottom: 4px;
}
#quoted-as ul { list-style: none; padding: 0; margin: 0; }
#quoted-as li { font-size: var(--text-sm); color: var(--ink); padding: 2px 0; }

/* --------------------------------------------------------- workspace mode */
.mode-switch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 11px;
  margin-bottom: 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
}
.mode-switch-label {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.mode-segments { display: flex; gap: 3px; padding: 3px; background: var(--surface); border-radius: 8px; }
.mode-segments button {
  min-height: 44px;
  padding: 8px 13px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--navy);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
}
.mode-segments button[aria-pressed="true"] {
  border-color: var(--navy);
  background: var(--navy);
  color: var(--white);
}
.mode-segments button:disabled { cursor: progress; opacity: .65; }
body.research-empty .wrap { max-width: 960px; grid-template-columns: minmax(0, 1fr); }

/* ---------------------------------------------- compact estimate setup */
.estimate-setup {
  margin-bottom: 13px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  padding: 12px 14px;
}
.estimate-setup-heading,
.setup-editor-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.estimate-setup h2 { color: var(--navy); font-size: var(--text-base); }
.setup-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.setup-chip {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  min-height: 44px;
  padding: 8px 11px;
  border: 1px solid var(--lt);
  border-radius: 999px;
  background: #eef6fb;
  color: var(--ink);
  font: inherit;
  font-size: var(--text-sm);
  cursor: pointer;
}
.setup-chip span { color: var(--muted); }
.setup-chip strong { color: var(--navy); }
.setup-chip[aria-expanded="true"] { border-color: var(--navy); box-shadow: inset 0 0 0 1px var(--navy); }
.setup-chip.needs-attention { border: 2px solid #b87819; background: #fff6e6; }
.setup-chip.needs-attention strong { color: #7a4b08; }
.setup-editor { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); }
.setup-editor h3 { color: var(--navy); font-size: var(--text-base); }
.setup-editor .opts { margin-top: 10px; }

/* Quick estimate: three plain, numbered decisions instead of internal
   pricing-path chips. One editor opens below the rows at a time. */
.quick-estimate {
  min-width: 0;
  margin-bottom: 13px;
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
}
.quick-estimate-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.quick-estimate-heading h2 { color: var(--navy); font-size: var(--text-lg); }
.quick-steps { display: grid; gap: 7px; margin-top: 11px; }
.quick-step {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-width: 0;
  min-height: 64px;
  padding: 9px 11px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  color: var(--ink);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.quick-step:hover { border-color: var(--adr); background: #f7fbfe; }
.quick-step:disabled { cursor: not-allowed; opacity: .62; background: var(--surface); }
.quick-step[aria-expanded="true"] { border-color: var(--adr); box-shadow: inset 0 0 0 1px var(--adr); }
.quick-step.needs-attention { border: 2px solid #b87819; background: #fffaf0; }
.quick-step.is-complete { border-left: 5px solid var(--adr); }
.quick-step-number {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--navy);
  color: var(--white) !important;
  font-weight: 800;
}
.quick-step-copy { min-width: 0; }
.quick-step-copy > span {
  display: block;
  color: var(--muted) !important;
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.quick-step-copy strong {
  display: block;
  margin-top: 2px;
  color: var(--navy);
  overflow-wrap: anywhere;
}
.quick-step-state {
  color: var(--muted) !important;
  font-size: var(--text-sm);
  font-weight: 700;
}
.quick-step-editor {
  min-width: 0;
  margin-top: 10px;
  padding: 13px;
  border: 1px solid var(--lt);
  border-radius: 8px;
  background: #f7fbfe;
}
.quick-step-editor.setup-editor { border-top: 1px solid var(--lt); }
.quick-step-editor > .btn { margin-top: 10px; }
.quick-option-group + .quick-option-group {
  margin-top: 15px;
  padding-top: 15px;
  border-top: 1px solid var(--line);
}
.quick-option-group h4 { color: var(--navy); font-size: var(--text-base); }
.quick-option-note { margin-top: 10px; color: var(--muted); }
.quick-gate-host:empty, .quick-estimate-status:empty { display: none; }
.quick-estimate-status { margin-top: 10px; color: var(--navy); font-weight: 700; }
.quick-estimate-status[data-tone="error"] {
  padding: 9px 10px;
  border-left: 4px solid #b94a48;
  background: #fff3f3;
  color: #7f2927;
}
.email-gate-panel {
  margin-top: 12px;
  padding: 13px;
  border: 2px solid var(--adr);
  border-radius: 8px;
  background: #eef8fc;
}
.email-gate-panel h3 { color: var(--navy); font-size: var(--text-base); }
.email-gate-panel p { margin-top: 5px; }

/* ------------------------------------------------ current estimate rail */
.current-estimate-summary {
  margin-bottom: 10px;
  border: 2px solid var(--adr);
  border-radius: 10px;
  overflow: hidden;
  background: var(--white);
}
.current-estimate-summary:focus-visible { outline: 4px solid var(--lt); outline-offset: 3px; }
.current-estimate-summary > h2 {
  padding: 10px 14px;
  background: var(--navy);
  color: var(--white);
  font-size: var(--text-lg);
  font-weight: 800;
}
.estimate-mode-note {
  padding: 8px 14px;
  background: #eef6fb;
  color: var(--navy);
  font-size: var(--text-sm);
  font-weight: 700;
}
.estimate-hero { padding: 15px 14px; }
.estimate-hero[data-state="priced"] { background: #f4fbff; }
.estimate-hero[data-state="deferred"] { background: #fff6e6; border-left: 5px solid #b87819; }
.estimate-hero[data-state="pending"] { background: #eef6fb; border-left: 5px solid var(--adr); }
.estimate-hero[data-state="empty"] { color: var(--muted); }
.estimate-kicker {
  color: var(--navy);
  font-size: var(--text-sm);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.estimate-category { color: var(--muted); font-size: var(--text-sm); font-weight: 700; }
.estimate-purchase-options {
  margin: 7px 0 0;
  border: 0;
  border-radius: 0;
  overflow: visible;
  background: transparent;
}
.estimate-purchase-options .cap { margin-bottom: 3px; }
.estimate-purchase-options .big { font-size: 1.7rem; }
.estimate-purchase-options .estimate-total,
.estimate-purchase-options .estimate-lease .big { white-space: nowrap; }
.estimate-purchase-options .estimate-lease { margin-top: 0; }
.estimate-lease-fee { margin-top: 4px; color: var(--muted); font-size: var(--text-sm); }
.estimate-total {
  margin-top: 2px;
  color: var(--navy);
  font-size: clamp(2rem, 3.8vw, 2.75rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.035em;
}
.estimate-state { margin-top: 7px; color: var(--ink); font-size: var(--text-sm); }
.estimate-lease { margin-top: 10px; color: var(--navy); font-size: var(--text-base); font-weight: 800; }
.estimate-lease span { display: block; color: var(--muted); font-size: var(--text-sm); font-weight: 600; }
/* Recurring cadence. The monthly total is a SEPARATE block from the one-time
   hero, never a line inside its arithmetic — the two totals are never summed,
   and the rule above the block is there so the eye does not read them as one
   running figure. */
.estimate-monthly {
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--line, rgba(0, 0, 0, .12));
}
.estimate-monthly-total {
  margin-top: 2px;
  color: var(--navy);
  font-size: clamp(1.5rem, 2.6vw, 1.9rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.03em;
}
/* Section headings appear only when both cadences are present. `aria-hidden`
   in the markup keeps them out of the accessibility tree, because each line
   already states its own cadence in its <dt> — a screen reader would otherwise
   hear the grouping twice. */
.rail-section-heading {
  margin: 12px 0 4px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  list-style: none;
}
.rail-section-heading:first-child { margin-top: 0; }
.rail-section-footnote {
  margin-top: 8px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-style: italic;
  list-style: none;
}
.estimate-items-card { margin-top: 0; }
.line-identity { min-width: 0; }
.line-name { display: block; color: var(--ink); overflow-wrap: anywhere; }
.line-price-breakdown {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 5px 16px;
  min-width: 0;
  margin: 7px 0 0;
}
.line-price-breakdown div:last-child:nth-child(3) {
  grid-column: 1 / -1;
}
.line-price-breakdown div { min-width: 0; }
.line-price-breakdown dt {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  white-space: nowrap;
}
.line-price-breakdown dd {
  margin: 1px 0 0;
  color: var(--navy);
  font-weight: 800;
  overflow-wrap: anywhere;
}
.line-price-pending {
  margin-top: 6px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.line-lifecycle, .line-successor { display: block; margin-top: 4px; font-size: var(--text-sm); }
.line-successor { color: var(--navy); font-weight: 700; }
.line-recommendation-note {
  display: block;
  min-width: 0;
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.line-alternatives { margin-top: 7px; }
.line-alternatives summary { min-height: 44px; display: flex; align-items: center; color: var(--navy); cursor: pointer; font-weight: 700; }
.line-alternatives ul { margin: 0; padding: 0 0 0 18px; }
.line-alternatives li { margin: 7px 0; }
.line-replacement-label {
  display: block;
  min-width: 0;
  margin-bottom: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.estimate-meta {
  margin-top: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  overflow-wrap: anywhere;
}
.estimate-meta:empty { display: none; }
.estimate-meta h4 { color: var(--navy); font-size: var(--text-sm); text-transform: uppercase; letter-spacing: .04em; }
.estimate-meta dl { display: grid; gap: 5px; margin: 8px 0 0; }
.estimate-meta dl div { display: grid; grid-template-columns: 92px 1fr; gap: 8px; font-size: var(--text-sm); }
.estimate-meta dt { color: var(--muted); }
.estimate-meta dd { margin: 0; font-weight: 600; }

/* Research is a protected workspace, not a second estimate review screen.
   Keep the saved estimate visible as reassurance without letting its total
   compete with the research prompt and composer for attention. Screen-only
   scoping keeps the full estimate intact when Print / save PDF is used. */
@media screen {
  body[data-mode="research"] .current-estimate-summary {
    border-width: 1px;
    border-color: var(--line);
    background: #f8fafc;
  }
  body[data-mode="research"] .current-estimate-summary > h2 {
    padding: 8px 12px;
    border-bottom: 1px solid var(--line);
    background: #eef3f8;
    color: var(--navy);
    font-size: var(--text-base);
  }
  body[data-mode="research"] .estimate-mode-note {
    padding: 8px 12px;
    border-left: 4px solid var(--adr);
    background: #eef8fc;
  }
  body[data-mode="research"] .estimate-hero { padding: 9px 12px; }
  body[data-mode="research"] .estimate-hero .estimate-category,
  body[data-mode="research"] .estimate-hero .note,
  body[data-mode="research"] #quoted-as,
  body[data-mode="research"] #estimate-meta,
  body[data-mode="research"] #rail > .note { display: none; }
  body[data-mode="research"] .estimate-hero .estimate-kicker { font-size: var(--text-sm); }
  body[data-mode="research"] .estimate-total { font-size: 1.75rem; }
  body[data-mode="research"] .estimate-purchase-options .estimate-lease .big { font-size: 1.25rem; }
  body[data-mode="research"] .estimate-state { margin-top: 4px; }
  body[data-mode="research"] .estimate-items-card { margin-bottom: 8px; }
  body[data-mode="research"] .estimate-items-card h3 { padding-block: 7px; }
  body[data-mode="research"] .estimate-items-card .bom { padding-block: 7px; }
  body[data-mode="research"] #rail > .rep { margin-top: 8px; padding: 8px 10px; }
}

/* ----------------------------------------- compact estimate history event */
.estimate-update {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
  padding: 10px 12px;
  border: 1px solid var(--adr);
  border-left: 5px solid var(--adr);
  border-radius: 8px;
  background: #eef6fb;
}
.estimate-update .estimate-history-label { margin: 0; padding: 0; border: 0; background: transparent; color: var(--ink); }
.estimate-update .estimate-history-label span,
.estimate-update .estimate-history-label strong { color: var(--navy); }
.estimate-update-action { min-height: 44px; flex: none; }
.estimate-update.is-superseded {
  border-color: #cdd3df;
  border-left-color: #8992a3;
  background: #f4f5f7;
}
.estimate-update.is-superseded .estimate-history-label { color: #555e6e; font-weight: 600; }
.estimate-history-disclosure { width: 100%; }
.estimate-history-disclosure summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  color: var(--navy);
  font-weight: 700;
  cursor: pointer;
}
.estimate-history-disclosure p { margin: 6px 0 2px; color: var(--muted); }

/* ----------------------------------------- compact family option selector */
.family-configurator {
  width: 100%;
  min-width: 0;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
  overflow: hidden;
}
.family-configurator-main { min-width: 0; padding: 14px; }
.family-configurator-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
}
.family-configurator-heading h3 { margin: 2px 0 0; color: var(--navy); }
.family-configurator-heading .opt-kicker { margin: 0; }
.family-option-count {
  flex: none;
  padding: 5px 8px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.family-shared-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 1px;
  margin: 12px 0;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--line);
  overflow: hidden;
}
.family-shared-facts div { min-width: 0; padding: 9px 10px; background: var(--surface); }
.family-shared-facts dt {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .03em;
}
.family-shared-facts dd { margin: 2px 0 0; color: var(--ink); font-weight: 700; overflow-wrap: anywhere; }
.family-dimensions { display: grid; gap: 12px; }
.family-dimension { min-width: 0; margin: 0; padding: 0; border: 0; }
.family-dimension legend { margin-bottom: 6px; color: var(--navy); font-weight: 800; }
.family-dimension-options { display: flex; flex-wrap: wrap; gap: 7px; }
.family-dimension-option {
  min-height: 44px;
  min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--white);
  color: var(--navy);
  font: inherit;
  font-weight: 700;
  text-align: left;
  cursor: pointer;
}
.family-dimension-option:hover { border-color: var(--adr); background: #f7fbfe; }
.family-dimension-option[aria-pressed="true"] {
  border-color: var(--adr);
  background: #eaf5fa;
  box-shadow: inset 0 0 0 1px var(--adr);
}
.family-dimension-option:focus-visible,
.family-ambiguous-option:focus-within,
.family-match-card:focus-visible { outline: 3px solid var(--lt); outline-offset: 2px; }
.family-package-caveat,
.family-taa-caveat {
  margin: 9px 0 0;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}
.family-resolution { min-width: 0; margin-top: 12px; }
.family-resolution-prompt,
.family-no-match,
.family-review-needed {
  margin: 0;
  padding: 11px 12px;
  border-left: 4px solid var(--adr);
  background: #eef6fb;
  color: var(--ink);
}
.family-resolution-prompt strong { color: var(--navy); }
.family-no-match h4,
.family-review-needed h4 { margin: 0; color: var(--navy); }
.family-no-match p,
.family-review-needed p { margin: 5px 0 0; }
.family-match-card {
  min-width: 0;
  padding: 13px;
  border: 2px solid var(--adr);
  border-radius: 9px;
  background: #f7fbfe;
}
.family-match-card h4 { margin: 2px 0 0; color: var(--navy); font-size: var(--text-lg); }
.family-match-sku { margin: 6px 0 0; overflow-wrap: anywhere; }
.family-match-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(135px, 1fr));
  gap: 7px 12px;
  margin: 11px 0;
}
.family-match-facts div { min-width: 0; }
.family-match-facts dt { color: var(--muted); font-size: var(--text-sm); font-weight: 700; }
.family-match-facts dd { margin: 1px 0 0; font-weight: 700; overflow-wrap: anywhere; }
.family-match-card .masters-price {
  margin: 10px 0;
  padding: 11px 12px;
  border-left: 5px solid var(--accent-strong);
  background: var(--white);
  color: var(--navy);
  font-size: var(--text-lg);
  font-weight: 900;
}
.family-match-card .family-use { width: 100%; min-height: 44px; }
.family-match-card.is-unavailable { border-color: #c7ccd6; background: #f7f7f8; }
.family-ambiguous-list { min-width: 0; margin: 0; padding: 12px; border: 1px solid var(--line); border-radius: 8px; }
.family-ambiguous-list legend { padding: 0 4px; color: var(--navy); font-weight: 800; }
.family-ambiguous-list > p { margin: 0 0 9px; color: var(--muted); }
.family-ambiguous-option {
  display: flex;
  align-items: center;
  gap: 9px;
  min-height: 44px;
  margin-top: 6px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  cursor: pointer;
}
.family-ambiguous-option input { flex: none; width: 20px; height: 20px; accent-color: var(--navy); }
.family-ambiguous-option span { min-width: 0; overflow-wrap: anywhere; }
.family-ambiguous-option span small,
.family-ambiguous-option span span { display: block; margin-top: 3px; color: var(--muted); font-size: var(--text-sm); }
.family-ambiguous-option.is-unavailable { color: var(--muted); background: #f7f7f8; cursor: not-allowed; }
.family-configurator-main > .family-switch-mode { width: 100%; min-height: 44px; margin-top: 10px; }
.family-expert-list { border-width: 1px 0 0; border-radius: 0; }
.family-package, .family-region { display: block; margin-top: 3px; color: var(--muted); }
.family-filter-bar {
  display: grid;
  grid-template-columns: repeat(3, minmax(140px, 1fr)) auto;
  gap: 8px;
  align-items: end;
  padding: 0 10px 10px;
}
.family-filter-bar label { margin: 0; color: var(--muted); font-weight: 700; }
.family-filter-bar select { margin-top: 4px; min-width: 0; }
.family-clear-filters { min-height: 44px; }
.family-selection-bar {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 14px;
  padding: 8px 10px;
  border-block: 1px solid var(--line);
  background: var(--surface);
}
.family-filter-status, .family-compare-status { color: var(--muted); font-size: var(--text-sm); }
.family-selection-bar .family-compare { margin-left: auto; }
.family-table-scroll { max-height: 70vh; overflow: auto; }
.family-variant-table { width: 100%; border-collapse: collapse; min-width: 1120px; font-size: var(--text-sm); }
.family-variant-table th,
.family-variant-table td { padding: 9px 8px; border-bottom: 1px solid var(--line); text-align: left; vertical-align: top; }
.family-variant-table thead th { position: sticky; top: 0; z-index: 1; background: var(--surface); color: var(--navy); }
.family-variant-row.is-unavailable { background: #f7f7f8; color: var(--muted); }
.family-compare-cell input { width: 44px; height: 44px; min-height: 44px; margin: 0; accent-color: var(--navy); }
.family-product-name, .family-sku, .family-lifecycle-banner, .family-unavailable-reason { display: block; }
.family-product-name { color: var(--navy); }
.family-sku { margin-top: 3px; color: var(--muted); font-weight: 500; overflow-wrap: anywhere; }
.family-config { display: block; min-width: 190px; }
.family-lifecycle { text-transform: capitalize; }
.family-lifecycle-banner { margin-top: 3px; color: #8a4f00; }
.family-shared-lifecycle { margin-top: 9px; }
.family-lifecycle-compact { min-width: 0; }
.family-price-cell { min-width: 155px; }
.family-price-cell .masters-price { margin: 0; color: var(--navy); font-weight: 800; }
.family-action-cell { min-width: 150px; }
.family-action-cell .btn { width: 100%; }
.family-unavailable-reason { margin-bottom: 6px; }
.family-compare-panel { margin: 12px 10px; padding: 12px; border: 2px solid var(--adr); border-radius: 8px; background: #f7fbfe; }
.family-compare-panel:focus-visible { outline: 4px solid var(--lt); outline-offset: 2px; }
.family-compare-heading { display: flex; justify-content: space-between; align-items: center; gap: 10px; }
.family-compare-heading h4 { color: var(--navy); }
.family-compare-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 8px; margin-top: 10px; }
.family-compare-card { padding: 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--white); }
.family-compare-card h5 { margin: 0; color: var(--navy); font-size: var(--text-base); }
.family-compare-card dl { margin: 8px 0; }
.family-compare-card dl div { margin-top: 6px; }
.family-compare-card dt { color: var(--muted); font-size: var(--text-sm); font-weight: 700; text-transform: uppercase; }
.family-compare-card dd { margin: 1px 0 0; }

/* Direct presentation of server-owned lifecycle status, milestone strings,
   timing labels, and caveats. Dates remain neutral; the fixed server banner
   alone receives the established attention colour. */
.lifecycle-block {
  min-width: 0;
  margin-top: 8px;
  overflow-wrap: anywhere;
}
.lifecycle-summary {
  display: grid;
  gap: 4px;
  min-width: 0;
  margin: 0;
}
.lifecycle-summary > div {
  display: grid;
  grid-template-columns: minmax(78px, auto) minmax(0, 1fr);
  gap: 5px 9px;
  align-items: baseline;
}
.lifecycle-summary dt {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.lifecycle-summary dd {
  min-width: 0;
  margin: 0;
  color: var(--ink);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}
.lifecycle-date dd { font-variant-numeric: tabular-nums; }
.lifecycle-timing {
  display: inline-block;
  margin-left: 3px;
  color: var(--muted);
  font-size: var(--text-sm);
}
.lifecycle-banner {
  margin: 0 0 5px;
  color: #8a4f00;
  font-size: var(--text-sm);
  font-weight: 700;
}
.lifecycle-caveat {
  margin-top: 5px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}
.lifecycle-block.is-compact { margin-top: 5px; }
.lifecycle-facts.is-compact { gap: 2px; }
.lifecycle-facts.is-compact > div {
  grid-template-columns: minmax(70px, auto) minmax(0, 1fr);
}
.lifecycle-facts.is-compact :is(dt, dd, .lifecycle-timing) {
  font-size: var(--text-sm);
}
.print-lifecycle-summary {
  display: block;
  margin-top: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}

/* The complete SKU list is an expert escape hatch. It used to be a
   1,120px-wide table inside a 70vh two-axis scroll box, which hid columns
   and trapped the page wheel. Present each SKU as a compact responsive row
   card instead: all fields remain available, while the document owns the
   vertical scroll and no horizontal panning is required. */
.family-configurator:has(.family-expert-list[open]),
.family-expert-list[open] { overflow: visible; }
.family-expert-list[open] > summary {
  position: sticky;
  top: 0;
  z-index: 5;
  min-height: 68px;
  border-bottom: 1px solid var(--line);
  background: var(--white);
}
.family-expert-list .family-selection-bar {
  position: sticky;
  top: 68px;
  z-index: 4;
}
.family-expert-list .family-table-scroll {
  max-height: none;
  overflow: visible;
  overscroll-behavior: auto;
}
.family-expert-list .family-variant-table {
  display: block;
  min-width: 0;
  border-collapse: separate;
}
.family-expert-list .family-variant-table thead {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
.family-expert-list .family-variant-table tbody {
  display: grid;
  gap: 9px;
  width: 100%;
  padding: 10px;
}
.family-expert-list .family-variant-table tbody tr {
  display: grid;
  /* Every information cell gets a useful reading width. The old 56px first
     track was intended only for the compare checkbox, but auto-placement also
     dropped later fields (including the action) into that track. Keep the
     identity row explicit and let the remaining fields flow into equal-width
     columns instead. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-areas: "compare product product";
  gap: 8px 12px;
  min-width: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
}
.family-expert-list .family-variant-table tbody :is(th, td) {
  min-width: 0;
  padding: 0;
  border: 0;
  color: inherit;
  text-align: left;
  overflow-wrap: anywhere;
}
.family-expert-list .family-variant-table tbody :is(th, td)::before {
  content: attr(data-label);
  display: block;
  margin-bottom: 2px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: .03em;
  text-transform: uppercase;
}
.family-expert-list .family-config,
.family-expert-list .family-price-cell,
.family-expert-list .family-action-cell { min-width: 0; }
.family-expert-list .family-compare-cell { grid-area: compare; }
.family-expert-list .family-variant-table tbody th[scope="row"] { grid-area: product; }
.family-expert-list .family-action-cell {
  grid-column: 1 / -1;
  width: 100%;
}
.family-expert-list .family-compare-cell input { width: 44px; height: 44px; min-height: 44px; }
.recommendation-choice.is-selected,
.family-match-card.is-selected,
.family-expert-row.is-selected {
  border-color: var(--adr);
  box-shadow: inset 4px 0 0 var(--adr);
  background: #f1f9fc;
}

/* ---------------------------------------- resilient connectivity workflow */
body[data-mode="speedfusion"] .wrap {
  max-width: 940px;
  grid-template-columns: minmax(0, 1fr);
}
body[data-mode="better-together"] .wrap {
  max-width: 980px;
  grid-template-columns: minmax(0, 1fr);
}
.speedfusion-workspace { min-width: 0; }
.better-together-workspace { min-width: 0; }
.speedfusion-heading {
  margin-bottom: 13px;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
}
.speedfusion-heading-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.speedfusion-back {
  min-height: 44px;
  margin: -8px 0 4px -8px;
}
.speedfusion-heading h2 {
  margin: 2px 0 5px;
  color: var(--navy);
  font-size: 1.35rem;
  line-height: 1.3;
}
.speedfusion-heading .hint { margin-bottom: 0; }
.speedfusion-progress {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 0 0 13px;
  padding: 0;
  list-style: none;
}
.speedfusion-progress li {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  min-height: 44px;
  padding: 8px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.speedfusion-progress li span {
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--surface);
  color: var(--navy);
}
.speedfusion-progress li[aria-current="step"] {
  border-color: var(--adr);
  background: #eef6fb;
  color: var(--navy);
}
.speedfusion-progress li[aria-current="step"] span {
  background: var(--navy);
  color: var(--white);
}
.speedfusion-progress li[data-complete="true"] {
  border-color: #8ab497;
  color: #1b5e20;
}
.speedfusion-status {
  min-height: 1.45em;
  margin: 0 0 8px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.speedfusion-status:empty { min-height: 0; margin: 0; }
.speedfusion-status[data-tone="success"] { color: #1b5e20; }
.speedfusion-status[data-tone="error"] { color: #9a3b39; }
.speedfusion-error { margin: 0 0 13px; }
.speedfusion-paths { display: grid; gap: 10px; margin-bottom: 10px; }
.speedfusion-path {
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #fbfcfe;
}
.speedfusion-path-heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
.speedfusion-path-heading h3 {
  color: var(--navy);
  font-size: var(--text-base);
}
.speedfusion-remove-path {
  min-height: 44px;
  color: #8c3836;
}
.speedfusion-path-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 12px;
}
.speedfusion-path-grid .speedfusion-wide { grid-column: 1 / -1; }
.speedfusion-field-help {
  display: block;
  margin-top: 3px;
  color: var(--muted);
  font-size: var(--text-sm);
  line-height: 1.4;
}
.speedfusion-step-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 8px;
  margin-top: 13px;
}
.speedfusion-goals { display: grid; gap: 14px; }
.speedfusion-question {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}
.speedfusion-question legend {
  margin-bottom: 6px;
  color: var(--navy);
  font-size: var(--text-sm);
  font-weight: 800;
}
.speedfusion-choices {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(175px, 1fr));
  gap: 8px;
}
.speedfusion-choice {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-height: 50px;
  margin: 0;
  padding: 10px;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  background: var(--white);
  color: var(--ink);
  cursor: pointer;
}
.speedfusion-choice:hover { border-color: var(--adr); }
.speedfusion-choice:has(input:checked) {
  border-color: var(--adr);
  background: #eef6fb;
  box-shadow: inset 0 0 0 1px var(--adr);
}
.speedfusion-choice input {
  flex: none;
  width: 18px;
  min-height: 18px;
  margin: 2px 0 0;
  padding: 0;
  accent-color: var(--navy);
}
.speedfusion-choice span {
  font-size: var(--text-sm);
  font-weight: 700;
  line-height: 1.4;
}
.speedfusion-result {
  padding: 17px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--white);
}
.speedfusion-result-heading {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.speedfusion-result-heading h2 {
  color: var(--navy);
  font-size: 1.2rem;
}
.speedfusion-tabs {
  display: flex;
  flex: none;
  gap: 3px;
  padding: 3px;
  border-radius: 8px;
  background: var(--surface);
}
.speedfusion-tabs button {
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--navy);
  font: inherit;
  font-size: var(--text-sm);
  font-weight: 700;
  cursor: pointer;
}
.speedfusion-tabs button[aria-selected="true"] {
  border-color: var(--adr);
  background: var(--white);
}
.speedfusion-recommendation {
  margin-top: 13px;
  padding: 13px;
  border-left: 5px solid var(--adr);
  background: #eef6fb;
}
.speedfusion-recommendation h3,
.speedfusion-result-block h3,
.speedfusion-explanation h3 {
  margin-bottom: 5px;
  color: var(--navy);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.speedfusion-recommendation p { font-size: var(--text-base); font-weight: 700; }
.speedfusion-result-block { margin-top: 13px; }
.speedfusion-result-block ul {
  margin: 5px 0 0;
  padding-left: 20px;
}
.speedfusion-result-block li {
  margin: 3px 0;
  font-size: var(--text-sm);
  line-height: 1.45;
}
.speedfusion-result-block.is-warning {
  padding: 9px 11px;
  border-left: 3px solid #d98c2b;
  border-radius: 0 6px 6px 0;
  background: #fff6e8;
  color: #7a4d10;
}
.speedfusion-result-block.is-unresolved {
  padding: 9px 11px;
  border-left: 3px solid #8992a3;
  border-radius: 0 6px 6px 0;
  background: #f4f5f7;
}
.speedfusion-explanation { margin-top: 13px; }
.speedfusion-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 15px;
}
.speedfusion-actions .btn { flex: 1 1 170px; }

.better-together-form {
  display: grid;
  gap: 13px;
  margin-bottom: 13px;
}
.better-together-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0 12px;
}
.better-together-wide { grid-column: 1 / -1; }
.better-together-checks {
  min-width: 0;
  margin: 5px 0 0;
  padding: 0;
  border: 0;
}
.better-together-checks legend {
  margin-bottom: 6px;
  color: var(--navy);
  font-size: var(--text-sm);
  font-weight: 800;
}
.better-together-check-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 8px;
}
.speedfusion-choice.is-disabled {
  border-color: var(--line);
  background: var(--surface);
  color: var(--muted);
  cursor: not-allowed;
}
.better-together-seed {
  margin-top: 12px;
  padding: 11px 13px;
  border-left: 4px solid var(--adr);
  border-radius: 0 7px 7px 0;
  background: #eef6fb;
}
.better-together-seed h3,
.better-together-router-section > h3,
.better-together-bom-section > h3 {
  margin-bottom: 5px;
  color: var(--navy);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: .04em;
}
.better-together-seed p { margin: 0; }
.better-together-seed .note { margin-top: 3px; }
.better-together-auto-additions {
  padding: 9px 11px;
  border-left: 3px solid #3c8a5a;
  border-radius: 0 6px 6px 0;
  background: #edf8f0;
}
.better-together-router-section,
.better-together-bom-section {
  margin-top: 17px;
}
.better-together-router-candidates {
  display: grid;
  gap: 10px;
}
.better-together-router-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(210px, .7fr);
  align-items: center;
  gap: 12px;
  padding: 13px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: #fbfcfe;
}
.better-together-router-card h4 {
  margin: 2px 0 4px;
  color: var(--navy);
  font-size: var(--text-base);
}
.better-together-lifecycle {
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.better-together-price {
  display: grid;
  gap: 2px;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 7px;
  background: var(--white);
  color: var(--muted);
  font-size: var(--text-sm);
}
.better-together-price strong {
  color: var(--navy);
  font-size: var(--text-base);
}
.better-together-price[data-state="ready"] {
  border-color: #3c8a5a;
  background: #edf8f0;
}
.better-together-price[data-state="unavailable"] {
  border-color: #d5a4a2;
  background: #fff4f3;
}
.better-together-price .better-together-unit-price {
  color: #1b5e20;
  font-size: 1.35rem;
}
.better-together-router-card > .btn {
  grid-column: 2;
  justify-self: stretch;
}
.better-together-table-scroll {
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--line);
  border-radius: 8px;
}
.better-together-table-scroll table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}
.better-together-table-scroll th,
.better-together-table-scroll td {
  padding: 9px 10px;
  border-bottom: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.better-together-table-scroll thead th {
  background: var(--surface);
  color: var(--navy);
}
.better-together-table-scroll tbody tr:last-child th,
.better-together-table-scroll tbody tr:last-child td {
  border-bottom: 0;
}

/* ------------------------------------------------ truthful request state */
.request-progress {
  flex: 0 0 100%;
  min-height: 0;
  margin: 2px 0 0;
  padding: 0 2px;
  color: var(--muted);
  font-size: var(--text-sm);
  font-weight: 700;
}
.request-progress:empty { display: none; }
.request-progress[data-state="request-sent"],
.request-progress[data-state="active"] { color: var(--accent-strong); }
.request-progress[data-state="slow"],
.request-progress[data-state="unconfirmed"],
.request-progress[data-state="review"] { color: #8a4f00; }
.request-progress[data-state="success"] { color: #1b5e20; }

/* ---------------------------------------------------------------------------
   Mobile / narrow viewport.

   Placement is load-bearing: this block MUST stay below every component rule
   it overrides and above the print block. (Do not write the print at-rule's
   literal name in this comment — tests slice the stylesheet at the first
   occurrence of that string.) A media query adds no specificity, so
   a same-specificity base rule further down the file beats the override on
   source order alone. This block used to sit near the top, which left 13 of
   its 18 declarations silently dead on every phone — including the 40x40
   thumb targets, which computed to the desktop 20x20. Guarded by
   tests/test_design_system.py::test_mobile_block_comes_after_the_rules_it_overrides.
   --------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .wrap { grid-template-columns: 1fr; padding: 18px; }
  .mode-switch { align-items: stretch; flex-direction: column; }
  .mode-segments { display: grid; grid-template-columns: 1fr 1fr; }
  .mode-segments button { padding-inline: 8px; }
  .task-grid,
  body.speedfusion-available .task-grid { grid-template-columns: 1fr; }
  .speedfusion-workspace,
  .better-together-workspace,
  .speedfusion-path,
  .speedfusion-result { min-width: 0; max-width: 100%; }
  .speedfusion-progress { grid-template-columns: 1fr; }
  .speedfusion-progress li { min-height: 44px; }
  .speedfusion-path-grid { grid-template-columns: 1fr; }
  .speedfusion-path-grid .speedfusion-wide { grid-column: auto; }
  .speedfusion-result-heading { align-items: stretch; flex-direction: column; }
  .speedfusion-tabs { display: grid; grid-template-columns: 1fr 1fr; }
  .speedfusion-choices { grid-template-columns: 1fr; }
  .speedfusion-step-actions { align-items: stretch; flex-direction: column-reverse; }
  .speedfusion-step-actions .btn,
  .speedfusion-actions .btn,
  #speedfusion-add-path { width: 100%; }
  .better-together-grid { grid-template-columns: 1fr; }
  .better-together-wide { grid-column: auto; }
  .better-together-check-grid { grid-template-columns: 1fr; }
  .better-together-router-card { grid-template-columns: 1fr; }
  .better-together-router-card > .btn {
    grid-column: auto;
    min-height: 44px;
    width: 100%;
  }
  .catalog-search-row { flex-wrap: wrap; }
  .catalog-search-row .btn { width: 100%; }
  .quote-finder-selected { align-items: stretch; flex-direction: column; }
  .quote-finder-selected .btn { width: 100%; }
  .catalog-fallback-buttons { align-items: stretch; flex-direction: column; }
  .catalog-fallback-buttons .btn,
  .catalog-fallback-buttons .linkish { width: 100%; justify-content: center; }
  .setup-chip { width: 100%; justify-content: space-between; text-align: left; }
  .setup-editor-heading { align-items: stretch; flex-direction: column; }
  .setup-editor-heading .setup-close { min-height: 44px; align-self: flex-start; }
  .estimate-update { align-items: stretch; flex-direction: column; }
  .estimate-update-action { align-self: flex-start; }
  .family-filter-bar { grid-template-columns: 1fr; }
  .family-clear-filters { justify-self: stretch; }
  .family-selection-bar { align-items: stretch; flex-direction: column; }
  .family-selection-bar .family-compare { width: 100%; margin-left: 0; }
  #chat-col, .turn.assistant, .turn.assistant .cards,
  .quick-estimate, .quick-step, .quick-step-editor,
  .family-configurator, .family-configurator-main, .family-resolution,
  .family-options-wrap, .family-options, .family-table-scroll {
    min-width: 0;
    max-width: 100%;
  }
  .quick-estimate { padding: 11px; }
  .quick-step { grid-template-columns: 32px minmax(0, 1fr); }
  .quick-step-state { grid-column: 2; }
  .quick-step-editor .opts { grid-template-columns: 1fr; }
  .email-gate { align-items: stretch; flex-direction: column; }
  .email-gate input, .email-gate .btn { width: 100%; min-width: 0; }
  .family-configurator-heading { align-items: stretch; flex-direction: column; }
  .family-option-count { align-self: flex-start; }
  .family-shared-facts, .family-match-facts { grid-template-columns: 1fr; }
  .family-dimension-options { display: grid; grid-template-columns: 1fr; }
  .family-dimension-option { width: 100%; }
  .family-table-scroll { width: 100%; max-height: 62vh; }
  .family-compare-heading { align-items: stretch; flex-direction: column; }
  .family-close-compare { min-height: 44px; align-self: flex-start; }
  .estimate-meta dl div { grid-template-columns: 1fr; gap: 1px; }

  /* The rail becomes a drawer opened by the fixed bar, instead of stacking
     below the entire conversation where it was never seen. */
  .quote-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    width: 100%;
    padding: 14px 18px;
    background: var(--navy);
    color: #fff;
    border: 0;
    border-top: 1px solid rgba(255,255,255,.15);
    font: inherit;
    font-size: 14px;
    font-weight: 700;
    text-align: left;
    cursor: pointer;
    /* Comfortable thumb target — the old rail controls were 20x20. */
    min-height: 52px;
  }
  .quote-bar-caret { transition: transform .18s ease; }
  .quote-bar[aria-expanded="true"] .quote-bar-caret { transform: rotate(180deg); }

  .sum {
    position: fixed;
    /* `top: auto` is load-bearing: .sum carries `top: 18px` from its desktop
       sticky rule, and on a fixed element a set `top` beats `bottom`, which
       left the drawer floating mid-screen instead of sitting on the bar. */
    top: auto;
    left: 0; right: 0; bottom: 52px;
    z-index: 39;
    max-height: 70vh;
    overflow-y: auto;
    margin: 0;
    padding: 16px 18px 22px;
    /* Must be OPAQUE — this overlays the conversation. `var(--bg)` was a
       typo for a token that does not exist, which resolves to transparent
       and let the transcript show through the drawer. */
    background: var(--surface);
    /* Flat design (extracted design system): separation comes from a border,
       never a drop shadow — see test_only_inset_ring_shadow_no_drop_shadows. */
    border-top: 2px solid var(--navy);
    display: none;
  }
  .sum.rail-open { display: block; }

  /* Keep the composer clear of the fixed bar. */
  body { padding-bottom: 64px; }

  /* Readable on a phone. The desktop scale runs 9.5-11px, which is fine at
     arm's length on a monitor and too small in a hand — and this is the
     device the tool is most often demoed and used on. */
  .why p, .why li, .bom li, .hint, .device p, .landing-h + .hint {
    font-size: 14px;
    line-height: 1.5;
  }
  .device .masters-price { font-size: 14px; }
  .estimate-jump {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    margin-top: 4px;
    font-size: 14px;
  }
  .note, .line-sku, .opt-sku, .bom li.sub { font-size: var(--text-sm); }
  /* Install terms, metered-service detail, and auto-add/omission notices are
     quote content, not desktop-only fine print. Keep them readable in both
     the conversation card and the quote drawer. */
  .line-terms, .line-desc, .auto .chip { font-size: var(--text-sm); }
  .chip.prompt, .btn { font-size: 14px; }
  #chat-text { font-size: 16px; }   /* >=16px stops iOS zooming the page on focus */

  /* Comfortable thumb targets. 20x20 is well under any usable minimum. */
  .build-line .line-btn,
  .build-line .remove {
    width: 44px;
    height: 44px;
    font-size: 16px;
  }
  .build-line .line-actions { gap: 8px; }
  .build-line { flex-wrap: wrap; }
  .build-line .line-actions { width: 100%; justify-content: flex-end; }
  .btn { min-height: 44px; }
  .family-expert-list .family-selection-bar { position: static; }
  /* Tablet layouts retain two scannable information columns. This is narrow
     enough for the single workspace column, but avoids the very tall list
     produced by collapsing every field into one stack. */
  .family-expert-list .family-variant-table tbody tr {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-template-areas: "compare product";
  }
}

@media (max-width: 520px) {
  .pricing-result-item {
    grid-template-columns: minmax(0, 1fr);
    gap: 7px;
  }
  .line-price-breakdown {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px 10px;
  }
  /* A phone cannot safely fit purchase, separator and lease into one row.
     Stack the alternatives and turn "or" into a quiet rule so neither price
     can collide with it at 320px. */
  .estimate-purchase-options .split { grid-template-columns: minmax(0, 1fr); gap: 7px; }
  .estimate-purchase-options .split .or {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
  }
  .lifecycle-summary > div,
  .lifecycle-facts.is-compact > div {
    grid-template-columns: minmax(0, 1fr);
    gap: 1px;
  }
  .estimate-purchase-options .split .or::before,
  .estimate-purchase-options .split .or::after {
    content: "";
    flex: 1;
    height: 1px;
    background: var(--line);
  }
  .family-expert-list .family-variant-table tbody tr {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "compare" "product";
  }
  .family-expert-list .family-variant-table tbody :is(th, td) {
    grid-column: 1;
    grid-row: auto;
  }
}

/* ---------------------------------------------------------------------------
   Print / save PDF.

   Rebuilt after the external review: the old rules hid .actions but not
   .line-actions or .email-gate-panel, and forced exact colour printing, so
   "Print / save PDF" produced the entire CONVERSATION plus an unresolved
   email field, live -/+/x controls, and dark navy backgrounds. That is not a
   document anyone would send a customer.

   The printed page is now the quote and nothing else: what was configured,
   what it costs, the disclaimers that must travel with it, and who to call.
   Everything interactive or conversational is dropped, and colour is left to
   the printer rather than forced, so it stays ink-friendly.
   --------------------------------------------------------------------------- */
.print-only { display: none; }

@media print {
  /* Conversation, controls, gates, forms, dev affordances — none of it
     belongs on a quote document. */
  #transcript, #composer, #landing, #home, #chat-col, #lead-form, #step-verify,
  #degraded-actions, #dev-continue, #quote-empty, .actions, .line-actions,
  #quote-status, .quote-status, .email-gate-panel, .linkish, .chip, .cards,
  .quote-bar { display: none !important; }

  /* A priced informational card can be printed before it is added to the
     cart. In that case the product section is the document; do not lead it
     with a contradictory "Your quote / Nothing yet" panel. */
  #rail.print-products-only > #current-estimate-summary,
  #rail.print-products-only > .estimate-items-card,
  #rail.print-products-only > #estimate-meta { display: none !important; }

  /* Exception: a provenance chip is not chrome. It is the only thing on the
     page that says a line was added FOR the customer rather than by them,
     so dropping it from the document would hand them a printed quote with
     an unexplained line on it. */
  .auto .chip { display: inline-flex !important; }

  /* On a narrow page the mobile rules turn the rail into a hidden drawer.
     Printing must always show it, open or not, or a phone prints a blank
     quote. */
  .sum, #rail {
    display: block !important;
    max-height: none;
    overflow: visible;
    background: #fff !important;
  }

  @page { margin: 14mm; }

  body {
    background: #fff;
    color: #000;
    font-size: 11pt;
  }

  /* The rail IS the document — full width, no card chrome competing. */
  .wrap, main { display: block; }
  .wrap { padding: 0; }
  .top {
    display: block;
    padding: 0 0 4mm;
  }
  .top img {
    height: 22px;
    margin-bottom: 2mm;
  }
  .sum, #rail { position: static; width: auto; max-width: none; margin: 0; }
  .print-estimate-title {
    display: block !important;
    margin-bottom: 2mm;
    color: #000;
    font-size: 17pt;
    font-weight: 800;
  }
  .current-estimate-summary {
    margin-bottom: 2mm;
    border: 0;
    border-radius: 0;
    overflow: visible;
    break-inside: avoid;
  }
  .current-estimate-summary > h2 {
    padding: 0 0 2mm;
    background: none !important;
    color: #000 !important;
    border-bottom: 1px solid #000;
    font-size: 12pt;
  }
  .estimate-mode-note { display: none !important; }
  .estimate-hero { padding: 2mm 0; background: #fff !important; border-left: 0 !important; }
  .estimate-total { color: #000; font-size: 28pt; }
  .estimate-kicker, .estimate-lease { color: #000; }
  /* Keep each closing block intact, but do not chain them into one large
     unbreakable group. Chromium otherwise moves all three to a mostly empty
     second page even when the first page has ample room. */
  .estimate-meta { margin-top: 2mm; border: 0; padding: 0; break-inside: avoid; }
  .estimate-items-card { margin-bottom: 2mm; break-inside: avoid; }
  .estimate-items-card h3 { padding: 2mm 0; }
  .estimate-items-card .bom { padding: 2mm 0; }
  #quoted-as { margin-top: 2mm; break-inside: avoid; }
  #quoted-as h4 { margin-bottom: 1mm; }
  #quoted-as li { padding: .5mm 0; }

  /* Device cards remain outside the cart, but their current authoritative
     Masters estimate is useful customer context. Only this reduced print
     projection is shown; the conversation and original cards stay hidden. */
  #print-products.has-items { display: block !important; margin: 8mm 0; }
  #print-products h4 { margin: 0 0 2mm; font-size: 12pt; }
  .print-product-list { list-style: none; margin: 4mm 0 0; padding: 0; }
  .print-device-line {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 8mm;
    padding: 3mm 0;
    border-bottom: 1px solid #ddd;
    break-inside: avoid;
  }
  .print-device-line strong { text-align: right; white-space: nowrap; }
  .print-device-line .line-config {
    display: block;
    margin-top: 1mm;
    color: #222;
    font-size: 9pt;
  }
  .print-device-line .print-lifecycle-summary {
    display: block;
    margin-top: 1mm;
    color: #222;
    font-size: 8.5pt;
    line-height: 1.3;
  }
  .device-price-panel {
    border-color: #777;
    background: #fff !important;
    color: #000;
  }
  .device-price-panel :is(.device-price-label, .device-price-value, .device-price-context) {
    color: #000;
  }
  .line-price-breakdown {
    display: grid;
    grid-template-columns: repeat(3, max-content);
    gap: 2mm 5mm;
    margin-top: 1mm;
  }
  .line-price-breakdown div:last-child:nth-child(3) { grid-column: auto; }
  .line-price-breakdown :is(dt, dd),
  .line-price-pending { color: #000; font-size: 8.5pt; }
  .build-line .lifecycle-block {
    margin-top: 1mm;
    break-inside: avoid;
  }
  .build-line .lifecycle-summary {
    display: block;
  }
  .build-line .lifecycle-summary > div {
    display: inline;
    margin-right: 3mm;
  }
  .build-line .lifecycle-summary :is(dt, dd) {
    display: inline;
    color: #000;
    font-size: 8.5pt;
  }
  .build-line .lifecycle-summary dt::after { content: ": "; }
  .build-line .lifecycle-summary dd::after { content: "  "; }
  .build-line .lifecycle-banner,
  .build-line .lifecycle-caveat {
    color: #000;
    font-size: 8.5pt;
  }
  .line-alternatives > ul { display: block !important; }
  .line-alternatives > summary { color: #000; min-height: 0; }
  .line-replacement-label,
  .line-recommendation-note { color: #000; }

  /* Ink-friendly: the navy header block and dark fills become plain text.
     Deliberately NOT print-color-adjust: exact — forcing a dark background
     onto a quote wastes a cartridge and reads badly in greyscale. */
  header, .card h3, .sum h3 {
    background: none !important;
    color: #000 !important;
    border-bottom: 1px solid #000;
  }
  .top .t h1 { color: #000 !important; }
  .top .t h1 span { color: #000 !important; }
  .top .sub { color: #000 !important; }
  header img {
    height: 42px;
    opacity: 1;
    /* Source logo is white for the navy screen header. Print is white, so
       invert it to a crisp dark mark instead of letting it disappear. */
    filter: invert(1) contrast(1.25);
  }

  .card, .rep, #quote-total { border: 0; padding: 0; }
  .build-line { break-inside: avoid; border-bottom: 1px solid #ddd; padding: 6px 0; }
  .line-sku { color: #444; }
  .note, .rep { font-size: 9pt; color: #000; }
  #rail > .note { margin-top: 2mm; break-inside: avoid; }
  .rep {
    margin-top: 1mm;
    border-top: 1px solid #000;
    border-radius: 0;
    padding-top: 1.5mm;
    break-inside: avoid;
  }
  .rep h4 { margin-bottom: 1mm; font-size: 10pt; line-height: 1.2; }
  .rep p { margin-bottom: 0; font-size: 8.5pt; line-height: 1.25; }

  /* SpeedFusion has its own recommendation document and never shares the
     estimate rail. Reveal only the current server-authored result; the
     intake controls, navigation, status chrome, and formal-review form stay
     off the page. Both approved explanation levels are useful in a saved
     design and contain no browser-derived claims. */
  body[data-mode="speedfusion"] #chat-col,
  body[data-mode="speedfusion"] #speedfusion-workspace,
  body[data-mode="speedfusion"] #speedfusion-result,
  body[data-mode="speedfusion"] .speedfusion-explanation {
    display: block !important;
  }
  body[data-mode="speedfusion"] #rail,
  body[data-mode="speedfusion"] #speedfusion-form,
  body[data-mode="speedfusion"] .speedfusion-heading,
  body[data-mode="speedfusion"] .speedfusion-progress,
  body[data-mode="speedfusion"] #speedfusion-status,
  body[data-mode="speedfusion"] #speedfusion-error,
  body[data-mode="speedfusion"] .sf-no-print {
    display: none !important;
  }
  body[data-mode="speedfusion"] .wrap { max-width: none; }
  body[data-mode="speedfusion"] .speedfusion-result {
    padding: 0;
    border: 0;
  }
  body[data-mode="speedfusion"] .speedfusion-tabs { display: none !important; }
  body[data-mode="speedfusion"] .speedfusion-result-block,
  body[data-mode="speedfusion"] .speedfusion-explanation,
  body[data-mode="speedfusion"] .speedfusion-recommendation {
    break-inside: avoid;
  }

  /* Better Together prints only the current server-authored configuration.
     Intake controls and informational price previews are intentionally
     omitted: a preview is not a quote and never becomes a virtual cart. */
  body[data-mode="better-together"] #chat-col,
  body[data-mode="better-together"] #better-together-workspace,
  body[data-mode="better-together"] #better-together-result {
    display: block !important;
  }
  body[data-mode="better-together"] #rail,
  body[data-mode="better-together"] #better-together-form,
  body[data-mode="better-together"] .speedfusion-heading,
  body[data-mode="better-together"] #better-together-status,
  body[data-mode="better-together"] #better-together-error,
  body[data-mode="better-together"] .better-together-price,
  body[data-mode="better-together"] .bt-no-print {
    display: none !important;
  }
  body[data-mode="better-together"] .wrap { max-width: none; }
  body[data-mode="better-together"] .speedfusion-result {
    padding: 0;
    border: 0;
  }
  body[data-mode="better-together"] .speedfusion-result-block,
  body[data-mode="better-together"] .better-together-router-card,
  body[data-mode="better-together"] .better-together-bom-section {
    break-inside: avoid;
  }

  a { color: #000; text-decoration: none; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}
