/* ============================================================
   Wokaway — components.
   Every surface here is a thing that exists in the restaurant: the painted
   wall, the terracotta table, the serving counter, the surfboard menu board,
   the printed ticket. Nothing is a generic card.
   ============================================================ */

/* ── masthead ────────────────────────────────────────────── */

.masthead {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--limewash) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.masthead__inner {
  width: min(100% - 2.5rem, var(--wrap));
  margin-inline: auto;
  display: flex; align-items: center; gap: var(--sp-3);
  min-height: 4.25rem;
}
.brand {
  display: flex; align-items: baseline; gap: .5rem;
  text-decoration: none; color: var(--forest);
  margin-right: auto;
}
.brand__word {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.32rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  line-height: 1;
}
.brand__mark {
  font-family: var(--font-mark);
  color: var(--terracotta);
  font-size: 1.05rem;
  line-height: 1;
}

.nav { display: flex; align-items: center; gap: var(--sp-3); }
.nav__link {
  font-size: var(--step--1);
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink);
  text-decoration: none;
  padding-block: .35rem;
  border-bottom: 2px solid transparent;
}
.nav__link:hover { color: var(--accent-ink); border-bottom-color: var(--rattan); }
.nav__link[aria-current="page"] { border-bottom-color: var(--terracotta); color: var(--accent-ink); }

/* The number, on every page, always. The masthead is sticky, so a hungry
   reader can order from wherever they have scrolled to without hunting for a
   contact page. It is the ordering channel the kitchen actually uses, so the
   link is WhatsApp and the aria-label says so; the digits are printed anyway
   for anyone who would rather just call. */
.masthead__order {
  display: inline-flex; align-items: center; gap: .5rem;
  min-height: 44px;
  padding: .45rem .9rem;
  background: var(--terracotta);
  color: #FFF8EE;
  border-radius: var(--radius);
  text-decoration: none;
  font-size: var(--step--1);
  font-weight: 700;
  white-space: nowrap;
  transition: background .18s var(--ease);
}
.masthead__order:hover { background: var(--terracotta-deep); color: #FFF8EE; }
.masthead__order-label { text-transform: uppercase; letter-spacing: .1em; }
.masthead__order-num { letter-spacing: .01em; }

.nav-toggle { display: none; }

@media (max-width: 56rem) {
  /* ⛔ At phone widths the number gets its OWN row, on purpose.
     .masthead__inner wraps so the open nav can take a full row, and measuring
     it showed brand + number + burger comes to 351px against 350px of usable
     width at 390px — so the burger dropped to a second line on its own and the
     header read as a bug. Shrinking the brand until it fits buys a cramped row
     and still fails at 360px.
     A full-width bar is honest about what it is, gives the number a large tap
     target, cannot overflow at any width, and keeps the word "Order" that the
     one-row version had to drop. Row one gives back some height to pay for it,
     because this whole block is sticky on every page. */
  .masthead__inner { min-height: 3.5rem; row-gap: 0; }
  .masthead__order {
    order: 5;
    width: 100%;
    justify-content: center;
    margin-bottom: .5rem;
  }

  .nav-toggle {
    display: block; list-style: none; cursor: pointer;
    order: 3; margin-left: auto;
  }
  .nav-toggle > summary {
    list-style: none; cursor: pointer;
    font-size: var(--step--1); font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase;
    color: var(--forest);
    border: 1px solid var(--rule-strong);
    padding: .45rem .7rem;
  }
  .nav-toggle > summary::-webkit-details-marker { display: none; }
  /* ⛔ .nav is a SIBLING of <details>, never a child: a closed <details>
     hides every non-summary child by UA rule, which would hide the nav
     from keyboard users even when open. */
  .nav {
    display: none;
    order: 4; width: 100%;
    flex-direction: column; align-items: stretch;
    gap: 0;
    padding-block: var(--sp-2) var(--sp-3);
    border-top: 1px solid var(--rule);
  }
  /* A thumb needs 44px. Stacked links get the full row so the target is the
     row, not the word. */
  .nav__link {
    display: flex; align-items: center;
    min-height: 48px;
    padding-block: 0;
    border-bottom: 1px solid var(--rule);
    border-left: 2px solid transparent;
    padding-left: .5rem;
  }
  .nav__link:hover,
  .nav__link[aria-current="page"] {
    border-bottom-color: var(--rule);
    border-left-color: var(--terracotta);
  }
  .masthead__inner:has(.nav-toggle[open]) .nav { display: flex; }
  .masthead__inner { flex-wrap: wrap; }
}

/* ── buttons ─────────────────────────────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: .5rem;
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-decoration: none;
  padding: .85rem 1.5rem;
  border: 2px solid var(--terracotta);
  background: var(--terracotta);
  color: #FFF8EE;
  border-radius: var(--radius);
  transition: background .18s var(--ease), border-color .18s var(--ease), transform .18s var(--ease);
  min-height: 44px;
}
.btn:hover { background: var(--terracotta-deep); border-color: var(--terracotta-deep); color: #FFF8EE; transform: translateY(-1px); }
.btn--ghost { background: transparent; color: var(--accent-ink); }
.btn--ghost:hover { background: var(--terracotta); color: #FFF8EE; }

/* On any dark surface the terracotta ghost button is close to invisible, so
   it inverts to paper. Scoped to the dark surfaces rather than added as a
   separate variant, so a ghost button dropped onto a dark band is legible
   by default instead of only when someone remembers to change the class. */
.hero .btn--ghost,
.band--forest .btn--ghost,
.band--cta .btn--ghost,
.band--terracotta .btn--ghost,
.footer .btn--ghost {
  color: #FFF8EE;
  border-color: rgba(255, 248, 238, .55);
}
.hero .btn--ghost:hover,
.band--forest .btn--ghost:hover,
.band--cta .btn--ghost:hover,
.footer .btn--ghost:hover {
  background: #FFF8EE;
  border-color: #FFF8EE;
  color: var(--forest-deep);
}
.band--terracotta .btn--ghost:hover {
  background: #FFF8EE; border-color: #FFF8EE; color: var(--terracotta-deep);
}
.btn--forest { background: var(--forest); border-color: var(--forest); }
.btn--forest:hover { background: var(--forest-deep); border-color: var(--forest-deep); }

.btnrow { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: var(--sp-4); }

/* ── hero ────────────────────────────────────────────────── */

.hero { position: relative; background: var(--forest-deep); color: var(--text-invert); overflow: hidden; }
.hero__media { position: absolute; inset: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 36%; }
/* The scrim is warm, not neutral grey: the frame is lit by one tungsten bulb
   and a cold overlay kills exactly the quality worth keeping. Kept light
   enough that the room is still legible behind the type — the photograph is
   the reason to come, so it must not be flattened into a colour field. */
.hero::after {
  content: ''; position: absolute; inset: 0;
  background:
    linear-gradient(to bottom, rgba(19,48,38,.26) 0%, rgba(19,48,38,.10) 30%, rgba(19,48,38,.42) 72%, rgba(19,48,38,.68) 100%),
    linear-gradient(to right, rgba(19,48,38,.52), rgba(19,48,38,.04) 60%);
}
.hero__inner {
  position: relative; z-index: 2;
  width: min(100% - 2.5rem, var(--wrap));
  margin-inline: auto;
  padding-block: clamp(5rem, 22vh, 11rem) clamp(2.5rem, 7vh, 4.5rem);
  min-height: min(84svh, 46rem);
  display: flex; flex-direction: column; justify-content: flex-end;
}
.hero__inner .yeungsum { color: var(--bowl-yellow); font-size: var(--step-4); margin-bottom: var(--sp-3); }
.hero h1 {
  font-size: var(--step-5);
  color: #FFF8EE;
  margin-bottom: var(--sp-3);
  max-width: 16ch;
}
.hero__sub {
  font-size: var(--step-1);
  color: rgba(255,248,238,.92);
  max-width: 34ch;
  margin-bottom: 0;
}
.hero__meta {
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  margin-top: var(--sp-4);
  font-size: var(--step--1);
  letter-spacing: .1em; text-transform: uppercase; font-weight: 700;
  color: var(--rattan-pale);
}
.hero__meta span { display: inline-flex; align-items: center; gap: .45rem; }

/* ── bands and panels ────────────────────────────────────── */

.band { padding-block: var(--sp-6); }

/* ⛔ DARK SURFACES REDEFINE THE COLOUR TOKENS, they do not restate colours
   per element. Setting `.band--forest p { color: light }` looks like it
   works until a component further down the file also sets `p { color:
   var(--text-muted) }` at equal specificity: source order wins and the text
   silently goes dark grey on dark green. That is exactly what happened to
   the three takeaway steps on the home page. Overriding the tokens fixes
   every descendant at once, whatever its specificity, including components
   written later that know nothing about this band. */
.on-dark,
.hero,
.band--forest,
.band--cta,
.band--terracotta,
.footer {
  --text: #FFF8EE;
  --text-muted: rgba(247, 244, 236, .84);
  --accent-ink: var(--bowl-yellow);
  --rule: rgba(247, 244, 236, .22);
  --rule-strong: rgba(247, 244, 236, .38);
  --mark-color: var(--bowl-yellow);
}
/* The terracotta band needs paper, not yellow, against its own red. */
.band--terracotta { --mark-color: #FFF8EE; }

.band--forest { background: var(--forest); color: var(--text); }
.band--forest h2, .band--forest h3, .band--forest h4 { color: #FFF8EE; }
.band--forest a:not(.btn) { color: var(--bowl-yellow); }
.band--terracotta { background: var(--terracotta); color: #FFF8EE; }
.band--terracotta { --text-muted: rgba(255, 248, 238, .9); --accent-ink: #FFF8EE; }
.band--terracotta h2, .band--terracotta h3 { color: #FFF8EE; }
.band--paper { background: var(--bg-alt); }

.band--cta { background: var(--forest); color: var(--text); text-align: center; }
.band--cta h2 { color: #FFF8EE; font-size: var(--step-3); }
.band--cta p { margin-inline: auto; }
.band--cta .yeungsum { color: var(--bowl-yellow); }
.band--cta .btnrow { justify-content: center; }
.band__inner { text-align: center; }
.band--cta .band__inner > p { max-width: 46ch; }

/* The woven amakan wall, used once, as a seam between sections. */
.seam {
  height: 74px;
  background-image: url('/images/opt/texture-amakan-1200.webp');
  background-size: 420px auto;
  background-repeat: repeat-x;
  opacity: .55;
  border-block: 1px solid var(--rule);
}

/* ── the answer-first lede ───────────────────────────────── */

.answer {
  border-left: 4px solid var(--terracotta);
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
  margin-bottom: var(--sp-4);
}
.answer p { font-size: var(--step-1); line-height: 1.5; margin-bottom: 0; max-width: 54ch; }

/* ── page head ───────────────────────────────────────────── */

.pagehead { padding-block: var(--sp-6) var(--sp-4); }
.pagehead h1 { max-width: 20ch; }
.pagehead__lead { font-size: var(--step-1); color: var(--text-muted); max-width: 52ch; }

/* A page head with a poster in it.
   ⛔ AUDIT 2026-09-15, all six heads. Four faults, all of them mine:
   1. THE GRADIENT WAS THE WORST OF IT. Fading flat screen-print ink over a
      textured cream page does not read as depth, it reads as a broken image —
      the Hong Kong skyline went ghost-grey, the lemongrass turned to mush.
      Flat ink has no business being semi-transparent. The mask is gone.
   2. The art was vertically centred on a section shorter than itself, so it
      overflowed UP behind the sticky masthead (every poster was clipped along
      the header edge) and DOWN over the paragraph below.
   3. It ended on a hard vertical cut in the middle of the page — the edge of
      its own box, floating, which is exactly what makes a picture look pasted
      on. It now bleeds off the RIGHT EDGE OF THE VIEWPORT instead.
   4. Scale and position drifted page to page because each poster sized itself.
      The art box is now a fixed band and the poster is fitted INSIDE it, so
      every page shares one baseline.

   The result reads as integrated because it bleeds off the page, not because
   it is faded into it. */
.pagehead--art {
  position: relative;
  /* ⛔ The poster gets a TALL BAND of its own rather than being allowed to
     spill down the page. Measured, the spilling version overlapped the lede
     paragraph by 59px on the best page and 259px on the worst — and flat ink
     is opaque, so an overlap does not dim a word, it deletes one. The band is
     deep enough that the art is large, and clipped so it can reach neither the
     sticky masthead above nor the paragraph below.
     The overlap Daniel asked for happens here instead, against the SHORT lines
     the head actually contains: the heading and its one-line lead. */
  overflow: hidden;
  isolation: isolate;
  display: grid;
  align-content: center;
  min-height: 36rem;
  padding-block: var(--sp-6) var(--sp-5);
}
.pagehead--art .pagehead__text {
  position: relative;
  z-index: 1;
  /* ⛔ Measured, not guessed. At 33rem the longest lead line ran to 710px and
     the Our Story artwork's ink starts at 690px — so "one wok" lost its k.
     Flat ink is opaque: a 20px tuck is not a soft overlap, it is a missing
     letter. 29rem keeps every line clear of the ink on all six pages, with the
     art still overlapping the text BLOCK, which is the effect. */
  max-width: 29rem;
}
.pagehead__art {
  position: absolute;
  z-index: 0;
  /* Fills the band, top to bottom, sitting inside the wrap. Bleeding it to the
     window edge pushed the right-hand half of the artwork off the screen. */
  inset-block: var(--sp-3);
  right: 0;
  width: min(62vw, 46rem);
  pointer-events: none;
}
.pagehead__art .figure { margin: 0; height: 100%; }
.pagehead__art picture { display: block; width: 100%; height: 100%; }
/* ⛔ SPECIFICITY. `.figure--4x3 img` sets `object-fit: cover` and lives LATER in
   this file, so the plain `.pagehead__art img` selector lost to it and every
   poster was being CROPPED to fill the band instead of fitted into it — the
   tops of the skylines and the bottoms of the beaches were being cut off, and
   it looked like the artwork had been badly framed. Same specificity is not
   enough when the other rule comes after; this one has to win outright. It
   also has to unset the 4:3 aspect-ratio that comes with it. */
.pagehead--art .pagehead__art img {
  width: 100%;
  height: 100%;
  aspect-ratio: auto;
  object-fit: contain;
  object-position: center right;
}

@media (max-width: 64rem) {
  .pagehead--art .pagehead__text { max-width: 26rem; }
  .pagehead__art { width: min(58vw, 30rem); }
}

@media (max-width: 52rem) {
  /* Stack, and leave the poster where the markup puts it: after the heading and
     the lead. Overlapping text is never legible at this width, and moving the
     art above the H1 would push the heading itself below the fold. */
  .pagehead--art { display: block; overflow: visible; min-height: 0; }
  .pagehead__art {
    position: static;
    width: 100%;
    height: auto;
    inset-block: auto;
    max-width: 22rem;
    margin: 0 auto var(--sp-3);
  }
  .pagehead__art .figure, .pagehead__art picture { height: auto; }
  .pagehead--art .pagehead__art img { height: auto; object-fit: contain; }
  .pagehead--art .pagehead__text { max-width: none; }
}

.crumbs {
  display: flex; flex-wrap: wrap; gap: .45rem;
  list-style: none; padding: 0; margin: 0 0 var(--sp-3);
  font-size: var(--step--1); color: var(--text-muted);
  letter-spacing: .06em; text-transform: uppercase;
}
.crumbs li + li::before { content: '/'; margin-right: .45rem; color: var(--rule-strong); }

/* ── the menu ────────────────────────────────────────────── */

.menu-section + .menu-section { margin-top: var(--sp-6); }
.menu-section__head {
  display: flex; align-items: baseline; gap: var(--sp-3);
  border-bottom: 2px solid var(--terracotta);
  padding-bottom: var(--sp-2);
  margin-bottom: var(--sp-4);
}
.menu-section__head h2 { margin: 0; font-size: var(--step-2); color: var(--accent-ink); }
.menu-section__blurb { margin: 0; color: var(--text-muted); font-size: var(--step--1); font-style: italic; }

/* Two columns is the ceiling. Three fits, but the dish descriptions wrap to
   five lines and the whole menu starts to read like a spreadsheet. */
.dishes { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-4) var(--sp-5); }
@media (min-width: 44rem) { .dishes { grid-template-columns: repeat(2, 1fr); } }

/* A dish is a printed ticket on the counter, not a floating card. */
.dish {
  display: grid;
  grid-template-columns: 92px 1fr auto;
  align-items: start;
  gap: var(--sp-3);
  padding-bottom: var(--sp-4);
  border-bottom: 1px solid var(--rule);
}
.dish__media { width: 92px; }
.dish__media picture, .dish__media img {
  width: 92px; height: 92px; object-fit: cover;
  object-position: var(--thumb-pos, 50% 50%);
  border-radius: var(--radius-round);
  background: var(--limewash-warm);
}
/* Every dish thumbnail now reads as a photograph, so they share one treatment.
   The distinction between a real photograph of this kitchen and a generated
   serving suggestion is carried by the line under the menu, not by a ring
   around the plate. */
.dish__body { min-width: 0; }
.dish__name {
  font-size: var(--step-0); margin: 0 0 .25rem;
  display: flex; align-items: baseline; gap: .5rem; flex-wrap: wrap;
  letter-spacing: -.005em;
}
.dish__desc { font-size: var(--step--1); color: var(--text-muted); margin: 0; }
.dish__price {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--step-0);
  color: var(--accent-ink);
  margin: 0; white-space: nowrap;
}
/* terracotta on the warm paper band measures 4.32:1, just under AA. */
.spice { color: var(--terracotta-deep); font-size: .62em; letter-spacing: .12em; }

.artnote {
  font-size: var(--step--1);
  font-style: italic;
  color: var(--text-muted);
  border-top: 1px solid var(--rule);
  padding-top: var(--sp-2);
  margin-top: var(--sp-5);
  max-width: 60ch;
}

.drinks { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--sp-2); max-width: 30rem; }
.drinks li {
  display: flex; align-items: baseline; gap: var(--sp-2);
  border-bottom: 1px dotted var(--rule-strong); padding-bottom: .35rem;
}
.drinks li span:first-child { flex: 1; }
.drinks li span:last-child { font-family: var(--font-display); font-weight: 400; color: var(--accent-ink); }

/* ── figures ─────────────────────────────────────────────── */

.figure { margin: 0; }
.figure img { width: 100%; }

/* The map on Find us. A self-hosted image, not an embed — see
   scripts/fetch-map.mjs for why — so it needs a border to read as a map
   rather than a pale rectangle, and a hover state to say it is a link. */
.mapcard a {
  display: block;
  border: 1px solid var(--rule-strong);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color .18s var(--ease), box-shadow .18s var(--ease);
}
.mapcard a:hover {
  border-color: var(--terracotta);
  box-shadow: 0 10px 26px -14px rgba(19, 48, 38, .45);
}
.figure figcaption {
  font-size: var(--step--1); color: var(--text-muted);
  padding-top: var(--sp-2); font-style: italic;
}
.figure--4x3 img { aspect-ratio: 4/3; object-fit: cover; }
.figure--3x4 img { aspect-ratio: 3/4; object-fit: cover; }
.figure--1x1 img { aspect-ratio: 1/1; object-fit: cover; }

/* ── two-up ──────────────────────────────────────────────── */

.duo { display: grid; gap: var(--sp-5); align-items: center; }
@media (min-width: 52rem) {
  .duo { grid-template-columns: 1fr 1fr; gap: var(--sp-6); }
  .duo--wide-left { grid-template-columns: 1.25fr 1fr; }
  .duo--wide-right { grid-template-columns: 1fr 1.25fr; }
  .duo--flip > :first-child { order: 2; }
}
.duo p:last-child { margin-bottom: 0; }

/* ── the two kitchens ────────────────────────────────────── */

.kitchens { display: grid; gap: var(--sp-4); }
@media (min-width: 48rem) { .kitchens { grid-template-columns: 1fr 1fr; } }
.kitchen {
  padding: var(--sp-4);
  border: 1px solid var(--rule-strong);
  background: color-mix(in srgb, var(--limewash) 70%, transparent);
}
.kitchen h3 { color: var(--accent-ink); }
.kitchen__mark { width: 76px; margin-bottom: var(--sp-3); }
.kitchen__mark img { width: 76px; height: 76px; }
.kitchen ul { padding-left: 1.1rem; margin: 0 0 var(--sp-3); color: var(--text-muted); font-size: var(--step--1); }

/* ── hours, address ──────────────────────────────────────── */

.hours { display: grid; grid-template-columns: auto 1fr; gap: .3rem var(--sp-3); margin: 0; max-width: 22rem; }
.hours dt { font-weight: 600; }
.hours dd { margin: 0; color: var(--text-muted); text-align: right; font-variant-numeric: tabular-nums; }
.hours dt:nth-of-type(2), .hours dd:nth-of-type(2) { color: var(--terracotta); }

.address { font-style: normal; display: grid; gap: .15rem; margin-bottom: var(--sp-3); }
.address__note { color: var(--text-muted); font-style: italic; }

.factbox {
  display: grid; gap: var(--sp-4);
  padding: var(--sp-4);
  border: 1px solid var(--rule-strong);
  background: color-mix(in srgb, var(--limewash) 70%, transparent);
}
@media (min-width: 44rem) { .factbox { grid-template-columns: 1fr 1fr; } }
.factbox h3 { font-size: var(--step-0); letter-spacing: .08em; text-transform: uppercase; font-family: var(--font-body); font-weight: 700; color: var(--accent-ink); }

/* ── faq ─────────────────────────────────────────────────── */

.faq { border-top: 1px solid var(--rule); max-width: 46rem; }
.faq details { border-bottom: 1px solid var(--rule); }
.faq summary {
  cursor: pointer; list-style: none;
  padding: var(--sp-3) 2rem var(--sp-3) 0;
  font-family: var(--font-display);
  font-weight: 400; font-size: var(--step-1);
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: '+'; position: absolute; right: .25rem; top: 50%;
  transform: translateY(-50%);
  color: var(--terracotta); font-size: 1.4em; line-height: 1;
}
.faq details[open] summary::after { content: '\2013'; }
.faq__a { padding-bottom: var(--sp-3); }
.faq__a p { margin-bottom: 0; color: var(--text-muted); }

/* ── steps ───────────────────────────────────────────────── */

.steps { list-style: none; counter-reset: s; padding: 0; margin: 0; display: grid; gap: var(--sp-4); }
@media (min-width: 48rem) { .steps { grid-template-columns: repeat(3, 1fr); } }
/* The rule and the numeral follow --accent-ink, which the dark surfaces above
   swap to the bowl yellow. Terracotta on forest green is close to invisible. */
.steps li { counter-increment: s; padding-top: var(--sp-3); border-top: 2px solid var(--accent-ink); }
.steps li::before {
  content: counter(s);
  font-family: var(--font-display);  font-weight: 400; font-size: var(--step-2); color: var(--accent-ink);
  display: block; line-height: 1; margin-bottom: var(--sp-2);
}
.steps h3 { font-size: var(--step-0); color: var(--text); }
.steps p { font-size: var(--step--1); color: var(--text-muted); margin-bottom: 0; }

/* ── quote ───────────────────────────────────────────────── */

.quote { border: 0; padding: 0; margin: 0; max-width: 40rem; }
.quote blockquote {
  margin: 0 0 var(--sp-2);
  font-family: var(--font-script); font-style: italic; font-size: var(--step-2); line-height: 1.3;
}
.quote figcaption { font-size: var(--step--1); letter-spacing: .1em; text-transform: uppercase; color: var(--text-muted); }

/* ── footer ──────────────────────────────────────────────── */

.footer { background: var(--forest-deep); color: rgba(247,244,236,.82); padding-block: var(--sp-6) var(--sp-4); }
.footer h2 {
  font-family: var(--font-body); font-size: var(--step--1); font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--rattan);
  margin-bottom: var(--sp-2);
}
.footer a { color: rgba(247,244,236,.88); text-decoration: none; }
.footer a:hover { color: var(--bowl-yellow); text-decoration: underline; }
.footer ul { list-style: none; padding: 0; margin: 0; display: grid; gap: .4rem; }
.footer__top { display: grid; gap: var(--sp-5); }
@media (min-width: 48rem) { .footer__top { grid-template-columns: 1.4fr 1fr 1fr; } }
.footer__brand .brand__word { color: #FFF8EE; font-size: 1.5rem; display: block; }
.footer__tag { font-style: italic; color: var(--rattan-pale); margin-top: .4rem; }
.footer .address, .footer .hours dd { color: rgba(247,244,236,.72); }
.footer .hours dt { color: rgba(247,244,236,.9); }
.footer__base {
  margin-top: var(--sp-5); padding-top: var(--sp-3);
  border-top: 1px solid rgba(247,244,236,.16);
  display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4);
  font-size: var(--step--1); color: rgba(247,244,236,.6);
}

/* ── the menu gallery ────────────────────────────────────── */
/* Tap a dish and the whole menu opens: the dish large with its name, heat,
   description and price, two ways to order it, and beside it every other dish
   and drink with prices, one tap away. It is the menu board, not a lightbox.

   ⛔ THE CARD SETS ITS OWN TYPE SIZES and does not use --step-*. The page
      scale is fluid, so on a wide screen --step-2 reaches 1.94rem and a dish
      name broke over three hyphenated lines inside a column that had not grown
      with it. A card is a fixed-width component: its type must be fixed too.

   ⛔ The picture is never stretched. These come from the restaurant's own menu
      artwork at about 240px square, so the stage sizes itself to the picture
      and the card carries the presence instead of the pixels. */

.is-zoomable { cursor: zoom-in; }
.no-js .is-zoomable { cursor: default; }

/* ⛔ base.css caps EVERY paragraph at 62ch, which is right for prose and wrong
   for a component. Inside the card it was silently shrinking the menu header
   (so its underline stopped two thirds of the way across) and the drinks rows
   (so their prices stopped short of the right edge). The measure that actually
   wants limiting is the dish description, and it says so for itself below. */
.lightbox p { max-width: none; }

/* ⛔ display:flex on the class BEATS the UA [hidden]{display:none} rule, so a
   closed viewer would still lay out and swallow every click underneath. */
.lightbox[hidden] { display: none !important; }

.lightbox {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  padding: clamp(.6rem, 3vw, 2.5rem);
  background: rgba(19, 48, 38, .96);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity .18s var(--ease);
  overscroll-behavior: contain;
}
.lightbox.is-open { opacity: 1; }

/* The controls hang off the CARD, not off the viewport. On a wide screen a
   close button pinned to the far corner reads as belonging to the browser. */
.lightbox__frame {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  gap: .75rem;
  width: min(100%, 69rem);
  max-height: 100%;
}

.lightbox__panel {
  display: grid;
  grid-template-columns: auto minmax(23rem, 1fr) 20rem;
  width: 100%;
  min-height: 0;
  /* ⛔ Cap the height. Left to stretch, the card takes its height from the
     menu column — fifteen rows — and the dish column ends up with a 380px
     hole between the price and the order button. Capped, the menu scrolls
     (its scrollbar is styled as part of the card) and the dish column reads
     as a composed page instead of a stretched one. */
  height: min(calc(100vh - 6rem), 33rem);
  background: var(--limewash);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 40px 90px -30px rgba(0, 0, 0, .7);
  transform: scale(.985);
  transition: transform .22s var(--ease);
}
.lightbox.is-open .lightbox__panel { transform: none; }

.lightbox__main { display: contents; }

.lightbox__stage {
  display: flex; align-items: center; justify-content: center;
  background: var(--limewash-warm);
  padding: 1.75rem;
  min-width: 0; min-height: 0;
  overflow: hidden;
}
.lightbox__img {
  display: block;
  max-width: 20rem;
  max-height: min(40vh, 19rem);
  width: auto; height: auto;
  object-fit: contain;
  border-radius: calc(var(--radius) - 2px);
  box-shadow: 0 14px 34px -14px rgba(19, 48, 38, .5);
}

.lightbox__info {
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  padding: 2rem;
  overflow-y: auto;
}
.lightbox__eyebrow {
  margin: 0 0 .55rem;
  font-size: .72rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--accent-ink);
}
.lightbox__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.55rem;
  line-height: 1.14;
  color: var(--ink);
  hyphens: manual;
}
.lightbox__heat {
  margin: .5rem 0 0;
  font-size: .68rem; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent-ink);
}
.lightbox__desc {
  margin: .85rem 0 0;
  max-width: 38ch;
  font-size: .95rem; line-height: 1.55;
  color: var(--text-muted);
}
.lightbox__price {
  margin: 1rem 0 0;
  font-family: var(--font-display);
  font-size: 1.45rem;
  color: var(--accent-ink);
}

/* Two ways to order, because most people reading this are outside on the road
   or already sitting at one of the three tables. */
.lightbox__cta { margin-top: auto; padding-top: 1.75rem; }
.lightbox__order {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 46px;
  padding: .7rem 1.35rem;
  background: var(--terracotta);
  color: #FFF8EE;
  border-radius: var(--radius);
  text-decoration: none;
  font-size: .76rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase;
  white-space: nowrap;
  box-shadow: 0 8px 18px -8px rgba(142, 55, 34, .6);
  transition: background .18s var(--ease), box-shadow .18s var(--ease);
}
.lightbox__order:hover {
  background: var(--terracotta-deep); color: #FFF8EE;
  box-shadow: 0 10px 22px -8px rgba(142, 55, 34, .75);
}
.lightbox__inperson {
  margin: .85rem 0 0;
  font-size: .875rem; line-height: 1.5;
  color: var(--text-muted);
}
.lightbox__call {
  display: inline-flex; align-items: center;
  min-height: 44px;
  font-size: .9rem; font-weight: 700;
  color: var(--accent-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lightbox__call:hover { color: var(--terracotta-deep); }

/* The whole menu, which is also the navigation */
.lightbox__menu {
  min-width: 0; min-height: 0;
  display: flex; flex-direction: column;
  border-left: 1px solid var(--rule);
  background: var(--limewash-warm);
  position: relative;
}
/* The list scrolls, and a hairline scrollbar is easy to miss, so the bottom
   edge fades to say so. */
.lightbox__menu::after {
  content: '';
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 2.25rem;
  background: linear-gradient(to top, var(--limewash-warm), rgba(237, 230, 216, 0));
  pointer-events: none;
}
.lightbox__menu-head {
  margin: 0;
  padding: 1.15rem 1.25rem .9rem;
  font-size: .72rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--text-muted);
  border-bottom: 1px solid var(--rule);
}
.lightbox__menu-scroll {
  min-height: 0;
  overflow-y: auto;
  padding: .75rem .9rem 1.25rem;
  overscroll-behavior: contain;
}
.lightbox__group {
  margin: 1.1rem 0 .3rem;
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--accent-ink);
}
.lightbox__menu-scroll > .lightbox__group:first-child { margin-top: .2rem; }
.lightbox__row {
  display: grid;
  grid-template-columns: 32px 1fr auto;
  align-items: center; gap: .65rem;
  width: 100%;
  min-height: 44px;
  padding: .3rem .45rem;
  border: 0;
  border-radius: calc(var(--radius) - 4px);
  background: none;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: .875rem;
  line-height: 1.3;
  text-align: left;
  cursor: pointer;
  transition: background .14s var(--ease), color .14s var(--ease);
}
.lightbox__row:hover { background: rgba(178, 74, 50, .08); }
/* ⛔ WHERE YOU ARE is not the same thing as WHAT TO DO, and it must not look
   like it. Both were a solid terracotta block, so the eye could not tell the
   order button from the highlighted row and the call to action stopped reading
   as one. The card now has exactly ONE solid terracotta block — the button —
   and the current row is marked the quieter way a selection should be: a wash
   of the same colour, a solid edge, and the name in ink. */
.lightbox__row.is-current {
  background: rgba(178, 74, 50, .13);
  box-shadow: inset 3px 0 0 var(--terracotta);
  color: var(--accent-ink);
  font-weight: 700;
}
.lightbox__row.is-current .lightbox__row-price { color: var(--accent-ink); }
.lightbox__row.is-current .lightbox__row-heat { color: var(--accent-ink); opacity: .8; }
.lightbox__row-img {
  width: 32px; height: 32px;
  border-radius: var(--radius-round);
  object-fit: cover;
  display: block;
}
.lightbox__row-name { min-width: 0; display: block; }
/* Inline, so a heat marker costs a few characters rather than a whole line. */
.lightbox__row-heat {
  display: inline-block;
  margin-left: .4rem;
  font-size: .62rem;
  letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-ink);
  vertical-align: .08em;
}
.lightbox__row-price { font-weight: 700; white-space: nowrap; color: var(--accent-ink); }
.lightbox__drink {
  display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
  margin: 0;
  padding: .45rem .45rem;
  font-size: .875rem;
  color: var(--text-muted);
}

/* ⭐ Scrollbars styled as part of the card. The default OS bars inside a
   cream panel were the single thing that made this look unfinished. */
.lightbox__info, .lightbox__menu-scroll, .lightbox__panel {
  scrollbar-width: thin;
  scrollbar-color: rgba(178, 74, 50, .32) transparent;
}
.lightbox__info::-webkit-scrollbar,
.lightbox__menu-scroll::-webkit-scrollbar,
.lightbox__panel::-webkit-scrollbar { width: 6px; }
.lightbox__info::-webkit-scrollbar-track,
.lightbox__menu-scroll::-webkit-scrollbar-track,
.lightbox__panel::-webkit-scrollbar-track { background: transparent; }
.lightbox__info::-webkit-scrollbar-thumb,
.lightbox__menu-scroll::-webkit-scrollbar-thumb,
.lightbox__panel::-webkit-scrollbar-thumb {
  background: rgba(178, 74, 50, .3);
  border-radius: 3px;
}

/* Close, and step */
.lightbox__close,
.lightbox__nav {
  position: absolute;
  width: 46px; height: 46px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid rgba(247, 244, 236, .3);
  border-radius: var(--radius-round);
  background: rgba(19, 48, 38, .55);
  color: #FFF8EE;
  cursor: pointer;
  z-index: 2;
  transition: background .16s var(--ease), border-color .16s var(--ease);
}
.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(247, 244, 236, .2); border-color: rgba(247, 244, 236, .6); }
.lightbox__close { top: .6rem; right: .6rem; }
.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev { left: .6rem; }
.lightbox__nav--next { right: .6rem; }

/* With room either side, the controls step out of the card entirely. */
@media (min-width: 78rem) {
  .lightbox__close { top: -.6rem; right: -3.5rem; }
  .lightbox__nav--prev { left: -3.5rem; }
  .lightbox__nav--next { right: -3.5rem; }
}

.lightbox__count {
  margin: 0;
  flex: 0 0 auto;
  font-size: .7rem;
  letter-spacing: .16em; text-transform: uppercase;
  color: rgba(247, 244, 236, .7);
  font-variant-numeric: tabular-nums;
}

/* ⛔ Every one of these sets a display, so [hidden] has to be restated or a
   hidden element still lays out and still takes clicks. */
.lightbox__nav[hidden], .lightbox__menu[hidden], .lightbox__cta[hidden],
.lightbox__order[hidden], .lightbox__call[hidden], .lightbox__eyebrow[hidden],
.lightbox__name[hidden], .lightbox__heat[hidden], .lightbox__desc[hidden],
.lightbox__price[hidden], .lightbox__count[hidden] { display: none !important; }

/* A room photograph is not a menu item: it opens as a picture with its
   caption, and the card shrinks to fit it. */
.lightbox--photo .lightbox__frame { width: min(100%, 44rem); }
.lightbox--photo .lightbox__panel { grid-template-columns: 1fr; }
.lightbox--photo .lightbox__stage { padding: 1.25rem; }
.lightbox--photo .lightbox__img { max-width: 100%; max-height: 70vh; }
.lightbox--photo .lightbox__info { padding: 1.25rem 2rem 1.75rem; }
.lightbox--photo .lightbox__desc {
  margin: 0; text-align: center; font-style: italic;
}

/* Between tablet and laptop the menu drops under the dish. */
@media (max-width: 68rem) {
  .lightbox__frame { width: min(100%, 42rem); }
  /* ⛔ The fixed height above is for the three-column layout. Once the menu
     drops to a row of its own it needs real room, and holding 33rem squashed
     it to a heading and half a line. */
  .lightbox__panel {
    grid-template-columns: auto 1fr;
    grid-template-rows: auto minmax(0, 1fr);
    height: auto;
    max-height: calc(100vh - 5rem);
  }
  .lightbox__menu { grid-column: 1 / -1; border-left: 0; border-top: 1px solid var(--rule); }
  .lightbox__menu-scroll { max-height: 30vh; }
  .lightbox__img { max-height: min(34vh, 14rem); max-width: 14rem; }
  .lightbox__info { padding: 1.5rem; }
  .lightbox__name { font-size: 1.45rem; }
}

/* Phone: everything stacks, and the card scrolls as ONE column. */
@media (max-width: 46rem) {
  .lightbox { padding: .5rem; }
  .lightbox__frame { gap: .5rem; width: 100%; }
  /* ⛔ ONE scroll, not three. With the picture, the details and the menu each
     scrolling inside their own box, the menu ended up below the fold of a box
     nobody could tell was scrollable, and read as a truncated list. */
  .lightbox__panel {
    grid-template-columns: 1fr;
    grid-template-rows: none;
    overflow-y: auto;
  }
  /* ⛔ min-height:0 is what lets a grid item shrink below its content. It is
     right in the three-column layout, where each column scrolls itself, and
     wrong here: the grid squeezed the dish column to fit and the panel clipped
     the overflow, so the price was sliced in half and the order button
     vanished entirely. On a phone every row keeps its natural height and the
     CARD does the scrolling. */
  .lightbox__stage { padding: 1rem; min-height: auto; }
  .lightbox__img { max-width: 100%; max-height: 28vh; }
  .lightbox__info { padding: 1.35rem; overflow: visible; min-height: auto; }
  .lightbox__menu { min-height: auto; }
  .lightbox__name { font-size: 1.35rem; }
  .lightbox__cta { margin-top: 1.25rem; padding-top: 0; }
  .lightbox__order { width: 100%; white-space: normal; }
  .lightbox__menu-head { position: sticky; top: 0; background: var(--limewash-warm); z-index: 1; }
  .lightbox__menu-scroll { max-height: none; overflow: visible; }
  .lightbox__menu::after { display: none; }
  /* The arrows would sit on the card at this width, so they go to the bottom
     rail either side of the counter. */
  .lightbox__nav { top: auto; bottom: -.15rem; transform: none; width: 44px; height: 44px; }
  .lightbox__nav--prev { left: .2rem; }
  .lightbox__nav--next { right: .2rem; }
  .lightbox__count { padding-inline: 3.2rem; }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox, .lightbox__panel, .lightbox__row { transition: none; }
  .lightbox__panel { transform: none; }
}
