/* =============================================================================
   LA BOCATA: styles.css
   Direction: "El Menú del Día". The site is art-directed as La Bocata's own
   printed menu card, blown up to magazine scale.

   Contract: DESIGN-SYSTEM.md. Every component in that catalogue is styled here,
   including the ordering and admin components, because the page builders add no
   CSS of their own.

   HARD TYPE RULE, stated here so it survives future edits:
     Fraunces is ONLY ever a name or a headline. It never appears in a button, a
     chip, a label, a price, a form field or a table cell.
     There are NO ITALICS on this site. No italic file is self-hosted and a
     browser-synthesised oblique on a high-contrast serif looks cheap, so
     `font-style: italic` appears nowhere. Emphasis is weight and letterspaced caps.
     No `font-variation-settings` either: the axes were checked (Fraunces = opsz +
     wght, DM Sans = wght, no SOFT/WONK) and fonts.css caps the usable range at
     400 to 700, so plain `font-weight` is enough.

   HARD COLOUR RULE:
     The GOLD held in --mustard (#f4ae2b, from the logo) is 1.80:1 on cream. It
     is a FILL token only. No rule in this file sets `color` to it on a cream
     surface. The primary CTA is the logo RED (--terracotta #da2227) with a
     WHITE label (4.95:1); the old mustard could never carry white, the logo red
     can, and that is the one real change to the button system.

   CONTENTS
     01  Tokens
     02  Reset and base
     03  Layout: wrap, section, band, flow
     04  Utilities
     05  Ornament: rosette, flourish, trim, rule
     06  Buttons
     07  Badges and chips
     08  Forms
     09  Skip link and preview notice
     10  Site header, nav, wordmark, status chip
     11  Mobile menu
     12  Hero
     13  Trust bar and rating chip
     14  Section heading
     15  Counter board (homepage 02)
     16  Item card and card grid
     17  Menu category, item row, the dot leader
     18  Category rail
     19  Media, gallery, photo run
     20  Quote and review card
     21  Hours table
     22  Find us, address, contact
     23  CTA band and page head
     24  Footer and social tiles
     25  Sticky order bar
     26  Sheet shell, paper, cart, options
     27  Cart line and stepper
     28  Fulfilment toggle
     29  Slot picker
     30  Order summary and order panel
     31  Admin order board
     32  Empty state, toast, alert
     33  404 and prose
     34  Motion
     35  Reduced motion
     36  Print
   ========================================================================== */

/* =============================================================================
   01  TOKENS
   ========================================================================== */

:root {
  /* --- colour ------------------------------------------------------------ */
  /* Palette sampled directly from Esther's real logo (2026-07-26): deep navy
     wordmark, VIVID red scrollwork and rosette, golden-amber "THE SANDWICH",
     on a warm cream. The token NAMES below are historical: --mustard now holds
     the logo GOLD and --terracotta now holds the logo RED. Values were changed
     in place rather than renamed, because 45 --mustard and 25 --terracotta
     usages (plus embedded rgba channels) made a rename pure risk for no gain. */
  --cream: #fbf7ef; /* the page, ~70% of every screen. The logo sits on white. */
  --cream-2: #f2ebda; /* alternating bands, row hover */
  --paper: #fffdf6; /* the WRAP: cart + confirmation */
  --near-white: #fffdf8;

  --navy: #182041; /* logo wordmark. Display type, rules, fixed bars. 14.87:1 on cream */
  --navy-panel: #131a3a; /* reversed panels */
  --navy-deep: #0b1024; /* footer */
  --navy-press: #101630;

  --ink: #231a12; /* body copy, 16.0:1 on cream */
  --ink-78: #584f46; /* descriptions, 7.4:1 on the new cream */
  --ink-70: #686056; /* captions, meta, 5.7:1. Do not go lighter. */

  /* GOLD (historically --mustard). FILL ONLY: 1.80:1 on cream. Legible as type
     only on navy (8.27:1). Primary button label is INK on gold (8.91:1). */
  --mustard: #f4ae2b;
  --mustard-press: #d9931f;

  /* RED (historically --terracotta). The logo's vivid red. Unlike the old muted
     terracotta this IS a valid primary button: WHITE on #da2227 is 4.95:1. */
  --terracotta: #da2227; /* trim, plate motif, rules, primary button fill. */
  --terracotta-deep: #b3141a; /* pressed / closed-state fill, WHITE 6.93:1, cream 6.1:1 */
  --terracotta-text: #c01a1f; /* small red text on cream, 5.77:1 */

  --rule: rgba(24, 32, 65, 0.18); /* decorative hairlines between rows */
  --rule-strong: rgba(24, 32, 65, 0.32); /* decorative, heavier */
  --rule-rev: rgba(251, 247, 239, 0.22);
  /* Interactive component boundaries. WCAG 2.2 SC 1.4.11 wants 3:1 for the edge
     of a control. The new navy is darker than the old, so these clear 3:1 on
     cream, cream-2 and paper by a wider margin than before; the reversed one on
     navy is 3.5:1. */
  --edge: rgba(24, 32, 65, 0.62);
  --edge-rev: rgba(251, 247, 239, 0.46);
  --leader: rgba(24, 32, 65, 0.38);

  --focus: #182041;
  --focus-rev: #fbf7ef;

  /* --- spacing ----------------------------------------------------------- */
  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;
  --s-8: 64px;
  --s-9: 96px;
  --s-10: 128px;

  --page-x: 20px;
  --gutter: 24px;
  --maxw: 1180px;
  --maxw-narrow: 760px;
  --maxw-wide: 1400px;
  --section-y: clamp(56px, 9vw, 112px);
  --measure: 58ch;

  /* --- radii and lines --------------------------------------------------- */
  --r-0: 0;
  --r-chip: 2px;
  --r-pill: 999px;
  --hair: 1px;

  /* --- the only three shadows in the build ------------------------------- */
  --shadow-tile: 0 4px 14px rgba(35, 26, 18, 0.18);
  --shadow-tile-hover: 0 8px 22px rgba(35, 26, 18, 0.28);
  --shadow-sheet: 0 -14px 44px rgba(11, 16, 36, 0.24);

  /* --- type -------------------------------------------------------------- */
  --f-display: 'Fraunces', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --f-sans: 'DM Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;

  --t-h1: clamp(2.5rem, 9.5vw, 6rem);
  --t-h2: clamp(2rem, 6vw, 3.5rem);
  --t-cat: clamp(1.75rem, 7vw, 3rem);
  --t-item: clamp(1.25rem, 1.05rem + 0.6vw, 1.5rem);
  --t-quote: clamp(1.375rem, 4.5vw, 2.125rem);
  --t-body: 1.0625rem;
  --t-body-lg: 1.125rem;
  --t-small: 0.9375rem;
  --t-meta: 0.8125rem;
  --t-eyebrow: 0.6875rem;
  --t-caption: 0.75rem;

  /* --- motion ------------------------------------------------------------ */
  --e-out: cubic-bezier(0.16, 1, 0.3, 1);
  --e-inout: cubic-bezier(0.22, 1, 0.28, 1);
  --d-fast: 180ms;
  --d-base: 260ms;
  --d-slow: 400ms;
  --d-reveal: 700ms;
  --d-sheet: 300ms;

  /* --- layering and bar heights ------------------------------------------ */
  --z-rail: 40;
  --z-header: 60;
  --z-order-bar: 65;
  --z-menu: 80;
  --z-sheet: 90;
  --z-toast: 100;

  /* Set per element by js/main.js from data-d. Declared here so it is
     discoverable; every use also carries a fallback. */
  --reveal-delay: 0ms;

  /* --header-h is the UNSCROLLED bar height and is what reserves body padding.
     --header-h-min is the condensed height and is what sticky things offset by,
     because by the time anything is stuck the bar has already condensed.
     Both are measured against the real content: wordmark 32px + padding. */
  --header-h: 60px;
  --header-h-min: 60px;
  --order-bar-h: 68px;

  /* Deep-link landing offset. A deep-linked control on menu.html is obstructed
     by the fixed header AND the sticky category rail beneath it (~60px + ~60px
     ≈ 121px together), so a plain header-height scroll-padding drops the target
     under the rail. This clears both, intentionally, in one place. */
  --scroll-offset: calc(var(--header-h-min) + var(--safe-t) + 68px);

  --safe-t: env(safe-area-inset-top, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px);
  --safe-l: env(safe-area-inset-left, 0px);
  --safe-r: env(safe-area-inset-right, 0px);
}

@media (min-width: 768px) {
  :root {
    --page-x: 32px;
    --header-h: 80px; /* 56px inner + 12px padding top and bottom */
    --header-h-min: 56px;
  }
}

/* =============================================================================
   02  RESET AND BASE
   ========================================================================== */

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

* {
  margin: 0;
}

html {
  /* iOS 26 glass recipe, step 2: explicit, never transparent. Must equal --cream. */
  background-color: #fbf7ef;
  color-scheme: light;

  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scrollbar-gutter: stable;
  overflow-x: clip; /* clip, not hidden: does not create a scroll container, so sticky still works */
  scroll-behavior: smooth;
  scroll-padding-top: var(--scroll-offset);
}

body {
  margin: 0;
  background-color: var(--cream);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
  padding-top: calc(var(--header-h) + var(--safe-t));
}

body:has(.order-bar),
body.has-order-bar {
  padding-bottom: calc(var(--order-bar-h) + var(--safe-b));
}

body.is-locked {
  overflow: hidden;
}

img,
picture,
svg,
video {
  display: block;
  max-width: 100%;
}

img {
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}

a {
  color: var(--navy);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

a:hover {
  color: var(--navy-press);
}

ul,
ol {
  padding: 0;
}

[role='list'],
.nav__list,
.mobile-menu__list,
.trust-bar__list,
.contact-list,
.footer-nav,
.menu-cat__list,
.board__list,
.card-grid,
.gallery__rail,
.cart__lines,
.orders,
.radio-list,
.order-summary__list {
  list-style: none;
}

table {
  border-collapse: collapse;
  width: 100%;
}

address {
  font-style: normal; /* no italics on this site */
}

blockquote {
  margin: 0;
}

fieldset {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}

legend {
  padding: 0;
}

hr {
  border: 0;
  border-top: var(--hair) solid var(--rule);
  margin-block: var(--s-6);
}

::selection {
  background: var(--mustard);
  color: var(--ink);
}

[hidden] {
  display: none !important;
}

:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
  border-radius: 1px;
}

.band--navy :focus-visible,
.band--panel :focus-visible,
.band--deep :focus-visible,
.order-bar :focus-visible,
.site-footer :focus-visible,
.mobile-menu :focus-visible {
  outline-color: var(--focus-rev);
}

/* Headings inherit nothing by default; every one is set by its component. */
h1,
h2,
h3,
h4 {
  font-weight: 600;
  line-height: 1.1;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

/* =============================================================================
   03  LAYOUT
   ========================================================================== */

.main {
  display: block;
}

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: max(var(--page-x), var(--safe-l)) max(var(--page-x), var(--safe-r));
}

.wrap--narrow {
  max-width: calc(var(--maxw-narrow) + var(--page-x) * 2);
}

.wrap--wide {
  max-width: var(--maxw-wide);
}

/* Full-width sections with padding on inner wrappers only.
   There is NO negative-margin 100vw bleed anywhere in this build: "full bleed"
   is an actual full-width section. That is the structural guarantee of zero
   horizontal scroll. */
.section {
  padding-block: var(--section-y);
}

.section--tight {
  padding-block: clamp(36px, 6vw, 64px);
}

.section--flush {
  padding-block: 0;
}

.band {
  background-color: var(--cream);
  color: var(--ink);
}

.band--cream-2 {
  background-color: var(--cream-2);
}

.band--navy {
  background-color: var(--navy);
  color: var(--cream);
}

.band--panel {
  background-color: var(--navy-panel);
  color: var(--cream);
}

.band--deep {
  background-color: var(--navy-deep);
  color: var(--cream);
}

/* Plain links on a dark band go cream. Buttons are EXCLUDED: this selector is
   (0,1,1) and out-specifies .btn--primary (0,1,0), which silently repainted the
   mustard CTA's label cream at 1.98:1 inside every navy band. */
.band--navy a:not([class*='btn']),
.band--panel a:not([class*='btn']),
.band--deep a:not([class*='btn']) {
  color: var(--cream);
}

.flow > * + * {
  margin-block-start: var(--s-4);
}

.flow > * + h2,
.flow > * + h3 {
  margin-block-start: var(--s-7);
}

/* =============================================================================
   04  UTILITIES
   ========================================================================== */

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.tabular {
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

.nowrap {
  white-space: nowrap;
}

.print-only {
  display: none;
}

.eyebrow {
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--navy);
}

.band--navy .eyebrow,
.band--panel .eyebrow,
.band--deep .eyebrow,
.order-bar .eyebrow {
  color: var(--cream);
}

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

/* =============================================================================
   05  ORNAMENT
   The only ornament in this build is La Bocata's own talavera rosette, lifted
   off the plaque on the shopfront wall, plus the filigree flourish, which
   appears exactly once, in the footer lockup. There is no icon set.
   ========================================================================== */

.rosette {
  width: 28px;
  height: 28px;
  /* Navy on cream. Mustard on cream is 1.98:1 and the ornament would vanish;
     mustard is reserved for the rosette sitting on a navy surface. */
  color: var(--navy);
  flex: none;
}

.band--navy .rosette,
.band--panel .rosette,
.band--deep .rosette,
.site-footer .rosette,
.mobile-menu .rosette {
  color: var(--mustard);
}

/* Footer lockup only, where it appears on the real plaque. Mustard on
   --navy-deep is 7.85:1. */
.flourish {
  width: 140px;
  height: 21px;
  color: var(--mustard);
  opacity: 0.85;
}

/* 6px terracotta trim closing every photograph, echoing the sun plates the food
   is actually served on. */
.trim {
  display: block;
  height: 6px;
  background-color: var(--terracotta);
}

/* The 2px mustard rule that draws itself in. Signature motion of the direction. */
.rule {
  display: block;
  width: 100%;
  max-width: 220px;
  height: 2px;
  margin-block-start: var(--s-5);
  background-color: var(--mustard);
  transform-origin: left center;
}

.band--navy .rule,
.band--panel .rule,
.band--deep .rule {
  background-color: var(--mustard);
}

/* =============================================================================
   06  BUTTONS
   Labels are always DM Sans 700 uppercase. Never Fraunces.
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 52px;
  padding-inline: var(--s-6);
  border: 2px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--f-sans);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out),
    color var(--d-fast) var(--e-out),
    transform var(--d-fast) var(--e-out);
}

.btn:hover {
  transform: translateY(-2px);
}

.btn:active {
  transform: translateY(0);
}

.btn--sm {
  min-height: 44px;
  padding-inline: var(--s-4);
  font-size: 0.75rem;
}

.btn--lg {
  min-height: 56px;
  padding-inline: var(--s-7);
}

.btn--block {
  display: flex;
  width: 100%;
}

.btn--primary {
  background-color: var(--terracotta);
  border-color: var(--terracotta);
  color: #fff; /* white on the logo red #da2227 = 4.95:1 */
}

.btn--primary:hover {
  background-color: var(--terracotta-deep);
  border-color: var(--terracotta-deep);
  color: #fff; /* white on #b3141a = 6.93:1 */
}

.btn--secondary {
  background-color: var(--navy);
  border-color: var(--navy);
  color: var(--cream); /* 10.63:1 */
}

.btn--secondary:hover {
  background-color: var(--navy-press);
  border-color: var(--navy-press);
  color: var(--cream);
}

.btn--ghost {
  background-color: transparent;
  border-color: var(--edge);
  color: var(--navy);
}

.btn--ghost:hover {
  border-color: var(--navy);
  background-color: var(--cream-2);
  color: var(--navy);
}

.btn--ghost-rev {
  background-color: transparent;
  border-color: var(--edge-rev);
  color: var(--cream);
}

.btn--ghost-rev:hover {
  border-color: var(--cream);
  color: var(--cream);
}

.btn--terracotta {
  background-color: var(--terracotta-deep);
  border-color: var(--terracotta-deep);
  color: var(--cream); /* 6.33:1 */
}

.btn--terracotta:hover {
  background-color: #8f1015;
  border-color: #8f1015;
  color: var(--cream);
}

.btn--link {
  min-height: 44px;
  padding-inline: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 0.3em;
}

.btn--link:hover {
  transform: none;
  color: var(--navy-press);
}

.btn[disabled],
.btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  transform: none;
}

/* =============================================================================
   07  BADGES AND CHIPS
   Badge strings are printed exactly as they appear in menu.json. No invented
   badge and no "Best seller" language anywhere.
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  min-height: 22px;
  padding-inline: var(--s-2);
  border: var(--hair) solid transparent;
  border-radius: var(--r-chip);
  font-family: var(--f-sans);
  font-size: 0.625rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  white-space: nowrap;
  vertical-align: 0.16em;
  margin-inline-start: var(--s-2);
}

.badge--loved,
.badge--local {
  background-color: var(--mustard);
  border-color: var(--mustard);
  color: var(--ink); /* 7.35:1 */
}

.badge--vegan,
.badge--veggie,
.badge--veg-option {
  background-color: transparent;
  border-color: var(--rule-strong);
  color: var(--navy); /* 10.63:1 */
}

.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding-inline: var(--s-4);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
  background-color: transparent;
  font-family: var(--f-sans);
  font-size: 0.8125rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy);
  white-space: nowrap;
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out);
}

.chip--selected {
  background-color: var(--mustard);
  border-color: var(--mustard);
  color: var(--ink);
}

.chip--disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* =============================================================================
   08  FORMS
   ========================================================================== */

.form {
  display: grid;
  gap: var(--s-5);
}

.form__row {
  display: grid;
  gap: var(--s-4);
}

@media (min-width: 560px) {
  .form__row {
    grid-template-columns: 1fr 1fr;
  }
}

.field {
  display: grid;
  gap: var(--s-2);
}

.field__label {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
}

.field__input,
.field__textarea {
  width: 100%;
  min-height: 52px;
  padding: var(--s-3) var(--s-4);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-chip);
  background-color: var(--near-white);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: 1rem; /* 16px minimum so iOS does not zoom on focus */
  line-height: 1.5;
  transition:
    border-color var(--d-fast) var(--e-out),
    background-color var(--d-fast) var(--e-out);
}

.field__textarea {
  min-height: 96px;
  resize: vertical;
}

.field__input::placeholder,
.field__textarea::placeholder {
  color: var(--ink-70);
}

.field__input:hover,
.field__textarea:hover {
  border-color: var(--navy);
}

.field__hint {
  font-size: var(--t-meta);
  line-height: 1.45;
  color: var(--ink-70);
}

.field__error {
  font-size: var(--t-meta);
  font-weight: 700;
  line-height: 1.45;
  color: var(--terracotta-text); /* 6.09:1 */
}

.field--invalid .field__input,
.field--invalid .field__textarea {
  border-color: var(--terracotta-deep);
  border-width: 2px;
}

.checkbox {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 44px;
}

.checkbox__input {
  width: 22px;
  height: 22px;
  flex: none;
  accent-color: var(--navy);
}

.checkbox__label {
  font-size: var(--t-body);
  line-height: 1.4;
  cursor: pointer;
}

/* Option groups inside the options sheet */
.radio-list {
  display: grid;
  gap: var(--s-2);
  margin: 0;
}

.radio-option {
  position: relative;
}

.radio-option__input {
  position: absolute;
  inset-block-start: 50%;
  inset-inline-start: var(--s-4);
  translate: 0 -50%;
  width: 22px;
  height: 22px;
  accent-color: var(--navy);
  margin: 0;
}

.radio-option__label {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  min-height: 52px;
  padding: var(--s-3) var(--s-4) var(--s-3) 54px;
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-chip);
  background-color: var(--near-white);
  font-size: var(--t-body);
  line-height: 1.35;
  cursor: pointer;
  transition:
    border-color var(--d-fast) var(--e-out),
    background-color var(--d-fast) var(--e-out);
}

.radio-option__label:hover {
  border-color: var(--navy);
}

.radio-option__input:checked + .radio-option__label {
  border-color: var(--navy);
  border-width: 2px;
  background-color: var(--cream-2);
}

.radio-option__input:focus-visible + .radio-option__label {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.radio-option__price {
  font-weight: 500;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.options__group + .options__group {
  margin-block-start: var(--s-6);
}

.options__group-title {
  display: block;
  margin-block-end: var(--s-3);
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
}

/* =============================================================================
   09  SKIP LINK AND PREVIEW NOTICE
   ========================================================================== */

.skip-link {
  position: absolute;
  inset-block-start: -100px;
  inset-inline-start: var(--s-4);
  z-index: 200;
  padding: var(--s-3) var(--s-5);
  background-color: var(--navy);
  color: var(--cream);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}

.skip-link:focus {
  inset-block-start: calc(var(--safe-t) + var(--s-2));
  color: var(--cream);
}

/* One slim line, in NORMAL FLOW, so it can never interact with the iOS bar rules. */
.preview-notice {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) max(var(--page-x), var(--safe-l));
  background-color: var(--ink);
  color: var(--cream);
  font-size: var(--t-meta);
  line-height: 1.4;
}

.preview-notice__text {
  flex: 1 1 auto;
}

.preview-notice__close {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-end: calc(var(--s-3) * -1);
  color: var(--cream);
}

.preview-notice__close svg {
  width: 16px;
  height: 16px;
}

.preview-notice__close:focus-visible {
  outline-color: var(--cream);
}

/* =============================================================================
   10  SITE HEADER
   iOS 26 glass recipe, steps 3 to 5: fully opaque on phones, no rgba and no
   backdrop-filter on the fixed element, safe-area padding, and the bar extended
   past the viewport edge with REAL border pixels (borders are the element's own
   paint box, so they survive where pseudo-element shields provably do not).
   ========================================================================== */

.site-header {
  position: fixed;
  inset-block-start: 0;
  inset-inline: 0;
  z-index: var(--z-header);

  background-color: var(--cream);
  border-top: 150px solid var(--cream);
  margin-top: -150px;
  border-bottom: var(--hair) solid transparent;

  padding-top: var(--safe-t);
  padding-inline: max(var(--page-x), var(--safe-l)) max(var(--page-x), var(--safe-r));

  transition: border-bottom-color var(--d-base) var(--e-out);
}

.site-header--scrolled {
  border-bottom-color: var(--rule);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  min-height: var(--header-h-min);
  padding-block: 0;
  transition: padding-block var(--d-base) var(--e-out);
}

.site-header__cta {
  display: none;
}

/* --- brand logo (the real lockup image) --------------------------------- */
/* Since 2026-07-26 the header carries Esther's actual full-colour logo (the
   whole "LA BOCATA / THE SANDWICH" + rosette lockup) as an image, not the
   typographic .wordmark. The link is a >=44px tap target and the image is
   sized so "THE SANDWICH" and the scrollwork stay legible, never mushy. */
.brand-logo {
  display: inline-flex;
  align-items: center;
  min-height: 44px; /* tap target, up from the old 32px wordmark */
  margin-inline-end: auto;
  padding-block: var(--s-1);
  padding-inline-end: var(--s-2); /* widens the hit area to the right */
  text-decoration: none;
  color: var(--navy);
}

.brand-logo img {
  display: block;
  width: auto;
  height: 46px; /* 600x314 lockup -> ~88px wide; THE SANDWICH stays readable at 390px */
  transition: opacity var(--d-fast) var(--e-out);
}

.brand-logo:hover img {
  opacity: 0.85; /* the lockup is full-colour, so a quiet fade, no colour shift */
}

@media (min-width: 768px) {
  .brand-logo img {
    height: 56px; /* fits the 56px inner row of the condensed desktop header */
  }
}

/* The reversed (cream wordmark) logo, for the navy-deep footer lockup. */
.brand-logo--footer {
  margin-inline-end: 0;
  min-height: 0;
  padding: 0;
}

.brand-logo--footer img {
  height: 60px;
}

.brand-logo--footer:hover img {
  opacity: 0.85;
}

/* --- wordmark (retained: still used for the footer/mobile-menu text mark) - */
.wordmark {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-inline-end: auto;
  text-decoration: none;
  color: var(--navy);
}

.wordmark__mark {
  width: 20px;
  height: 20px;
  color: var(--navy);
  transition: transform var(--d-base) var(--e-out);
}

.wordmark:hover .wordmark__mark {
  transform: rotate(22.5deg);
}

.wordmark__text {
  display: block;
}

.wordmark__name {
  display: block;
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--navy);
}

.wordmark__sub {
  display: block;
  margin-block-start: 3px;
  font-family: var(--f-sans);
  font-size: 0.5625rem;
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink-70);
}

/* --- nav ---------------------------------------------------------------- */
.nav {
  display: none;
}

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  margin: 0;
}

.nav__item {
  display: block;
}

.nav__link {
  position: relative;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--navy);
}

.nav__link::after {
  content: '';
  position: absolute;
  inset-block-end: 10px;
  inset-inline: 0;
  height: 2px;
  background-color: var(--mustard);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--d-base) var(--e-out);
}

.nav__link:hover::after,
.nav__link:focus-visible::after,
.nav__link--current::after {
  transform: scaleX(1);
}

/* --- open/closed status chip -------------------------------------------- */
.status-chip {
  display: none;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-3);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
  font-family: var(--f-sans);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--navy);
  white-space: nowrap;
}

.status-chip__text {
  display: inline-block;
}

.status-chip__dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-pill);
  background-color: var(--mustard);
  box-shadow: 0 0 0 1px var(--edge);
  flex: none;
}

.status-chip--closed .status-chip__dot {
  background-color: var(--terracotta);
}

/* --- nav toggle --------------------------------------------------------- */
.nav-toggle {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -10px;
  flex: none;
  color: var(--navy);
}

.nav-toggle__bars {
  display: grid;
  gap: 6px;
  width: 22px;
}

.nav-toggle__bars > span {
  display: block;
  height: 2px;
  background-color: currentColor;
  transition: transform var(--d-base) var(--e-out);
}

.nav-toggle[aria-expanded='true'] .nav-toggle__bars > span:first-child {
  transform: translateY(4px) rotate(45deg);
}

.nav-toggle[aria-expanded='true'] .nav-toggle__bars > span:last-child {
  transform: translateY(-4px) rotate(-45deg);
}

@media (min-width: 768px) {
  .site-header__inner {
    padding-block: var(--s-3);
  }

  .site-header--scrolled .site-header__inner {
    padding-block: 0;
  }

  .status-chip {
    display: inline-flex;
  }
}

@media (min-width: 1040px) {
  .nav {
    display: block;
  }

  .site-header__cta {
    display: inline-flex;
  }

  .nav-toggle {
    display: none;
  }
}

/* =============================================================================
   11  MOBILE MENU
   Hidden with display:none via the [hidden] attribute, never with opacity or
   transform alone (iOS 26 rule).
   ========================================================================== */

.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: var(--z-menu);
  display: flex;
  justify-content: flex-end;
}

.mobile-menu__backdrop {
  position: absolute;
  inset: 0;
  background-color: rgba(11, 16, 36, 0.55);
  opacity: 0;
  transition: opacity var(--d-sheet) var(--e-inout);
}

.mobile-menu__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: min(420px, 100%);
  height: 100%;
  padding: calc(var(--safe-t) + var(--s-4)) max(var(--page-x), var(--safe-r))
    calc(var(--safe-b) + var(--s-5)) var(--page-x);
  background-color: var(--navy);
  color: var(--cream);
  transform: translateX(6%);
  opacity: 0;
  transition:
    transform var(--d-sheet) var(--e-inout),
    opacity var(--d-sheet) var(--e-inout);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.mobile-menu--open .mobile-menu__backdrop {
  opacity: 1;
}

.mobile-menu--open .mobile-menu__panel {
  transform: none;
  opacity: 1;
}

.mobile-menu__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block-end: var(--s-5);
  border-bottom: var(--hair) solid var(--rule-rev);
}

.mobile-menu__head .wordmark__name {
  color: var(--cream);
}

.mobile-menu__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -10px;
  color: var(--cream);
}

.mobile-menu__close svg {
  width: 20px;
  height: 20px;
}

.mobile-menu__list {
  margin: 0;
  padding-block: var(--s-4);
  flex: 1 1 auto;
}

.mobile-menu__link {
  display: flex;
  align-items: center;
  min-height: 60px;
  border-bottom: var(--hair) solid var(--rule-rev);
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-weight: 600;
  font-size: 1.75rem;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-decoration: none;
  color: var(--cream);
  transition: color var(--d-fast) var(--e-out);
}

.mobile-menu__link:hover {
  color: var(--mustard);
}

.mobile-menu__foot {
  display: grid;
  gap: var(--s-3);
  padding-block-start: var(--s-5);
}

@media (min-width: 1040px) {
  .mobile-menu {
    display: none !important;
  }
}

/* =============================================================================
   12  HERO
   Magazine cover, not a banner. At 390px the TYPE paints first, so the LCP
   element is text with zero image dependency. The h1 is flush left and never
   sits on top of a photo.
   ========================================================================== */

.hero {
  position: relative;
  padding-block-start: clamp(28px, 6vw, 56px);
}

.hero__inner {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: max(var(--page-x), var(--safe-l)) max(var(--page-x), var(--safe-r));
}

.hero__type {
  display: block;
  max-width: 22ch;
}

@media (min-width: 560px) {
  .hero__type {
    max-width: none;
  }
}

.hero__eyebrow {
  margin-block-end: var(--s-4);
  color: var(--ink-70);
}

.hero__title {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-h1);
  font-weight: 700;
  line-height: 0.94;
  letter-spacing: -0.02em;
  color: var(--navy);
  text-wrap: balance;
}

.hero__line {
  display: block;
}

.hero__line--light {
  font-weight: 400;
  letter-spacing: -0.015em;
}

.hero__sub {
  max-width: 44ch;
  margin-block-start: var(--s-5);
  font-size: var(--t-body-lg);
  line-height: 1.6;
  color: var(--ink-78);
}

.hero__ctas {
  display: grid;
  gap: var(--s-3);
  margin-block-start: var(--s-6);
}

.hero__figure {
  margin-block-start: var(--s-7);
}

.hero__img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 45%;
  will-change: transform;
}

.hero__caption {
  padding: var(--s-3) max(var(--page-x), var(--safe-l));
  font-family: var(--f-sans);
  font-size: var(--t-caption);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-70);
}

@media (min-width: 560px) {
  .hero__ctas {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1040px) {
  .hero {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 46%);
    align-items: center;
    column-gap: var(--s-8);
    padding-inline-start: max(0px, calc((100% - var(--maxw)) / 2));
    padding-block: var(--s-9) 0;
  }

  .hero__inner {
    grid-column: 1;
    grid-row: 1;
    max-width: none;
    margin-inline: 0;
    padding-inline-start: max(var(--page-x), var(--safe-l));
    padding-inline-end: 0;
  }

  .hero__figure {
    position: relative;
    grid-column: 2;
    grid-row: 1;
    align-self: stretch;
    display: flex;
    flex-direction: column;
    margin-block-start: 0;
  }

  .hero__img {
    aspect-ratio: 3 / 4;
    height: 100%;
    min-height: 62vh;
    max-height: 78vh;
  }

  .hero__caption {
    padding-inline: 0 max(var(--page-x), var(--safe-r));
  }

  .hero__ctas {
    grid-template-columns: repeat(2, minmax(0, auto));
    justify-content: start;
  }

  .hero__ctas .btn--block {
    width: auto;
  }
}

/* =============================================================================
   13  TRUST BAR AND RATING CHIP
   Every chip traces to brief/FACTS.md. The 5.0 from 82 is a linked VISUAL chip
   and appears nowhere in the structured data.
   ========================================================================== */

.trust-bar {
  padding-block: var(--s-5);
  border-block: var(--hair) solid var(--rule);
  background-color: var(--cream);
}

.trust-bar__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin: 0;
}

.trust-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 36px;
  padding-inline: var(--s-4);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-pill);
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  line-height: 1.2;
  color: var(--ink);
}

.trust-chip__strong {
  font-weight: 700;
}

.trust-chip--closed {
  background-color: var(--terracotta-deep);
  border-color: var(--terracotta-deep);
  color: var(--cream); /* 6.33:1 */
}

.rating-chip {
  display: inline-flex;
  align-items: center; /* was baseline; centre keeps the 44px pill balanced */
  gap: var(--s-2);
  min-height: 44px; /* house 44px tap target (the chip is a link) */
  padding: 0 var(--s-4);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
  text-decoration: none;
  color: var(--navy);
  transition:
    border-color var(--d-fast) var(--e-out),
    background-color var(--d-fast) var(--e-out);
}

.rating-chip:hover {
  border-color: var(--navy);
  background-color: var(--cream-2);
}

.rating-chip__score {
  font-family: var(--f-sans);
  font-size: 1rem;
  font-weight: 700;
  color: var(--navy);
}

.rating-chip__label {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  color: var(--ink);
}

.site-footer .rating-chip,
.band--navy .rating-chip,
.band--panel .rating-chip,
.band--deep .rating-chip {
  border-color: var(--rule-rev);
  color: var(--cream);
}

.site-footer .rating-chip:hover,
.band--navy .rating-chip:hover {
  border-color: var(--cream);
  background-color: rgba(251, 247, 239, 0.08);
}

.site-footer .rating-chip__score,
.site-footer .rating-chip__label,
.band--navy .rating-chip__score,
.band--navy .rating-chip__label {
  color: var(--cream);
}

/* =============================================================================
   14  SECTION HEADING (bilingual)
   ========================================================================== */

.section-head {
  position: relative;
  max-width: 34ch;
}

.section-head__index {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  margin-block-end: var(--s-4);
  padding-inline: var(--s-2);
  border-radius: var(--r-chip);
  background-color: var(--mustard);
  font-family: var(--f-sans);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ink); /* 7.35:1 */
  font-variant-numeric: tabular-nums;
}

.section-head__es {
  display: block;
  margin-block-end: var(--s-2);
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--terracotta-text); /* 6.09:1 */
}

.section-head__en {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-h2);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.015em;
  color: var(--navy);
}

.section-head__blurb {
  max-width: var(--measure);
  margin-block-start: var(--s-4);
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--ink-78);
}

.section-head--reverse .section-head__en {
  color: var(--cream);
}

.section-head--reverse .section-head__es {
  color: var(--mustard); /* 5.37:1 on navy. mustard-press would be 4.13:1. */
}

.band--navy .section-head__es,
.band--panel .section-head__es,
.band--deep .section-head__es {
  color: var(--mustard);
}

.band--navy .section-head__en,
.band--panel .section-head__en,
.band--deep .section-head__en {
  color: var(--cream);
}

.band--navy .section-head__blurb,
.band--panel .section-head__blurb,
.band--deep .section-head__blurb {
  color: rgba(251, 247, 239, 0.82);
}

/* =============================================================================
   15  COUNTER BOARD (homepage section 02)
   Four typographic rows, one per menu.json category. Not cards.
   ========================================================================== */

.board {
  margin-block-start: var(--s-7);
}

.board__list {
  margin: 0;
  border-top: var(--hair) solid var(--rule);
}

.board-row {
  border-bottom: var(--hair) solid var(--rule);
}

.board-row__link {
  display: grid;
  grid-template-columns: auto 1fr 96px;
  align-items: center;
  gap: var(--s-4);
  padding-block: var(--s-5);
  text-decoration: none;
  color: var(--ink);
  transition: background-color var(--d-fast) var(--e-out);
}

.board-row__link:hover {
  background-color: var(--cream-2);
  color: var(--ink);
}

.board-row__index {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  border-radius: var(--r-chip);
  background-color: var(--mustard);
  font-family: var(--f-sans);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  align-self: start;
  margin-block-start: 6px;
  transition: transform var(--d-base) var(--e-out);
}

.board-row__link:hover .board-row__index,
.board-row__link:focus-visible .board-row__index {
  transform: scale(1.08);
}

.board-row__body {
  min-width: 0;
}

.board-row__es {
  display: block;
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-cat);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--navy);
}

.board-row__en {
  display: block;
  margin-block-start: var(--s-2);
  font-family: var(--f-sans);
  font-size: var(--t-small);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
}

.board-row__meta {
  display: block;
  margin-block-start: 2px;
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  line-height: 1.4;
  color: var(--ink-70);
  font-variant-numeric: tabular-nums;
}

.board-row__thumb {
  display: block;
  width: 96px;
  height: 96px;
  overflow: hidden;
  align-self: center;
}

.board-row__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.board__panel {
  display: none;
}

.board__cta {
  margin-block-start: var(--s-6);
}

@media (min-width: 1040px) {
  .board {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 38%);
    align-items: start;
    gap: var(--s-8);
  }

  .board__list {
    grid-column: 1;
  }

  .board-row__link {
    grid-template-columns: auto 1fr;
    padding-block: var(--s-6);
  }

  .board-row__thumb {
    display: none;
  }

  .board__panel {
    display: block;
    position: sticky;
    inset-block-start: calc(var(--header-h-min) + var(--safe-t) + var(--s-6));
    grid-column: 2;
    aspect-ratio: 3 / 4;
  }

  .board__panel-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 240ms var(--e-out);
  }

  .board__panel-img--active {
    opacity: 1;
  }

  .board__cta {
    grid-column: 1;
    justify-self: start;
    width: auto;
  }
}

/* =============================================================================
   16  ITEM CARD AND CARD GRID (homepage shortlist)
   Text only. Rule 5 forbids putting a photograph next to a single item name.
   ========================================================================== */

.card-grid {
  display: grid;
  gap: var(--s-5);
  margin: 0;
  margin-block-start: var(--s-7);
}

@media (min-width: 768px) {
  .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-6);
  }
}

.item-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding-block: var(--s-5);
  border-top: 2px solid var(--navy);
}

.item-card__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}

.item-card__name {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-item);
  font-weight: 600;
  line-height: 1.15;
  color: var(--navy);
}

.item-card__price {
  flex: none;
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.item-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
}

.item-card__badges .badge {
  margin-inline-start: 0;
}

.item-card__desc {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--ink-78);
}

.item-card__foot {
  margin-block-start: auto;
  padding-block-start: var(--s-3);
}

/* =============================================================================
   17  MENU CATEGORY, ITEM ROW, THE DOT LEADER
   The dot leader is the component nobody templates: item name, a row of navy
   dots, then the price, tabular.
   ========================================================================== */

.menu-cat {
  padding-block-end: var(--section-y);
  scroll-margin-top: calc(var(--header-h-min) + var(--safe-t) + 56px);
}

.menu-cat:nth-of-type(even) {
  background-color: var(--cream-2);
}

.menu-cat__spread {
  margin-block-end: var(--s-7);
}

.menu-cat__spread img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}

.menu-cat__list {
  margin: 0;
  margin-block-start: var(--s-7);
  border-top: 2px solid var(--navy);
}

/* --- the row ------------------------------------------------------------ */
.item-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px;
  column-gap: var(--s-4);
  row-gap: var(--s-2);
  padding-block: var(--s-4);
  border-bottom: var(--hair) solid var(--rule);
  transition: background-color 200ms var(--e-out);
}

.item-row:hover,
.item-row--pressed {
  background-color: var(--cream-2);
}

.menu-cat:nth-of-type(even) .item-row:hover,
.menu-cat:nth-of-type(even) .item-row--pressed {
  background-color: var(--cream);
}

.item-row__main {
  grid-column: 1;
  grid-row: 1;
  min-width: 0;
}

.item-row__name {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-item);
  font-weight: 600;
  line-height: 1.15;
  color: var(--navy);
  text-wrap: pretty;
}

/* The leader is off below 340px: the row stacks name over price instead.
   "Churros with Sugar & Cinnamon" plus a badge is the breaking case. */
.item-row__leader {
  display: none;
}

.item-row__price {
  display: block;
  margin-block-start: var(--s-1);
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  transition: transform 200ms var(--e-out);
}

.item-row__from {
  font-size: var(--t-meta);
  font-weight: 500;
  color: var(--ink-70);
}

.item-row__desc {
  grid-column: 1;
  grid-row: 2;
  max-width: 46ch;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--ink-78);
}

.item-row__add {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: start;
  justify-self: end;
}

@media (min-width: 340px) {
  .item-row__main {
    display: flex;
    align-items: baseline;
    gap: 0;
  }

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

  .item-row__leader {
    display: block;
    flex: 1 1 12px;
    min-width: 12px;
    height: 6px;
    align-self: baseline;
    margin-inline: 10px;
    background-image: radial-gradient(circle at 3.5px 3px, var(--leader) 1.4px, transparent 1.5px);
    background-size: 7px 6px;
    background-repeat: repeat-x;
    transition: background-position-x 200ms var(--e-out);
  }

  .item-row__price {
    flex: none;
    margin-block-start: 0;
  }
}

/* Row press: the price slides toward the name and the dots visibly travel.
   Costs nothing, feels bespoke. */
.item-row--pressed .item-row__price {
  transform: translateX(-2px);
}

.item-row--pressed .item-row__leader {
  background-position-x: 3px;
}

/* --- the add button ----------------------------------------------------- */
.add-btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 2px solid var(--mustard);
  /* The mustard ring is the art direction; the inset hairline is what makes the
     control boundary discernible (mustard on cream is 1.98:1). */
  box-shadow: inset 0 0 0 1px var(--edge);
  border-radius: var(--r-pill);
  background-color: transparent;
  color: var(--navy);
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out),
    box-shadow var(--d-fast) var(--e-out);
}

.add-btn:hover,
.add-btn:active {
  background-color: var(--mustard);
  border-color: var(--mustard);
  box-shadow: inset 0 0 0 1px var(--mustard);
  color: var(--ink);
}

.add-btn__glyph {
  font-family: var(--f-sans);
  font-size: 1.25rem;
  font-weight: 500;
  line-height: 1;
}

/* =============================================================================
   18  CATEGORY RAIL (menu page)
   Sticky, not fixed, so the iOS fixed-bar rules do not apply. Still opaque.
   ========================================================================== */

.cat-rail {
  position: sticky;
  inset-block-start: calc(var(--header-h-min) + var(--safe-t));
  z-index: var(--z-rail);
  background-color: var(--cream);
  border-bottom: var(--hair) solid var(--rule);
}

.cat-rail__inner {
  display: flex;
  gap: var(--s-2);
  padding-block: var(--s-2);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
}

.cat-rail__inner::-webkit-scrollbar {
  display: none;
}

.cat-rail__chip {
  flex: none;
  scroll-snap-align: start;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: var(--s-4);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
  background-color: transparent;
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--navy);
  white-space: nowrap;
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out),
    color var(--d-fast) var(--e-out);
}

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

.cat-rail__chip--current {
  background-color: var(--mustard);
  border-color: var(--mustard);
  color: var(--ink); /* 7.35:1 */
}

/* =============================================================================
   19  MEDIA, GALLERY, PHOTO RUN
   Every photograph touches a viewport edge and is closed with the 6px
   terracotta trim.
   ========================================================================== */

.media {
  display: block;
}

.media--full img {
  width: 100%;
}

/* bocatas-table-spread: a stranger's striped torso and hand sit at the TOP
   RIGHT of that frame. 78% pushes them out and fills the frame with sandwiches. */
.media--bench img {
  object-position: 50% 78%;
}

/* counter-and-menu-board is the single riskiest asset in the folder: at 900px
   the RETIRED chalk board is legible (THE NAVARRE, THE BREKKIE, £4.50 prices)
   and FACTS.md says to ignore that board entirely. Cap it and pull the crop left
   onto the counter and the team. Never full-bleed, never on the menu page. */
.media--capped {
  max-width: 560px;
}

.media--counter img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: 22% 50%;
}

.gallery-figure {
  position: relative;
}

.gallery-figure__img {
  width: 100%;
}

.gallery-figure__caption {
  padding: var(--s-3) max(var(--page-x), var(--safe-l));
  font-family: var(--f-sans);
  font-size: var(--t-caption);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-70); /* 5.64:1 */
}

.photo-run {
  display: block;
}

.photo-run__full img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.photo-run__text {
  padding-block: var(--section-y);
}

.photo-run__text p {
  max-width: var(--measure);
}

.photo-run__two {
  display: grid;
  gap: var(--s-1);
}

.photo-run__two img {
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
}

@media (min-width: 768px) {
  .photo-run__two {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* Scroll-snap gallery band */
.gallery {
  overflow: hidden;
}

.gallery__rail {
  display: flex;
  gap: var(--s-1);
  margin: 0;
  padding-inline: max(var(--page-x), var(--safe-l));
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

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

.gallery__rail > li {
  flex: 0 0 78%;
  scroll-snap-align: start;
}

.gallery-figure--snap img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

.gallery-figure--snap .gallery-figure__caption {
  padding-inline: 0;
}

@media (min-width: 768px) {
  .gallery__rail > li {
    flex: 0 0 38%;
  }
}

@media (min-width: 1280px) {
  .gallery__rail > li {
    flex: 0 0 26%;
  }
}

/* =============================================================================
   20  QUOTE AND REVIEW CARD
   Verbatim reviews only. No dates (Google's relative dates drift). No invented
   star rows. Nothing here ever reaches the JSON-LD.
   ========================================================================== */

.quotes-grid {
  display: grid;
  gap: var(--s-7);
  margin-block-start: var(--s-7);
}

@media (min-width: 900px) {
  .quotes-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-6);
  }
}

.quote {
  padding-block-start: var(--s-5);
  border-top: 2px solid var(--rule-strong);
}

.quote__text {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-quote);
  font-weight: 400;
  line-height: 1.3;
  letter-spacing: -0.005em;
  color: var(--navy);
  text-wrap: pretty;
}

.quote__attrib {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin-block-start: var(--s-4);
}

.quote__name {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  font-style: normal;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink);
}

.quote__badge {
  font-family: var(--f-sans);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-70);
}

/* The starred variant is ONLY valid inside a navy band: gold on cream is 1.98:1
   and must never happen. Stars are real data (reviews.json stars: 5). */
.reviews-grid {
  display: grid;
  gap: var(--s-5);
  margin-block-start: var(--s-7);
}

@media (min-width: 700px) {
  .reviews-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1040px) {
  .reviews-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.review-card {
  padding-block-start: var(--s-4);
  border-top: var(--hair) solid var(--rule-rev);
}

.review-card__stars {
  display: flex;
  gap: 2px;
  margin-block-end: var(--s-3);
}

.review-card__stars svg {
  width: 16px;
  height: 16px;
  color: var(--mustard); /* 5.37:1 on navy, 6.73:1 on the panel */
}

.band--navy .review-card__stars svg,
.band--panel .review-card__stars svg,
.band--deep .review-card__stars svg {
  color: var(--mustard);
}

/* Belt and braces: if a review card is ever placed on cream by mistake, the
   stars go navy rather than shipping a 1.98:1 contrast failure. */
.review-card__stars svg {
  color: var(--navy);
}

.band--navy .review-card,
.band--panel .review-card,
.band--deep .review-card {
  color: var(--cream);
}

.review-card__text {
  font-size: var(--t-body);
  line-height: 1.6;
}

.review-card__name {
  margin-block-start: var(--s-3);
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.review-card__badge {
  margin-inline-start: var(--s-2);
  font-size: 0.625rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--mustard);
  text-transform: uppercase;
}

/* =============================================================================
   21  HOURS TABLE
   ========================================================================== */

.hours {
  width: 100%;
  max-width: 420px;
  margin-block-start: var(--s-4);
  font-size: var(--t-body);
}

.hours__row {
  border-bottom: var(--hair) solid var(--rule);
}

.hours__day,
.hours__time {
  padding-block: var(--s-3);
  text-align: start;
  font-weight: 400;
  vertical-align: baseline;
}

.hours__day {
  font-family: var(--f-sans);
  color: var(--ink);
}

.hours__time {
  font-family: var(--f-sans);
  color: var(--ink-78);
  font-variant-numeric: tabular-nums;
  text-align: end;
}

.hours__row--today {
  position: relative;
}

.hours__row--today .hours__day,
.hours__row--today .hours__time {
  font-weight: 700;
  color: var(--navy);
}

.hours__row--today .hours__day {
  box-shadow: inset 3px 0 0 0 var(--mustard);
  padding-inline-start: var(--s-3);
}

.hours__row--closed .hours__time {
  color: var(--terracotta-text); /* 6.09:1 */
  font-weight: 500;
}

.hours--compact {
  font-size: var(--t-meta);
}

.hours--compact .hours__day,
.hours--compact .hours__time {
  padding-block: var(--s-2);
}

.site-footer .hours__row {
  border-bottom-color: var(--rule-rev);
}

.site-footer .hours__day {
  color: var(--cream);
}

.site-footer .hours__time {
  color: rgba(251, 247, 239, 0.78);
}

.site-footer .hours__row--today .hours__day,
.site-footer .hours__row--today .hours__time {
  color: var(--cream);
}

.site-footer .hours__row--closed .hours__time {
  color: rgba(251, 247, 239, 0.7);
}

/* =============================================================================
   22  FIND US, ADDRESS, CONTACT
   No map iframe: third-party request, privacy, and the static preview stays clean.
   ========================================================================== */

.find-us {
  padding-block: 0;
}

.find-us__media img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: 50% 40%;
}

.find-us__body {
  padding-block: var(--section-y);
}

.address {
  display: grid;
  margin-block-start: var(--s-5);
  font-size: var(--t-body-lg);
  line-height: 1.5;
  color: var(--ink);
}

.address__line {
  display: block;
}

.contact-list {
  display: grid;
  gap: var(--s-1);
  margin: 0;
  margin-block-start: var(--s-4);
}

.contact-link {
  display: inline-flex;
  align-items: center;
  min-height: 52px;
  font-family: var(--f-sans);
  font-size: var(--t-body-lg);
  font-weight: 500;
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 0.24em;
}

.contact-link:hover {
  color: var(--navy-press);
}

.site-footer .contact-link {
  min-height: 44px;
  font-size: var(--t-body);
  color: var(--cream);
}

@media (min-width: 1040px) {
  .find-us {
    display: grid;
    grid-template-columns: minmax(0, 42%) minmax(0, 1fr);
    align-items: center;
    column-gap: var(--s-8);
    padding-inline-end: max(0px, calc((100% - var(--maxw)) / 2));
  }

  .find-us__media {
    grid-column: 1;
  }

  .find-us__media img {
    aspect-ratio: 3 / 4;
    height: 100%;
    max-height: 82vh;
  }

  .find-us__body {
    grid-column: 2;
    max-width: none;
    margin-inline: 0;
    padding-inline-start: 0;
    padding-inline-end: max(var(--page-x), var(--safe-r));
  }
}

/* =============================================================================
   23  CTA BAND AND PAGE HEAD
   ========================================================================== */

.cta-band__inner {
  max-width: 44ch;
}

.cta-band__title {
  margin-block-start: var(--s-4);
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-h2);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -0.015em;
  color: var(--cream);
}

.cta-band__note {
  margin-block-start: var(--s-4);
  font-size: var(--t-body);
  line-height: 1.6;
  color: rgba(251, 247, 239, 0.82);
}

.cta-band .btn {
  margin-block-start: var(--s-6);
}

.page-head {
  padding-block: clamp(32px, 7vw, 72px) clamp(28px, 5vw, 48px);
}

.page-head__title {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-h1);
  font-weight: 700;
  line-height: 0.96;
  letter-spacing: -0.02em;
  color: var(--navy);
}

.page-head__sub {
  max-width: var(--measure);
  margin-block-start: var(--s-4);
  font-size: var(--t-body-lg);
  line-height: 1.6;
  color: var(--ink-78);
}

.page-head--reverse .page-head__title {
  color: var(--cream);
}

.page-head--reverse .page-head__sub {
  color: rgba(251, 247, 239, 0.82);
}

/* =============================================================================
   24  FOOTER AND SOCIAL TILES
   ========================================================================== */

.site-footer {
  background-color: var(--navy-deep);
  color: var(--cream);
  padding-block-start: var(--section-y);
}

.site-footer__inner {
  display: grid;
  gap: var(--s-7);
  padding-block-end: var(--s-8);
}

@media (min-width: 700px) {
  .site-footer__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1040px) {
  .site-footer__inner {
    grid-template-columns: 1.3fr 1fr 1fr 1fr;
    gap: var(--s-6);
  }
}

.site-footer__col {
  min-width: 0;
}

.site-footer__col--brand {
  grid-column: 1 / -1;
}

@media (min-width: 1040px) {
  .site-footer__col--brand {
    grid-column: auto;
  }
}

.site-footer__mark .wordmark__name {
  font-size: 1.75rem;
  color: var(--cream);
}

.site-footer__mark .wordmark__sub {
  color: rgba(251, 247, 239, 0.6);
}

.site-footer .flourish {
  margin-block-start: var(--s-4);
}

.site-footer__note {
  max-width: 30ch;
  margin-block-start: var(--s-4);
  font-size: var(--t-small);
  line-height: 1.6;
  color: rgba(251, 247, 239, 0.78);
}

.site-footer__title {
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--mustard); /* 7.85:1 on --navy-deep */
}

.site-footer .address {
  font-size: var(--t-body);
  color: rgba(251, 247, 239, 0.88);
  margin-block-start: var(--s-4);
}

.site-footer .rating-chip {
  margin-block-start: var(--s-4);
}

/* Official full-colour brand tiles: brand colour fills the tile, white glyph.
   Copied from _claude-shared/brand-assets/social-icons-color.html. */
.socialbar {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  margin-block-start: var(--s-4);
}

.socialbar a {
  width: 48px;
  height: 48px;
  border-radius: 14px;
  display: grid;
  place-items: center;
  box-shadow: var(--shadow-tile);
  transition:
    transform 0.2s ease,
    box-shadow 0.2s ease;
}

.socialbar a:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-tile-hover);
}

.socialbar a svg {
  width: 56%;
  height: 56%;
  display: block;
}

.site-footer__legal {
  border-top: var(--hair) solid var(--rule-rev);
  padding-block: var(--s-5) calc(var(--s-5) + var(--safe-b));
}

.site-footer__legal-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}

.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-5);
  margin: 0;
}

.footer-nav__link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: var(--t-meta);
  font-weight: 500;
  color: rgba(251, 247, 239, 0.82);
  text-decoration: none;
}

.footer-nav__link:hover {
  color: var(--cream);
  text-decoration: underline;
}

.credit {
  font-size: var(--t-meta);
  color: rgba(251, 247, 239, 0.82);
}

.credit a {
  color: var(--cream);
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 0.24em;
}

/* =============================================================================
   25  STICKY ORDER BAR
   iOS 26 glass recipe again: ALWAYS fully opaque navy, no rgba and no
   backdrop-filter on the fixed element, safe-area padding, and the bar extended
   past the viewport edge with real border pixels.
   The bar is never dead: empty state sells collection and offers the phone,
   because lunch trade rings.
   ========================================================================== */

.order-bar {
  position: fixed;
  inset-block-end: 0;
  inset-inline: 0;
  z-index: var(--z-order-bar);

  background-color: var(--navy);
  border-bottom: 200px solid var(--navy);
  margin-bottom: -200px;
  border-top: 2px solid transparent;

  padding-top: var(--s-3);
  padding-bottom: max(var(--s-3), var(--safe-b));
  padding-inline: max(var(--page-x), var(--safe-l)) max(var(--page-x), var(--safe-r));

  color: var(--cream);
  transition: border-top-color var(--d-slow) var(--e-out);
}

.order-bar__inner {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  min-height: 44px;
}

.order-bar__empty,
.order-bar__filled {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
}

.order-bar--empty .order-bar__filled {
  display: none;
}

.order-bar:not(.order-bar--empty) .order-bar__empty {
  display: none;
}

.order-bar__call {
  flex: none;
  min-width: 88px;
}

.order-bar__summary {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 600;
  line-height: 1.2;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}

.order-bar__count {
  font-weight: 700;
  display: inline-block;
}

.order-bar__count-label {
  font-weight: 500;
  color: rgba(251, 247, 239, 0.8);
}

.order-bar__total {
  margin-inline-start: auto;
  font-weight: 700;
}

.order-bar__filled .btn {
  flex: none;
}

@media (min-width: 560px) {
  .order-bar__total {
    margin-inline-start: var(--s-4);
  }

  .order-bar__filled .btn {
    margin-inline-start: auto;
  }
}

/* =============================================================================
   26  SHEET SHELL, PAPER, CART, OPTIONS
   One shell, two instances. Full-screen sheets on phones, never side drawers.
   Closed state is the [hidden] attribute (display:none), never opacity or
   transform alone.
   ========================================================================== */

.sheet {
  position: fixed;
  inset: 0;
  z-index: var(--z-sheet);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

.sheet__backdrop {
  position: absolute;
  inset: 0;
  background-color: rgba(11, 16, 36, 0.6);
  opacity: 0;
  transition: opacity var(--d-sheet) var(--e-inout);
}

.sheet__panel {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 640px;
  /* svh, not dvh and not 100%, so the iOS URL bar can never clip the confirm. */
  max-height: 88svh;
  background-color: var(--paper);
  color: var(--ink);
  box-shadow: var(--shadow-sheet);
  transform: translateY(100%);
  transition: transform var(--d-sheet) var(--e-inout);
}

.sheet--open .sheet__backdrop {
  opacity: 1;
}

.sheet--open .sheet__panel {
  transform: none;
}

.sheet__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  flex: none;
  padding: var(--s-5) var(--s-5) var(--s-4);
  border-bottom: var(--hair) solid var(--rule);
}

.sheet__title {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: 1.5rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--navy);
}

.sheet__close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-end: -10px;
  color: var(--navy);
  border-radius: var(--r-pill);
  transition: background-color var(--d-fast) var(--e-out);
}

.sheet__close:hover {
  background-color: var(--cream-2);
}

.sheet__close svg {
  width: 20px;
  height: 20px;
}

.sheet__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  padding: var(--s-5);
  display: grid;
  gap: var(--s-6);
}

.sheet__foot {
  flex: none;
  display: grid;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5) calc(var(--s-5) + var(--safe-b));
  border-top: var(--hair) solid var(--rule);
  background-color: var(--paper);
}

/* Two instances of one shell. The cart is the taller of the two and always
   carries the WRAP treatment; the options sheet is a short, focused decision. */
.sheet--cart .sheet__panel {
  min-height: 60svh;
}

.sheet--options .sheet__panel {
  max-height: 76svh;
}

@media (min-width: 700px) {
  .sheet {
    align-items: center;
  }

  .sheet__panel {
    max-height: 86svh;
  }

  .sheet--cart .sheet__panel {
    min-height: 0;
  }
}

/* --- the WRAP -----------------------------------------------------------
   The branded white greaseproof with the rosette repeat is the single most
   authentically-theirs surface in the business, so the order literally looks
   written on their sandwich paper. Background-image inside the component, NEVER
   a body pseudo-element, because an always-on full-viewport fixed overlay is
   the proven root cause of the iOS 26 chrome-strip bug. */
.paper {
  background-color: var(--paper);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='72' viewBox='0 0 72 72'%3E%3Cg fill='%23231a12' fill-opacity='.05'%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(45 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(90 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(135 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(180 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(225 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(270 36 36)'/%3E%3Cellipse cx='36' cy='21' rx='4.2' ry='10.5' transform='rotate(315 36 36)'/%3E%3Ccircle cx='36' cy='36' r='5.2'/%3E%3C/g%3E%3Ccircle cx='36' cy='36' r='27' fill='none' stroke='%23231a12' stroke-opacity='.045' stroke-width='1.3'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 72px 72px;
}

/* Scalloped deckled top edge, so the sheet reads as a torn sheet of wrap. */
.paper--deckle::before {
  content: '';
  position: absolute;
  inset-inline: 0;
  inset-block-start: -9px;
  height: 10px;
  pointer-events: none;
  background-image: radial-gradient(circle at 8px 10px, var(--paper) 7.6px, transparent 8px);
  background-size: 16px 10px;
  background-repeat: repeat-x;
}

/* --- cart contents ------------------------------------------------------ */
.cart__lines {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: var(--hair) solid var(--rule);
}

.cart__section {
  display: grid;
  gap: var(--s-3);
}

.cart__section-title {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
}

.cart__note {
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--ink-78);
}

.cart__note--allergy {
  padding: var(--s-3) var(--s-4);
  border-inline-start: 3px solid var(--mustard);
  background-color: rgba(244, 174, 43, 0.12);
  color: var(--ink);
  font-weight: 500;
}

.cart__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}

.cart__total-label {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
}

.cart__total-value {
  font-family: var(--f-sans);
  font-size: 1.375rem;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* =============================================================================
   27  CART LINE AND STEPPER
   Every numeral in the ordering machine is DM Sans 500 tabular-nums, so columns
   never jitter when the total changes.
   ========================================================================== */

.cart-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: var(--s-4);
  row-gap: var(--s-2);
  padding-block: var(--s-4);
  border-bottom: var(--hair) solid var(--rule);
}

.cart-line__body {
  min-width: 0;
}

.cart-line__name {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1.2;
  color: var(--navy);
}

.cart-line__opts {
  margin-block-start: var(--s-1);
  font-size: var(--t-meta);
  line-height: 1.45;
  color: var(--ink-70);
}

.cart-line__controls {
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.cart-line__price {
  min-width: 5.5ch;
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 500;
  text-align: end;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.cart-line__remove {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--terracotta-text);
  text-decoration: underline;
  text-underline-offset: 0.24em;
}

.stepper {
  display: flex;
  align-items: center;
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
}

.stepper__btn {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-pill);
  font-family: var(--f-sans);
  font-size: 1.125rem;
  font-weight: 500;
  line-height: 1;
  color: var(--navy);
  transition: background-color var(--d-fast) var(--e-out);
}

.stepper__btn:hover {
  background-color: var(--cream-2);
}

.stepper__qty {
  min-width: 2.5ch;
  text-align: center;
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* =============================================================================
   28  FULFILMENT TOGGLE
   While ordering.delivery.enabled is false there is NO toggle at all, just the
   honest line. A disabled Delivery tab is a dead target mid-checkout that
   advertises a service which does not exist. The control below is pre-built and
   appears the moment the flag flips.
   ========================================================================== */

.fulfil {
  display: grid;
  gap: var(--s-3);
}

.fulfil__note {
  font-size: var(--t-body);
  line-height: 1.5;
  color: var(--ink);
}

.fulfil__toggle {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 0;
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
  overflow: hidden;
}

.fulfil__option {
  position: relative;
  display: flex;
}

.fulfil__input {
  position: absolute;
  opacity: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  cursor: pointer;
}

.fulfil__label {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 48px;
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--navy);
  cursor: pointer;
  transition:
    background-color var(--d-fast) var(--e-out),
    color var(--d-fast) var(--e-out);
}

.fulfil__input:checked + .fulfil__label {
  background-color: var(--mustard);
  color: var(--ink); /* 7.35:1 */
}

.fulfil__input:focus-visible + .fulfil__label {
  outline: 2px solid var(--focus);
  outline-offset: -3px;
}

/* =============================================================================
   29  SLOT PICKER
   Never a 40-option select and never a calendar. A day rail plus a slot grid,
   with ASAP pre-selected because at 11.50 the most common intent should take
   zero taps.
   ========================================================================== */

.slots {
  display: grid;
  gap: var(--s-4);
}

.slots__title {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
}

.slots__day-rail {
  display: flex;
  gap: var(--s-2);
  overflow-x: auto;
  overscroll-behavior-inline: contain;
  scrollbar-width: none;
  scroll-snap-type: x proximity;
  padding-block-end: var(--s-1);
}

.slots__day-rail::-webkit-scrollbar {
  display: none;
}

.day-chip {
  flex: none;
  scroll-snap-align: start;
  display: grid;
  align-content: center;
  gap: 2px;
  min-width: 84px;
  min-height: 52px;
  padding-inline: var(--s-3);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-pill);
  background-color: transparent;
  text-align: center;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out),
    color var(--d-fast) var(--e-out);
}

.day-chip__label {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  line-height: 1.1;
}

.day-chip__date {
  font-family: var(--f-sans);
  font-size: 0.6875rem;
  font-weight: 500;
  line-height: 1.1;
  color: var(--ink-70);
}

.day-chip:hover {
  border-color: var(--navy);
}

.day-chip--selected {
  background-color: var(--navy);
  border-color: var(--navy);
  color: var(--cream);
}

.day-chip--selected .day-chip__date {
  color: rgba(251, 247, 239, 0.78);
}

/* Sundays render as a VISIBLE disabled chip, never silently omitted: the
   closure is information, not an absence. */
.day-chip--closed {
  background-color: transparent;
  border-style: dashed;
  border-color: var(--rule);
  color: var(--ink-70);
  cursor: not-allowed;
}

.day-chip--closed .day-chip__date {
  color: var(--terracotta-text);
  font-weight: 700;
}

.day-chip--closed:hover {
  border-color: var(--rule);
}

.slots__body {
  display: grid;
  gap: var(--s-2);
}

.slot {
  display: grid;
  place-items: center;
  min-height: 44px;
  padding-inline: var(--s-2);
  border: var(--hair) solid var(--edge);
  border-radius: var(--r-chip);
  background-color: transparent;
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  line-height: 1.2;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
  transition:
    background-color var(--d-fast) var(--e-out),
    border-color var(--d-fast) var(--e-out),
    color var(--d-fast) var(--e-out);
}

.slot:hover {
  border-color: var(--navy);
}

.slot--asap {
  min-height: 52px;
  font-weight: 700;
  letter-spacing: 0.04em;
}

.slot--selected {
  background-color: var(--navy);
  border-color: var(--navy);
  color: var(--cream);
}

.slots__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--s-2);
}

/* =============================================================================
   30  ORDER SUMMARY AND ORDER PANEL
   Payment copy is non-negotiable: mode is "demo", so nothing is charged and the
   confirmation says so in plain words. No card field is ever rendered.
   ========================================================================== */

.order-summary {
  padding: var(--s-5);
  border: var(--hair) solid var(--rule);
  background-color: var(--paper);
}

.order-summary__title {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--navy);
}

.order-summary__list {
  margin: 0;
  margin-block-start: var(--s-4);
}

.order-summary__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  padding-block: var(--s-3);
  border-bottom: var(--hair) solid var(--rule);
  font-size: var(--t-body);
}

.order-summary__label {
  color: var(--ink);
}

.order-summary__value {
  flex: none;
  font-family: var(--f-sans);
  font-weight: 500;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.order-summary__total {
  border-bottom: 0;
  border-top: 2px solid var(--navy);
  margin-block-start: var(--s-2);
  padding-block-start: var(--s-4);
}

.order-summary__total .order-summary__label {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--navy);
}

.order-summary__total .order-summary__value {
  font-size: 1.375rem;
  font-weight: 700;
}

.order-summary__meta {
  display: grid;
  gap: var(--s-3);
  margin-block-start: var(--s-5);
  padding-block-start: var(--s-5);
  border-top: var(--hair) solid var(--rule);
}

.order-summary__meta-row {
  display: grid;
  gap: 2px;
}

.order-summary__meta-row dt {
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.order-summary__meta-row dd {
  margin: 0;
  font-size: var(--t-body);
  line-height: 1.45;
  color: var(--ink);
}

.order-panel {
  display: grid;
  gap: var(--s-6);
}

@media (min-width: 1040px) {
  .order-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
    align-items: start;
    gap: var(--s-8);
  }

  .order-panel {
    position: sticky;
    inset-block-start: calc(var(--header-h-min) + var(--safe-t) + var(--s-5));
    padding: var(--s-6);
    border: var(--hair) solid var(--rule);
    background-color: var(--paper);
  }
}

/* =============================================================================
   31  ADMIN ORDER BOARD
   ========================================================================== */

.admin {
  padding-block: var(--s-7) var(--s-9);
}

.admin__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
}

.admin__filters {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-block-start: var(--s-5);
}

.orders {
  display: grid;
  margin: 0;
  margin-block-start: var(--s-6);
  border-top: 2px solid var(--navy);
}

.order-row {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: baseline;
  column-gap: var(--s-4);
  row-gap: var(--s-2);
  padding: var(--s-4) var(--s-4) var(--s-4) var(--s-4);
  border-bottom: var(--hair) solid var(--rule);
  border-inline-start: 3px solid transparent;
  background-color: var(--paper);
}

.order-row--new {
  border-inline-start-color: var(--mustard);
}

/* The "open now" chip on the trust bar. js/main.js toggles --open / --closed;
   before this the open state had no declaration at all. */
.trust-chip--open {
  border-color: var(--navy);
  font-weight: 600;
}

.trust-chip--closed {
  color: var(--ink-78);
}

/* The Preparing lane's dot, so the three lanes are distinguishable at a glance
   on a busy counter. Matches .order-row--preparing. */
.status-dot--preparing {
  background-color: var(--terracotta);
}

.order-row--preparing {
  border-inline-start-color: var(--terracotta);
}

.order-row--ready {
  border-inline-start-color: var(--navy);
}

.order-row--collected {
  color: var(--ink-70);
  background-color: transparent;
}

.order-row__time {
  font-family: var(--f-sans);
  font-size: 1.125rem;
  font-weight: 700;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}

.order-row__ref {
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--ink-70);
}

.order-row__name {
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 700;
  color: var(--ink);
}

.order-row__items {
  grid-column: 1 / -1;
  font-size: var(--t-small);
  line-height: 1.5;
  color: var(--ink-78);
}

.order-row__total {
  font-family: var(--f-sans);
  font-size: var(--t-body);
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.order-row__status {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--navy);
}

.order-row__actions {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin-block-start: var(--s-2);
}

.status-dot {
  width: 10px;
  height: 10px;
  border-radius: var(--r-pill);
  background-color: var(--rule-strong);
  flex: none;
}

.status-dot--new {
  background-color: var(--mustard);
}

.status-dot--ready {
  background-color: var(--navy);
}

.status-dot--collected {
  background-color: var(--edge);
}

@media (min-width: 900px) {
  .order-row {
    grid-template-columns: 72px 96px 1fr auto 130px auto;
    align-items: center;
    column-gap: var(--s-5);
  }

  .order-row__items {
    grid-column: 3;
    grid-row: 1;
  }

  .order-row__actions {
    grid-column: 6;
    grid-row: 1;
    margin-block-start: 0;
  }
}

/* =============================================================================
   32  EMPTY STATE, TOAST, ALERT
   ========================================================================== */

.empty {
  display: grid;
  justify-items: start;
  gap: var(--s-3);
  padding-block: var(--s-7);
}

.empty__mark {
  width: 32px;
  height: 32px;
  color: var(--navy);
  opacity: 0.3;
}

.empty__title {
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--navy);
}

.empty__text {
  max-width: 36ch;
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--ink-78);
}

.empty__action {
  margin-block-start: var(--s-3);
}

.toast-region {
  position: fixed;
  inset-block-end: calc(var(--order-bar-h) + var(--safe-b) + var(--s-4));
  inset-inline: max(var(--page-x), var(--safe-l)) max(var(--page-x), var(--safe-r));
  z-index: var(--z-toast);
  display: grid;
  gap: var(--s-2);
  justify-items: center;
  pointer-events: none;
}

.toast {
  max-width: 460px;
  padding: var(--s-3) var(--s-5);
  border-radius: var(--r-pill);
  background-color: var(--ink);
  color: var(--cream);
  font-family: var(--f-sans);
  font-size: var(--t-meta);
  font-weight: 500;
  line-height: 1.4;
  text-align: center;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity var(--d-base) var(--e-out),
    transform var(--d-base) var(--e-out);
}

.toast--in {
  opacity: 1;
  transform: none;
}

.toast--error {
  background-color: var(--terracotta-deep);
  color: var(--cream);
}

.alert {
  padding: var(--s-3) var(--s-4);
  border-inline-start: 3px solid var(--rule-strong);
  background-color: var(--cream-2);
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--ink);
}

.alert + .alert {
  margin-block-start: var(--s-2);
}

.alert--info {
  border-inline-start-color: var(--navy);
}

.alert--warn {
  border-inline-start-color: var(--mustard);
  background-color: rgba(244, 174, 43, 0.14);
}

/* The only place terracotta carries small text: a fill with cream on top. */
.alert--closed {
  border-inline-start-color: var(--terracotta-deep);
  background-color: var(--terracotta-deep);
  color: var(--cream); /* 6.33:1 */
  font-weight: 500;
}

/* =============================================================================
   33  404 AND PROSE
   ========================================================================== */

.notfound {
  padding-block: clamp(64px, 14vw, 160px);
}

.notfound__code {
  font-family: var(--f-sans);
  font-size: var(--t-eyebrow);
  font-weight: 700;
  letter-spacing: 0.24em;
  color: var(--ink-70);
  font-variant-numeric: tabular-nums;
}

.notfound__title {
  margin-block-start: var(--s-4);
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: var(--t-h2);
  font-weight: 700;
  line-height: 1.02;
  letter-spacing: -0.02em;
  color: var(--navy);
}

.notfound__text {
  max-width: 46ch;
  margin-block-start: var(--s-4);
  font-size: var(--t-body-lg);
  line-height: 1.6;
  color: var(--ink-78);
}

.notfound__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  margin-block-start: var(--s-6);
}

.prose {
  padding-block: var(--s-7) var(--s-9);
}

.prose > * + * {
  margin-block-start: var(--s-4);
}

.prose h2 {
  margin-block-start: var(--s-8);
  font-family: var(--f-display);
  font-optical-sizing: auto;
  font-size: 1.75rem;
  font-weight: 600;
  line-height: 1.15;
  color: var(--navy);
}

.prose h3 {
  margin-block-start: var(--s-6);
  font-family: var(--f-sans);
  font-size: var(--t-body-lg);
  font-weight: 700;
  color: var(--navy);
}

.prose p,
.prose li {
  max-width: var(--measure);
  font-size: var(--t-body);
  line-height: 1.7;
  color: var(--ink);
}

.prose ul,
.prose ol {
  padding-inline-start: 1.25em;
}

.prose li + li {
  margin-block-start: var(--s-2);
}

.prose a {
  color: var(--navy);
  text-decoration: underline;
  text-underline-offset: 0.24em;
}

/* =============================================================================
   34  MOTION
   All transform and opacity, except two deliberate paint-only exceptions (the
   menu row background and the desktop nav condense padding). Hand-written
   vanilla: build rule 10 forbids CDN script tags, so the motion budget is met
   here rather than skipped.

   js/main.js sets `class="js"` on <html>, so a visitor with no JS at all sees
   every element in its final state rather than a blank page.
   ========================================================================== */

html.js [data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity var(--d-reveal) var(--e-out),
    transform var(--d-reveal) var(--e-out);
  transition-delay: var(--reveal-delay, 0ms);
}

html.js [data-reveal].in {
  opacity: 1;
  transform: none;
}

/* The rules draw themselves in from the left. This is the signature of the
   whole direction: the page appears to be ruled up like a menu card as you
   scroll. */
html.js .rule {
  transform: scaleX(0);
  transition: transform 600ms var(--e-out);
  transition-delay: var(--reveal-delay, 120ms);
}

html.js .rule.in,
html.js [data-reveal].in .rule {
  transform: scaleX(1);
}

/* 1. Hero print-on */
html.js .hero__line {
  opacity: 0;
  transform: translateY(24px);
  animation: lb-line-in 800ms var(--e-out) forwards;
}

html.js .hero__line:nth-child(2) {
  animation-delay: 70ms;
}

html.js .hero__line:nth-child(3) {
  animation-delay: 140ms;
}

html.js .hero__img {
  animation: lb-press-on 1200ms var(--e-out) both;
}

@keyframes lb-line-in {
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes lb-press-on {
  from {
    transform: scale(1.06);
  }
  to {
    transform: scale(1);
  }
}

/* 2. Ken-burns, gated to no-preference AND min-width 700px: skipped on phones
   for battery and for the iOS compositing reason. */
@media (prefers-reduced-motion: no-preference) and (min-width: 700px) {
  html.js .hero__img {
    animation:
      lb-press-on 1200ms var(--e-out) both,
      lb-ken 12s var(--e-inout) 1400ms infinite alternate;
  }
}

@keyframes lb-ken {
  from {
    transform: scale(1);
  }
  to {
    transform: scale(1.04);
  }
}

/* 7. Add to order stamp. No item-flies-to-cart animation: it janks on
   mid-range Androids and adds nothing. */
.add-btn--stamp {
  animation: lb-stamp 260ms var(--e-out);
}

@keyframes lb-stamp {
  0% {
    transform: scale(0.9);
  }
  55% {
    transform: scale(1.06);
  }
  100% {
    transform: scale(1);
  }
}

.order-bar--flash {
  border-top-color: var(--mustard);
}

.order-bar__count--pop {
  animation: lb-pop 260ms var(--e-out);
}

@keyframes lb-pop {
  0% {
    transform: scale(1);
  }
  45% {
    transform: scale(1.25);
  }
  100% {
    transform: scale(1);
  }
}

/* 10. The live open-state dot pulses. */
@media (prefers-reduced-motion: no-preference) {
  .status-chip--open .status-chip__dot,
  .trust-chip--open .status-chip__dot {
    animation: lb-pulse 2.4s ease-in-out infinite;
  }
}

@keyframes lb-pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: 0.35;
  }
}

/* =============================================================================
   35  REDUCED MOTION
   One blanket block neutralises every transition and animation. .01ms rather
   than 0 so `transitionend` still fires and the sheets still set [hidden] on
   close.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  html {
    scroll-behavior: auto;
  }

  html.js [data-reveal],
  html.js [data-reveal].in {
    opacity: 1 !important;
    transform: none !important;
  }

  html.js .rule,
  html.js .rule.in {
    transform: none !important;
  }

  html.js .hero__line {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }

  html.js .hero__img {
    animation: none !important;
    transform: none !important;
  }

  .btn:hover,
  .socialbar a:hover,
  .board-row__link:hover .board-row__index {
    transform: none !important;
  }

  .status-chip--open .status-chip__dot,
  .trust-chip--open .status-chip__dot {
    animation: none !important;
  }
}

/* =============================================================================
   36  PRINT
   People print lunch menus. The dot leaders are the whole point, so they stay.
   ========================================================================== */

@media print {
  html,
  body {
    background: #fff !important;
    color: #000 !important;
    padding: 0 !important;
    font-size: 11pt;
  }

  .print-only {
    display: block !important;
  }

  .no-print,
  .site-header,
  .mobile-menu,
  .order-bar,
  .sheet,
  .toast-region,
  .preview-notice,
  .cat-rail,
  .nav-toggle,
  .cta-band,
  .add-btn,
  .gallery,
  .board__panel,
  .socialbar,
  .skip-link,
  .menu-cat__spread,
  .hero__figure,
  .find-us__media,
  .photo-run__two,
  .photo-run__full,
  .footer-nav,
  .btn {
    display: none !important;
  }

  .main,
  .section,
  .menu-cat,
  .prose,
  .page-head {
    padding-block: 8pt !important;
  }

  .wrap {
    max-width: none;
    padding-inline: 0;
  }

  .item-row {
    grid-template-columns: 1fr;
    break-inside: avoid;
    page-break-inside: avoid;
    padding-block: 5pt;
    border-bottom: 0.5pt solid #999;
  }

  .item-row__name,
  .item-row__price,
  .section-head__en,
  .page-head__title,
  .cart-line__name {
    color: #000 !important;
  }

  .item-row__desc {
    color: #333 !important;
  }

  .item-row__leader {
    background-image: radial-gradient(
      circle at 3.5px 3px,
      #888 1.2px,
      transparent 1.3px
    ) !important;
  }

  .menu-cat {
    background: #fff !important;
    break-before: auto;
  }

  .section-head,
  .menu-cat__head {
    break-after: avoid;
    page-break-after: avoid;
  }

  .rule,
  .trim {
    display: none !important;
  }

  .site-footer {
    background: #fff !important;
    color: #000 !important;
    border-top: 0.5pt solid #999;
    padding-block: 10pt !important;
  }

  .site-footer__title,
  .site-footer__note,
  .credit,
  .site-footer .hours__day,
  .site-footer .hours__time,
  .site-footer .address,
  .site-footer .contact-link {
    color: #000 !important;
  }

  a[href^='http']::after {
    content: ' (' attr(href) ')';
    font-size: 8pt;
    color: #555;
  }

  .contact-link[href^='tel']::after,
  .credit a::after {
    content: '';
  }
}
