/* Cotton On, black and white. Every value here is sampled from cottonon.com:
   ink #333434, near-black chrome and buttons #111, page black, light grey
   surfaces #f4f4f2, hairline #e2e2e2. The site carries no second colour, so
   what used to be brand blue/red/yellow all resolve to the same black —
   emphasis comes from weight and case, not hue. Swap these and the app
   follows. Type is CircularPro/CircularProBook (the real brand faces, used
   when installed) over Figtree, the closest free stand-in, loaded in
   index.html. */
:root {
  --font: CircularProBook, CircularPro, Figtree, "Helvetica Neue", Helvetica, Arial, sans-serif;
  --font-head: CircularPro, Figtree, "Helvetica Neue", Helvetica, Arial, sans-serif;

  --page: #000000;
  --brand: #111111;
  --brand-deep: #000000;
  --brand-line: rgba(0, 0, 0, 0.12);
  --bubble: #ffffff;
  --ink: #333434;
  --white-soft: rgba(255, 255, 255, 0.78);
  --live: #111111;
  --error: #111111;
  --amber: #8a8a8a;
  /* Back arrow, cart, send and call all render at this size. */
  --icon: 22px;

  /* Shop surfaces */
  --shop-bg: #f4f4f2;
  --card: #ffffff;
  --muted: #6b6c6c;
  --accent: #111111;
  --accent-bright: #000000;
  --red: #111111;
  --heart: #111111;
  --star: #111111;
  --hairline: #e2e2e2;
}

* { box-sizing: border-box; }

/* Screens set display, so `hidden` needs to outrank it. */
[hidden] { display: none !important; }

html, body { height: 100%; }

/* Phone sits dead centre of the page, both axes. */
body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: var(--page);
  color: var(--ink);
  font: 15px/1.5 var(--font);
  -webkit-font-smoothing: antialiased;
}

/* Two columns: the copy on the left, the phone on the right. Both are
   centred against each other on the cross axis, and the pair is centred in
   the page by the flex rules on body. */
.stage {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(32px, 6vw, 96px);
  width: 100%;
  max-width: 1180px;
}

.intro {
  flex: 1 1 0;
  max-width: 560px;
  /* The logo is pushed to the bottom of the column, so the block needs a
     height to push against — matched to the phone's own height. */
  min-height: min(900px, calc(100vh - 40px));
  display: flex;
  flex-direction: column;
  justify-content: center;
  color: #fff;
}

.intro h1 {
  margin: 0 0 18px;
  font-family: var(--font-head);
  font-weight: 700;
  text-transform: uppercase;
  font-size: clamp(34px, 4.4vw, 52px);
  line-height: 1.05;
  letter-spacing: -0.02em;
}

.intro p {
  margin: 0 0 12px;
  color: var(--white-soft);
  font-size: 17px;
}

.intro ol,
.intro ul {
  margin: 0 0 26px;
  padding-left: 22px;
  color: var(--white-soft);
  font-size: 16px;
}

.intro li { margin-bottom: 10px; }
.intro li:last-child { margin-bottom: 0; }
.intro strong { color: #fff; }

/* Sits under the copy, and travels with it as the block centres. Opens the
   Spaceman site in a new tab. Sized 25% up from the original 300px/70%. */
.intro-logo-link {
  display: block;
  padding-top: 44px;
  width: min(375px, 87.5%);
}

.intro-logo {
  display: block;
  width: 100%;
  height: auto;
}

/* Below this the columns can't both breathe, so stack them and let the
   page scroll instead of squeezing the phone. */
@media (max-width: 900px) {
  body { align-items: flex-start; }

  .stage {
    flex-direction: column;
    gap: 40px;
  }

  .intro {
    min-height: 0;
    max-width: min(430px, 100%);
    align-items: flex-start;
  }

  .intro-logo-link { padding-top: 24px; }
}

.phone {
  flex: none;
  width: min(430px, 100%);
  height: min(900px, calc(100vh - 40px));
  padding: 12px;
  border-radius: 52px;
  background: #000;
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.22), 0 40px 80px rgba(0, 0, 0, 0.6);
}

.app {
  position: relative;
  height: 100%;
  display: grid;
  /* statusbar / header / screen / footer (tabbar, composer or product bar) */
  grid-template-rows: auto auto 1fr auto;
  border-radius: 42px;
  overflow: hidden;
  background: #fff;
}

/* Every screen fills the middle row and scrolls independently. */
.screen {
  overflow-y: auto;
  background: var(--shop-bg);
  scrollbar-width: none;
}
.screen::-webkit-scrollbar { display: none; }
#screen-chat { background: var(--shop-bg); }

/* ---------------------------------------------------------------- statusbar --- */

.statusbar {
  height: 50px;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 0 26px;
  color: var(--ink);
}
.time { font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }

.island {
  width: 106px;
  height: 30px;
  border-radius: 16px;
  background: #000;
}

.indicators {
  justify-self: end;
  display: flex;
  align-items: center;
  gap: 6px;
}
.indicators svg { fill: currentColor; height: 12px; }
.indicators .signal { width: 18px; }
.indicators .wifi { width: 16px; }
.indicators .battery { width: 26px; }

/* ------------------------------------------------------------------ header --- */

header {
  display: grid;
  grid-template-columns: 40px 1fr 40px;
  align-items: center;
  gap: 8px;
  padding: 6px 18px 12px;
}

/* Logo slot: drop a file at public/logo.png and it replaces the wordmark. */
.brand {
  display: grid;
  place-items: center;
  text-align: center;
  font-family: var(--font-head);
  font-size: 19px;
  font-weight: 700;
  /* The wordmark is set the way the shopfront sets it: all caps, tight. */
  text-transform: uppercase;
  letter-spacing: -0.01em;
  color: var(--ink);
  /* Tapping the wordmark returns to home from anywhere. */
  cursor: pointer;
}
.brand .glass { font-size: 17px; }
/* Whole artwork, letterboxed rather than cropped, so dropping in a different
   logo needs no per-file offsets. --logo-ratio is width/height of the art;
   `contain` keeps it honest if the real file differs. */
.brand-logo {
  /* 34px keeps the logo inside the 36px icon-button row, so the header
     doesn't grow, while filling the middle column properly. */
  --logo-h: 34px;
  --logo-ratio: 3.662;
  height: var(--logo-h);
  width: calc(var(--logo-h) * var(--logo-ratio));
  max-width: 100%;
  background-image: var(--logo-src, url("/logo.png"));
  background-repeat: no-repeat;
  background-size: contain;
  background-position: center;
}
.brand-logo[hidden] { display: none; }

.icon-btn {
  position: relative;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.icon-btn svg { width: var(--icon); height: var(--icon); fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }

/* Connection state is conveyed by the call button itself: outlined black
   phone when idle, filled black hang-up while live. */

/* --------------------------------------------------------------- transcript --- */

#screen-chat { display: flex; flex-direction: column; overflow: hidden; }

#transcript {
  flex: 1;
  overflow-y: auto;
  padding: 6px 16px 16px;
  display: flex;
  flex-direction: column;
  gap: 7px;
  scrollbar-width: thin;
  scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
}
#transcript::-webkit-scrollbar { width: 6px; }
#transcript::-webkit-scrollbar-thumb { background: rgba(0, 0, 0, 0.18); border-radius: 3px; }

.row {
  display: flex;
  align-items: flex-end;
}
.row.user { justify-content: flex-end; }

.bubble {
  max-width: 88%;
  /* Half the leading of the 1.5 default — the gap between lines, not the glyphs. */
  line-height: 1.25;
  padding: 13px 16px;
  border-radius: 18px;
  background: var(--bubble);
  color: var(--ink);
  border: 1px solid var(--hairline);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.bubble p { margin: 0; }

/* On a light transcript the two speakers separate by inversion rather than by
   colour: the shopper's own turns are the black ones. */
.row.user .bubble {
  background: var(--brand);
  border-color: var(--brand);
  color: #fff;
}

.row.system {
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
  font-size: 12.5px;
  color: var(--muted);
  padding: 2px 20px;
}

/* --------------------------------------------------------------------- card --- */

.card {
  /* Fixed width, not max-width: while the image is still generating the card
     has little content and would otherwise shrink to a narrow column, then
     jump wider when the picture and product strip arrive. */
  width: 92%;
  max-width: 92%;
  padding: 16px;
  border-radius: 20px;
  background: var(--brand-deep);
  color: #fff;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.18);
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.card-head { font-family: var(--font-head); font-size: 19px; font-weight: 700; text-transform: uppercase; letter-spacing: 0; }

/* Direct children only: the product cards in the shop strip live inside .card
   too, and must not inherit the cocktail photo's crop. */
.card > img,
.card > .holder {
  width: 100%;
  /* 5:3 rather than 4:3 — at the same width that is exactly 20% less height. */
  aspect-ratio: 5 / 3;
  border-radius: 14px;
  border: 3px solid #fff;
}
.card > img { display: block; object-fit: cover; }

.card-text { display: flex; flex-direction: column; gap: 3px; }

.card-title {
  margin: 0;
  font-size: 13px;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
}
/* Breathing room above a second title, but not above the first. */
.card-title + * { margin-bottom: 4px; }
.card-desc + .card-title,
.ingredients + .card-title { margin-top: 6px; }

.card-desc { margin: 0; font-size: 14px; line-height: 1.22; color: rgba(255, 255, 255, 0.92); }

.ingredients,
.method {
  margin: 0;
  font-size: 14px;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.92);
}
.ingredients { padding: 0; list-style: none; }
.method { padding-left: 18px; }
.method li { padding-left: 2px; }
.method li + li { margin-top: 3px; }

/* Product strip inside the mixologist card. Sits within the card's own padding
   so it insets equally on both sides, matching the text above it. */
.card-shop {
  display: flex;
  gap: 10px;
  margin: 6px 0 0;
  padding: 0 0 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.card-shop::-webkit-scrollbar { display: none; }
.card-shop .card-product {
  flex: none;
  width: 152px;
  scroll-snap-align: start;
  color: var(--ink);
}
.card-shop .card-body { padding: 10px; }
.card-shop .card-body strong { font-size: 14.5px; }
.card-shop .sub { font-size: 12.5px; }
.card-shop .rating { font-size: 12px; gap: 4px; }
.card-shop .price { font-size: 17px; }
.card-shop .plus-btn { width: 32px; height: 32px; font-size: 19px; }
.card-shop .heart { width: 28px; height: 28px; top: 8px; right: 8px; }
.card-shop .heart svg { width: 16px; height: 16px; }

.holder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.85);
  background: rgba(0, 0, 0, 0.22);
}
.holder small { color: rgba(255, 255, 255, 0.82); max-width: 85%; text-align: center; line-height: 1.4; }
.holder.error { color: rgba(255, 255, 255, 0.82); }

/* While the image generates, the barman fills the same box the finished photo
   will occupy, so nothing shifts when it swaps in. */
.holder.loading {
  position: relative;
  overflow: hidden;
  justify-content: flex-end;
  padding-bottom: 12px;
}

.holder.loading video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Caption sits over the footage, with a scrim so it stays legible against
   whatever frame is showing. */
.holder.loading span {
  position: relative;
  z-index: 1;
  padding: 4px 12px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(3px);
}

/* No holding footage for this tool: centre the caption on the panel instead of
   sitting it at the bottom of a video that isn't there. */
.holder.loading.no-clip {
  justify-content: center;
  padding-bottom: 0;
}
.holder.loading.no-clip span { background: none; backdrop-filter: none; }

/* The finished image rises over the still-playing video rather than snapping
   in. Duration is mirrored by FADE_MS in chat.js. */
.holder.swap {
  position: relative;
  overflow: hidden;
  padding: 0;
  /* Card colour, not black: if a frame ever slips through between the video
     and the image, it reads as the card rather than a flash. */
  background: var(--brand-deep);
}

.holder.swap video,
.holder.swap img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity 1300ms ease;
}

/* The image starts hidden and is revealed once it has decoded, so the fade
   never rises to a blank frame. */
.holder.swap img { opacity: 0; }
.holder.swap img.shown { opacity: 1; }
.holder.swap video.gone { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .holder.swap video,
  .holder.swap img { transition: none; }
}

/* ----------------------------------------------------------------- composer --- */

#composer {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px 20px;
}

.pill {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 52px;
  padding: 0 14px;
  border-radius: 26px;
  background: #fff;
  border: 1px solid var(--hairline);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.pill svg { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* Sits inside the pill, left of the field, the way the send button sits right
   of it — an upload is an input to the conversation, not a separate action. */
.attach {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--icon);
  height: var(--icon);
  color: var(--ink);
  cursor: pointer;
}
.attach svg {
  width: var(--icon);
  height: var(--icon);
  stroke: currentColor;
  stroke-width: 1.9;
}

#text-input {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: none;
  font: inherit;
  font-size: 15px;
  color: var(--ink);
  background: transparent;
}
#text-input::placeholder { color: #9a9b9b; }

.send {
  display: grid;
  place-items: center;
  flex: none;
  width: var(--icon);
  height: var(--icon);
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--brand);
  cursor: pointer;
}
.send svg { width: var(--icon); height: var(--icon); stroke: currentColor; }

.call {
  position: relative;
  flex: none;
  width: 52px;
  height: 52px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: var(--brand);
  cursor: pointer;
  /* Outlined rather than filled, so the live state below can invert it. */
  box-shadow: inset 0 0 0 1.5px var(--brand), 0 1px 3px rgba(0, 0, 0, 0.06);
  transition: background 0.15s, color 0.15s, transform 0.15s;
}
.call svg { width: var(--icon); height: var(--icon); fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.call:hover { transform: scale(1.04); }
/* Live call inverts the button into a filled hang-up. */
.call[data-on="true"] { background: var(--brand); color: #fff; }
.call[data-on="true"] svg { transform: rotate(135deg); }

/* ============================================================== shop screens === */

.section-title {
  margin: 18px 0 12px;
  font-family: var(--font-head);
  font-size: 22px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.screen { padding: 0 16px 20px; }
.screen-product { padding: 0; }

.empty { margin: 24px 4px; color: var(--muted); font-size: 14px; text-align: center; }

/* ------------------------------------------------------------------- hero --- */

.hero {
  position: relative;
  display: block;
  width: 100%;
  margin-top: 14px;
  padding: 0;
  border: 0;
  border-radius: 18px;
  overflow: hidden;
  aspect-ratio: 16 / 11;
  text-align: left;
  cursor: pointer;
  color: #fff;
  /* Sits behind /hero.mp4 and shows through until the first frame paints, so
     it stays a brand-coloured card rather than a black box on a slow load. */
  background: linear-gradient(135deg, #3a3a3a 0%, #1b1b1b 55%, #000 100%);
}
/* Looping video sits behind the scrim. Muted and playsinline, or mobile
   browsers refuse to autoplay it. */
.hero video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border: 0;
}
.hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(0, 0, 0, 0.05) 30%, rgba(0, 0, 0, 0.78) 100%);
}
.hero-copy { position: absolute; z-index: 2; left: 20px; right: 20px; bottom: 18px; }
.hero-copy h2 { margin: 0 0 4px; font-family: var(--font-head); font-size: 25px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.01em; }
.hero-copy p { margin: 0; font-size: 14.5px; line-height: 1.3; color: rgba(255, 255, 255, 0.92); }

/* ---------------------------------------------------------------- costs --- */

/* Three columns so the amounts form a straight right edge however long the
   material names are. The note column absorbs the slack. */
.costs { list-style: none; margin: 0 0 4px; padding: 0; }
.costs li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "label amount" "note amount";
  align-items: baseline;
  column-gap: 10px;
  padding: 6px 0;
  border-bottom: 1px solid var(--hairline);
}
.cost-label  { grid-area: label; font-size: 14px; }
.cost-note   { grid-area: note; font-size: 12px; color: var(--muted); }
.cost-amount {
  grid-area: amount;
  align-self: center;
  font-size: 14px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.costs .cost-total {
  border-bottom: 0;
  border-top: 2px solid var(--ink);
  margin-top: 2px;
  padding-top: 8px;
}
.cost-total .cost-label { font-weight: 700; }
.cost-total .cost-amount { font-size: 16px; }

/* --------------------------------------------------------------- products --- */

.grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }

.card-product {
  background: var(--card);
  border-radius: 16px;
  overflow: hidden;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06);
}

.card-media { position: relative; }
.card-body { padding: 12px; display: flex; flex-direction: column; gap: 2px; }
.card-body strong { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.sub { color: var(--muted); font-size: 13.5px; line-height: 1.25; }

.thumb {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  padding: 14px;
}
/* 88% rather than 100%: the cut-out shots sit better with breathing room. */
.thumb img { max-width: 88%; max-height: 88%; object-fit: contain; }
/* Real photography is cut out on white, so drop the category tint behind it. */
.thumb.has-photo { background: #fff !important; }
/* The glyph is a placeholder; a real photo loading next to it wins. */
.thumb img + .pack { display: none; }
.pack { height: 62%; width: auto; }
.thumb.big { aspect-ratio: 4 / 3; border-radius: 18px; }

.rating { display: flex; align-items: center; gap: 6px; font-size: 13.5px; color: var(--ink); margin-top: 2px; }
.stars { color: var(--star); letter-spacing: 0.5px; }

.price-row { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; }
.price { font-family: var(--font-head); font-size: 20px; font-weight: 700; letter-spacing: -0.01em; }

.plus-btn {
  flex: none;
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}

.heart {
  position: absolute;
  top: 10px;
  right: 10px;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #fff;
  color: var(--heart);
  cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
}
/* Outline by default, solid once favourited — same glyph as the tab bar. */
.heart svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.heart.on svg { fill: currentColor; }
.heart.inline { position: static; box-shadow: none; background: transparent; width: 26px; height: 26px; }
.heart.inline svg { width: 24px; height: 24px; }
.heart.floating { top: 16px; right: 16px; }

/* ------------------------------------------------------------ search rows --- */

.search-field {
  width: 100%;
  margin-top: 14px;
  padding: 16px 18px;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 14px;
  outline: none;
}
.search-field::placeholder { color: #9a9b9b; }

.chips { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 16px; }
.chip {
  flex: 1 1 28%;
  padding: 11px 8px;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--hairline);
  border-radius: 999px;
  cursor: pointer;
}
.chip.on { background: var(--accent); border-color: var(--accent); color: #fff; }

.rows { display: flex; flex-direction: column; gap: 10px; }

.row-product {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 10px;
  background: var(--card);
  border-radius: 14px;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.row-product .thumb { width: 62px; aspect-ratio: 1; padding: 7px; border-radius: 10px; flex: none; }
.row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.row-body strong { font-size: 16.5px; font-weight: 700; letter-spacing: -0.01em; }
.row-body .price { font-size: 18px; margin-top: 2px; }
.qty-tag { font-weight: 700; color: var(--muted); }

/* ------------------------------------------------------------------- cart --- */

.cart-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px 10px 10px;
  background: var(--card);
  border-radius: 14px;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.cart-row .thumb { width: 62px; aspect-ratio: 1; padding: 7px; border-radius: 10px; flex: none; }
.cart-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cart-body strong { font-size: 16.5px; font-weight: 700; letter-spacing: -0.01em; }
.cart-row .price { flex: none; font-size: 19px; align-self: center; }

.stepper.small { margin-top: 6px; align-self: flex-start; padding: 0; gap: 4px; border: 0; background: transparent; }
.stepper.small button {
  width: 30px;
  height: 30px;
  border: 1px solid var(--hairline);
  background: var(--card);
  font-size: 17px;
}
.stepper.small span { min-width: 20px; font-size: 15px; }

.summary-card {
  margin-top: 14px;
  padding: 16px 18px;
  background: var(--card);
  border-radius: 14px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
.summary-line { display: flex; justify-content: space-between; align-items: baseline; font-size: 16px; color: var(--muted); }
.summary-line + .summary-line { margin-top: 8px; }
.summary-line.total {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--hairline);
  color: var(--ink);
}
.summary-line.total strong { font-family: var(--font-head); font-size: 22px; font-weight: 700; letter-spacing: -0.01em; }

/* The shopfront sets its calls to action as black rectangles in caps, so the
   pill shape is dropped here even though chips and steppers keep theirs. */
.checkout,
.continue {
  width: 100%;
  height: 56px;
  margin-top: 16px;
  border: 0;
  border-radius: 4px;
  color: #fff;
  font: inherit;
  font-family: var(--font-head);
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.checkout { background: var(--accent); }

/* ------------------------------------------------- checkout confirmation --- */

.confirm {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: 70px 24px 0;
}
.tick {
  display: grid;
  place-items: center;
  width: 92px;
  height: 92px;
  border-radius: 50%;
  background: var(--accent);
}
.tick svg { width: 46px; height: 46px; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }
.confirm h2 { margin: 22px 0 6px; font-family: var(--font-head); font-size: 28px; font-weight: 700; text-transform: uppercase; letter-spacing: 0; }
.confirm p { margin: 0; font-size: 16px; color: var(--muted); }
.continue { width: auto; padding: 0 34px; margin-top: 22px; background: var(--brand); }

.account-card {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 16px;
  background: var(--card);
  border-radius: 16px;
}
.account-card strong { display: block; font-size: 17px; }
.account-card span { color: var(--muted); font-size: 14px; }
.avatar-lg {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--shop-bg);
}
.avatar-lg svg { width: 26px; height: 26px; fill: none; stroke: var(--ink); stroke-width: 1.7; stroke-linecap: round; }

/* --------------------------------------------------------- product detail --- */

.screen-product { padding: 14px 16px 20px; }
.product-hero { position: relative; }
.product-info { padding: 18px 2px 0; }
.tag {
  display: inline-block;
  padding: 7px 14px;
  border-radius: 999px;
  /* Outlined, not filled: the detail screen sits on the same grey the pill
     used, so a filled chip would disappear against it. */
  background: #fff;
  border: 1px solid var(--hairline);
  color: var(--ink);
  font-size: 12px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.product-info h2 { margin: 14px 0 2px; font-family: var(--font-head); font-size: 28px; font-weight: 700; text-transform: uppercase; letter-spacing: 0; }
.product-info .sub { font-size: 16px; }
.big-price { margin-top: 16px; font-family: var(--font-head); font-size: 38px; font-weight: 700; letter-spacing: -0.02em; }

.product-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px 20px;
  background: var(--shop-bg);
  border-top: 1px solid var(--hairline);
}
.stepper {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: var(--card);
}
.stepper button {
  width: 38px;
  height: 38px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  font-size: 20px;
  color: var(--ink);
  cursor: pointer;
}
.stepper span { min-width: 22px; text-align: center; font-weight: 700; }
.add-to-cart {
  flex: 1;
  height: 54px;
  border: 0;
  border-radius: 4px;
  background: var(--accent);
  color: #fff;
  font: inherit;
  font-family: var(--font-head);
  font-size: 16px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  cursor: pointer;
}

/* ----------------------------------------------------------------- tabbar --- */

#tabbar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  padding: 12px 14px 20px;
  background: #fff;
  border-top: 1px solid var(--hairline);
}
#tabbar button {
  position: relative;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border: 0;
  border-radius: 50%;
  background: var(--shop-bg);
  color: var(--ink);
  cursor: pointer;
}
#tabbar svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
#tabbar button.active { background: var(--brand); color: #fff; }

.badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--heart);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
/* A brief pop so adding from the product page is visible without navigating. */
.badge.pop { animation: badge-pop 0.32s ease; }
@keyframes badge-pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.45); }
  100% { transform: scale(1); }
}

#detail-header .badge { top: -1px; right: -3px; }

/* ----------------------------------------------------------------- drawer --- */

.drawer-scrim { position: absolute; inset: 0; background: rgba(0, 0, 0, 0.45); z-index: 5; }

.drawer {
  position: absolute;
  inset: 0 auto 0 0;
  z-index: 6;
  width: 78%;
  display: flex;
  flex-direction: column;
  background: #fff;
  transform: translateX(-100%);
  transition: transform 0.22s ease;
}
.drawer.open { transform: translateX(0); }

.drawer-head { padding: 46px 22px 18px; background: var(--brand); color: #fff; }
.drawer-head strong { display: block; font-family: var(--font-head); font-size: 20px; font-weight: 700; text-transform: uppercase; letter-spacing: 0; }
.drawer-head span { font-size: 14px; color: rgba(255, 255, 255, 0.75); }
/* Same crop window as the header logo, just smaller. */
.drawer-logo { --logo-h: 38px; margin-bottom: 6px; }

.drawer-links { flex: 1; display: flex; flex-direction: column; padding: 12px 0; }
.drawer-links button {
  display: flex;
  align-items: center;
  gap: 15px;
  padding: 15px 22px;
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 18px;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}
.drawer-links svg {
  flex: none;
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  color: var(--brand);
}
.drawer-links button:hover { background: var(--shop-bg); }

.drawer-foot { padding: 18px 22px 26px; border-top: 1px solid var(--hairline); }
.drawer-foot strong { display: block; color: var(--heart); font-size: 17px; font-weight: 700; }
.drawer-foot span { font-size: 14px; color: var(--muted); }

/* Was-price on a marked-down product: stacked under the current price rather
   than beside it, so a long pair never squeezes the + button. */
.price {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.05;
}
.price s {
  margin-top: 2px;
  font-size: 0.62em;
  font-weight: 600;
  color: var(--muted);
  text-decoration-thickness: 1px;
}

/* Home rails: horizontal scrollers that bleed to the screen edges, so a
   partially visible card signals there is more to swipe. Favourites keeps the
   two-column .grid. */
.rail {
  display: flex;
  gap: 12px;
  margin: 0 -16px;
  padding: 0 16px 4px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Snap points sit at the padding edge, not the container edge — without this
     the first card snaps flush left and loses the 16px inset. */
  scroll-padding-left: 16px;
  scrollbar-width: none;
}
.rail::-webkit-scrollbar { display: none; }
.rail .card-product {
  flex: none;
  width: 168px;
  scroll-snap-align: start;
}

/* An unordered method list (the event planner's drink types) still wants the
   same indent as the numbered one, just with bullets. */
ul.method { list-style: disc; }
