/* ═══════════════════════════════════════════════════════════
   Guest ordering — photography led, full-bleed cards.
   Card treatment follows the reference template: image fills the
   frame, type sits on it, everything reveals on scroll.
   ═══════════════════════════════════════════════════════════ */

body{overflow:auto;height:auto;}

/* The guest page's own paper: the warm cream of the 1718 brand, in light
   mode only. Set here, not in tokens.css, so the back office keeps its white
   — this file is only ever loaded by the guest page. */
:root[data-theme="light"]{
  --bg:#F3ECDF;
  --surface:#FBF7F0;
  --surface-2:#F0E8DA;
  --surface-3:#E6DCCB;
  --line:rgba(52,38,16,.10);
  --line-2:rgba(52,38,16,.18);
  --page-grad:
    radial-gradient(1000px 520px at 84% -6%, rgba(17,80,75,.05), transparent 62%),
    linear-gradient(180deg,#F5EFE4 0%,#F1E9DC 100%);
}

/* ══════════════════ HERO — signature drinks ══════════════════
   A coloured stage the whole section takes its background from. Everything
   here is white-on-colour, because the backdrop is a saturated brand tone
   that changes with the drink rather than a photograph. */
.sig{
  position:relative;width:100%;height:100svh;min-height:560px;overflow:hidden;
  --curve-depth:clamp(44px,8vw,110px);
  /* The cup's own gradient, lid colour at the top to base colour at the
     bottom; hero.js sets the two ends per drink. They are registered colours
     (below), which is what lets a gradient cross-fade — an unregistered custom
     property can only snap. The flat colour is the fallback where that is not
     supported. */
  --sig-a:#EE8A36;--sig-b:#C25A22;
  background-color:#D8722C;               /* first slide; hero.js drives it after */
  background-image:linear-gradient(180deg,var(--sig-a) 0%,var(--sig-b) 100%);
  --sig-panel:#F3B98F;
}
@property --sig-a{syntax:'<color>';inherits:true;initial-value:#EE8A36;}
@property --sig-b{syntax:'<color>';inherits:true;initial-value:#C25A22;}

/* Fine noise over the flat colour. Flat fills band on cheap panels and read
   as unfinished; a little grain is what makes them look printed. */
.sig-grain{
  position:absolute;inset:0;z-index:50;pointer-events:none;opacity:.4;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.08'/%3E%3C/svg%3E");
  background-size:200px 200px;background-repeat:repeat;
}

/* The word the drinks stand in front of. Deliberately larger than the
   viewport can hold at small widths — it is texture, not a heading. */
.sig-ghost{
  position:absolute;top:16%;left:0;right:0;z-index:2;
  display:flex;align-items:center;justify-content:center;
  pointer-events:none;user-select:none;
  font-family:'Anton',var(--display),sans-serif;
  font-size:clamp(84px,26vw,360px);font-weight:400;line-height:1;
  letter-spacing:-.02em;text-transform:uppercase;white-space:nowrap;
  color:#fff;opacity:.96;
}

.sig-top{
  position:absolute;top:0;left:0;right:0;z-index:60;
  display:flex;align-items:center;gap:12px;
  padding:20px clamp(16px,4vw,44px);
}
.sig-top .spacer{flex:1;}
.sig-top .theme-btn{
  background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.3);color:#fff;
}
.sig-top .theme-btn:hover{background:rgba(255,255,255,.28);}
/* Membership and Loyalty: labelled pills, the two doors a returning guest
   looks for. The back-office lock stays a small, quiet icon. */
.nav-pill{
  display:inline-flex;align-items:center;gap:7px;height:38px;padding:0 15px 0 12px;flex:none;
  border-radius:999px;border:1px solid rgba(255,255,255,.34);background:rgba(255,255,255,.18);
  color:#fff;font-size:.82rem;font-weight:700;letter-spacing:.01em;white-space:nowrap;
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  transition:background var(--tap) var(--ease),transform var(--tap) var(--ease);
}
.nav-pill:hover{background:rgba(255,255,255,.3);}
.nav-pill:active{transform:scale(.95);}
.nav-pill svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round;}
.sig-top .admin-link{width:30px;height:30px;opacity:.72;}
.sig-top .admin-link svg{width:14px;height:14px;}
.sig-top .admin-link:hover{opacity:1;}
@media (max-width:420px){
  .sig-top{gap:7px;}
  .nav-pill{height:34px;padding:0 11px 0 9px;gap:5px;font-size:.76rem;}
  .nav-pill svg{width:15px;height:15px;}
}
@media (max-width:350px){ .nav-pill svg{display:none;} .nav-pill{padding:0 11px;} }
/* Sign in / the guest's first name, Membership, Loyalty, theme and the lock:
   five things on one phone-width row, so tighter than the rules above. */
@media (max-width:460px){
  .sig-top{gap:5px;padding-left:12px;padding-right:12px;}
  .nav-pill{height:34px;padding:0 9px 0 7px;gap:4px;font-size:.72rem;}
  .nav-pill svg{width:14px;height:14px;}
  .sig-top .theme-btn:not(.admin-link){width:32px;height:32px;flex:none;}
  .sig-top .c-mark{flex:none;}                 /* never squeeze the logo */
  #accountLbl{max-width:68px;overflow:hidden;text-overflow:ellipsis;}
}
/* On the narrowest phones the three labelled pills drop their little icons —
   the words are enough, and the logo keeps its full size. */
@media (max-width:420px){
  .nav-pill svg{display:none;}
  .nav-pill{padding:0 10px;}
}
@media (max-width:340px){
  .sig-top{gap:3px;padding-left:8px;padding-right:8px;}
  .nav-pill{padding:0 7px;font-size:.66rem;}
  .sig-top .c-mark img{width:28px;height:38px;}
}

/* ── the stage ── */
.sig-stage{position:absolute;inset:0;z-index:3;}
/* left/bottom/height are set once by hero.js's layoutBase() and never
   transition — every role's difference is a transform instead (see hero.js),
   so the sweep only ever touches transform and opacity, the two properties a
   compositor can animate without re-running layout on every frame. */
.sig-fig{
  position:absolute;aspect-ratio:.6 / 1;
  will-change:transform,filter,opacity;
  transition:transform 650ms cubic-bezier(.4,0,.2,1),
             filter    650ms cubic-bezier(.4,0,.2,1),
             opacity   650ms cubic-bezier(.4,0,.2,1);
}
.sig-fig img{
  width:100%;height:100%;object-fit:contain;object-position:bottom center;
  filter:drop-shadow(0 30px 50px rgba(0,0,0,.22));
}
/* The 3D cup (hero3d.js) is drawn into this canvas, over the poster image;
   .is-3d is set once its first frame is in, and the poster steps aside.
   The canvas is larger than the figure — 66% taller above it, 14% below and
   20% wider each side (PAD_TOP / PAD_BOT / PAD_X in hero3d.js) — so a lid in
   the air or a cup that is leaning or ducking is never cut off; the cup itself sits exactly where the
   figure is. It takes no pointer events: the figure's own box does, so the
   extra margin never covers a neighbouring cup.
   pan-y: a sideways drag turns the centre cup, a vertical one still scrolls. */
.sig-fig{touch-action:pan-y;}
.sig-fig canvas{
  position:absolute;left:-20%;top:-66%;width:140%;height:180%;opacity:0;pointer-events:none;
}
.sig-fig.is-3d canvas{opacity:1;}
.sig-fig.is-3d img{visibility:hidden;}
.sig-fig.is-3d[style*="z-index: 20"]{cursor:grab;}
.sig-fig.is-3d.is-grabbed{cursor:grabbing;}
/* ── The cup comes with you: the section under the hero ──────────────────
   A tall track (.sig-next) with one screen pinned inside it (.sig-next-pin):
   the words, and — in front of them — the cup that travelled down from the
   hero. With 3D that cup is .sig-travel, a fixed canvas hero3d.js moves with
   the scroll; without it, .sn-cup, the same cup as a picture. */
.sig-next{position:relative;height:125vh;height:125svh;background:var(--bg);--next-ink:#C25A22;--next-tint:#F3B98F;}
.sig-next-pin{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;
  display:flex;align-items:center;justify-content:center;}
.sn-words{margin:0;text-align:center;text-transform:uppercase;
  font-family:'Anton',var(--display),sans-serif;font-weight:400;
  font-size:clamp(40px,10.6vw,176px);line-height:.98;letter-spacing:-.01em;
  color:var(--next-ink);transition:color 650ms cubic-bezier(.4,0,.2,1);}
.sn-words span{display:block;white-space:nowrap;}
.sn-words br{display:none;}
/* on the dark theme the deep end of the cup's colour would sink into the page */
:root[data-theme="dark"] .sn-words{color:var(--next-tint);}
.sn-kick{position:absolute;top:clamp(18px,4vh,44px);margin:0;
  font-family:var(--mono);font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--fg-3);}
.sn-kick-l{left:clamp(16px,4vw,44px);} .sn-kick-r{right:clamp(16px,4vw,44px);}
/* two of the café's own posters, as small tilted cards tucked among the words
   (they are 4:5 with their own lettering, so they are shown whole, not cropped) */
.sn-pill{position:absolute;width:clamp(80px,9.5vw,150px);aspect-ratio:4/5;border-radius:clamp(12px,1.4vw,22px);
  background:var(--next-tint) center/cover no-repeat;box-shadow:0 24px 50px -20px rgba(0,0,0,.45);
  transition:background-color 650ms cubic-bezier(.4,0,.2,1);}
.sn-pill-a{left:clamp(10px,6vw,110px);bottom:9%;rotate:-7deg;background-image:url(../img/next-mornings.jpg);}
.sn-pill-b{right:clamp(10px,6vw,110px);top:11%;rotate:6deg;background-image:url(../img/next-moments.jpg);}
/* the cup as a picture — only until, or instead of, the 3D one */
.sn-cup{position:absolute;left:50%;top:50%;height:70%;translate:-50% -50%;rotate:10deg;
  filter:drop-shadow(0 30px 50px rgba(0,0,0,.22));}
.sig-next.has-3d .sn-cup{visibility:hidden;}
/* The travelling cup. Sized and placed entirely by hero3d.js (a transform);
   above the hero and these words, below the dock, sheets and dialogs. */
.sig-travel{position:absolute;left:0;top:0;z-index:65;pointer-events:none;display:none;
  transform-origin:0 0;will-change:transform;}
.sig-travel.on{display:block;}
/* while its cup is away, the hero's centre figure shows nothing */
.sig-fig.is-away canvas{opacity:0 !important;}
.sig-fig.is-away::after{opacity:0;}
@media (min-width:640px){.sig-travel{filter:drop-shadow(0 30px 50px rgba(0,0,0,.22));}}
@media (max-width:639px){
  /* On a phone the pinned screen is shorter than the window (and pins a
     little below its top), so the words do not leave a screen's worth of
     empty page beneath them before the menu starts. */
  .sig-next{height:104vh;height:104svh;}
  .sig-next-pin{top:8vh;top:8svh;height:84vh;height:84svh;}
  /* the cup flies into this screen from the hero above it (hero3d.js, phones),
     so it must be able to show outside the top edge on the way in */
  .sig-next-pin{overflow:visible;overflow-x:clip;}
  .sn-words{font-size:clamp(52px,19vw,104px);line-height:.96;}
  .sn-words br{display:inline;}
  .sn-cup{height:43%;}
  .sn-pill{width:18vw;} .sn-pill-a{bottom:7%;} .sn-pill-b{top:8%;}
}

/* ── The deck: the four signatures as a stack of cards (core/showcase.js) ──
   Every card sits in the same box; --pos (0 = front) steps the ones behind
   up and to the right. The front card leaves to the left (.is-leaving) and
   is put back at the rear. */
.deck{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);align-items:center;
  gap:clamp(20px,5vw,80px);max-width:1280px;margin:0 auto;padding:clamp(48px,9vw,120px) clamp(16px,4vw,44px);}
.deck-kick{margin:0 0 14px;font-family:var(--mono);font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--fg-3);}
.deck-say h2{margin:0;font-family:'Anton',var(--display),sans-serif;font-weight:400;text-transform:uppercase;
  font-size:clamp(40px,6.4vw,96px);line-height:.98;color:var(--fg);}
.deck-note{margin:18px 0 0;max-width:34ch;color:var(--fg-2);font-size:.95rem;line-height:1.5;}
.deck-ctl{display:flex;gap:10px;margin-top:26px;}
.deck-arrow{width:48px;height:48px;border-radius:50%;border:1.5px solid var(--line-2);background:none;color:var(--fg);
  display:grid;place-items:center;cursor:pointer;transition:background var(--tap) var(--ease),color var(--tap) var(--ease);}
.deck-arrow:hover{background:var(--fg);color:var(--bg);}
.deck-arrow svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.deck-cards{position:relative;width:min(100%,520px);aspect-ratio:.86/1;justify-self:center;
  --dx:clamp(14px,3.2vw,40px);--dy:clamp(12px,2.6vw,32px);
  /* room for the cards stepping away behind the front one */
  margin:calc(var(--dy)*3) calc(var(--dx)*3) 0 0;}
.dk-card{position:absolute;inset:0;display:flex;flex-direction:column;padding:clamp(14px,2.2vw,24px);
  background:var(--surface);border:clamp(5px,.8vw,9px) solid #fff;border-radius:6px;cursor:pointer;
  box-shadow:0 30px 60px -34px rgba(0,0,0,.4);
  transform:translate(calc(var(--pos)*var(--dx)),calc(var(--pos)*var(--dy)*-1));
  transition:transform 420ms cubic-bezier(.3,.9,.3,1),opacity 300ms ease;}
:root[data-theme="dark"] .dk-card{border-color:var(--line-2);}
.dk-card.no-anim{transition:none;}
.dk-card.is-leaving{transform:translate(-62%,6%) rotate(-9deg);opacity:0;}
/* the soft glow of the drink's own colour behind its cup */
.dk-card::before{content:'';position:absolute;inset:14% 12% 22%;border-radius:50%;pointer-events:none;
  background:radial-gradient(closest-side,color-mix(in srgb,var(--dk-a) 34%,transparent),transparent);}
.dk-tag{align-self:flex-start;padding:7px 14px;border-radius:4px;background:var(--surface-2);font-size:.8rem;color:var(--fg-2);}
.dk-bag{position:absolute;top:clamp(14px,2.2vw,24px);right:clamp(14px,2.2vw,24px);width:44px;height:44px;border:none;border-radius:4px;
  background:var(--dk-a);color:#fff;display:grid;place-items:center;cursor:pointer;transition:transform var(--tap) var(--ease);}
.dk-bag:hover{transform:scale(1.08);}
.dk-bag svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.dk-cup{position:relative;flex:1;min-height:0;}
/* out of the flow, so the picture's own 1100px height can never size the card */
.dk-cup img{position:absolute;left:50%;top:50%;height:104%;width:auto;max-width:none;translate:-50% -50%;
  rotate:-11deg;filter:drop-shadow(-18px 26px 28px rgba(0,0,0,.2));
  transition:rotate 500ms cubic-bezier(.3,.9,.3,1),scale 500ms cubic-bezier(.3,.9,.3,1);}
.dk-card[data-pos="0"]:hover .dk-cup img{rotate:-4deg;scale:1.04;}
.dk-foot{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;}
.dk-code{display:inline-block;padding:3px 10px;border:1px solid var(--line-2);border-radius:999px;
  font-family:var(--mono);font-size:.62rem;letter-spacing:.06em;color:var(--fg-3);}
.dk-foot h3{margin:8px 0 0;font-size:clamp(1.1rem,2.2vw,1.7rem);font-weight:600;letter-spacing:-.02em;color:var(--fg);}
.dk-price{text-align:right;white-space:nowrap;}
.dk-price span{display:block;font-size:.72rem;color:var(--fg-3);}
.dk-price b{font-size:clamp(1.1rem,2.2vw,1.6rem);font-weight:500;color:var(--fg);}
.dk-price i{font-style:normal;font-size:.6em;color:var(--fg-3);}
/* behind the front card only the frame shows, as in a real stack */
.dk-card:not([data-pos="0"]) > *{visibility:hidden;}
/* …except the next one while the front card is sliding off it */
.deck-cards.is-shuffling .dk-card[data-pos="1"] > *{visibility:visible;}
@media (max-width:760px){
  .deck{grid-template-columns:1fr;gap:8px;}
  .deck-cards{width:min(100%,400px);justify-self:start;margin-left:0;}
}

.deck[hidden]{display:none;}   /* parked — see the note on #sigDeck in index.html */
/* in the menu's own column: its edges line up with the sections around it */
.deck.in-menu{padding:clamp(8px,2vw,24px) 0 clamp(48px,7vw,86px);max-width:none;}

/* ── The shelf: the last section — a coloured panel all four cups arrive in ──
   Each cup has a resting place (--x1/--y1, its tilt --r) and a place just
   outside the panel it starts from (--x0/--y0): the two in the middle below
   the bottom edge, the two at the sides beyond the left and right edges.
   .is-in (core/showcase.js, when the panel scrolls into view) sends them to
   rest one after another, with a little overshoot so they bounce into place.
   The panel's overflow is what hides them until then. */
.shelf{position:relative;overflow:hidden;margin:clamp(24px,5vw,64px) clamp(10px,2vw,28px) clamp(40px,7vw,96px);
  height:clamp(480px,88vh,840px);border-radius:clamp(20px,2.6vw,36px);color:#fff;
  background:radial-gradient(120% 90% at 50% 100%,#D8722C 0%,#B5501C 46%,#7A3210 100%);}
/* The words sit centred over the row, like the cups beneath them: a small
   label, the heading on balanced lines, one sentence, the button. */
.shelf-say{position:relative;z-index:3;display:flex;flex-direction:column;align-items:center;text-align:center;
  margin:0 auto;padding:clamp(28px,5vw,72px) clamp(20px,4vw,48px) 0;max-width:min(100%,780px);}
.shelf-key{font:500 11px/1 var(--mono,ui-monospace,SFMono-Regular,Menlo,monospace);letter-spacing:.24em;text-transform:uppercase;
  padding:8px 14px;border:1px solid rgba(255,255,255,.35);border-radius:999px;color:#FFE9C6;margin-bottom:clamp(14px,1.8vw,22px);}
.shelf-say h2{margin:0;font-size:clamp(2rem,4.4vw,3.8rem);line-height:1.04;font-weight:600;letter-spacing:-.03em;text-wrap:balance;max-width:14ch;}
.shelf-say p{margin:clamp(12px,1.4vw,18px) 0 0;opacity:.85;font-size:clamp(.9rem,1.3vw,1.05rem);line-height:1.5;max-width:38ch;text-wrap:balance;}
.shelf-go{display:inline-flex;align-items:stretch;margin-top:clamp(18px,2vw,26px);color:#fff;text-decoration:none;font-weight:600;font-size:.9rem;}
.shelf-go span{padding:14px 22px;background:rgba(255,255,255,.18);border-radius:4px 0 0 4px;backdrop-filter:blur(6px);}
.shelf-go i{display:grid;place-items:center;width:48px;background:#F08A3C;border-radius:0 4px 4px 0;transition:background var(--tap) var(--ease);}
.shelf-go:hover i{background:#fff;color:#B5501C;}
.shelf-go svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;}
/* One row of four: the same size, the same distance apart, standing on the
   same line and sunk the same amount below the bottom edge. Sized by WIDTH
   (a share of the panel's), which is what keeps the gaps equal at any
   window size. Only how each one gets there differs. */
.shelf{--cup-w:21%;--sink:30%;}
.shelf-cup{position:absolute;left:var(--at);bottom:0;width:var(--cup-w);height:auto;max-width:none;
  translate:calc(-50% + var(--x0,0%)) calc(var(--sink) + var(--y0,0%));rotate:var(--r0,0deg);
  filter:drop-shadow(0 30px 40px rgba(0,0,0,.3));
  transition:translate 950ms cubic-bezier(.3,1.45,.5,1) var(--d,0ms),rotate 950ms cubic-bezier(.3,1.3,.5,1) var(--d,0ms);}
.shelf.is-in .shelf-cup{translate:-50% var(--sink);rotate:0deg;}
/* the two in the middle: straight up from below the bottom edge */
.shelf-cl{--at:38%;--y0:110%;--d:0ms;}
.shelf-cr{--at:62%;--y0:110%;--d:140ms;}
/* the two at the sides: in from beyond the edges, tipped over as they come, straightening as they land */
.shelf-sl{--at:14%;--x0:-200%;--r0:-28deg;--d:300ms;}
.shelf-sr{--at:86%;--x0:200%;--r0:28deg;--d:420ms;}
@media (max-width:760px){
  /* four across a phone are small cups, so the panel is only as tall as they need */
  /* The panel is as tall as its words plus the row of cups — never a fixed
     height, which on a narrow phone let the button sit on top of the lids.
     The space kept under the words is the cups' own height: each is a
     quarter of the panel wide and 5:3 tall, with a tenth sunk below the edge. */
  .shelf{height:auto;--cup-w:25%;--sink:10%;}
  .shelf-say{padding-bottom:calc(37.5% + 28px);}
  .shelf-sl{--at:13.5%;} .shelf-cl{--at:37.8%;} .shelf-cr{--at:62.2%;} .shelf-sr{--at:86.5%;}
}
@media (prefers-reduced-motion:reduce){
  .shelf-cup,.dk-card,.dk-cup img{transition:none;}
  .shelf-cup{translate:-50% var(--sink);rotate:0deg;}
}

/* What flies out of a tapped cup (heroFx.js): one canvas over the whole
   stage, above the cups, never in the way of a touch. */
.sig-fx{position:absolute;inset:0;width:100%;height:100%;z-index:30;pointer-events:none;}
/* The drop shadow is re-filtered every frame the cup turns — fine on a
   desktop GPU, not worth it on a phone, which keeps the soft ::after shadow. */
@media (min-width:640px){
  .sig-fig.is-3d canvas{filter:drop-shadow(0 30px 50px rgba(0,0,0,.22));}
}
/* Only the two flanking figures are worth a pointer — the centre one is
   already here and the back one is not reachable in a single step. */
.sig-fig[style*="z-index: 10"]{cursor:pointer;}

/* A soft shadow tucked behind the centre cup only — the side and back
   figures are already dimmed by blur, so an extra shadow there just reads as
   smudged. It sits behind the cup image (negative z-index, within the figure's
   own stacking context) and overlaps the base, so the cup itself hides most of
   it and only a soft edge shows past the silhouette — a shadow cast behind the
   object, not a puddle sitting in front of it. */
.sig-fig[style*="z-index: 20"]::after{
  content:'';
  position:absolute;left:50%;bottom:2%;z-index:-1;
  width:64%;height:14%;transform:translateX(-50%);
  background:radial-gradient(ellipse at center,rgba(0,0,0,.4) 0%,rgba(0,0,0,0) 72%);
  filter:blur(6px);pointer-events:none;
}

/* ── what it is ── */
.sig-say{
  position:absolute;left:clamp(16px,4vw,60px);bottom:clamp(20px,5vh,64px);
  z-index:60;max-width:min(360px,72vw);color:#fff;
}
/* The bottom edge bows into an oval as the page scrolls away. Not by changing
   the hero's border-radius — that repainted the whole full-screen hero (its
   blurred cups, its grain) on every scroll frame and made the page stutter.
   Instead a band of the page colour with an oval cut out of it sits over the
   hero's bottom edge and is scaled up with a transform, which the compositor
   moves without painting anything. curveHeroOnScroll() in hero.js drives it,
   and lifts the text, the arrows and SIGNATURE by the same amount (also
   transforms) so nothing is ever covered. */
.sig-curve{position:absolute;left:0;right:0;bottom:-1px;height:calc(var(--curve-depth) + 1px);z-index:55;
  pointer-events:none;transform-origin:50% 100%;transform:scaleY(0);will-change:transform;
  background:radial-gradient(ellipse 50% 100% at 50% 0%,transparent calc(100% - 1.5px),var(--bg) 100%);}
.sig-say,.sig-go,.sig-ghost{will-change:translate;}
.sig-eyebrow{
  font-family:var(--mono);font-size:.6rem;font-weight:500;
  letter-spacing:.22em;text-transform:uppercase;opacity:.75;margin-bottom:8px;
}
.sig-name{
  font-family:'Anton',var(--display),sans-serif;font-weight:400;
  font-size:clamp(30px,5.2vw,52px);line-height:1.02;letter-spacing:-.01em;
  text-transform:uppercase;margin-bottom:10px;white-space:pre-line;
}
.sig-note{
  font-size:.83rem;line-height:1.62;opacity:.9;margin-bottom:14px;
}
.sig-pills{display:flex;gap:7px;flex-wrap:wrap;margin-bottom:16px;}
.sig-pill{
  padding:5px 11px;border-radius:100px;
  background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.26);
  font-family:var(--mono);font-size:.56rem;font-weight:500;
  letter-spacing:.09em;text-transform:uppercase;
}
.sig-pill b{font-weight:700;}

.sig-controls{display:flex;align-items:center;gap:10px;}
.sig-arrow{
  width:42px;height:42px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:transparent;border:2px solid rgba(255,255,255,.85);color:#fff;
  transition:transform 150ms var(--ease),background-color 150ms var(--ease);
}
.sig-arrow:hover{transform:scale(1.08);background:rgba(255,255,255,.14);}
.sig-arrow:active{transform:scale(.94);}
.sig-arrow svg{width:18px;height:18px;stroke:currentColor;fill:none;
  stroke-width:2.25;stroke-linecap:round;stroke-linejoin:round;}

.sig-dots{display:flex;align-items:center;gap:7px;margin-left:6px;}
.sig-dots button{
  width:7px;height:7px;border-radius:50%;padding:0;
  background:rgba(255,255,255,.42);
  transition:width 400ms var(--ease),background-color 400ms var(--ease);
}
.sig-dots button.on{width:22px;border-radius:100px;background:#fff;}

/* ── to the menu ── */
.sig-go{
  position:absolute;right:clamp(16px,4vw,44px);bottom:clamp(20px,5vh,64px);z-index:60;
  display:flex;align-items:center;gap:10px;color:#fff;opacity:.95;
  transition:opacity 200ms var(--ease),transform 200ms var(--ease);
}
.sig-go:hover{opacity:1;transform:translateX(3px);}
.sig-go span{
  font-family:'Anton',var(--display),sans-serif;font-weight:400;
  font-size:clamp(19px,3.6vw,50px);line-height:1;letter-spacing:-.02em;
  text-transform:uppercase;
}
.sig-go svg{width:clamp(19px,3vw,32px);height:clamp(19px,3vw,32px);
  stroke:currentColor;fill:none;stroke-width:2.25;stroke-linecap:round;
  stroke-linejoin:round;}

@media (max-width:640px){
  /* The description is the first thing to go — on a phone the figure and the
     name carry it, and the arrows must stay above the fold. */
  .sig-note{display:none;}
  .sig-say{bottom:16px;max-width:66vw;}
  .sig-go{bottom:16px;}
  .sig-arrow{width:38px;height:38px;}
  .sig-arrow svg{width:16px;height:16px;}
}

@media (prefers-reduced-motion:reduce){
  .sig,.sig-fig,.sig-dots button{transition-duration:1ms !important;}
}

/* ══════════════════ BROWSE + DOCK ══════════════════
   The menu's controls sit beside the food rather than in a bar pinned across
   the top of it. On a wide screen the dock is a rail that follows you down the
   page and lights up whichever section you are reading; narrower, it drops to
   a floating bar inside thumb reach. Either way it never covers the menu. */
/* The rail sits closer to the left edge than the cards do — it is furniture
   rather than content, so it hugs the window while the menu keeps its margin. */
.browse{
  max-width:1480px;margin:0 auto;
  /* A breath between the hero and the first heading — the menu should start,
     not collide with the bottom of the stage. */
  padding:clamp(30px,5vw,64px) clamp(14px,2.4vw,24px) 0 clamp(8px,1.3vw,14px);
  display:grid;grid-template-columns:244px minmax(0,1fr);
  gap:clamp(18px,2.4vw,34px);align-items:start;
}
.browse-main{min-width:0;}

/* Deliberately NOT a scroll container.
 *
 * It was `max-height:100vh; overflow-y:auto` as a guard for short screens, and
 * that quietly broke the sort popover: an overflow value other than visible
 * makes the element clip its absolutely-positioned descendants, so the menu
 * opened inside the rail and was cut away to nothing. Nothing looked wrong —
 * the button just stopped doing anything.
 *
 * With no clipping the rail can simply be as tall as it needs to be; sticky
 * does not crop, so a rail longer than the window is reached by scrolling. */
.dock{
  position:sticky;top:20px;
  z-index:60;align-self:start;
  display:flex;flex-direction:column;gap:12px;
  padding:12px;border-radius:var(--r-lg);
  /* Near-solid, not blurred: on a wide screen nothing ever passes behind the
     rail, and a backdrop blur there was being redone on every scroll frame. */
  background:color-mix(in srgb,var(--surface) 94%,transparent);
  border:1px solid var(--line);
  box-shadow:var(--shadow-sm);
}

/* A centred variant was tried here — `top:50vh` plus a `translateY(-50%)` to
   pull the stuck rail up around the middle of a tall screen. `transform`
   applies unconditionally, though, not only once sticky actually engages, so
   it also yanked the rail up by half its own height while still in normal
   flow — on a tall enough viewport that showed up as the rail overlapping the
   bottom of the hero before the page had even been scrolled. A sticky element
   can't tell CSS "only once you're actually stuck," so the fixed offset stays
   the same at every viewport height instead. */

/* ── search ── */
.dock-search{
  display:flex;align-items:center;gap:9px;flex:none;
  padding:10px 12px;border-radius:100px;
  background:var(--surface-2);border:1px solid transparent;
  transition:border-color var(--tap) var(--ease),background-color var(--tap) var(--ease);
}
.dock-search:focus-within{border-color:var(--accent-line);background:var(--surface);}
.dock-search svg{width:15px;height:15px;flex:none;stroke:var(--fg-3);fill:none;stroke-width:1.9;}
.dock-search input{flex:1;min-width:0;font-size:.86rem;}
.dock-search input::placeholder{color:var(--fg-3);}
.sort-clear{
  width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;
  background:var(--surface-3);color:var(--fg-3);font-size:.6rem;
  transition:background-color var(--tap) var(--ease),color var(--tap) var(--ease);
}
.sort-clear:hover{background:var(--danger);color:#fff;}

/* ── the sections list ──
   Vertical on a rail. The marker on the left is the thing that makes it a
   position indicator rather than a set of buttons: it slides to whichever
   section the page is actually showing. */
/* Every section listed, no inner scroller. The list capped itself at 52vh
   before, which hid the last few categories behind a scrollbar inside a panel
   that was itself scrolling — two nested scrollers for one short list. If the
   whole rail outgrows the window, .dock scrolls; this never does. */
.sort-cats{
  display:flex;flex-direction:column;gap:1px;
}

/* Each entry: running number · name · count pill. Hover slides a soft fill in
   from the left and nudges the name; the lit entry takes a teal tint, grows
   its accent bar and fills its count. The list fades in entry by entry the
   first time it is drawn. Everything moves inside the rail — nothing here
   scrolls or shifts the page. */
.sort-cats button{
  position:relative;display:flex;align-items:center;gap:10px;overflow:hidden;
  padding:9px 10px 9px 14px;border-radius:12px;
  text-align:left;white-space:nowrap;
  color:var(--fg-3);font-size:.85rem;font-weight:500;
  background:linear-gradient(90deg,var(--surface-2),var(--surface-2)) left center / 0% 100% no-repeat;
  transition:color .25s var(--ease),background-size .35s var(--ease),background-color .25s var(--ease);
  animation:cat-in .5s var(--ease) both;animation-delay:calc(var(--i, 0) * 28ms);
}
@keyframes cat-in{from{opacity:0;transform:translateX(-10px);}to{opacity:1;transform:none;}}
.sort-cats button::before{
  content:'';position:absolute;left:4px;top:50%;translate:0 -50%;
  width:3px;height:0;border-radius:3px;background:var(--accent-fill);
  transition:height .4s cubic-bezier(.3,1.4,.5,1);
}
.sort-cats button em{flex:none;width:16px;font-style:normal;font-family:var(--mono);font-size:.56rem;
  letter-spacing:.04em;color:var(--fg-3);opacity:.6;transition:color .25s,opacity .25s;}
.sort-cats button span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;transition:translate .3s var(--ease);}
.sort-cats button i{
  flex:none;min-width:24px;padding:2px 7px;border-radius:999px;text-align:center;
  font-style:normal;font-family:var(--mono);font-size:.56rem;letter-spacing:.04em;
  color:var(--fg-3);background:var(--surface-2);
  transition:color .25s,background-color .25s,transform .3s cubic-bezier(.3,1.5,.5,1);
}
.sort-cats button:hover{color:var(--fg);background-size:100% 100%;}
.sort-cats button:hover span{translate:3px 0;}
.sort-cats button:hover i{background:var(--surface-3);}
.sort-cats button.on{color:var(--accent);font-weight:600;background-color:var(--accent-soft);background-size:0 0;}
.sort-cats button.on::before{height:18px;}
.sort-cats button.on em{color:var(--accent);opacity:1;}
.sort-cats button.on i{color:#fff;background:var(--accent-fill);transform:scale(1.06);}
@media (prefers-reduced-motion:reduce){ .sort-cats button{animation:none;} }

/* ── sort ── */
.dock-foot{position:relative;flex:none;padding-top:2px;border-top:1px solid var(--line);}
.sort-trigger{
  display:flex;align-items:center;gap:9px;width:100%;
  padding:10px 12px;border-radius:var(--r-sm);
  color:var(--fg-2);font-size:.82rem;font-weight:500;
  transition:background-color var(--tap) var(--ease),color var(--tap) var(--ease);
}
.sort-trigger:hover{background:var(--surface-2);color:var(--fg);}
.sort-trigger.open{background:var(--surface-2);color:var(--fg);}
.sort-trigger svg{width:15px;height:15px;flex:none;stroke:currentColor;fill:none;
  stroke-width:1.9;stroke-linecap:round;}
.sort-trigger span{flex:1;min-width:0;text-align:left;overflow:hidden;text-overflow:ellipsis;}
.sort-trigger i{
  width:0;height:0;flex:none;
  border-left:4px solid transparent;border-right:4px solid transparent;
  border-top:5px solid var(--fg-3);
  transition:transform var(--tap) var(--ease);
}
.sort-trigger.open i{transform:rotate(180deg);}

.sort-menu{
  position:absolute;bottom:calc(100% + 8px);left:0;right:0;z-index:80;
  min-width:230px;padding:6px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--line-2);
  box-shadow:var(--shadow);
  opacity:0;transform:translateY(6px) scale(.98);pointer-events:none;
  transition:opacity .18s var(--ease),transform .18s var(--ease);
}
.sort-menu.open{opacity:1;transform:none;pointer-events:auto;}
.sort-menu button{
  display:flex;align-items:center;gap:10px;width:100%;
  padding:9px 11px;border-radius:var(--r-sm);text-align:left;
  transition:background-color var(--tap) var(--ease);
}
.sort-menu button:hover{background:var(--surface-2);}
.sort-menu button span{flex:1;min-width:0;}
.sort-menu button b{display:block;font-size:.85rem;font-weight:600;}
.sort-menu button i{
  display:block;margin-top:2px;font-style:normal;
  font-size:.72rem;color:var(--fg-3);
}
.sort-menu button svg{
  width:15px;height:15px;flex:none;stroke:var(--accent);fill:none;
  stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;opacity:0;
}
.sort-menu button.on{background:var(--accent-soft);}
.sort-menu button.on svg{opacity:1;}

/* The "Showing …" summary that used to sit here is gone. It restated what the
   rail, the search box and the sort button were each already showing, and on
   picking a section it pushed the whole menu down by its own height. */

/* ── narrow: the rail becomes a floating bar ──
   Fixed to the bottom rather than the top, so it stays under the thumb and
   never sits between the reader and the food. The search collapses to its
   icon and opens on focus, which is the only way all three controls fit on a
   phone without stacking into a second row. */
@media (max-width:1080px){
  /* Keeps the top breathing space — a bare `padding:0 …` here wiped the gap
     the wide layout sets between the hero and the first heading. */
  .browse{display:block;padding:14px clamp(14px,3vw,20px) 0;}

  /* Floating, so it would otherwise hang over the hero from the moment the
     page opens — furniture for a menu the reader has not reached yet. It
     stays tucked below the fold until the menu itself is in view; customer.js
     adds .show when that happens. */
  .dock{
    position:fixed;left:12px;right:12px;bottom:calc(26px + env(safe-area-inset-bottom));
    top:auto;z-index:190;
    flex-direction:row;align-items:center;gap:8px;
    padding:8px;border-radius:100px;
    /* the menu scrolls under it here, so it keeps a (light) frosted look */
    background:color-mix(in srgb,var(--surface) 84%,transparent);
    backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
    box-shadow:var(--shadow);

    transform:translateY(calc(100% + 22px));opacity:0;pointer-events:none;
    transition:transform .42s var(--ease),opacity .3s var(--ease);
  }
  .dock.show{transform:none;opacity:1;pointer-events:auto;}

  .dock-search{
    width:40px;padding:9px;overflow:hidden;flex:none;
    transition:width .32s var(--ease),border-color var(--tap) var(--ease);
  }
  .dock-search:focus-within{width:min(210px,46vw);}
  .dock-search input{width:0;transition:width .32s var(--ease);}
  .dock-search:focus-within input{width:auto;flex:1;}
  .sort-clear{display:none;}
  .dock-search:focus-within .sort-clear:not(.hidden){display:grid;}

  .sort-cats{
    flex-direction:row;gap:4px;flex:1;min-width:0;max-height:none;
    overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
  }
  .sort-cats::-webkit-scrollbar{display:none;}
  .sort-cats button{
    flex:none;padding:8px 13px;border-radius:100px;
  }
  .sort-cats button::before,.sort-cats button em{display:none;}
  .sort-cats button{gap:6px;animation:none;background-image:none;}
  .sort-cats button i{min-width:0;padding:1px 6px;font-size:.54rem;}
  /* the lit chip is a teal pill that pops as it takes over */
  .sort-cats button.on{background:var(--accent-fill);color:#fff;animation:chip-pop .35s cubic-bezier(.3,1.5,.5,1);}
  .sort-cats button.on i{background:rgba(255,255,255,.22);color:#fff;transform:none;}
  @keyframes chip-pop{from{transform:scale(.9);}to{transform:scale(1);}}

  .dock-foot{border-top:none;padding-top:0;flex:none;}
  .sort-trigger{width:auto;padding:10px;}
  .sort-trigger span,.sort-trigger i{display:none;}
  .sort-menu{right:0;left:auto;min-width:236px;}

  /* Clear the floating dock. The bar's own offset is set further down, after
     its base rule — put here it lost to that rule at tablet widths. */
  .c-main{padding-bottom:150px;}
}

@media (prefers-reduced-motion:reduce){
  .dock-search,.dock-search input,.sort-cats button::before{transition:none;}
}

/* ══════ MENU ══════ */
/* The old 140px tail was there to clear a fixed bottom bar that no longer sits
   over this column on a wide screen, and it left the footer stranded a screen
   below the last card. */
.c-main{max-width:1240px;margin:0 auto;padding:34px 4px 24px;}

.c-sec{margin-bottom:clamp(56px,8vw,86px);scroll-margin-top:78px;}
/* The gap after the last section is the footer's business, not the section's —
   stacked, the two left a screen of dead space above the footer. */
.c-sec:last-child{margin-bottom:0;}

/* A numbered chapter head with the name ghosted behind it at size. What makes
   a long scroll feel edited rather than dumped: you always know which part of
   the menu you are in, even mid-scroll. */
.c-sec-head{
  position:relative;display:flex;align-items:baseline;gap:14px;
  margin-bottom:clamp(20px,3vw,30px);padding-top:18px;
}
/* Sits high and slightly left of the heading so the two overlap only at the
   shoulders — enough to feel layered, not so much that either is hard to
   read. Kept faint on purpose: it is a watermark, not a second title. */
/* Bounded on the right and clipped.
 *
 * It is set nowrap at a size measured in vw, so a long category — "Premium
 * Single Origin Coffee" — ran about 90px past a phone screen. Being absolutely
 * positioned it still counts toward the page's scrollable width, so the whole
 * document could be dragged sideways, and every fixed bar then sized itself
 * against that wider layout viewport instead of the screen. */
.c-sec-ghost{
  position:absolute;left:-6px;right:0;top:-26px;overflow:hidden;
  z-index:0;pointer-events:none;user-select:none;
  font-family:'Anton',var(--display),sans-serif;font-weight:400;
  font-size:clamp(44px,8.4vw,96px);line-height:1;letter-spacing:-.03em;
  text-transform:uppercase;white-space:nowrap;
  color:var(--fg);opacity:.045;
}
.c-sec-no{
  position:relative;z-index:1;flex:none;
  font-family:var(--mono);font-size:.62rem;font-weight:500;letter-spacing:.12em;
  color:var(--accent);
}
.c-sec-head h2{
  position:relative;z-index:1;
  font-size:clamp(1.55rem,4.2vw,2.3rem);letter-spacing:-.034em;line-height:1.05;
}
.c-sec-rule{flex:1;height:1px;background:var(--line);position:relative;top:-6px;}
.c-sec-count{
  position:relative;z-index:1;flex:none;
  font-family:var(--mono);font-size:.62rem;color:var(--fg-3);letter-spacing:.1em;
}

.c-grid{
  display:grid;gap:clamp(14px,1.6vw,20px);
  grid-template-columns:repeat(auto-fill,minmax(238px,1fr));
}
/* The first card of a section takes two columns and stands taller — an
   entry point for the eye, borrowed from how a menu gives its house drink
   more room than the rest of the list.
 *
 * Two earlier attempts put the photo beside the words: first stacked full
 * height (roughly twice its neighbours' height, a well of empty white beside
 * it), then on its side with the photo stretched to match the row (a well of
 * empty air above the price instead, since a short description rarely fills
 * a tall photo's own height). Both left the row's height at the mercy of
 * whichever side was taller. A full-bleed photo with the words set on top of
 * it, the way a poster carries a title, needs no such match — one layer,
 * nothing left over to fill. `height:100%` rather than a number pins it to
 * the row's own height, so it stands exactly as tall as the ordinary cards
 * beside it instead of a fixed guess that happened to be close. */
@media (min-width:760px){
  .c-card.lead{grid-column:span 2;position:relative;overflow:hidden;height:100%;padding:0;}
  .c-card.lead .c-card-img{
    position:absolute;inset:0;width:100%;height:100%;aspect-ratio:auto;border-radius:0;
  }
  .c-card.lead .c-card-body{
    position:absolute;left:0;right:0;bottom:0;z-index:1;
    padding:22px 22px 18px;
    background:linear-gradient(to top,rgba(0,0,0,.94) 0%,rgba(0,0,0,.68) 55%,transparent 100%);
  }
  .c-card.lead .c-card-info{margin-block:0;}
  .c-card.lead .c-card-foot{margin-top:12px;}
  .c-card.lead h3{font-size:1.4rem;color:#fff;}
  .c-card.lead .c-kcal{color:rgba(255,255,255,.85);}
  .c-card.lead .c-kcal i{color:rgba(255,255,255,.55);}
  .c-card.lead .c-recipe{-webkit-line-clamp:2;font-size:.85rem;color:rgba(255,255,255,.8);}
  .c-card.lead .c-meta-pill{
    background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.28);color:rgba(255,255,255,.9);
  }
  .c-card.lead .c-price{color:#fff;}
  .c-card.lead .c-price small{color:rgba(255,255,255,.62);}
}

/* ── the card ──
   The photo sits in its own tinted well inside the card rather than filling
   the top edge of it, and is allowed to overhang that well slightly. A cup
   then stands proud of its frame instead of being cropped into a tile, which
   is the whole difference between a menu and a spreadsheet of food. */
.c-card{
  position:relative;display:flex;flex-direction:column;text-align:left;width:100%;
  padding:10px;border-radius:var(--r-lg);
  background:var(--surface);border:1px solid var(--line);
  transition:transform .4s var(--ease),border-color .4s var(--ease),
             box-shadow .4s var(--ease);
}

/* Inset inside the card rather than bleeding off its top edge — the card
   keeps a visible margin all the way round, which is what makes a grid of
   them read as considered rather than as a contact sheet.
 *
 * The photo fills the well. An earlier pass let it overhang the top, copied
 * from menu sites that use cut-out product shots on transparent backgrounds;
 * ours are rectangular lifestyle photographs, so `contain` letterboxed them
 * into a grey frame and the overhang had nothing to overhang with. */
.c-card-img{
  position:relative;aspect-ratio:5 / 4;flex:none;overflow:hidden;
  border-radius:calc(var(--r-lg) - 5px);
  background:var(--surface-2);
}
.c-card-img img{
  width:100%;height:100%;object-fit:cover;
  opacity:0;transform:scale(1.04);
  transition:opacity .55s var(--ease),transform .7s var(--ease);
}
.c-card-img img.ready{opacity:1;transform:scale(1);}

.c-card-body{
  flex:1;padding:14px 8px 6px;display:flex;flex-direction:column;
}
.c-card-info{display:flex;flex-direction:column;gap:7px;}
.c-card-top{display:flex;align-items:flex-start;gap:10px;}
.c-card h3{
  flex:1;min-width:0;
  font-size:1.04rem;line-height:1.22;letter-spacing:-.024em;color:var(--fg);
}
/* Calories moved off the photo and into the type, where it is information
   rather than a sticker — and where it stops covering the drink. */
.c-kcal{
  flex:none;display:flex;flex-direction:column;align-items:flex-end;line-height:1;
  font-family:var(--mono);font-size:.82rem;font-weight:500;color:var(--fg-2);
}
.c-kcal i{
  font-style:normal;font-size:.46rem;letter-spacing:.12em;
  text-transform:uppercase;color:var(--fg-3);margin-top:3px;
}
.c-card .c-recipe{
  color:var(--fg-3);font-size:.79rem;line-height:1.45;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.c-card-meta{display:flex;gap:6px;flex-wrap:wrap;margin-top:2px;}
.c-meta-pill{
  padding:4px 9px;border-radius:100px;
  background:var(--surface-2);border:1px solid var(--line);
  color:var(--fg-3);font-family:var(--mono);font-size:.5rem;
  font-weight:500;letter-spacing:.08em;text-transform:uppercase;
}

.c-card-foot{
  display:flex;align-items:center;gap:10px;margin-top:auto;padding-top:14px;
}
.c-price{
  display:flex;align-items:baseline;gap:5px;
  font-family:var(--display);font-size:1.2rem;font-weight:600;
  letter-spacing:-.028em;color:var(--fg);
}
.c-price small{
  font-family:var(--mono);font-size:.55rem;font-weight:400;
  letter-spacing:.09em;color:var(--fg-3);
}
.c-add{
  margin-left:auto;width:38px;height:38px;border-radius:50%;flex:none;
  background:var(--accent-grad);color:var(--accent-ink);
  display:grid;place-items:center;
  transition:transform var(--tap) var(--ease),filter var(--tap) var(--ease);
}
.c-add svg{width:17px;height:17px;stroke:currentColor;fill:none;
  stroke-width:2.6;stroke-linecap:round;}
.c-add:active{transform:scale(.85);}

/* still used by the item panel header */
.c-tag{
  padding:5px 10px;border-radius:100px;
  background:rgba(8,8,9,.62);backdrop-filter:blur(8px);
  border:1px solid rgba(255,255,255,.16);color:#fff;
  font-family:var(--mono);font-size:.53rem;font-weight:500;letter-spacing:.09em;
  text-transform:uppercase;
}

@media (hover:hover){
  .c-card:hover{transform:translateY(-5px);border-color:var(--accent-line);box-shadow:var(--shadow);}
  /* The cup lifts a little further than the card does, so it reads as
     standing in the well rather than printed on it. */
  .c-card:hover .c-card-img img.ready{transform:translateY(-6px) scale(1.03);}
  .c-add:hover{filter:brightness(1.08);}
}

/* The choice chips, .c-opt rows and .i-qty stepper live in app.css — both
   this page and the counter till use them, and duplicating them here once
   left the back office rendering bare unstyled text. */

/* required / optional flag on a question */
.i-block > .mono .req,
.i-block > .mono .opt{
  font-style:normal;margin-left:9px;padding:2px 7px;border-radius:100px;
  font-size:.52rem;letter-spacing:.09em;
}
.i-block > .mono .req{background:var(--accent-soft);color:var(--accent);}
.i-block > .mono .opt{background:var(--surface-3);color:var(--fg-3);}

/* scroll reveal */
.c-card{opacity:0;transform:translateY(26px);}
.c-card.in{opacity:1;transform:none;
  transition:opacity .7s var(--ease),transform .7s var(--ease),
             border-color .45s var(--ease),box-shadow .45s var(--ease);}
@media (prefers-reduced-motion:reduce){.c-card{opacity:1;transform:none;}}

/* ══════ BASKET BAR ══════
   Hidden by opacity and visibility, not by sliding alone.
 *
 * The slide is 180% of the bar's own height, which cleared the screen while it
 * sat 20px from the bottom. Once it was raised to stand clear of the dock, 180%
 * no longer reached past the edge and an empty basket sat visibly on top of the
 * category pills reading "0.00 EGP". Fading it out as well makes the hidden
 * state independent of whatever offset it is given. */
.c-bar{
  position:fixed;left:50%;bottom:20px;transform:translate(-50%,180%);
  opacity:0;visibility:hidden;
  z-index:200;width:min(560px,calc(100% - 32px));
  padding:12px 12px 12px 22px;border-radius:100px;
  background:var(--surface);border:1px solid var(--line-2);
  display:flex;align-items:center;gap:16px;
  box-shadow:var(--shadow);
  transition:transform .48s var(--ease),opacity .3s var(--ease),
             visibility 0s linear .48s;
}
.c-bar.up{
  transform:translate(-50%,0);
  opacity:1;visibility:visible;
  transition:transform .48s var(--ease),opacity .3s var(--ease),
             visibility 0s linear 0s;
}

/* Stands the bar clear of the floating dock, at every width where that dock
   exists. It has to live HERE, after the base rule above — the same
   declaration inside the earlier max-width:1080px block lost to that base at
   tablet widths, where the narrow-phone block that also sets it never applies.
   Two rules of equal specificity, and the later one in the file wins. */
@media (max-width:1080px){
  .c-bar{bottom:calc(118px + env(safe-area-inset-bottom));}
}
.c-bar-info b{display:block;font-size:1.05rem;font-weight:600;font-variant-numeric:tabular-nums;}
.c-bar-info span{color:var(--fg-3);font-family:var(--mono);font-size:.55rem;letter-spacing:.1em;}
.c-bar .btn{margin-left:auto;}

/* ══════ SHEET ══════ */
.c-sheet-back{
  position:fixed;inset:0;z-index:300;background:var(--scrim);
  display:flex;align-items:flex-end;justify-content:center;
  backdrop-filter:blur(5px);animation:fade .26s var(--ease);
}
.c-sheet{
  width:100%;max-width:580px;max-height:92dvh;overflow-y:auto;
  background:var(--surface);border:1px solid var(--line-2);border-bottom:none;
  border-radius:var(--r-xl) var(--r-xl) 0 0;
  padding:22px 22px calc(26px + env(safe-area-inset-bottom));
  animation:sheet-up .44s var(--ease);
}
@keyframes sheet-up{from{transform:translateY(100%);}}
.c-sheet-grip{width:40px;height:4px;border-radius:2px;background:var(--line-2);
  margin:-8px auto 18px;}
.c-sheet h3{font-size:1.4rem;}
.c-sheet > .mono{color:var(--fg-2);margin-top:4px;}
.c-sheet-body{margin:20px 0;display:flex;flex-direction:column;gap:14px;}

/* A secondary way into a sheet's own action — "not this, the other thing" —
   so it reads as an alternative rather than competing with the accent
   button above it for attention. */
.c-link-btn{
  color:var(--fg-2);font:inherit;font-size:.84rem;font-weight:600;
  text-decoration:underline;text-underline-offset:3px;text-align:center;
}
.c-link-btn:active{opacity:.7;}

/* ══════ GUEST ACCOUNT ══════
   Sign in / create account, and the account sheet: overview, orders, saved
   addresses, refer a friend, profile (core/guestAccount.js). */
.nav-pill.on{background:rgba(255,255,255,.34);}
.ga-seg,.ga-tabs{display:flex;gap:6px;margin:16px 0 4px;padding:4px;border-radius:999px;background:var(--surface-2);border:1px solid var(--line);}
.ga-tabs{overflow-x:auto;scrollbar-width:none;margin-top:14px;}
.ga-tabs::-webkit-scrollbar{display:none;}
.ga-seg button,.ga-tabs button{flex:1 0 auto;padding:9px 10px;border-radius:999px;font:inherit;font-size:.82rem;font-weight:600;
  color:var(--fg-2);white-space:nowrap;transition:background .2s,color .2s;}
.ga-seg button.on,.ga-tabs button.on{background:var(--fg);color:var(--bg);}
.ga-msg{color:var(--danger);min-height:1.2em;margin:0;}
.ga-fine{margin-top:14px;text-align:center;color:var(--fg-3);line-height:1.6;}
.ga-note{margin:14px 0;color:var(--fg-2);line-height:1.6;}
.ga-pw{position:relative;display:flex;}
.ga-pw input{flex:1;padding-right:64px;}
.ga-eye{position:absolute;right:6px;top:50%;transform:translateY(-50%);padding:6px 10px;border-radius:999px;
  font:inherit;font-size:.74rem;font-weight:600;color:var(--accent);}
.ga-check{margin:8px 0 2px;display:flex;align-items:flex-start;gap:10px;font-size:.88rem;color:var(--fg-2);cursor:pointer;line-height:1.4;}
.ga-check input{margin-top:3px;accent-color:var(--accent);}
.ga-forgot{display:block;width:100%;margin-top:14px;}
.ga-otp{display:flex;flex-direction:column;gap:10px;align-items:flex-start;margin-top:-4px;}
.ga-otp #gaCodeWrap{width:100%;}
.ga-sent{margin:0 0 10px;color:var(--fg-2);line-height:1.6;}
.ga-codeinput{width:100%;text-align:center;font-family:var(--mono);font-size:1.5rem;letter-spacing:.35em;padding:14px 12px;}
.ga-codeinput::placeholder{letter-spacing:.2em;font-size:1.2rem;opacity:.5;}
.ga-ref-hint{min-height:1.2em;margin:-6px 0 0;color:var(--fg-3);}
.ga-ref-hint.ok{color:var(--accent);} .ga-ref-hint.bad{color:var(--danger);}
#addrWrap > .field:first-child{margin-bottom:14px;}
.ga-signed{margin:0;color:var(--fg-2);} .ga-signed b{color:var(--fg);}

.ga-hello{display:flex;align-items:center;gap:14px;}
.ga-hello h3{font-size:1.3rem;margin:0;}
.ga-hello .mono{margin:2px 0 0;color:var(--fg-3);}
.ga-avatar{width:46px;height:46px;border-radius:50%;flex:none;display:grid;place-items:center;font-weight:700;font-size:1.1rem;color:#fff;
  background:linear-gradient(135deg,rgba(132,196,164,1),rgba(78,154,120,1) 70%,rgba(63,138,104,1));}
/* a floor on the height, so the sheet does not jump as you move between tabs */
.ga-body{margin-top:16px;display:flex;flex-direction:column;gap:12px;min-height:46dvh;}
.ga-card{padding:16px 18px;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);display:flex;flex-direction:column;gap:8px;align-items:flex-start;}
.ga-card .mono{color:var(--fg-3);margin:0;}
.ga-big{font-size:2.4rem;font-weight:300;letter-spacing:-.03em;line-height:1;}
.ga-lead{font-size:1.05rem;font-weight:600;display:flex;align-items:center;gap:8px;flex-wrap:wrap;}
.ga-bar{width:100%;height:7px;border-radius:999px;background:var(--line);overflow:hidden;}
.ga-bar i{display:block;height:100%;border-radius:999px;background:linear-gradient(90deg,rgba(132,196,164,1),rgba(78,154,120,1));}
.ga-two{display:grid;grid-template-columns:1fr 1fr;gap:10px;}
.ga-tile{padding:14px 16px;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);text-align:left;
  display:flex;flex-direction:column;gap:4px;font:inherit;color:inherit;cursor:pointer;transition:border-color .2s,transform .2s;}
.ga-tile:not(.static):hover{border-color:var(--accent-line);transform:translateY(-1px);}
.ga-tile b{font-size:1.15rem;font-weight:600;} .ga-tile .mono{color:var(--fg-3);margin:0;line-height:1.4;}
.ga-chip{display:inline-block;padding:3px 10px;border-radius:999px;font-style:normal;font-size:.72rem;font-weight:600;text-transform:capitalize;
  background:var(--surface-3,#eee);color:var(--fg-2);}
.ga-chip.active,.ga-chip.completed,.ga-chip.ready{background:var(--accent-soft);color:var(--accent);}
.ga-chip.pending,.ga-chip.accepted,.ga-chip.preparing{background:rgba(238,122,47,.14);color:#B4531A;}
.ga-chip.rejected,.ga-chip.ended,.ga-chip.cancelled{background:rgba(214,69,69,.12);color:#B73A3A;}

.ga-order{padding:16px 18px;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);}
.ga-order header{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;}
.ga-order header b{font-size:1rem;display:block;} .ga-order header .mono{color:var(--fg-3);display:block;margin-top:2px;}
.ga-meta{display:flex;align-items:center;gap:10px;margin:10px 0 0;flex-wrap:wrap;}
.ga-src{font-size:.74rem;font-weight:600;padding:3px 10px;border-radius:999px;}
.ga-src.online{background:rgba(148,136,212,.15);color:#5E52A8;} .ga-src.cafe{background:var(--accent-soft);color:var(--accent);}
.ga-addr{margin:8px 0 0;color:var(--fg-2);line-height:1.5;}
.ga-items{list-style:none;margin:12px 0;padding:12px 0;border-top:1px dashed var(--line-2);border-bottom:1px dashed var(--line-2);
  display:flex;flex-direction:column;gap:6px;font-size:.88rem;}
.ga-items i{display:block;font-style:normal;color:var(--fg-3);font-size:.78rem;margin-top:1px;}
.ga-order footer{display:flex;justify-content:space-between;align-items:center;}
.ga-order footer b{font-size:1.05rem;}
.ga-empty{padding:30px 10px;text-align:center;} .ga-empty b{font-size:1.05rem;}
.ga-empty .mono{color:var(--fg-3);margin-top:6px;line-height:1.6;}

.ga-addr-card{padding:14px 16px;border-radius:var(--r);background:var(--surface-2);border:1px solid var(--line);}
.ga-addr-top{display:flex;align-items:center;gap:8px;} .ga-addr-card p{margin:6px 0 0;line-height:1.5;font-size:.9rem;}
.ga-addr-card .mono{color:var(--fg-3);}
.ga-addr-act{display:flex;gap:6px;flex-wrap:wrap;margin-top:12px;}

.ga-ref{align-items:center;text-align:center;gap:10px;}
.ga-code{font-family:var(--mono);font-size:1.9rem;letter-spacing:.14em;font-weight:600;}
.ga-ref-act{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;}
.ga-how{margin:4px 0;padding-left:20px;display:flex;flex-direction:column;gap:8px;font-size:.9rem;color:var(--fg-2);line-height:1.5;}
.ga-how b{color:var(--fg);}

.ga-more{border-radius:var(--r);border:1px solid var(--line);padding:2px 16px;margin-top:10px;}
.ga-more summary{cursor:pointer;padding:12px 0;font-weight:600;font-size:.9rem;}
.ga-more .c-sheet-body{margin:4px 0 14px;}
.ga-danger summary{color:var(--danger);}

/* ══════ JOIN THE LOYALTY PROGRAM ══════ */
.lr-head{text-align:center;}
.lr-badge{
  width:52px;height:52px;border-radius:50%;margin:0 auto 14px;
  background:var(--accent-soft);border:1px solid var(--accent-line);
  display:grid;place-items:center;color:var(--accent);
  animation:pop .5s var(--ease) backwards;
}
.lr-badge svg{width:24px;height:24px;fill:currentColor;}
.lr-perks{
  display:flex;flex-direction:column;gap:9px;margin:16px 0 0;padding:0;
  list-style:none;text-align:left;
}
.lr-perks li{display:flex;align-items:center;gap:10px;font-size:.86rem;color:var(--fg-2);}
.lr-perks li svg{
  width:16px;height:16px;flex:none;color:var(--accent);
  stroke:currentColor;stroke-width:2.4;fill:none;stroke-linecap:round;stroke-linejoin:round;
}
.lr-bonus{
  margin-top:18px;padding:12px 16px;border-radius:var(--r);text-align:center;
  background:var(--accent-soft);border:1px solid var(--accent-line);
  color:var(--fg-2);font-size:.86rem;
}
.lr-bonus b{color:var(--accent);}

/* The checkout phone field recognising a loyalty member as it's typed —
   informational only, so it reads like a quiet confirmation rather than
   another form control competing for attention. */
.loyalty-badge{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-top:8px;padding:9px 14px;border-radius:var(--r-sm);
  background:var(--accent-soft);border:1px solid var(--accent-line);
}
.loyalty-badge span{color:var(--fg-3);font-size:.6rem;letter-spacing:.06em;}
.loyalty-badge b{color:var(--accent);font-size:.82rem;}

/* ══════ LOYALTY MEMBERSHIP CARD ══════
   A wallet card, not a form — the teal gradient and bird watermark are the
   café's own loyalty artwork; the loyalty details, replacing the stamp
   tracker, are what changes card to card. */
.lc-wrap{display:flex;flex-direction:column;align-items:center;padding:4px 0 8px;}
.lc-card{
  position:relative;overflow:hidden;width:100%;max-width:340px;
  aspect-ratio:0.62;border-radius:22px;padding:22px 22px 20px;
  display:flex;flex-direction:column;color:#F4EEE3;
  /* The 1718 club teal — the café's own card, cream type on it, gold for
     the figures that matter. */
  background:
    radial-gradient(420px 300px at 88% 6%, rgba(216,185,136,.16), transparent 60%),
    linear-gradient(140deg,#1F6964 0%,#11504B 52%,#093532 100%);
  box-shadow:0 18px 44px rgba(6,40,37,.38);
}
/* The café's own line-art parrot, faint enough to sit behind every line of
   text without fighting it — see showMembershipCard() for the asset path.
   Perched toward the lower-right rather than centred, the same placement as
   the café's own reference card. It ships as black-on-transparent, so
   invert(1) flips the line work white — the same trick the logo above it
   uses. Plain opacity rather than a blend mode: multiply/screen both mix
   with the gradient underneath and read as a green tint either way, where
   a flat translucent white is what actually looks white on a green card. */
.lc-bird{
  position:absolute;inset:0;
  background-image:url('../img/loyalty-bird.png');
  background-position:-80% 10%;background-repeat:no-repeat;
  background-size:140%;opacity:.16;filter:invert(1);
  pointer-events:none;
}
/* Under the logo, in normal flow with it — the top-right corner the
   reference card puts this in is exactly where the bird's head sits once
   its tail is placed to clip off the card's own edge (see .lc-bird above),
   so this stays on the side of the card the bird never reaches instead. */
.lc-points{display:flex;align-items:baseline;gap:5px;margin-top:2px;}
.lc-points b{font-family:var(--display);font-size:1.1rem;color:#FFFFFF;}
.lc-points span{font-family:var(--mono);font-size:.52rem;letter-spacing:.1em;
  text-transform:uppercase;color:rgba(244,238,227,.66);}
/* The "you've earned a coffee" moment — a solid banner rather than a small
   floating circle, so it reads as the headline of the card the instant it
   is eligible, not a badge someone has to notice. Solid background, so
   sitting over the bird is never a legibility problem the way transparent
   text on it was — only the icon/text below need their own contrast. */
.lc-claim{
  display:flex;align-items:center;gap:10px;width:100%;
  margin-top:12px;padding:10px 12px;border-radius:14px;
  background:#F7F1E6;color:#0B2E2B;text-align:left;
  box-shadow:0 10px 24px rgba(6,40,37,.3);
}
.lc-claim > svg{width:28px;height:28px;flex:none;stroke:#0B2E2B;stroke-width:1.6;fill:none;}
.lc-claim span{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0;}
.lc-claim b{font-size:.82rem;font-weight:700;line-height:1.25;}
.lc-claim i{font-style:normal;font-size:.66rem;color:rgba(11,46,43,.62);}
.lc-claim-go{width:18px;height:18px;flex:none;stroke:rgba(11,46,43,.4);stroke-width:2;fill:none;}
.lc-top{display:flex;flex-direction:column;align-items:flex-start;gap:2px;position:relative;}
.lc-top .lc-logo{width:46px;height:auto;}
.lc-tagline{font-family:var(--mono);font-size:.5rem;line-height:1.35;letter-spacing:.16em;
  text-transform:uppercase;color:rgba(244,238,227,.72);}
.lc-mid{margin-top:auto;position:relative;}
.lc-eyebrow{font-family:var(--mono);font-size:.6rem;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(244,238,227,.66);margin:0 0 4px;}
.lc-name{font-family:var(--display);font-size:1.5rem;line-height:1.1;margin:0;}
.lc-since{font-family:var(--mono);font-size:.62rem;letter-spacing:.04em;
  color:rgba(244,238,227,.66);margin:5px 0 0;}
/* The code plate itself (QR beside the number) is .code-plate in app.css. */
.lc-barcode{margin-top:16px;}
.lc-foot{
  position:relative;margin-top:16px;padding-top:14px;
  border-top:1px solid rgba(244,238,227,.2);
  display:flex;align-items:stretch;justify-content:space-between;gap:14px;
}
/* Centred against the taller "visit our website" column beside it, rather
   than pinned to the top of the row — the same vertical mid-line the
   reference card's own two columns share. */
.lc-foot > div:first-child{display:flex;flex-direction:column;justify-content:center;}
.lc-label{display:block;font-family:var(--mono);font-size:.5rem;
  letter-spacing:.1em;text-transform:uppercase;color:rgba(244,238,227,.66);margin-bottom:5px;}
.lc-social{display:flex;align-items:center;gap:6px;}
.lc-ico{width:15px;height:15px;flex:none;stroke:#F4EEE3;stroke-width:1.7;fill:none;}
.lc-handle{margin:0;font-size:.8rem;font-weight:600;}
.lc-web{
  display:flex;flex-direction:column;align-items:flex-end;text-align:right;
  padding-left:14px;border-left:1px solid rgba(244,238,227,.2);
}
.lc-url{margin:0 0 8px;font-size:.8rem;font-weight:600;}
.lc-visit{
  display:flex;align-items:center;gap:6px;flex:none;
  padding:8px 14px;border-radius:100px;background:#FFFFFF;color:#0B2E2B;
  font-size:.72rem;font-weight:600;text-decoration:none;
}
.lc-visit svg{width:13px;height:13px;stroke:currentColor;stroke-width:2.2;fill:none;}

/* Sits below the card rather than on it — a system action (hand this card
   to iOS), not part of the café's own artwork. Disabled/placeholder until
   a real Pass Type ID certificate exists — see showMembershipCard(). */
.lc-wallet{
  display:flex;align-items:center;justify-content:center;gap:8px;
  width:100%;max-width:340px;margin-top:12px;padding:12px;
  border-radius:12px;background:#000;color:#fff;
  font-family:inherit;font-size:.9rem;font-weight:600;
}
.lc-wallet:active{opacity:.85;}
.lc-wallet svg{width:19px;height:19px;fill:currentColor;}

/* A plain download rather than a system-branded button — no wallet, no
   certificate needed, just the card's own artwork saved as an image. */
.lc-download{
  display:flex;align-items:center;justify-content:center;gap:8px;
  width:100%;max-width:340px;margin-top:12px;padding:12px;
  border-radius:12px;background:var(--surface-2);color:var(--fg);
  border:1px solid var(--line);
  font-family:inherit;font-size:.9rem;font-weight:600;
}
.lc-download:active{opacity:.85;}
.lc-download svg{width:19px;height:19px;stroke:currentColor;stroke-width:2;fill:none;
  stroke-linecap:round;stroke-linejoin:round;}

/* step 2 and 3 of checkout — a way back that does not look like Cancel */
.c-back{
  color:var(--fg-3);font:inherit;font-size:.82rem;margin-bottom:6px;
  padding:4px 0;align-self:flex-start;
}
.c-back:hover{color:var(--fg-2);}

/* review step: where it is going, and who is paying — plain fact rows, the
   same shape wherever the till and the reports print one. */
.c-review-where,.c-review-pay{
  display:flex;flex-direction:column;gap:2px;padding:12px 14px;
  background:var(--surface-2);border-radius:var(--r);
}
.c-review-where span,.c-review-pay span{color:var(--fg-3);}
.c-review-where b{font-size:1.02rem;}
.c-review-where i{color:var(--fg-3);font-style:normal;margin-top:2px;}
.c-review-note{color:var(--fg-3);line-height:1.7;}

/* basket lines */
.c-line{display:flex;gap:13px;align-items:flex-start;padding:13px 0;
  border-bottom:1px solid var(--line);}
.c-line:last-of-type{border-bottom:none;}
.c-line-shot{width:58px;height:58px;border-radius:var(--r-sm);flex:none;
  overflow:hidden;background:var(--surface-2);}
.c-line-shot img{width:100%;height:100%;object-fit:cover;}
.c-line-main{flex:1;min-width:0;}
.c-line-main b{font-size:.94rem;font-weight:600;line-height:1.3;display:block;}
.c-line-main .mono{color:var(--fg-3);margin-top:4px;}
.c-line-note{margin-top:4px;color:var(--warn);font-size:.74rem;}
.c-line-right{display:flex;flex-direction:column;align-items:flex-end;gap:9px;}
.c-line-total{font-family:var(--mono);font-size:.88rem;}

.c-qty{display:flex;align-items:center;gap:3px;background:var(--surface-2);
  border-radius:100px;padding:3px;border:1px solid var(--line);}
.c-qty button{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;
  font-size:1.05rem;line-height:1;color:var(--fg-2);}
.c-qty button:active{background:var(--surface-3);color:var(--fg);}
.c-qty b{min-width:20px;text-align:center;font-family:var(--mono);font-size:.78rem;}

/* ── how they want it: eaten in, collected, or delivered ── */
.c-types{display:flex;gap:9px;}
.c-types .c-opt{flex:1;justify-content:center;min-width:0;}
/* Three across is tight on a small phone; let them wrap rather than squash. */
@media (max-width:380px){
  .c-types{flex-wrap:wrap;}
  .c-types .c-opt{flex:1 1 46%;}
}
.c-deliv-note{
  color:var(--fg-3);line-height:1.7;margin-top:10px;
}
#addrWrap textarea{
  width:100%;resize:vertical;min-height:76px;font:inherit;line-height:1.6;
}
/* an address is long — let it wrap on the confirmation rather than clip */
.c-done-addr{
  display:block;line-height:1.5;word-break:break-word;
  font-size:1rem;margin-top:2px;
}

/* The phone field with its country code is defined in app.css — the guest
   types one at checkout and staff type one at the till, and admin.html (the
   back office) never loads this file. .c-opt lives there for the same reason. */

/* ══════ CONFIRMATION ══════ */
.c-done{text-align:center;padding:12px 0 4px;}
.c-tick{
  width:66px;height:66px;border-radius:50%;margin:0 auto 20px;
  background:var(--accent-fill);display:grid;place-items:center;
  animation:pop .55s var(--ease) backwards;
}
@keyframes pop{from{transform:scale(0) rotate(-25deg);}}
.c-tick svg{width:31px;height:31px;stroke:var(--accent-ink);fill:none;stroke-width:2.8;
  stroke-linecap:round;stroke-linejoin:round;}
.c-done h3{font-size:1.6rem;}
.c-orderno{
  display:inline-block;margin:14px 0 6px;padding:9px 18px;border-radius:100px;
  background:var(--surface-2);border:1px solid var(--line);
  font-family:var(--mono);font-size:.88rem;letter-spacing:.08em;
}
.c-done p{color:var(--fg-2);font-size:.9rem;line-height:1.65;margin-top:16px;}
.c-done p b{color:var(--fg);}

/* where it is going — the thing the guest checks twice */
.c-done-where{
  margin-top:18px;padding:14px 18px;border-radius:var(--r);
  background:var(--accent-soft);border:1px solid var(--accent-line);
}
.c-done-where .mono{display:block;color:var(--accent);opacity:.85;}
.c-done-where b{
  display:block;margin-top:5px;font-family:var(--display);
  font-size:1.5rem;font-weight:600;letter-spacing:-.028em;color:var(--fg);
}

.c-done-total{
  margin-top:14px;padding:14px 18px;border-radius:var(--r);
  background:var(--surface-2);border:1px solid var(--line);
}
.c-done-total .mono{display:block;color:var(--fg-3);}
.c-done-total b{
  display:block;margin-top:5px;font-family:var(--display);
  font-size:1.4rem;font-weight:600;letter-spacing:-.028em;
}
.c-done-total em{
  display:block;margin-top:4px;font-style:normal;
  font-family:var(--mono);font-size:.56rem;letter-spacing:.09em;
  text-transform:uppercase;color:var(--fg-3);
}

/* the tax lines read quieter than the items they sit under */
.c-sheet .sums .sum span:first-child{color:var(--fg-2);}
.c-sheet .sums{
  padding:14px 16px;border-radius:var(--r);
  background:var(--surface-2);border:1px solid var(--line);
}
.c-sheet .sums .sum.total{border-top:none;padding-top:0;margin-top:0;}
.bill-note{
  margin-top:9px;padding-top:9px;border-top:1px solid var(--line);
  color:var(--fg-3);line-height:1.7;
}

/* ══════════════════ FOOTER ══════════════════
   Small mono capitals over a wordmark that is cut out of horizontal rules.
   The ruling is a repeating gradient clipped to the glyphs, so the mark stays
   real text — selectable, searchable, and it scales with the window instead of
   being an image that has to be redrawn whenever the café is renamed. */
.foot{
  position:relative;margin-top:clamp(28px,4vw,52px);
  padding:clamp(34px,5vw,58px) clamp(16px,4vw,54px) clamp(20px,3vw,30px);
  border-top:1px solid var(--line);
  background:linear-gradient(180deg,transparent,color-mix(in srgb,var(--bg) 60%,transparent));
}

.foot-grid{
  display:grid;gap:clamp(26px,4vw,60px);
  grid-template-columns:1.4fr 1fr 1fr;align-items:start;
  max-width:1480px;margin:0 auto;
}
.foot-col{min-width:0;}

.foot-key{
  font-family:var(--mono);font-size:.66rem;font-weight:500;
  letter-spacing:.14em;text-transform:uppercase;color:var(--fg-2);
  line-height:2;
}
.foot-dim{color:var(--fg-3);}

.foot-head{
  font-family:var(--mono);font-size:.7rem;font-weight:600;
  letter-spacing:.2em;text-transform:uppercase;color:var(--fg);
  margin-bottom:16px;
}

.foot-list{list-style:none;display:flex;flex-direction:column;gap:9px;}
.foot-list li{display:flex;align-items:baseline;gap:12px;}
/* The letter is a label, not a bullet — fixed width so the values line up. */
.foot-list i{
  flex:none;width:14px;font-style:normal;
  font-family:var(--mono);font-size:.6rem;letter-spacing:.1em;
  color:var(--accent);
}
.foot-list span{color:var(--fg);font-size:.95rem;word-break:break-word;}
.foot-list a{border-bottom:1px solid transparent;transition:border-color var(--tap) var(--ease);}
.foot-list a:hover{border-bottom-color:var(--accent);}

.foot-links{gap:6px;}
.foot-links li{display:block;}
.foot-links a{
  color:var(--fg);font-size:.95rem;
  border-bottom:1px solid transparent;transition:border-color var(--tap) var(--ease);
}
.foot-links a:hover{border-bottom-color:var(--accent);}

/* ── the wordmark ──
   Set to span the width, whatever the name is.
 *
 * The size is measured and applied by fitFootMark() in customer.js rather than
 * fixed here: a vw value only fills the screen for a name of one particular
 * length, and this one is whatever the café called itself. The clamp below is
 * just a sane starting value for the instant before that runs.
 *
 * 96vw rather than 100vw — the latter counts the scrollbar's width on desktop
 * and would put the page back into sideways scrolling. */
.foot-mark{
  margin:clamp(34px,6vw,74px) 0 clamp(14px,2vw,22px);
  width:96vw;max-width:none;margin-left:50%;transform:translateX(-50%);
  font-family:'Anton',var(--display),sans-serif;font-weight:400;
  font-size:clamp(38px,15vw,220px);line-height:.92;letter-spacing:-.03em;
  text-transform:uppercase;text-align:center;user-select:none;
  white-space:nowrap;

  /* 2px of ink then 3px of air, repeated down the glyph. -webkit- prefixes
     are still required on Safari for both properties. */
  background-image:repeating-linear-gradient(
    180deg,
    var(--fg) 0 2px,
    transparent 2px 5px
  );
  -webkit-background-clip:text;
  background-clip:text;
  color:transparent;
  opacity:.5;
}

.foot-rule{height:1px;background:var(--line);max-width:1480px;margin:0 auto;}
.foot-tag{
  max-width:1480px;margin:14px auto 0;
  display:flex;gap:10px;flex-wrap:wrap;
}
/* The café's own line and the VAT note are two separate sentences that would
   otherwise read as one run-on. The divider only appears when there is
   actually a second one — :empty covers the case where no VAT is added. */
#taxFoot:not(:empty)::before{content:'·';margin-right:10px;opacity:.45;}

@media (max-width:820px){
  .foot-grid{grid-template-columns:1fr 1fr;gap:26px;}
  .foot-col:first-child{grid-column:1 / -1;}
}
@media (max-width:520px){
  .foot-grid{grid-template-columns:1fr;}
  .foot-tag{flex-direction:column;gap:4px;}
}

/* ══════ ITEM PANEL ══════
   Recovered: these rules sat between the FOOTER and MOBILE markers, and a
   splice that replaced that whole range to rebuild the footer took them
   with it. Nothing threw — the panel simply opened with no styling and so
   had no size, which reads as "the customisation menu is missing". */
.i-back-drop{
  position:fixed;inset:0;z-index:400;
  background:rgba(6,6,8,.52);
  backdrop-filter:blur(16px) saturate(.9);
  -webkit-backdrop-filter:blur(16px) saturate(.9);
  display:grid;place-items:center;padding:20px;
  animation:fade .28s var(--ease);
  overscroll-behavior:contain;
}
:root[data-theme="light"] .i-back-drop{background:rgba(20,20,16,.34);}

.i-card{
  position:relative;width:100%;max-width:520px;max-height:88dvh;overflow-y:auto;
  border-radius:var(--r-xl);
  /* frosted, not solid — the menu stays faintly readable behind it */
  background:color-mix(in srgb,var(--surface) 82%,transparent);
  backdrop-filter:blur(26px) saturate(1.5);
  -webkit-backdrop-filter:blur(26px) saturate(1.5);
  border:1px solid color-mix(in srgb,var(--line-2) 70%,transparent);
  box-shadow:0 26px 70px rgba(0,0,0,.46),inset 0 1px 0 rgba(255,255,255,.07);
  animation:card-up .42s var(--ease);
  overscroll-behavior:contain;
}
@keyframes card-up{from{opacity:0;transform:translateY(24px) scale(.97);}}

.i-close{
  position:absolute;top:14px;right:14px;z-index:5;
  width:34px;height:34px;border-radius:50%;
  display:grid;place-items:center;font-size:.86rem;
  background:rgba(8,8,10,.5);backdrop-filter:blur(10px);
  border:1px solid rgba(255,255,255,.18);color:#fff;
  transition:background var(--tap) var(--ease),transform var(--tap) var(--ease);
}
.i-close:hover{background:rgba(8,8,10,.74);}
.i-close:active{transform:scale(.88);}

.i-shot{
  position:relative;height:186px;background:var(--surface-2);overflow:hidden;
}
.i-shot img{width:100%;height:100%;object-fit:cover;opacity:0;
  transition:opacity .7s var(--ease);}
.i-shot img.ready{opacity:1;}
.i-shot::after{
  content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,transparent 46%,rgba(6,6,8,.78));
}
.i-shot-body{position:absolute;left:0;right:0;bottom:0;z-index:2;padding:16px 18px;}
.i-shot-body .c-tag{position:static;display:inline-block;margin-bottom:9px;}
.i-shot h1{
  font-size:clamp(1.4rem,4.2vw,1.85rem);line-height:1.1;letter-spacing:-.028em;color:#fff;
  text-shadow:0 2px 18px rgba(0,0,0,.45);
}

.i-body{padding:20px 18px 22px;}
.i-block{margin-bottom:20px;}
.i-block:last-child{margin-bottom:0;}
.i-block > .mono{color:var(--fg-3);margin-bottom:10px;display:block;}

.i-ings{display:flex;flex-wrap:wrap;gap:7px;}
.i-ing{
  padding:8px 13px;border-radius:100px;
  background:var(--surface-2);border:1px solid var(--line);
  font-size:.82rem;color:var(--fg-2);
}

.i-facts{display:flex;flex-wrap:wrap;gap:9px;}
.i-fact{
  flex:1;min-width:104px;
  background:var(--surface-2);border:1px solid var(--line);
  border-radius:var(--r-sm);padding:13px 14px;
}
.i-fact .mono{color:var(--fg-3);font-size:.53rem;}
.i-fact b{display:block;margin-top:6px;font-family:var(--display);
  font-size:1.2rem;font-weight:600;letter-spacing:-.025em;}
.i-fact b small{font-size:.58rem;font-family:var(--mono);color:var(--fg-3);
  letter-spacing:.08em;margin-left:3px;font-weight:400;}

.i-opts{display:flex;flex-direction:column;gap:8px;}

/* order footer — sticks to the bottom of the panel while the body scrolls */
.i-order{
  position:sticky;bottom:0;
  border-top:1px solid var(--line);
  background:color-mix(in srgb,var(--surface) 92%,transparent);
  backdrop-filter:blur(20px);
  -webkit-backdrop-filter:blur(20px);
  padding:16px 18px 18px;
}
.i-order-row{display:flex;align-items:center;gap:14px;margin-bottom:14px;}
.i-price{display:flex;align-items:baseline;gap:7px;}
.i-price b{font-family:var(--display);font-size:1.75rem;font-weight:600;letter-spacing:-.03em;}
.i-price span{font-family:var(--mono);font-size:.62rem;color:var(--fg-3);letter-spacing:.1em;}
/* .i-qty is defined in app.css; here it just sits to the right */
.i-order-row .i-qty{margin-left:auto;background:var(--surface);}
.i-cta{width:100%;}

.i-more{margin-top:4px;}
.i-more .c-grid{grid-template-columns:repeat(3,1fr);gap:9px;}
.i-more .c-card{aspect-ratio:3 / 4;border-radius:var(--r);}
.i-more .c-card h3{font-size:.82rem;line-height:1.2;}
.i-more .c-card .c-price{font-size:.8rem;}
.i-more .c-card-body{padding:11px;}
.i-more .c-card-info{gap:5px;}
.i-more .c-card-foot{margin-top:2px;}

/* ══════════════════ MOBILE ══════════════════ */
@media (max-width:760px){
  /* svh so the hero is not cut off by the browser's own chrome */
  .hero{min-height:88svh;padding:0 18px 34px;}
  .hero-top{padding:16px 18px;}
  .c-mark img{width:34px;height:46px;}
  .hero-kicker{margin-bottom:16px;}
  .hero-title{font-size:clamp(2.4rem,11vw,3.4rem);}
  .hero-lede{font-size:.92rem;margin-top:16px;}
  .hero-meta{margin-top:20px;gap:7px;}
  .hero-pill{padding:8px 13px;font-size:.52rem;}

  .c-main{padding:24px 14px 132px;}
  .c-sec{margin-bottom:38px;}
  .c-sec-head{gap:12px;margin-bottom:16px;}

  /* two across — one column is too much scrolling for an 82-item menu */
  .c-grid{grid-template-columns:repeat(2,1fr);gap:10px;}
  .c-card-body{padding:11px 12px 12px;}
  .c-card-info{gap:4px;}
  .c-card h3{font-size:.92rem;}
  .c-card .c-recipe{font-size:.72rem;}
  .c-card-meta{display:none;}
  .c-card-foot{padding-top:9px;}
  .c-price{font-size:1rem;}
  .c-add{width:34px;height:34px;}
  .c-add svg{width:15px;height:15px;}
  .c-kcal{top:7px;right:7px;padding:4px 7px;font-size:.46rem;}

  /* Bottom offset deliberately not set here — it is owned by the one rule
     under .c-bar.up, so there is a single place that decides it. */
  .c-bar{
    left:14px;right:14px;width:auto;gap:10px;
    transform:translateY(180%);padding:8px 8px 8px 16px;
  }
  .c-bar.up{transform:none;}
  .c-bar-info b{font-size:.9rem;}
  .c-bar-info span{font-size:.5rem;}
  .c-bar .btn{padding:10px 16px;font-size:.6rem;}

  /* the item panel becomes a bottom sheet at this size */
  .i-back-drop{padding:0;align-items:flex-end;}
  .i-card{
    max-width:none;max-height:92svh;
    border-radius:var(--r-xl) var(--r-xl) 0 0;
    animation:card-rise .42s var(--ease);
  }
  @keyframes card-rise{from{transform:translateY(100%);}}
  .i-shot{height:158px;}
  .i-body{padding:18px 16px 20px;}
  .i-order{padding:14px 16px calc(16px + env(safe-area-inset-bottom));}
  .i-more .c-grid{grid-template-columns:repeat(3,1fr);gap:8px;}
  .i-more .c-card h3{font-size:.74rem;}
  .i-more .c-card .c-price{font-size:.72rem;}
  .chip-opt{padding:9px 13px;}

  .c-sheet{max-height:92svh;padding:20px 16px calc(24px + env(safe-area-inset-bottom));}
  .c-line-shot{width:50px;height:50px;}
  .foot{padding:30px 18px 40px;}
}

/* very small phones */
@media (max-width:380px){
  .c-grid{grid-template-columns:1fr;}
  .i-more .c-grid{grid-template-columns:repeat(2,1fr);}
}

/* ── memberships: the panel across the top of the menu ──────────────────
   The plans as the membership cards themselves, in their own teal shades
   (one ladder: Daily Pass jade, Student, Remote, Pro near-black with gold),
   on a light panel so the cards are what you see. Wide: fanned like a hand
   of cards — each straightens and lifts forward under the pointer. Phone:
   stacked like a wallet, each card's top showing name and price. */
.ms-promo{grid-column:1 / -1;margin:0 0 6px;min-width:0;}
.ms-promo[hidden]{display:none;}
.msp-panel{
  position:relative;overflow:hidden;isolation:isolate;
  display:grid;grid-template-columns:minmax(280px,.75fr) minmax(0,2fr);gap:30px;align-items:center;
  padding:30px 34px 30px 40px;border-radius:32px;
  background:
    radial-gradient(60% 90% at 100% 0%,rgba(17,80,75,.10) 0%,transparent 60%),
    radial-gradient(50% 80% at 0% 100%,rgba(216,185,136,.16) 0%,transparent 60%),
    var(--surface);
  border:1px solid var(--line);
  box-shadow:var(--shadow-sm);
}
.msp-bird{position:absolute;z-index:-1;pointer-events:none;left:-60px;bottom:-120px;width:360px;height:440px;
  background:url('../img/loyalty-bird.png') no-repeat left top/100% auto;opacity:.06;}
:root[data-theme="dark"] .msp-bird{filter:invert(1);opacity:.07;}
.msp-kicker{display:flex;align-items:center;gap:6px;margin:0 0 10px;font-family:var(--mono);font-size:.62rem;
  letter-spacing:.18em;text-transform:uppercase;color:var(--gold);}
.msp-kicker svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linejoin:round;}
.msp-title{margin:0;font-family:var(--display);font-size:clamp(1.5rem,2.7vw,2.2rem);line-height:1.08;color:var(--fg);}
.msp-title em{font-style:normal;color:var(--accent);}
.msp-sub{margin:10px 0 0;font-family:var(--mono);font-size:.62rem;letter-spacing:.16em;text-transform:uppercase;color:var(--fg-3);}
.msp-from{margin:16px 0 0;font-size:.86rem;color:var(--fg-2);}
.msp-from b{font-family:var(--display);font-size:1.15rem;color:var(--fg);}
.msp-all{margin-top:18px;display:inline-flex;align-items:center;gap:5px;padding:9px 15px;border-radius:999px;
  border:1px solid var(--line-2);color:var(--fg);font-size:.78rem;font-weight:600;background:var(--surface);
  transition:background var(--tap) var(--ease);}
.msp-all:hover{background:var(--surface-2);}
.msp-all svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2.2;}

/* the deck */
.mcd-deck{position:relative;height:260px;min-width:0;}
.mcd{
  --a:#1F6964;--b:#093532;--w:clamp(250px,24vw,300px);
  position:absolute;top:30px;left:calc(var(--i) * (100% - var(--w)) / 3);width:var(--w);aspect-ratio:1.586;
  display:flex;flex-direction:column;padding:15px 16px 13px;border-radius:18px;overflow:hidden;isolation:isolate;
  text-align:left;color:#F4EEE3;font:inherit;cursor:pointer;
  background:linear-gradient(140deg,var(--a) 0%,var(--b) 100%);
  border:1px solid rgba(255,255,255,.12);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 16px 30px rgba(6,40,37,.28);
  rotate:var(--r);translate:0 var(--y);z-index:var(--i);
  transition:rotate .45s cubic-bezier(.2,.9,.3,1),translate .45s cubic-bezier(.2,.9,.3,1),
             scale .45s cubic-bezier(.2,.9,.3,1),box-shadow .45s,opacity .5s;
}
.mcd-daily{--a:#5DB39E;--b:#237A69;}
.mcd-student{--a:#3A9486;--b:#1C6760;}
.mcd-remote{--a:#1F6964;--b:#093532;}
.mcd-pro{--a:#123F3B;--b:#031816;}
/* a sheen across the top-left, like light on a plastic card */
.mcd::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(120deg,rgba(255,255,255,.18) 0%,transparent 38%);}
.mcd-bird{position:absolute;z-index:-1;pointer-events:none;right:-40px;top:-14px;width:170px;height:210px;
  background:url('../img/loyalty-bird.png') no-repeat left top/100% auto;opacity:.14;filter:invert(1);}
.mcd:hover,.mcd:focus-visible{rotate:0deg;translate:0 -14px;scale:1.05;z-index:10;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 28px 44px rgba(6,40,37,.36);}
.mcd-head{display:flex;justify-content:space-between;align-items:flex-start;gap:10px;}
.mcd-head > span:first-child{display:flex;flex-direction:column;gap:3px;min-width:0;}
.mcd-head i{font-style:normal;font-family:var(--mono);font-size:.52rem;letter-spacing:.16em;text-transform:uppercase;color:#D8B988;}
.mcd-head > span > b{font-family:var(--display);font-size:1.3rem;line-height:1;text-transform:uppercase;letter-spacing:.02em;color:#fff;}
.mcd-price{display:flex;flex-direction:column;align-items:flex-end;flex:none;}
.mcd-price b{font-family:var(--display);font-size:1.25rem;line-height:1;color:#fff;}
.mcd-price i{margin-top:3px;letter-spacing:.06em !important;color:rgba(244,238,227,.72) !important;}
.mcd-line{margin-top:auto;font-size:.7rem;line-height:1.35;color:rgba(244,238,227,.82);}
/* In the fan each card is covered on its right by the next, so everything
   that matters stays on the left: price under the name, the line kept short. */
.mcd-head{flex-direction:column;gap:8px;}
.mcd-price{flex-direction:row;align-items:baseline;gap:6px;}
.mcd-price i{margin-top:0;}
.mcd-line{max-width:64%;}
.mcd:last-child .mcd-line{max-width:none;}
.mcd-foot{margin-top:10px;display:flex;align-items:center;justify-content:space-between;}
.mcd-foot img{height:24px;width:auto;opacity:.95;}
.mcd-go{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:999px;
  background:#F4EEE3;color:#0A2B29;font-size:.72rem;font-weight:700;}
.mcd-pro .mcd-go{background:#D8B988;}
.mcd-go svg{width:12px;height:12px;fill:none;stroke:currentColor;stroke-width:2.4;}
/* Only the front card, or the one under the pointer, shows its Join — on a
   covered card it would peek out from under its neighbour as a stray blob. */
.mcd-go{transition:opacity .3s;}
.mcd:not(:last-child):not(:hover):not(:focus-visible) .mcd-go{opacity:0;}

/* dealt in: each card slides up into its place a beat after the last */
.mcd{opacity:0;translate:0 70px;}
.msp-in .mcd{opacity:1;translate:0 var(--y);transition-delay:calc(var(--i) * 90ms);}
.msp-in .mcd:hover,.msp-in .mcd:focus-visible{translate:0 -14px;transition-delay:0s;}
@media (prefers-reduced-motion:reduce){ .mcd{opacity:1;translate:0 var(--y);transition:none;} }

@media (max-width:1180px){
  .msp-panel{grid-template-columns:1fr;gap:10px;}
  .mcd-deck{height:250px;}
}
@media (max-width:1080px){
  .ms-promo{margin-bottom:34px;}
}
/* Phone: a wallet stack. Every card but the last is covered except its top
   strip — name and price — and the last lies fully open. A percentage
   margin is a share of the column's width, which is the card's width, so
   the overlap stays exact at any phone size. */
@media (max-width:700px){
  .msp-panel{padding:24px 16px 18px;border-radius:26px;gap:18px;}
  .msp-bird{left:auto;right:-110px;bottom:auto;top:-60px;width:300px;height:370px;}
  .mcd-deck{height:auto;display:flex;flex-direction:column;}
  .mcd{--w:100%;position:relative;left:auto;top:auto;rotate:0deg;padding:16px 18px 14px;border-radius:20px;
    box-shadow:0 -6px 18px rgba(6,40,37,.22);}
  .mcd + .mcd{margin-top:calc(-100% / 1.586 + 68px);}
  .mcd:hover,.mcd:focus-visible{rotate:0deg;scale:1;translate:0 0;}
  .msp-in .mcd,.msp-in .mcd:hover{translate:0 0;}
  .mcd-head > span > b{font-size:1.25rem;}
  .mcd-head{flex-direction:row;gap:10px;}
  .mcd-price{flex-direction:column;align-items:flex-end;gap:0;}
  .mcd-price i{margin-top:3px;}
  .mcd-line{max-width:none;}
}
/* ── memberships: the plans sheet (what the ribbon opens) ─────────────── */
.msp-sheet{--msp-red:#11504B;--msp-ink:#0B2E2B;overflow-x:hidden;}
/* The plan cards scroll sideways inside the sheet; nothing in the sheet may
   grow it wider than the screen. */
.msp-sheet > *{min-width:0;max-width:100%;}
.msp-head{text-align:center;margin:4px 0 18px;}
.msp-eyebrow{font-family:var(--mono);font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;color:var(--msp-red);margin:0 0 8px;}
.msp-head h2{font-family:var(--display);font-size:1.7rem;line-height:1.08;margin:0;color:var(--fg);}
.msp-head h2 em{font-style:normal;color:var(--gold);}
.msp-sub{margin:8px 0 0;color:var(--fg-3);font-family:var(--mono);font-size:.62rem;letter-spacing:.14em;text-transform:uppercase;}
.msp-plans{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(250px,1fr);gap:12px;overflow-x:auto;
  scroll-snap-type:x mandatory;padding:12px 2px 8px;width:100%;min-width:0;}
/* Every plan always in view — side by side on a wide screen, one under
   another on a phone. No sideways scrolling: a plan off to the right is a
   plan nobody sees (Pro was missed exactly that way). */
.c-sheet.msp-sheet{max-width:1000px;}
.msp-plans{grid-auto-flow:row;grid-template-columns:repeat(3,minmax(0,1fr));overflow:visible;}
@media (max-width:759px){ .msp-plans{grid-template-columns:1fr;gap:18px;} }
.msp-plan{
  position:relative;display:flex;flex-direction:column;gap:6px;padding:22px 18px 18px;border-radius:18px;
  scroll-snap-align:center;background:#FBF7F0;color:var(--msp-ink);border:1px solid rgba(17,80,75,.16);
}
.msp-plan.msp-popular{background:linear-gradient(140deg,#1F6964 0%,#11504B 52%,#093532 100%);color:#F4EEE3;border-color:#11504B;}
.msp-flag{position:absolute;top:-10px;left:50%;transform:translateX(-50%);white-space:nowrap;
  padding:3px 11px;border-radius:100px;background:#FFFFFF;color:#0B2E2B;
  font-family:var(--mono);font-size:.54rem;letter-spacing:.14em;text-transform:uppercase;}
.msp-plan h3{font-family:var(--display);font-size:1.4rem;text-transform:uppercase;letter-spacing:.03em;margin:0;color:inherit;}
.msp-tag{margin:0;font-family:var(--mono);font-size:.56rem;letter-spacing:.12em;text-transform:uppercase;opacity:.75;}
.msp-price{margin:4px 0 2px;}
.msp-price b{font-family:var(--display);font-size:1.7rem;}
.msp-price span{font-size:.78rem;opacity:.75;}
.msp-plan ul{list-style:none;margin:4px 0 12px;padding:0;display:flex;flex-direction:column;gap:6px;flex:1;}
.msp-plan li{display:flex;gap:7px;align-items:flex-start;font-size:.82rem;line-height:1.35;}
.msp-plan li svg{flex:none;width:15px;height:15px;margin-top:1px;fill:none;stroke:var(--msp-red);stroke-width:2.2;}
.msp-popular li svg{stroke:#D8B988;}
.msp-join{width:100%;justify-content:center;}
.msp-popular .msp-join{background:#FFFFFF;color:#0B2E2B;border-color:#D8B988;}
.msp-plan:not(.msp-popular) .msp-join{color:var(--msp-red);border-color:rgba(17,80,75,.35);}
/* The Daily Pass, under the monthly plans — one day, one line. */
.msp-daily{display:flex;align-items:center;gap:14px;margin-top:12px;padding:16px 18px;border-radius:16px;
  background:linear-gradient(140deg,#5DB39E 0%,#237A69 100%);color:#F4EEE3;}
.msp-daily div{flex:1;min-width:0;}
.msp-daily h3{margin:0;font-family:var(--display);font-size:1.15rem;text-transform:uppercase;letter-spacing:.03em;}
.msp-daily h3 b{margin-left:6px;color:#F0DDB8;}
.msp-daily p{margin:4px 0 2px;font-size:.8rem;opacity:.85;}
.msp-daily i{font-size:.72rem;opacity:.6;}
.msp-daily .msp-join{width:auto;flex:none;color:#F4EEE3;border-color:rgba(244,238,227,.45);}
@media (max-width:520px){ .msp-daily{flex-direction:column;align-items:stretch;} .msp-daily .msp-join{width:100%;} }
.msj-renew{width:100%;max-width:340px;margin-top:12px;}

/* ── memberships: the join sheet and the card sheet ─────────────────── */
.msj-plans{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin-bottom:12px;}
@media (max-width:520px){ .msj-plans{grid-template-columns:repeat(2,1fr);} }
.msj-plan{display:flex;flex-direction:column;gap:2px;padding:10px 8px;border-radius:12px;
  border:1px solid var(--line);background:var(--surface-2);color:var(--fg);font:inherit;cursor:pointer;}
.msj-plan b{font-size:.95rem;}
.msj-plan span{font-family:var(--mono);font-size:.62rem;color:var(--fg-3);}
.msj-plan.on{background:var(--accent-grad);border-color:var(--accent-fill);color:#F4EEE3;}
.msj-plan.on span{color:rgba(244,238,227,.78);}
.msj-perks{list-style:none;margin:0 0 14px;padding:0;display:grid;grid-template-columns:1fr 1fr;gap:6px 12px;}
.msj-perks li{display:flex;gap:6px;font-size:.8rem;color:var(--fg-2);line-height:1.3;}
.msj-perks svg{flex:none;width:14px;height:14px;fill:none;stroke:var(--accent);stroke-width:2.4;margin-top:1px;}
.msj-insta{margin-top:10px;padding:12px;border-radius:12px;background:var(--surface-2);font-size:.88rem;}
.msj-insta p{margin:0 0 8px;}
.msj-insta img{display:block;width:150px;height:150px;object-fit:contain;margin:0 0 8px;background:#fff;border-radius:8px;}
.msj-done{text-align:center;margin-bottom:12px;}
.msj-done h3{margin:10px 0 0;}
.msj-renews{max-width:340px;width:100%;margin:6px 0 0;font-family:var(--mono);font-size:.68rem;
  letter-spacing:.06em;color:var(--fg-3);text-align:center;}
.msj-next{max-width:340px;width:100%;margin:14px 0 0;font-size:.88rem;color:var(--fg-2);line-height:1.45;text-align:center;}
@media (max-width:420px){ .msj-perks{grid-template-columns:1fr;} }

/* ── basket: close and clear ─────────────────────────────────────── */
.c-sheet{position:relative;}
.c-sheet-x{
  position:absolute;top:14px;right:14px;z-index:2;width:36px;height:36px;border-radius:50%;
  display:grid;place-items:center;background:var(--surface-2);border:1px solid var(--line);color:var(--fg-2);
  transition:background var(--tap) var(--ease),color var(--tap) var(--ease),transform var(--tap) var(--ease);
}
.c-sheet-x:hover{background:var(--surface-3);color:var(--fg);}
.c-sheet-x:active{transform:scale(.92);}
.c-sheet-x svg{width:16px;height:16px;stroke:currentColor;stroke-width:2.2;fill:none;stroke-linecap:round;}
.c-clear{
  display:flex;align-items:center;justify-content:center;gap:7px;width:100%;margin-top:10px;padding:11px;
  border-radius:100px;border:1px solid transparent;color:var(--fg-3);font-size:.84rem;font-weight:600;
  transition:color .2s var(--ease),background .2s var(--ease),border-color .2s var(--ease);
}
.c-clear svg{width:16px;height:16px;stroke:currentColor;stroke-width:1.9;fill:none;stroke-linecap:round;stroke-linejoin:round;}
.c-clear:hover{color:var(--danger);}
.c-clear.armed{color:#fff;background:var(--danger);border-color:var(--danger);}

/* Happy hour: a ribbon on the photo and the old price struck through. */
.c-card-img{position:relative;}
.c-promo{position:absolute;top:10px;left:10px;z-index:2;padding:5px 10px;border-radius:999px;
  background:var(--accent-fill);color:var(--accent-ink);font-family:var(--mono);font-size:.58rem;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;box-shadow:0 4px 12px rgba(0,0,0,.18);}
.c-price s{opacity:.5;font-size:.72em;margin-right:6px;font-weight:400;}

/* ── happy hour on the guest page (customer.js hhBannerHTML()) ───────── */
.hh-banner{margin:0 0 26px;padding:18px 20px;border-radius:22px;
  background:linear-gradient(120deg,color-mix(in srgb,#D9A441 16%,var(--surface)) 0%,var(--surface) 70%);
  border:1px solid color-mix(in srgb,#D9A441 35%,var(--line));display:flex;flex-direction:column;gap:14px;}
.hh-banner.live{background:linear-gradient(120deg,color-mix(in srgb,#D9A441 26%,var(--surface)) 0%,color-mix(in srgb,#D9A441 6%,var(--surface)) 80%);}
.hh-head{display:flex;align-items:center;gap:12px;flex-wrap:wrap;}
.hh-head p{margin:0;color:var(--fg-2);font-size:.86rem;}
.hh-badge{display:inline-flex;align-items:center;gap:8px;padding:6px 13px;border-radius:999px;
  background:#D9A441;color:#24180A;font-family:var(--mono);font-size:.62rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;}
.hh-badge i{width:7px;height:7px;border-radius:50%;background:#24180A;animation:hh-pulse 1.6s ease-in-out infinite;}
@keyframes hh-pulse{0%,100%{opacity:1;}50%{opacity:.3;}}
.hh-offers{display:grid;grid-template-columns:repeat(auto-fill,minmax(260px,1fr));gap:10px;}
.hh-offer{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;column-gap:14px;row-gap:4px;align-items:center;
  padding:12px 14px;border-radius:16px;background:color-mix(in srgb,var(--bg) 55%,transparent);border:1px solid var(--line);}
.hh-offer.on{border-color:color-mix(in srgb,#D9A441 55%,transparent);}
.hh-offer b{grid-row:1 / span 2;font-family:var(--display);font-size:1.7rem;font-weight:600;letter-spacing:-.03em;color:#C98F2A;}
.hh-offer span{display:flex;flex-direction:column;min-width:0;}
.hh-offer strong{font-size:.92rem;}
.hh-offer em{font-style:normal;font-size:.76rem;color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.hh-offer i{font-style:normal;font-family:var(--mono);font-size:.62rem;letter-spacing:.08em;color:var(--fg-2);}
.hh-offer.on i{color:#C98F2A;font-weight:600;}
.c-sec-hh .c-sec-no{color:#C98F2A;}
@media (max-width:620px){ .hh-banner{padding:14px;border-radius:18px;} .hh-offers{grid-template-columns:1fr;} }

/* The café's day is closed — shown above the menu (customer.js closedBannerHTML()). */
.closed-banner{grid-column:1/-1;margin:0 0 44px;padding:16px 18px;border-radius:18px;
  background:var(--danger-soft);border:1px solid color-mix(in srgb,var(--danger) 35%,transparent);}
.closed-banner b{display:block;font-size:1rem;color:var(--danger);}
.closed-banner p{margin:4px 0 0;color:var(--fg-2);font-size:.9rem;}

/* ── 1718 Neighbours (mall staff card) — customer.js openNeighbours() ── */
.nb-badge svg{fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.nb-lede{margin:8px auto 0;max-width:34ch;text-align:center;color:var(--fg-2);font-size:.92rem;line-height:1.45;}
.nb-link{display:block;width:100%;margin-top:10px;padding:12px 14px;border-radius:14px;
  background:color-mix(in srgb,var(--accent) 8%,transparent);border:1px solid color-mix(in srgb,var(--accent) 22%,transparent);}
.nb-link b{color:var(--accent);}
.nb-link{text-decoration:none;}

/* Loyalty sheet: under "Find my card", two side-by-side choices — join
   loyalty, or the 1718 Neighbours card (mall staff). */
.l-pick{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:16px;}
.l-tile{display:flex;flex-direction:column;align-items:flex-start;gap:6px;text-align:left;
  padding:14px 14px 15px;border-radius:16px;cursor:pointer;font:inherit;color:var(--fg-1);
  background:var(--surface,rgba(255,255,255,.6));border:1px solid var(--line,rgba(0,0,0,.08));
  transition:border-color var(--tap,.2s) var(--ease,ease),transform var(--tap,.2s) var(--ease,ease);}
.l-tile:hover{border-color:var(--accent-line);}
.l-tile:active{transform:scale(.98);}
.l-tile b{font-size:.95rem;font-weight:600;line-height:1.2;}
.l-tile > span:last-child{font-size:.78rem;line-height:1.35;color:var(--fg-2);}
.l-ico{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;margin-bottom:2px;
  background:var(--accent-soft);border:1px solid var(--accent-line);color:var(--accent);}
.l-ico svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linejoin:round;stroke-linecap:round;}

/* ── Upcoming events (customer.js drawEvents()) ──
   Just above the menu. Cards sit in a row that scrolls sideways on a phone.
   A picture keeps its own shape (its width and height come from the server),
   so tall posters and wide banners both show whole — nothing is cropped. */
.events{max-width:1480px;margin:clamp(28px,5vw,64px) auto 0;padding:0 clamp(14px,3vw,28px);}
.events[hidden]{display:none;}
.ev-head{margin-bottom:clamp(14px,2vw,22px);}
.ev-kick{margin:0 0 6px;font:500 11px/1 var(--mono,ui-monospace,monospace);letter-spacing:.22em;text-transform:uppercase;color:var(--accent);}
.ev-head h2{margin:0;font-family:'Anton',var(--display),sans-serif;font-weight:400;text-transform:uppercase;
  font-size:clamp(2rem,4.6vw,3.4rem);line-height:.95;letter-spacing:.005em;color:var(--fg-1,#16130F);}
.ev-row{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(280px,360px);gap:16px;align-items:stretch;
  overflow-x:auto;scroll-snap-type:x mandatory;padding:2px 2px 14px;scrollbar-width:thin;}
.ev-card{scroll-snap-align:start;display:flex;flex-direction:column;border-radius:22px;overflow:hidden;cursor:pointer;
  background:var(--card,#FBF7EF);border:1px solid var(--line,rgba(0,0,0,.07));box-shadow:0 14px 34px -22px rgba(17,80,75,.35);
  transition:transform .25s var(--ease,ease),box-shadow .25s var(--ease,ease);}
.ev-card:hover{transform:translateY(-3px);box-shadow:0 22px 40px -24px rgba(17,80,75,.45);}
.ev-img{display:block;width:100%;height:auto;background:color-mix(in srgb,var(--accent) 10%,transparent);}
.ev-body{flex:1;display:flex;gap:14px;padding:16px 16px 18px;}
.ev-date{flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;width:66px;height:76px;border-radius:16px;
  background:linear-gradient(160deg,#1C6A62,#0E433F);color:#F6EFE2;box-shadow:0 10px 20px -10px rgba(17,80,75,.6);}
.ev-date b{font-size:2rem;line-height:1;font-weight:700;letter-spacing:-.02em;}
.ev-date span{font:600 11px/1 var(--mono,ui-monospace,monospace);letter-spacing:.16em;text-transform:uppercase;margin-top:5px;color:#E5CC94;}
.ev-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px;}
.ev-text h3{margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;font-family:'Anton',var(--display),sans-serif;font-weight:400;text-transform:uppercase;letter-spacing:.01em;
  font-size:clamp(1.45rem,2vw,1.75rem);line-height:1.02;color:var(--fg-1,#16130F);}
.ev-when{margin:2px 0 0;font-size:.84rem;font-weight:600;color:var(--accent,#11504B);}
/* only a taste of the description here — the whole of it is in the details sheet */
.ev-desc{margin:4px 0 0;font-size:.86rem;line-height:1.45;color:var(--fg-2);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
/* an event with no picture still gets a picture-shaped space, so the row lines up */
.ev-noimg{aspect-ratio:4/3;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;color:#F3ECDD;
  background:url(../img/loyalty-bird.png) right -30px bottom -30px/70% no-repeat,radial-gradient(120% 90% at 100% 0%,#1E6B63,#11504B 50%,#0B3936);}
.ev-noimg span{font-family:'Anton',var(--display),sans-serif;font-size:3.2rem;line-height:1;letter-spacing:.02em;}
.ev-noimg i{font:600 11px/1 var(--mono,ui-monospace,monospace);font-style:normal;letter-spacing:.28em;text-transform:uppercase;color:#E5CC94;}
.ev-foot{display:flex;align-items:center;justify-content:flex-start;gap:8px;margin-top:auto;padding-top:12px;flex-wrap:wrap;}
.ev-tag{display:inline-block;padding:5px 10px;border-radius:999px;font-size:.72rem;font-weight:600;
  background:color-mix(in srgb,var(--accent) 10%,transparent);color:var(--accent);}
.ev-tag.ticket{background:rgba(201,168,106,.18);color:#7A5A1E;}
.ev-tag.full{background:rgba(176,68,46,.1);color:#B0442E;}
.ev-live{align-self:flex-start;padding:3px 9px;border-radius:999px;font-size:.68rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  background:#B0442E;color:#fff;}
/* one or two events: a panel fills the rest of the row (evAside()); three or
   more and it is not drawn. On a phone it sits under the card(s). */
.events.has-aside .ev-row{grid-auto-flow:row;grid-template-columns:repeat(var(--ev-n),minmax(280px,360px)) minmax(300px,1fr);overflow:visible;}
.ev-aside{position:relative;overflow:hidden;align-self:stretch;display:flex;
  border-radius:22px;container-type:inline-size;
  background:var(--card,#FBF7EF);border:1px solid var(--line,rgba(0,0,0,.07));box-shadow:0 14px 34px -22px rgba(17,80,75,.35);}
.ev-aside-in{flex:1;display:grid;grid-template-rows:auto 1fr;}
/* one of the signature cups — on a warm glow beside the words once there is
   room, a short band above them while the panel is narrow */
.ev-aside-cup{position:relative;display:flex;align-items:flex-end;justify-content:center;min-height:190px;overflow:hidden;
  background:radial-gradient(60% 70% at 50% 70%,rgba(238,138,54,.32),rgba(238,138,54,.08) 60%,transparent 75%);}
.ev-aside-cup img{width:auto;height:240px;max-width:none;margin-bottom:-56px;rotate:8deg;
  filter:drop-shadow(0 24px 30px rgba(120,50,10,.28));}
.ev-aside-text{display:flex;flex-direction:column;gap:12px;padding:clamp(20px,2.6vw,32px);}
@container (min-width:600px){
  .ev-aside-in{grid-template-rows:none;grid-template-columns:minmax(0,1.25fr) minmax(0,.85fr);}
  /* the words set the panel's height; the cup is placed inside its half and
     never pushes it taller */
  .ev-aside-cup{order:2;min-height:0;display:block;
    background:radial-gradient(70% 60% at 50% 62%,rgba(238,138,54,.3),rgba(238,138,54,.07) 62%,transparent 78%);}
  .ev-aside-cup img{position:absolute;left:50%;bottom:-8%;height:96%;margin:0;translate:-50% 0;}
}
.ev-aside h3{margin:0;font-size:clamp(1.25rem,2vw,1.7rem);line-height:1.22;font-weight:600;letter-spacing:-.01em;max-width:22ch;color:var(--fg-1,#16130F);}
.ev-aside-text > p:not(.ev-kick){margin:0;font-size:.9rem;line-height:1.55;color:var(--fg-2);max-width:44ch;}
.ev-aside-list{list-style:none;margin:4px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:8px;}
.ev-aside-list li{display:flex;align-items:center;gap:7px;padding:6px 12px;border-radius:999px;font-size:.78rem;font-weight:500;
  color:var(--accent);background:color-mix(in srgb,var(--accent) 7%,transparent);border:1px solid color-mix(in srgb,var(--accent) 16%,transparent);}
.ev-aside-list svg{width:15px;height:15px;fill:none;stroke:#B08A3E;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}
.ev-aside-act{display:flex;flex-wrap:wrap;gap:10px;margin-top:auto;padding-top:8px;}
@media (max-width:860px){
  .events.has-aside .ev-row{grid-template-columns:1fr;}
  .events.has-aside .ev-card{max-width:520px;}
}
@media (min-width:861px) and (max-width:1180px){
  .events.has-aside .ev-row{grid-template-columns:repeat(var(--ev-n),minmax(260px,330px)) minmax(260px,1fr);}
}

/* the detail sheet */
.ev-sheet-img{display:block;width:100%;height:auto;border-radius:16px;margin:4px 0 14px;max-height:60vh;object-fit:contain;
  background:color-mix(in srgb,var(--accent) 8%,transparent);}
.ev-sheet-tags{margin:8px 0 4px;}
.ev-sheet-desc{white-space:pre-line;font-size:.92rem;line-height:1.55;color:var(--fg-2);margin:10px 0;}
.ev-terms{margin:8px 0 12px;padding:10px 14px;border-radius:12px;background:color-mix(in srgb,var(--accent) 6%,transparent);}
.ev-terms summary{cursor:pointer;font-weight:600;font-size:.86rem;}
.ev-terms p{white-space:pre-line;font-size:.82rem;line-height:1.5;color:var(--fg-2);margin:8px 0 0;}
.ev-agree{display:flex;align-items:center;gap:8px;font-size:.85rem;margin-top:4px;}
.ev-note{margin:14px 0 4px;padding:12px 14px;border-radius:12px;text-align:center;font-weight:600;font-size:.9rem;
  background:color-mix(in srgb,var(--accent) 8%,transparent);color:var(--accent);}
/* on a phone the row is swiped one card at a time — each card its own height,
   rather than stretched to the tallest one beside it */
@media (max-width:640px){ .ev-row{align-items:start;} .events:not(.has-aside) .ev-foot{margin-top:6px;} }
/* the "More at 1718" panel is for a wide screen with room to spare — not on a phone or tablet */
@media (max-width:860px){ .ev-aside{display:none;} }

/* Offers (customer.js paintOffers): a banner per menu offer, with the cups and
   the parrot, then a slim strip of promo codes. */
.offers{scroll-margin-top:24px;}
.of-sale{position:relative;overflow:hidden;display:block;margin-bottom:14px;min-height:clamp(250px,25vw,320px);padding:clamp(22px,3vw,38px) clamp(22px,4vw,52px);
  border-radius:clamp(20px,2.4vw,30px);color:#F3ECDD;text-decoration:none;
  background:radial-gradient(60% 130% at 78% 110%,rgba(226,205,162,.34),transparent 70%),radial-gradient(110% 150% at 0% 0%,#1B6E66,#0B3C38 62%);}
.of-sale::before{content:'';position:absolute;right:clamp(-120px,-6vw,-40px);top:50%;width:clamp(380px,46vw,640px);aspect-ratio:1;translate:0 -50%;border-radius:50%;
  border:1px dashed rgba(229,204,148,.3);box-shadow:0 0 0 clamp(26px,3.4vw,46px) rgba(255,255,255,.025),inset 0 0 0 clamp(36px,4.6vw,64px) rgba(255,255,255,.025);}
.of-sale-main{position:relative;z-index:2;max-width:min(54%,560px);}
.of-sale-key{display:inline-block;margin-bottom:12px;padding:6px 11px;border-radius:7px;background:#E2CDA2;color:#0B3C38;font:700 10px/1 var(--mono,ui-monospace,monospace);letter-spacing:.18em;text-transform:uppercase;}
.of-sale-line{display:flex;align-items:center;gap:14px;}
.of-sale-line b{font-family:'Anton',var(--display),sans-serif;font-weight:400;font-size:clamp(4rem,8vw,6.6rem);line-height:.95;color:#fff;}
.of-sale-line span{font-family:'Anton',var(--display),sans-serif;text-transform:uppercase;font-size:clamp(1.1rem,2.1vw,1.8rem);line-height:1.08;color:#E5CC94;}
.of-sale h3{margin:12px 0 3px;font-size:1.12rem;font-weight:700;color:#fff;}
.of-sale p{margin:0;line-height:1.45;color:rgba(243,236,221,.78);}
.of-sale-foot{display:flex;flex-wrap:wrap;align-items:center;gap:10px 18px;margin-top:16px;}
.of-sale-left{padding:9px 13px;border-radius:10px;background:rgba(255,255,255,.1);border:1px solid rgba(229,204,148,.32);font-size:.84rem;color:#E5CC94;}
.of-sale-left b{margin-left:3px;font-weight:700;color:#fff;}
.of-sale-go{display:inline-flex;align-items:center;gap:7px;font-weight:700;font-size:.94rem;color:#fff;}
.of-sale-go svg{width:17px;height:17px;fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;transition:transform .2s;}
.of-sale:hover .of-sale-go svg{transform:translateX(4px);}
.of-sale-cups{position:absolute;right:clamp(8px,3vw,56px);bottom:-20%;width:clamp(300px,37vw,520px);aspect-ratio:2.1;z-index:1;}
.of-sale-cups img{position:absolute;bottom:0;width:35%;filter:drop-shadow(0 16px 20px rgba(0,0,0,.38));}
.of-sale-cups img:nth-child(1){left:0;rotate:-11deg;bottom:-6%;}
.of-sale-cups img:nth-child(2){left:21%;rotate:-3deg;width:40%;z-index:2;bottom:4%;}
.of-sale-cups img:nth-child(3){left:44%;rotate:4deg;width:40%;z-index:3;bottom:4%;}
.of-sale-cups img:nth-child(4){left:68%;rotate:11deg;bottom:-6%;}

.of-promos{display:grid;grid-template-columns:auto minmax(200px,300px) 1fr;gap:clamp(14px,2.2vw,30px);align-items:center;
  padding:12px clamp(18px,2.6vw,30px);border-radius:clamp(18px,2vw,24px);background:#F6F0E4;border:1px solid rgba(17,80,75,.12);}
.of-bird{display:block;height:92px;width:auto;opacity:.85;pointer-events:none;}
.of-promos-say .ev-kick{margin:0 0 3px;}
.of-promos-say h3{margin:0 0 2px;font-size:1.05rem;font-weight:700;color:#0B3C38;}
.of-promos-say p:last-child{margin:0;font-size:.82rem;line-height:1.35;color:#5B6B68;}
.of-chips{display:flex;flex-wrap:wrap;justify-content:flex-end;gap:10px;min-width:0;}
.of-chip{display:flex;align-items:center;gap:12px;padding:10px 12px 10px 16px;border-radius:14px;background:#fff;cursor:pointer;box-shadow:0 10px 22px -18px rgba(17,80,75,.6);}
.of-chip-text{display:flex;flex-direction:column;gap:1px;max-width:210px;min-width:0;}
.of-chip-text b{font-size:.98rem;color:#0B3C38;white-space:nowrap;}
.of-chip-text span{font-size:.78rem;color:#5B6B68;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
.of-code{padding:7px 10px;border:1.5px dashed rgba(17,80,75,.4);border-radius:8px;font:700 .78rem/1 var(--mono,ui-monospace,monospace);letter-spacing:.08em;color:#11504B;white-space:nowrap;}
@media (max-width:980px){
  .of-promos{grid-template-columns:auto 1fr;}
  .of-chips{grid-column:1/-1;justify-content:flex-start;}
}
@media (max-width:760px){
  /* A compact card on a phone: the words on the left, two whole cups on the right. */
  .of-sale{min-height:0;padding:18px;background:radial-gradient(90% 120% at 100% 100%,rgba(226,205,162,.3),transparent 70%),radial-gradient(120% 150% at 0% 0%,#1B6E66,#0B3C38 65%);}
  .of-sale::before{display:none;}
  .of-sale-main{max-width:60%;}
  .of-sale-key{margin-bottom:8px;padding:5px 8px;font-size:9px;}
  .of-sale-line{display:block;}
  .of-sale-line b{display:block;font-size:4rem;}
  .of-sale-line span{display:block;margin-top:2px;font-size:.92rem;}
  .of-sale-line span br{display:none;}
  .of-sale h3{margin:9px 0 1px;font-size:.98rem;}
  .of-sale p{font-size:.8rem;line-height:1.3;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
  .of-sale-foot{margin-top:11px;gap:0;}
  .of-sale-left{padding:7px 10px;font-size:.76rem;white-space:nowrap;}
  .of-sale-go{display:none;}
  .of-sale-app .of-sale-main{max-width:55%;}
  .of-sale-app .of-sale-foot{gap:9px;}
  .of-sale-app .of-sale-go{display:inline-flex;font-size:.84rem;}
  .of-sale-cups{right:8px;bottom:-10px;width:43%;aspect-ratio:auto;height:100%;}
  .of-sale-cups img:nth-child(1),.of-sale-cups img:nth-child(4){display:none;}
  .of-sale-cups img:nth-child(2){left:auto;right:38%;bottom:0;width:60%;rotate:-7deg;}
  .of-sale-cups img:nth-child(3){left:auto;right:0;bottom:-4px;width:70%;rotate:6deg;}
  .of-bird{height:72px;}
  .of-chip{flex:1 1 100%;flex-wrap:wrap;}
  .of-chip-text{flex:1 1 74px;max-width:none;}
  .of-chip .btn{margin-left:auto;}
}

@media (max-width:380px){
  .of-chip .btn{flex:1 1 100%;margin-left:0;}
}

/* The promo box at checkout. */
.pc-box{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;}
.pc-row{display:flex;gap:8px;}
.pc-row input{flex:1;min-width:0;text-transform:uppercase;letter-spacing:.06em;}
.pc-msg{margin:0;color:var(--danger);}
.pc-taps{margin-top:2px;}
.pc-on{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:14px;background:rgba(17,80,75,.08);}
.pc-on>div{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.pc-tick{flex:none;width:28px;height:28px;border-radius:50%;background:#11504B;display:grid;place-items:center;}
.pc-tick svg{width:15px;height:15px;fill:none;stroke:#fff;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round;}

/* Your rewards at checkout: the free coffee on points and a membership, as
   switches. Same teal as the promo box beside it. */
.rw-box{display:flex;flex-direction:column;gap:8px;margin-bottom:16px;}
.rw-row{display:flex;align-items:center;gap:14px;width:100%;padding:13px 14px;border-radius:14px;text-align:left;
  background:var(--surface-2);border:1.5px solid var(--line-2);color:var(--fg);cursor:pointer;
  transition:background .2s,border-color .2s;}
.rw-row.on{background:rgba(17,80,75,.08);border-color:#11504B;}
.rw-row:disabled{opacity:.55;cursor:default;}
.rw-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px;}
.rw-main b{font-size:15px;line-height:1.3;}
.rw-main .mono{color:var(--fg-3);line-height:1.5;}
.rw-sw{flex:none;position:relative;width:42px;height:25px;border-radius:13px;background:var(--line-2);transition:background .2s;}
.rw-sw i{position:absolute;top:3px;left:3px;width:19px;height:19px;border-radius:50%;background:#fff;
  box-shadow:0 1px 3px rgba(0,0,0,.25);transition:transform .22s cubic-bezier(.3,.7,.3,1);}
.rw-row.on .rw-sw{background:#11504B;}
.rw-row.on .rw-sw i{transform:translateX(17px);}
.rw-note{margin:0;color:var(--fg-3);line-height:1.6;}
.rw-out{display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:12px 14px;border-radius:14px;background:rgba(17,80,75,.08);}
.rw-out .mono{flex:1 1 180px;line-height:1.6;}

/* The app's two store buttons — in the hero and in the section before the footer. */
.dl-badges{display:flex;flex-wrap:wrap;gap:10px;}
.dl-badge{display:inline-flex;align-items:center;gap:10px;height:54px;padding:0 18px 0 14px;border-radius:12px;background:#0B0F0E;color:#fff;
  border:1px solid rgba(255,255,255,.2);text-decoration:none;font-weight:600;font-size:1.02rem;line-height:1.1;transition:transform .2s;}
.dl-badge:hover{transform:translateY(-2px);}
.dl-badge svg{width:26px;height:26px;flex:none;}
.dl-badge span{display:flex;flex-direction:column;}
.dl-badge small{font-size:.66rem;font-weight:500;opacity:.8;}
/* Above "See the menu", where the cup leaves the corner clear. */
.sig-dl{position:absolute;z-index:60;right:clamp(16px,4vw,44px);bottom:calc(clamp(20px,5vh,64px) + clamp(19px,3.6vw,50px) + 46px);display:flex;flex-direction:column;align-items:flex-end;gap:8px;}
.sig-dl .dl-badge{background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.5);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);}
.sig-dl .dl-badge:hover{background:rgba(255,255,255,.24);}
.sig-dl-key{font:600 11px/1 var(--mono,ui-monospace,monospace);letter-spacing:.24em;text-transform:uppercase;color:#fff;}

.app-get{position:relative;overflow:hidden;display:grid;grid-template-columns:1.1fr .9fr;align-items:center;gap:clamp(20px,4vw,64px);
  margin:0 clamp(10px,2vw,28px) clamp(40px,7vw,96px);padding:clamp(32px,6vw,84px) clamp(22px,6vw,96px) 0;border-radius:clamp(22px,3vw,40px);
  background:radial-gradient(120% 120% at 0% 0%,#17605A,#0B3C38 60%);color:#F3ECDD;}
.app-get-say{padding-bottom:clamp(32px,6vw,84px);}
.app-get-key{font:600 11px/1 var(--mono,ui-monospace,monospace);letter-spacing:.24em;text-transform:uppercase;color:#E5CC94;}
.app-get h2{margin:14px 0 12px;font-family:'Anton',var(--display),sans-serif;font-weight:400;text-transform:uppercase;line-height:1.02;font-size:clamp(2.4rem,5.4vw,4.6rem);}
.app-get p{margin:0 0 24px;max-width:46ch;line-height:1.55;color:rgba(243,236,221,.82);}
.app-get-phone{align-self:end;justify-self:center;width:min(100%,340px);height:clamp(360px,44vw,520px);overflow:hidden;border-radius:36px 36px 0 0;
  border:8px solid rgba(255,255,255,.14);border-bottom:0;background:#000;box-shadow:0 -10px 50px rgba(0,0,0,.3);}
.app-get-phone img{display:block;width:100%;}
@media (max-width:760px){
  .app-get{grid-template-columns:1fr;text-align:left;}
  .app-get-say{padding-bottom:0;}
  .app-get-phone{height:340px;width:min(82%,300px);}
  .dl-badge{height:48px;padding:0 14px 0 11px;font-size:.92rem;}
}
/* On a phone the two buttons take the place of the info pills, which keep their
   room so the drink's name stays where it was. */
@media (max-width:640px){
  .sig-pills{visibility:hidden;height:52px;overflow:hidden;}
  .sig-dl{left:clamp(16px,4vw,44px);right:clamp(16px,4vw,44px);bottom:82px;align-items:flex-start;}
  .sig-dl-key{display:none;}
  .sig-dl .dl-badges{gap:8px;flex-wrap:nowrap;}
  .sig-dl .dl-badge{height:40px;padding:0 11px 0 9px;gap:7px;font-size:.8rem;}
  .sig-dl .dl-badge svg{width:20px;height:20px;}
  .sig-dl .dl-badge small{font-size:.55rem;}
}
