/** Shopify CDN: Minification failed

Line 732:50 Unexpected "1440"

**/
/* ============================================================
   LIQUOR v2 -> SHOPIFY: PORT ADDITIONS
   Loaded AFTER liquor.css. Everything the theme needs that the concept's stylesheet does not
   contain. Kept in a separate file on purpose so `assets/liquor.css` stays provably identical
   to the concept's stylesheet (see _qc/css-port-check.py) and every addition is auditable here.

   Two kinds of thing live in this file, and nothing else:
     A. CSS the CONCEPT ships from JAVASCRIPT (store.js injectChatCSS) rather than from its
        stylesheet - so it is part of the oracle, it just was not in the .css file.
     B. CSS for surfaces SHOPIFY FORCES that the concept never had (pagination, a search results
        page, real customer-account templates).

   RULE: no new generic class names. On the concept, a fresh `.opt` inherited the checkout
   delivery-option card and painted two fat white boxes into a dark form. Everything here is
   either the concept's own name or namespaced. Grep liquor.css before naming anything.
   ============================================================ */


/* ------------------------------------------------------------
   A. CELLAR CONCIERGE - ported verbatim from store.js injectChatCSS()
   ------------------------------------------------------------ */
#chatFab{position:fixed;right:20px;bottom:20px;z-index:540;background:var(--ink);color:#fff;
  display:flex;align-items:center;gap:9px;padding:14px 19px;border-radius:30px;box-shadow:var(--shadow-pop);font-weight:700;font-size:14px}
#chatFab svg{width:20px;height:20px;color:var(--amber)}
#chatFab:hover{background:var(--ink-2)}

/* 🔴 SPINE S9 - DELIBERATE DEVIATION FROM THE CONCEPT.
   The concept collapses at 560px, which leaves a 172px pill sitting over products at 768px
   (Allen caught this on the pilot). Collapsing at 900px is the "chat FAB breakpoint reconcile"
   item from the 2026-07-10 port plan, decided rather than inherited. Re-check 768 before
   changing it back. */
@media(max-width:900px){#chatFab span{display:none}#chatFab{padding:15px;border-radius:50%}}

#chatWin{position:fixed;right:20px;bottom:84px;z-index:541;width:min(372px,calc(100vw - 30px));height:524px;max-height:72vh;
  background:#fff;border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow-pop);
  display:none;flex-direction:column;overflow:hidden}
#chatWin.open{display:flex}
.cw-head{display:flex;align-items:center;justify-content:space-between;padding:16px 18px;background:var(--ink);border-bottom:1px solid var(--line);color:#fff}
.cw-head b{display:block;font-size:15px;font-family:var(--font-d);font-weight:700}
.cw-head span{font-size:11.5px;color:rgba(255,248,236,.7)}
.cw-head button{color:rgba(255,248,236,.7)}
.cw-head button:hover{color:#fff}
.cw-body{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:10px;background:var(--paper)}
.cw-msg{max-width:86%;padding:11px 14px;border-radius:14px;font-size:13.5px;line-height:1.5}
.cw-msg.bot{background:#fff;color:var(--ink-soft);border:1px solid var(--line);border-bottom-left-radius:3px}
.cw-msg.bot a{color:var(--amber-ink);text-decoration:underline;font-weight:600}
.cw-msg.me{background:var(--amber);color:var(--ink-on-amber);align-self:flex-end;border-bottom-right-radius:3px;font-weight:500}
.cw-prods{display:flex;flex-direction:column;gap:7px;margin-top:9px}
.cw-prod{display:flex;align-items:center;gap:10px;background:#fff;border:1px solid var(--line);border-radius:9px;padding:7px}
.cw-prod:hover{border-color:var(--amber)}
.cwp-ph{width:38px;height:38px;background:var(--paper);border-radius:6px;display:grid;place-items:center;padding:3px;flex:none}
.cwp-ph img{max-height:100%;width:auto}
.cw-prod b{display:block;font-size:12px;color:var(--ink);line-height:1.2}
.cwp-pr{font-family:var(--font-l);font-size:11.5px;color:var(--wine);font-weight:600}
.cw-quick{display:flex;flex-wrap:wrap;gap:6px;padding:10px 12px;background:#fff;border-top:1px solid var(--line)}
.cw-quick button{font-size:11.5px;border:1px solid var(--line-2);color:var(--ink-soft);padding:7px 11px;border-radius:14px}
.cw-quick button:hover{border-color:var(--amber);color:var(--amber-deep);background:var(--amber-soft)}
.cw-in{display:flex;gap:8px;padding:11px 12px;background:#fff;border-top:1px solid var(--line)}
.cw-in input{flex:1;height:42px;border-radius:21px;border:1px solid var(--line-2);background:var(--paper);color:var(--ink);padding:0 15px;font-size:13.5px}


/* ------------------------------------------------------------
   B. SURFACES SHOPIFY FORCES THAT THE CONCEPT NEVER HAD
   Built from the existing tokens only - no new colours, radii, fonts or spacing values.
   ------------------------------------------------------------ */

/* a11y utility. Never display:none - that hides it from screen readers too. */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* --- pagination. The concept rendered all 1,324 products client-side and never paginated. --- */
.pager{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;
  margin:clamp(24px,4vw,44px) auto 0;max-width:var(--maxw)}
.pager .pg{display:grid;place-items:center;min-width:42px;height:42px;padding:0 14px;
  border:1px solid var(--line-2);border-radius:var(--radius);background:#fff;color:var(--ink-soft);
  font-family:var(--font-l);font-size:14px;font-weight:600;transition:.18s var(--ease)}
.pager a.pg:hover{border-color:var(--amber);color:var(--amber-deep);background:var(--amber-soft)}
.pager .pg.is-current{background:var(--ink);border-color:var(--ink);color:var(--cream)}
.pager .pg-gap{border-color:transparent;background:none;min-width:22px;padding:0}
@media(max-width:560px){.pager .pg-prev,.pager .pg-next{width:100%}}

/* --- /search results template --- */
.search-form{display:flex;gap:10px;flex-wrap:wrap;margin:0 0 clamp(18px,3vw,30px)}
.search-form input{flex:1 1 260px;min-width:0;height:52px;padding:0 18px;font-size:16px;
  border:1px solid var(--line-2);border-radius:var(--radius);background:var(--paper);color:var(--ink)}
.sr-count{font-family:var(--font-l);color:var(--muted);margin:0 0 clamp(14px,2vw,22px)}

/* --- /404. Shopify forces a not-found template; the concept never had one (probed 2026-07-30:
   its own /404.html is Netlify's default page). Justification (b): a surface the platform forces.
   Five names, all namespaced `nf-`, all built from existing tokens: no new colour, radius, font
   or shadow. Everything else on the template reuses ported components verbatim: .search-form,
   .hero-cta, .btn, .eyebrow, .section, .sec-head, .cat-circles/.ccircle, .vprops/.vprop. --- */
.nf-hero{position:relative;overflow:hidden;border-bottom:1px solid var(--line);
  /* the same gradient .hero uses (liquor.css:459), so the band reads as this store's top-of-page */
  background:linear-gradient(120deg,var(--amber-soft),#fff 62%);
  padding-block:clamp(40px,6.5vw,84px)}

/* The numeral is anchored to the CONTENT COLUMN, not the full-bleed band, see the note in
   sections/main-404.liquid. Positioning it against the band passed every mechanical check and
   still fell apart at 2560. */
.nf-hero .wrap{position:relative}
.nf-in{position:relative;z-index:1;max-width:660px}
.nf-in h1{font-size:clamp(31px,5vw,58px);font-weight:800;letter-spacing:-.03em;margin:14px 0;text-wrap:balance}
.nf-lead{font-size:clamp(15px,1.6vw,18px);color:var(--ink-soft);max-width:46ch;margin-bottom:24px}
/* 🔴 `--muted` (#7C7060) MEASURED 4.28:1 HERE at 768px: a real AA fail on 13px text, and one the
   hex pair does not predict: #7C7060 on white is 4.9:1, but this text sits on the amber end of
   the band's gradient, where the same ink lands at 4.28. It read 4.65 at 390 and 4.54 at 1440, so
   it was passing on most widths while failing on one, which is exactly why a single-viewport
   contrast check is not a contrast check. `--ink-soft` is the palette's next step down and clears
   it everywhere with room to spare. The note stays visually subordinate via size, not colour. */
.nf-hint{font-size:13px;color:var(--ink-soft);margin:-8px 0 20px;max-width:56ch}

/* Decorative numeral. `aria-hidden` in the markup: it is texture, not content.
   🔴 IT SITS BEHIND/BESIDE TEXT, so its contrast cost is NOT calculable from hex: `--amber-line`
   over a gradient is a different pixel at every x. Measured against rendered PIXELS by
   _qc/nf-check.mjs at all six widths. If it ever fails there the fix is a local backing chip or
   moving the numeral, NOT a scrim over the band, which would flatten the gradient the whole
   design language uses.
   MOBILE (default): a narrow column has no room beside the copy, so it bleeds out of the
   bottom-right corner behind the CTA row (those are opaque buttons) at low opacity. */
.nf-num{position:absolute;z-index:0;right:-18px;bottom:-32px;
  font-family:var(--font-d);font-weight:800;font-size:clamp(140px,32vw,240px);line-height:.78;
  letter-spacing:-.05em;color:var(--amber-line);opacity:.34;pointer-events:none;user-select:none}

/* DESKTOP: two real grid tracks, so copy and numeral CANNOT overlap by construction. Hand-tuning
   an absolute offset until it "looks clear" is a value that survives exactly until the next
   breakpoint; a track that cannot collide needs no tuning. */
@media(min-width:901px){
  .nf-hero .wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:clamp(24px,4vw,64px)}
  .nf-num{position:static;justify-self:end;opacity:.6;font-size:clamp(150px,17vw,300px);
    /* a light optical bleed past the gutter so it reads as part of the band, not a boxed graphic */
    margin-right:calc(var(--gut) * -0.45)}
}
/* `.vprop` is a static trust card on the homepage; on /404 the same card is a route, so it needs
   an interactive affordance. Scoped to the anchor so the homepage cards are untouched. */
a.vprop{transition:border-color .18s var(--ease),box-shadow .18s var(--ease)}
a.vprop:hover{border-color:var(--amber);box-shadow:var(--shadow-card)}

/* --- customer account templates. The concept only mocked account.html. --- */
.acct{display:block}
.acct label{display:block;margin:14px 0 6px;font-weight:600;font-size:13.5px;color:var(--ink-soft)}
/* 48px @ 16px: meets the 44px touch minimum and stops iOS zooming the field on focus. */
.acct input{width:100%;height:48px;padding:0 15px;font-size:16px;
  border:1px solid var(--line-2);border-radius:var(--radius);background:var(--paper);color:var(--ink)}
.acct .btn{margin-top:20px}
.acct-order,.acct-addr{display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center;
  padding:14px 16px;border:1px solid var(--line);border-radius:var(--radius);background:#fff;margin-bottom:10px}
.acct-order a{font-weight:700;color:var(--ink)}
.acct-order span{font-family:var(--font-l);font-size:13.5px;color:var(--muted)}

/* --- small bits the scaffold templates need --- */
/* KEPT 2026-07-28. The CART no longer uses this: it now renders the ported `aside.summary` +
   `.row.tot` (liquor.css:742-746), which is the oracle's structure and what `.cartwrap`'s
   1fr/360px grid expects. But `sections/main-customers-order.liquid` ALSO emits it for the order
   total, which I missed when deleting it, and the class-contract gate caught the regression on its
   very next run. 🔑 Before deleting a CSS rule, grep every consumer, not the one you are editing. */
.cart-tot{display:flex;justify-content:space-between;align-items:baseline;gap:16px;
  padding:16px 0;border-top:1px solid var(--line);margin-top:10px;font-family:var(--font-l);font-size:18px}
.ph-desc{color:var(--muted);max-width:68ch}
.ph-count{font-family:var(--font-l);font-size:13.5px;color:var(--muted)}
.art{margin-inline:auto}
.art-meta{font-family:var(--font-l);font-size:13.5px;color:var(--muted);margin:6px 0 18px}
.art-body{font-size:17px;line-height:1.7}
.pdp-desc{margin-top:22px;line-height:1.7;color:var(--ink-soft)}
.bc-ph{display:block;aspect-ratio:16/10;overflow:hidden;border-radius:var(--radius);background:var(--paper)}
.bc-ph img{width:100%;height:100%;object-fit:cover}
.ccard{display:block;background:#fff;border:1px solid var(--line);border-radius:var(--radius-lg);
  padding:14px;text-align:center;transition:.18s var(--ease)}
.ccard:hover{border-color:var(--amber);box-shadow:var(--shadow-card)}
/* S1: contained media - max-height must win, so no width/height attrs on the img and no
   aspect-ratio box growing to the intrinsic height. */
.cc-ph{display:grid;place-items:center;height:150px;background:var(--paper);border-radius:var(--radius);padding:10px}
.cc-ph img{max-width:100%;max-height:100%;width:auto;height:auto;object-fit:contain;mix-blend-mode:multiply}
.ccard .n{font-family:var(--font-l);font-size:13px;color:var(--muted)}

/* REMOVED 2026-07-28: `.pcard--sponsored` was a BEM name invented during the port. The concept's
   real contract is `.pcard.sponsored` + a `.sp-ribbon` child, fully styled in liquor.css:1285-1293
   (amber outline, ribbon, and the .tags/.wish top offsets the ribbon requires). The markup now
   emits the real class, so these two rules matched nothing.
   ⚠ Note for future class audits: this rule living HERE is why `grep pcard--sponsored
   assets/liquor.css` returned 0 and the card still had *some* styling. ALWAYS grep the
   stylesheets as a UNION (liquor.css + liquor-port.css + any inline block in theme.liquid). */

/* offer modal success line */
#offerPop .ok{color:var(--green);font-weight:600;margin-top:10px}

/* toast icon slot (the concept drew the glyph inline; the theme renders it from the icon set) */
.t-ico{display:inline-grid;place-items:center;width:18px;height:18px;flex:none}

/* ============================================================
   ACCESSIBILITY ADDITIONS, 2026-07-28
   ⛔ These live HERE, never in liquor.css. That file is a byte-identical port of the approved
   concept stylesheet and is the design contract; editing it breaks the only reliable way to tell
   a port defect from a design change. Additions go in this file, each with the reason.
   ============================================================ */

/* Mega nav was MOUSE-ONLY: liquor.css:191 has just `.has-mega:hover .mega`, so ~42 subcategory
   links across 7 panels were unreachable by keyboard: Tab jumped straight past the panel to the
   next top-level link. `:focus-within` opens it on the same terms as hover, using the identical
   three properties so the two paths cannot drift apart. */
.has-mega:focus-within .mega{opacity:1;visibility:visible;transform:none}

/* The footer accordion heading is now a real <button> inside the <h4> (it was an unfocusable
   `<h4 onclick>`). It must inherit the heading's own typography exactly: this is a semantics
   fix, not a visual change. */
.foot-col h4 .fc-toggle{all:unset;display:flex;align-items:center;justify-content:space-between;
  gap:10px;width:100%;cursor:pointer;font:inherit;color:inherit;letter-spacing:inherit;
  text-transform:inherit}
.foot-col h4 .fc-toggle:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:3px}
@media(min-width:768px){
  /* Above the accordion breakpoint the links are always visible, so the control is decorative.
     leave the cursor alone rather than implying it toggles something. */
  .foot-col h4 .fc-toggle{cursor:default}
}

/* The age gate's "Go back" recovery control (shown only after "No"). Matches .age-actions spacing
   so it does not look bolted on. */
#ageGate #ageBack{margin-top:14px}

/* `inert` is applied to closed off-canvas panels so they leave the tab order. Browsers without
   inert support fall back to aria-hidden; this hides them from pointer input too so the two
   paths agree. */
[inert]{pointer-events:none}

/* ------------------------------------------------------------
   STATES THE CONCEPT NEVER HAD, found by _qc/class-contract.mjs, 2026-07-28.
   Each of these was emitted by markup or toggled by JS with NO rule anywhere in the union, i.e.
   invisible feedback. Category B: surfaces Shopify forces that the concept did not model.
   ------------------------------------------------------------ */

/* SOLD OUT. The concept's catalogue has only three stock states (in / low / supplier, see
   store.js stockLabel), because nothing in it was ever out of stock. Shopify has real inventory,
   so `.stock.out` is a genuinely new state and had no rule: a sold-out product rendered the words
   "Sold out" in default body colour with no pip, i.e. looking identical to in-stock. */
.stock.out{color:var(--wine)}
.stock.out::before{background:var(--wine)}

/* ADD-TO-CART BUTTON FEEDBACK. theme.js toggles `is-loading` then `is-added` on the button
   (S4 handler), and neither existed in any stylesheet, so the entire loading and success
   feedback was invisible. This is the same failure shape as the offer modal's `.show`/`.open`:
   the class is applied, nothing renders, nothing errors.
   Reduced motion is respected: the spinner is the only animation and it is dropped, not slowed. */
.btn.is-loading{position:relative;color:transparent!important;pointer-events:none}
.btn.is-loading::after{content:"";position:absolute;top:50%;left:50%;width:16px;height:16px;
  margin:-8px 0 0 -8px;border:2px solid currentColor;border-top-color:transparent;border-radius:50%;
  color:var(--ink-on-amber);animation:lq-spin .7s linear infinite}
@keyframes lq-spin{to{transform:rotate(360deg)}}
.btn.is-added{background:var(--green);border-color:var(--green);color:#fff}
@media(prefers-reduced-motion:reduce){
  .btn.is-loading::after{animation:none;border-top-color:currentColor;opacity:.6}
}

/* NEWSLETTER RESULT MESSAGES. The concept faked the signup with a toast, so it never had a
   success or error line; the theme posts to a real Shopify customer form and rendered both
   completely unstyled. `role="status"` / `role="alert"` are already on them in the markup. */
.nl-ok{color:var(--green);font-weight:600;margin-top:10px;font-size:14px}
.nl-err{color:var(--wine);font-weight:600;margin-top:10px;font-size:14px}

/* QUANTITY INPUT inside the ported `.qty` stepper.
   The concept's stepper holds a `<span>` (liquor.css:330, min-width:30px). Shopify's no-JS cart
   needs a real `<input name="updates[]">`, and an unstyled `input[type=number]` defaults to about
   20 characters, measured 189px. Inside `.cart-line`'s `96px 1fr auto` grid that inflated the
   min-content width of the 1fr track to 251px, blowing the whole line to 444px in a 390px
   viewport (documentElement.scrollWidth 460). The row is the ported design; the input is ours,
   so the input is what gets constrained, matching the span it replaced.
   ⚠ 16px font is deliberate: below it iOS zooms the viewport on focus. */
.qty input[type="number"]{width:44px;min-width:0;text-align:center;font-family:var(--font-l);
  font-size:16px;border:0;background:transparent;color:var(--ink);padding:0;height:30px;
  -moz-appearance:textfield;appearance:textfield}
.qty input[type="number"]::-webkit-outer-spin-button,
.qty input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.qty input[type="number"]:focus-visible{outline:2px solid var(--amber);outline-offset:1px;border-radius:4px}
/* The 1fr track must be allowed to shrink below its min-content width, or any future wide child
   repeats this bug. This is the grid min-width:auto trap. */
.cart-line > *{min-width:0}

/* ── WAVE 4b: PLP FILTER PRICE RANGE ────────────────────────────────────────────────────────
   A surface the PLATFORM forces that the concept never had (S10 justification (b)).
   The concept's price control is ONE max slider over a client-side catalogue; Shopify's
   price_range filter is a min/max PAIR, and a single-ended port would either misreport the
   range or silently drop the min. So the pair is ours and gets styled here: `.range-vals`
   itself stays the ported class, holding what the oracle put there.

   🔴 SAME TRAP AS THE CART, CAUGHT BEFORE IT SHIPPED THIS TIME: an unstyled
   `input[type=number]` renders ~189px wide (about 20 characters). TWO of them inside a 260px
   filter rail overflow it immediately. The rail is the ported design, the inputs are ours, so
   the inputs are what get constrained. Width is explicit, and the flex children may shrink. */
.range-vals{display:flex;align-items:center;gap:8px}
.range-vals > *{min-width:0}
.range-vals label{display:flex;align-items:center;gap:3px;flex:1 1 0;
  font-family:var(--font-l);font-size:13px;color:var(--muted);
  border:1px solid var(--line);border-radius:8px;padding:6px 8px;background:#fff}
.range-vals input[type="number"]{width:100%;min-width:0;border:0;background:transparent;
  font-family:var(--font-l);font-size:16px;color:var(--ink);padding:0;
  -moz-appearance:textfield;appearance:textfield}
.range-vals input[type="number"]::-webkit-outer-spin-button,
.range-vals input[type="number"]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.range-vals label:focus-within{border-color:var(--amber);box-shadow:0 0 0 2px rgba(253,163,25,.25)}

/* ── WAVES 4e-4h: CONTENT PAGES ─────────────────────────────────────────────────────────────
   S10 justification (a) again: each of these replaces an INLINE style the concept writes from
   JavaScript, or a surface the platform shapes differently. Values are the concept's own where
   it had one; where it had none (it built the element in JS with no styling at all) the rule is
   minimal and uses existing design tokens rather than introducing new visual language.

   ⚠ `.ctk-copy`, `.case-pick` and `.vp` are the ORACLE's own class names with NO rule in the
   ported stylesheet, verified against the concept's markup. They are allow-listed in
   class-contract.mjs as parity rather than given invented rules here. */

/* brands A-Z. THE DIRECTORY'S OWN CSS IS NOT HERE ANY MORE: the concept's brand-directory
   block (.bd-tools .bd-count .bd-filter .bd-az .bd-group .bd-letter .bd-grid .bd-card .bd-shot
   .bd-txt .bd-badge .bd-feat .bdf-* .bd-empty .bd-note, 30 rules) is ported verbatim into
   assets/liquor.css, where the rest of the design system lives.

   What used to sit here were five invented names, .brand-search .brand-grid .brand-card
   ".brand-card b" and .brand-none, written against a stylesheet that had never been given the
   concept's block. An audit of both theme stylesheets this round found ZERO .bd-* rules against
   16 .bd-* selectors in the concept, and all three of this page's remaining unstyled classes
   traced back to that. The five rules are DELETED, not softened: page-brands.liquid emits the
   concept's names now, and nothing else in the theme emits the old ones (grep of sections,
   snippets, templates, layout and theme.js: zero hits).

   ONE rule survives, and it is here because this theme FILTERS differently from the concept.
   It is not a design opinion. */

/* 1. The directory controller in sections/page-brands.liquid sets `card.hidden = true` on every
      non-matching card. The concept never needs an equivalent: brands.js rebuilds the whole list
      from the index on each keystroke, so no card is ever hidden in place. `.bd-card` declares
      display:grid, which outranks the UA sheet's `[hidden]{display:none}`, so without this the
      filters would run, recount correctly, and hide nothing at all.
      ⚠ The rule used to name theme.js's initBrandFilter(), which was removed on 2026-08-28 when
      the three filters were folded into one controller. The MECHANISM is unchanged: something
      still sets `hidden` on a display:grid element, so this rule is still load bearing. */
.bd-card[hidden]{display:none}

/* 2. DELETED 2026-08-28, ON ITS OWN STATED CONDITION.
      The rule was `.bd-card{grid-template-columns:1fr}`, collapsing the concept's `auto 1fr`
      (a 48px .bd-shot packshot, then .bd-txt) to one track, because the directory snapshot held
      no flagship image and a permanently empty second track would strand a gap at the right of
      every tile. Its own note set the exit condition: "IF A PACKSHOT IS EVER SEEDED INTO THE
      DIRECTORY: emit .bd-shot and DELETE this rule."

      That condition is now met. shop.metafields.custom.brand_shots carries a packshot for all
      234, MEASURED off this store's own products, and page-brands.liquid emits .bd-shot. With
      the override still in place the card rendered the packshot ABOVE the label instead of
      beside it: a real visual difference from the concept that the parity gate cannot see,
      because .bd-shot was present and every class name matched. 🔑 A CLASS NAME GATE ANSWERS
      "IS IT THERE", NEVER "IS IT IN THE RIGHT PLACE".

      Still not emitted, and this is unchanged: `.bd-badge` and `.bd-card--enh`, the "Partner"
      chip. On the concept it means the brand bought the enhanced page; this store sells no such
      placement, so the chip would be a commercial claim about 234 real companies that nobody has
      made. `.bd-txt`'s ported padding-right:38px is that badge's gutter and is LEFT ALONE. */

/* faq rail card (concept: faq.html inline styles) */
.faq-help{text-align:center}
.faq-help h3{margin-bottom:6px}
.faq-help p{color:var(--muted)}
/* <details>/<summary> replaces the concept's <h4 onclick>, so strip the native marker so the
   ported .faq-q chevron is the only affordance. */
.faq-item > summary{list-style:none;cursor:pointer}
.faq-item > summary::-webkit-details-marker{display:none}
.faq-item[open] > summary .ic{transform:rotate(45deg)}
.faq-a{padding:0 0 18px;color:var(--muted);max-width:70ch;max-height:none;overflow:visible}

/* vault pillars: the concept builds these in JS with no class of their own */
.vp{display:flex;flex-direction:column;gap:6px}
.vp-ic{color:var(--amber);display:block}
.vp-ic svg{width:22px;height:22px}
.vp b{font-family:var(--font-d);font-size:17px}
.vp span{color:var(--muted);font-size:14px}

/* wishlist (concept: wishlist.html inline styles) */
.wish-wrap{padding:32px 0}
.wish-empty{text-align:center;padding:60px 20px}
.wish-empty svg{width:40px;height:40px;color:var(--muted-2)}
.wish-empty h2{margin:16px 0 8px}
.wish-empty p{color:var(--muted);margin-bottom:20px}
.wish-empty[hidden]{display:none}
/* Loading state shown between the empty state and the fetched cards, same shape as .wish-empty
   above so it doesn't jump the layout when it swaps in/out. Reuses the @keyframes lq-spin ring
   already defined for .btn.is-loading further up this file. */
.wish-loading{text-align:center;padding:60px 20px}
.wish-loading[hidden]{display:none}
.wish-loading .spinner{display:inline-block;width:32px;height:32px;border:3px solid var(--line-2);
  border-top-color:var(--amber);border-radius:50%;animation:lq-spin .7s linear infinite}
.wish-loading p{color:var(--muted);margin-top:14px}
@media(prefers-reduced-motion:reduce){
  .wish-loading .spinner{animation:none;border-top-color:var(--amber);opacity:.6}
}

/* build-a-case */
.case-section{padding-top:clamp(20px,3vw,30px)}
/* 🔴 THE HIDDEN ATTRIBUTE DOES NOT HIDE A FLEX CARD. liquor.css:900 sets
   .case-card{display:flex}, which beats the user agent's [hidden]{display:none} on specificity,
   so every one of the 144 cards the chips filter over rendered at once. MEASURED, not reasoned:
   parity-check read case-card 48 -> 144 on the first push of cluster 2 and that count is the
   only thing that said so, because every class name was present and correct. Same rule
   .wish-empty[hidden] already needed six lines up. */
.case-card[hidden]{display:none}
/* THIRD TIME ON THIS PAGE, so it is written down at the point of use rather than remembered:
   liquor.css:1341 sets .cp-cross .xrow{display:flex}, so the cross-sell's candidate rows need
   the same guard the cards above needed. .cp-cross itself is a plain block and the UA rule would
   hide it, but it is listed here too: a future edit that gives the wrapper a display value would
   otherwise re-open the identical hole silently, and one selector costs nothing. */
.cp-cross[hidden],
.cp-cross .xrow[hidden]{display:none}
.cp-offer{font-size:12.5px;color:var(--muted);line-height:1.5;margin-top:8px}
/* DELETED 2026-08-28 with cluster 2: five rules for a line item this theme no longer builds.
   They styled a .cp-line holding .cp-nm and a .rm text button, the shape theme.js emitted while
   the oracle's line item was unported. The panel now emits the oracle's own .ph / .cp-info
   (.nm, .pr) / .cp-q, which liquor.css:947-956 already styles.
   THIS FILE LOADS AFTER liquor.css (layout/theme.liquid:32-33), so leaving the first rule here
   would have kept .cp-line{display:flex} winning over the oracle's
   .cp-line{display:grid;grid-template-columns:42px 1fr auto}: the thumbnail would have had no
   column, and every class name would still have been present, so parity-check would have
   reported PARITY on it. That is the .bd-card{grid-template-columns:1fr} trap from cluster 3,
   in the same file, one round later. */

/* ── WAVE 4e: CART ──────────────────────────────────────────────────────────────────────────
   S10 justification (a) throughout: the concept builds the cart with innerHTML and styles all
   of this with INLINE style="" attributes written in JavaScript (cart.html:67-90). Inline
   styles generated by a JS template do not port to server-rendered Liquid, so each becomes a
   class here. Every value below is the concept's own, transcribed unchanged, nothing is
   redesigned on the way across.

   ⚠ `.rm` already exists but ONLY scoped to `.mini-line` (liquor.css). On the cart page the
   concept relied entirely on its inline style, so an unscoped rule is required, and is kept
   scoped to `.cart-line` rather than made global, because a bare `.rm` in a shared stylesheet
   is exactly the "generic name is a live grenade" trap S10 warns about. */
.cart-line .ln-meta{font-size:12.5px;color:var(--muted);margin:4px 0}
.cart-line .ln-meta .on-sale{color:var(--wine);font-weight:600}
.cart-line .ln-pr .ln-was{font-size:12px;color:var(--muted);text-decoration:line-through;font-weight:400}
.cart-line .rm{background:none;border:0;padding:0;cursor:pointer;color:var(--muted-2);
  font-size:13px;margin-left:12px;text-decoration:underline}
.cart-line .rm:hover{color:var(--wine)}
.cart-line .rm:focus-visible{outline:2px solid var(--amber);outline-offset:2px;border-radius:4px}

.cart-actions{margin-top:18px;display:flex;gap:10px;flex-wrap:wrap}

.summary .save-amt{color:var(--wine)}
.summary .disc-amt{color:var(--green)}
.summary .pf-line{font-size:12.5px;color:var(--bnpl);text-align:center;margin:8px 0;font-weight:600}
/* PROMO FEEDBACK: the error state must NOT borrow the price accent.
   `--wine` (#A92F26) is documented in liquor.css as the "price / save accent": it is the colour a
   shopper learns means MONEY OFF. Reusing it for a rejected code makes the failure read, for a
   beat, as a saving: the one wrong meaning available. `--wine-deep` (#7E211B) is the error tone
   already adopted for form errors elsewhere in this theme, and clears AA comfortably on the
   summary's white surface. Success keeps `--green`, matching `.nl-ok` and `#offerPop .ok`.
   Colour is never the only carrier: the message states the outcome in words, and a pip echoes
   the `.stock.out` state-marker pattern this theme already uses. */
.summary #promoMsg{font-size:12.5px;margin-bottom:6px;line-height:1.45}
.summary #promoMsg:empty{display:none}
.summary #promoMsg.ok,
.summary #promoMsg.err{display:flex;gap:6px;align-items:baseline;font-weight:600}
.summary #promoMsg.ok::before,
.summary #promoMsg.err::before{content:"";flex:0 0 auto;width:6px;height:6px;border-radius:50%;
  transform:translateY(-1px)}
.summary #promoMsg.ok{color:var(--green)}
.summary #promoMsg.ok::before{background:var(--green)}
.summary #promoMsg.err{color:var(--wine-deep)}
.summary #promoMsg.err::before{background:var(--wine-deep)}
.summary .btn-block{margin-top:14px}

.paybadges{display:flex;gap:6px;justify-content:center;margin-top:14px;flex-wrap:wrap}
.paybadges span{font-family:var(--font-l);font-size:10px;border:1px solid var(--line-2);
  border-radius:4px;padding:4px 8px;color:var(--muted);text-transform:uppercase}

/* Empty cart. The concept inlines this block too (cart.html:45-47). */
.cart-empty{text-align:center;padding:70px 20px}
.cart-empty svg{width:40px;height:40px;color:var(--muted-2)}
.cart-empty h2{margin:16px 0 8px}
.cart-empty p{color:var(--muted);margin-bottom:20px}

/* Empty Build-a-Case grid. Same form as .wish-empty and .cart-empty above: this is the third
   empty state in the theme and it borrows theirs rather than inventing a look. It spans the grid
   so the message centres in the panel instead of sitting in column 1. */
.case-empty{grid-column:1/-1;text-align:center;padding:70px 20px;color:var(--muted);margin:0}
.case-empty a{color:var(--ink);text-decoration:underline}

/* ── WAVE 4d: PDP AVAILABILITY PILL ─────────────────────────────────────────────────────────
   S10 justification (a): CSS the concept ships from JAVASCRIPT. The concept writes the colour
   as an inline style built in the page script:
       availMap = { in:['In stock, ships today','var(--green)'],
                    low:['Low stock, order soon','#cf9a25'],
                    supplier:['In stock with supplier, 2-4 days','var(--muted)'] }
       <div class="pdp-avail" style="color:${av[1]}">
   An inline style generated by a JS template does not port to server-rendered Liquid, so the
   states become classes and the colours move here. Values are the concept's own, unchanged.

   🔴 FOUND BY GREPPING, NOT BY THE GATE. `class="pdp-avail is-{{ avail_state }}"` leaves the
   dangling prefix `is-`, which class-contract.mjs deliberately skips (it cannot know the
   runtime value), so all four states were unstyled while the gate reported PASS. The gate now
   prints dynamic prefixes as a NOTE so they get looked at instead of silently skipped. */
.pdp-avail.is-in{color:var(--green)}
.pdp-avail.is-low{color:#cf9a25}
.pdp-avail.is-supplier{color:var(--muted)}
.pdp-avail.is-out{color:var(--wine)}

/* A filter option with no matches is kept visible only when it is already ticked (so the
   shopper can untick it). Disabled options must READ as disabled, not merely fail to respond.
   an unstyled disabled checkbox looks identical to a live one. */
.acc-opt input:disabled ~ .acc-lab,
.acc-opt input:disabled ~ .c{opacity:.45}
.acc-opt:has(input:disabled){cursor:not-allowed}

/* Keyboard focus on the rail. The concept's accordion is mouse-first; every control here is
   reachable by Tab, so it must be visible when focused. */
.acc-head:focus-visible,
.acc-opt input:focus-visible,
.sortsel:focus-visible{outline:2px solid var(--amber);outline-offset:2px;border-radius:6px}

/* ============================================================
   ON-DEMAND BADGE: two deliberate deviations from the concept (2026-07-29)
   The badge itself is ported byte-identically in liquor.css; these override only the two
   behaviours that were wrong ONCE THE ELEMENT ACTUALLY EXISTED ON THE PAGE. Both follow the
   precedent already set for this element's own twin, spine S9.

   ⚠ RESTATE-THE-WHOLE-SET DISCIPLINE (CSS bug class #22): the 900px rule below restates EVERY
   property the 560px rule sets (padding, width, height, justify-content, border-radius, gap)
   not just the ones that change. A partial sizing set is how an element ends up half-collapsed.
   ============================================================ */

/* 1. COLLAPSE AT 900px, NOT 560px.
   liquor.css's own banner calls this badge the "mirror twin of #chatFab", and #chatFab collapses
   at 900px in this theme, moved there on the pilot because a wide pill covered products at 768px
   (Allen caught it). Inheriting 560px here would leave, between 561px and 900px, a circle on the
   right and a ~200px pill on the LEFT sitting over the product grid: the same S9 defect mirrored,
   and a "twin" that stops being a twin at exactly the widths where it matters.
   Re-check 768px before changing this back. */
@media(max-width:900px){
  .od-badge{padding:0;width:52px;height:52px;justify-content:center;border-radius:50%;gap:0}
  .od-txt{display:none}
}

/* 2. LIFT ABOVE THE MOBILE PDP STICKY BAR.
   liquor.css has `body.pdp-bar-on #chatFab{bottom:calc(80px + safe-area)}` but no rule for this
   badge, because in the concept this badge did not exist as a real element to collide with
   anything. The PDP sticky bar is a FULL-WIDTH opaque bar at <=760px, so without this the badge
   is not merely overlapped: it is completely buried, and a control the user cannot see reads as
   a component that was never built. Same offset and the same safe-area allowance as the twin, so
   the two floating affordances continue to rise together. */
@media(max-width:760px){
  body.pdp-bar-on .od-badge{bottom:calc(80px + env(safe-area-inset-bottom,0px))}
}
/* liquor.css transitions only background+transform, so the lift above would SNAP while the twin
   (`transition:...bottom .28s ease`) glides. Same easing, so they move as one system.

   🔴 WRAPPED IN no-preference DELIBERATELY. DO NOT UNWRAP IT.
   liquor.css already carries `@media(prefers-reduced-motion:reduce){.od-badge{transition:none}}`,
   but liquor-port.css loads AFTER liquor.css (layout/theme.liquid:32-33) and a bare
   `.od-badge{transition:...}` here has EQUAL specificity, so it would win on source order and
   silently RE-ENABLE motion for users who asked for less. That is the source-order override bug
   this build has already been bitten by, arriving as an accessibility regression instead of a
   layout one. Scoping to no-preference makes the two rules mutually exclusive, so neither can
   depend on which file loads last. */
@media(prefers-reduced-motion:no-preference){
  .od-badge{transition:background .2s ease, transform .2s ease, bottom .28s ease}
}

/* ─────────────────────────────────────────────────────────────────────────────
   SHOPIFY FORM FEEDBACK: .form-errors and .mf-done
   ─────────────────────────────────────────────────────────────────────────────
   These two classes have NO counterpart in liquor.css, and that is correct rather
   than an omission: the concept's contact and partner forms were MOCKS. They
   called a handler that did not exist and revealed a hardcoded "✓ Thanks!", so
   the concept never had an error state to style: a form that cannot fail needs
   no failure styling. Porting the forms to native {% form 'contact' %} created a
   real error path for the first time, so these rules are NEW, not ported.

   🔴 They were caught by class-contract as INVENTED CLASSES (spine S10): the two
   sections emitted .form-errors and .mf-done while carrying their whole visual as
   inline style attributes. An unstyled class name that only looks styled because
   of an inline attribute is exactly the shape that gate exists to catch, and the
   fix is to make the class real, not to delete it and keep the inline styles.

   COLOUR: --wine-deep is the palette's darkest red (9.9:1 on --paper/white).
   The inline attribute said `var(--red,#B3261E)`, and --red is defined NOWHERE in
   this theme, so every one of those rules was silently falling back to #B3261E,
   a Material red that belongs to no part of this brand. --wine is the palette's
   red, and --wine-deep is its error-weight sibling; using --wine itself would read
   as the price/save accent it is used for everywhere else on the page.

   These are new names, so they cannot collide with a liquor.css rule on source
   order, so the hazard documented for .od-badge above does not apply here. */
.form-errors{
  color:var(--wine-deep);
  margin-bottom:12px;
  font-weight:600;
}
.form-errors ul{margin:0;padding-left:18px}

.mf-done{
  color:var(--green);
  margin-bottom:12px;
  font-weight:600;
}

/* ============================================================
   HEINEKEN HOMEPAGE BAND, PORTED VERBATIM 2026-08-27 from the concept's
   css/liquor.css lines 1130-1222. Allen: the concept moved to this band and the theme
   was never re-synced, so the dev store still showed the delivery band it replaced.
   The concept is the oracle: these bytes are copied, not rewritten.
   Brand reads through the lockup, the Featured-Partner flag, and the brand strip below.

   FIXED 2026-08-28: ONE LINE OF THIS COMMENT USED TO SIT OUTSIDE IT, AND THE RULE BELOW WAS
   DEAD BECAUSE OF IT. The block closed at the ==== line, then a stray sentence and a SECOND
   comment CLOSE followed, so the parser read the sentence plus that close plus `.hk-hero--life
   .hk-visual` as ONE selector and dropped `{display:none}` with it. Present since the band
   was ported on 2026-08-27; found by counting comment opens against closes in this file,
   66 against 67, while deleting an unrelated rule.
   A CSS FILE WITH MORE CLOSES THAN OPENS HAS A DEAD RULE IN IT, and nothing renders an
   error. The `@media` block two lines down was unaffected, which is why the page still
   looked plausible: at-rule error recovery is not declaration error recovery.
   ============================================================ */
.hk-hero--life .hk-visual{display:none}
@media(max-width:900px){
  .hk-hero--life .hk-in{min-height:auto}
}

/* ============================================================
   HEINEKEN HOMEPAGE BAND (.hk-band): full-bleed always-on placement
   Replaces the "How it works / From cart to doorstep" delivery band (Allen, 2026-08-15).
   Third variant of the takeover family, after .plp-tk (category band) and .hk-hero
   (landing hero). Composed to the LOCKED language: shared unbranded backdrop, veil,
   giant watermark bottom-left, AD kicker pinned top-right, amber brand lockup left,
   text-link CTA with a cart icon (⛔ never a solid amber pill, explicitly rejected),
   real packshot on an amber glow, ad-legal underneath.

   Why the SHARED backdrop and not the rooftop photo used on heineken.html:
     1. `.hk-hero--life` already established that a composited 6-pack collides with the
        people in that photo: an ad band with no product in it is a weak ad, so the
        shared unbranded backdrop is the one that lets the pack stay.
     2. The homepage already carries the .jw-ad brand takeover; that one is a CONTAINED
        rounded card and this one is FULL-BLEED, which is what separates them structurally.
   ============================================================ */
.hk-band{position:relative;overflow:hidden;isolation:isolate;background:#120c06;color:var(--cream)}
.hk-band .tk-bg{position:absolute;inset:0;z-index:0;width:100%;height:100%;object-fit:cover;
  object-position:50% 42%;opacity:.9}
/* Left-anchored scrim. Load-bearing: the lockup sits over photography and this is the
   only thing guaranteeing its contrast floor. */
.hk-band::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,rgba(10,7,3,.95) 0%,rgba(10,7,3,.8) 38%,rgba(10,7,3,.38) 66%,rgba(10,7,3,.14) 100%)}
/* .wrap is the positioning context for BOTH the watermark and the kicker, see the note in
   index.html. Without this they resolve against the full-bleed band and drift away from the
   lockup on wide screens. */
.hk-band .wrap{position:relative;z-index:2}
/* ⛔ NO giant wordmark on this variant. The takeover family puts one bottom-left, but that
   corner is where THIS unit's facts row, CTA and legal line live, and at any vertical offset the
   wordmark ran straight through them and read as a rendering fault, not as texture (Allen,
   2026-08-15). Precedent for dropping it per-variant: .hk-hero--life does the same.
   Brand attribution here is the amber lockup, the pack and the AD kicker. */
.hk-band .hkb-mark{display:none}
.hk-band .hkb-kicker{position:absolute;z-index:3;top:clamp(12px,1.4vw,20px);right:0;
  display:inline-flex;align-items:center;gap:10px;white-space:nowrap}
.hk-band .tk-sponsor{font-family:var(--font-l);text-transform:uppercase;letter-spacing:.16em;
  font-size:11px;color:rgba(255,248,236,.6);white-space:nowrap}
/* minmax on the visual column stops the pack collapsing to its intrinsic width and leaving a
   dead trench down the middle of the band; the copy is sized so "Great company. Great beer."
   runs ACROSS on one line from 1440 up, which is what closes the gap from the other side. */
.hkb-in{display:grid;grid-template-columns:minmax(0,1fr) minmax(200px,330px);gap:clamp(20px,3vw,44px);
  align-items:center;min-height:clamp(300px,29vw,400px);padding-block:clamp(28px,3.4vw,44px)}
.hkb-copy{min-width:0;max-width:min(100%,700px)}
.hkb-brand{display:block;font-family:var(--font-d);font-weight:800;color:var(--amber);
  font-size:clamp(22px,2.4vw,32px);letter-spacing:-.01em;line-height:1;margin-bottom:8px}
.hkb-copy h2{color:#fff;font-size:clamp(28px,3.8vw,50px);font-weight:800;letter-spacing:-.03em;
  line-height:1;margin:0;padding-bottom:.04em;text-wrap:balance}
.hkb-copy p{color:rgba(255,248,236,.84);font-size:clamp(14px,1.5vw,16.5px);line-height:1.5;
  margin:14px 0 0;max-width:50ch}
.hkb-copy p b{color:var(--cream);font-weight:600}
/* Real pack facts, not a claim: three brands, two pack sizes. Keeps the band selling
   the RANGE without inventing a price, a discount or a stat. */
.hkb-facts{display:flex;gap:clamp(18px,2.6vw,34px);margin-top:20px;flex-wrap:wrap}
.hkb-facts b{display:block;font-family:var(--font-d);font-weight:800;font-size:clamp(17px,1.9vw,22px);color:#fff;line-height:1.1}
.hkb-facts span{font-family:var(--font-l);text-transform:uppercase;letter-spacing:.1em;font-size:10.5px;
  color:var(--amber)}
.hkb-cta{display:inline-flex;align-items:center;gap:9px;white-space:nowrap;margin-top:24px;
  font-family:var(--font-l);font-weight:700;font-size:15px;letter-spacing:.01em;
  color:var(--amber);text-decoration:none;padding:4px 2px 6px;
  border-bottom:1.5px solid rgba(244,214,154,.45);
  transition:color .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease)}
.hkb-cta .hkb-cta-ic{display:inline-flex}
.hkb-cta .hkb-cta-ic svg{width:17px;height:17px}
.hkb-cta:hover{color:#fff;border-bottom-color:var(--amber);transform:translateX(2px)}
.hkb-cta:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:3px}
.hkb-visual{position:relative;z-index:2;display:grid;place-items:center;min-width:160px}
.hkb-visual::before{content:"";position:absolute;width:118%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(253,163,25,.32),transparent 66%);filter:blur(9px)}
.hkb-visual img{position:relative;max-height:clamp(190px,23vw,318px);width:auto;height:auto;max-width:100%;
  filter:drop-shadow(0 24px 34px rgba(0,0,0,.65))}
.hk-band .ad-legal{position:relative;z-index:2;border-top-color:rgba(255,248,236,.16);padding-inline:0}
@media(prefers-reduced-motion:reduce){.hkb-cta{transition:none}}
@media(max-width:900px){
  /* Single column, pack ABOVE the copy: it is the product being advertised, so unlike
     .hk-hero (a landing page whose product grid is right below) it does not get hidden. */
  .hkb-in{grid-template-columns:1fr;gap:20px;min-height:0;padding-top:52px;text-align:center}
  .hkb-copy{max-width:none;margin-inline:auto}
  .hkb-copy p{margin-inline:auto}
  .hkb-visual{order:-1}
  .hkb-visual img{max-height:170px}
  .hkb-facts{justify-content:center}
  .hkb-cta{margin-inline:auto}
  .hk-band::after{background:linear-gradient(rgba(10,7,3,.86),rgba(10,7,3,.92))}
  .hk-band .hkb-kicker{top:14px;right:auto;left:50%;transform:translateX(-50%)}
  /* flex-start, not center: centring wrapped the 18+ roundel onto its own line above the text */
  .hk-band .ad-legal{justify-content:flex-start;text-align:left}
}

.hkb-cta--label{border-bottom:0;padding-bottom:2px;cursor:default}
.hkb-cta--label:hover{color:var(--amber);transform:none}
.hkb-links{display:flex;flex-wrap:wrap;gap:10px 24px;margin:12px 0 0;padding:0;list-style:none}
.hkb-link{display:inline-flex;align-items:center;gap:7px;white-space:nowrap;
  font-family:var(--font-l);font-weight:600;font-size:14px;letter-spacing:.01em;
  color:var(--cream);text-decoration:none;padding:3px 2px 5px;
  border-bottom:1.5px solid rgba(244,214,154,.45);
  transition:color .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease)}
.hkb-link:hover{color:var(--amber);border-bottom-color:var(--amber);transform:translateX(2px)}
.hkb-link:focus-visible{outline:2px solid var(--amber);outline-offset:3px;border-radius:3px}
@media(prefers-reduced-motion:reduce){.hkb-link{transition:none}}
@media(max-width:900px){.hkb-links{justify-content:center}}

/* ===== JOURNAL SPONSORSHIP (cluster 4) =====
   Ported 1:1 from the oracle (css/liquor.css:2985-3034). The theme’s copy of liquor.css
   predates this unit, which is why these rules are here and not there, the same way
   .pdp-brandlink is. The oracle’s own note about the CTA colour is kept: it records a real
   contrast defect elsewhere in the house style and the reason this link does not repeat it. */
   and the probe MEASURES it on painted pixels at 1440 and 390.
   🔴 AND THE CTA IS NOT --amber-deep. #E07C00 on #FFF4DE is 2.73:1. The house
   .bp-pres-cta pairs exactly those two and is a real contrast defect on brand pages
   (found by looking, not by a gate; reported, not silently changed here). This link
   is --ink with an amber rule under it, and its hover swaps the RULE, not the ink. */
.jad{background:var(--amber-soft);border:1px solid var(--amber-line);
  border-left:4px solid var(--amber);border-radius:var(--radius-lg);
  padding:clamp(16px,2.2vw,22px) clamp(16px,2.4vw,26px) 4px;
  margin:clamp(18px,2.6vw,28px) 0}
/* Three zones, and the middle one is the point of the unit: who is advertising, what an
   advertiser does and does not buy, and the bottle. The hairline between zone 1 and
   zone 2 is the firewall, drawn. */
.jad-in{display:grid;grid-template-columns:minmax(0,auto) minmax(0,1fr) auto;
  grid-template-areas:"copy fire pack";
  gap:16px clamp(18px,2.6vw,34px);align-items:center}
/* Named areas, not auto-placement: the packshot has to stay beside the lockup when the
   firewall line drops to its own row, and auto-placement pushes it to a third row. */
.jad-copy{grid-area:copy;display:flex;flex-direction:column;align-items:flex-start;
  gap:11px;min-inline-size:0}
/* A compact label may shrink but must never wrap to a second line. */
.jad-copy>.ad-flag{white-space:nowrap;color:var(--ink)}
/* NEVER nowrap the wordmark: a brand name is unpredictable content, and nowrap on
   unpredictable content is how a 390px screen gets a horizontal scrollbar. */
.jad-brand{font-family:var(--font-l);text-transform:uppercase;letter-spacing:.07em;
  font-weight:600;font-size:clamp(21px,2.6vw,30px);line-height:1.1;color:var(--ink);
  min-inline-size:0;overflow-wrap:anywhere}
.jad-cta{font-family:var(--font-l);text-transform:uppercase;letter-spacing:.1em;
  font-size:12px;font-weight:600;color:var(--ink);
  border-bottom:2px solid var(--amber);padding-bottom:2px;
  transition:border-color .18s var(--ease)}
.jad-cta:hover{border-bottom-color:var(--ink)}
.jad-pack{grid-area:pack;width:clamp(96px,11vw,152px);display:grid;place-items:center}
/* Packshots are white-background jpgs: on a light ground they need multiply, which is
   this site's established treatment for them (.bp-head-shot, .bd-shot, .cc-media). A bare
   white rectangle on the amber ground reads as a broken asset; the first render was one. */
.jad-pack img{max-width:100%;height:auto;max-height:148px;object-fit:contain;display:block;
  mix-blend-mode:multiply}
.jad-firewall{grid-area:fire;margin:0;font-size:12.5px;line-height:1.55;color:var(--ink-soft);
  max-width:62ch;min-inline-size:0;
  border-left:1px solid var(--amber-line);padding-left:clamp(16px,2vw,26px)}
/* .ad-legal is built for a card interior (22px side padding, --line rule). Inside this
   panel it sits on the panel's own padding and takes the panel's hairline. */
.jad .ad-legal{padding-inline:0;border-top-color:var(--amber-line);margin-top:14px}
/* The rule is a divider between two columns. The moment they stack it is a rule under
   nothing, so it goes: this is a layout change, not a decoration that survives it. */
@media(max-width:900px){
  .jad-in{grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"copy pack" "fire fire"}
  .jad-firewall{max-width:74ch;border-left:0;padding-left:0}
}
@media(max-width:560px){
  .jad-in{grid-template-columns:1fr;grid-template-areas:"copy" "pack" "fire"}
  .jad-pack{width:118px;justify-self:start}
}

.content .shopify-policy__container{max-width:none;margin:0;padding:0}
.content .shopify-policy__title{display:none}
.content:has(.shopify-policy__container),.content.lq-doc{margin-inline:0}
:is(.shopify-policy__body,.lq-doc) p:empty{display:none}
:is(.shopify-policy__body,.lq-doc) ul{margin:0 0 16px;padding-left:0}
:is(.shopify-policy__body,.lq-doc) ul > li{position:relative;padding-left:26px;margin-bottom:8px}
:is(.shopify-policy__body,.lq-doc) ul > li::before{content:"";position:absolute;left:0;top:9px;width:12px;height:3px;background:var(--amber);border-radius:2px}
:is(.shopify-policy__body,.lq-doc) ol{margin:0 0 16px;padding-left:1.5em}
:is(.shopify-policy__body,.lq-doc) ol > li{margin-bottom:8px;padding-left:4px}
:is(.shopify-policy__body,.lq-doc) :is(ul,ol) :is(ul,ol){margin:8px 0 0}
.lq-doc .lq-sub{padding-left:1.75em}
.lq-doc .spec-table{margin:0 0 32px}
.lq-doc .spec-table td{vertical-align:top;padding-right:16px}
.lq-doc .spec-table ul{margin:0}
.lq-doc .spec-table li:last-child{margin-bottom:0}

/* ==== BEGIN r15-gifting ==== */
/* THE GIFTING BAND'S AD CHIP NEEDS ITS OWN GROUND, and it is the only .ad-flag.light on the
   site that does. MEASURED on the served page 2026-08-29, 1440 wide: the label read 2.10:1
   against the photograph on its local mean and 1.42:1 at its worst column. The floor is 4.5:1
   and this is a legally required disclosure, so it was the one thing on the page that had to
   change rather than be ported as found.

   WHY IT HAPPENS HERE AND NOWHERE ELSE. `.dband .veil` is DIRECTIONAL:
   linear-gradient(95deg, rgba(20,15,8,.9), rgba(20,15,8,.5) 62%, transparent). It darkens the
   copy column and releases to the bare photograph on the right. `.hero-adflag` is parked
   top:16px right:20px, which is the released end of that ramp. Every other .ad-flag.light in
   this build sits on a controlled dark ground it inherits from its band (the co-brand gradient,
   the takeover scrim, the hk-band plate). This one had none. Craft-traps #110 exactly: a scrim
   anchored to the band is tuned to the headline, and the small type outside it sits in the
   released ramp.

   ⛔ THE BAND'S ART DIRECTION IS NOT TOUCHED. Extending the veil to cover the corner would
   darken the photograph's subject, which is on the right. The label gets a ground; the picture
   keeps its own.

   ⛔ THE INK IS NOT RESTATED. `.ad-flag.light` still declares its own colour, so a planted
   defect aimed at the component still propagates here (craft-traps #179: re-typing the literal
   in the surface rule kills the plant while looking identical).

   THE ALPHA IS DERIVED, NOT PICKED. The band image is a merchant asset, so the ground behind
   this corner is unknown by design. rgba(20,15,8,.78) under the component's own
   rgba(255,248,236,.72) clears 4.5:1 against a PURE WHITE plate, which is the worst ground any
   photograph can present. Against the current image it measures well above that. A value tuned
   to today's photograph would be a claim about tomorrow's.

   No new colour token: rgba(20,15,8) is the veil's own ink. Longhand padding only, because
   this element already carries the .ad-flag rule (craft-traps #183). */
.dband .hero-adflag{background:rgba(20,15,8,.78);border-radius:6px;
  padding-block:5px;padding-inline:6px 10px}
/* ==== END r15-gifting ==== */
