.commerce-page [hidden] { display: none !important; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
/* The Bag control is laid out in storefront-mobile.css. The second copy of the
   count's circle that used to live here out-specified that file, which is what
   broke the badge on every commerce surface — see the note there. */
.catalog-bag { color: var(--ivory) !important; white-space: nowrap; }
.commerce-main { max-width: 1580px; margin: 0 auto; padding: clamp(3rem, 6vw, 6rem) max(5vw, 1.25rem) clamp(5rem, 8vw, 8rem); }
.commerce-intro { max-width: 800px; margin-bottom: clamp(2.5rem, 5vw, 5rem); }
.commerce-intro h1 { margin: .6rem 0 1rem; font: 400 clamp(3.4rem, 7vw, 7rem)/1 var(--display); letter-spacing: -.035em; }
.commerce-intro > p:last-child { color: var(--muted); line-height: 1.7; }
.commerce-notice { padding: 1rem 1.25rem; margin: 0 0 1.5rem; border: 1px solid var(--gold); color: var(--ivory); line-height: 1.5; }
.bag-layout, .checkout-layout { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(280px, .8fr); gap: clamp(2rem, 5vw, 6rem); align-items: start; }
.bag-line { display: grid; grid-template-columns: clamp(90px, 13vw, 155px) minmax(0, 1fr) auto; gap: clamp(.85rem, 2vw, 2rem); padding: 1.5rem 0; border-top: 1px solid var(--line); }
.bag-image { position: relative; display: block; aspect-ratio: 4/5; background: #29251e; overflow: hidden; }
.bag-image .product-sale-badge { top: .45rem; left: .45rem; max-width: calc(100% - .9rem); font-size: .58rem; }
.bag-image img { width: 100%; height: 100%; display: block; object-fit: cover; }
.bag-line-info { min-width: 0; }
.bag-line h2 { margin: 0; font: 400 clamp(1.3rem, 2.5vw, 2rem)/1.2 var(--display); overflow-wrap: anywhere; }
.bag-meta, .bag-unit, .bag-summary > p { color: var(--muted); font-size: .86rem; line-height: 1.6; }
.bag-meta { margin: .65rem 0 .3rem; }
.bag-unit { margin: .3rem 0; }
.bag-unit del { display: block; color: var(--muted); font-size: .78rem; }
.bag-unit strong { display: block; color: #e7b273; font-size: .95rem; }
.bag-issue { color: #e5bd78; font-size: .85rem; line-height: 1.5; }
.bag-line-total { font-weight: 400; font-size: .94rem; white-space: nowrap; }
.bag-controls { display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .65rem; margin-top: 1rem; }
.bag-controls button:not(.bag-text-action) { width: 44px; height: 44px; border: 1px solid var(--line); background: transparent; cursor: pointer; }
.bag-controls button:disabled { opacity: .35; cursor: not-allowed; }
.bag-quantity { min-width: 2rem; text-align: center; }
.bag-text-action { min-height: 44px; padding: .4rem; border: 0; background: transparent; color: var(--gold); text-decoration: underline; text-underline-offset: .25rem; cursor: pointer; }
.bag-summary, .checkout-panel { padding: clamp(1.4rem, 3vw, 2.5rem); border: 1px solid var(--line); background: #151310; min-width: 0; }
.bag-summary h2, .checkout-panel h2 { margin: 0 0 2rem; font: 400 clamp(1.8rem, 3vw, 2.5rem) var(--display); }
.summary-row, .checkout-summary-line { display: flex; justify-content: space-between; gap: 1rem; padding: 1rem 0; border-top: 1px solid var(--line); line-height: 1.5; }
.summary-row span:last-child, .checkout-summary-line span:last-child { text-align: right; }
.checkout-summary-line span:last-child { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .25rem .5rem; }
.checkout-summary-line del { color: var(--muted); font-size: .82em; }
.checkout-summary-line strong { color: #e7b273; font-weight: 700; }
.commerce-primary, .commerce-secondary { min-height: 48px; display: inline-flex; align-items: center; justify-content: center; padding: .8rem 1rem; border: 1px solid var(--gold); font: 500 .75rem var(--sans); letter-spacing: .12em; text-align: center; text-transform: uppercase; cursor: pointer; transition: background .35s cubic-bezier(.2,.7,.2,1), color .35s cubic-bezier(.2,.7,.2,1), transform .35s cubic-bezier(.2,.7,.2,1); }
.commerce-primary { background: var(--gold); color: var(--ink); }
.commerce-secondary { background: transparent; color: var(--ivory); }
.commerce-primary:focus-visible, .commerce-secondary:focus-visible { transform: translateY(-2px); background: var(--ivory); border-color: var(--ivory); color: var(--ink); }
/* The lift is a pointer flourish; on touch the button answers with a firm press
   instead, so the two never fight over the same transform. */
.commerce-primary:active, .commerce-secondary:active { transform: translateY(0); background: var(--gold); color: var(--ink); }
@media (hover: hover) {
  .commerce-primary:hover, .commerce-secondary:hover { transform: translateY(-2px); background: var(--ivory); border-color: var(--ivory); color: var(--ink); }
}
.commerce-primary:disabled, .commerce-primary[aria-disabled="true"] { opacity: .45; cursor: not-allowed; transform: none; }
.bag-summary .commerce-primary, .bag-summary .commerce-secondary { width: 100%; margin-top: 1rem; }
.bag-empty { padding: clamp(3rem, 8vw, 7rem) 1rem; border-block: 1px solid var(--line); text-align: center; }
.bag-empty h2 { font: 400 clamp(2rem, 5vw, 4rem)/1.1 var(--display); }
.bag-empty p:last-child { color: var(--muted); }
.product-purchase { padding: 1.5rem 0; border-top: 1px solid var(--line); }
.product-purchase > label { display: block; margin-bottom: .7rem; color: var(--muted); font-size: .7rem; letter-spacing: .13em; text-transform: uppercase; }
.purchase-controls { display: flex; gap: .75rem; }
.purchase-controls input { width: 74px; min-height: 48px; padding: .5rem; border: 1px solid var(--line); background: #171513; color: var(--ivory); font: inherit; text-align: center; }
.purchase-controls button { flex: 1; min-height: 48px; border: 1px solid var(--gold); background: var(--gold); color: var(--ink); font-size: .75rem; letter-spacing: .12em; text-transform: uppercase; cursor: pointer; transition: background .3s ease, transform .3s ease; }
.purchase-controls button:focus-visible { background: var(--ivory); transform: translateY(-2px); }
.purchase-controls button:active { transform: translateY(0); }
@media (hover: hover) {
  .purchase-controls button:hover { background: var(--ivory); transform: translateY(-2px); }
}
.purchase-controls button:disabled { opacity: .45; cursor: not-allowed; transform: none; }
.product-purchase [data-add-message] { min-height: 1.5em; color: var(--muted); font-size: .85rem; }
.product-purchase [data-view-bag] { min-height: 44px; display: inline-flex; align-items: center; color: var(--gold); font-size: .8rem; text-transform: uppercase; letter-spacing: .1em; }

/* Phase 5.5 — Save to wishlist.
   Its own control rather than a second button inside .purchase-controls, because
   that container's button is the gold "Add to Bag" and stretches to fill: saving
   is a secondary action and it must not be mistaken for the primary one. Full
   width on its own line, the 48px the other purchase controls use, and a gold
   outline rather than a gold fill so the two never compete. */
.product-purchase [data-wishlist-save] { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 48px; margin-top: 1.1rem; border: 1px solid var(--gold); background: none; color: var(--gold); font: 500 .75rem/1 var(--sans); letter-spacing: .12em; text-transform: uppercase; cursor: pointer; transition: background .3s ease, color .3s ease; }
/* Inside @media (hover: hover), because this is exactly the rule
   touch-hover-media-check.mjs exists to catch. Unguarded, it latches on tap:
   the finger goes down, the fill stays, and the page scrolls with a button that
   looks pressed long after the finger left. The guard is not a nicety here —
   the control sits directly under "Add to Bag", so a latched Save is the most
   visible possible instance of the bug. */
@media (hover: hover) {
  .product-purchase [data-wishlist-save]:hover { background: var(--gold); color: var(--ink); }
}
.product-purchase [data-wishlist-save]:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.product-purchase [data-wishlist-save]:disabled { opacity: .45; cursor: not-allowed; }
/* The saved state, which is a toggle the customer can undo — so it is still
   enabled, just filled. aria-pressed carries the same information for a screen
   reader, and the label change is the same information visually. */
.product-purchase [data-wishlist-save][aria-pressed="true"] { background: var(--gold); color: var(--ink); }
.product-purchase [data-wishlist-save][hidden] { display: none; }
.product-purchase [data-wishlist-save-notice] { min-height: 1.5em; color: var(--muted); font-size: .85rem; }
.product-purchase [data-wishlist-save-notice].is-success { color: var(--gold); }
.product-purchase [data-wishlist-save-notice].is-error { color: #d98b82; }

.checkout-panel h2:not(:first-child) { margin-top: 2.5rem; }

/* Phase 5.9 — the account block that sits above the Customer heading.
   A hairline rule, the same uppercase micro-label the field labels use, and the
   same input treatment as .field input. Deliberately not a card: the panel it
   lives in is already the card, and a second bordered box inside it would read
   as a hierarchy that is not there. It sits before the <h2> so the .checkout-panel
   h2:not(:first-child) margin above still applies to "Customer" and not to this. */
.checkout-account { margin: 0 0 2.5rem; padding: 0 0 2rem; border-bottom: 1px solid var(--line); min-width: 0; }
.checkout-account-line { margin: 0 0 1.4rem; color: var(--muted); font-size: .9rem; line-height: 1.6; }
/* 44px on a text link is a target, not padding: it is the only way from the
   checkout into the address book, and a phone customer aiming at a word in a
   sentence needs more than the word. inline-flex with a negative margin keeps the
   line's own rhythm while the tap area reaches the full height. */
.checkout-account-line a { display: inline-flex; align-items: center; min-height: 44px; margin: -11px 0; color: var(--gold); text-underline-offset: 3px; }
.checkout-addresses-label { display: block; margin-bottom: .5rem; color: var(--muted); font-size: .73rem; letter-spacing: .1em; text-transform: uppercase; }
.checkout-addresses select { width: 100%; min-width: 0; min-height: 48px; padding: .75rem; border: 1px solid var(--line); border-radius: 0; background: #1d1a16; color: var(--ivory); font: 1rem var(--sans); }
.checkout-addresses-hint { min-height: 1.5em; margin: .6rem 0 0; color: var(--muted); font-size: .85rem; line-height: 1.6; overflow-wrap: anywhere; }
.checkout-addresses-note { margin: .2rem 0 0; color: var(--muted); font-size: .8rem; line-height: 1.6; }
/* A text-weight action, not a second submit-shaped button: choosing to check out
   without the account is a preference, and giving it a filled control would put
   it in competition with "Review details". 44px is the same target the header and
   the menu commit to. */
.checkout-account-action { display: inline-flex; align-items: center; min-height: 44px; margin-top: 1.2rem; padding: 0; border: 0; background: none; color: var(--gold); font: 500 .95rem var(--sans); text-align: left; text-decoration: underline; text-underline-offset: 4px; cursor: pointer; }
.checkout-account-action:active { color: var(--ivory); }
@media (hover: hover) {
  .checkout-account-action:hover { color: var(--ivory); }
}
.checkout-account-status { margin: 1rem 0 0; color: var(--muted); font-size: .85rem; line-height: 1.6; }

.checkout-fields { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.2rem; }
.field { min-width: 0; }.field-wide { grid-column: 1 / -1; }
.field label { display: block; margin-bottom: .5rem; color: var(--muted); font-size: .73rem; letter-spacing: .1em; text-transform: uppercase; }
.field input, .field textarea { width: 100%; min-height: 48px; padding: .75rem; border: 1px solid var(--line); border-radius: 0; background: #1d1a16; color: var(--ivory); font: 1rem var(--sans); }
.field input[aria-invalid="true"] { border-color: #e5bd78; }
.field-error { margin: .4rem 0 0; color: #e5bd78; font-size: .85rem; }
.checkout-panel form > .commerce-primary { margin-top: 2rem; }
[data-error-summary] a { display: block; min-height: 32px; text-decoration: underline; }
[data-review] p:not(.eyebrow) { color: var(--muted); line-height: 1.7; }
[data-review-details] { display: grid; grid-template-columns: minmax(7rem, 28%) minmax(0, 1fr); margin: 2rem 0 0; }
[data-review-details] dt, [data-review-details] dd { margin: 0; padding: 1rem 0; border-top: 1px solid var(--line); }
[data-review-details] dt { padding-right: 1.5rem; color: var(--muted); font: 500 .7rem/1.7 var(--sans); letter-spacing: .1em; text-transform: uppercase; }
[data-review-details] dd { min-width: 0; font: 400 1rem/1.7 var(--sans); overflow-wrap: anywhere; }
/* ---- Phase 6.2 confirmation: the confirmation is a PAGE, not a panel --------
   In this state the Bag aside is hidden, so the two-column grid has nothing in
   its second column — and without the collapse below the confirmation keeps
   rendering into the wide column with a dead one beside it, which is most of what
   read as "clustered". The chrome goes with it: the form panel is a card, but a
   placed order is the page, so the border and the raised background are dropped
   and the confirmation is centred on the ink ground instead.

   Every rule is scoped to `[data-confirmed="true"]`, which checkout-confirm.mjs
   sets on the layout. That is not decoration: `.checkout-panel h2` and its
   `:not(:first-child)` sibling already style the form's headings, and the summary
   heading is an h2 inside the same panel, so the state selector is what lets the
   confirmation restyle it without an escalation of one-off overrides. */
.checkout-layout[data-confirmed="true"] { grid-template-columns: minmax(0, 1fr); gap: 0; }
.checkout-layout[data-confirmed="true"] .checkout-panel { padding: 0; border: 0; background: none; }
.checkout-layout[data-confirmed="true"] .order-result { max-width: 44rem; margin: 0 auto; }
/* 1. The state, as a micro-label. Reuses the site's .eyebrow treatment. */
.checkout-layout[data-confirmed="true"] .order-result-eyebrow { margin-bottom: 1.25rem; }
/* 2. The page heading. Display face at page scale — smaller than the storefront
      h1, which is a hero, and far larger than the card heading it replaces. */
.checkout-layout[data-confirmed="true"] .order-result-heading { margin: 0 0 1.5rem; font: 400 clamp(2.3rem, 5vw, 3.4rem)/1.08 var(--display); letter-spacing: -.02em; }
.checkout-layout[data-confirmed="true"] .order-result-message { margin: 0; color: var(--muted); line-height: 1.8; max-width: 52ch; }
/* 3. The reference, in a block of its own between two hairlines. The order number
      is what a customer reads out to support, so it is labelled and set apart
      rather than left anonymous next to a badge. */
.checkout-layout[data-confirmed="true"] .order-reference { margin-top: clamp(2rem, 4vw, 3rem); padding: 1.5rem 0; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.checkout-layout[data-confirmed="true"] .order-reference-label { margin: 0 0 .6rem; font: 500 .7rem var(--sans); letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }
.checkout-layout[data-confirmed="true"] .order-reference-value { margin: 0; font: 500 clamp(1.05rem, 2.5vw, 1.3rem)/1.5 var(--sans); font-variant-numeric: tabular-nums; letter-spacing: .025em; color: var(--ivory); overflow-wrap: anywhere; }
/* 5. The order's own details, as a two-column information list: one labelled fact
      per row, the label in the margin and the value as the record itself. It is
      deliberately NOT a table in the invoice sense — no header row, no vertical
      borders, no zebra striping, no cell walls. What makes it read as premium
      rather than as an admin panel is what is left out, plus the hairlines
      BETWEEN rows only and the room around them. */
.checkout-layout[data-confirmed="true"] .order-notes {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  /* The rule is drawn by the cells themselves, so the column gap has to be ZERO:
     a gap would break the line between a label and its value. The gutter is
     padding on the label instead, which keeps the rule continuous across the row
     and still starts every value at the same x. */
  column-gap: 0;
  row-gap: 0;
  margin: clamp(2rem, 4vw, 3rem) 0 0;
}
.checkout-layout[data-confirmed="true"] .order-notes dt,
.checkout-layout[data-confirmed="true"] .order-notes dd { padding: 1.1rem 0; border-top: 1px solid var(--line); }
/* No rule above the first row, because the reference block's own hairline already
   closes the space above it. `:first-child` is structural rather than visible, so
   this holds when the status row has hidden itself for a status this build does
   not know — the row that then leads the list simply carries the first rule, which
   is where a reader expects to find it. */
.checkout-layout[data-confirmed="true"] .order-notes > dt:first-child,
.checkout-layout[data-confirmed="true"] .order-notes > dt:first-child + dd { border-top: 0; }
.checkout-layout[data-confirmed="true"] .order-notes dt {
  /* The label is a micro-label set in caps at .7rem, so its first line sits higher
     than the value's; the extra top padding is the optical alignment that puts the
     two on the same visual line. `align-self: start` keeps a label that wraps off
     the value's vertical centring. */
  align-self: start;
  padding-top: calc(1.1rem + .28rem);
  padding-right: clamp(1.5rem, 6vw, 3.5rem);
  font: 500 .7rem var(--sans);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted);
}
/* The value is ivory, not the muted grey the prose around it uses: those two rows
   are the ORDER's own facts rather than commentary, and the reference value above
   is already set this way. */
.checkout-layout[data-confirmed="true"] .order-notes dd { margin: 0; color: var(--ivory); line-height: 1.75; max-width: 46ch; }
/* 6/7. The summary. Label left, value right, one hairline above the total only —
      a receipt line-item table is what this replaces. */
.checkout-layout[data-confirmed="true"] .order-summary { margin-top: clamp(2.5rem, 5vw, 4rem); }
.checkout-layout[data-confirmed="true"] .order-summary-heading { margin: 0 0 1.5rem; font: 500 .7rem var(--sans); letter-spacing: .18em; text-transform: uppercase; color: var(--muted); }
.checkout-layout[data-confirmed="true"] .order-totals { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 1rem 1.25rem; max-width: 28rem; margin: 0; padding: 0; border: 0; }
.checkout-layout[data-confirmed="true"] .order-totals dt { color: var(--muted); }
.checkout-layout[data-confirmed="true"] .order-totals dd { margin: 0; text-align: right; color: var(--ivory); font: 400 1.0625rem/1.5 var(--sans); font-variant-numeric: tabular-nums; }
.checkout-layout[data-confirmed="true"] .order-totals .total-label { padding-top: 1.5rem; border-top: 1px solid var(--line); color: var(--ivory); }
.checkout-layout[data-confirmed="true"] .order-totals .total-value { padding-top: 1.5rem; border-top: 1px solid var(--line); font: 500 clamp(1.4rem, 3.5vw, 1.6rem)/1.4 var(--sans); font-variant-numeric: tabular-nums; }
/* 8. One action, and it is the filled one. */
.checkout-layout[data-confirmed="true"] .order-result-cta { min-width: min(100%, 16rem); }
.review-actions { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 2rem; }
@media (max-width: 560px) {
  [data-review-details] { grid-template-columns: minmax(0, 1fr); }
  [data-review-details] dt { padding-right: 0; padding-bottom: .35rem; }
  [data-review-details] dd { border-top: 0; padding-top: 0; }
  /* Below this width the label column costs more than it earns once the values
     start wrapping, so the list stacks: the label sits above its value and the
     rule moves onto the label. The value must then drop its own rule, or every
     entry would be closed by a second line. */
  .checkout-layout[data-confirmed="true"] .order-notes { grid-template-columns: minmax(0, 1fr); }
  .checkout-layout[data-confirmed="true"] .order-notes dt { padding-bottom: .5rem; padding-right: 0; }
  .checkout-layout[data-confirmed="true"] .order-notes dd { border-top: 0; padding-top: 0; }
  .checkout-layout[data-confirmed="true"] .order-result-cta { width: 100%; }
}
@media (max-width: 850px) { .bag-layout, .checkout-layout { grid-template-columns: 1fr; } }
@media (max-width: 700px) { .catalog-header nav a:not(.catalog-bag):not(:nth-child(2)) { display: none; } .commerce-main { padding-inline: 5vw; } }
@media (max-width: 500px) { .bag-line { grid-template-columns: 85px minmax(0, 1fr); } .bag-line-total { grid-column: 2; } .checkout-fields { grid-template-columns: 1fr; } .field-wide { grid-column: auto; } .commerce-intro h1 { font-size: clamp(3rem, 13vw, 4.5rem); } }
@media (max-width: 360px) { .catalog-header nav { gap: .4rem; } .bag-line { gap: .7rem; } }
@media (prefers-reduced-motion: reduce) { .commerce-page *, .commerce-page *::before, .commerce-page *::after, .product-purchase * { transition-duration: .01ms !important; animation-duration: .01ms !important; } }
.order-purchased-items .order-items { padding: 0; list-style: none; font-family: var(--sans); }
.order-purchased-items .order-items li { display: flex; justify-content: space-between; gap: 1rem; padding: .8rem 0; border-bottom: 1px solid var(--line); }
.order-purchased-items .order-items span { font-variant-numeric: tabular-nums; }
@media (max-width: 560px) { .order-purchased-items .order-items li { flex-direction: column; gap: .3rem; } }

[data-manual-methods]{display:grid;gap:.75rem;margin-bottom:1.5rem;padding:1rem;border:1px solid #b79a65;}[data-manual-methods] label{display:flex;gap:.5rem;align-items:flex-start;}
