/* ══════════════════════════════════════════════════════════════════════════
   Price Matrix — certificate-of-analysis assay sheet
   Every SKU is a specimen: a measured value (recommended selling price), a
   specification limit (MRP benchmark), and replicate measurements (channel
   listings). Ruled paper, hairline graphite, one committed assay green.
   ══════════════════════════════════════════════════════════════════════════ */

:root {
  /* Paper stock ─ warm lab-report white against sheet white cells */
  --paper: #fbfbf9;
  --sheet: #ffffff;
  --sheet-alt: #f6f6f3;
  --sheet-hover: #f4f5f1;
  --sheet-sunk: #efefea;

  /* Graphite ink */
  --ink: #1c2024;
  --ink-2: #454b53;
  --ink-3: #5d636b;
  /* The lightest tone that still clears 4.5:1 on both sheet and sheet-alt.
     Anything lighter is a mark, not text. */
  --ink-35: #666c74;
  /* Reserved for non-text marks only — below the 4.5:1 floor for body copy. */
  --ink-4: #9aa0a7;

  /* Hairline rules — the only structure this sheet has */
  --rule-faint: #f2f0eb;
  --rule: #eceae5;
  --rule-2: #dedcd6;
  --rule-3: #c4c3bb;
  /* Closes the pinned columns. Softened from full graphite: it should read as
     a boundary, not as a bar drawn across the sheet. */
  --rule-datum: #a9a89f;

  /* Assay green — brand, action, in-spec */
  --assay-900: #0b4d39;
  --assay-800: #08402f;
  --assay-700: #0f6b4f;
  --assay-600: #158a66;
  --assay-100: #d6e9df;
  --assay-50: #edf6f1;

  /* Brass — the rich-margin band of the chip ramp */
  --brass-700: #78530f;

  /* Out of spec */
  --spec-700: #8f1d1d;
  --spec-600: #b32020;
  --spec-100: #eecfcb;
  --spec-50: #fbedec;

  /* Pinned tune (a specimen with operator-set parameters) */
  --tune-700: #5b3fa8;
  --tune-100: #e2dcf4;
  --tune-50: #f2eefb;

  /* ── Chip ramp ──────────────────────────────────────────────────────────
     Not six unrelated pastels: an ordered measurement scale. Both ends of
     the ramp are alarming (selling under cost, or so far over it the price
     will not clear), the healthy band sits in assay green, and the ramp
     warms through brass as margin gets rich. */
  --chip-neg-bg: var(--spec-50);
  --chip-neg-text: var(--spec-700);
  --chip-neg-border: var(--spec-100);

  --chip-zero-bg: #f1f1ee;
  --chip-zero-text: #4a4f56;
  --chip-zero-border: #dedcd5;

  --chip-tier1-bg: #eef4f1;
  --chip-tier1-text: #2c5f4d;
  --chip-tier1-border: #cee1d8;

  --chip-tier2-bg: #e2f0e8;
  --chip-tier2-text: #14614a;
  --chip-tier2-border: #b5d9c7;

  --chip-tier3-bg: #f6eedb;
  --chip-tier3-text: var(--brass-700);
  --chip-tier3-border: #e3d1a6;

  --chip-tier4-bg: #f6e4da;
  --chip-tier4-text: #8a3b14;
  --chip-tier4-border: #e5c1ab;

  --chip-mkt-disc-bg: #e2f0e8;
  --chip-mkt-disc-text: #14614a;
  --chip-mkt-disc-border: #b5d9c7;

  --chip-mkt-prem-bg: var(--spec-50);
  --chip-mkt-prem-text: var(--spec-700);
  --chip-mkt-prem-border: var(--spec-100);

  /* Depth exists in exactly two places: the datum rule that closes the
     pinned columns, and the dialog lifting off the sheet. */
  --shadow-datum: 6px 0 14px -8px rgba(28, 32, 36, 0.28);
  --shadow-dialog: 0 24px 56px -12px rgba(28, 32, 36, 0.28), 0 2px 8px rgba(28, 32, 36, 0.08);

  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-display: 'Plus Jakarta Sans', var(--font-sans);

  --head-1: 46px;   /* register tier */
  --head-2: 46px;   /* instrument tier */

  --col-row: 76px;
  --col-product: 300px;
  --col-brand: 128px;
  --col-mfg: 124px;
  --col-market: 196px;
  --col-selling: 210px;
}

* { box-sizing: border-box; margin: 0; padding: 0; }

html { color-scheme: light; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 14px;
  height: 100vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  letter-spacing: -0.006em;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /* Lining tabular figures everywhere: this sheet is read down its columns. */
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: 'tnum' 1, 'lnum' 1, 'cv05' 1;
}

/* Browser surfaces belong to the design system too. */
::selection { background: var(--assay-700); color: #fff; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--sheet-alt); }
::-webkit-scrollbar-thumb { background: var(--rule-3); border: 3px solid var(--sheet-alt); }
::-webkit-scrollbar-thumb:hover { background: var(--ink-4); }
::-webkit-scrollbar-corner { background: var(--sheet-alt); }
* { scrollbar-color: var(--rule-3) var(--sheet-alt); scrollbar-width: thin; }

:focus-visible {
  outline: 2px solid var(--assay-700);
  outline-offset: 1px;
}

a { color: var(--assay-700); text-underline-offset: 3px; text-decoration-thickness: 1px; }

/* ══ 1. Sheet header ══════════════════════════════════════════════════════
   Two ruled tiers. Register (who/what/how much) over instrument (how to
   read it). Nothing floats; nothing is a card. */

header.app-header {
  flex-shrink: 0;
  background: var(--sheet);
  border-bottom: 1px solid var(--rule-2);
  z-index: 50;
}

.header-register {
  height: var(--head-1);
  display: flex;
  align-items: stretch;
  border-bottom: 1px solid var(--rule);
}

.header-left {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 0 18px;
  border-right: 1px solid var(--rule);
}

.brand-title {
  font-family: var(--font-display);
  font-size: 13px;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  display: flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
}

/* Sync lamp: hollow until both the catalog and the engine have landed. */
.brand-dot {
  width: 7px;
  height: 7px;
  flex: 0 0 auto;
  background: transparent;
  border: 1.5px solid var(--ink-4);
  transition: background .3s ease, border-color .3s ease;
}
.brand-dot.synced {
  background: var(--assay-600);
  border-color: var(--assay-600);
}

.divider-v { display: none; }

.header-meta-pill {
  display: flex;
  align-items: baseline;
  gap: 5px;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-3);
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.header-meta-pill strong {
  color: var(--ink);
  font-weight: 700;
  font-size: 12.5px;
}
.header-meta-pill .meta-sep {
  color: var(--rule-3);
  padding: 0 2px;
}

.header-right {
  display: flex;
  align-items: stretch;
  gap: 0;
  margin-left: auto;
}

/* One rule per boundary: the register strip's children each own their left
   edge, so no two adjacent borders ever double up. */
.header-right > * { border-left: 1px solid var(--rule); }

.header-instrument {
  height: var(--head-2);
  display: flex;
  align-items: stretch;
  gap: 0;
  padding: 0 0 0 18px;
  background: var(--sheet-alt);
}

.header-center {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  min-width: 0;
  padding-right: 12px;
}

/* ── Fields ─────────────────────────────────────────────────────────────── */
.search-field {
  position: relative;
  flex: 1.6;
  min-width: 190px;
  max-width: 340px;
}
.search-field svg {
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 14px;
  height: 14px;
  color: var(--ink-4);
  pointer-events: none;
}
.search-field input {
  width: 100%;
  height: 30px;
  padding: 0 10px 0 31px;
  background: var(--sheet);
  border: 1px solid var(--rule-2);
  border-radius: 0;
  font-size: 12.5px;
  font-family: inherit;
  color: var(--ink);
  outline: none;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.search-field input::placeholder { color: var(--ink-4); }
.search-field input:hover { border-color: var(--rule-3); }
.search-field input:focus {
  border-color: var(--assay-700);
  box-shadow: inset 0 -2px 0 var(--assay-700);
}
.search-field input::-webkit-search-cancel-button { filter: grayscale(1) opacity(.55); }

.select-field {
  position: relative;
  flex: 1;
  min-width: 108px;
}
.select-field select {
  width: 100%;
  height: 30px;
  padding: 0 26px 0 10px;
  background: var(--sheet);
  border: 1px solid var(--rule-2);
  border-radius: 0;
  font-size: 12px;
  font-weight: 500;
  font-family: inherit;
  color: var(--ink);
  outline: none;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  text-overflow: ellipsis;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.select-field select:hover { border-color: var(--rule-3); }
.select-field select:focus {
  border-color: var(--assay-700);
  box-shadow: inset 0 -2px 0 var(--assay-700);
}
.select-field::after {
  content: '';
  position: absolute;
  right: 11px;
  top: 50%;
  width: 7px;
  height: 7px;
  margin-top: -5px;
  border-right: 1.5px solid var(--ink-3);
  border-bottom: 1.5px solid var(--ink-3);
  transform: rotate(45deg);
  pointer-events: none;
}

/* ── Header buttons ─────────────────────────────────────────────────────── */
.btn-calc {
  height: 30px;
  padding: 0 14px;
  border-radius: 0;
  border: 1px solid var(--assay-900);
  background: var(--assay-900);
  color: #fff;
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  white-space: nowrap;
  transition: background .12s ease, border-color .12s ease;
}
.btn-calc:hover:not(:disabled) { background: var(--assay-700); border-color: var(--assay-700); }
.btn-calc:active:not(:disabled) { background: var(--assay-800); }
.btn-calc:disabled { opacity: .45; cursor: not-allowed; }
.btn-calc svg { width: 14px; height: 14px; }

/* The compare cord: one control that re-reads every chip in the field at
   once. Framed to close tier 2 on the same edge tier 1 closes on. */
.btn-toggle-view {
  height: 100%;
  padding: 0 15px;
  border: 0;
  border-left: 1px solid var(--rule-2);
  background: var(--sheet);
  color: var(--ink-2);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  flex: 0 0 auto;
  transition: background .12s ease, color .12s ease;
}
.btn-toggle-view:hover { background: var(--sheet-sunk); color: var(--ink); }
.btn-toggle-view.active-mode {
  background: var(--assay-900);
  color: #fff;
  border-left-color: var(--assay-900);
}
/* Same 30px framed control as the fields beside it, wrapped in the full-height
   ruled cell that closes the tier — consistent affordance, aligned edge. */
.btn-toggle-view::before {
  content: '';
  position: absolute;
  inset: 8px 0;
  border: 1px solid var(--rule-2);
  pointer-events: none;
}
.btn-toggle-view { position: relative; }
.btn-toggle-view.active-mode::before { border-color: rgba(255, 255, 255, .28); }
.btn-toggle-view svg { width: 13px; height: 13px; flex: 0 0 auto; }

/* Register-tier controls read as ruled tabs, not floating buttons. Their
   dividing rules come from `.header-right > *`, so none is drawn twice. */
.btn-register {
  height: 100%;
  padding: 0 15px;
  border: 0;
  background: transparent;
  color: var(--ink-2);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.btn-register:hover { background: var(--sheet-alt); color: var(--ink); }
.btn-register svg { width: 14px; height: 14px; }

/* Icon-only register control: square rather than padded like a labelled one,
   so it reads as a mark and not as a button that lost its text. */
.btn-register.is-icon {
  padding: 0;
  width: 46px;
  justify-content: center;
  color: var(--ink-3);
}
.btn-register.is-icon:hover { color: var(--ink); }
.btn-register.is-icon svg { width: 15px; height: 15px; }

/* The primary action is the one saturated mass in the register tier. Seated
   in assay-700 rather than 900: at full height it was reading as a slab. */
.btn-register.is-primary {
  background: var(--assay-700);
  color: #fff;
}
.btn-register.is-primary:hover { background: var(--assay-900); color: #fff; }
.header-right > .btn-register.is-primary { border-left-color: var(--assay-700); }

/* Out-of-spec readout: a count that filters the sheet when clicked. Framed
   like the other register controls so its pressability is not in doubt. */
.spec-flag {
  height: 100%;
  padding: 0 15px;
  border: 0;
  background: var(--spec-50);
  color: var(--spec-700);
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
  transition: background .12s ease, color .12s ease;
}
.spec-flag[hidden] { display: none; }
.spec-flag .spec-flag-verb { font-weight: 600; }
.spec-flag .spec-flag-count {
  font-size: 13px;
  font-weight: 700;
  color: var(--spec-700);
}
.spec-flag .spec-flag-mark {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  background: var(--spec-600);
}
.header-right > .spec-flag { border-left-color: var(--spec-100); }
.spec-flag:hover { background: var(--spec-100); }
.spec-flag[aria-pressed='true'] {
  background: var(--spec-600);
  color: #fff;
}
.spec-flag[aria-pressed='true'] .spec-flag-count { color: #fff; }
.spec-flag[aria-pressed='true'] .spec-flag-mark { background: #fff; }
.header-right > .spec-flag[aria-pressed='true'] { border-left-color: var(--spec-600); }

/* ══ 2. Register tabs (sourcing books) ════════════════════════════════════
   The two books dock into the header rule as register tabs. Each carries
   its own specimen count, so the size of the book you are not reading is
   legible from here. */
.origin-switch {
  display: flex;
  align-items: stretch;
}
.origin-option {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0 16px;
  border-right: 1px solid var(--rule);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink-3);
  text-decoration: none;
  white-space: nowrap;
  position: relative;
  transition: background .12s ease, color .12s ease;
}
.origin-option:last-child { border-right: 0; }
.origin-option:hover { background: var(--sheet-alt); color: var(--ink); }
.origin-option.is-active {
  color: var(--ink);
  background: var(--sheet);
}
.origin-option.is-active::after {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 2px;
  background: var(--assay-700);
}
.origin-count {
  font-size: 11px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  padding: 1px 6px;
  background: var(--sheet-sunk);
  color: var(--ink-2);
}
.origin-option.is-active .origin-count {
  background: var(--assay-50);
  color: var(--assay-900);
}

/* ══ 3. The sheet ═════════════════════════════════════════════════════════ */
.table-viewport {
  flex: 1;
  overflow: auto;
  position: relative;
  background: var(--sheet);
  overscroll-behavior: contain;
}

table {
  border-collapse: separate;
  border-spacing: 0;
  width: max-content;
  min-width: 100%;
}

/* ── Column heads: small-caps label over a unit-of-measure basis line ───── */
thead th {
  position: sticky;
  top: 0;
  z-index: 30;
  background: var(--sheet-alt);
  padding: 0;
  border-bottom: 1px solid var(--rule-2);
  border-right: 1px solid var(--rule);
  white-space: nowrap;
  user-select: none;
  vertical-align: bottom;
  text-align: left;
  transition: background .12s ease;
}
thead th:hover { background: var(--sheet-sunk); }

.sort-button {
  appearance: none;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 7px 12px 8px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: inherit;
  cursor: pointer;
}
/* The head labels the column; the data is what gets read. Setting them in
   ink-3 rather than ink-2 drops them behind the numbers without losing them. */
.head-label {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 10.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-3);
}
.head-basis {
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-35);
  text-transform: none;
}
.sort-mark {
  width: 9px;
  height: 11px;
  flex: 0 0 auto;
  color: var(--ink-4);
  opacity: .55;
  transition: opacity .12s ease, color .12s ease;
}
thead th:hover .sort-mark { opacity: 1; }
th[aria-sort='ascending'] .sort-mark,
th[aria-sort='descending'] .sort-mark { opacity: 1; color: var(--assay-700); }
th[aria-sort='ascending'] .head-label,
th[aria-sort='descending'] .head-label { color: var(--assay-900); }
th[aria-sort='ascending'],
th[aria-sort='descending'] { box-shadow: inset 0 -2px 0 var(--assay-700); }

th.source-col-head {
  min-width: 186px;
  text-align: left;
}
.source-head-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1px;
}
.badge-channel {
  font-size: 9px;
  padding: 1px 5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}
.badge-channel.official { background: var(--assay-50); color: var(--assay-900); }
.badge-channel.market { background: var(--sheet-sunk); color: var(--ink-3); }

/* ── Pinned specimen columns ───────────────────────────────────────────── */
/* The workbook row is the leftmost datum: it is how a figure on screen is
   traced back to a cell in the source spreadsheet, so it pins ahead of the
   product title and every following offset is measured from it. */
.col-row {
  position: sticky;
  left: 0;
  z-index: 20;
  width: var(--col-row);
  min-width: var(--col-row);
  max-width: var(--col-row);
  background: var(--sheet);
}
.col-product {
  position: sticky;
  left: var(--col-row);
  z-index: 20;
  width: var(--col-product);
  min-width: var(--col-product);
  max-width: var(--col-product);
  background: var(--sheet);
}
.col-brand {
  position: sticky;
  left: calc(var(--col-row) + var(--col-product));
  z-index: 20;
  width: var(--col-brand);
  min-width: var(--col-brand);
  max-width: var(--col-brand);
  background: var(--sheet);
}
.col-mfg {
  position: sticky;
  left: calc(var(--col-row) + var(--col-product) + var(--col-brand));
  z-index: 20;
  width: var(--col-mfg);
  min-width: var(--col-mfg);
  max-width: var(--col-mfg);
  background: var(--sheet);
  text-align: right;
}
.col-market {
  position: sticky;
  left: calc(var(--col-row) + var(--col-product) + var(--col-brand) + var(--col-mfg));
  z-index: 20;
  width: var(--col-market);
  min-width: var(--col-market);
  max-width: var(--col-market);
  background: var(--sheet);
}
.col-selling-price {
  position: sticky;
  left: calc(var(--col-row) + var(--col-product) + var(--col-brand) + var(--col-mfg) + var(--col-market));
  z-index: 20;
  width: var(--col-selling);
  min-width: var(--col-selling);
  max-width: var(--col-selling);
  background: var(--sheet);
  /* The datum rule: everything left of it is what we know, everything right
     of it is what the market is doing. */
  border-right: 1px solid var(--rule-datum) !important;
  box-shadow: var(--shadow-datum);
}
th.col-mfg .sort-button,
th.col-market .sort-button,
th.col-selling-price .sort-button { align-items: flex-end; text-align: right; }

thead th.col-row,
thead th.col-product,
thead th.col-brand,
thead th.col-mfg,
thead th.col-market,
thead th.col-selling-price {
  z-index: 35;
  background: var(--sheet-alt);
}

/* ── Rows ──────────────────────────────────────────────────────────────── */
tbody tr {
  cursor: pointer;
  transition: background-color .08s ease;
}
tbody tr:hover td,
tbody tr:focus-visible td { background-color: var(--sheet-hover) !important; }
tbody tr:hover td.source-data-cell:has(.cell-dash) { background-color: var(--sheet-sunk) !important; }
tbody tr:focus-visible { outline: none; }
tbody tr:focus-visible td:first-child { box-shadow: inset 2px 0 0 var(--assay-700); }

/* Rows carry a horizontal rule; the vertical is lighter still. Thirteen
   channel columns are read across, so the column boundary has to survive —
   but at equal weight the two together drew a cage around every number. */
td {
  padding: 11px 12px;
  border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule-faint);
  vertical-align: middle;
  height: 58px;
  background: var(--sheet);
}

.item-name {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.32;
  letter-spacing: -0.008em;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Pack size disambiguates same-name SKUs, so it gets its own ruled mark. */
.item-size {
  margin-top: 3px;
  display: inline-block;
  padding: 0 5px;
  border: 1px solid var(--rule-2);
  color: var(--ink-3);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 15px;
}

/* The workbook coordinate: the Excel row number over the sheet it came from.
   Typing the number into Excel's Name Box lands on the cell that produced the
   figures in this row, so it is a reference, not decoration -- rendered in the
   same tabular figures as the money it traces. */
.row-ref {
  display: flex;
  flex-direction: column;
  gap: 1px;
  align-items: flex-start;
}
.row-ref-num {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums lining-nums;
  line-height: 16px;
}
.row-ref-sheet {
  font-size: 9.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-35);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  line-height: 13px;
}
.row-ref-none { color: var(--ink-4); font-size: 12.5px; }

.brand-label {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--ink-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  display: block;
}

.num-price {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}
.num-price.mfg { font-weight: 700; color: var(--ink); }
.num-price.selling { font-weight: 700; color: var(--assay-900); }
.num-price.custom-tuned { font-weight: 700; color: var(--tune-700); }
.num-price.mrp-official { font-weight: 600; color: var(--ink); }
.num-price.mrp-thirdparty { font-weight: 600; color: var(--brass-700); }
.num-price.mrp-ref { font-weight: 600; color: var(--ink-2); }

.dual-metric-cell {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 7px;
  width: 100%;
}

.custom-tune-tag {
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  background: var(--tune-50);
  border: 1px solid var(--tune-100);
  color: var(--tune-700);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* ── Inline price editing (admin) ──────────────────────────────────────── */
/*
 * Source Cost and MRP are directly editable by an admin. The affordance is
 * deliberately quiet: a dotted underline on hover, nothing at rest, so the
 * sheet still reads as a sheet rather than a form.
 *
 * The input replaces the number INSIDE the existing cell box and inherits the
 * row's height. Money inputs elsewhere run ~40px tall, but 407 rows of that
 * would reflow the whole sheet on every edit; here the figure earns its weight
 * through the focus ring and tabular type instead of padding.
 */
.cell-editable {
  cursor: text;
  border-bottom: 1px dotted transparent;
}
tbody tr:hover .cell-editable,
.cell-editable:focus-visible {
  border-bottom-color: var(--ink-4);
}
.cell-editable:focus-visible {
  outline: 2px solid var(--assay-700);
  outline-offset: 1px;
}

.price-edit-input {
  flex: 1 1 auto;
  min-width: 64px;
  width: 100%;
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--assay-700);
  border-radius: 0;
  background: var(--sheet);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums lining-nums;
}
.price-edit-input:focus { outline: none; }
/* The spinner would shift the figure off the column's right edge. */
.price-edit-input::-webkit-outer-spin-button,
.price-edit-input::-webkit-inner-spin-button { appearance: none; margin: 0; }
.price-edit-input[type='number'] { appearance: textfield; -moz-appearance: textfield; }

.price-edit-input.is-saving { opacity: 0.6; }
.price-edit-input.is-error { border-bottom-color: var(--spec-600); color: var(--spec-700); }

/* An edited figure and its provenance marker, matching how Tuned reads. */
.num-price.price-edited { color: var(--tune-700); }
.price-edit-tag {
  font-size: 9px;
  font-weight: 700;
  padding: 1px 5px;
  background: var(--tune-50);
  border: 1px solid var(--tune-100);
  color: var(--tune-700);
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

/* For an admin the marker IS the undo control. It keeps the violet
   operator-set reading at rest and turns crimson on hover/focus, where it
   states the destructive action it performs. Both faces are laid in the same
   grid cell so swapping them cannot change the chip's width and reflow the
   column under the pointer. */
button.price-edit-tag {
  display: inline-grid;
  border-radius: 0;
  font-family: inherit;
  line-height: 1.45;
  cursor: pointer;
  transition: background 120ms linear, border-color 120ms linear, color 120ms linear;
}
button.price-edit-tag > * {
  grid-area: 1 / 1;
  display: flex;
  align-items: center;
  gap: 3px;
  justify-content: center;
}
button.price-edit-tag .tag-undo { visibility: hidden; }
button.price-edit-tag .tag-undo svg { width: 9px; height: 9px; }

button.price-edit-tag:hover,
button.price-edit-tag:focus-visible {
  background: var(--spec-50);
  border-color: var(--spec-100);
  color: var(--spec-700);
}
button.price-edit-tag:hover .tag-word,
button.price-edit-tag:focus-visible .tag-word { visibility: hidden; }
button.price-edit-tag:hover .tag-undo,
button.price-edit-tag:focus-visible .tag-undo { visibility: visible; }

button.price-edit-tag:focus-visible {
  outline: 2px solid var(--spec-600);
  outline-offset: 1px;
}
button.price-edit-tag:active { background: var(--spec-100); }
button.price-edit-tag.is-saving { opacity: 0.6; cursor: progress; }
button.price-edit-tag.is-error {
  background: var(--spec-600);
  border-color: var(--spec-600);
  color: var(--sheet);
}

/* Implied trade discount, shown live while editing a local SKU. It floats
   beneath the cell instead of consuming horizontal room and shrinking the
   money input to zero. */
.dual-metric-cell:has(.price-edit-input) { position: relative; }
.implied-discount-note {
  position: absolute;
  z-index: 45;
  top: calc(100% + 4px);
  right: 0;
  padding: 3px 6px;
  border: 1px solid var(--rule-2);
  background: var(--sheet);
  font-size: 10px;
  color: var(--ink-35);
  font-variant-numeric: tabular-nums lining-nums;
  text-align: right;
  white-space: nowrap;
}
.implied-discount-note .shift {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  color: var(--tune-700);
  font-weight: 600;
}
.implied-discount-note .shift svg { width: 12px; height: 8px; }

/* ── Replicate measurement cells (channels) ────────────────────────────── */
.source-data-cell {
  padding: 6px 10px;
  min-width: 186px;
  background: var(--sheet);
}
.price-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.price-left-group {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
}
.price-val {
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}

/* ── The chip ramp ─────────────────────────────────────────────────────── */
.markup-chip {
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 6px;
  display: inline-flex;
  align-items: center;
  gap: 3px;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  white-space: nowrap;
  font-variant-numeric: tabular-nums lining-nums;
}
.markup-chip svg { width: 8px; height: 8px; flex: 0 0 auto; }

.markup-chip.neg { background: var(--chip-neg-bg); border-color: var(--chip-neg-border); color: var(--chip-neg-text); }
.markup-chip.zero { background: var(--chip-zero-bg); border-color: var(--chip-zero-border); color: var(--chip-zero-text); }
.markup-chip.t1 { background: var(--chip-tier1-bg); border-color: var(--chip-tier1-border); color: var(--chip-tier1-text); }
.markup-chip.t2 { background: var(--chip-tier2-bg); border-color: var(--chip-tier2-border); color: var(--chip-tier2-text); }
.markup-chip.t3 { background: var(--chip-tier3-bg); border-color: var(--chip-tier3-border); color: var(--chip-tier3-text); }
.markup-chip.t4 { background: var(--chip-tier4-bg); border-color: var(--chip-tier4-border); color: var(--chip-tier4-text); }
.markup-chip.mkt-disc { background: var(--chip-mkt-disc-bg); border-color: var(--chip-mkt-disc-border); color: var(--chip-mkt-disc-text); }
.markup-chip.mkt-prem { background: var(--chip-mkt-prem-bg); border-color: var(--chip-mkt-prem-border); color: var(--chip-mkt-prem-text); }

/* Out of spec: not a tier on the ramp, a failed measurement. */
.markup-chip.above-market {
  background: var(--spec-600) !important;
  border-color: var(--spec-700) !important;
  color: #fff !important;
  font-weight: 700;
}

/* ── Deep link / unverified marker ─────────────────────────────────────── */
.btn-open-link {
  color: var(--ink-4);
  text-decoration: none;
  min-width: 28px;
  min-height: 28px;
  border: 1px solid transparent;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  transition: color .12s ease, background .12s ease, border-color .12s ease;
}
.btn-open-link svg { width: 13px; height: 13px; }
.price-card:hover .btn-open-link { color: var(--assay-700); border-color: var(--rule-2); }
.btn-open-link:hover { color: var(--assay-900) !important; background: var(--assay-50); border-color: var(--assay-100) !important; }

/* Close the last channel column against the viewport edge rather than
   letting its chip clip at the scroll boundary. */
th.source-col-head:last-child,
td.source-data-cell:last-child { padding-right: 18px; border-right: 0; }

/* A channel with no listing for this SKU: state the absence quietly instead
   of drawing a full-weight rule around emptiness. */
.source-data-cell:has(.cell-dash) { background: var(--sheet-alt); }

/* A price recorded from research with no confirmed product page: the cell
   says the measurement is unreplicated rather than faking a link. */
.listing-unverified {
  color: var(--ink-4);
  min-width: 28px;
  min-height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  cursor: help;
}
.listing-unverified svg { width: 12px; height: 12px; }
.listing-unverified-text {
  color: var(--ink-3);
  font-size: 11.5px;
}

.cell-dash {
  color: var(--rule-3);
  font-size: 13px;
  display: block;
}
.col-mfg .cell-dash,
.col-market .cell-dash,
.col-selling-price .cell-dash { text-align: right; }

/* ══ 4. Notices ═══════════════════════════════════════════════════════════ */
.sync-error {
  position: sticky;
  left: 0;
  top: 0;
  z-index: 60;
  padding: 10px 18px;
  border-bottom: 1px solid var(--spec-100);
  background: var(--spec-50);
  color: var(--spec-700);
  font-size: 12px;
  font-weight: 600;
}

/* One over-market SKU is a tuning job; a hundred is a broken global model. */
.above-market-banner {
  position: sticky;
  left: 0;
  z-index: 55;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  border-bottom: 1px solid var(--spec-100);
  background: var(--spec-50);
  color: var(--spec-700);
  font-size: 12px;
  font-weight: 600;
}

.empty-state {
  padding: 88px 20px;
  text-align: center;
  color: var(--ink-3);
  font-size: 13px;
}

/* ══ 5. Specimen record (dialogs) ═════════════════════════════════════════ */
dialog {
  margin: auto;
  padding: 0;
  border: 1px solid var(--rule-2);
  border-radius: 0;
  background: var(--sheet);
  color: var(--ink);
  width: min(720px, calc(100% - 32px));
  box-shadow: var(--shadow-dialog);
  outline: none;
}
dialog#dialog { width: min(880px, calc(100% - 32px)); }
dialog::backdrop {
  background: rgba(28, 32, 36, 0.42);
  backdrop-filter: blur(2px);
}

.modal-header {
  padding: 18px 22px 16px;
  border-bottom: 1px solid var(--rule-2);
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 16px;
  background: var(--sheet-alt);
}
.modal-heading-group {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.modal-kicker {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--ink-3);
}
.modal-title {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.018em;
  color: var(--ink);
  text-wrap: balance;
}
.modal-btn-close {
  flex: 0 0 auto;
  background: var(--sheet);
  border: 1px solid var(--rule-2);
  color: var(--ink-2);
  width: 30px;
  height: 30px;
  border-radius: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background .12s ease, color .12s ease, border-color .12s ease;
}
.modal-btn-close svg { width: 13px; height: 13px; }
.modal-btn-close:hover { background: var(--ink); border-color: var(--ink); color: #fff; }

.modal-body {
  padding: 22px;
  display: grid;
  gap: 20px;
  max-height: 74vh;
  overflow-y: auto;
}

/* ── Section rule: a labelled band, not a card ─────────────────────────── */
.record-section { display: grid; gap: 10px; }
.record-legend {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--ink-3);
}
.record-legend::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--rule);
}

/* ── Specimen identity strip ───────────────────────────────────────────── */
.record-spec-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border: 1px solid var(--rule);
  border-bottom: 0;
}
.record-spec-item {
  flex: 1 1 150px;
  display: grid;
  gap: 3px;
  padding: 9px 12px;
  border-right: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
}
.record-spec-item:last-child { border-right: 0; }
.record-spec-item dt {
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--ink-3);
}
.record-spec-item dd {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  line-height: 1.35;
}

/* ── Assay readings ────────────────────────────────────────────────────── */
.detail-stats-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border: 1px solid var(--rule-2);
}
.detail-stat-box {
  padding: 11px 13px;
  border-right: 1px solid var(--rule);
  display: grid;
  gap: 4px;
  align-content: start;
}
.detail-stat-box:last-child { border-right: 0; }
.detail-stat-box.is-result { background: var(--assay-50); }
.detail-stat-box.is-out-of-spec { background: var(--spec-50); }
.detail-stat-box span {
  display: block;
  font-size: 9.5px;
  color: var(--ink-3);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.detail-stat-box strong {
  font-size: 18px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  font-variant-numeric: tabular-nums lining-nums;
}
.detail-stat-box.is-result strong { color: var(--assay-900); }
.detail-stat-box.is-out-of-spec strong { color: var(--spec-700); }

/* A percentage means nothing without its basis, so each reading names one. */
.stat-readings {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 1px;
}
.stat-reading {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ── Cost stack: where the recommended price comes from ────────────────── */
.cost-stack { display: grid; gap: 8px; }
.cost-stack-bar {
  display: flex;
  height: 24px;
  border: 1px solid var(--rule-2);
  overflow: hidden;
}
.cost-stack-seg {
  min-width: 2px;
  transition: filter .12s ease;
}
.cost-stack-seg.seg-source { background: var(--assay-900); }
.cost-stack-seg.seg-overhead { background: var(--assay-600); }
.cost-stack-seg.seg-margin { background: var(--chip-tier3-text); }
.cost-stack-seg.seg-discount { background: repeating-linear-gradient(135deg, var(--spec-100) 0 4px, var(--spec-50) 4px 8px); }
.cost-stack-key {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 18px;
}
.cost-stack-key-item {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  font-size: 11.5px;
  color: var(--ink-2);
}
.cost-stack-key-item i {
  width: 9px;
  height: 9px;
  flex: 0 0 auto;
  align-self: center;
}
.cost-stack-key-item i.seg-source { background: var(--assay-900); }
.cost-stack-key-item i.seg-overhead { background: var(--assay-600); }
.cost-stack-key-item i.seg-margin { background: var(--chip-tier3-text); }
.cost-stack-key-item i.seg-discount { background: repeating-linear-gradient(135deg, var(--spec-100) 0 3px, var(--spec-50) 3px 6px); border: 1px solid var(--spec-100); }
.cost-stack-key-item b {
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}

/* ── Replicate spread: where our price sits against the channels ───────── */
.spread-rail {
  position: relative;
  height: 60px;
  border: 1px solid var(--rule-2);
  background: var(--sheet-alt);
}
/* The inner track is inset so a tick at either extreme stays inside the
   frame while still measuring 0–100% of the real price range. */
.spread-inner {
  position: absolute;
  inset: 0 22px;
}
.spread-track {
  position: absolute;
  left: 0;
  right: 0;
  top: 24px;
  height: 1px;
  background: var(--rule-2);
}
.spread-band {
  position: absolute;
  top: 16px;
  height: 17px;
  background: var(--assay-50);
  border-left: 1px solid var(--assay-100);
  border-right: 1px solid var(--assay-100);
}
.spread-tick {
  position: absolute;
  top: 12px;
  width: 1px;
  height: 25px;
  background: var(--ink-4);
  transform: translateX(-0.5px);
}
.spread-tick.is-ours {
  width: 3px;
  height: 35px;
  top: 6px;
  background: var(--assay-900);
  transform: translateX(-1.5px);
}
.spread-tick.is-ours.is-out-of-spec { background: var(--spec-600); }
.spread-tick.is-mrp { background: var(--ink); height: 31px; top: 8px; }
.spread-label {
  position: absolute;
  top: 42px;
  font-size: 9.5px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-2);
  white-space: nowrap;
  transform: translateX(-50%);
}
.spread-label.is-ours { color: var(--assay-900); }
.spread-label.is-out-of-spec { color: var(--spec-700); }
.spread-endpoints {
  display: flex;
  justify-content: space-between;
  /* Aligned to the inner track's inset so each caption sits under its own
     end tick rather than out at the frame edge. */
  padding: 0 22px;
  font-size: 11px;
  font-weight: 600;
  color: var(--ink-2);
  font-variant-numeric: tabular-nums lining-nums;
}
.spread-endpoints span:first-child { transform: translateX(-50%); }
.spread-endpoints span:last-child { transform: translateX(50%); }

/* ── Channel audit ─────────────────────────────────────────────────────── */
.detail-sources-list {
  display: grid;
  border: 1px solid var(--rule);
  border-bottom: 0;
}
.detail-source-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px 13px;
  border-bottom: 1px solid var(--rule);
  background: var(--sheet);
}
.detail-source-row:nth-child(even) { background: var(--sheet-alt); }
.source-row-name {
  font-weight: 600;
  font-size: 12.5px;
  color: var(--ink);
}
.source-row-title {
  font-size: 11px;
  color: var(--ink-3);
  margin-top: 2px;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
}
.source-row-figure {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
  font-weight: 700;
  font-size: 14px;
  color: var(--ink);
  font-variant-numeric: tabular-nums lining-nums;
}
.detail-source-row a {
  color: var(--assay-700);
  text-decoration: none;
  font-size: 11.5px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: 3px;
}
.detail-source-row a svg { width: 11px; height: 11px; }
.detail-source-row a:hover { text-decoration: underline; }
.detail-source-empty {
  padding: 14px 13px;
  border: 1px solid var(--rule);
  color: var(--ink-3);
  font-size: 12px;
}

/* ── Tabs ──────────────────────────────────────────────────────────────── */
.tab-nav {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--rule-2);
}
.tab-btn {
  padding: 8px 15px;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--ink-3);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  margin-bottom: -1px;
  transition: color .12s ease, border-color .12s ease;
}
.tab-btn:hover { color: var(--ink); }
.tab-btn.active {
  color: var(--assay-900);
  border-bottom-color: var(--assay-700);
}

/* ══ 6. Engine form ═══════════════════════════════════════════════════════ */
.engine-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
}
.engine-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.engine-field label,
.engine-field legend {
  font-size: 12.5px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.01em;
}
.engine-field span.hint {
  font-size: 11.5px;
  line-height: 1.45;
  color: var(--ink-3);
  margin-top: 1px;
}
/* These fields set money. They are sized to be read and corrected with
   confidence, not to match the density of a filter control. */
.engine-input {
  height: 40px;
  padding: 0 12px;
  border: 1px solid var(--rule-2);
  border-radius: 0;
  font-size: 14.5px;
  font-weight: 600;
  font-family: inherit;
  font-variant-numeric: tabular-nums lining-nums;
  outline: none;
  background: var(--sheet);
  color: var(--ink);
  transition: border-color .12s ease, box-shadow .12s ease, background .12s ease;
}
.engine-input:hover:not(:disabled) { border-color: var(--rule-3); }
.engine-input:focus {
  border-color: var(--assay-700);
  box-shadow: inset 0 -2px 0 var(--assay-700);
}
.engine-input.is-pinned {
  border-color: var(--tune-100);
  background: var(--tune-50);
  font-weight: 600;
  color: var(--tune-700);
}
.engine-input:disabled,
.engine-input[readonly] {
  background: var(--sheet-alt);
  color: var(--ink-3);
  cursor: not-allowed;
}
.engine-input[readonly] { cursor: default; }

.tune-inherit-note {
  margin: 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--ink-3);
  padding-left: 11px;
  border-left: 1px solid var(--rule-2);
}

.engine-preview-card {
  border: 1px solid var(--rule-2);
  background: var(--sheet-alt);
  padding: 0;
  display: grid;
}
.engine-preview-row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 14px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--rule);
  font-size: 12.5px;
  color: var(--ink-2);
}
.engine-preview-row:last-child { border-bottom: 0; }
.engine-preview-row strong {
  color: var(--ink);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums lining-nums;
}
.engine-preview-row.total-highlight {
  background: var(--sheet);
  font-weight: 700;
  color: var(--ink);
}
.engine-preview-row.total-highlight strong {
  font-size: 17px;
  letter-spacing: -0.02em;
  color: var(--assay-900);
}

/* The type toggle and its value are one control in two parts, so they sit in
   a shared field with a small gap — not stacked flush like two rows. */
.discount-type-group {
  display: flex;
  border: 1px solid var(--rule-2);
  margin-bottom: 6px;
}
.discount-type-btn {
  flex: 1;
  height: 34px;
  border: 0;
  border-right: 1px solid var(--rule-2);
  background: var(--sheet);
  font-family: inherit;
  font-size: 11.5px;
  font-weight: 600;
  color: var(--ink-3);
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.discount-type-btn:last-child { border-right: 0; }
.discount-type-btn:hover:not(:disabled) { background: var(--sheet-alt); color: var(--ink); }
.discount-type-btn.active {
  background: var(--assay-700);
  color: #fff;
}
.discount-type-btn:disabled { opacity: .5; cursor: not-allowed; }

.status-message {
  min-height: 17px;
  font-size: 12px;
  color: var(--ink-3);
}
.status-message.error { color: var(--spec-700); font-weight: 600; }
.status-message.success { color: var(--assay-700); font-weight: 600; }

.read-only-note {
  padding: 10px 12px;
  border: 1px solid var(--rule-2);
  background: var(--sheet-alt);
  color: var(--ink-2);
  font-size: 12px;
  line-height: 1.5;
}

.btn-ghost {
  height: 34px;
  padding: 0 14px;
  border: 1px solid var(--rule-2);
  border-radius: 0;
  background: var(--sheet);
  color: var(--ink);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s ease, border-color .12s ease;
}
.btn-ghost:hover:not(:disabled) { background: var(--sheet-alt); border-color: var(--rule-3); }
.btn-ghost:disabled { opacity: .45; cursor: not-allowed; }

.form-actions { display: flex; gap: 10px; }
.form-actions .btn-calc { flex: 1; height: 36px; }

/* ── Danger zone ───────────────────────────────────────────────────────────
   Irreversible, catalog-wide actions get their own labelled region. The
   weight comes from a solid crimson field, not a stripe on the edge. */
.danger-zone {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 13px 14px;
  border: 1px solid var(--spec-600);
  background: var(--spec-50);
}
.danger-zone-copy { display: grid; gap: 3px; }
.danger-zone-copy strong { color: var(--spec-700); font-size: 12.5px; font-weight: 700; }
.danger-zone-copy span { color: var(--spec-700); font-size: 11.5px; line-height: 1.45; opacity: .85; }
.btn-danger {
  flex: 0 0 auto;
  height: 32px;
  padding: 0 14px;
  border: 1px solid var(--spec-600);
  border-radius: 0;
  background: var(--sheet);
  color: var(--spec-700);
  font-family: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}
.btn-danger:hover:not(:disabled) { background: var(--spec-600); color: #fff; }
.btn-danger:disabled { opacity: .5; cursor: not-allowed; }

/* ══ 7. Utility ═══════════════════════════════════════════════════════════ */
.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;
}
[hidden] { display: none !important; }
.text-sm { font-size: 12.5px; line-height: 1.55; }
.text-muted { color: var(--ink-3); }

/* ══ 8. Adaptation ════════════════════════════════════════════════════════
   Structural, not fluid: the sheet sheds pinned columns and stacks its
   tiers. Type sizes hold, because operators read at a fixed distance. */

@media (max-width: 1180px) {
  .header-instrument { flex-wrap: wrap; height: auto; padding: 0 0 8px 14px; }
  .header-center { flex-wrap: wrap; padding: 8px 12px 0 0; }
  .search-field { max-width: none; flex-basis: 100%; }
  .btn-toggle-view { height: 32px; margin: 8px 14px 0 0; border-left: 1px solid var(--rule-2); border: 1px solid var(--rule-2); }
  .btn-toggle-view::before { display: none; }
  .btn-toggle-view.active-mode { border-color: var(--assay-900); }
}

@media (max-width: 980px) {
  body { height: 100dvh; }
  .header-register { height: auto; flex-wrap: wrap; }
  .header-left { flex-basis: 100%; border-right: 0; border-bottom: 1px solid var(--rule); height: 44px; }
  /* Two ruled rows instead of one overflowing strip: the books, then the
     out-of-spec filter beside the write actions. `align-content: flex-start`
     keeps a wrapped line at its own height rather than stretching it. */
  .header-right {
    width: 100%;
    flex-wrap: wrap;
    align-items: flex-start;
    align-content: flex-start;
  }
  /* Each register control is its own 44px cell; without a fixed height they
     stretch to fill the whole wrapped strip. */
  .header-right > * { height: 44px; min-height: 44px; }
  .header-right > *:first-child { border-left: 0; }
  .origin-switch { flex: 1 0 100%; }
  .origin-option { flex: 1; justify-content: center; }
  .spec-flag {
    flex: 1 0 100%;
    justify-content: center;
    border-top: 1px solid var(--rule);
    border-left: 0 !important;
  }
  .btn-register {
    flex: 1 1 50%;
    justify-content: center;
    border-top: 1px solid var(--rule);
  }

  .col-brand,
  .col-mfg,
  .col-market,
  .col-selling-price {
    position: static;
    left: auto;
    box-shadow: none;
  }
  /* `thead th` pins globally; unpinning the columns must not unpin the
     header ROW, or it tears in half on vertical scroll. */
  thead th.col-brand,
  thead th.col-mfg,
  thead th.col-market,
  thead th.col-selling-price {
    position: sticky;
    top: 0;
    left: auto;
    z-index: 30;
  }
  .col-selling-price { border-right: 1px solid var(--rule-datum) !important; }
  :root {
    --col-row: 66px;
    --col-product: 244px;
    --col-brand: 112px;
    --col-mfg: 112px;
    --col-market: 168px;
    --col-selling: 178px;
  }
  .detail-stats-grid { grid-template-columns: 1fr 1fr; }
  .detail-stat-box:nth-child(2) { border-right: 0; }
  .detail-stat-box:nth-child(-n+2) { border-bottom: 1px solid var(--rule); }
}

@media (max-width: 640px) {
  .header-instrument { padding: 0 0 8px 12px; }
  .header-left { padding: 0 12px; gap: 10px; }
  .header-meta-pill { font-size: 10.5px; }
  /* Two even columns: a 38px-wide select is a control nobody can read. */
  .header-center { display: grid; grid-template-columns: 1fr 1fr; padding: 8px 12px 0 0; }
  .select-field { min-width: 0; }
  .search-field, .select-field:last-child { grid-column: 1 / -1; }
  .btn-toggle-view {
    width: calc(100% - 12px);
    /* 44px is the touch-target floor; 40 was a miss-tap waiting to happen. */
    min-height: 44px;
    justify-content: center;
    margin: 8px 12px 0 0;
  }
  :root { --col-product: 210px; }
  th.source-col-head, .source-data-cell { min-width: 164px; }
  .engine-grid { grid-template-columns: 1fr; }
  .detail-stats-grid { grid-template-columns: 1fr; }
  .detail-stat-box { border-right: 0; border-bottom: 1px solid var(--rule); }
  .detail-stat-box:last-child { border-bottom: 0; }
  .modal-body { padding: 16px; }
  .detail-source-row { align-items: flex-start; flex-direction: column; gap: 8px; }
  .source-row-figure { justify-content: flex-start; }
  .btn-open-link, .listing-unverified { min-width: 40px; min-height: 40px; }
  .record-spec-item { flex-basis: 100%; border-right: 0; }
  .form-actions { flex-direction: column; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}
