/* ═══════════════════════════════════════════════════════════════════════════
   Combos — Ikoyi, Lagos

   Every colour here was sampled from their own printed menu card: the red of
   the MENU headline, the coral of the price bubbles, the cream field behind
   everything, the amber dots, and the near-black of the wordmark. Their brand
   is already loud, warm and graphic — the job is to build in it, not around it.

   Cream ground rather than dark, because that is what their card is, and
   because five builds in a row of dark hero pages would be a habit rather than
   a decision.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  --cream:    #FCE6C2;
  --cream-2:  #FFF4E2;
  --cream-3:  #F6D9AE;
  /* Their menu red, kept exactly as sampled for large display type where the
     3:1 large-text floor applies. --red-ink is the same hue stepped down until
     it clears 4.5:1 on cream, for anything set at body size; --red-solid is the
     step at which white text on top of it clears 4.5:1 too.
       #E52C2E on cream ... 3.64  (fails at body size)
       #C41F21 on cream ... 4.83  (passes)
       white on #C41F21 ... 5.89  (passes) */
  --red:      #E52C2E;
  --red-ink:  #C41F21;
  --red-solid:#C41F21;
  --red-dk:   #A81A1C;
  --coral:    #FA8C7A;
  --coral-lt: #FCC4B2;
  --amber:    #EBAC3C;
  --ink:      #0E1212;
  /* Warm mid-tone. A neutral grey on cream goes green. */
  --mud:      #6B5A46;
  --line:     rgba(14,18,18,.14);
  --line-2:   rgba(14,18,18,.07);

  --display:"Bricolage Grotesque",Impact,"Arial Black",sans-serif;
  --body:"Outfit",system-ui,-apple-system,"Segoe UI",sans-serif;

  --pad:clamp(1.15rem,4.5vw,4.5rem);
  --maxw:1300px;
  --ease:cubic-bezier(.22,1,.36,1);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;color-scheme:light}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
[id]{scroll-margin-top:5.5rem}

body{
  margin:0;background:var(--cream);color:var(--ink);
  font-family:var(--body);font-weight:400;
  font-size:clamp(1rem,.96rem + .2vw,1.07rem);line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

/* The blobs from their card. Big soft shapes in cream-3, sitting under
   everything, so the page reads as the same printed object. */
body::before{
  content:'';position:fixed;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(38% 30% at 8% 12%,var(--cream-3) 0 60%,transparent 62%),
    radial-gradient(30% 26% at 96% 40%,var(--cream-3) 0 60%,transparent 62%),
    radial-gradient(44% 24% at 60% 96%,var(--cream-3) 0 60%,transparent 62%);
  opacity:.75;
}
main,.nav,.foot{position:relative;z-index:1}

img{max-width:100%;height:auto;display:block}
a{color:inherit}
::selection{background:var(--red-solid);color:#fff}
:focus-visible{outline:3px solid var(--ink);outline-offset:2px}
body{caret-color:var(--red)}
html{scrollbar-color:var(--coral) var(--cream)}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:var(--cream)}
::-webkit-scrollbar-thumb{background:var(--coral);border:3px solid var(--cream)}
button,a{touch-action:manipulation}

.skip{position:absolute;left:-9999px;top:0;z-index:300;background:var(--ink);color:var(--cream);padding:.8rem 1.3rem;font-weight:600}
.skip:focus{left:0}

/* ── type ─────────────────────────────────────────────────────────────────
   Bricolage is chunky and very slightly off-register, which is how the
   headings on their card are drawn. Outfit is the plain warm voice under it. */
h1,h2,h3{font-family:var(--display);font-weight:800;line-height:.94;letter-spacing:-.02em;margin:0}
h1{font-size:clamp(2.9rem,1.5rem + 6.4vw,6.4rem)}
h2{font-size:clamp(2.1rem,1.2rem + 4vw,4.4rem);text-wrap:balance}
h1 em,h2 em{font-style:normal;color:var(--red)}
.lede{color:var(--mud);max-width:48ch;margin:1.1rem 0 0;font-size:1.05rem}
.head{max-width:52ch;margin-bottom:clamp(2rem,4.5vw,3.5rem)}

/* ── buttons ──────────────────────────────────────────────────────────────
   Fully rounded, like the price bubbles on the card. */
.btn{
  --bg:var(--ink);--fg:var(--cream-2);
  display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:.85rem 1.6rem;border-radius:999px;
  background:var(--bg);color:var(--fg);border:2px solid var(--ink);
  font-family:var(--body);font-weight:600;font-size:.92rem;
  text-decoration:none;
  transition:background .24s var(--ease),color .24s var(--ease),transform .24s var(--ease);
}
.btn:hover{transform:translateY(-2px)}
.btn--big{--bg:var(--red-solid);--fg:#fff;border-color:var(--red-solid);font-size:1rem;padding:1rem 1.9rem}
.btn--big:hover{--bg:var(--red-dk);border-color:var(--red-dk)}
.btn--ghost{--bg:transparent;--fg:var(--ink)}
.btn--ghost:hover{--bg:var(--ink);--fg:var(--cream-2)}
.btn--sm{min-height:40px;padding:.55rem 1.1rem;font-size:.84rem}

/* ── nav ──────────────────────────────────────────────────────────────── */
.nav{
  position:fixed;inset:0 0 auto;z-index:80;
  display:flex;align-items:center;justify-content:space-between;gap:1.5rem;
  padding:.75rem var(--pad);
  border-bottom:2px solid transparent;
  transition:background .35s,border-color .35s;
}
.nav.is-stuck{background:rgba(252,230,194,.94);backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);border-bottom-color:var(--ink)}
.nav__mark{display:block;line-height:0}
.nav__mark img{width:auto;height:38px}
.nav__links{display:flex;gap:1.6rem}
.nav__links a{text-decoration:none;font-weight:600;font-size:.94rem;transition:color .2s}
.nav__links a:hover{color:var(--red-ink)}
@media (max-width:880px){.nav__links{display:none}}

/* ── hero / builder ───────────────────────────────────────────────────── */
.hero{
  position:relative;overflow:hidden;
  min-height:600px;min-height:88svh;min-height:88dvh;
  display:flex;align-items:flex-end;
  padding:clamp(7rem,14vh,10rem) var(--pad) clamp(3rem,7vh,5rem);
}
.hero__film{position:absolute;inset:0;z-index:-1}
.hero__film video{width:100%;height:100%;object-fit:cover;object-position:center}

/* The veil is CREAM. Hibachi scrims its film in near-black because that site is
   dark; this one is a printed cream card, and a black scrim would hand the hero
   to a different brand. Opaque behind the copy on the left, clearing over the
   burger on the right — so the headline sits on flat cream and stays at full
   contrast without a box around it. */
.hero__veil{
  position:absolute;inset:0;
  background:
    linear-gradient(90deg,
      var(--cream) 0%, rgba(252,230,194,.96) 30%,
      rgba(252,230,194,.62) 52%, rgba(252,230,194,.10) 78%,
      rgba(252,230,194,0) 100%),
    linear-gradient(0deg, rgba(252,230,194,.80) 0%, rgba(252,230,194,0) 42%);
}
@media (max-width:960px){
  /* PHONES GET A TWO-PART LAYOUT, NOT AN OVERLAY.
     The desktop hero overlays copy on film and leans on a gradient to keep the
     text readable. On a phone that made the composition depend on viewport
     HEIGHT: on a tall Android the headline landed under the cup, on a shorter
     iPhone the same block rode up and sat across it, with the cup's own logo
     showing through the lede. Same page, two different designs.

     So on a phone the film is a BAND with its own height and the copy sits
     beneath it on flat cream. The band is sized from the viewport WIDTH, which
     every phone shares a sense of, rather than from its height, which they do
     not — so the proportions hold from a 320px handset to a 430px one. Capped
     against svh so a short-and-wide screen cannot let the band eat the fold. */
  .hero{
    display:grid;grid-template-rows:auto auto;
    min-height:0;align-items:start;
    padding:0 0 clamp(2rem,6vh,3.25rem);
  }
  .hero__film{
    position:relative;inset:auto;z-index:0;
    height:min(100vw,54svh);
  }
  .hero__film video{height:100%}
  /* Only the bottom of the band fades now — the copy is no longer on top of it,
     so the veil's job is just to hand the photograph over to the page. */
  .hero__veil{
    background:linear-gradient(0deg,
      var(--cream) 0%, rgba(252,230,194,.55) 26%, rgba(252,230,194,0) 62%);
  }
  .hero__copy{
    position:relative;z-index:1;
    max-width:none;padding:0 var(--pad);
    margin-top:-1.75rem;              /* tuck into the fade so the join is soft */
  }
  /* Both calls to action on one row at every width. They stacked on narrow
     phones and sat side by side on wide ones, which was the same layout
     inconsistency in miniature. */
  .hero__cta{display:grid;grid-template-columns:1fr 1fr;gap:.55rem;margin-top:1.4rem}
  .hero__cta .btn{padding-inline:.85rem;font-size:.88rem;text-align:center}
}
@media (max-width:360px){
  .hero__cta .btn{font-size:.8rem;padding-inline:.6rem}
}
.hero__copy{max-width:min(30rem,100%)}
.hero__cta{display:flex;gap:.7rem;flex-wrap:wrap;margin-top:1.8rem}

/* ── build your own ───────────────────────────────────────────────────────── */
.build{position:relative}
.build__picks{max-width:58rem;margin:clamp(1.5rem,3vw,2.5rem) auto 0}
.hero__lede{color:var(--mud);max-width:38ch;margin:1.2rem 0 2rem;font-size:1.06rem}
@media (min-width:760px){
  /* Without the 3D stage beside it the picker was a single narrow ribbon down
     the middle of a wide page, so it gets the full column and the tally is
     capped so the price does not stretch to the window. */
  .tally{max-width:34rem}
}
.pick{margin-bottom:1.5rem}
.pick__h{
  font-family:var(--body);font-size:.78rem;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--mud);margin:0 0 .6rem;
}
.pick__row{display:flex;flex-wrap:wrap;gap:.5rem}
.chip{
  display:inline-flex;align-items:baseline;gap:.45rem;cursor:pointer;
  min-height:44px;padding:.55rem 1rem;border-radius:999px;
  background:transparent;border:2px solid var(--ink);color:var(--ink);
  font-family:var(--body);font-size:.9rem;font-weight:500;
  transition:background .2s,color .2s,transform .2s var(--ease);
}
.chip i{font-style:normal;font-size:.82em;opacity:.62;font-variant-numeric:tabular-nums}
.chip:hover{transform:translateY(-2px)}
.chip.is-on{background:var(--ink);color:var(--cream-2)}
.chip.is-on i{opacity:.75}
.chip--add.is-on{background:var(--red-solid);border-color:var(--red-solid);color:#fff}

.tally{
  margin-top:1.8rem;padding:1.3rem 1.4rem;
  background:var(--cream-2);border:2px solid var(--ink);border-radius:22px;
  box-shadow:5px 5px 0 var(--ink);
}
.tally__name{margin:0;font-family:var(--display);font-weight:800;font-size:1.5rem;line-height:1.05}
.tally__bits{margin:.3rem 0 0;font-size:.9rem;color:var(--mud)}
.tally__tot{margin:.7rem 0 1rem;font-family:var(--display);font-weight:800;font-size:2.4rem;line-height:1;color:var(--red);font-variant-numeric:tabular-nums}
.tally .btn{width:100%}
.tally__note{margin:.7rem 0 0;font-size:.8rem;color:var(--mud)}

/* ── the drip ─────────────────────────────────────────────────────────────
   Melted cheese running off the bottom of the hero and onto the page. Full
   bleed, and it hangs past the section boundary into the menu below so it
   reads as having escaped the picture rather than being a section divider.

   Purely decorative: aria-hidden, and it sits behind content with a negative
   z-index so a long drip can never intercept a tap. */
.drip{
  position:absolute;left:50%;transform:translateX(-50%);
  bottom:-1px;width:100vw;line-height:0;
  pointer-events:none;z-index:-1;
}
.drip svg{display:block;width:100%;height:clamp(84px,10vw,158px)}
.drip path,.drip ellipse{fill:var(--amber)}
@media (prefers-reduced-motion:no-preference){
  .drip{animation:drip-settle 1.1s var(--ease) .35s both}
}
@keyframes drip-settle{
  from{transform:translateX(-50%) translateY(-14%)}
  to  {transform:translateX(-50%) translateY(0)}
}

/* ── sections ─────────────────────────────────────────────────────────── */
.section{padding:clamp(3.5rem,8vw,7rem) var(--pad);max-width:var(--maxw);margin-inline:auto}

/* ── the gallery ──────────────────────────────────────────────────────────
   A deliberately uneven mosaic. Equal tiles in equal rows read as a catalogue —
   the eye scans it and leaves. Different spans give the page a rhythm and let
   the best plates be big, which is how a menu actually works: some dishes are
   the reason you came.

   Auto-rows plus per-tile spans rather than a masonry library: the row height
   is fixed, so there is never a reflow when a photo decodes late. */
.mosaic{
  display:grid;gap:clamp(.7rem,1.6vw,1.15rem);
  grid-template-columns:repeat(2,1fr);
  grid-auto-rows:clamp(8.5rem,26vw,11rem);
  grid-auto-flow:dense;               /* let small tiles backfill the gaps */
}
/* TWO COLUMNS NEEDS ITS OWN BANDS.
   The size classes were cut so each band sums to the column count at 3 and at
   6 columns — 1+2 and 2+4. Neither divides into 2, so on a phone the rows never
   closed and the mosaic was left with holes: a short tile beside a tall one,
   then a gap where nothing could backfill.

   Position is fixed (the DOM order is the running order of the section), so the
   spans are reassigned by position here rather than by class. Bands become
   tall+tall, one full-width, then three pairs of equal-height tiles — every row
   closes exactly. */
@media (max-width:699px){
  .mosaic{grid-template-columns:repeat(2,1fr);grid-auto-flow:row}
  .shot{grid-column:span 1;grid-row:span 2}
  .shot:nth-child(1),.shot:nth-child(2),
  .shot:nth-child(8),.shot:nth-child(9){grid-column:span 1;grid-row:span 3}
  .shot:nth-child(3){grid-column:span 2;grid-row:span 2}
}
@media (min-width:700px){ .mosaic{grid-template-columns:repeat(3,1fr)} }
@media (min-width:1100px){ .mosaic{grid-template-columns:repeat(6,1fr);grid-auto-rows:11.5rem} }

.shot{
  position:relative;display:block;overflow:hidden;
  margin:0;padding:0;
  grid-column:span 1;grid-row:span 2;
  background:var(--cream-3);
  border:2px solid var(--ink);border-radius:20px;
  box-shadow:4px 4px 0 var(--ink);
  text-decoration:none;color:var(--ink);
  transition:transform .3s var(--ease),box-shadow .3s var(--ease);
}
.shot--wide{grid-column:span 2}
.shot--tall{grid-row:span 3}
.shot--big{grid-column:span 2;grid-row:span 3}
/* The spans have to CHANGE per breakpoint or the mosaic collapses back into a
   uniform grid — at 6 columns every tile was span-2, which is the catalogue
   look this section exists to avoid. */
@media (min-width:700px){
  .shot{grid-column:span 1;grid-row:span 2}
  .shot--wide{grid-column:span 2;grid-row:span 2}
  .shot--tall{grid-column:span 1;grid-row:span 3}
  .shot--big{grid-column:span 2;grid-row:span 3}
}
@media (min-width:1100px){
  .shot{grid-column:span 2;grid-row:span 2}
  .shot--wide{grid-column:span 4;grid-row:span 2}
  .shot--tall{grid-column:span 2;grid-row:span 3}
  .shot--big{grid-column:span 4;grid-row:span 3}
}

.shot img{
  display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .5s var(--ease);
}

/* The price bubble from their printed card, on a scrim so it stays legible
   over a bright plate or a dark one. */
.shot__tag{
  position:absolute;left:.6rem;right:.6rem;bottom:.6rem;
  display:flex;align-items:center;justify-content:space-between;gap:.6rem;
  padding:.5rem .75rem;
  background:var(--cream-2);border:2px solid var(--ink);border-radius:16px;
  font-size:.76rem;line-height:1.2;
  transition:transform .3s var(--ease);
}
/* Two lines rather than an ellipsis. On the narrowest tiles (175px on a phone)
   a single line clipped "Fried Chicken Burger" to "Fried Chic…", which tells a
   customer nothing. Wrapping keeps the name; the clamp stops a long one from
   pushing the bubble over the photo. */
.shot__tag b{
  font-weight:700;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;
  overflow:hidden;
}

@media (prefers-reduced-motion:reduce){
  .shot,.shot img,.shot__tag{transition-duration:.01ms}
}

/* ── menu cards ───────────────────────────────────────────────────────── */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:clamp(1rem,2vw,1.6rem)}
.card{
  background:var(--cream-2);border:2px solid var(--ink);border-radius:22px;
  padding:clamp(1.2rem,2.4vw,1.7rem);
  box-shadow:5px 5px 0 var(--ink);
}
.card__h{font-size:1.6rem;color:var(--red);margin-bottom:.15rem}
.card__sub{margin:0 0 .9rem;font-size:.84rem;color:var(--mud)}
.lines{list-style:none;margin:0;padding:0}
.line + .line{border-top:1px solid var(--line-2)}
.line a{display:block;padding:.7rem 0;text-decoration:none;min-height:48px}
.line__top{display:flex;align-items:baseline;gap:.75rem;justify-content:space-between}
.line__top b{font-weight:600;font-size:1rem}
.line__top i{
  font-style:normal;flex:none;font-weight:600;font-variant-numeric:tabular-nums;
  background:var(--coral-lt);border-radius:999px;padding:.15rem .6rem;font-size:.86rem;
}
.line__d{display:block;margin-top:.2rem;font-size:.84rem;color:var(--mud);line-height:1.4}
.line a:hover .line__top b{color:var(--red-ink)}
.line a:hover .line__top i{background:var(--coral)}

/* ── heat ─────────────────────────────────────────────────────────────── */
.heat{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:clamp(1rem,2vw,1.6rem)}
/* The heat tiles are buttons now, so they need a pressed state and a real
   focus ring — they change what gets ordered. */
.heat__i{
  appearance:none;width:100%;text-align:left;cursor:pointer;
  font:inherit;color:inherit;
}
.heat__i.is-on{background:var(--ink);color:var(--cream-2);border-color:var(--ink)}
.heat__i.is-on p{color:var(--cream-3)}
.heat__i.is-on .heat__dots i{border-color:var(--cream-2)}
.heat__i.is-on .heat__dots i.on{background:var(--coral);border-color:var(--coral)}
.heat__i:focus-visible{outline:3px solid var(--red-solid);outline-offset:3px}
.heat__note{
  margin:1.1rem 0 0;font-size:.92rem;font-weight:600;color:var(--red-ink);
  opacity:0;transform:translateY(-.25rem);
  transition:opacity .25s var(--ease),transform .25s var(--ease);
}
.heat__note.is-on{opacity:1;transform:none}
.heat__i{border-top:2px solid var(--ink);padding-top:.9rem}
.heat__i h3{display:flex;align-items:center;gap:.6rem;font-size:1.3rem;margin-bottom:.3rem}
.heat__i p{margin:0;font-size:.9rem;color:var(--mud)}
.heat__dots{display:inline-flex;gap:3px}
/* A drawn heat scale, not a chilli emoji. */
.heat__dots i{width:7px;height:7px;border-radius:50%;background:transparent;border:1.5px solid var(--red)}
.heat__dots i.on{background:var(--red)}

/* ── find ─────────────────────────────────────────────────────────────── */
.find__copy{max-width:52ch}
address{font-style:normal;font-family:var(--display);font-weight:700;font-size:clamp(1.6rem,1.2rem + 1.6vw,2.4rem);line-height:1.1;margin:1.2rem 0 1.8rem}
.find__cta{display:flex;gap:.7rem;flex-wrap:wrap}
.find__meta{margin:2.2rem 0 0;display:grid;gap:1.1rem}
.find__meta div{display:grid;gap:.1rem}
.find__meta dt{font-size:.74rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--mud)}
.find__meta dd{margin:0}
.find__meta a{font-weight:600;text-decoration:none;border-bottom:2px solid var(--coral)}
.find__meta a:hover{border-color:var(--red-ink);color:var(--red-ink)}

/* ── find: the map ────────────────────────────────────────────────────────
   Two columns on desktop, address above map on a phone. The map is a figure,
   not a decoration, so it gets the same 2px ink border and 5px hard shadow as
   .card and .tally — it belongs to the printed object, not to the browser. */
.find{display:grid;gap:clamp(1.6rem,4vw,3rem);align-items:start}
@media (min-width:900px){
  .find{grid-template-columns:minmax(0,1fr) minmax(0,1.15fr)}
}

.map{
  margin:0;
  background:var(--cream-2);
  border:2px solid var(--ink);border-radius:22px;
  box-shadow:5px 5px 0 var(--ink);
  overflow:hidden;
}
.map canvas{
  display:block;width:100%;
  /* Explicit height: a <canvas> is a REPLACED element, so it takes its
     intrinsic 300x150 ratio unless told otherwise — aspect-ratio on the
     parent will not reach it. */
  height:clamp(260px,52vw,420px);
}
.map.is-off canvas{display:none}
.map.is-off .map__cap::before{
  content:'Map unavailable — use “Get directions”.';
  color:var(--mud);font-size:.85rem;
}
.map__cap{
  display:flex;align-items:center;justify-content:space-between;gap:1rem;
  flex-wrap:wrap;
  padding:.85rem 1.1rem;
  border-top:2px solid var(--ink);
  font-size:.86rem;
}
/* On a phone the floating WhatsApp button owns the bottom-right corner, and a
   right-aligned "Get directions" ended up underneath it — a link you can see
   and cannot tap. Stack them left instead. */
@media (max-width:699px){
  .map__cap{flex-direction:column;align-items:flex-start;gap:.6rem}
}
.map__key{display:inline-flex;align-items:center;gap:.5rem;font-weight:600}
.map__key i{
  width:1.6rem;height:.42rem;border-radius:999px;
  background:var(--red);border:1.5px solid var(--ink);
  flex:none;
}
.map__dir{
  font-weight:700;color:var(--ink);text-decoration:none;
  border-bottom:2px solid var(--coral);
}
.map__dir:hover{color:var(--red-ink);border-color:var(--red-ink)}

/* ── footer ───────────────────────────────────────────────────────────── */
.foot{
  border-top:2px solid var(--ink);padding:clamp(2rem,4vw,3rem) var(--pad) 6rem;
  max-width:var(--maxw);margin-inline:auto;
  display:flex;justify-content:space-between;align-items:center;gap:1.5rem;flex-wrap:wrap;
}
.foot__mark{width:auto;height:44px}
.foot__fine{margin:0;font-size:.86rem;color:var(--mud)}

/* ── whatsapp ─────────────────────────────────────────────────────────── */
/* Hidden while the hero is on screen — see the JS. */
.wa.is-away{opacity:0;transform:scale(.85) translateY(.5rem);pointer-events:none}
.wa{transition:opacity .3s var(--ease),transform .3s var(--ease)}
.wa{
  position:fixed;right:clamp(1rem,3vw,2rem);bottom:clamp(1rem,3vw,2rem);z-index:90;
  width:56px;height:56px;display:grid;place-items:center;border-radius:50%;
  background:var(--red-solid);color:#fff;border:2px solid var(--ink);
  box-shadow:4px 4px 0 var(--ink);
  transition:background .25s,transform .3s var(--ease);
}
.wa:hover{background:var(--red-dk);transform:translateY(-2px)}

/* ── entrances ────────────────────────────────────────────────────────── */
.rev{opacity:0;transition:opacity .7s var(--ease),transform .8s var(--ease);transition-delay:var(--d,0ms)}
.rev[data-rev=up]{transform:translateY(20px)}
.rev[data-rev=left]{transform:translateX(-22px)}
.rev[data-rev=scale]{transform:scale(.96)}
.rev.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .rev{opacity:1;transform:none;transition:none}
  .btn:hover,.chip:hover,.wa:hover{transform:none}
}

/* ── loader: the order ticket ─────────────────────────────────────────────
   What a burger counter actually produces. It prints a line at a time as the
   real work finishes, and the total adds up with it. */
.pre{
  position:fixed;inset:0;z-index:200;
  display:grid;place-content:center;justify-items:center;
  background:var(--cream);
  transition:opacity .7s var(--ease),visibility .7s;
}
.pre.is-done{opacity:0;visibility:hidden}
.ticket{
  width:min(300px,80vw);background:#fff;color:var(--ink);
  padding:1.4rem 1.3rem 1.1rem;
  font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;font-size:.8rem;
  box-shadow:0 14px 30px -18px rgba(14,18,18,.6);
  /* The torn-off bottom edge of a printed docket. Uneven teeth: a uniform
     zigzag reads as pinking shears, not as paper that was ripped. */
  clip-path:polygon(0 0,
    100% 0,
    100% calc(100% - 8px),
    91.8% calc(100% - 2px),
    87.9% 100%,
    83.9% 100%,
    80.1% 100%,
    75.6% calc(100% - 8px),
    70.0% calc(100% - 3px),
    63.7% calc(100% - 3px),
    55.5% 100%,
    48.8% calc(100% - 8px),
    45.1% calc(100% - 2px),
    38.8% calc(100% - 6px),
    33.2% 100%,
    29.1% calc(100% - 4px),
    25.1% 100%,
    18.4% calc(100% - 3px),
    12.2% calc(100% - 2px),
    5.6% calc(100% - 8px),
    0.0% calc(100% - 9px),
    0 100%);
}
.ticket__h{margin:0;font-weight:700;letter-spacing:.12em;text-align:center}
.ticket__sub{margin:.15rem 0 .9rem;text-align:center;color:var(--mud);font-size:.72rem;letter-spacing:.1em}
.ticket__lines{list-style:none;margin:0;padding:.7rem 0;border-block:1px dashed rgba(14,18,18,.35);min-height:5.6rem}
.ticket__lines li{display:flex;justify-content:space-between;gap:1rem;padding:.16rem 0;white-space:pre}
.ticket__tot{display:flex;justify-content:space-between;margin:.7rem 0 0;font-weight:700}

/* ── toast ────────────────────────────────────────────────────────────────
   Confirms the order text reached the clipboard.

   Anchored to the TOP, under the nav, not the bottom. The bottom of this page
   is crowded: the floating WhatsApp button sits bottom-right, and on a phone
   the .tally card fills the lower half — a bottom toast landed directly on the
   "Send this order" button it was confirming, hiding the thing the customer
   had just pressed. Same hard-shadow card as .tally and .card so it reads as
   part of the same printed object rather than browser chrome. */
.toast{
  position:fixed;z-index:95;
  top:calc(env(safe-area-inset-top,0px) + 4.6rem);
  left:var(--pad);right:var(--pad);
  margin-inline:auto;max-width:26rem;width:fit-content;
  padding:.8rem 1.2rem;
  background:var(--cream-2);color:var(--ink);
  border:2px solid var(--ink);border-radius:16px;
  box-shadow:4px 4px 0 var(--ink);
  font-size:.9rem;font-weight:500;text-align:center;
  opacity:0;transform:translateY(-10px);pointer-events:none;
  transition:opacity .28s var(--ease),transform .28s var(--ease);
}
.toast.is-up{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .toast{transition-duration:.01ms}
}


/* ── menu lines are buttons now ───────────────────────────────────────────── */
.line__btn{
  appearance:none;width:100%;text-align:left;cursor:pointer;
  background:none;border:0;padding:0;font:inherit;color:inherit;
}
.line__btn:focus-visible{outline:3px solid var(--red-solid);outline-offset:2px;border-radius:8px}

/* ── the order tray, as a printed docket ─────────────────────────────────
   The same object the loader prints: white thermal paper, monospace, dotted
   leaders, a torn bottom edge. It is a betslip — you stack items on it and
   there is one button at the end that places the lot.

   The shadow lives on the OUTER element as a drop-shadow filter, because
   clip-path on the paper would clip a box-shadow away with it. */
.tray{
  position:fixed;z-index:90;
  left:var(--pad);right:var(--pad);bottom:calc(env(safe-area-inset-bottom,0px) + .9rem);
  margin-inline:auto;max-width:26rem;
  filter:drop-shadow(0 12px 22px rgba(14,18,18,.28));
  animation:tray-in .32s var(--ease) both;
}
@keyframes tray-in{from{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.tray{animation-duration:.01ms}}

.tray__paper{
  background:#fff;color:var(--ink);
  padding:.95rem 1.05rem 1.15rem;
  font-family:ui-monospace,"SFMono-Regular",Menlo,monospace;
  font-size:.78rem;line-height:1.5;
  /* Torn off a roll. Uneven teeth, or it reads as pinking shears. */
  clip-path:polygon(0 0,100% 0,
    100% calc(100% - 8px), 91.8% calc(100% - 2px), 87.9% 100%, 83.9% 100%,
    80.1% 100%, 75.6% calc(100% - 8px), 70.0% calc(100% - 3px),
    63.7% calc(100% - 3px), 55.5% 100%, 48.8% calc(100% - 8px),
    45.1% calc(100% - 2px), 38.8% calc(100% - 6px), 33.2% 100%,
    29.1% calc(100% - 4px), 25.1% 100%, 18.4% calc(100% - 3px),
    12.2% calc(100% - 2px), 5.6% calc(100% - 8px), 0.0% calc(100% - 9px), 0 100%);
}
.tray__head{margin:0;font-weight:700;letter-spacing:.14em;text-align:center;font-size:.72rem}
.tray__no{margin:.1rem 0 .55rem;text-align:center;font-size:.66rem;color:var(--mud);letter-spacing:.08em}

/* The dotted leader that makes a row read as a receipt line. */
.tray__lead{
  flex:1;min-width:1.5rem;align-self:flex-end;
  border-bottom:1px dotted rgba(14,18,18,.45);
  transform:translateY(-.32em);
}

.tray__toggle{
  appearance:none;cursor:pointer;width:100%;
  display:flex;align-items:center;gap:.45rem;
  padding:.45rem 0;background:none;color:inherit;font:inherit;text-align:left;
  border:0;border-top:1px dashed rgba(14,18,18,.4);
  border-bottom:1px dashed rgba(14,18,18,.4);
}
.tray__count{
  flex:none;display:grid;place-items:center;min-width:1.4rem;height:1.4rem;
  border-radius:999px;background:var(--red-solid);color:#fff;
  font-weight:700;font-size:.72rem;
}
.tray__word{font-weight:600;letter-spacing:.06em;text-transform:uppercase;font-size:.68rem}
.tray__tot{font-weight:700;font-size:.92rem;font-variant-numeric:tabular-nums}
.tray__chev{flex:none;transition:transform .25s var(--ease)}
.tray__toggle[aria-expanded="true"] .tray__chev{transform:rotate(180deg)}
.tray__toggle:focus-visible{outline:2px solid var(--red-solid);outline-offset:2px}

.tray__items{
  list-style:none;margin:0;padding:.5rem 0 .35rem;
  max-height:min(34vh,15rem);overflow-y:auto;
}
.tray__items li{display:flex;align-items:center;gap:.4rem;padding:.2rem 0}
.tray__nm{flex:none;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tray__nm i{font-style:normal;color:var(--mud)}
.tray__items b{flex:none;font-weight:700;font-variant-numeric:tabular-nums}
.tray__x{
  appearance:none;cursor:pointer;flex:none;
  width:1.25rem;height:1.25rem;line-height:1;padding:0;
  background:transparent;border:1px solid rgba(14,18,18,.3);border-radius:999px;
  color:var(--mud);font-size:.8rem;font-family:inherit;
}
.tray__x:hover{background:var(--red-solid);border-color:var(--red-solid);color:#fff}

.tray__foot{
  display:flex;align-items:center;gap:.7rem;
  margin-top:.5rem;padding-top:.6rem;
  border-top:1px dashed rgba(14,18,18,.4);
}
.tray__clear{
  appearance:none;cursor:pointer;background:none;border:0;padding:.35rem 0;
  font:inherit;font-size:.7rem;font-weight:600;color:var(--mud);
  letter-spacing:.08em;text-transform:uppercase;
  text-decoration:underline;text-underline-offset:3px;
}
.tray__clear:hover{color:var(--red-ink)}
/* The one button that places the bet. Brand red, not receipt grey. */
.tray__send{
  flex:1;min-height:42px;font-family:var(--body);font-size:.9rem;
  border-radius:999px;
}

/* Clear of the tray. */
body{padding-bottom:6.5rem}
.wa{bottom:calc(env(safe-area-inset-bottom,0px) + 6.6rem)}
