/* ============================================================
   PORTED VERBATIM from prototypes/13/variant-selector.css
   (committed 9cae73d). Brief: docs/briefs/2026-08-15-product-variant-selector.md
   § S4 — "port verbatim; do not re-derive CSS."

   Everything below this header is byte-identical to the prototype
   file. Do not edit it here: change the prototype and re-port, so
   the CD mockup stays the source of truth.

   SCOPING NOTE: the `.pv-*` selectors are deliberately UNSCOPED, as
   in the prototype. They are safe site-wide because (a) the `.pv-`
   prefix is unique to this component and (b) every colour resolves
   through light-register tokens (--ink / --rule-2 / --burgundy /
   --card-2 …) that only exist inside a light scope — on this theme,
   `.rhinory-merch-pdp` in assets/css/merch-pdp.css. The component is
   only ever rendered inside that wrapper.
   ============================================================ */

/* ============================================================
   RHINORY v13 · PRODUCT VARIANT SELECTOR (.pv)
   ------------------------------------------------------------
   ONE component, two shapes, light-warm register only (wine PDP +
   shop catalog). Drop it between the product copy and the price
   row; it never replaces the price row and never adds a second CTA.

     .pv--chips  → flat price grid. Gift-card denominations, 6-11
                   options, labelled by formatted price, ascending.
     .pv--seg    → segmented control. 2-5 named options, labelled by
                   the option's own title with its price beneath.
     .pv--menu   → the same named options as a select, for 6+ options
                   or labels longer than ~28 characters.

   Grammar borrowed on purpose, nothing invented:
     · option chip = .sa-shopby-chip (shop-all "shop by" pick-one chip)
     · burgundy fill = the selected state, exactly as that chip
     · struck figure = the .pt-was / .sa-was centered pseudo-rule
     · label type = Josefin 600 uppercase, 10-12px, tracking by size
     · radius 2px, hairline rules, no shadows on flat controls

   Tokens are inherited from the surrounding light register scope
   (.light-warm on the PDP, .shop-all on the catalog). This file sets
   no colours of its own beyond fallbacks.
   ============================================================ */

/* Container context: mobile rules key on the WIDTH OF THE COLUMN the
   selector sits in, not the viewport, so the same component works in
   a PDP details column, a 390 phone, and a catalog tile. */
.pv-ctx{ container-type:inline-size; }

.pv{ margin:30px 0 0; }
.pv-head{ display:flex; align-items:baseline; justify-content:space-between; gap:10px 20px; flex-wrap:wrap; margin:0 0 14px; }
.pv-label{
  margin:0; font-family:var(--ff-label); font-size:11px; font-weight:600;
  letter-spacing:0.18em; text-transform:uppercase; color:var(--ink,var(--ink-warm));
}
.pv-count{
  margin:0; font-family:var(--ff-label); font-size:10px; font-weight:600;
  letter-spacing:0.16em; text-transform:uppercase; color:var(--muted,var(--rhino-warm));
}

/* ---------- shared option cell ---------- */
.pv-opt{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  min-height:48px; padding:11px 18px; background:none; cursor:pointer;
  border:1px solid var(--rule-2,var(--rule-warm-2)); border-radius:2px;
  color:var(--ink,var(--ink-warm)); text-align:center;
  transition:background .2s, border-color .2s, color .2s;
}
.pv-opt .fig{
  font-family:var(--ff-display); font-size:20px; font-weight:500; line-height:1;
  letter-spacing:-0.005em; font-variant-numeric:lining-nums; font-feature-settings:"lnum" 1;
}
.pv-opt .nm{
  font-family:var(--ff-label); font-size:11px; font-weight:600; letter-spacing:0.14em;
  text-transform:uppercase; line-height:1.25;
}
.pv-opt:hover{ border-color:var(--burgundy); color:var(--burgundy); background:var(--burgundy-tint,rgba(82,0,0,0.07)); }
.pv-opt:focus-visible{ outline:2px solid var(--burgundy); outline-offset:2px; }
.pv-opt[aria-checked="true"]{
  background:var(--burgundy); border-color:var(--burgundy); color:var(--paper);
}
.pv-opt[aria-checked="true"]:hover{ background:var(--burgundy-2,#3d0000); color:var(--paper); }

/* sold out: dimmed by GROUND, not by ink (muted ink on the deeper bed fails AA).
   Stays focusable and announced; the click is ignored, not swallowed silently. */
.pv-opt[aria-disabled="true"]{
  background:var(--card-2); border-color:var(--rule-2,var(--rule-warm-2));
  color:var(--ink-2,var(--ink-warm-2)); cursor:not-allowed;
}
.pv-opt[aria-disabled="true"]:hover{ background:var(--card-2); border-color:var(--rule-2,var(--rule-warm-2)); color:var(--ink-2,var(--ink-warm-2)); }
.pv-opt[aria-disabled="true"] .fig{ position:relative; opacity:.72; }
.pv-opt[aria-disabled="true"] .fig::after{
  content:""; position:absolute; left:-2px; right:-2px; top:50%; height:1px;
  background:currentColor; transform:translateY(-0.5px);
}
.pv-so{
  font-family:var(--ff-label); font-size:9px; font-weight:600; letter-spacing:0.16em;
  text-transform:uppercase; color:var(--ink-2,var(--ink-warm-2)); line-height:1;
}

/* ---------- SHAPE 1 · chips (denominations) ---------- */
.pv--chips .pv-grid{ display:flex; flex-wrap:wrap; gap:8px; }
.pv--chips .pv-opt{ min-width:86px; }
.pv--chips .pv-opt[aria-disabled="true"]{ flex-direction:column; gap:3px; min-height:48px; padding:7px 16px; }

/* ---------- SHAPE 2 · segmented control (named options) ---------- */
.pv--seg .pv-grid{
  display:flex; border:1px solid var(--rule-2,var(--rule-warm-2)); border-radius:2px; overflow:hidden;
}
.pv--seg .pv-opt{
  flex:1 1 0; min-width:0; flex-direction:column; align-items:flex-start; gap:7px;
  min-height:74px; padding:15px 18px; border:0; border-radius:0; text-align:left;
  border-left:1px solid var(--rule-2,var(--rule-warm-2));
}
.pv--seg .pv-opt:first-child{ border-left:0; }
.pv--seg .pv-opt .fig{ font-size:23px; }
.pv--seg .pv-opt:focus-visible{ outline-offset:-3px; }
.pv--seg .pv-opt[aria-disabled="true"] .pv-so{ margin-left:auto; }
.pv--seg .pv-optfoot{ display:flex; align-items:baseline; gap:12px; width:100%; }

/* ---------- SHAPE 2b · menu fallback ---------- */
.pv--menu .pv-select{
  width:100%; max-width:420px; min-height:52px; padding:14px 42px 14px 16px; cursor:pointer;
  font-family:var(--ff-label); font-size:12px; font-weight:600; letter-spacing:0.12em; text-transform:uppercase;
  color:var(--ink,var(--ink-warm)); background-color:var(--card); border:1px solid var(--rule-2,var(--rule-warm-2)); border-radius:2px;
  appearance:none; -webkit-appearance:none;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23520000' stroke-width='1.6'><path d='M2 4l4 4 4-4'/></svg>");
  background-repeat:no-repeat; background-position:right 16px center;
}
.pv--menu .pv-select:hover{ border-color:var(--burgundy); }
.pv--menu .pv-select:focus-visible{ outline:2px solid var(--burgundy); outline-offset:2px; }

/* ---------- price row additions ---------- */
/* "from" rides in front of the figure in the same slot the sale
   treatment gives "was", so a multi-variant price and a marked-down
   price never fight for the same real estate. */
.pv-from{
  font-family:var(--ff-label); font-size:11px; font-weight:600; letter-spacing:0.2em;
  text-transform:uppercase; color:var(--muted,var(--rhino-warm)); align-self:center;
}
.pv-from[hidden]{ display:none; }
.pv-amt{ display:inline-block; transition:opacity .13s ease, transform .13s ease; }
.pv-amt.is-out{ opacity:0; transform:translateY(-5px); }
.pv-amt.is-in{ animation:pv-in .26s cubic-bezier(.2,.7,.2,1) both; }
@keyframes pv-in{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
@media (prefers-reduced-motion:reduce){
  .pv-amt, .pv-amt.is-out, .pv-amt.is-in{ transition:none; animation:none; opacity:1; transform:none; }
}
/* the selected option, restated in words next to the price */
.pv-chosen{
  font-family:var(--ff-label); font-size:10px; font-weight:600; letter-spacing:0.16em;
  text-transform:uppercase; color:var(--burgundy); display:inline-flex; align-items:center; gap:9px;
}
.pv-chosen::before{ content:""; width:18px; height:1px; background:currentColor; }
.pv-chosen[hidden]{ display:none; }

/* ---------- CTA gate ---------- */
button.pv-gate[disabled], button.pv-gate[aria-disabled="true"]{
  background:var(--card-2); border-color:var(--rule-2,var(--rule-warm-2)); color:#6B645B;
  cursor:not-allowed; box-shadow:none; transform:none;
}
button.pv-gate[disabled]:hover, button.pv-gate[aria-disabled="true"]:hover{ background:var(--card-2); color:#6B645B; transform:none; box-shadow:none; }
.pv-hint{
  margin:0; font-family:var(--ff-body); font-style:italic; font-size:14px; line-height:1.6;
  color:var(--ink-2,var(--ink-warm-2));
}
.pv-hint[hidden]{ display:none; }

/* ---------- member price, per selected option ---------- */
/* Reserve green is the member state on light transactional surfaces
   (.sa-memberline / .sa-buy--member on shop-all). Same ink here. */
.pv-member{ display:flex; flex-direction:column; gap:7px; }
.pv-memberline{
  display:inline-flex; align-items:center; gap:8px; margin:0; white-space:nowrap;
  font-family:var(--ff-label); font-size:10px; font-weight:700; letter-spacing:0.12em;
  text-transform:uppercase; color:#1F4F37;
}
.pv-memberline .pip{ width:6px; height:6px; background:#1F4F37; flex:none; }
.pv-mfig{
  font-family:var(--ff-display); font-weight:500; font-size:34px; line-height:1; color:#1F4F37;
  font-variant-numeric:lining-nums; font-feature-settings:"lnum" 1;
}
.pv-mrow{ display:flex; align-items:baseline; gap:10px; }
.pv-mnote{
  margin:0; font-family:var(--ff-label); font-size:10px; font-weight:600; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--muted,var(--rhino-warm));
}
/* live re-fetch on option change: the figure never flickers between two
   big numbers, it goes quiet for the length of the request. */
.pv-member.is-pending .pv-mfig{ opacity:.28; }
.pv-member.is-pending .pv-mnote .dots::after{ content:""; animation:pv-dots 1.1s steps(4,end) infinite; }
@keyframes pv-dots{ 0%{content:""} 25%{content:"."} 50%{content:".."} 75%{content:"..."} }
@media (prefers-reduced-motion:reduce){ .pv-member.is-pending .pv-mnote .dots::after{ animation:none; content:"..."; } }

/* ---------- catalog tile picker (secondary surface) ---------- */
.pv--tile{ margin:14px 0 0; }
.pv--tile .pv-head{ margin-bottom:9px; }
.pv--tile .pv-label{ font-size:10px; letter-spacing:0.16em; }
.pv--tile .pv-grid{ gap:6px; }
.pv--tile .pv-opt{ min-height:44px; min-width:0; padding:9px 12px; }
.pv--tile .pv-opt .fig{ font-size:17px; }
.pv--tile .pv-more{
  font-family:var(--ff-label); font-size:10px; font-weight:600; letter-spacing:0.14em;
  text-transform:uppercase; color:var(--burgundy); align-self:center; padding:0 4px;
  border-bottom:1px solid var(--rule-burg,rgba(82,0,0,0.24)); text-decoration:none;
}
.pv--tile .pv-more:hover{ border-color:var(--burgundy); }

/* ---------- narrow columns (phone, tile, drawer) ---------- */
@container (max-width:520px){
  .pv{ margin-top:24px; }
  .pv--chips:not(.pv--tile) .pv-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:7px; }
  .pv--chips:not(.pv--tile) .pv-opt{ min-width:0; padding:11px 8px; }
  .pv--seg .pv-grid{ flex-direction:column; }
  .pv--seg .pv-opt{ border-left:0; border-top:1px solid var(--rule-2,var(--rule-warm-2)); min-height:64px; }
  .pv--seg .pv-opt:first-child{ border-top:0; }
  .pv--menu .pv-select{ max-width:none; }
}

/* screen-reader only status line (price changes announced politely) */
.pv-sr{ position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
