/* ==========================================================================
   BEANERY — QR menu
   Built phone-first: this page is opened at a table, one-handed, often in
   low light. Density is high (60+ lines), so the paper metaphor survives only
   as a material cue — stock colour, gold rules, leader dots. No heavy frames.
   ========================================================================== */

:root {
  --bg: #F7F1DC;
  --card: #FEFAE0;
  --line: rgba(40, 54, 24, .14);
  --dotline: rgba(40, 54, 24, .3);
  --ink: #283618;
  --ink-soft: #5B6B3E;
  --ink-faint: #94997A;

  --green: #606C38;
  --green-deep: #283618;
  --green-ink: #46531F;
  --gold: #BC6C25;
  --gold-soft: #DDA15E;
  --frame: #1D2712;

  --blob-a: rgba(96, 108, 56, .14);
  --blob-b: rgba(188, 108, 37, .12);

  --display: "Playfair Display", Georgia, serif;
  --script: "Dancing Script", cursive;
  --board: "Oswald", "Arial Narrow", sans-serif;
  --ui: "Manrope", system-ui, -apple-system, "Segoe UI", sans-serif;

  --maxw: 720px;
  --pad: clamp(1.1rem, 5vw, 1.75rem);
  --headH: 58px;
  /* sticky category bar height */

  /* the shop's marble — same crop and tone as the landing page */
  --marble: url("marble.webp");
  --marble-crop: center;
  --marble-zoom: cover;
}

/* dark: a café at night, phone at full brightness in someone's face */
@media (prefers-color-scheme: dark) {
  :root {
    --bg: #171F0F;
    --card: #212C16;
    --line: rgba(245, 239, 217, .13);
    --dotline: rgba(245, 239, 217, .26);
    --ink: #F5EFD9;
    --ink-soft: #C4C09E;
    --ink-faint: #8B8A6C;
    --green: #8FA25E;
    --green-deep: #67793C;
    --green-ink: #E4E8CE;
    --gold: #E2A458;
    --gold-soft: #EFC488;
    --frame: #10150A;
    --blob-a: rgba(143, 162, 94, .16);
    --blob-b: rgba(226, 164, 88, .12);
  }

  /* a full-brightness green header is glare in a dim room — sink it */
  .mhead {
    background:
      radial-gradient(130% 95% at 6% -14%, rgba(251, 247, 239, .08) 0%, transparent 52%),
      linear-gradient(168deg, #202B13 0%, #2A3A19 100%);
  }

  .mhead__title p {
    color: rgba(245, 239, 217, .7);
  }

  .sec--feature {
    background: linear-gradient(158deg, #2A3A19 0%, #212C14 100%);
  }

  .sec--feature .sec__head h2,
  .list--flavours .item__name {
    color: #F5EFD9;
  }
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: hidden;
  width: 100%;
}

body {
  margin: 0;
  width: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--ui);
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1,
h2 {
  margin: 0;
  font-family: var(--display);
  font-weight: 700;
  line-height: 1.08;
  letter-spacing: -.015em;
}

p {
  margin: 0;
}

ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
}

.sprite {
  position: absolute;
  width: 0;
  height: 0;
}

svg {
  width: 100%;
  height: 100%;
}

/* soft brand blobs bleeding under the whole page, echoing the shop's hero,
   plus a faint fixed grain so the cream reads as stock, not a flat fill */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(closest-side, var(--blob-a), rgba(88, 123, 76, 0) 70%) -14% -6%/50vmin 50vmin no-repeat,
    radial-gradient(closest-side, var(--blob-b), rgba(196, 149, 42, 0) 70%) 108% 8%/38vmin 38vmin no-repeat,
    radial-gradient(closest-side, var(--blob-a), rgba(88, 123, 76, 0) 70%) 96% 78%/34vmin 34vmin no-repeat;
}

body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 60;
  pointer-events: none;
  opacity: .035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

:where(a, button, input):focus-visible {
  outline: 2.5px solid var(--green);
  outline-offset: 2px;
  border-radius: 8px;
}

/* ==========================================================================
   HEADER
   ========================================================================== */
.mhead {
  position: relative;
  z-index: 1;
  overflow: hidden;
  /* the radial is the TOP layer, so it must fade to transparent — ending it
     on an opaque colour paints a flat panel over the linear beneath and the
     green never shows. The linear underneath carries green-deep -> --card. */
  background:
    radial-gradient(130% 95% at 6% -14%, rgba(251, 247, 239, .12) 0%, transparent 52%),
    linear-gradient(168deg, var(--green-deep) 0%, var(--card) 78%);
  color: #FBF7EF;
  /* longhand, not shorthand: mixing var(--pad) with literal values in one
     padding shorthand triggers a Chrome layout bug that overflows the page
     horizontally — see the width rules on html/body for the belt-and-braces */
  padding-top: calc(.6rem + env(safe-area-inset-top));
  padding-right: var(--pad);
  padding-bottom: 1.9rem;
  padding-left: var(--pad);
  border-radius: 0 0 34px 34px;
}

/* with the hero and the tile grid gone, this header is the whole opening —
   give it room to breathe once the screen can afford it */
@media (min-width:560px) {
  .mhead {
    padding-bottom: 2.4rem;
  }

  .mhead__title {
    margin-top: 2.1rem;
    max-width: min(60%, 42ch);
  }
}

.mhead::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* the photo is a double-tap toggle, so this layer has to accept taps. It
   sits at z-index 0, under the bar / title / search (all z-index 1), so it
   only ever catches taps that land on the photo itself.
   touch-action:manipulation suppresses the browser's double-tap-to-zoom,
   which would otherwise eat the second tap on a phone. */
.mhead__deco {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: auto;
  touch-action: manipulation;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

/* the cup photo lives behind the text, confined to the right side and
   feathered in with a mask so it reads as part of the green rather than
   a pasted rectangle — a tint on top pulls its colour into the brand green */
.mhead__photo-wrap {
  position: absolute;
  inset: 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(100deg, transparent 0%, transparent 36%, rgba(0, 0, 0, .5) 54%, #000 74%);
  mask-image: linear-gradient(100deg, transparent 0%, transparent 36%, rgba(0, 0, 0, .5) 54%, #000 74%);
}

.mhead__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 76% 40%;
  transition: opacity .22s ease;
}

/* the frappé shot is 3:2 against the cup shot's 1.9:1, so a wide desktop
   header crops it hard vertically. anchoring high keeps the cream and the
   chocolate splash in frame instead of showing a mid-band of bare cup. */
.mhead__photo--alt {
  object-position: 58% 28%;
}

.mhead__photo-wrap::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg, var(--green-deep) 0%, var(--green-deep) 30%, transparent 62%),
    radial-gradient(ellipse 90% 70% at 30% 105%, rgba(14, 18, 7, .6), transparent 62%);
  mix-blend-mode: multiply;
  opacity: .72;
}

.mhead__bar {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: .8rem;
  min-height: 48px;
  animation: mheadRise .6s cubic-bezier(.22, 1, .36, 1) both;
}

.mhead__back {
  width: 40px;
  height: 40px;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(251, 247, 239, .16);
  color: inherit;
  text-decoration: none;
  transition: background .2s ease, transform .2s ease;
}

.mhead__back:hover {
  background: rgba(251, 247, 239, .26);
  transform: translateX(-2px);
}

.mhead__back svg {
  width: 19px;
  height: 19px;
}

.mhead__brand {
  display: flex;
  align-items: center;
  gap: .55rem;
  margin-right: auto;
}

/* 20:26 keeps the monogram's own 504.47:658.02 proportion */
.mhead__b {
  width: 20px;
  height: 26px;
  color: var(--gold-soft);
}

.mhead__brand p {
  font-family: var(--board);
  font-weight: 500;
  letter-spacing: .2em;
  font-size: .82rem;
  line-height: 1.25;
}

.mhead__brand span {
  display: block;
  font-size: .5rem;
  letter-spacing: .3em;
  color: rgba(251, 247, 239, .65);
}

.mhead__open {
  font-family: var(--board);
  font-size: .62rem;
  letter-spacing: .16em;
  text-transform: uppercase;
  background: rgba(251, 247, 239, .18);
  padding: .4rem .7rem;
  border-radius: 999px;
  white-space: nowrap;
}

/* the photo mask fades in across 36%–74%, so the text column stops short of
   it — otherwise the subtitle's tail lands on the bright cup and the cream
   type loses all contrast against it */
.mhead__title {
  position: relative;
  z-index: 1;
  margin-top: 1.5rem;
  max-width: 58%;
}

.mhead__kicker {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--board);
  font-weight: 600;
  font-size: .68rem;
  letter-spacing: .24em;
  text-transform: uppercase;
  color: var(--gold-soft);
  margin-bottom: .6rem;
  animation: mheadRise .6s cubic-bezier(.22, 1, .36, 1) .08s both;
}

.mhead__kicker::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--gold-soft);
  border-radius: 2px;
}

.mhead__title h1 {
  font-size: clamp(2.6rem, 10.5vw, 3.6rem);
  animation: mheadRise .7s cubic-bezier(.22, 1, .36, 1) .14s both;
}

.mhead__title p {
  color: rgba(251, 247, 239, .8);
  font-size: .92rem;
  margin-top: .35rem;
  animation: mheadRise .7s cubic-bezier(.22, 1, .36, 1) .2s both;
}

@keyframes mheadRise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }

  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* search */
.search {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  margin-top: 1.3rem;
  background: var(--card);
  border-radius: 999px;
  padding: .2rem;
  box-shadow: 0 14px 30px -16px rgba(0, 0, 0, .65), 0 1px 0 rgba(255, 255, 255, .5) inset;
  transition: box-shadow .25s ease, transform .25s ease;
  animation: mheadRise .7s cubic-bezier(.22, 1, .36, 1) .28s both;
}

.search:focus-within {
  box-shadow: 0 14px 30px -16px rgba(0, 0, 0, .65), 0 0 0 3px rgba(232, 206, 134, .3);
  transform: translateY(-1px);
}

.search__ico {
  width: 19px;
  height: 19px;
  margin: 0 .3rem 0 .9rem;
  color: var(--ink-faint);
  flex: 0 0 auto;
}

.search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--ui);
  font-size: 16px;
  /* 16px stops iOS zoom on focus */
  padding: .85rem .4rem;
}

.search input::placeholder {
  color: var(--ink-faint);
}

.search input::-webkit-search-cancel-button {
  display: none;
}

.search__clear {
  width: 34px;
  height: 34px;
  flex: 0 0 auto;
  margin-right: .35rem;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 2.5px solid #606C38;
  border-radius: 50%;
  background: #FEFAE0;
  color: #283618;
  display: grid;
  place-items: center;
  cursor: pointer;
}

.search__clear svg {
  width: 15px;
  height: 15px;
}

.search__clear[hidden] {
  display: none;
}

/* ==========================================================================
   STICKY CATEGORY NAV
   ========================================================================== */
.cats {
  position: sticky;
  top: 0;
  z-index: 20;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid var(--line);
}

.cats__track {
  display: flex;
  gap: .4rem;
  overflow-x: auto;
  scrollbar-width: none;
  padding-top: .7rem;
  padding-bottom: .7rem;
  padding-left: var(--pad);
  padding-right: var(--pad);
  max-width: var(--maxw);
  margin: 0 auto;
  scroll-snap-type: x proximity;
  /* this row is now the only navigation on the page, so it has to *look*
     scrollable — the pills dissolve into the gutters instead of being
     guillotined at the viewport edge, which reads as "there is more here" */
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 var(--pad), #000 calc(100% - var(--pad)), transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 var(--pad), #000 calc(100% - var(--pad)), transparent 100%);
}

.cats__track::-webkit-scrollbar {
  display: none;
}

.cat {
  flex: 0 0 auto;
  scroll-snap-align: center;
  text-decoration: none;
  white-space: nowrap;
  font-size: .84rem;
  font-weight: 600;
  color: var(--ink-soft);
  padding: .5rem .9rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  transition: background .32s cubic-bezier(.22, 1, .36, 1), color .32s cubic-bezier(.22, 1, .36, 1),
    border-color .32s ease, box-shadow .32s ease, transform .18s ease;
}

.cat:hover {
  border-color: var(--green);
  color: var(--green);
}

.cat:active {
  transform: scale(.96);
}

.cat.is-on {
  background: var(--green);
  border-color: var(--green);
  color: #FBF7EF;
  box-shadow: 0 8px 18px -10px rgba(44, 66, 39, .6);
}

/* ==========================================================================
   PILL BUTTON (shared) — echoes the shop's own "Get directions" CTA
   ========================================================================== */
.btn-pill {
  display: inline-flex;
  align-items: center;
  gap: .7rem;
  background: var(--green);
  color: #FBF7EF;
  font-family: var(--board);
  font-weight: 600;
  font-size: .76rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  padding: .4rem .4rem .4rem 1.15rem;
  border-radius: 999px;
  text-decoration: none;
  transition: transform .2s ease, box-shadow .2s ease;
}

.btn-pill:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 22px -14px rgba(0, 0, 0, .55);
}

.btn-pill__arrow {
  width: 30px;
  height: 30px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: rgba(251, 247, 239, .2);
  display: grid;
  place-items: center;
}

.btn-pill__arrow svg {
  width: 14px;
  height: 14px;
}

.btn-pill--gold {
  background: var(--gold);
  color: #2A1B0A;
}

.btn-pill--gold .btn-pill__arrow {
  background: rgba(42, 27, 10, .18);
}

/* ==========================================================================
   SECTIONS
   ========================================================================== */
main {
  position: relative;
  z-index: 1;
  max-width: var(--maxw);
  margin: 0 auto;
  padding-top: 2.1rem;
  padding-right: var(--pad);
  padding-bottom: 2rem;
  padding-left: var(--pad);
}

.sec {
  position: relative;
  overflow: hidden;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: 1.5rem 1.3rem 1.2rem;
  margin-bottom: 1rem;
  scroll-margin-top: calc(var(--headH) + 12px);
  box-shadow: 0 1px 0 rgba(38, 36, 31, .05);
  transition: box-shadow .25s ease, transform .25s ease, border-color .25s ease;
}

/* the faintest paper grain — a material cue, not a texture you notice */
.sec::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: .025;
  mix-blend-mode: multiply;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (hover:hover) and (pointer:fine) {
  .sec:hover {
    border-color: rgba(96, 108, 56, .28);
    box-shadow: 0 14px 28px -22px rgba(40, 54, 24, .35);
  }
}

.sec__head {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: .75rem;
}

.sec__icon {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  display: grid;
  place-items: center;
  background: linear-gradient(155deg, var(--green) 0%, var(--green-deep) 100%);
  color: var(--card);
  box-shadow: 0 6px 14px -8px rgba(40, 54, 24, .5), inset 0 1px 0 rgba(255, 255, 255, .2);
}

.sec__icon svg {
  width: 18px;
  height: 18px;
}

.sec__icon--gold {
  background: linear-gradient(155deg, var(--gold-soft) 0%, var(--gold) 100%);
  box-shadow: 0 6px 14px -8px rgba(120, 80, 20, .45), inset 0 1px 0 rgba(255, 255, 255, .28);
}

.sec__head h2 {
  font-family: var(--board);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 1.16rem;
  letter-spacing: .02em;
  position: relative;
  padding-bottom: .4rem;
}

.sec__head h2::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 32px;
  height: 2.5px;
  background: var(--gold);
}

.sec__count {
  margin-left: auto;
  font-family: var(--board);
  font-size: .68rem;
  letter-spacing: .1em;
  color: var(--ink-faint);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: .15rem .5rem;
}

.sec__note {
  position: relative;
  z-index: 1;
  font-size: .8rem;
  color: var(--ink-faint);
  font-style: italic;
  margin-top: .5rem;
}

.sec__note--ar {
  font-style: normal;
  font-size: .86rem;
}

/* ==========================================================================
   PRODUCT CARDS — a horizontally-scrolling row per section, echoing a
   boutique catalogue rather than a paper price list. Native scroll-snap,
   no JS required for touch; a pair of arrow buttons appear for mouse users.
   ========================================================================== */
.cardrow {
  position: relative;
  z-index: 1;
  margin: 1rem -1.3rem 0;
}

.cardrow__track {
  display: flex;
  gap: .9rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  /* left/right bumped past the arrow buttons' own footprint so the first
     and last card get real breathing room instead of sitting flush
     against the section edge, under the floating arrow. Fluid, not a flat
     rem, so it doesn't eat a disproportionate slice of a small phone's
     already-scarce card width the way a fixed inset would. */
  padding: .2rem clamp(1.6rem, 8vw, 2.2rem) .5rem;
}

.cardrow__track::-webkit-scrollbar {
  display: none;
}

/* (an edge-fade overlay lived here — dropped it: it was corrupting the
   first card's text in this environment's renderer, and the always-on
   arrows below already say "there's more" without it) */

/* always on — on a touch phone there is no hover state to reveal them with,
   and a bare card row gives no hint that it scrolls, so the arrows are the
   only affordance a thumb gets. Sized to a real touch target (40px). */
.cardrow__arrow {
  display: flex;
  position: absolute;
  /* centered on the 128px photo tile (track padding-top .2rem + half the tile) */
  top: 67px;
  z-index: 3;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  /* fixed beige fill + green ring, not swapped in dark mode — reads
     as the same physical button in either theme rather than shifting */
  border: 3px solid #606C38;
  background: #FEFAE0;
  color: #283618;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 10px 20px -12px rgba(20, 28, 10, .45);
  transition: transform .2s ease, opacity .2s ease, box-shadow .2s ease;
}

.cardrow__arrow svg {
  position: relative;
  z-index: 1;
  width: 17px;
  height: 17px;
}

/* the row bleeds via negative margin all the way to .sec's own edge, and
   .sec clips (overflow: hidden) right at that edge — a negative offset here
   pushed the circle past it and got sliced off. Keep it non-negative so the
   whole ring stays inside .sec's bounds while still overlapping the card. */
.cardrow__arrow--prev {
  left: 4px;
  transform: translateY(-50%) scaleX(-1);
}

.cardrow__arrow--next {
  right: 4px;
  transform: translateY(-50%);
}

.cardrow__arrow:hover {
  box-shadow:
    0 10px 20px -12px rgba(20, 28, 10, .55),
    0 0 0 3px rgba(96, 108, 56, .3);
}

.cardrow__arrow--prev:hover {
  transform: translateY(-50%) scaleX(-1) scale(1.08);
}

.cardrow__arrow--next:hover {
  transform: translateY(-50%) scale(1.08);
}

.cardrow__arrow:active {
  transform: translateY(-50%) scale(.92);
}

.cardrow__arrow--prev:active {
  transform: translateY(-50%) scaleX(-1) scale(.92);
}

.cardrow__arrow[disabled] {
  opacity: 0;
  pointer-events: none;
}

/* A touch screen never fires :hover, so the ring that makes this button
   read as live would never show. Bake the hover treatment in as the
   default there, scale included, which also gives a thumb a slightly
   bigger target. :active is a class + pseudo-class so it still outranks
   this — the press feedback survives. */
@media (hover:none) {
  .cardrow__arrow {
    box-shadow:
      0 10px 20px -12px rgba(20, 28, 10, .55),
      0 0 0 3px rgba(96, 108, 56, .3);
  }

  .cardrow__arrow--prev {
    transform: translateY(-50%) scaleX(-1) scale(1.08);
  }

  .cardrow__arrow--next {
    transform: translateY(-50%) scale(1.08);
  }
}

.sec--feature .cardrow__arrow {
  /* centered on the larger 140px feature tile */
  top: 73px;
  /* a soft cream halo so the beige button still pops against the
     feature panel's own green backdrop */
  box-shadow:
    0 10px 20px -12px rgba(0, 0, 0, .6),
    0 0 0 3px rgba(254, 250, 224, .35);
}

.sec--feature .cardrow__arrow:hover {
  box-shadow:
    0 10px 20px -12px rgba(0, 0, 0, .6),
    0 0 0 4px rgba(254, 250, 224, .5);
}

.pcard {
  position: relative;
  flex: 0 0 auto;
  width: 128px;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

/* card rise animation removed with the scroll reveal — cards render in place */

/* hairline divider sitting in the .9rem track gap so adjacent cards read as
   separate items. Inset top/bottom so it stays a quiet tick, not a full rule. */
.pcard:not(.is-hidden)+.pcard:not(.is-hidden)::before {
  content: "";
  position: absolute;
  top: 20%;
  bottom: 20%;
  left: calc(-.45rem - .5px);
  width: 1px;
  background: var(--line);
  pointer-events: none;
}

/* the feature panel is dark in both themes, so the light-theme --line
   would all but vanish against it */
.sec--feature .pcard:not(.is-hidden)+.pcard:not(.is-hidden)::before {
  background: rgba(254, 250, 224, .16);
}

/* fixed cream tile regardless of theme — a lit display slab for the photo
   rather than a surface tied to --card, so it still pops against the dark
   panel in dark mode instead of blending into it */
.pcard__photo {
  position: relative;
  width: 128px;
  height: 128px;
  background: #ffffff00;
  border-radius: 18px;
  box-shadow: none;
  display: grid;
  place-items: center;
  transition: transform .32s cubic-bezier(.22, 1, .36, 1), box-shadow .32s ease;
}

/* Every drink is normalised to one on-screen height. The source PNGs are all
   900x900, but the product inside fills wildly different fractions of that
   canvas — a wide cappuccino mug covers 66% of the height, a tall frappe cup
   86% — so object-fit alone left the mugs looking stunted next to the cups.
   --fit-s is a per-image correction measured from each PNG's alpha bounding
   box; the generated block below carries the numbers. #desserts is excluded
   on purpose: those items are flat by nature and normalise on width instead. */
.pcard__photo img {
  --fit-s: 1;
  --fit-x: 0%;
  --fit-y: 0%;
  --fit-hover: 1;
  width: 84%;
  /* an explicit square box, not height: 84% — a percentage height here has no
     definite containing block to resolve against, so the two non-square PNGs
     (sm-ube, sm-blacksesame) fell back to their own aspect ratio and rendered
     ~26% oversized, spilling past the tile */
  aspect-ratio: 1;
  height: auto;
  object-fit: contain;
  /* translate runs before scale, so --fit-x/y stay in unscaled box units and
     re-centre the artwork's bounding box on the tile */
  transform: scale(calc(var(--fit-s) * var(--fit-hover))) translate(var(--fit-x), var(--fit-y));
  filter: drop-shadow(0 7px 8px rgba(40, 54, 24, .18));
  transition: transform .32s cubic-bezier(.22, 1, .36, 1), filter .32s ease;
}

/* --- generated: per-image drink size normalisation --- */
.pcard__photo img[src$="/amricano.webp" i] { --fit-s: 0.936; }
.pcard__photo img[src$="/berry-mojito.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/brew.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/cappuccino.webp" i] { --fit-s: 1.206; }
.pcard__photo img[src$="/caramel-latte.webp" i] { --fit-s: 1.056; --fit-x: -0.056%; --fit-y: 0.889%; }
.pcard__photo img[src$="/cfs-ciminin.webp" i] { --fit-s: 0.931; }
.pcard__photo img[src$="/cfs-pistachio.webp" i] { --fit-s: 0.93; }
.pcard__photo img[src$="/cfs-saffron.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/cfs-ube.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/cfs-vanilla.webp" i] { --fit-s: 0.935; }
.pcard__photo img[src$="/chocolate-milkshake.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/cortado.webp" i] { --fit-s: 0.931; }
.pcard__photo img[src$="/double-espresso.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/frappe-carmel.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/frappe-hazelnut.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/frappe.webp" i] { --fit-s: 0.934; --fit-x: -0.056%; --fit-y: -0.167%; }
.pcard__photo img[src$="/golden-lemon.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/iced-caramel-latte.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/iced-latte.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/iced-spanish-latte.webp" i] { --fit-s: 0.935; }
.pcard__photo img[src$="/icetea-passionfruit.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/latte.webp" i] { --fit-s: 1.008; --fit-x: -0.167%; --fit-y: -0.222%; }
.pcard__photo img[src$="/macchiato.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/match-strawberry.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/matcha-coconut.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/matcha-ube.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/matcha-vanilla.webp" i] { --fit-s: 0.93; }
.pcard__photo img[src$="/matcha.webp" i] { --fit-s: 0.933; --fit-x: -0.167%; --fit-y: 0.111%; }
.pcard__photo img[src$="/mocha.webp" i] { --fit-s: 1.13; }
.pcard__photo img[src$="/mojito.webp" i] { --fit-s: 0.931; }
.pcard__photo img[src$="/orange-juice.webp" i] { --fit-s: 0.931; }
.pcard__photo img[src$="/passion-fruit-iced-tea.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/peach-iced-tea.webp" i] { --fit-s: 0.933; }
.pcard__photo img[src$="/pistachio-milkshake.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/single-espresso.webp" i] { --fit-s: 0.935; }
.pcard__photo img[src$="/SM-BlackSesame.webp" i] { --fit-s: 1.162; --fit-x: -1.757%; --fit-y: -1.984%; }
.pcard__photo img[src$="/sm-saffron.webp" i] { --fit-s: 0.934; }
.pcard__photo img[src$="/sm-ube.webp" i] { --fit-s: 0.9; --fit-x: -0.456%; --fit-y: -0.814%; }
.pcard__photo img[src$="/spanish-latte.webp" i] { --fit-s: 1.043; }
.pcard__photo img[src$="/strawberry-lemonade.webp" i] { --fit-s: 0.931; }
.pcard__photo img[src$="/turkish-coffee.webp" i] { --fit-s: 1.024; --fit-x: -0.056%; --fit-y: -0.167%; }
.pcard__photo img[src$="/vanilla-latte.webp" i] { --fit-s: 0.954; --fit-x: 0%; --fit-y: 0.944%; }
.pcard__photo img[src$="/vanilla-milkshake.webp" i] { --fit-s: 0.935; }
.pcard__photo img[src$="/white-mocha.webp" i] { --fit-s: 1.113; }
/* --- end generated --- */

/* desserts only — a soft all-around gray glow instead of the grounded
   directional shadow the other sections use. Stronger than a first pass
   so it actually reads as different against the cream tile. */
#desserts .pcard__photo img {
  filter: drop-shadow(0 0 10px rgba(80, 80, 80, .55));
}

@media (hover:hover) and (pointer:fine) {
  .pcard:hover .pcard__photo {
    transform: translateY(-5px);
    box-shadow: 0 16px 24px -10px rgba(20, 28, 10, .48);
  }

  /* nudges the shared --fit-hover factor so the hover lift multiplies the
     per-image normalisation instead of overwriting its transform */
  .pcard:hover .pcard__photo img {
    --fit-hover: 1.05;
    filter: drop-shadow(0 14px 16px rgba(40, 54, 24, .3));
  }
}

.pcard__name {
  font-family: var(--ui);
  font-weight: 600;
  font-size: .84rem;
  color: var(--ink);
  line-height: 1.25;
}

.pcard__price {
  font-family: var(--board);
  font-weight: 500;
  font-size: .8rem;
  color: var(--gold);
  letter-spacing: .01em;
}

.pcard__price span {
  font-size: .68rem;
  color: var(--ink-faint);
  font-weight: 400;
  margin-left: .15rem;
}

.pcard__desc {
  font-family: var(--ui);
  font-size: .72rem;
  line-height: 1.4;
  color: rgba(254, 250, 224, .75);
}

.pcard__photo--empty {
  background: transparent;
  box-shadow: inset 0 0 0 1.5px dashed var(--line);
}

.sec--feature .pcard__name {
  color: #FEFAE0;
}

.sec--feature .pcard {
  width: 140px;
}

.sec--feature .pcard__photo {
  width: 140px;
  height: 140px;
}

.list {
  position: relative;
  z-index: 1;
  margin-top: .9rem;
}

.item {
  display: flex;
  align-items: baseline;
  gap: .45rem;
  padding: .6rem 0 .6rem .55rem;
  border-bottom: 1px solid transparent;
  border-radius: 9px;
}

.item+.item {
  border-top: 1px solid var(--line);
}

@media (hover:hover) and (pointer:fine) {
  .item {
    transition: background-color .2s ease, padding-left .2s ease;
  }

  .item:hover {
    background: rgba(96, 108, 56, .08);
    padding-left: 1rem;
  }

  .sec--feature .item:hover {
    background: rgba(254, 250, 224, .09);
  }
}

.item__img {
  flex: 0 0 auto;
  width: 46px;
  height: 46px;
  border-radius: 12px;
  object-fit: cover;
  background: var(--line);
  box-shadow: inset 0 0 0 1px rgba(38, 36, 31, .08);
}

.item__img--empty {
  background: transparent;
  box-shadow: none;
}

.list--pics .item {
  align-items: center;
  gap: .7rem;
}

.item__name {
  flex: 0 1 auto;
  min-width: 0;
  font-weight: 500;
}

.item__dots {
  flex: 1 1 auto;
  min-width: 14px;
  height: .5em;
  border-bottom: 1.5px dotted var(--dotline);
}

.item__price {
  flex: 0 0 auto;
  font-family: var(--board);
  font-weight: 500;
  font-size: 1.02rem;
  color: var(--green-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.new {
  display: inline-block;
  font-family: var(--board);
  font-size: .55rem;
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  vertical-align: middle;
  background: var(--gold);
  color: #FEFAE0;
  padding: .1rem .38rem;
  border-radius: 4px;
  margin-left: .35rem;
}

/* signature block gets the only visual promotion on the page */
.sec--feature {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  background: linear-gradient(158deg, var(--green) 0%, var(--green-deep) 100%);
  color: #FBF7EF;
  box-shadow: 0 14px 30px -20px rgba(44, 66, 39, .9);
}

/* the shop's marble under the green — the signature drink on a stone coaster.
   soft-light keeps luminance (and so the text contrast) essentially intact. */
.sec--feature::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  /* the shop's marble layers on top when present; the gradients underneath
     stand alone as a stone-like sheen if that asset isn't available */
  background-image:
    var(--marble),
    radial-gradient(120% 90% at 15% 0%, rgba(255, 255, 255, .5), transparent 55%),
    radial-gradient(90% 70% at 100% 100%, rgba(0, 0, 0, .35), transparent 60%),
    repeating-linear-gradient(118deg, rgba(255, 255, 255, .05) 0 2px, transparent 2px 14px);
  background-size: var(--marble-zoom), cover, cover, auto;
  background-position: var(--marble-crop), center, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat, repeat;
  /* darkened to mid-grey so soft-light barely moves the green's luminance —
     the veins still read, the white text keeps its contrast ratio */
  filter: saturate(.12) contrast(1.4) brightness(.9);
  mix-blend-mode: soft-light;
  opacity: .85;
}

.sec--feature__mark {
  position: absolute;
  right: -8px;
  bottom: -12px;
  width: 132px;
  height: 112px;
  color: #FBF7EF;
  opacity: .07;
  pointer-events: none;
}

.sec--feature .sec__head h2 {
  color: #FBF7EF;
}

.sec--feature .sec__count {
  color: rgba(251, 247, 239, .75);
  border-color: rgba(251, 247, 239, .3);
}

.sec--feature .sec__note {
  color: rgba(251, 247, 239, .82);
}

.feature__price {
  display: inline-flex;
  align-items: baseline;
  gap: .5rem;
  margin-top: .9rem;
  background: rgba(251, 247, 239, .14);
  border-radius: 999px;
  padding: .4rem 1rem;
  font-family: var(--board);
  font-size: .72rem;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.feature__price b {
  font-size: 1.1rem;
  letter-spacing: .02em;
  color: var(--gold-soft);
}

.list--flavours .item {
  align-items: flex-start;
  gap: .75rem;
}

.list--flavours .item+.item {
  border-top-color: rgba(251, 247, 239, .18);
}

.swatch {
  flex: 0 0 auto;
  width: 13px;
  height: 13px;
  margin-top: .35rem;
  border-radius: 50%;
  background: var(--dot);
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, .3), 0 0 0 2px rgba(251, 247, 239, .22);
}

.list--flavours .item__name {
  display: block;
  font-weight: 600;
}

.list--flavours em {
  display: block;
  font-style: normal;
  font-weight: 400;
  font-size: .8rem;
  color: rgba(251, 247, 239, .85);
  margin-top: .1rem;
}

.sec--addons .item__price {
  color: var(--ink-soft);
}

/* search empty state */
.noresults {
  text-align: center;
  padding: 2.5rem 1rem;
  color: var(--ink-soft);
}

.noresults button {
  display: block;
  margin: .6rem auto 0;
  border: 0;
  background: transparent;
  color: var(--green);
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}

/* ==========================================================================
   FOOTER + BACK TO TOP
   ========================================================================== */
.mfoot {
  position: relative;
  z-index: 1;
  overflow: hidden;
  background: var(--frame);
  color: #CFC9BC;
  text-align: center;
  border-radius: 30px 30px 0 0;
  padding-top: 2.4rem;
  padding-right: var(--pad);
  padding-bottom: calc(2.8rem + env(safe-area-inset-bottom));
  padding-left: var(--pad);
}

.mfoot__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.9rem;
}

.mfoot__script {
  font-family: var(--script);
  font-weight: 700;
  font-size: 1.7rem;
  color: var(--gold-soft);
}

.mfoot__sub {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  font-family: var(--board);
  font-size: .6rem;
  letter-spacing: .34em;
  margin-top: .3rem;
}

.mfoot__sub::before {
  content: "";
  width: 22px;
  height: 2px;
  background: var(--gold);
}

.mfoot__bean {
  width: 32px;
  height: 27px;
  color: var(--gold-soft);
  opacity: .85;
  margin: 0 auto .9rem;
  display: block;
}

.mfoot__aside {
  max-width: 38ch;
}

.mfoot__note {
  font-size: .76rem;
  color: #8D877B;
}

.mfoot__link {
  display: inline-block;
  margin-top: 1.3rem;
  font-size: .82rem;
  font-weight: 600;
  color: #CFC9BC;
  text-decoration: none;
  border-bottom: 1.5px solid var(--gold);
  padding-bottom: .15rem;
}

.mfoot__credit {
  position: relative;
  z-index: 1;
  margin-top: 2.1rem;
  padding-top: 1.3rem;
  border-top: 1px solid rgba(207, 201, 188, .14);
  font-family: var(--ui);
  font-size: .72rem;
  letter-spacing: .02em;
  color: #78726A;
}

.mfoot__credit a {
  color: var(--gold-soft);
  text-decoration: none;
  border-bottom: 1px solid rgba(221, 161, 94, .4);
  padding-bottom: .08rem;
  transition: color .2s ease, border-color .2s ease;
}

.mfoot__credit a:hover {
  color: var(--gold);
  border-bottom-color: var(--gold);
}

.mfoot__drips {
  position: absolute;
  left: 1.4rem;
  bottom: 1.5rem;
  display: flex;
  align-items: flex-end;
  gap: .5rem;
  opacity: .5;
}

.mfoot__drop {
  width: 11px;
  height: 13px;
  color: var(--green);
}

.mfoot__drop--b {
  width: 8px;
  height: 10px;
  opacity: .75;
}

@media (min-width:680px) {
  .mfoot__inner {
    flex-direction: row;
    align-items: flex-start;
    justify-content: space-between;
    max-width: var(--maxw);
    margin: 0 auto;
    text-align: left;
  }

  .mfoot__brand .mfoot__sub {
    justify-content: flex-start;
  }

  .mfoot__aside {
    text-align: right;
    max-width: 34ch;
  }

  .mfoot__bean {
    margin: 0 0 .9rem auto;
  }
}

/* ==========================================================================
   cart: per-item add buttons + order-summary bar + order panel
   ========================================================================== */

.pcard__add,
.item__add {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: grid;
  place-items: center;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 2.5px solid #606C38;
  background: #FEFAE0;
  color: #283618;
  border-radius: 50%;
  box-shadow: 0 6px 14px -5px rgba(20, 28, 10, .5);
  transition: transform .15s ease, box-shadow .15s ease;
}

.pcard__add svg,
.item__add svg {
  width: 13px;
  height: 13px;
}

/* sits inset from the photo's own corner (never negative) — a negative
   offset used to poke past .cardrow__track's overflow-x:auto, which clips
   its own top edge, and got sliced flat */
.pcard__add {
  position: absolute;
  top: 7px;
  right: 7px;
  width: 27px;
  height: 27px;
  z-index: 2;
}

.item__add {
  align-self: center;
  width: 27px;
  height: 27px;
  flex: 0 0 auto;
  margin-left: .5rem;
}

.pcard__add:active,
.item__add:active {
  transform: scale(.88);
}

@media (hover:hover) and (pointer:fine) {

  .pcard__add:hover,
  .item__add:hover {
    transform: scale(1.08);
  }
}

/* a priced item's slot is filled in later — a dashed rule instead of a
   number keeps the row from looking broken until someone sets the price */
.item__price--tbd {
  display: inline-block;
  min-width: 46px;
  height: .9em;
  border-bottom: 1.5px dashed var(--dotline);
}

/* body scroll is locked while the sheet is open — a stray background
   scroll under a modal reads as broken, not polished */
body.cart-open {
  overflow: hidden;
}

/* ---------- order launcher: always visible, invites the first tap ---------- */

.cartbar {
  all: unset;
  box-sizing: border-box;
  position: fixed;
  right: 14px;
  bottom: calc(14px + env(safe-area-inset-bottom));
  z-index: 30;
  display: flex;
  align-items: center;
  gap: .6rem;
  padding: .4rem 1.05rem .4rem .4rem;
  border-radius: 999px;
  cursor: pointer;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 3px solid #606C38;
  background: #FEFAE0;
  box-shadow: 0 14px 30px -12px rgba(20, 28, 10, .5);
  transition: transform .15s ease, box-shadow .15s ease;
}

.cartbar:active {
  transform: scale(.96);
}

.cartbar--bump {
  animation: cartbar-bump .32s cubic-bezier(.22, 1, .36, 1);
}

@keyframes cartbar-bump {
  0% { transform: scale(1); }
  45% { transform: scale(1.08); }
  100% { transform: scale(1); }
}

/* a slow, quiet pulse while the cart is empty — the nudge that says
   "you can order right here", not an alarm */
.cartbar--invite {
  animation: cartbar-invite 2.6s ease-in-out infinite;
}

@keyframes cartbar-invite {
  0%, 100% {
    box-shadow:
      0 14px 30px -12px rgba(20, 28, 10, .6),
      0 0 0 0 rgba(96, 108, 56, .55);
  }
  50% {
    box-shadow:
      0 14px 30px -12px rgba(20, 28, 10, .6),
      0 0 0 11px rgba(96, 108, 56, 0);
  }
}

/* Ordered: the round is with the counter and there is nothing new waiting to
   be sent. Green fill instead of beige, so the bar reads as a receipt at a
   glance rather than as one more thing left to do — and no invite pulse,
   which would be nagging for an order already placed. */
.cartbar--sent {
  border-color: #606C38;
  background: #606C38;
  animation: none;
}

.cartbar--sent .cartbar__icon {
  background: rgba(254, 250, 224, .18);
}

/* direct child only: the tick badge is nested inside .cartbar__icon too, and
   recolouring it here would paint a beige tick onto a beige badge */
.cartbar--sent .cartbar__icon > svg,
.cartbar--sent .cartbar__label {
  color: #FEFAE0;
}

.cartbar--sent .cartbar__total {
  color: #FEFAE0;
  opacity: .85;
}

.cartbar__icon {
  position: relative;
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: rgba(96, 108, 56, .16);
  color: #283618;
  flex: 0 0 auto;
}

.cartbar__icon svg {
  width: 18px;
  height: 18px;
}

.cartbar__badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 4px;
  border-radius: 999px;
  background: #283618;
  color: #FBF7EF;
  font-family: var(--board);
  font-size: .64rem;
  font-weight: 700;
  display: grid;
  place-items: center;
  box-shadow: 0 0 0 2px #606C38;
}

/* the count is replaced by a tick, not zeroed — "0" beside a cart icon reads
   as a failure, a tick reads as the thing that actually happened */
.cartbar__badge--check {
  background: #FEFAE0;
  color: #283618;
}

.cartbar__badge--check svg {
  width: 11px;
  height: 11px;
}

.cartbar__badge[hidden] {
  display: none;
}

.cartbar__text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: 1.25;
}

.cartbar__label {
  font-family: var(--ui);
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: #606C38;
}

.cartbar__total {
  font-family: var(--board);
  font-size: .92rem;
  font-weight: 500;
  color: #283618;
  font-variant-numeric: tabular-nums;
}

.cartbar__total[hidden] {
  display: none;
}

/* ---------- overlay + popup ---------- */

.cart-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(16, 21, 10, .55);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .25s ease;
}

.cart-overlay.is-open {
  opacity: 1;
}

.cart-overlay[hidden] {
  display: none;
}

/* the cart itself: a centred pop-up card, not a sheet — a gradient ring
   (transparent border painted from a border-box layer) instead of a flat
   stroke, plus a bouncy "pop" easing so opening it feels playful */
.cart {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 50;
  width: min(92vw, 430px);
  max-height: min(85vh, 660px);
  display: flex;
  flex-direction: column;
  border: 2.5px solid transparent;
  border-radius: 28px;
  background:
    linear-gradient(var(--card), var(--card)) padding-box,
    linear-gradient(135deg, var(--green) 0%, var(--card) 50%, var(--green-deep) 100%) border-box;
  box-shadow: 0 32px 70px -20px rgba(0, 0, 0, .55), 0 0 0 1px rgba(0, 0, 0, .04);
  padding: 1.1rem var(--pad) calc(1.1rem + env(safe-area-inset-bottom));
  transform: translate(-50%, -50%) scale(.88);
  opacity: 0;
  transition: transform .4s cubic-bezier(.34, 1.56, .64, 1), opacity .22s ease;
}

.cart.is-open {
  transform: translate(-50%, -50%) scale(1);
  opacity: 1;
}

.cart[hidden] {
  display: none;
}

.cart__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: .8rem;
  padding-bottom: .8rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: .2rem;
}

.cart__head__row {
  display: flex;
  align-items: center;
  gap: .5rem;
}

.cart__head__text h2 {
  font-family: var(--display);
  font-size: 1.35rem;
  color: var(--ink);
  line-height: 1.15;
}

.cart__table {
  flex: 0 0 auto;
  font-family: var(--ui);
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--green-ink);
  background: var(--line);
  padding: .2rem .55rem;
  border-radius: 999px;
}

.cart__table[hidden] {
  display: none;
}

.cart__table b {
  font-family: var(--board);
  font-weight: 700;
}

.cart__head__sub {
  display: inline-block;
  font-family: var(--ui);
  font-size: .95rem;
  font-weight: 700;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  color: #283618;
  margin-top: .3rem;
  padding: .28rem .75rem;
  border-radius: 999px;
  background: rgba(254, 250, 224, .55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  box-shadow: inset 0 0 0 1px rgba(254, 250, 224, .6);
}

.cart__close {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 2.5px solid #606C38;
  color: #283618;
  background: #FEFAE0;
  flex: 0 0 auto;
  transition: transform .15s ease;
}

.cart__close:hover {
  transform: scale(1.06);
}

.cart__close svg {
  width: 16px;
  height: 16px;
}

.cart__empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: .3rem;
  padding: 2.6rem 1rem 2.8rem;
  color: var(--ink-faint);
}

.cart__empty[hidden] {
  display: none;
}

.cart__empty__ico {
  width: 40px;
  height: 40px;
  color: var(--ink-faint);
  opacity: .5;
  margin-bottom: .5rem;
}

.cart__empty p {
  font-family: var(--ui);
  font-weight: 600;
  font-size: .95rem;
  color: var(--ink-soft);
}

.cart__empty span {
  font-size: .82rem;
  max-width: 22em;
}

.cart__empty span b {
  color: var(--green-ink);
}

/* The panel now stacks two lists — what is already at the counter, and what
   is being added now — so the scroll moved up to a wrapper around both.
   Scrolling the editable list alone would pin the sent list to the top and
   eat the card's height with it. */
.cart__scroll {
  overflow-y: auto;
  flex: 1 1 auto;
  margin: .3rem 0;
  padding: 0 2px 0 0;
  display: flex;
  flex-direction: column;
  gap: .55rem;
  /* Firefox */
  scrollbar-width: thin;
  scrollbar-color: var(--green) transparent;
}

.cart__scroll[hidden] {
  display: none;
}

/* WebKit/Chromium/Edge — replaces the OS's default arrow-and-track
   scrollbar with a slim themed thumb so it doesn't look like a stray
   system control dropped onto the card */
.cart__scroll::-webkit-scrollbar {
  width: 6px;
}

.cart__scroll::-webkit-scrollbar-track {
  background: transparent;
}

.cart__scroll::-webkit-scrollbar-thumb {
  background: var(--green);
  border-radius: 999px;
}

.cart__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .55rem;
}

.cart__item {
  display: flex;
  flex-direction: column;
  gap: .5rem;
  padding: .7rem .7rem .75rem;
  border-radius: 16px;
  background: var(--bg);
}

@media (hover:hover) and (pointer:fine) {
  .cart__item:hover {
    box-shadow: inset 0 0 0 1px var(--line);
  }
}

.cart__item__top {
  display: flex;
  align-items: center;
  gap: .65rem;
}

.cart__item__media {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  border-radius: 12px;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--card);
  box-shadow: inset 0 0 0 1px var(--line);
}

.cart__item__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 3px;
}

.cart__item__avatar {
  font-family: var(--board);
  font-weight: 500;
  font-size: .95rem;
  color: var(--green-ink);
}

.cart__item__name {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  font-size: .88rem;
  color: var(--ink);
}

.cart__remove {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 2.5px solid #606C38;
  color: #283618;
  background: #FEFAE0;
  flex: 0 0 auto;
  transition: transform .15s ease, box-shadow .15s ease;
}

.cart__remove:hover {
  transform: scale(1.08);
}

.cart__remove svg {
  width: 15px;
  height: 15px;
}

/* No indent by default. On a ~320px phone the 52px indent, plus the
   nowrap unit price, the stepper and the line total, is wider than the
   row: the line total gets clipped and the list picks up a horizontal
   scrollbar. The indent only aligns this row under the name above it —
   decorative, and a small screen has no width to spend on it. Wrapping
   is the backstop for anything narrower still. */
.cart__item__bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .45rem .6rem;
  min-width: 0;
}

/* add-ons attached to a drink render as a quiet sub-list under the
   drink's own row, still inside the same .cart__item box — the drink is
   the root, its add-ons sit indented under it, never their own
   top-level cart row */
.cart__addons {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .3rem;
  margin: -.1rem 0 0 52px;
}

.cart__addons__node {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
}

.cart__addons__name {
  font-size: .78rem;
  color: var(--ink-faint);
  min-width: 0;
}

.cart__addons__price {
  flex: 0 0 auto;
  font-family: var(--board);
  font-size: .76rem;
  color: var(--green-ink);
  white-space: nowrap;
}

/* a customer's typed special request — same indent as the add-ons list
   so it reads as another child of the drink's own box */
.cart__note {
  margin: -.1rem 0 0 52px;
  font-size: .78rem;
  font-style: italic;
  color: var(--ink-faint);
  overflow-wrap: anywhere;
}

/* wide enough that the indent fits alongside everything else */
@media (min-width:400px) {
  .cart__item__bottom {
    flex-wrap: nowrap;
    padding-left: calc(42px + .65rem);
  }
}

.cart__item__unit {
  font-family: var(--board);
  font-size: .74rem;
  color: var(--ink-faint);
  white-space: nowrap;
}

.cart__item__right {
  display: flex;
  align-items: center;
  gap: .7rem;
  margin-left: auto;
}

.cart__qty {
  display: flex;
  align-items: center;
  gap: .1rem;
  background: var(--line);
  border-radius: 999px;
  padding: .15rem;
}

.cart__qty button {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  display: grid;
  place-items: center;
  width: 23px;
  height: 23px;
  border-radius: 50%;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 3px solid #606C38;
  background: #FEFAE0;
  color: #283618;
  transition: transform .15s ease;
}

.cart__qty button:hover {
  transform: scale(1.1);
}

.cart__qty button svg {
  width: 12px;
  height: 12px;
}

.cart__qty span {
  min-width: 1.6em;
  text-align: center;
  font-family: var(--board);
  font-weight: 600;
  font-size: .84rem;
}

.cart__line {
  flex: 0 0 auto;
  min-width: 58px;
  text-align: right;
  font-family: var(--board);
  font-weight: 600;
  font-size: .86rem;
  color: var(--green-ink);
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   already ordered — the rounds already with the counter
   Deliberately quieter than the editable cart above it: no photo, no stepper,
   no remove. The kitchen has these, so every control here would be a promise
   the page cannot keep. A left rule and a check mark say "done", not "gone".
   ========================================================================== */

.cart__prev {
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.cart__prev[hidden] {
  display: none;
}

.cart__prev__title {
  display: flex;
  align-items: center;
  gap: .38rem;
  font-family: var(--ui);
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--green-ink);
}

.cart__prev__title svg {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
}

.cart__prev__list {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .45rem;
}

.cart__order {
  border-radius: 16px;
  padding: .6rem .7rem .65rem;
  background: var(--bg);
  border-left: 3px solid var(--green);
  opacity: .92;
}

.cart__order__head {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  padding-bottom: .45rem;
  margin-bottom: .45rem;
  border-bottom: 1px dashed var(--line);
}

.cart__order__label {
  font-family: var(--board);
  font-weight: 600;
  font-size: .8rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--ink);
}

.cart__order__time {
  font-size: .72rem;
  color: var(--ink-faint);
}

.cart__order__sum {
  margin-left: auto;
  font-family: var(--board);
  font-weight: 600;
  font-size: .8rem;
  color: var(--green-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

/* one sent line — shared by the receipt and the list above, because the two
   are the same fact shown twice and must never disagree */
.cart__sent {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .38rem;
}

.cart__sent__line {
  display: flex;
  align-items: baseline;
  gap: .5rem;
}

.cart__sent__qty {
  flex: 0 0 auto;
  min-width: 1.9em;
  font-family: var(--board);
  font-weight: 600;
  font-size: .8rem;
  color: var(--green-ink);
  font-variant-numeric: tabular-nums;
}

.cart__sent__body {
  flex: 1 1 auto;
  min-width: 0;
}

.cart__sent__name {
  font-size: .84rem;
  font-weight: 600;
  color: var(--ink);
  overflow-wrap: anywhere;
}

.cart__sent__addons {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .16rem;
  margin-top: .16rem;
}

.cart__sent__addons li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .5rem;
  font-size: .74rem;
  color: var(--ink-faint);
}

.cart__sent__plus {
  flex: 0 0 auto;
  font-family: var(--board);
  color: var(--green-ink);
  white-space: nowrap;
}

.cart__sent__note {
  margin-top: .16rem;
  font-size: .74rem;
  font-style: italic;
  color: var(--ink-faint);
  overflow-wrap: anywhere;
}

.cart__sent__price {
  flex: 0 0 auto;
  min-width: 54px;
  text-align: right;
  font-family: var(--board);
  font-weight: 600;
  font-size: .82rem;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* between rounds: nothing in the cart, but plenty on the table. The big
   empty-cart illustration would be a lie here, so this replaces it. */
.cart__resume {
  padding: .1rem .2rem .3rem;
  font-size: .8rem;
  line-height: 1.5;
  color: var(--ink-faint);
}

.cart__resume[hidden] {
  display: none;
}

.cart__resume b {
  color: var(--green-ink);
}

/* ==========================================================================
   the two-tab strip — sent rounds on one side, the round being built on the
   other. Echoes the category pills at the top of the page rather than
   inventing a second switch language for the same gesture.
   ========================================================================== */

/* sticky: a long sent list would otherwise scroll the way back to the other
   tab off the top of the panel */
.cart__tabs {
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  gap: .4rem;
  padding: .15rem 0 .55rem;
  background: var(--card);
}

.cart__tabs[hidden] {
  display: none;
}

.cart__tab {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .35rem;
  white-space: nowrap;
  padding: .5rem .7rem;
  border-radius: 999px;
  border: 1px solid var(--line);
  font-family: var(--ui);
  font-size: .78rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: background .32s cubic-bezier(.22, 1, .36, 1), color .32s cubic-bezier(.22, 1, .36, 1),
    border-color .32s ease, box-shadow .32s ease;
}

.cart__tab svg {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
}

/* the long label goes before the count does — on a narrow phone the number
   is the part that still has to be readable */
.cart__tab > span:first-of-type {
  overflow: hidden;
  text-overflow: ellipsis;
}

.cart__tab.is-on {
  background: var(--green);
  border-color: var(--green);
  color: #FBF7EF;
  box-shadow: 0 8px 18px -10px rgba(44, 66, 39, .6);
}

.cart__tab__n {
  flex: 0 0 auto;
  min-width: 1.35em;
  padding: 0 .3em;
  border-radius: 999px;
  background: var(--line);
  font-family: var(--board);
  font-size: .72rem;
  font-weight: 700;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

.cart__tab.is-on .cart__tab__n {
  background: rgba(251, 247, 239, .22);
  color: #FBF7EF;
}

@media (hover:hover) and (pointer:fine) {
  .cart__tab:not(.is-on):hover {
    border-color: var(--green);
    color: var(--green-ink);
  }
}

.cart__new[hidden],
.cart__prev__title[hidden] {
  display: none;
}

/* ==========================================================================
   the receipt — shown once, the moment an order reaches the counter
   ========================================================================== */

.cart__done {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  overflow-y: auto;
  flex: 1 1 auto;
  margin: .3rem 0 0;
  padding: .4rem .1rem 0;
  scrollbar-width: thin;
  scrollbar-color: var(--green) transparent;
}

.cart__done[hidden] {
  display: none;
}

.cart__done:focus {
  outline: none;
}

.cart__done::-webkit-scrollbar {
  width: 6px;
}

.cart__done::-webkit-scrollbar-thumb {
  background: var(--green);
  border-radius: 999px;
}

.cart__done__mark {
  align-self: center;
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 3px solid #606C38;
  background: #FEFAE0;
  color: #283618;
  box-shadow: 0 12px 24px -12px rgba(40, 54, 24, .55);
  animation: cart-done-pop .45s cubic-bezier(.34, 1.56, .64, 1) both;
}

.cart__done__mark svg {
  width: 24px;
  height: 24px;
  /* the tick draws itself in, so the confirmation reads as something that
     just happened rather than a state that was always there */
  stroke-dasharray: 30;
  stroke-dashoffset: 30;
  animation: cart-done-tick .38s .18s ease-out forwards;
}

@keyframes cart-done-pop {
  from {
    transform: scale(.4);
    opacity: 0;
  }

  to {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes cart-done-tick {
  to {
    stroke-dashoffset: 0;
  }
}

.cart__done__title {
  margin-top: .7rem;
  text-align: center;
  font-family: var(--display);
  font-size: 1.3rem;
  color: var(--ink);
}

.cart__done__sub {
  margin-top: .2rem;
  text-align: center;
  font-size: .84rem;
  color: var(--ink-soft);
}

.cart__done__list {
  margin-top: 1.05rem;
  padding: .7rem .8rem;
  border-radius: 16px;
  background: var(--bg);
  border-left: 3px solid var(--green);
}

.cart__done__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: .7rem;
  padding: .1rem .2rem;
  font-family: var(--ui);
}

.cart__done__total span {
  font-size: .86rem;
  color: var(--ink-soft);
}

.cart__done__total b {
  font-family: var(--board);
  font-size: 1.25rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.cart__done__total b small {
  font-size: .66rem;
  font-weight: 400;
  color: var(--ink-faint);
  margin-left: .15rem;
}

/* the way back to the menu. Outlined, not filled: the loud button on this
   screen has already been pressed. */
.cart__more {
  all: unset;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: 100%;
  cursor: pointer;
  margin-top: 1rem;
  padding: .9rem;
  border-radius: 16px;
  border: 2.5px solid var(--green);
  color: var(--green-ink);
  background: transparent;
  font-family: var(--ui);
  font-weight: 600;
  font-size: .92rem;
  transition: transform .15s ease, background .2s ease;
}

.cart__more--foot {
  margin-top: 0;
}

.cart__more[hidden] {
  display: none;
}

.cart__more:active {
  transform: scale(.98);
}

@media (hover:hover) and (pointer:fine) {
  .cart__more:hover {
    background: var(--line);
  }
}

/* ==========================================================================
   footer sums — two subtotals that never merge into one list, and the single
   number the guest actually settles
   ========================================================================== */

.cart__sum {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: .6rem;
  padding: .18rem .2rem;
  font-family: var(--ui);
  font-size: .82rem;
  color: var(--ink-faint);
}

.cart__sum[hidden] {
  display: none;
}

.cart__sum b {
  font-family: var(--board);
  font-weight: 600;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* the first sum already carries the rule above it, so the total drops its
   own — two hairlines a few pixels apart just look like a mistake */
.cart__sums:has(.cart__sum:not([hidden])) .cart__sum:first-child {
  border-top: 1px solid var(--line);
  padding-top: .6rem;
  margin-top: .45rem;
}

.cart__sums:has(.cart__sum:not([hidden])) .cart__total {
  border-top: 0;
  padding-top: .35rem;
}

.cart__foot {
  padding-top: .3rem;
  flex: 0 0 auto;
}

.cart__foot[hidden] {
  display: none;
}

.cart__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: .8rem .2rem;
  border-top: 1px solid var(--line);
  font-family: var(--ui);
}

.cart__total span {
  color: var(--ink-soft);
  font-size: .88rem;
}

.cart__total b {
  font-family: var(--board);
  font-size: 1.4rem;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.cart__total b small {
  font-size: .68rem;
  font-weight: 400;
  color: var(--ink-faint);
  margin-left: .15rem;
}

.cart__send {
  all: unset;
  box-sizing: border-box;
  display: grid;
  place-items: center;
  width: 100%;
  cursor: pointer;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 3px solid #606C38;
  background: #FEFAE0;
  color: #283618;
  font-family: var(--ui);
  font-weight: 600;
  font-size: .95rem;
  letter-spacing: .01em;
  padding: .95rem;
  border-radius: 16px;
  box-shadow: 0 12px 24px -12px rgba(40, 54, 24, .55);
  transition: opacity .2s ease, transform .15s ease;
}

.cart__send:active {
  transform: scale(.98);
}

.cart__send:disabled {
  opacity: .65;
  cursor: default;
  transform: none;
}

/* .cart__send sets display: grid, which outranks the UA sheet's
   [hidden] { display: none } — without this the button stays on screen
   after the cart empties into an order */
.cart__send[hidden] {
  display: none;
}

.cart__status {
  margin-top: .35rem;
  font-size: .8rem;
  text-align: center;
  min-height: 1.2em;
  color: var(--ink-soft);
}

.cart__status--error {
  color: #B3261E;
}

/* script reads fine for a two-word tagline (see .mfoot__script) but this
   is a full sentence someone has to actually parse before choosing — keep
   it in the family for tone, just sized and spaced so it stays legible:
   generous size, loose line-height, full ink contrast, no letter-spacing
   fighting the letterforms' own connections. */
.addon-modal .addon-modal__title {
  font-family: var(--script);
  font-weight: 700;
  font-size: clamp(1.4rem, 5.5vw, 1.75rem);
  line-height: 1.35;
  letter-spacing: .01em;
  color: var(--ink);
}

.addon-modal__list {
  list-style: none;
  overflow-y: auto;
  flex: 1 1 auto;
  margin: .6rem 0;
  padding: 0 2px 0 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  /* Firefox */
  scrollbar-width: thin;
  scrollbar-color: var(--green) transparent;
}

.addon-modal__list::-webkit-scrollbar {
  width: 6px;
}

.addon-modal__list::-webkit-scrollbar-track {
  background: transparent;
}

.addon-modal__list::-webkit-scrollbar-thumb {
  background: var(--green);
  border-radius: 999px;
}

.addon-modal__label {
  display: flex;
  align-items: center;
  gap: .65rem;
  padding: .65rem .75rem;
  border-radius: 14px;
  background: var(--bg);
  cursor: pointer;
  box-shadow: inset 0 0 0 1px transparent;
  transition: box-shadow .15s ease, background-color .15s ease;
}

.addon-modal__label:has(.addon-modal__check:checked) {
  background: rgba(96, 108, 56, .1);
  box-shadow: inset 0 0 0 1.5px var(--green);
}

.addon-modal__check {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 21px;
  height: 21px;
  margin: 0;
  border-radius: 7px;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 2.2px solid #606C38;
  background: #FEFAE0;
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: background-color .15s ease;
}

.addon-modal__check::after {
  content: "";
  width: 10px;
  height: 5px;
  border-left: 2.4px solid #FEFAE0;
  border-bottom: 2.4px solid #FEFAE0;
  transform: rotate(-45deg) scale(0);
  transition: transform .15s cubic-bezier(.34, 1.56, .64, 1);
}

.addon-modal__check:checked {
  background: #606C38;
}

.addon-modal__check:checked::after {
  transform: rotate(-45deg) scale(1);
}

.addon-modal__name {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 600;
  font-size: .88rem;
  color: var(--ink);
}

.addon-modal__price {
  flex: 0 0 auto;
  font-family: var(--board);
  font-weight: 500;
  font-size: .84rem;
  color: var(--green-ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.addon-modal__note {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: .35rem;
  margin-bottom: .2rem;
}

.addon-modal__notelabel {
  font-family: var(--ui);
  font-weight: 600;
  font-size: .82rem;
  color: var(--ink-soft);
}

.addon-modal__notelabel span {
  font-weight: 400;
  color: var(--ink-faint);
}

.addon-modal__notefield {
  box-sizing: border-box;
  width: 100%;
  resize: none;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--ui);
  font-size: .86rem;
  padding: .6rem .75rem;
  transition: box-shadow .15s ease, border-color .15s ease;
}

.addon-modal__notefield::placeholder {
  color: var(--ink-faint);
}

.addon-modal__notefield:focus {
  outline: none;
  border-color: var(--green);
  box-shadow: 0 0 0 3px rgba(96, 108, 56, .15);
}

.addon-modal__foot {
  display: flex;
  gap: .6rem;
  padding-top: .5rem;
  flex: 0 0 auto;
}

.addon-modal__add {
  all: unset;
  box-sizing: border-box;
  cursor: pointer;
  text-align: center;
  font-family: var(--ui);
  font-weight: 600;
  font-size: .9rem;
  padding: .85rem .6rem;
  border-radius: 999px;
  transition: transform .15s ease;
}


.addon-modal__add {
  /* the only button in the footer now that cancelling is the X and the
     backdrop — nothing to share the row with */
  flex: 1 1 auto;
  /* fixed beige + green, not swapped in dark mode — see .cardrow__arrow */
  border: 3px solid #606C38;
  background: #FEFAE0;
  color: #283618;
}

.addon-modal__add:active {
  transform: scale(.97);
}

.addon-modal__addtotal {
  font-family: var(--board);
  font-weight: 500;
  margin-left: .3rem;
  opacity: .85;
}

.addon-modal__addtotal:empty {
  margin-left: 0;
}

.cart__status--ok {
  color: var(--green-ink);
  font-weight: 600;
}

/* ==========================================================================
   wider screens: header/search widen and recentre; the menu itself stays
   one column all the way up — see note below on why
   ========================================================================== */
@media (min-width:680px) {
  :root {
    --maxw: 960px;
  }

  /* header content lines up with the menu below it */
  .mhead {
    padding-bottom: 1.9rem;
    border-radius: 0 0 40px 40px;
  }

  .mhead__bar,
  .mhead__title,
  .search {
    max-width: var(--maxw);
    margin-left: auto;
    margin-right: auto;
  }

  /* line the search box up with the left edge of the centred header block */
  .search {
    max-width: 520px;
    margin-left: max(0px, calc((100% - var(--maxw)) / 2));
  }

  .mhead__title h1 {
    font-size: 3.4rem;
  }

  /* One column even at desktop width, deliberately — CSS multi-column text
     flow used to hold this, but it breaks card rows (a scrolling .cardrow
     doesn't reflow the way multi-column expects) mid-card and produces
     inconsistent gaps around spanning elements. A single centred column
     inside the wider --maxw stays simple and never mis-breaks a section. */
}

/* ==========================================================================
   state, motion, print
   ========================================================================== */
.is-hidden {
  display: none !important;
}

/* Live POS state, applied by syncWithPos() in menu.js.

   Sold out and unavailable read the same to a guest — the drink is not coming
   — so they look the same. They are separate classes because they mean
   different things to whoever is debugging: is-soldout is the cafe saying so,
   is-unavailable is this page carrying an id the POS no longer has.

   The add button is removed by the script rather than hidden here, so the item
   is un-orderable even with CSS blocked. */
.pcard.is-soldout,
.pcard.is-unavailable,
.item.is-soldout,
.item.is-unavailable {
  opacity: .45;
  /* Not pointer-events:none on the row: the name and price must stay
     selectable and readable to a screen reader. There is simply no button. */
}

.pcard.is-soldout .pcard__name::after,
.item.is-soldout .item__name::after {
  content: " · sold out";
  font-size: .78em;
  letter-spacing: .04em;
  text-transform: uppercase;
  opacity: .8;
}

/* Opened without scanning a table QR. The menu reads normally; there is
   nothing to add things to, so the cart affordances go away rather than
   offering an order that cannot be placed. */
body.is-browsing .cartbar,
body.is-browsing .pcard__add,
body.is-browsing .item__add {
  display: none !important;
}

@media (prefers-reduced-motion:reduce) {
  html {
    scroll-behavior: auto;
  }

  * {
    transition-duration: .01ms !important;
    animation: none !important;
  }

  /* the confirmation tick is drawn BY its animation, so killing the animation
     above would leave an empty circle where the tick should be — paint it
     complete instead of not at all */
  .cart__done__mark svg {
    stroke-dashoffset: 0;
  }
}

/* staff print a clean copy for the counter */
@media print {

  .cats,
  .search,
  .cartbar,
  .cart,
  .cart-overlay,
  .pcard__add,
  .item__add,
  .mhead__back,
  .mfoot__link,
  .mhead__deco,
  .mfoot__drips,
  .mfoot__bean,
  body::before,
  body::after,
  .mfoot__credit {
    display: none;
  }

  body {
    background: #fff;
    color: #000;
  }

  .mhead {
    background: none;
    color: #000;
    border-radius: 0;
    padding: 0 0 1rem;
  }

  .mhead__brand span,
  .mhead__title p {
    color: #444;
  }

  .mhead__open {
    background: none;
    border: 1px solid #000;
  }

  main {
    display: block;
    max-width: none;
    padding: 0;
  }

  .sec {
    background: none;
    box-shadow: none;
    break-inside: avoid;
    padding: 0 0 1rem;
    margin-bottom: 1rem;
  }

  .sec--feature {
    color: #000;
  }

  .sec--feature .sec__head h2,
  .pcard__desc,
  .sec--feature .sec__note {
    color: #000;
  }

  .sec--feature__mark {
    display: none;
  }

  .cardrow {
    margin: .6rem 0 0;
  }

  .cardrow__arrow {
    display: none;
  }

  .cardrow__track {
    flex-wrap: wrap;
    overflow: visible;
  }

  .pcard:not(.is-hidden)+.pcard:not(.is-hidden)::before {
    display: none;
  }

  .mfoot {
    background: none;
    color: #000;
    border-radius: 0;
  }

  .mfoot__inner {
    display: block;
  }
}

@media (forced-colors:active) {

  .sec,
  .cat,
  .search {
    border: 1px solid;
  }

  .mhead__deco,
  .mfoot__drips,
  body::before,
  body::after {
    display: none;
  }
}

/* ==========================================================================
   Accessibility repairs — hit areas and focus
   ========================================================================== */

/* Every control here is built on `all: unset`, which also strips the focus
   ring, so a keyboard user has no idea where they are. Put a visible one
   back. :focus-visible only, so a mouse click or a thumb tap never shows it
   and nothing about the design changes. Each selector is written out rather
   than grouped under :where() — :where() contributes no specificity and
   would lose to the `all: unset` that caused the problem. */
.search__clear:focus-visible,
.mhead__back:focus-visible,
.cardrow__arrow:focus-visible,
.pcard__add:focus-visible,
.item__add:focus-visible,
.cart__close:focus-visible,
.cart__remove:focus-visible,
.cart__qty button:focus-visible,

/* the two green-filled controls — dark green on green would disappear, so
   these take the cream side of the same fixed pair */
.cartbar:focus-visible,
.cart__tab:focus-visible,
.cart__more:focus-visible,
.cart__send:focus-visible,
.addon-modal__add:focus-visible {
  outline: 3px solid #FEFAE0;
  outline-offset: 3px;
}

/* Hit-area expansion. These buttons are drawn small on purpose, so grow what
   a thumb can hit rather than what the eye sees: the visible ring stays
   23-34px, only the tappable box reaches 44px. Nothing moves or resizes.
   .pcard__add is deliberately absent from the `position: relative` list —
   it is already position: absolute, so it is a containing block, and
   relative would drop it out of its corner. */
.item__add,
.cart__remove,
.cart__close,
.cart__qty button {
  position: relative;
}

.pcard__add::after,
.item__add::after,
.cart__remove::after,
.cart__close::after,
.cart__qty button::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
  /* square, not a 50% circle: a round pad of the same width loses the
     corners, and a diagonal thumb press 22px out lands outside it */
}

/* the stepper's minus and plus sit ~47px apart centre to centre; keep their
   pads under that so they cannot overlap and steal each other's taps */
.cart__qty button::after {
  width: 40px;
}
