/* ============================================================
 * Public stock teaser styles · scoped to .price-page
 *
 * Loads ONLY on /online-inventory, /online-inventory/{item} and
 * /warehouse-inventory: App.razor nests this <link> inside the
 * pillar-stylesheet block behind isPublicStockRoute (the
 * flipping.css precedent). Layers over landing.css (tokens,
 * .wrap) and pillar.css (.prelude, .qa, .sku-table, .deal-chip,
 * .badge, .state-table, .warehouse-card) — every selector below
 * is scoped under .price-page so nothing leaks into the six
 * routes that render-block on pillar.css alone.
 *
 * Consumes the landing.css document-level tokens (this file
 * declares no token block of its own — the guard test is a
 * file-wide text match, so don't name that selector here even in
 * a comment). ONE new token:
 * --console-bg — Direction C's single dark module (the
 * pillar.css .conversion precedent at pillar.css:846).
 * ============================================================ */

.price-page{
  --console-bg: var(--ink);
}

/* Accessible-only text (hub thumb column header). Self-contained
   rather than relying on the Paces bundle's visually-hidden rule.
   `clip` is deprecated but still the only thing some older engines
   honour, so both it and clip-path ship.

   WARNING for the markup author: apply this to an element INSIDE the
   cell (<th><span class="sr-only">…</span></th>), never to a bare
   <th class="sr-only">. position:absolute takes the cell out of the
   table's row box, which drops a column from the row and desyncs it
   from the colgroup — every fixed width below then applies to the
   wrong column. */
.price-page .sr-only{
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============ Dark console band (contract C6) ============ */
/* Full-bleed sibling of .prelude — rendered by TeaserConsole.razor:
   <section class="console"> > .wrap > .console-tiles > 4 × .console-tile,
   plus an optional <time class="console-stamp">. Values are gold mono
   on ink: the app's visual signature, spent exactly once per page. */
.price-page .console{
  background: var(--console-bg);
  color: var(--bg);
  padding: clamp(20px, 2.5vw, 30px) 0;
}
.price-page .console .console-tiles{
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
}
.price-page .console .console-tile{
  padding: 4px 22px;
  border-left: 1px solid rgba(255, 255, 255, .10);
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.price-page .console .console-tile:first-child{ border-left: 0; padding-left: 0; }
/* Labels WRAP; they do not truncate. (W9 Task 9 fix round 1.)
   These labels carry the scope qualifiers that make the figures honest —
   "(all-time)", "any-channel", "(30d)" — and tail-first ellipsis eats exactly
   those, because a qualifier is what sits at the end. Measured at a 390px
   viewport the tile box is 139.5px while "Typical window (all-time)" is 185px
   and "Any-channel restocks today" is 192px: both lost their qualifier on
   every phone, i.e. the truncation was silently undoing the fix. Shortening
   the labels would have traded the same honesty away by hand, so the class
   changed instead.
   Keeping the gold values on one optical row is then handled by BOTTOM-aligning
   them (margin-top:auto on .v below), not by reserving a fixed number of label
   lines: the grid already stretches every tile in a row to the same height, so
   an auto top margin puts every value on the row's baseline no matter how many
   lines its label took. A reserved two-line box was tried first and broke at
   390px, where "Fastest any-channel sellout (30d)" needs THREE lines and left
   the tile beside it 13px high. */
.price-page .console .console-tile .lbl{
  font-family: var(--mono);
  font-size: 10px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .55);
  line-height: 1.3;
  overflow-wrap: break-word;
}
.price-page .console .console-tile .v{
  /* Bottom-align: the grid stretches every tile in a row to one height, so this
     keeps all four values on a single baseline however many lines their labels
     wrapped to. See the .lbl comment above. */
  margin-top: auto;
  font-family: var(--mono);
  font-size: clamp(20px, 2vw, 26px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--gold-300);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.price-page .console .console-stamp{
  display: block;
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: .08em;
  color: rgba(255, 255, 255, .45);
}
@media (max-width: 880px){
  .price-page .console .console-tiles{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .price-page .console .console-tile{ padding: 10px 16px; }
  .price-page .console .console-tile:nth-child(odd){ border-left: 0; padding-left: 0; }
  .price-page .console .console-tile:nth-child(n+3){
    border-top: 1px solid rgba(255, 255, 255, .10);
    padding-top: 14px;
    margin-top: 6px;
  }
}

/* ============ Hub table: thumbnail column (Task 5) ============ */
/* Semantic-table twin of pillar.css's .sku-row .thumb (212–224):
   background on the img itself is the CSS-only degrade path — a
   missing/blocked Costco-hosted image collapses to a neutral
   var(--surface-2) tile with no script involved. */
/* The horizontal padding override is load-bearing, not cosmetic. pillar.css
   gives every body cell `padding: 13px 18px` and landing.css puts the page in
   border-box, so a 56px image inside the inherited 18px insets needs 92px of
   min-content — and a table without table-layout:fixed treats `width` as a
   MINIMUM, so 92px would silently win over both the 72px here and the 72px on
   col.col-thumb. 56 + 8 + 8 = 72 makes the declared width actually reachable.
   Do NOT reach for table-layout:fixed instead: it would change how every other
   column in the table resolves. */
.price-page .sku-table td.thumb{
  width: 72px;
  padding: 8px;
}
.price-page .sku-table td.thumb img{
  display: block;
  width: 56px; height: 56px;
  border-radius: 8px;
  border: 1px solid var(--border-soft);
  background: var(--surface-2);
  object-fit: contain;
  padding: 4px;
}
/* Sold-out rows. Smaller, not faded — see the razor comment beside the
   markup for why size carries the hierarchy here and opacity does not. */
.price-page .sku-table td.thumb.thumb-sm{
  width: 56px;
}
.price-page .sku-table td.thumb.thumb-sm img{
  width: 40px; height: 40px;
  border-radius: 6px;
  padding: 3px;
}

/* Fixed column widths so 50+ thumbnails never reflow the hub table
   (CLS). Task 5 emits <colgroup> with EXACTLY these class names —
   col-thumb … col-stock. Do not shorten them to c-*: a colgroup
   whose classes match no rule silently drops every fixed width. */
.price-page .sku-table col.col-thumb{ width: 72px; }
/* Sold-out table's smaller thumbnail. The same min-content arithmetic the
   td.thumb comment above spells out applies at this size: 40 + 8 + 8 = 56,
   so the declared width stays reachable and `width` (a MINIMUM without
   table-layout:fixed) cannot be overridden by the cell's own content. The
   col rule must be BOTH classes — a bare .col-thumb would re-widen it to 72. */
.price-page .sku-table col.col-thumb.col-thumb-sm{ width: 56px; }
.price-page .sku-table col.col-product{ width: auto; }
.price-page .sku-table col.col-weight{ width: 90px; }
.price-page .sku-table col.col-price{ width: 110px; }
.price-page .sku-table col.col-premium{ width: 150px; }
.price-page .sku-table col.col-stock{ width: 110px; }

/* Mono item number under the product name (mirrors pillar's .sku-row .name .item). */
.price-page .sku-table .item{
  display: block;
  margin-top: 3px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
  font-weight: 400;
}
.price-page .sku-table td.weight{
  font-family: var(--mono);
  font-size: 13px;
  color: var(--ink-soft);
}

/* ============ Stocked-warehouse photo grid (Task 8) ============ */
/* pillar.css owns .warehouse-grid/.warehouse-card/.state-pill/.city/.meta
   (494–566); only the teaser-specific top margin lives here. Task 8
   appends its map/legend/state-table rules but does NOT redefine this,
   so this one line stays in the scaffold. */
.price-page .warehouse-grid{ margin-top: 24px; }

/* ------------------------------------------------------------------
   ONE BLOCK PER TASK, OWNED BY THE TASK WHOSE MARKUP RENDERS IT.
   Task 6's per-SKU hero and availability bar are the block below;
   Task 7 appends the sibling strip (.sibling-grid, .sibling-card);
   Task 8 appends the map card, legend, .state-table .with-bars
   re-grid and .state-zero block. Pre-shipping a later task's rules
   here produced two definitions of the same selector with different
   values. Do not re-add them. --------------------------------------- */

/* ============ Task 6: per-SKU hero (two-column, dark figure panel) ============ */
/* ≥880px: fixed 380px figure column + fluid main column (ui-design rec 4 wireframe);
   below that it stacks. 380 = 320px image + 2×28px panel padding + border allowance. */
.price-page .sku-hero{
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  align-items: center;
  margin-top: 18px;
}
@media (min-width: 880px){
  .price-page .sku-hero{ grid-template-columns: 380px minmax(0, 1fr); gap: 40px; }
}
/* Dark inset card — the app-signature surface. Doubles as the CSS-only empty/broken
   image state: the panel + mono item number need no image to look intentional. */
.price-page .sku-hero-figure{
  position: relative;
  margin: 0;
  background: var(--console-bg, var(--ink));
  border-radius: 16px;
  padding: 28px;
  box-shadow: var(--shadow-md);
  display: grid;
  place-items: center;
  min-height: 280px;
  overflow: hidden;
}
/* Gold radial glow behind the product — the .prelude::before gradient recipe
   (pillar.css:29-33) re-tuned for a dark ground. */
.price-page .sku-hero-figure::before{
  content: "";
  position: absolute;
  inset: -40px 10% auto 10%;
  height: 240px;
  background: radial-gradient(50% 60% at 50% 0%, rgba(214,173,85,.18), transparent 70%);
  filter: blur(20px);
  pointer-events: none;
}
.price-page .sku-hero-figure img{
  position: relative;
  width: min(320px, 100%);
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: contain;
}
.price-page .sku-hero-figure .figure-item{
  position: relative;
  font-family: var(--mono);
  font-size: 13px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--gold-300);
}
.price-page .sku-hero-figure .metal-pill{
  position: absolute;
  top: 14px; left: 14px;
  font-family: var(--mono);
  font-size: 10px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255,255,255,.92);
  color: var(--ink);
  box-shadow: var(--shadow-sm);
}
/* The H1 steps down inside the hero: pillar.css sizes .prelude h1 as a full-width
   display headline (up to 84px, max-width 18ch), which in a ~600px column wraps a
   SKU name across five or six lines and out-shouts the price this column exists to
   lead with. Long product names still need a wrap allowance, so the measure widens
   as the size drops. */
.price-page .sku-hero-main h1{
  font-size: clamp(26px, 2.6vw, 36px);
  line-height: 1.15;
  max-width: 24ch;
  margin: 0 0 16px;
}
/* Price-dominant right column */
.price-page .hero-price-row{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 14px;
  margin: 0 0 10px;
}
.price-page .hero-price-row .price-big{
  font-family: var(--mono);
  font-size: clamp(30px, 3.2vw, 40px);
  font-weight: 600;
  letter-spacing: -.01em;
  color: var(--ink);
  font-feature-settings: "tnum";
}

/* Hero CTA: a statement line over the trial button. The line STATES this SKU's
   situation and the gold submit button beneath it carries the ask, so the line
   steps back to the subline's muted prose weight instead of competing with the
   button. (pillar.css:1063 still styles `.price-page .hero-cta a` from when this
   was a text link to /register — no anchor renders here any more; that rule is
   left alone rather than deleted because .hero-cta is a pillar-scoped class.) */
.price-page .hero-cta{
  margin: 0 0 12px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 48ch;
}
/* landing.css gives .hero-ctas a 28px top margin sized for the LANDING hero's
   composition (a 48px H1 with a lede under it); here the statement line directly
   above already supplies that gap, and inheriting it opened a 40px hole between
   the two. Two classes on one compound selector so this beats
   `.landing-page .hero-ctas` on specificity, not on link order — both files load
   on this route and the order is App.razor's business, not this rule's. */
.landing-page.price-page .hero-ctas{
  margin-top: 0;
}

/* ============ Task 6 availability proportion bar — REMOVED in Task 9 ============ */
/* The bar's width and its readout both encoded a share of the last 90 days that
   was manufactured from two different spans (a 90-day restock count scaled by an
   average taken over every window on record). No honest 90-day share is derivable
   from the data the page is allowed to read, so the element is gone rather than
   restyled, and its four rules go with it. The availability section is prose plus
   the confirmed-window table below it; the two real figures live in the console
   band. Do not re-add a proportion bar here without a real in-window numerator. */

/* ============ Task 7: sibling-SKU strip ============ */
.price-page .sibling-grid{
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 14px;
}
.price-page .sibling-card{
  display: grid;
  gap: 8px;
  align-content: start;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 14px;
  box-shadow: var(--shadow-sm);
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.price-page .sibling-card:hover{
  transform: translateY(-2px);
  box-shadow: var(--shadow-md);
  border-color: var(--gold-100);
}
/* Thumb tile doubles as the CSS-only missing/broken-image state (neutral surface). */
.price-page .sibling-card .thumb{
  width: 112px; height: 112px;
  margin: 0 auto;
  border-radius: 10px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  display: grid;
  place-items: center;
  overflow: hidden;
}
.price-page .sibling-card .thumb img{
  width: 100%; height: 100%;
  object-fit: contain;
  padding: 6px;
}
.price-page .sibling-card .name{
  font-size: 13.5px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.35;
  letter-spacing: -.01em;
}
.price-page .sibling-card .line{
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.price-page .sibling-card .price{
  font-family: var(--mono);
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  font-feature-settings: "tnum";
}
/* The stock badge is the card's last row — shrink-wrap it to its text instead of
   letting the grid column stretch it edge to edge. */
.price-page .sibling-card .badge{
  justify-self: start;
}

/* ============ Task 7: FAQ answer links ============ */
/* pillar.css styles prose links inside .qa-head .answer, but NOT inside .faq-item p —
   so an anchor in an FAQ answer inherited --ink-soft with no underline and rendered
   pixel-identical to the body text around it. Actual blast radius is the THREE public
   stock teasers, all of which had the defect: App.razor loads this stylesheet only on
   isPublicStockRoute, so /costco-{metal}-price never sees it, and PriceToday.razor
   carries no .faq-item markup either way. (An earlier revision of this comment claimed
   four surfaces.) The pillar page is not .price-page and is untouched. Values mirror
   pillar.css:170 so a teaser FAQ link and a teaser prose link look the same. */
.price-page .faq-item p a{
  color: var(--ink);
  text-decoration: underline;
  text-decoration-color: var(--gold-300);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: text-decoration-color .15s;
}
.price-page .faq-item p a:hover{ text-decoration-color: var(--gold-500); }

/* ============ Task 8: warehouse page — map card, legend, split state table ============ */
.price-page .map-card{
  margin-top: 24px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 18px 18px 12px;
  box-shadow: var(--shadow-sm);
}
.price-page .map-card .price-map{ margin-top: 0; }
/* Key swatches carry the LITERAL fills pillar.css:1273-1280 gives the map's bands
   and dots. If either side ever changes, change both — a key that disagrees with
   the choropleth it labels is worse than no key at all.

   NAME IS LOAD-BEARING: landing.css:1066 already owns `.map-legend` as the home
   page's Leaflet overlay pill (position:absolute; left:10px; bottom:10px;
   z-index:900; pointer-events:none). Every teaser wrapper carries .landing-page,
   and `.landing-page .map-legend` and `.price-page .map-legend` tie on specificity,
   so the properties this block does NOT redeclare — position, left, bottom — would
   survive and fling the key to the bottom-left of the document. Do not rename this
   back. */
.price-page .map-key{
  list-style: none;
  margin: 10px 0 2px;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--ink-muted);
}
.price-page .map-key li{ display: inline-flex; align-items: center; gap: 6px; }
.price-page .map-key .swatch{
  width: 12px; height: 12px;
  border-radius: 3px;
  /* --border, not --border-soft: the latter is the same hex as --surface-3, which
     would leave the "no stock" swatch borderless on the white card. */
  border: 1px solid var(--border);
}
.price-page .map-key .swatch.none{ background: var(--surface-3); }
.price-page .map-key .swatch.low{ background: var(--gold-100); }
.price-page .map-key .swatch.high{ background: var(--gold-500); }
.price-page .map-key .dot{ width: 9px; height: 9px; border-radius: 50%; }
.price-page .map-key .dot.in{ background: var(--in-stock); }
.price-page .map-key .dot.out{ background: rgba(12, 12, 10, .30); }

/* 4-column state table (State / share / In stock / Warehouses). pillar.css's price-page
   variant is 3-col; the .with-bars modifier widens it — higher specificity + later in
   the cascade, so it wins without touching pillar.css. The bar itself is styled by
   pillar.css's .state-table-row .bar-wrap (--w) rules already on this route. */
.price-page .state-table.with-bars .state-table-head,
.price-page .state-table.with-bars .state-table-row{
  grid-template-columns: minmax(0, 1.1fr) minmax(90px, 1fr) 80px 100px;
}
/* The share column holds the bar AND its integer readout in ONE grid cell, so the
   row keeps a text value under every header label. */
.price-page .state-table.with-bars .bar-cell{
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.price-page .state-table.with-bars .bar-cell .bar-wrap{ flex: 1 1 auto; min-width: 0; }
.price-page .state-table.with-bars .bar-pct{
  flex: 0 0 auto;
  width: 34px;
  text-align: right;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--ink-muted);
  font-feature-settings: "tnum";
  font-variant-numeric: tabular-nums;
}
/* Paint floor for a real-but-tiny share. This lives in CSS on purpose: clamping the
   NUMBER instead (the first draft's Math.Clamp(…, 2, 100)) would print "2%" beside a
   state that is actually 1% stocked, now that the figure is rendered as text. */
.price-page .state-table.with-bars .bar-wrap::after{ min-width: 3px; }
@media (max-width: 560px){
  /* The bar drops out but its readout does NOT — the share is data, and keeping it
     preserves the 4-labels / 4-values parity at every width. */
  .price-page .state-table.with-bars .state-table-head,
  .price-page .state-table.with-bars .state-table-row{
    grid-template-columns: minmax(0, 1fr) 58px 58px 68px;
    gap: 10px;
  }
  .price-page .state-table.with-bars .bar-cell .bar-wrap{ display: none; }
  .price-page .state-table.with-bars .bar-pct{ width: auto; flex: 1 1 auto; }
}

/* Muted secondary block for zero-stock states (replaces 30+ all-zero table rows) */
.price-page .state-zero{
  margin-top: 20px;
  padding: 16px 18px;
  background: var(--surface-2);
  border: 1px solid var(--border-soft);
  border-radius: 14px;
}
.price-page .state-zero h3{
  margin: 0 0 8px;
  font-family: var(--mono);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ink-muted);
}
.price-page .state-zero p{
  margin: 0;
  font-size: 13px;
  line-height: 1.7;
  color: var(--ink-muted);
}
.price-page .state-zero p.note{
  margin-top: 10px;
  font-family: var(--mono);
  font-size: 11px;
  line-height: 1.5;
}
