/* =========================================================================
   Customer POS — mobile first.
   Desktop is re-laid out (category column + grid + cart panel), never a
   stretched phone screen.
   ========================================================================= */

.pos {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--shelf);
}

/* ------------------------------------------------------------- pos header
   The brand bar alone is sticky, so the cart is always one tap away while
   the search field and collection strip scroll away and give the products
   the screen. The category rail then parks directly beneath the bar.        */
.pos-head {
  position: sticky;
  top: 0;
  z-index: 41;
  background: var(--ink);
  color: #fff;
}
.pos-subhead {
  position: relative;
  z-index: 40;
  background: var(--ink);
  color: #fff;
}
.pos-head__bar {
  display: flex;
  align-items: center;
  gap: var(--s3);
  min-height: var(--header-h);
  padding: calc(env(safe-area-inset-top, 0px) + var(--s2)) var(--s3) var(--s2);
  background: var(--ink);
}
.pos-head__brand {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 7px;
  margin-right: auto;
  padding: 0 var(--s1);
  min-width: 0;
}
/* Editorial, not a logo block: normal width, restrained weight, wide
   tracking. Extra-bold ultra-wide read as heavy signage, not a cellar. */
.pos-head__name {
  font-variation-settings: "wdth" 100, "wght" 620;
  font-size: var(--text-md);
  letter-spacing: 0.19em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}
.pos-head__src {
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: 0.04em;
  line-height: 1;
  color: rgba(255, 255, 255, 0.62);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* On wide screens the header rows line up with the POS columns below. */
@media (min-width: 1100px) {
  .pos-head__bar,
  .pos-head__collect,
  .pos-search__box {
    max-width: var(--pos-max);
    margin-inline: auto;
  }
  .pos-search {
    padding-inline: var(--s5);
  }
  .pos-head__bar,
  .pos-head__collect {
    padding-inline: var(--s5);
  }
}
.pos-head__btn {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 46px;
  height: 46px;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: rgba(255, 255, 255, 0.92);
  transition: background var(--t-fast), color var(--t-fast);
}
.pos-head__btn:hover {
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
}
.pos-head__count {
  position: absolute;
  top: 5px;
  right: 4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--ticket);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  line-height: 18px;
  text-align: center;
}

/* collection strip — always tells the customer where they're collecting */
.pos-head__collect {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  min-height: 44px;
  padding: var(--s2) var(--s3);
  border: 0;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.05);
  color: rgba(255, 255, 255, 0.9);
  font-size: var(--text-sm);
  text-align: left;
}
.pos-head__collect strong {
  font-weight: 700;
  color: #fff;
}
.pos-head__collect:hover {
  background: rgba(255, 255, 255, 0.1);
}
.pos-head__collect .spacer {
  flex: 1;
}

/* search */
.pos-search {
  padding: var(--s3) var(--s3) var(--s4);
  background: var(--ink);
  border-top: 1px solid rgba(255, 255, 255, 0.14);
}
.pos-search__box {
  position: relative;
  display: flex;
  align-items: center;
}
.pos-search__box svg {
  position: absolute;
  left: 14px;
  color: var(--ink-40);
  pointer-events: none;
}
.pos-search__input {
  width: 100%;
  min-height: 46px;
  padding: 0 var(--s10) 0 44px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--text-md);
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.06),
    inset 0 1px 2px rgba(14, 31, 25, 0.06);
  transition: box-shadow var(--t-fast), border-color var(--t-fast);
}
.pos-search__input::placeholder {
  color: var(--ink-40);
}
.pos-search__input:hover {
  border-color: rgba(255, 255, 255, 0.28);
}
.pos-search__input:focus {
  outline: none;
  border-color: var(--ticket);
  box-shadow: 0 0 0 3px rgba(255, 199, 44, 0.28);
}
.pos-search__clear {
  position: absolute;
  right: 4px;
  width: 34px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--r-sm);
  background: none;
  color: var(--ink-60);
}

/* ------------------------------------------------------------ category rail */
.cat-rail {
  position: sticky;
  top: calc(var(--header-h) + env(safe-area-inset-top, 0px));
  z-index: 30;
  display: flex;
  gap: var(--s2);
  padding: var(--s3);
  background: var(--shelf);
  border-bottom: 1px solid var(--rule);
  overflow-x: auto;
  scroll-padding-inline: var(--s3);
  /* The rail runs past the right edge on a phone. Fading the last chip says
     "there is more" — a hard crop just looks like a broken layout. */
  -webkit-mask-image: linear-gradient(
    to right,
    #000 0,
    #000 calc(100% - 32px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    #000 0,
    #000 calc(100% - 32px),
    transparent 100%
  );
}
/* Flex-centred, not just min-height: as a bare block the label sat against
   the top of the 42px chip with the slack all underneath it. */
.cat-rail__btn {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 42px;
  padding: 0 var(--s4);
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  font-variation-settings: "wdth" 104, "wght" 600;
  font-size: var(--text-md);
  line-height: 1;
  white-space: nowrap;
  color: var(--ink-80);
}
.cat-rail__btn:hover {
  border-color: var(--ink-40);
}
.cat-rail__btn--on {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.cat-rail__btn--deals {
  background: var(--ticket);
  border-color: var(--ticket-deep);
  color: var(--ink);
  font-variation-settings: "wdth" 108, "wght" 800;
}
.cat-rail__btn--deals.cat-rail__btn--on {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--ticket);
}

/* --------------------------------------------------------------- pos body */
.pos-body {
  flex: 1;
  width: 100%;
  max-width: var(--pos-max);
  margin: 0 auto;
  padding: var(--s4) var(--s3) 96px;
}
.pos-body--flush {
  padding-left: 0;
  padding-right: 0;
}

.pos-columns {
  display: block;
}

/* the desktop layout only appears when there is room for all three columns */
@media (min-width: 1100px) {
  .pos-columns {
    display: grid;
    /* Browse rail + catalogue. The cart lives in the header and in the
       summary bar, so the page is not paying a third of its width for a
       panel that is empty most of the time. */
    grid-template-columns: 184px minmax(0, 1fr);
    gap: var(--s6);
    align-items: start;
    width: 100%;
    max-width: var(--pos-max);
    margin: 0 auto;
    /* clears the fixed cart summary bar in the bottom corner */
    padding: var(--s6) var(--s5) 96px;
  }
  .pos-body {
    padding: 0;
    max-width: none;
  }
  .cat-rail {
    display: none;
  }
}

/* desktop category column */
.cat-column {
  display: none;
}
@media (min-width: 1100px) {
  .cat-column {
    display: block;
    position: sticky;
    top: calc(var(--header-h) + var(--s5));
  }
  .cat-column__head {
    margin-bottom: var(--s3);
    padding: 0 var(--s3);
  }
  .cat-column__list {
    display: flex;
    flex-direction: column;
    gap: 1px;
  }
  .cat-column__btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s3);
    width: 100%;
    min-height: 38px;
    padding: 0 var(--s3);
    border: 0;
    border-radius: var(--r-sm);
    background: none;
    text-align: left;
    font-size: var(--text-md);
    font-weight: 500;
    color: var(--ink-80);
    transition: background var(--t-fast), color var(--t-fast);
  }
  .cat-column__btn:hover {
    background: rgba(14, 31, 25, 0.05);
    color: var(--ink);
  }
  /* The selected category reads as a solid ink plate — one strong state in
     the column, everything else quiet. */
  .cat-column__btn--on,
  .cat-column__btn--on:hover {
    background: var(--ink);
    color: #fff;
    font-weight: 600;
  }
  .cat-column__btn--deals {
    color: #7a5100;
    font-weight: 600;
  }
  .cat-column__btn--deals:hover {
    background: rgba(255, 199, 44, 0.16);
    color: #6b4700;
  }
  /* Selected deals: the mustard has to move to the accent or it sits dark
     on the dark active plate. */
  .cat-column__btn--on.cat-column__btn--deals,
  .cat-column__btn--on.cat-column__btn--deals:hover {
    background: var(--ink);
    color: var(--ticket);
  }
  .cat-column__btn--on.cat-column__btn--deals .cat-column__n {
    color: rgba(255, 199, 44, 0.72);
  }
  .cat-column__n {
    flex: none;
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    font-variant-numeric: tabular-nums;
    color: var(--ink-40);
  }
  .cat-column__btn--on .cat-column__n {
    color: rgba(255, 255, 255, 0.7);
  }
}

/* ------------------------------------------------------- promotion strip */
.promo-strip {
  display: flex;
  gap: var(--s3);
  overflow-x: auto;
  padding: 0 var(--s3) var(--s4);
  margin: 0 calc(var(--s3) * -1);
  scroll-snap-type: x mandatory;
  /* the next card peeks and then fades, so the cut edge reads as
     "keep scrolling" rather than as a clipped layout */
  -webkit-mask-image: linear-gradient(
    to right,
    #000 0,
    #000 calc(100% - 40px),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    #000 0,
    #000 calc(100% - 40px),
    transparent 100%
  );
}
/* From tablet up every promotion is on screen at once — no scroller, no
   half-shown card, no ragged gap after the last one. They divide the row
   evenly and wrap only if the shop ever runs more than three at a time.
   Below this the peeking carousel is the right pattern for a thumb. */
@media (min-width: 720px) {
  .promo-strip {
    display: grid;
    /* Low enough that all three still share one row in the narrowest
       three-column layout (a 492px centre column at 1100px). A higher floor
       drops the last card onto a row of its own with a void beside it. */
    grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
    gap: var(--s4);
    margin: 0;
    padding: 0 0 var(--s5);
    overflow: visible;
    -webkit-mask-image: none;
    mask-image: none;
  }
}
/* Slimmer than a content card and quieter than a banner: a dark ribbon with
   one hairline of accent, not a block of yellow. */
.promo-card {
  position: relative;
  flex: none;
  scroll-snap-align: start;
  display: flex;
  align-items: stretch;
  width: min(292px, 82vw);
  border: 1px solid var(--ink);
  border-radius: var(--r-md);
  background: var(--ink);
  color: #fff;
  overflow: hidden;
  text-align: left;
  transition: transform var(--t-med), box-shadow var(--t-med),
    border-color var(--t-med);
}
.promo-card:hover {
  transform: translateY(-2px);
  border-color: var(--bottle);
  box-shadow: var(--shadow-lift);
}
/* the faintest warmth off the top-right corner — depth, not decoration */
.promo-card::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(
    90% 80% at 100% 0%,
    rgba(255, 199, 44, 0.07) 0%,
    rgba(255, 199, 44, 0) 62%
  );
}
/* From tablet up the strip is a grid, so the card takes its track's width. */
@media (min-width: 720px) {
  .promo-card {
    width: auto;
    min-width: 0;
  }
}
.promo-card__flag {
  flex: none;
  width: 3px;
  background: var(--ticket);
}
.promo-card__body {
  padding: var(--s3);
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  flex: 1;
}
@media (min-width: 1360px) {
  .promo-card__body {
    padding: var(--s3) var(--s4);
  }
}
.promo-card__title {
  font-variation-settings: "wdth" 106, "wght" 700;
  font-size: var(--text-md);
  letter-spacing: 0.005em;
  line-height: var(--lh-tight);
}
/* These wrap rather than truncate: in a three-up row on a 1280px laptop the
   card is ~170px wide, and an ellipsis would eat the offer itself. Cards are
   grid items, so a wrapped line stretches all three to the same height. */
.promo-card__sub {
  font-size: var(--text-sm);
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.68);
  text-wrap: balance;
}
.promo-card__meta {
  margin-top: auto;
  padding-top: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--text-2xs);
  letter-spacing: 0.02em;
  line-height: 1.4;
  color: rgba(255, 199, 44, 0.82);
  text-transform: uppercase;
}
.promo-card__meta span {
  white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .promo-card:hover {
    transform: none;
  }
}

/* ------------------------------------------------------------ section head */
.sec-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s3);
}
.sec-head__title {
  font-variation-settings: "wdth" 108, "wght" 800;
  font-size: var(--text-xl);
  letter-spacing: -0.015em;
}
.sec-head__count {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-60);
}

/* ------------------------------------------------------------ product grid */
.grid-products {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(152px, 1fr));
  gap: var(--s3);
}
@media (min-width: 640px) {
  .grid-products {
    grid-template-columns: repeat(auto-fill, minmax(178px, 1fr));
    gap: var(--s4);
  }
}
/* three across in the desktop POS column — four no longer leaves the name
   and price room to sit on their own lines. */
@media (min-width: 1100px) {
  .grid-products {
    grid-template-columns: repeat(auto-fill, minmax(185px, 1fr));
    gap: var(--s4);
  }
}

.pcard {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  overflow: hidden;
  box-shadow: 0 1px 1px rgba(14, 31, 25, 0.03);
  transition: transform var(--t-med), border-color var(--t-med),
    box-shadow var(--t-med);
}
.pcard:hover {
  transform: translateY(-2px);
  border-color: var(--rule-strong);
  box-shadow: var(--shadow-lift);
}
.pcard--out {
  opacity: 0.72;
}
.pcard--out:hover {
  transform: none;
  box-shadow: none;
}

/* The image well: an ivory alcove the bottle stands in, not a grey box. */
.pcard__art {
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 122px;
  padding: var(--s5) var(--s3) var(--s2);
  background: linear-gradient(172deg, #fdfcf8 0%, var(--cream) 60%, #f0ece1 100%);
  border: 0;
  border-bottom: 1px solid var(--rule);
  width: 100%;
  overflow: hidden;
  cursor: pointer;
}
@media (min-width: 640px) {
  .pcard__art {
    height: 152px;
  }
}
/* Every bottle is drawn on one viewBox and anchored to the same baseline,
   so a magnum and a can sit at identical scale across the whole grid. */
.pcard__art .vessel {
  height: 100%;
  width: auto;
  transform-origin: 50% 100%;
  transition: transform var(--t-med);
}
.pcard:hover .pcard__art .vessel {
  transform: scale(1.045);
}
@media (prefers-reduced-motion: reduce) {
  .pcard:hover,
  .pcard:hover .pcard__art .vessel {
    transform: none;
  }
}
/* On the tile the deal badge is a small marker, not a banner — it sits in
   the corner clear of the bottle and lets the price carry the offer. */
.pcard__ticket {
  position: absolute;
  top: var(--s3);
  left: var(--s3);
  padding: 3px 8px 3px 15px;
  font-variation-settings: "wdth" 104, "wght" 700;
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.2;
  background: var(--ticket);
  box-shadow: 0 1px 2px rgba(14, 31, 25, 0.12);
}
.pcard__ticket::before {
  left: 6px;
  width: 5px;
  height: 5px;
  margin-top: -2.5px;
  box-shadow: inset 0 0 0 1px rgba(14, 31, 25, 0.2);
}
.pcard__flag {
  position: absolute;
  top: var(--s3);
  right: var(--s3);
}

/* Six steps, each with its own measure of air:
   brand → name → size → price → saving → button. */
.pcard__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--s4);
  gap: 0;
}
/* One line always — a wrapping brand knocks every card in the row out of
   alignment with its neighbours. */
.pcard__brand {
  font-size: var(--text-2xs);
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--ink-60);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.pcard__name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: var(--s2);
  font-size: var(--text-md);
  font-variation-settings: "wdth" 102, "wght" 620;
  line-height: 1.3;
  min-height: 2.6em;
  /* long names break on a word boundary rather than mid-word */
  overflow-wrap: break-word;
  hyphens: auto;
  text-align: left;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: inherit;
  transition: color var(--t-fast);
}
.pcard__name:hover {
  color: var(--bottle);
}
.pcard__size {
  margin-top: var(--s2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.3;
  color: var(--ink-40);
}
/* The saving line is reserved whether or not the product has one, so a row
   of full-price products is exactly as tall as a row of deals and the grid
   keeps one rhythm all the way down. Floor = price line + gap + saving line. */
.pcard__price {
  margin-top: var(--s5);
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-height: 3.1em;
}
/* The price the customer pays is the loudest thing on the card; the old
   price and the saving sit under it as supporting detail. */
.pcard__price .price {
  align-items: baseline;
  gap: var(--s2);
}
.pcard__price .price__now {
  font-size: 1.5rem; /* 24 */
  letter-spacing: -0.02em;
}
.pcard__price .price__was {
  font-size: var(--text-xs);
  color: var(--ink-40);
  text-decoration-thickness: 1px;
}
.pcard__save {
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.05em;
  line-height: 1.3;
  color: #8a5a00;
  text-transform: uppercase;
}
.pcard__foot {
  margin-top: auto;
  padding-top: var(--s4);
}

/* stepper that replaces "Add" once the product is in the cart */
.qty {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 40px;
  border: 1px solid var(--ink);
  border-radius: var(--r-md);
  overflow: hidden;
  background: var(--surface);
}
.qty__btn {
  width: 40px;
  height: 100%;
  border: 0;
  background: var(--ink);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.qty__btn:hover {
  background: var(--ink-80);
}
.qty__n {
  flex: 1;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 600;
  font-size: var(--text-md);
}
.qty--lg {
  height: 48px;
}
.qty--lg .qty__btn {
  width: 48px;
}

/* The Add button carries the whole card, so it gets a quieter weight and a
   little more air than a generic primary button. */
.pcard__foot .btn {
  width: 100%;
  min-height: 42px;
  padding: 0;
  gap: 7px;
  font-variation-settings: "wdth" 104, "wght" 650;
  letter-spacing: 0.02em;
  transform: translateY(0);
  transition: background var(--t-fast), transform var(--t-fast),
    box-shadow var(--t-fast);
}
.pcard__foot .btn svg {
  flex: none;
}
.pcard__foot .btn--primary:hover:not(:disabled) {
  background: var(--bottle);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px -4px rgba(14, 31, 25, 0.42);
}
.pcard__foot .btn--primary:active:not(:disabled) {
  transform: translateY(0);
  box-shadow: none;
}
@media (prefers-reduced-motion: reduce) {
  .pcard__foot .btn--primary:hover:not(:disabled) {
    transform: none;
  }
}

.pcard__out {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 42px;
  border: 1px dashed var(--rule-strong);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-60);
}

/* --------------------------------------------------------- cart bottom bar */
.cart-bar {
  position: fixed;
  z-index: 45;
  left: 0;
  right: 0;
  bottom: 0;
  padding: var(--s3);
  padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  background: linear-gradient(
    to top,
    var(--shelf) 62%,
    rgba(236, 239, 234, 0)
  );
}
/* With the side panel gone this bar is the running cart on every screen
   size, so it stays put on desktop and just narrows to a summary pill. */
@media (min-width: 1100px) {
  .cart-bar {
    left: auto;
    right: var(--s5);
    padding-bottom: var(--s5);
    background: none;
  }
  .cart-bar__inner {
    width: auto;
    min-width: 320px;
  }
}
.cart-bar__inner {
  display: flex;
  align-items: center;
  gap: var(--s3);
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  min-height: 54px;
  padding: 0 var(--s3) 0 var(--s4);
  border: 0;
  border-radius: var(--r-md);
  background: var(--ink);
  color: #fff;
  box-shadow: var(--shadow-bar);
  text-align: left;
}
.cart-bar__inner > div {
  min-width: 0;
  padding: var(--s2) 0;
}
.cart-bar__count {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  line-height: 1.3;
  color: rgba(255, 255, 255, 0.72);
}
.cart-bar__total {
  display: block;
  margin-top: 2px;
  font-variation-settings: "wdth" 110, "wght" 800;
  font-size: var(--text-xl);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.cart-bar__cta {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s2) var(--s3);
  border-radius: var(--r-sm);
  background: var(--ticket);
  color: var(--ink);
  font-weight: 800;
  font-size: var(--text-md);
}
.cart-bar__save {
  display: block;
  margin-top: 3px;
  font-size: var(--text-2xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  line-height: 1.3;
  color: var(--ticket);
  text-transform: uppercase;
}

/* ------------------------------------------------------------- cart lines */
.cline {
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr) auto;
  gap: var(--s3);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--rule);
  align-items: start;
}
.cline:last-child {
  border-bottom: 0;
}
.cline__art {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  height: 64px;
  background: var(--surface-sunk);
  border-radius: var(--r-sm);
}
.cline__name {
  font-size: var(--text-md);
  font-weight: 650;
  line-height: var(--lh-tight);
}
.cline__meta {
  margin-top: var(--s1);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  line-height: 1.35;
  color: var(--ink-60);
}
/* The saving badge and the promotion name are separate units — they wrap as
   whole chips, never mid-phrase. */
.cline__promo {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s1) var(--s2);
  margin-top: var(--s2);
}
.cline__right {
  text-align: right;
}
.cline__actions {
  display: flex;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s3);
}
.cline__qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
}
.cline__qty button {
  width: 34px;
  height: 34px;
  border: 0;
  background: var(--surface);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
}
.cline__qty button:hover {
  background: var(--surface-sunk);
}
.cline__qty span {
  min-width: 30px;
  text-align: center;
  font-family: var(--font-mono);
  font-weight: 600;
}
.cline__remove {
  min-height: 34px;
  padding: 0 var(--s2);
  border: 0;
  background: none;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--ink-60);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.cline__remove:hover {
  color: var(--alert);
}

/* ------------------------------------------------------------ totals block */
.totals {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}
.totals__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  font-size: var(--text-md);
}
.totals__row span:last-child {
  font-variant-numeric: tabular-nums;
}
.totals__row--save {
  color: #8a5a00;
  font-weight: 700;
}
.totals__row--grand {
  padding-top: var(--s3);
  border-top: 1px solid var(--rule);
  font-variation-settings: "wdth" 108, "wght" 800;
  font-size: var(--text-xl);
}
.totals__gst {
  font-size: var(--text-xs);
  color: var(--ink-60);
}

/* ---------------------------------------------------------------- pages -- */
.page {
  width: 100%;
  max-width: 720px;
  margin: 0 auto;
  padding: var(--s4) var(--s3) var(--s16);
}
.page--wide {
  max-width: 900px;
}
.page__title {
  font-variation-settings: "wdth" 110, "wght" 800;
  font-size: var(--text-2xl);
  letter-spacing: -0.02em;
  margin-bottom: var(--s1);
}
.page__lead {
  color: var(--ink-60);
  margin-bottom: var(--s5);
}
@media (min-width: 720px) {
  .page {
    padding: var(--s8) var(--s5) var(--s16);
  }
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: var(--s1);
  min-height: 36px;
  margin-bottom: var(--s2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink-60);
}
.back-link:hover {
  color: var(--ink);
}

/* --------------------------------------------------------- location cards */
.loc-list {
  display: grid;
  gap: var(--s3);
}
.loc-card {
  display: block;
  width: 100%;
  padding: var(--s4);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--surface);
  text-align: left;
  transition: border-color var(--t-fast);
}
.loc-card:hover {
  border-color: var(--ink-40);
}
.loc-card--on {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink);
}
.loc-card__top {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s3);
}
.loc-card__name {
  font-size: var(--text-lg);
  font-variation-settings: "wdth" 104, "wght" 700;
}
.loc-card__dist {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-60);
  white-space: nowrap;
}
.loc-card__addr {
  margin-top: 2px;
  font-size: var(--text-sm);
  color: var(--ink-60);
}
.loc-card__rows {
  margin-top: var(--s3);
  display: grid;
  gap: var(--s2);
  font-size: var(--text-sm);
}
.loc-card__row {
  display: flex;
  gap: var(--s2);
  align-items: flex-start;
  color: var(--ink-80);
}
.loc-card__row svg {
  flex: none;
  margin-top: 1px;
  color: var(--ink-40);
}

/* --------------------------------------------------------------- receipt */
.receipt {
  background: var(--surface);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg) var(--r-lg) 0 0;
  overflow: hidden;
}
.receipt__head {
  padding: var(--s6) var(--s5) var(--s5);
  text-align: center;
  border-bottom: 1px dashed var(--rule-strong);
}
.receipt__tick {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  margin-bottom: var(--s3);
  border-radius: 50%;
  background: var(--bottle);
  color: #fff;
}
.receipt__title {
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: var(--text-2xl);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.receipt__no {
  margin-top: var(--s1);
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  letter-spacing: 0.06em;
  color: var(--ink-60);
}
.receipt__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--rule);
  border-bottom: 1px solid var(--rule);
}
.receipt__cell {
  padding: var(--s4) var(--s5);
  background: var(--surface);
}
.receipt__cell--full {
  grid-column: 1 / -1;
}
.receipt__k {
  font-size: var(--text-2xs);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-60);
  font-weight: 700;
}
.receipt__v {
  margin-top: 3px;
  font-size: var(--text-lg);
  font-variation-settings: "wdth" 104, "wght" 700;
}
.receipt__code {
  display: flex;
  align-items: center;
  gap: var(--s5);
  padding: var(--s5);
  background: var(--surface);
}
.receipt__code-body {
  min-width: 0;
}
.receipt__code-value {
  font-family: var(--font-mono);
  font-size: var(--text-2xl);
  font-weight: 600;
  letter-spacing: 0.12em;
}
.qr-frame {
  flex: none;
  padding: var(--s2);
  border: 1px solid var(--rule);
  border-radius: var(--r-sm);
  background: #fff;
}

/* -------------------------------------------------------------- timeline */
.timeline {
  display: flex;
  flex-direction: column;
}
.timeline__row {
  position: relative;
  display: grid;
  grid-template-columns: 26px minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s3);
  padding: var(--s2) 0;
  color: var(--ink-40);
}
.timeline__row::before {
  content: "";
  position: absolute;
  left: 9px;
  top: 26px;
  bottom: -6px;
  width: 2px;
  background: var(--rule);
}
.timeline__row:last-child::before {
  display: none;
}
.timeline__mark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  border: 2px solid var(--rule-strong);
  background: var(--surface);
  color: #fff;
}
.timeline__label {
  display: flex;
  align-items: center;
  gap: var(--s2);
  font-size: var(--text-md);
}
.timeline__time {
  font-size: var(--text-xs);
}
.timeline__row.is-done {
  color: var(--ink-80);
}
.timeline__row.is-done .timeline__mark {
  background: var(--bottle);
  border-color: var(--bottle);
}
.timeline__row.is-on {
  color: var(--ink);
  font-weight: 700;
}
.timeline__row.is-on .timeline__mark {
  border-color: var(--ink);
  box-shadow: inset 0 0 0 3px var(--ticket);
}
.timeline__row.is-terminal {
  color: var(--alert);
}
.timeline__row.is-terminal .timeline__mark {
  background: var(--alert);
  border-color: var(--alert);
}
.timeline__now {
  padding: 1px 6px;
  border-radius: 2px;
  background: var(--ticket);
  color: var(--ink);
  font-size: var(--text-2xs);
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --------------------------------------------------------- order summary */
.order-card {
  display: block;
  padding: var(--s4);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
  background: var(--surface);
}
.order-card + .order-card {
  margin-top: var(--s3);
}
.order-card__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s3);
  margin-bottom: var(--s2);
}
.order-card__no {
  font-family: var(--font-mono);
  font-size: var(--text-lg);
  font-weight: 600;
}
.order-card__meta {
  font-size: var(--text-sm);
  color: var(--ink-60);
}

/* ------------------------------------------------------------- quick view */
.qv {
  display: flex;
  flex-direction: column;
  gap: var(--s4);
}
@media (min-width: 560px) {
  .qv {
    flex-direction: row;
  }
}
/* Same ivory alcove as the product tile, so the detail view reads as a
   larger view of the same object. */
.qv__art {
  flex: none;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  width: 100%;
  height: 190px;
  padding-top: var(--s3);
  overflow: hidden;
  background: linear-gradient(170deg, #fdfcf8 0%, var(--cream) 62%, #f1ede2 100%);
  border: 1px solid var(--rule);
  border-radius: var(--r-md);
}
.qv__art .vessel {
  height: 100%;
  width: auto;
}
@media (min-width: 560px) {
  .qv__art {
    width: 172px;
    height: 210px;
  }
}
.qv__brand {
  font-size: var(--text-xs);
  letter-spacing: 0.08em;
  line-height: 1.3;
  text-transform: uppercase;
  color: var(--ink-60);
  font-weight: 700;
}
.qv__name {
  font-variation-settings: "wdth" 106, "wght" 750;
  font-size: var(--text-2xl);
  line-height: var(--lh-tight);
  margin: var(--s1) 0 var(--s2);
}
.qv__desc {
  margin: var(--s4) 0;
  font-size: var(--text-md);
  color: var(--ink-80);
  line-height: 1.6;
}
.qv__spec {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-bottom: var(--s3);
}

/* --------------------------------------------------------------- QR entry */
.qr-entry {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s5);
  padding: var(--s6) var(--s4) var(--s10);
  background: var(--ink);
  color: #fff;
  text-align: center;
}
.qr-entry__mark {
  font-variation-settings: "wdth" 112, "wght" 800;
  font-size: var(--text-xl);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.qr-entry__card {
  width: min(400px, 100%);
  padding: var(--s6);
  background: var(--surface);
  color: var(--ink);
  border-radius: var(--r-lg);
}
.qr-entry__label {
  font-size: var(--text-2xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--ink-60);
}
.qr-entry__venue {
  margin-top: var(--s2);
  font-variation-settings: "wdth" 104, "wght" 700;
  font-size: var(--text-xl);
  line-height: var(--lh-tight);
}
.qr-entry__qr {
  display: flex;
  justify-content: center;
  margin: var(--s4) 0;
}
.qr-entry__code {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  letter-spacing: 0.1em;
  color: var(--ink-60);
}
.qr-entry__alt {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  column-gap: var(--s5);
  row-gap: var(--s3);
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.78);
}
.qr-entry__alt a {
  text-decoration: underline;
  text-underline-offset: 3px;
}
.qr-entry__alt a:hover {
  color: #fff;
}
.qr-entry__reset {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: 0;
  background: none;
  color: rgba(255, 255, 255, 0.6);
  font-size: var(--text-sm);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.qr-entry__reset:hover {
  color: #fff;
}
.qr-entry__note {
  max-width: 46ch;
  font-size: var(--text-sm);
  color: rgba(255, 255, 255, 0.68);
  line-height: 1.6;
}

/* --------------------------------------------------------------- checkout */
.checkout {
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--shelf);
}
.checkout__head {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--surface);
  border-bottom: 1px solid var(--rule);
  padding-top: env(safe-area-inset-top, 0px);
}
.checkout__bar {
  display: flex;
  align-items: center;
  gap: var(--s2);
  height: var(--header-h);
  padding: 0 var(--s3);
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
}
.checkout__title {
  font-variation-settings: "wdth" 104, "wght" 700;
  font-size: var(--text-lg);
}
.checkout__steps {
  max-width: 900px;
  margin: 0 auto;
  width: 100%;
  padding: 0 var(--s3) var(--s2);
}
.checkout__body {
  flex: 1;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  /* clears the sticky action footer */
  padding: var(--s5) var(--s3) 120px;
}
.checkout__foot {
  position: sticky;
  bottom: 0;
  padding: var(--s3);
  padding-bottom: calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  background: var(--surface);
  border-top: 1px solid var(--rule);
}
.checkout__foot-inner {
  display: flex;
  align-items: center;
  gap: var(--s3);
  max-width: 640px;
  margin: 0 auto;
}
.checkout__foot .btn {
  flex: 1;
}
.checkout__foot-total {
  flex: none;
  line-height: 1.15;
}
.checkout__foot-total b {
  display: block;
  font-variation-settings: "wdth" 108, "wght" 800;
  font-size: var(--text-lg);
  font-variant-numeric: tabular-nums;
}

/* review list */
.review-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--rule);
}
.review-line:last-child {
  border-bottom: 0;
}
.review-line__qty {
  font-family: var(--font-mono);
  color: var(--ink-60);
  margin-right: var(--s2);
}

/* mock payment card */
.paycard {
  padding: var(--s5);
  border: 1px solid var(--rule);
  border-radius: var(--r-lg);
  background: var(--surface);
}
.paymethods {
  display: grid;
  gap: var(--s2);
  margin-bottom: var(--s4);
}
@media (min-width: 480px) {
  .paymethods {
    grid-template-columns: repeat(3, 1fr);
  }
}
.paymethod {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-height: 62px;
  border: 1px solid var(--rule-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  font-size: var(--text-sm);
  font-weight: 600;
}
.paymethod--on {
  border-color: var(--ink);
  background: var(--bottle-tint);
}
.pay-processing {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s4);
  padding: var(--s10) var(--s5);
  text-align: center;
}
.spinner {
  width: 34px;
  height: 34px;
  border: 3px solid var(--rule);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .spinner {
    animation-duration: 2.4s;
  }
}
