/* Beachside Gyros · CERAMIC / CYCLADIC
 * ═════════════════════════════════════════════════════════════════════════
 * display: Gorditas Bold, title case · body: Work Sans · tokens: tokens.css
 *
 * THE ONE RULE THAT DEFINES THIS BUILD:
 *   Separation comes from flat blocks of colour and space. Nothing else.
 *   A tiled wall has no borders — the tiles simply meet.
 *
 * Therefore, permanently banned. Every one of these was in a previous version
 * of this site and each is why it read either generic or childish:
 *   ✗ borders / outlines on cards, tags, buttons        (read neo-brutalist)
 *   ✗ box-shadow of any kind, hard OR soft              (nothing floats here)
 *   ✗ border-radius                                     (tiles are square)
 *   ✗ ALL-CAPS display headings                         (shouting)
 *   ✗ solid + ghost button PAIRS                        (AI-page fingerprint)
 *     (one outlined button alone on a photograph is fine — it is the pair,
 *      shown side by side, that is the tell)
 *   ✗ pill badges above an h1                           (AI-page fingerprint)
 *   ✗ hover lifts — translateY(-Npx)                    (AI-page fingerprint)
 *   ✗ "→" appended to link text                         (AI-page fingerprint)
 *   ✗ frosted-glass backdrop-filter                     (phone-OS idiom)
 *   ✗ the tile pattern used as a repeating border       (souvenir shop)
 *   ✗ the diagonal "glaze lattice" on the dark bands — REMOVED 2026-08-08.
 *     Justified to myself as glazed tile catching light; at full width on a
 *     navy field it read as cheap woven fabric. Dark bands are FLAT COLOUR.
 *   ✗ the dashed/lozenge band — removed 2026-08-08. At full width it read as
 *     a perforated tear-off strip. It was replaced by a real drawn Greek key
 *     (meander), which is the site's ONLY ornament and runs in exactly ONE
 *     place: leading the masthead. The footer needs nothing — deep navy
 *     meeting plaster is already maximum contrast. Do not add a second one.
 *
 * That last line has now been tested twice and held twice. On 2026-08-09 a
 * second run was added under the masthead bar to frame it, and a third had
 * been sitting above the footer since the rebuild; Marcus cut both the same
 * day — "it's too much". ONE full-width band per page. That restraint is the
 * whole difference between "Cycladic" and "taverna placemat".
 * ═════════════════════════════════════════════════════════════════════════ */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;   /* clears the condensed sticky masthead */
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--color-paper);
  color: var(--color-ink);
  font: 400 var(--text-base)/1.65 var(--font-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* height:auto is load-bearing: the width/height attributes on every <img> are
   presentational hints, and an explicit height silently defeats aspect-ratio. */
img { max-width: 100%; display: block; height: auto; }

/* Title case, never caps — setting a display face in caps as well is how this
   build shouted the first time. Size and colour carry hierarchy, since Fugaz
   One ships a single weight. */
h1, h2 {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-style: normal;
  /* Gorditas has long ascenders and real descenders, so it needs more leading
     than the condensed faces that preceded it — but nowhere near the 1.34 the
     old brush script wanted for its tails. */
  line-height: 1.22;
  letter-spacing: var(--track-display);
  margin: 0;
  text-wrap: balance;
  overflow-wrap: anywhere;
  min-width: 0;
}
/* h3 is a subhead, not a headline. It stays in the body face at 700 so the
   display voice means something when it does appear. */
h3 {
  font-family: var(--font-body);
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: 0;
  margin: 0;
  text-wrap: balance;
  overflow-wrap: anywhere;
  min-width: 0;
}
p { margin: 0 0 1.15em; }
a { color: inherit; }

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

:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 3px; }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: var(--z-skip);
  background: var(--color-ink); color: var(--color-paper);
  padding: var(--space-xs) var(--space-md); font-weight: 700;
}
.skip:focus { left: var(--space-sm); top: var(--space-sm); }

.h-display { font-size: var(--text-display-s); max-width: 22ch; }
/* Section level: three units of the same key, left-aligned under the heading.
   Short, so it reads as a mark rather than another band. */
.h-display::after,
.phead__title::after,
.slate__inner > h2::after,
.praise__say > h2::after {
  content: "";
  display: block;
  width: 75px; height: 20px;
  margin-top: var(--space-md);
  background-color: var(--color-accent);
  -webkit-mask: var(--meander) repeat-x left / var(--meander-size);
          mask: var(--meander) repeat-x left / var(--meander-size);
}
/* On the deep bands it steps to the pale tone. */
.kitchen .h-display::after,
.slate .h-display::after,
.slate__inner > h2::after,
.praise__say > h2::after { background-color: var(--color-accent-pale); }


/* ── Links ────────────────────────────────────────────────
   No arrow glyph, no sliding. A rule that thickens under the word. */
.tlink {
  display: inline-block;
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-accent);
  padding-bottom: 4px;
  box-shadow: inset 0 -1px 0 var(--color-accent-pale);
  transition: box-shadow var(--dur-short) var(--ease-out),
              color var(--dur-short) var(--ease-out);
}
.tlink:hover { color: var(--color-accent-2); box-shadow: inset 0 -2px 0 var(--color-accent); }
.tlink--strong {
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 700;
  text-transform: none;
}
/* Arrows are gone from the markup; neutralise any that survive an edit. */
.tlink span[aria-hidden], .btn span[aria-hidden] { display: none; }

/* ── Button ───────────────────────────────────────────────
   A solid glazed tile. No border, no shadow, no lift — it deepens on hover.
   There is one button style. A solid/outline pair is an AI-page fingerprint. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 52px;
  padding: 0 var(--space-xl);
  border: 0;
  background: var(--color-accent);
  color: var(--color-accent-ink);
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  transition: background var(--dur-short) var(--ease-out);
}
.btn:hover { background: var(--color-accent-2); }
/* `.btn--outline` was DELETED on 2026-08-09. It was a transparent tile with a
   1px inset ring for use on photographs, it was the only outlined object on a
   site whose tokens ban outlines, and Marcus called it out on sight as reading
   like generic AI. The hero's `.callboard` replaced its one use. The rule is
   gone rather than left unreferenced so it cannot quietly come back. */
.btn--onphoto { background: var(--color-paper); color: var(--color-ink); }
.btn--onphoto:hover { background: #fff; }

/* ── Masthead ─────────────────────────────────────────────
   ONE horizontal row: nav left, wordmark centre, contact right, with the Greek
   key band pinned above it. It was a four-row stack (standfirst / wordmark /
   nav / band) which ran 206px on a laptop and 260px on a phone — a quarter of
   the screen spent before any content, and the reason the full-screen hero
   still opened on a slab of empty paper. Set to Marcus's catering mockup,
   2026-08-09.

   The standfirst line came out with the stack. "Home of Maria's famous
   tzatziki" still opens the tzatziki band on the home page, so the phrase is
   not lost — only its second, chrome-level printing.

   Sticky and condensing: the nav and the phone number are what a hungry
   visitor wants at any moment, and letting them scroll away costs the page
   its usefulness. Opaque — frosted glass is a phone-OS idiom, not a tiled one. */
.mast {
  position: sticky; top: 0; z-index: var(--z-sticky);
  /* The glazed-tile field, same token as the catering strip and the menu
     board — NOT the warm plaster the rest of the page sits on. Set on
     Marcus's call, 2026-08-09, pointing at the "Feeding a crowd?" strip. It
     also does the job the removed second meander band was reaching for: the
     bar now separates from the page by ground colour, which is the direction's
     own rule, instead of by a second run of ornament. */
  background: var(--color-paper-2);
}
/* ONE band, leading. As the first thing on the page it reads as a printed
   border rather than as a divider under a block of chrome, and it is what
   stays pinned to the top edge once the page scrolls.

   A matching band was added under the bar on 2026-08-09 to frame it and
   Marcus cut it the same day — "it's too much". Do not re-add it: two runs of
   meander around a bar this short is more ornament than masthead.

   It runs at 18px where the rest of the site's keys run at 20px, which is the
   part of that change worth keeping — Marcus asked for the pattern itself to
   be shorter. 18px is the FLOOR, not a preference: `tokens.css` records that
   below ~18px a single meander stops reading as a key and turns to texture.
   The source is 25×20, so the width steps to 22px with it and the key keeps
   its proportion rather than stretching. The footer band stays at 20px. */
.mast {
  --mast-key-h: 18px;
  --mast-key-size: 22px 18px;
}
.mast::before {
  content: ""; display: block;
  height: var(--mast-key-h);
  background-color: var(--color-accent);
  -webkit-mask: var(--meander) repeat-x center / var(--mast-key-size);
          mask: var(--meander) repeat-x center / var(--mast-key-size);
}
.mast__bar {
  max-width: var(--shell); margin: 0 auto;
  /* Bottom-heavy on purpose: there is a band above the bar and nothing below,
     so even padding would sit the wordmark high against the ornament. */
  padding: var(--space-2xs) var(--page-gutter) var(--space-xs);
  display: grid;
  /* Equal side tracks, so the wordmark is centred on the PAGE and not merely
     placed between two unequal runs of links. */
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
  transition: padding var(--dur-medium) var(--ease-out);
}
/* Without this the nav and the wordmark size to max-content and overflow the
   bar, which overflow-x:clip then hides rather than wraps. Cost one mobile bug
   a scrollWidth check could not see. */
.mast__name, .mast__nav { min-width: 0; max-width: 100%; }

.mast.is-stuck .mast__bar { padding-block: var(--space-3xs); }
/* font-size did nothing once the wordmark became an image — this has to be
   height or the bar stops condensing on scroll. */
.mast.is-stuck .mast__logo { height: clamp(1.25rem, 2vw, 1.75rem); }

/* Without mask support the band would render as a solid blue bar — fall back
   to the hairline instead. */
@supports not ((mask-image: url("#x")) or (-webkit-mask-image: url("#x"))) {
  .mast::before { height: 1px; background-color: var(--color-rule); }
  .h-display::after, .phead__title::after,
  .slate__inner > h2::after, .praise__say > h2::after { display: none; }
}

/* The wordmark is now the truck's OWN painted lettering, not type. Marcus
   supplied it on 2026-08-09 and it replaced a type-set rendering of the
   name — which was a good stand-in, but this is the real thing: the same
   hand-painted mark that hangs over the service window in the hero
   photograph, cream offset shadow and all. The site now carries one logo
   instead of an impression of one.

   It stays an <a> wrapping an <img alt="Beachside Gyros">, so the link still
   has a text accessible name and the masthead still announces correctly. */
.mast__name {
  display: block;
  text-decoration: none;
  text-align: center;
  justify-self: center;
}
/* Height-driven, because the condense-on-scroll below animates height and an
   image has no font-size to shrink.

   ⚠️ THIS IS A ~7:1 SINGLE-LINE MARK. It replaced a two-line stacked version
   on 2026-08-09, and the height had to come down hard with it: at the 2.9rem
   the stacked one used, one line of lettering is over 320px wide and shoves
   the nav on either side. Sized off height so it stays optically level with
   the nav type, with a width cap for the narrow middle track. If the artwork
   is ever swapped back to a stacked lockup, this clamp is wrong. */
.mast__logo {
  display: block; margin-inline: auto;
  height: clamp(1.6rem, 2.5vw, 2.2rem); width: auto;
  max-width: min(100%, 24rem);
  transition: height var(--dur-medium) var(--ease-out);
}
.mast__nav ul {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-2xs) var(--space-sm);
  list-style: none; padding: 0; margin: 0;
}
.mast__nav--start ul { justify-content: flex-start; }
.mast__nav--end ul { justify-content: flex-end; }
.mast__nav a {
  display: inline-block;
  white-space: nowrap;                 /* clickable text never wraps */
  padding: var(--space-2xs);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: var(--track-caps);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--color-ink-2);
  transition: color var(--dur-short) var(--ease-out),
              background var(--dur-short) var(--ease-out);
}
/* The nav item becomes a glazed tile. No underline sweep.
   It steps to paper-3 rather than paper-2 because the BAR is paper-2 now — a
   paper-2 hover on a paper-2 bar is an invisible hover. */
.mast__nav a:hover { background: var(--color-paper-3); color: var(--color-accent); }
.mast__nav a.is-here { background: var(--color-accent); color: var(--color-accent-ink); }
.mast__nav .mast__tel { color: var(--color-accent); font-variant-numeric: tabular-nums; }
.mast__nav .mast__tel:hover { background: var(--color-paper-3); }
.mast__rule { display: none; }       /* the ::before band is the border */

/* ── Hero ─────────────────────────────────────────────────
   One screen. Centred, one line of brush script, one action, and the four
   facts along the floor. Full-bleed photograph under a deep Aegean scrim —
   the scrim pulls the photo into the palette AND masks the softness in the
   supplied images that a bright contained crop exposed.

   Sized to the rest of the viewport rather than to a clamp, so the facts land
   ON the fold instead of just under it. svh, not vh or dvh: the small viewport
   is the one a phone shows before the URL bar collapses, so the band is
   visible on arrival rather than after the first scroll. --mast-h is measured
   in script.js — the fallback is deliberately generous, because guessing high
   only shortens the hero while guessing low pushes the band off-screen, which
   is the exact bug this layout exists to fix. */
.hero {
  position: relative; background: var(--color-deep);
  min-height: calc(100svh - var(--mast-h, 14rem));
  display: grid; grid-template-rows: 1fr auto;
}
.hero__inner {
  position: relative; z-index: var(--z-raised);
  width: 100%; max-width: var(--shell); margin: 0 auto;
  /* The top figure is a floor, not a spacer. Content is bottom-aligned inside a
     1fr row, so on a tall screen the air above is free — but the padding still
     counts toward the box's intrinsic height, and at 7rem it was pushing the
     proof band off a 720-tall laptop on its own. */
  padding: var(--space-xl) var(--page-gutter) var(--space-xl);
  /* Bottom-aligned, not centred. The photograph has its own giant lettering —
     the hand-painted sign — and centred copy landed straight on top of it.
     Dropping to the lower third lets the sign read AND the headline read. */
  display: grid; align-content: end; justify-items: center;
  text-align: center;
}
.hero__shot { position: absolute; inset: 0; margin: 0; overflow: hidden; }
/* The landscape exterior landed 2026-08-09 and this is now a composition
   choice rather than the rescue value it used to be. History, because the
   numbers are the reason the photograph was worth chasing: the old 1200×1600
   portrait had to be enlarged 1.2× at 1440 and 1.6× at 1920 to fill this band
   and still showed only ~40% of its height, which is why "zoom the background
   out" had no answer in CSS. The 1360×1020 landscape is enlarged 1.06× at
   1440 and shows ~76% — the truck, the sign and the tables all fit now.

   TOP-ALIGNED, and it has to be. The file is already cropped to 1.73 — close
   enough to the band that only a few percent of height is ever cut — but at
   1920 the cut grows to ~9%, and centred that would slice the top off the
   hand-painted sign, which is the only real brand mark this business owns.
   Pinned to the top, every viewport spends its whole crop budget on the empty
   asphalt along the bottom instead. Do not "balance" this to 50%. */
.hero__shot img { width: 100%; height: 100%; object-fit: cover; object-position: center top; }
.hero__shot figcaption {
  position: absolute; z-index: 2;
  left: var(--page-gutter); bottom: var(--space-sm);
  font-size: var(--text-xs); letter-spacing: 0.04em;
  color: oklch(100% 0 0 / 0.55);
}
/* Even hold across the whole frame — the copy is centred now, so a
   left-weighted gradient would leave the headline half-lit. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  /* Bottom-weighted, but LIGHTLY. It ran 0.94 at the floor and 0.88 a third of
     the way up, which is very nearly opaque — the bottom of the photograph,
     where the picnic tables and the whole forecourt are, went dead black and
     the proof strip sat on a slab rather than on a picture. Marcus called it
     on 2026-08-09.

     These numbers are not eyeballed: they are the lowest the ramp goes while
     every piece of type over it still clears 4.5:1 against the actual
     composited pixels behind it, sampled at 1440 and 390. If the photograph is
     ever swapped, re-run that check before trusting them. */
  background: linear-gradient(to top,
    oklch(16% 0.052 248 / 0.74) 0%,
    oklch(16% 0.052 248 / 0.70) 26%,
    oklch(16% 0.052 248 / 0.62) 46%,
    oklch(16% 0.052 248 / 0.40) 64%,
    oklch(16% 0.052 248 / 0.13) 82%,
    oklch(16% 0.052 248 / 0.00) 100%);
}
.hero__say { max-width: 40rem; color: var(--color-onphoto); }

/* ⚠️ DO NOT PUT A SCRIM BEHIND THE COPY. A soft radial ellipse was tried here
   on 2026-08-09 to hold the headline over the bright canopy, and it read as
   exactly what it was — a grey smudge floating in the middle of a sunny
   photograph. Marcus killed it on sight.

   Legibility is carried by the type instead. A tight text-shadow does the same
   work and is invisible as an effect: it darkens only the pixels immediately
   under each glyph, so nothing reads as a shape. This is the one shadow on the
   site and it is not a depth cue — tokens.css bans shadows as a way of lifting
   surfaces off a page, which this is not doing. */
.hero__say :is(h1, p) {
  text-shadow: 0 1px 2px oklch(12% 0.03 248 / 0.55),
               0 2px 14px oklch(12% 0.03 248 / 0.40);
}
/* The board carries its own ground, so type on it needs no help and picks up
   a muddy edge if it gets any. */
.hero__act .callboard :is(span) { text-shadow: none; }

/* The one line of script on the whole site. */
.hero__title {
  font-size: clamp(1.9rem, 3.6vw, 3.2rem);
  line-height: 1.25;
  max-width: none;                  /* one line — it stops fighting the sign */
  white-space: nowrap;
  color: var(--color-onphoto);
  margin: 0 0 var(--space-lg);
  /* Pacifico sits high on the baseline; this re-centres the optical block. */
  padding-top: 0.08em;
  text-shadow: 0 2px 18px oklch(16% 0.05 248 / 0.5);
}
.hero__sub {
  font-size: var(--text-md); line-height: 1.6;
  font-weight: 500;                 /* 400 disintegrates over a photograph */
  color: var(--color-onphoto-2);
  max-width: 34ch; margin: 0 auto var(--space-xl);
}
/* ── The call board ───────────────────────────────────────
   The hero's one action, built to Marcus's pick from concepts-hero-cta.html
   on 2026-08-09. It replaced `.btn--outline`, which was a transparent 1px
   rectangle with tracked caps floating on a photograph — the most-generated
   hero button on the web, and the only outlined object on a site whose
   tokens.css bans outlines outright.

   The idea is that the button is made of the same thing as the sign hanging
   above it in the photograph: a slab of hand-cut painted board. That is the
   only genuine logo this business has, so it is the one shape here that no
   template could have produced. */
.hero__act { margin: 0; display: grid; justify-items: center; gap: var(--space-md); }

.callboard {
  position: relative;
  display: inline-grid; gap: 1px; justify-items: center;
  /* 56px+ tall in every state — this is the primary tap target on a phone. */
  padding: var(--space-sm) clamp(var(--space-lg), 6vw, var(--space-2xl));
  text-decoration: none;
  /* Still darker than the scrim, but nothing like as dark as it was. It went
     out at 15% lightness to guarantee separation from a scrim that was then
     running at 0.94 opacity; with the scrim lightened the board no longer has
     to fight for it, and 15% read as a black hole punched in a sunny
     photograph. 26% is a navy you can see is a navy.

     The floor is roughly 22%: below that it stops reading as painted board
     and starts reading as a hole. The ceiling is whatever still separates
     from the scrim — check both together if either moves. */
  background: oklch(26% 0.055 254);
  color: var(--color-onphoto);
  /* THE WHOLE POINT — the edge is cut by hand, not radiused. A border-radius
     is still a rectangle, which is the thing being escaped. Percentages, so
     the cut stays proportional as the board grows with its label. */
  clip-path: polygon(0.6% 6%, 12% 2%, 31% 5%, 55% 1%, 78% 5%, 93% 2%, 99.4% 7%,
                     99% 92%, 86% 97%, 63% 93%, 41% 98%, 19% 94%, 7% 98%, 1% 91%);
  transition: transform var(--dur-short) var(--ease-out),
              background var(--dur-short) var(--ease-out);
}
.callboard__kick {
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent-pale);
}
.callboard__num {
  /* Body face, not display: these are times and they sit in a column that
     people scan down. Gorditas has no tabular figures. */
  font-family: var(--font-body);
  font-weight: 700;
  font-size: clamp(1.5rem, 2.8vw, 2rem); line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
/* Hung on a nail, not lifted off the page — there are no shadows on this site
   and this is not the place to introduce one. */
.callboard:hover { transform: rotate(-0.4deg) scale(1.015); background: oklch(21% 0.052 254); }
/* clip-path crops an outline, so focus has to be drawn OUTSIDE the shape. */
.callboard:focus-visible { outline: 3px solid var(--color-focus); outline-offset: 5px; }
@media (prefers-reduced-motion: reduce) { .callboard:hover { transform: none; } }

/* Quiet, and never a second button: a solid/outline pair in one hero is the
   exact fingerprint this whole change removes. */
.hero__second {
  /* Padded to a 44px target. The rule lives on the inner span, NOT on the
     anchor — put it on the anchor and the padding pushes the underline away
     from the words and it stops reading as a link. */
  display: inline-flex; align-items: center;
  min-height: 44px; padding-inline: var(--space-2xs);
  font-size: var(--text-sm); font-weight: 600; letter-spacing: 0.06em;
  color: var(--color-onphoto-2); text-decoration: none;
  transition: color var(--dur-short) var(--ease-out);
}
.hero__second span {
  border-bottom: 1px solid oklch(100% 0 0 / 0.4);
  padding-bottom: 2px;
  transition: border-color var(--dur-short) var(--ease-out);
}
.hero__second span::after { content: " \2192"; }
.hero__second:hover { color: var(--color-onphoto); }
.hero__second:hover span { border-bottom-color: var(--color-onphoto); }
.hero__status {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  margin: var(--space-lg) 0 0;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-onphoto-2);
}

/* ── Proof strip, on the photograph ───────────────────────
   Four hard facts along the floor of the hero. Not a card grid — flat cells
   that meet, in keeping with the system. It used to be a paper band in the
   section below; carried on the scrim instead, the picture stays full-screen
   and the facts stop costing a scroll. The scrim is at its heaviest down here
   (0.94), so the band needs no fill of its own — a hairline is enough to sit
   it apart from the copy above. */
.hero__proof {
  position: relative; z-index: var(--z-raised);
  padding: var(--space-md) var(--page-gutter) var(--space-lg);
  border-top: var(--rule-hair) solid oklch(100% 0 0 / 0.16);
}
.proof__list {
  max-width: var(--shell); margin: 0 auto; padding: 0;
  list-style: none;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-md);
  text-align: center;
}
.proof__list li + li { border-left: var(--rule-hair) solid oklch(100% 0 0 / 0.22); }
.proof__list strong {
  display: block;
  /* Figures. Body face — see .callboard__num. */
  font-family: var(--font-body);
  font-size: var(--text-lg);
  font-weight: 700;
  line-height: 1.3;
  color: var(--color-onphoto);
  text-shadow: 0 1px 12px oklch(16% 0.05 248 / 0.55);
}
.proof__list span {
  display: block; margin-top: var(--space-3xs);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-onphoto-2);
}
.proof__list span a {
  color: inherit;
  text-decoration: none;
  box-shadow: inset 0 -1px 0 oklch(100% 0 0 / 0.4);
}
.proof__list span a:hover { color: var(--color-onphoto); box-shadow: inset 0 -2px 0 currentColor; }

/* ── Interior page head ───────────────────────────────── */
.phead {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-2xl) var(--page-gutter) var(--space-lg);
}
.phead__title { font-size: var(--text-display); max-width: 18ch; }
.phead__lede {
  margin: var(--space-md) 0 0; max-width: 52ch;
  font-size: var(--text-md); line-height: 1.6; color: var(--color-ink-2);
}
.phead__aside {
  margin: var(--space-sm) 0 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-md);
  color: var(--color-accent);
}
.phead .fold__status {
  display: inline-flex; align-items: center; gap: var(--space-2xs);
  margin-top: var(--space-md);
  padding: var(--space-3xs) var(--space-sm);
  background: var(--color-paper-2);
  color: var(--color-ink-2);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
}
/* Menu-page-only trim. The board below it is 43 rows long and the head is the
   last thing between the reader and a price, so it gives back a little of its
   air. Scoped rather than applied to .phead itself because find.html and
   catering.html open onto short pages where the head IS the content. */
.phead--tight { padding-block: var(--space-xl) var(--space-md); }

.phead__rule { display: none; }      /* the tonal band change is the divider */
/* A section opening straight after a page head does not need its full 7rem
   lead-in on top of the head's own padding — that stacked to ~10rem of air.
   .board is not in this list: it now carries the tighter lead-in itself. */
.phead__rule + .prose,
.phead__rule + .gallery { padding-top: var(--space-xl); }

/* status dot, shared */
.fold__dot {
  width: 7px; height: 7px; border-radius: 50%; flex: none;
  background: currentColor; opacity: 0.55;
}
.fold__status.is-open .fold__dot,
.hero__status.is-open .fold__dot { background: var(--color-open); opacity: 1; }

/* ── Prose ────────────────────────────────────────────── */
.prose { max-width: var(--shell); margin: 0 auto; padding: var(--space-2xl) var(--page-gutter); }
.prose__measure { max-width: var(--measure); }
.prose p { font-size: var(--text-base); line-height: 1.75; }
.prose .h-display,
.slate h2,
.kitchen .h-display { margin-bottom: var(--space-md); }
.prose__sub { font-size: var(--text-lg); margin: var(--space-xl) 0 var(--space-sm); }

.picks__more {
  margin: var(--space-2xl) 0 0;
  padding-top: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
}

/* ── What to order ────────────────────────────────────── */
.picks { padding: var(--space-3xl) var(--page-gutter); }
.picks__inner { max-width: var(--shell); margin: 0 auto; }
.picks__head { margin-bottom: var(--space-xl); }
.picks__note { max-width: 48ch; color: var(--color-muted); margin: var(--space-sm) 0 0; }
.picks__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: var(--space-md);
}
/* Flat glazed panel. No border, no shadow. */
.pick { background: var(--color-paper-2); }
.pick__shot { background: var(--color-paper-3); }
.pick__shot img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.pick__name {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-sm);
  font-size: var(--text-md);
  margin: var(--space-md) var(--space-md) var(--space-2xs);
}
.pick__price {
  flex: none;
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--text-base);
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.pick__note {
  margin: 0 var(--space-md) var(--space-md);
  font-size: var(--text-sm); color: var(--color-muted); line-height: 1.6;
}



/* ── The board · a printed menu card ──────────────────────
   Fourth structure, and the one Marcus specified from a mockup. v1 was three
   white cards on cream (a pricing table). v2 flooded the section with ink. v3
   was a tiled wall of flat colour with a photo plate on each tile — which kept
   losing to the source material rather than to the layout.

   v4 drops the photographs from this section entirely and sets it the way a
   menu is actually set: centred masthead between two runs of the key, three
   columns divided by hairlines, leader dots, a closing plaque of line art.
   Nothing here depends on a photograph being good.

   DELIBERATE DEPARTURE from the "no outlines" rule in tokens.css. Column
   dividers and the plaque's frame are the entire grammar of a printed card;
   without them this is three lists adrift on plaster. The departure is scoped
   to .picks--board and the rules are genuine hairlines in the site's own rule
   token — it is not a licence to start boxing things elsewhere. */
.picks--board { background: var(--color-paper); color: var(--color-ink); }

/* ── Masthead ─────────────────────────────────────────────
   key ──── sprig + title ──── key, tagline beneath, all centred. The keys are
   the section mark at this level, so the usual ::after mark is not used here. */
.menuhead {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: 0 var(--space-lg);
  text-align: center;
}
.menuhead__key {
  height: 20px;
  background-color: var(--color-accent);
  -webkit-mask: var(--meander) repeat-x right center / var(--meander-size);
          mask: var(--meander) repeat-x right center / var(--meander-size);
  opacity: 0.9;
}
/* Mirrored, so the two runs read outward from the title instead of marching
   through it in one direction. */
.menuhead__key--flip { transform: scaleX(-1); }

/* The key is a geometric, architectural ornament and it needs a face with a
   flat cap-height band to sit against. Gorditas gives it one: an even, solid
   top line the two runs can align to. This used to be set
   in Prata to avoid a script masthead under a script wordmark — that problem
   is gone now the headline face and the logo are the same hand. */
.menuhead__title {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-sm);
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-display-s);
  line-height: 1.1;
  max-width: none;
}
.menuhead__sprig {
  width: 2.4rem; height: auto; flex: none;
  color: var(--color-accent);
}
.menuhead__line {
  grid-column: 1 / -1;
  margin: var(--space-sm) 0 0;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-ink-2);
  /* Without this it broke as "…NOT ALL OF / IT." on a phone. */
  text-wrap: balance;
}

/* ── The three columns ────────────────────────────────────
   Equal thirds here, unlike v3. A menu card's authority comes from the columns
   being the same measure — the asymmetry that made the tiled wall work reads as
   a mistake once the fill colour is gone and only a hairline marks the split. */
.breadth {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: calc(var(--space-lg) * 2);
  margin-top: var(--space-2xl);
}
.breadth__col { display: flex; flex-direction: column; }
/* The divider is pulled back into the middle of the gutter by a negative margin
   that the padding immediately gives back, so the content box still starts at
   the track edge. That matters: padding the columns directly instead cost the
   MIDDLE column 64px of measure against 32px for the outer two, and a menu card
   whose centre column runs visibly short reads as a mistake. This way all three
   measures are identical and the rule sits centred in the gutter. */
.breadth__col + .breadth__col {
  border-left: var(--rule-hair) solid var(--color-rule);
  margin-left: calc(var(--space-lg) * -1);
  padding-left: var(--space-lg);
}

.breadth__cap {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  line-height: 1;
  color: var(--color-accent);
  margin-bottom: var(--space-md);
}
/* Flanking dashes — the masthead's device one level down and one weight lighter.
   As ::before/::after on a flex container they are flex items, so they simply
   absorb whatever width the label leaves. */
.breadth__cap::before,
.breadth__cap::after {
  content: "";
  flex: 0 1 1.6rem; min-width: 0.45rem;
  height: var(--rule-hair);
  background: var(--color-accent);
  opacity: 0.5;
}
/* Tracking adds a trailing space after the last letter, which throws the
   optical centre a few pixels right. Claw it back. */
.breadth__cap span { margin-right: calc(var(--track-caps) * -1); }
.breadth__icon { width: 1.6rem; height: 1.6rem; flex: none; }

/* No rule between rows. The leader dots already carry the eye across, and a
   line under every item turned the columns straight back into a table. */
.breadth .list li { border-top: 0; padding: var(--space-2xs) 0; }
.breadth .list__item { font-weight: 700; color: var(--color-ink); }
.breadth .list__item::after { border-bottom-color: var(--color-rule); }
.breadth .list__price {
  font-family: var(--font-body); font-weight: 600;
  font-variant-numeric: tabular-nums;
  font-size: var(--text-md);
  color: var(--color-accent);
}
.breadth .veg { color: var(--color-olive); }

/* Top-aligned, NOT flushed to the column floor. The three lists are all four
   rows, so aligning tops puts the footnotes on one line; auto-margin instead
   aligned their BOTTOMS, which dropped the one-line note a whole line below the
   two-line ones and read as a mistake. No rule above it either — the space is
   the separation, and a hairline there fought the column dividers. */
.breadth__foot {
  display: flex; gap: var(--space-xs);
  margin: 0; padding-top: var(--space-lg);
  font-size: var(--text-sm); color: var(--color-ink-2); line-height: 1.55;
}
.breadth__leaf {
  width: 1.6rem; height: auto; flex: none;
  margin-top: 0.2em;
  color: var(--color-accent); opacity: 0.75;
}

/* Closer to the card above than to the plaque below, so it reads as the card's
   own last line rather than as something floating between two objects. */
.picks--board .picks__more {
  margin: var(--space-xl) 0 0;
  padding-top: 0; border-top: 0;
  text-align: center;
}

/* ── Closing plaque ───────────────────────────────────────
   The one framed object on the page. A plaque without an edge is just more
   text, so this is where the outline departure earns itself. */
.commune {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--space-lg);
  margin-top: var(--space-2xl);
  padding: var(--space-md) var(--space-xl);
  border: var(--rule-hair) solid var(--color-accent);
  text-align: center;
}
.commune__art {
  width: clamp(6.5rem, 13vw, 11.5rem); height: auto;
  color: var(--color-accent); opacity: 0.55;
}
.commune__kicker {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.commune__body {
  margin: 0 auto; max-width: 44ch;
  font-size: var(--text-sm); color: var(--color-ink-2); line-height: 1.6;
}

/* width/height 0 rather than display:none — display:none stops <use> resolving
   in some engines. */
.u-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ── The tzatziki ─────────────────────────────────────────
   Rebuilt 2026-08-09 to Marcus's third mockup. Was a 13rem thumbnail, a
   heading and two prices in a row: correct information, no presence, on the
   one product this truck is actually known by name for.

   Now a full-bleed two-up. The photograph runs off the LEFT EDGE OF THE
   VIEWPORT with no shell to hold it back, which is the cheapest way to make a
   soft phone snap look deliberate — crop it harder and let it bleed. The type
   sits on the dark ground to the right of centre. Because the shell is centred,
   the 50% column boundary IS the shell's midpoint, so the text starts on a line
   the rest of the page already knows about.

   --color-deep-2, NOT --color-deep. This band sits directly under the board,
   and an earlier rule that tried to differentiate the two was silently losing
   the cascade to a later `.tzat { background: var(--color-deep) }` at equal
   specificity — so the two slabs rendered identical and read as one flat
   rectangle half the page tall. That is most of why the board looked cheap. */
.tzat {
  position: relative;
  background: var(--color-deep); color: var(--color-onphoto);
  /* A four-track bleed grid: gutter | food | type | gutter, with the two middle
     tracks adding up to --shell. Every other section on this site centres its
     content on that same 1180px measure, and this band has to as well — a
     free-running two-column split put the food and the type in the left half of
     a wide monitor and left a third of the section as dead navy on the right.
     Now the leftover width is symmetric page margin, which is what the rest of
     the page already does. */
  display: grid;
  grid-template-columns:
    minmax(var(--page-gutter), 1fr)
    minmax(0, calc(var(--shell) * 0.46))
    minmax(0, calc(var(--shell) * 0.54))
    minmax(var(--page-gutter), 1fr);
  /* Room for a torn edge on each side. --tear-h is declared here so the band,
     the two edges and the key tile can never drift out of step. */
  --tear-h: clamp(2rem, 2.9vw, 3.1rem);
  /* Clear of both torn edges, plus real breathing room. */
  padding-block: calc(var(--tear-h) + var(--space-md));
  align-items: center;
  overflow: hidden;
}

/* NOT a photo panel. The cut-out is a transparent PNG standing directly on the
   band's own ground, so there is no second rectangle and no seam — the whole
   section is one flat block of colour, which is the direction's actual rule.
   That is also why this band moved from --color-deep-2 to --color-deep: with
   nothing behind the food, the darker ground is what makes it read as lit. */
/* Bled off the left edge of the page. Three things matter here and each one
   has already broken once:
     · the cap is on the FIGURE, not the image, so the figure's right edge is
       exactly the edge of the bowl — that is what lets the seal anchor to
       `right: 0` and land against it instead of floating in dead space;
     · align-self: center, NOT the grid default of stretch. Stretched, the
       figure ran the full row height and `bottom: 8%` dropped the seal well
       below the bowl;
     · no vertical padding, so the figure's box IS the image's box and the
       seal's percentages mean what they look like they mean.
   The cap is sized so the food and the four lines of type beside it come out
   at roughly the same height — the photograph is the section's other half,
   not its headline. */
/* No negative margin and no bleed. The cut-out was hanging into the page gutter
   and .tzat clips its overflow, so the pita was being sliced down its left side
   on every wide screen. It sits inside its track, whole. */
.tzat__shot {
  grid-column: 2;
  position: relative; align-self: center;
  margin: 0; padding: 0;
}
.tzat__shot img { display: block; width: 100%; height: auto; }

/* A printed stamp on the photograph.
   THE ONE ROUNDED THING IN THE BUILD, and it does not contradict the zero-radius
   rule in tokens.css: that rule is about tiles and panels not having softened
   corners. This is a hard circle, an ornament in the same class as the sprig —
   nobody will mistake it for a rounded card. Do not generalise from it. */
/* ── The seal ─────────────────────────────────────────────
   THERE IS NO RING. Three attempts at this got rejected on 2026-08-09 and the
   thin outer ring was the common factor every time — Marcus called it, exactly,
   "common AI slop", and he is right: a 1px circle inset from an otherwise empty
   edge is the default badge every generator draws. A hairline around nothing
   is not a design, it is a placeholder for one.

   So the mark is built the way the rest of this site's identity now is: flat
   colour, a hand-cut edge, and nothing outlined. It is CREAM WITH NAVY TYPE,
   inverted from the band it sits on, which makes it read as a paper label
   stuck on the tub rather than as a translucent UI badge — and it matches the
   painted wordmark in the masthead, which is navy on cream with a cut edge.

   Bigger, too. It ran at 6.2rem, which is under 100px, and three lines of caps
   at that size is where the cramping came from. */
.tzat__seal {
  position: absolute; z-index: 1;
  /* Unchanged: the PNG is cropped to the food's own alpha bounds, so the
     figure's right edge IS the edge of the bowl. 30%, not 34% — the mark is
     larger now and the overhang has to stay under .tzat__say's lead padding. */
  right: 0; bottom: 6%; transform: translateX(30%) rotate(-4deg);
  width: 8.6rem; height: 8.6rem; margin: 0;
  display: grid; place-content: center; justify-items: center;
  gap: var(--space-3xs);
  background: var(--color-paper);
  color: var(--color-accent-2);
  text-align: center;
  font-size: var(--text-sm); font-weight: 800;
  /* Half the old tracking. 0.14em is a label idiom for ONE short line; over
     three stacked lines in a disc it was what forced the negative-margin
     correction below. */
  letter-spacing: 0.06em; text-transform: uppercase; line-height: 1.3;
  /* Cut by hand, not drawn by a radius. A circle that is very slightly not a
     circle is the whole difference between pressed and generated. */
  clip-path: polygon(50% 0%, 63% 1%, 74% 6%, 84% 12%, 92% 21%, 97% 32%, 100% 45%,
                     99% 58%, 94% 71%, 86% 81%, 76% 90%, 63% 96%, 50% 100%,
                     37% 97%, 25% 91%, 15% 83%, 7% 72%, 2% 60%, 0% 47%, 2% 34%,
                     8% 22%, 16% 12%, 27% 5%, 38% 1%);
}
.tzat__seal svg { width: 1.9rem; height: auto; color: var(--color-accent); }
/* The tracking is applied to the right of every glyph, including the last one
   on each line, which pushes centred lines visibly left. */
.tzat__seal span { margin-right: -0.06em; }

.tzat__say {
  grid-column: 3;
  display: grid; align-content: center; justify-items: start;
  padding-inline: var(--space-2xl) 0;
}
.tzat__kicker {
  margin: 0; font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent-pale);
}
.tzat__title {
  margin: var(--space-xs) 0 0; max-width: 15ch;
  font-size: var(--text-display); line-height: 1.16;
  color: var(--color-onphoto);
}
/* Hairline, sprig, hairline — but only trailing, so it reads as a rule drawn
   out from the headline rather than a centred ornament on a left-aligned block. */
.tzat__rule {
  display: flex; align-items: center; gap: var(--space-sm);
  width: 100%; max-width: 20rem; margin: var(--space-md) 0 0;
}
.tzat__rule svg { width: 1.8rem; height: auto; flex: none; color: var(--color-accent-pale); }
.tzat__rule::after {
  content: ""; flex: 1 1 auto; min-width: 1rem;
  height: var(--rule-hair); background: var(--color-accent-pale); opacity: 0.5;
}
.tzat__blurb {
  margin: var(--space-md) 0 0; max-width: 56ch;
  color: var(--color-onphoto-2); font-weight: 450;
}

/* The $3 / $1 price pair and the "Call to order · See the full menu" row that
   used to close this block are gone. Both were repeats — the price list lives
   on the menu, and the call button is in the masthead, on the callbar and in
   the section directly below. Removing them is most of why this band is short
   now: it says one thing, which is the one thing painted on the truck. */

/* ── The torn edge ────────────────────────────────────────
   The band does not stop on a ruled line, it is torn off. Drawn as one SVG
   shape filled with the paper colour of the section below, so there is no
   overlay, no gradient and nothing to keep in sync — if the next section's
   ground ever changes, this is the single value to change with it. */
/* A MASK, not a drawing. Three vector attempts at this edge all read as vector
   — the giveaway is that a path has one hard boundary, and a loaded flat brush
   dragged sideways does not: it leaves a band where coverage breaks up into
   grain, plus bristle streaks running with the drag. That is per-pixel, so the
   shape ships as an alpha png and the COLOUR still comes from the token here.
   Regenerate with scratchpad/brush.py if it ever needs re-cutting. */
.tzat__tear {
  position: absolute; left: 0; right: 0;
  height: var(--tear-h);
  z-index: 2; pointer-events: none;
  background: var(--color-paper);
  /* `auto 100%` + repeat-x, NOT `100% 100%`. Stretching 2400px of chips into a
     390px phone squeezed them into a vertical comb. Scaled by height only, the
     grain keeps its real size at every width; the source is flat at both ends
     so the repeat joins invisibly (and at these proportions the tile is wider
     than the viewport anyway, so it rarely gets to repeat at all). */
  -webkit-mask: url("assets/photos/tear-mask.png") repeat-x left center / auto 100%;
          mask: url("assets/photos/tear-mask.png") repeat-x left center / auto 100%;
}
.tzat__tear--bot { bottom: 0; }
/* One asset, mirrored, so the top edge bites down out of the paper above and
   the bottom edge bites up out of the paper below. */
.tzat__tear--top { top: 0; transform: scaleY(-1); }
/* `.tzat__key` — a single 2rem meander tile on a paper ground, centred on the
   bottom tear — was removed on 2026-08-09. Marcus called it "the random
   square", and at that size, straddling a ragged edge, that is exactly what
   it read as: a boxed glyph with no siblings, too small to be legible as a
   key and too hard-edged to belong to the tear. The tear is the device.
   Do not put a seal back on it. */

/* ── The menu ─────────────────────────────────────────── */
/* Asymmetric on purpose: the last panel in each column carries its own 1.5rem
   bottom margin, so a matching 2rem here would read as 3.5rem of tail. */
.board {
  background: var(--color-paper-2);
  padding: var(--space-lg) var(--page-gutter) var(--space-2xs);
}
.board__head {
  max-width: var(--shell); margin: 0 auto var(--space-xl);
  display: grid; gap: var(--space-sm);
}
.board__note { max-width: 54ch; color: var(--color-muted); margin: 0; }
.board__cols {
  max-width: var(--shell); margin-inline: auto;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(19rem, 1fr));
  gap: var(--space-md);
}
/* MULTI-COLUMN, not grid, and that is the whole point: grid rows stretch every
   panel to the height of the tallest one in its row, so Sandwiches (6 items)
   was being padded out to 957px of dead plaster purely to match Gyros (12
   items) beside it, and Sweets to match Sides. Three rows of that was most of a
   screen of nothing. Multicol has no rows — it packs the groups into balanced
   columns and each panel is exactly as tall as its own list. Reading order
   becomes column-first, which is how a printed menu reads anyway, and the DOM
   order is untouched so screen readers are unaffected.

   THREE columns, measured, not assumed: at 1440 the board is 1503px at three
   and 1985px at two. The panels themselves get slightly taller because the
   descriptions wrap more at 377px, but six indivisible groups pack far better
   into three columns than two — with two, Gyros+Sandwiches+Dinners lands in one
   column and strands ~480px of empty band under Sweets.

   The count is set in two places on purpose. `columns: 2 19rem` handles the
   drop to a single stack at about 40rem, and the third column is held back
   behind its own query rather than being left to fall out of that 19rem
   minimum — on its own, 19rem goes to three at ~1100px and hands each column
   only 273px of measure, under the 280px this menu's longest row ("Spinach Pie
   Platter VEG ⋯ $16") needs. The query waits until the 1180px shell is actually
   full, where three columns are a comfortable 377px. */
.board__cols--two {
  display: block;
  columns: 2 19rem;
  column-gap: var(--space-md);
}
@media (min-width: 75rem) { .board__cols--two { column-count: 3; } }
/* Multicol has no row gap, so the panels carry their own. `avoid` keeps a group
   from being sliced in half across the column break. */
.board__cols--two .grp {
  margin-bottom: var(--space-md);
  -webkit-column-break-inside: avoid;
          break-inside: avoid;
}
/* Narrow panels should not spend 1.5rem a side on plaster — below this the
   column is ~340px and that padding is a seventh of it. The page gutter is
   already holding the panel off the edge of the screen. */
@media (max-width: 54rem) {
  .grp { padding: var(--space-sm); }
  .board__cols--two .grp { margin-bottom: var(--space-sm); }
}

/* Plaster panel on the tile field — reversed from the surrounding band. */
.grp { background: var(--color-surface); padding: var(--space-md); }
/* Badge, then the name, then a rule running out to the panel edge. Set to
   Marcus's menu mockup, 2026-08-09 — it was a plain heading over a 2px accent
   underline, which read as a form fieldset once there were six of them. */
.grp__head {
  display: flex; align-items: center; gap: var(--space-sm);
  margin-bottom: var(--space-2xs);
}
.grp__badge {
  flex: none;
  display: grid; place-items: center;
  width: 2.6rem; height: 2.6rem;
  border-radius: 50%;
  color: var(--color-accent);
  background: var(--color-paper-2);
  box-shadow: 0 0 0 var(--rule-hair) var(--color-accent-pale) inset;
}
.grp__badge svg { width: 1.4rem; height: 1.4rem; }
.grp__title {
  flex: 1 1 auto;
  display: flex; align-items: center; gap: var(--space-sm);
  /* Kept on the display face: these name the sections of the menu and are the
     one place on a dense page that should read as lettering. */
  font-family: var(--font-display);
  font-size: var(--text-lg); font-weight: var(--weight-display); line-height: 1.15;
  border-bottom: 0; padding-bottom: 0;
}
/* The rule takes whatever width the name leaves, so it ends flush with the
   panel however long the name is. */
.grp__title::after {
  content: ""; flex: 1 1 auto; height: var(--rule-hair);
  background: var(--color-rule);
}
.grp__note {
  margin: var(--space-2xs) 0 var(--space-3xs);
  font-size: var(--text-sm); color: var(--color-muted); line-height: 1.55;
}
.grp__foot {
  margin: var(--space-sm) 0 0; padding-top: var(--space-2xs);
  border-top: var(--rule-hair) solid var(--color-rule);
  font-size: var(--text-sm); color: var(--color-muted);
}
/* The two surcharges are not a footnote to the gyro list, they are a thing you
   can order — so they get a plate rather than a rule and a smaller grey. */
.grp__foot--plate {
  display: grid; gap: var(--space-3xs);
  margin-top: var(--space-md); padding: var(--space-sm) var(--space-md);
  border-top: 0;
  background: var(--color-paper-2);
  color: var(--color-ink-2);
}
.board__more {
  max-width: var(--shell); margin: var(--space-xl) auto 0;
  padding-top: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
}

/* ══ MENU PAGE HEAD, TABS AND PICKS ═══════════════════════════════════════
   Rebuilt 2026-08-09 to Marcus's blueprint. The head was a two-column split
   with a photograph bled off the right edge; the blueprint is symmetrical and
   centred — a playbill, with the food cut out and floating on painted water.

   ONE DOCUMENTED DEVIATION from tokens.css, which sets every radius to zero
   on the grounds that tiles are square: the blueprint's tabs and cards are
   visibly rounded, and squaring them off turns the tab row into a filing
   cabinet. The radius is defined here, scoped to these three components, and
   is NOT a licence to round anything else on the site.

   Contained here rather than spread through the file so the whole of the menu
   page's own furniture is in one place. --------------------------------- */
.mhead, .mfilter, .mpicks {
  --menu-radius: 10px;
  --menu-radius-sm: 8px;
}

/* ── Menu head ──────────────────────────────────────────── */
/* ── Menu head ────────────────────────────────────────────
   THE WHOLE HEAD IS SIZED AGAINST VIEWPORT HEIGHT, not just width, and that
   is the point of it: Marcus landed on this page in a normal Safari window on
   2026-08-09 and the plate ran off the bottom of the screen. A head that has
   to be scrolled to be seen is not a head.

   So every vertical measure below — the top padding, the title, the sprigs,
   the rule, the two gaps and the plate itself — carries a `vh` term inside
   its clamp. On a tall window they all sit at their comfortable maximum; on a
   short one the whole block scales down together and stays in proportion,
   rather than one part collapsing while the photograph stays 560px tall.

   `svh`, deliberately, NOT `vh` or `dvh`. `svh` is the viewport with the
   mobile browser chrome SHOWN, which is exactly the height the visitor has at
   the moment they land — and unlike `dvh` it does not change as the URL bar
   retracts, so nothing resizes under the reader mid-scroll. */
.mhead {
  position: relative;
  overflow: hidden;
  padding: clamp(var(--space-sm), 3svh, var(--space-xl)) var(--page-gutter) 0;
  background: var(--color-paper);
  text-align: center;
}
.mhead__say {
  position: relative; z-index: var(--z-raised);
  max-width: 46rem; margin-inline: auto;
}
.mhead__where {
  margin: 0 0 var(--space-2xs);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}

/* Title and laurels are one line box, so the sprigs track the title's size
   instead of being parked at fixed offsets that break at every width. */
.mhead__crown {
  display: flex; align-items: center; justify-content: center;
  gap: clamp(var(--space-2xs), 1.8vw, var(--space-lg));
}
/* The stem runs bottom-left to top-right, so the sprite as drawn IS the right
   hand sprig and the left one is the mirror — not the other way round. Get
   this backwards and both branches lean into the title like closing brackets. */
.mhead__sprig {
  flex: none;
  width: clamp(2.2rem, min(4.4vw, 6svh), 4.4rem); height: auto;
  color: var(--color-accent);
}
.mhead__sprig--flip { transform: scaleX(-1); }
/* Slanted, because at this size "Our Menu" is a brand moment — it is the first
   lettering below the wordmark and should echo it rather than dodge it. The old
   build set this in a serif specifically to avoid a script clashing with the
   script wordmark; matching the logo outright is the better answer. */
.mhead__title {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  /* The min() is the height governor: on a wide-but-short window 6.8vw would
     ask for 125px of type in a viewport that has no room for it. */
  font-size: clamp(2.2rem, min(6.2vw, 9svh), 4.8rem);
  font-weight: 400; line-height: 1.0;
  letter-spacing: var(--track-display);
  color: var(--color-accent-2);
  margin: 0;
}
.mhead__title::after { display: none; }
.mhead__wave {
  display: block;
  width: clamp(6rem, 11vw, 9.5rem); height: 12px;
  margin: clamp(var(--space-3xs), 1.2svh, var(--space-xs)) auto
          clamp(var(--space-2xs), 1.8svh, var(--space-sm));
  color: var(--color-rule);
}
/* Two beats, the second stepped right — an aside pencilled under the copy,
   not a third sentence of it. */
.mhead__aside {
  display: grid; justify-items: center;
  margin: clamp(var(--space-2xs), 2.2svh, var(--space-md)) 0 0;
  font-weight: 500;
  font-size: var(--text-md); line-height: 1.5;
  color: var(--color-accent);
}
.mhead__aside span + span { margin-left: clamp(1rem, 4vw, 3.5rem); }

/* ── The plate ────────────────────────────────────────────
   The cut-out sits above the wash, and the wash is allowed past the gutter on
   both sides — a watercolour that stops dead at the text column reads as a
   rectangle someone blurred. */
.mhead__plate {
  position: relative;
  margin-top: clamp(var(--space-3xs), 1.5svh, var(--space-md));
}
/* Sits high — starting ABOVE the top of the plate and running out around its
   waist. Level with the food it reads as a shadow; above it, it reads as the
   sea the truck is parked beside, which is the whole point of the device. */
.mhead__wash {
  position: absolute; z-index: var(--z-base);
  left: 50%; translate: -50% 0;
  width: 112vw; max-width: none;
  top: -8%; height: 78%;
  /* Aegean, thinned. Kept as properties so the wash recolours with the
     palette instead of pinning four hexes into the markup. */
  --wash-1: oklch(80% 0.070 236 / 0.85);
  --wash-2: oklch(72% 0.092 240 / 0.60);
  --wash-3: oklch(87% 0.048 234 / 0.72);
  /* Turbulence tears the top and bottom edges but leaves the left and right
     as clean vertical cuts against the viewport, which is the one place a
     watercolour must not have a straight edge. The mask does that end. */
  -webkit-mask: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
          mask: linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
}
/* SIZED BY HEIGHT, NOT WIDTH — the inversion is deliberate and load-bearing.
   Given `width: min(100%, 54rem)` the plate was ~570px tall on any desktop
   window, which is most of a laptop viewport before the tabs are even
   reached. Height-first means the photograph takes a fixed share of whatever
   screen it lands on and the head fits by construction.

   ⚠️ IT IS STILL WIDTH-DRIVEN — the height budget is expressed AS a width.
   `76svh` is `50svh × 1.5217`, the plate's own 1400∶920 ratio, and `51.75rem`
   is the 34rem cap through the same multiplier. So the picture never exceeds
   half the viewport's height, while `height: auto` keeps the intrinsic ratio
   at every width. Change the height budget by changing these two numbers.

   Do NOT "simplify" this to `height: min(50svh, 34rem); max-width: 100%`.
   That was tried and it SQUASHES the plate: when max-width clamps the used
   width the browser keeps the specified height, so at 390px it rendered
   350×422 — a 1.52 photograph crushed to 0.83. `aspect-ratio` does not
   rescue it either (height stays definite, so the ratio resolves width and
   the clamp then overrides it), and `object-fit: contain` only fixes the
   painting while leaving ~190px of empty box shoving the tab row down.
   Width-driven has no such failure mode: one axis is auto, always. */
.mhead__cut {
  position: relative; z-index: var(--z-raised);
  display: block;
  width: min(100%, 76svh, 51.75rem); height: auto;
  margin: 0 auto -2px;              /* -2px kills the seam against .mfilter */
}

/* ── Menu filter ──────────────────────────────────────────
   Six courses and 43 rows: the tabs are the difference between reading the
   board and scanning for the one thing you came for. Shipped hidden — see the
   note in menu.html — and they filter in place rather than jumping, because
   an anchor jump on a multicol board lands you mid-column. */
.mfilter { padding: 0 var(--page-gutter); background: var(--color-paper); }
.mfilter__inner {
  max-width: var(--shell); margin: 0 auto;
  display: flex; gap: var(--space-2xs);
  /* Height-aware for the same reason the head is: the tab row is the last
     thing that has to clear the fold. */
  padding: clamp(var(--space-2xs), 2svh, var(--space-md)) 0 var(--space-sm);
}
/* Grow to fill the row but keep their natural proportions, so "Dinners &
   Platters" stays the widest tab and "Gyros" the narrowest — seven equal
   boxes would read as a segmented control, which this is not. */
.mfilter__tab {
  position: relative;
  flex: 1 1 auto;
  appearance: none; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-2xs);
  padding: var(--space-xs) var(--space-sm) calc(var(--space-xs) + 5px);
  border: var(--rule-hair) solid var(--color-accent-pale);
  border-radius: var(--menu-radius-sm);
  background: var(--color-surface);
  color: var(--color-ink-2);
  font: inherit;
  font-size: var(--text-xs); font-weight: 700;
  /* One notch under --track-caps. At the full 0.14em "Dinners & Platters" and
     "Sweets & Drinks" no longer fit their tabs on one line, and a two-line tab
     in a row of one-line tabs bows the whole row. */
  letter-spacing: 0.1em; text-transform: uppercase;
  line-height: 1.1; white-space: nowrap;
  transition: background var(--dur-short) var(--ease-out),
              color var(--dur-short) var(--ease-out),
              border-color var(--dur-short) var(--ease-out);
}
.mfilter__ic {
  flex: none;
  width: 1.2rem; height: 1.2rem;
  color: var(--color-accent);
  transition: color var(--dur-short) var(--ease-out);
}
/* The sprig is drawn 68×46. Squared off with the rest it letterboxes down to
   a few grey pixels, so it keeps its own ratio. */
.mfilter__ic--wide { width: 1.7rem; height: 1.15rem; }
.mfilter__tab:hover {
  background: var(--color-paper-2); color: var(--color-accent);
  border-color: var(--color-accent);
}
.mfilter__tab.is-on {
  background: var(--color-accent); color: var(--color-accent-ink);
  border-color: var(--color-accent);
}
.mfilter__tab.is-on .mfilter__ic { color: currentColor; }
/* The keel. Marks the live tab a second time, so the row still reads when the
   navy fill is the thing a colour-blind visitor cannot separate. */
.mfilter__tab.is-on::after {
  content: ""; position: absolute;
  left: 50%; translate: -50% 0; bottom: 6px;
  width: 1.9rem; height: 2px;
  background: currentColor; opacity: 0.85;
}

/* ── Three to start with ──────────────────────────────────
   Photographed cards under the tabs. They are buttons, not links — see the
   note in menu.html — so everything type-ish inside them has to be re-set,
   because a <button> inherits nothing worth having. */
.mpicks { padding: 0 var(--page-gutter) var(--space-md); background: var(--color-paper); }
.mpicks__inner {
  max-width: var(--shell); margin: 0 auto;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-md);
}
.mpick {
  appearance: none; cursor: pointer; text-align: left;
  display: flex; flex-direction: column;
  padding: 0; overflow: hidden;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--menu-radius);
  background: var(--color-surface);
  font: inherit; color: inherit;
  transition: border-color var(--dur-short) var(--ease-out),
              background var(--dur-short) var(--ease-out);
}
/* The photo rounds its own top corners rather than leaning on the card's
   overflow:hidden. A <button> in Chromium does not reliably clip descendants
   to its border-radius — the card reads rounded while the photograph inside
   it keeps square corners. Minus the 1px border so the curve sits on the
   frame instead of a pixel outside it. */
.mpick__shot {
  display: block; aspect-ratio: 16 / 10; overflow: hidden;
  border-radius: calc(var(--menu-radius) - 1px) calc(var(--menu-radius) - 1px) 0 0;
  background: var(--color-paper-2);
}
.mpick__shot img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: scale var(--dur-medium) var(--ease-out);
}
/* greek-salad.jpg is a square frame with the salad on the left and a takeout
   lid and a dressing cup on the right. Cropped from the centre the packaging
   wins; held to the left it is a Greek salad. */
.mpick__shot--left img { object-position: 18% center; }
.mpick__say {
  display: grid; gap: var(--space-3xs);
  padding: var(--space-md);
}
.mpick__name {
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--text-md); line-height: 1.15;
  color: var(--color-ink);
}
.mpick__note { font-size: var(--text-sm); line-height: 1.5; color: var(--color-muted); }
.mpick__from {
  margin-top: var(--space-3xs);
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.mpick:hover { border-color: var(--color-accent-pale); background: var(--color-paper); }
.mpick:hover .mpick__shot img { scale: 1.04; }
@media (prefers-reduced-motion: reduce) {
  .mpick:hover .mpick__shot img { scale: 1; }
}

/* ── Call it in ───────────────────────────────────────────
   The badge is the mockup's device: the phone is the whole point of the band,
   so it gets a mark rather than sitting inside the sentence. */
.cta__badge {
  flex: none;
  display: grid; place-items: center;
  width: 3.4rem; height: 3.4rem;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-accent-ink);
}
.cta__badge svg { width: 1.6rem; height: 1.6rem; }
.cta__say { display: flex; align-items: center; gap: var(--space-md); }

.list { list-style: none; margin: 0; padding: 0; }
/* name .......... price, with any description on its own line beneath. */
.list li {
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: 0 var(--space-sm);
  /* 8px, not 12. There are 43 rows on menu.html and this is multiplied by every
     one of them — the four pixels back were the single cheapest thing on the
     page. Still a comfortable 44px row, well over the 24px touch minimum once
     the line box is counted. */
  padding: var(--space-2xs) 0;
}
.list li + li { border-top: var(--rule-hair) solid var(--color-rule-soft); }
.list__item { flex: 0 1 auto; min-width: 0; font-weight: 600; }
.list__price {
  flex: none; margin-left: auto; white-space: nowrap;
  font-weight: 700; color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.list__desc {
  flex: 1 0 100%; margin-top: 3px;
  font-size: var(--text-sm); color: var(--color-muted); line-height: 1.5;
}
/* Not a boxed stamp — olive small caps, the way a menu marks a dish. */
.veg {
  font-style: normal;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--color-olive);
  margin-left: var(--space-2xs);
}

/* ── The deep band — story / catering brief ───────────── */
.kitchen, .slate {
  background: var(--color-deep); color: var(--color-onphoto);
  padding: var(--space-3xl) var(--page-gutter);
}
.kitchen__inner, .slate__inner { max-width: var(--shell); margin-inline: auto; }
.kitchen .h-display, .slate h2 { color: var(--color-onphoto); }
.kitchen__inner > p, .slate p { color: var(--color-onphoto-2); max-width: var(--measure); }
.kitchen__inner > p, .slate p, .foot__blurb, .foot__hours, .foot address { font-weight: 450; }
.kitchen .tlink, .slate .tlink {
  color: var(--color-onphoto); box-shadow: inset 0 -1px 0 oklch(100% 0 0 / 0.5);
}
.kitchen .tlink:hover, .slate .tlink:hover { color: #fff; box-shadow: inset 0 -2px 0 #fff; }
.kitchen__quote {
  /* A sentence someone said, not a sign. The display face at 34ch of running
     text is unreadable — the body face at 500 keeps it a quote. */
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-lg); line-height: 1.5;
  color: var(--color-onphoto);
  max-width: 34ch;
  margin: var(--space-lg) 0 var(--space-md);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid oklch(100% 0 0 / 0.3);
}

/* ══════════════════════════════════════════════════════════════════════════
   CATERING PAGE — rebuilt 2026-08-10 to Marcus's picture-free mockup.

   WHAT CHANGED AND WHY IT MUST NOT DRIFT BACK:
   Every photograph came off this page. It ran a split hero with the truck
   bleeding off the right edge and three round food plates in the formats
   band; the mockup that replaced it is navy line art and flat tinted blocks
   on plaster, and one photograph anywhere in that would read as a banner
   pasted onto a different page. The library also has no exterior shot and no
   catering shot at all (assets/photos/README.md), so the images that were
   here were three listing photos of food standing in for an event — which is
   most of why the page never looked like catering.

   The grammar of the page is now four things and only four:
     · flat tinted blocks (--color-paper-2) on plaster (--color-paper)
     · navy line art, stroked, never filled except the seal's spit
     · caps labels in the body face, display only for the format names and
       the one closing line
     · the Greek key at section scale — short flanking runs, never a band
   ══════════════════════════════════════════════════════════════════════════ */

/* ── Catering hero ────────────────────────────────────────
   Split, not banded: the argument sits on paper at the left and the
   photograph runs off the right edge of the page. Built to Marcus's mockup
   2026-08-09 and KEPT on 2026-08-10 when everything below it went
   picture-free. It is the page's only photograph on purpose — the sections
   under it are line art and flat tinted blocks, and this is the one place a
   customer gets to see who is actually going to show up. */
.chero {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  background: var(--color-paper);
  overflow: hidden;                    /* the shot bleeds; nothing else may */
}
/* Right-aligned inside the left half and capped at half the shell, so the copy
   starts exactly on the page's left gutter line without a full-bleed grid and
   its four tracks. The right column is then free to run to the viewport edge. */
.chero__say {
  position: relative; z-index: var(--z-raised);
  justify-self: end;
  width: 100%; max-width: calc(var(--shell) / 2);
  padding: var(--space-2xl) var(--space-lg) var(--space-2xl) var(--page-gutter);
}
.chero__title {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-display);
  line-height: 1.02;
  margin: 0;
}
/* The one line of script above the fold, and it finishes the headline's
   sentence rather than repeating it. */
.chero__script {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-display-s);
  line-height: 1.05;
  color: var(--color-accent);
  margin: var(--space-2xs) 0 0;
}
/* A short run of the key, used as a rule. Three tiles, not a full band — at
   page width it is a border, at paragraph width it is punctuation. */
.chero__key {
  width: 4.6rem; height: 12px; border: 0; margin: var(--space-md) 0;
  background-color: var(--color-accent);
  -webkit-mask: var(--meander) repeat-x left center / 15px 12px;
          mask: var(--meander) repeat-x left center / 15px 12px;
}
.chero__lede {
  max-width: 34ch;
  font-size: var(--text-base); line-height: 1.7;
  color: var(--color-ink-2);
  margin: 0 0 var(--space-lg);
}
.chero__act { margin: 0; }

.chero__shot { position: relative; margin: 0; height: 100%; min-height: clamp(20rem, 46vh, 30rem); }
.chero__shot img { width: 100%; height: 100%; object-fit: cover; object-position: center 42%; }
/* Dissolves into the paper instead of butting against it with a hard seam.
   The mockup blends the same way; a straight edge here reads as a stock banner. */
.chero__shot::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to right,
    oklch(97.4% 0.006 95 / 1) 0%,
    oklch(97.4% 0.006 95 / 0.72) 18%,
    oklch(97.4% 0.006 95 / 0) 46%);
}

/* ── Shared section head ──────────────────────────────────
   The centred caps line with a run of the key flanking each side. Used by the
   promises band and the service-area band; the hero above sets its own type
   because it is the only left-aligned block on the page. */
.expect__kicker,
.area__title {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: var(--space-sm);
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
/* The section-scale key. tokens.css allows exactly two scales — the
   full-width page band and this ~75px segment — and this is the segment,
   halved and mirrored so it flanks a line instead of underlining it. */
.keyflank {
  flex: none; width: 2.6rem; height: 11px;
  background-color: var(--color-accent-pale);
  -webkit-mask: var(--meander) repeat-x right center / 14px 11px;
          mask: var(--meander) repeat-x right center / 14px 11px;
}
.keyflank--flip { transform: scaleX(-1); }
/* The heads are flex rows holding two ornament spans; the site-wide meander
   ::after would land inside as a third child and break the centring. */
.expect__kicker::after,
.area__title::after,
.fit__title::after,
.promise__title::after,
.ask__title::after,
.area__head::after { content: none; }

/* ── The three ways people book us ────────────────────────
   Three separate tinted cards on plaster, not one band split by hairlines.
   The band version was built on 2026-08-09 around three round food plates,
   and hairlines were the only thing holding it together once the photographs
   came out — three columns of centred type on one flat ground with a 1px line
   between them is a table, not a set of cards. Separate blocks with plaster
   showing between them is the same separation done the way the tokens ask
   for it: ground colour and space, no rules. */
.fits {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-lg) var(--page-gutter) var(--space-2xl);
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-md);
}
.fit {
  display: grid; align-content: start; justify-items: center;
  background: var(--color-paper-2);
  padding: var(--space-xl) var(--space-lg) var(--space-lg);
  text-align: center;
}
.fit__ic { width: 2.4rem; height: 2.4rem; color: var(--color-accent); }
/* Script, and the only place on the page it carries a heading. These are the
   three names a customer is choosing between, so they are the one thing that
   should read as lettering rather than as a label. */
.fit__title {
  margin: var(--space-sm) 0 0;
  font-family: var(--font-display); font-weight: var(--weight-display);
  font-size: var(--text-xl); line-height: 1.12;
  color: var(--color-ink);
  text-wrap: balance;
}
.fit__for {
  margin: var(--space-2xs) 0 0;
  font-family: var(--font-body);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.fit__say {
  margin: var(--space-sm) 0 0; max-width: 32ch;
  font-size: var(--text-sm); line-height: 1.65;
  color: var(--color-ink-2);
  text-wrap: pretty;
}
.fit .checks { margin-top: var(--space-lg); }

/* ── Checklists ───────────────────────────────────────────
   Shared by the format cards and the "what we need" column.

   The mark is a ring with a tick in it, which is an OUTLINED circle, and the
   tokens ban outlines. It is allowed here for one reason: every other mark on
   this page is stroked line art at the same 1.4–1.6px weight, so the ring
   reads as a sibling of the truck and the umbrella rather than as a border.
   The ban is about boxing CONTENT — cards, tags, buttons — and it still holds
   for all of those. Do not take this as a licence to outline a panel.

   Both halves are drawn, not typed: a ✓ character sets at a different weight
   in every fallback font and drifts off the first line's baseline. */
.checks {
  list-style: none; padding: 0; margin: 0;
  display: grid; gap: var(--space-2xs);
  text-align: left;
}
.checks li {
  position: relative;
  padding-left: 1.75rem;
  font-size: var(--text-sm); line-height: 1.5;
  color: var(--color-ink-2);
}
.checks li::before {
  content: ""; position: absolute;
  left: 0; top: 0.16em;
  width: 1.05rem; height: 1.05rem; border-radius: 50%;
  box-shadow: inset 0 0 0 1.4px var(--color-accent);
}
.checks li::after {
  content: ""; position: absolute;
  left: 0.29rem; top: 0.44em;
  width: 0.46rem; height: 0.24rem;
  border-left: 1.6px solid var(--color-accent);
  border-bottom: 1.6px solid var(--color-accent);
  transform: rotate(-45deg);
}
/* The booking column's list is a form the customer is reading to prepare, not
   a set of examples, so it sets at reading size. */
.checks--lg li {
  padding-left: 2.1rem;
  font-size: var(--text-base); line-height: 1.6;
  margin-bottom: var(--space-3xs);
}
.checks--lg li::before { width: 1.2rem; height: 1.2rem; top: 0.14em; }
.checks--lg li::after { left: 0.34rem; top: 0.46em; width: 0.54rem; height: 0.28rem; }

/* ── What to expect ───────────────────────────────────────
   ONE tinted band, four columns on hairlines — the device the formats row
   gave up when it became three cards. It earns the hairlines here because
   these four are one statement read across, not four things to choose
   between: nothing in the row is clickable and no column stands alone. */
.expect {
  background: var(--color-paper-2);
  padding: var(--space-xl) var(--page-gutter) var(--space-2xl);
}
.expect__kicker { margin-bottom: var(--space-xl); }
.expect__row {
  max-width: var(--shell); margin: 0 auto;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
}
.promise { padding-inline: var(--space-md); text-align: center; }
/* Between the columns only. A rule on every column would box the band, and
   the band is meant to read as one object. */
.promise + .promise { border-left: var(--rule-hair) solid var(--color-accent-pale); }
.promise__ic { width: 2.2rem; height: 2.2rem; color: var(--color-accent); }
/* The truck is drawn in a 32×24 box, not 24×24 — a vehicle squeezed into a
   square either shrinks below the others or distorts. Wider, same height. */
.promise__ic--wide { width: 2.95rem; }
.promise__title {
  margin: var(--space-xs) 0 var(--space-2xs);
  font-family: var(--font-body);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-ink);
}
.promise p {
  margin: 0; max-width: 26ch; margin-inline: auto;
  font-size: var(--text-sm); line-height: 1.6;
  color: var(--color-ink-2);
  text-wrap: pretty;
}

/* ── The ask, and the booking ─────────────────────────────
   Two blocks with plaster between them and the seal set in the gap. They
   separate on GROUND — tinted on the left, the lighter surface on the right —
   rather than on an outline, because a bordered "book now" card is precisely
   the object the outline ban exists to prevent. */
.ask {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-2xl) var(--page-gutter);
}
.ask__inner {
  position: relative;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-2xl);
}
.ask__col {
  position: relative; min-width: 0;
  padding: var(--space-xl);
  text-align: center;
}
.ask__col--need { background: var(--color-paper-2); }
.ask__col--book {
  background: var(--color-surface);
  display: grid; align-content: center;
}
.ask__title {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
/* A short run of the key as a rule under the head — the section scale again,
   centred here because both heads are. */
.ask__key {
  display: block;
  width: 2.6rem; height: 11px;
  margin: var(--space-2xs) auto var(--space-md);
  background-color: var(--color-accent-pale);
  -webkit-mask: var(--meander) repeat-x left center / 14px 11px;
          mask: var(--meander) repeat-x left center / 14px 11px;
}
/* The list is left-ragged inside a centred column: centred list items with a
   mark on the left is the one thing that always looks broken. inline-grid
   keeps the BLOCK centred while its rows stay flush left. */
.ask__col--need .checks {
  display: inline-grid;
  justify-self: center;
  max-width: 30rem;
}
.ask__close {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-2xs);
  margin: var(--space-lg) 0 0;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--text-md); line-height: 1.2;
  color: var(--color-accent);
}
.ask__swoop { flex: none; width: 2.4rem; height: 1.5rem; }
.ask__lede {
  margin: 0 auto; max-width: 34ch;
  font-size: var(--text-base); line-height: 1.7;
  color: var(--color-ink-2);
  text-wrap: pretty;
}
.ask__act { margin: var(--space-lg) 0 0; }
/* The page's one primary action, so it takes a full-width tile rather than
   sitting as a small chip in the middle of an empty panel. */
.btn--wide { width: min(100%, 22rem); }
.ask__aside {
  margin: var(--space-sm) 0 0;
  font-size: var(--text-sm); color: var(--color-muted);
}

/* ── The seal, set in the gap between the two blocks ──────
   A THICK RING OF TWENTY GREEK-KEY UNITS. Read the note on .tzat__seal before
   touching this: three seal concepts were rejected on 2026-08-09 and a thin
   outer ring was the common factor every time — "common AI slop", and right,
   because a 1px circle inset from an empty edge is the default badge every
   generator draws. A band of the site's own ornament is a drawn object. A
   hairline around nothing is not.

   The disc under it is plaster, matching the page ground, so the seal reads
   as one mark laid across the seam rather than as a hole punched in it. */
.ask__seal {
  position: absolute; z-index: var(--z-raised);
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  display: grid; place-items: center;
  width: 7.4rem; height: 7.4rem;
  border-radius: 50%;
  background: var(--color-paper);
}
.ask__seal > svg { width: 100%; height: 100%; overflow: visible; }
.ask__seal-ring { color: var(--color-accent); }
.ask__seal-mark { color: var(--color-accent-2); overflow: visible; }

/* ── Where we deliver ─────────────────────────────────────
   Map, towns, contact — three columns on hairlines, the same device as the
   promises band and for the same reason: one statement read across. */
.area {
  background: var(--color-paper-2);
  padding: var(--space-xl) var(--page-gutter) var(--space-2xl);
}
.area__inner {
  max-width: var(--shell); margin: 0 auto;
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: var(--space-xl);
}
.area__map { position: relative; width: 7.2rem; flex: none; }
.area__fl { display: block; width: 100%; height: auto; fill: var(--color-accent-pale); }
/* Brevard is the mid-east coast. The pin is positioned to that point on the
   silhouette, not centred — a centred pin on a state outline says nothing. */
/* Translated so the pin's POINT sits on Brevard — the mid-east coast — rather
   than its bounding box. A pin whose box is positioned reads about 10px low. */
.area__pin {
  position: absolute; left: 94%; top: 43%;
  transform: translate(-50%, -88%);
  width: 1.7rem; height: 1.7rem;
  color: var(--color-accent);
}
.area__say {
  text-align: center;
  padding-inline: var(--space-xl);
  border-inline: var(--rule-hair) solid var(--color-accent-pale);
}
.area__towns {
  margin: var(--space-sm) auto 0; max-width: 44ch;
  font-size: var(--text-base); line-height: 1.9;
  color: var(--color-ink);
  text-wrap: pretty;
}
/* The separators are ornament, not punctuation — they step back so the town
   names carry the line. */
.area__town { white-space: nowrap; }
.area__dot { color: var(--color-muted); margin-inline: 0.45rem; }
.area__note {
  margin: var(--space-sm) auto 0; max-width: 46ch;
  font-size: var(--text-sm); line-height: 1.6;
  color: var(--color-ink-2);
}
.area__ask { text-align: left; }
.area__head {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.area__contact {
  list-style: none; padding: 0;
  margin: var(--space-sm) 0 0;
  display: grid; gap: var(--space-2xs);
}
.area__contact li {
  display: flex; align-items: center; gap: var(--space-2xs);
  font-size: var(--text-sm);
}
.area__contact svg { flex: none; width: 1.1rem; height: 1.1rem; color: var(--color-accent); }
.area__contact a { color: var(--color-ink); text-decoration: none; }
.area__contact a:hover { color: var(--color-accent); text-decoration: underline; }

/* The split hero stops splitting: below this the copy column is under 300px and
   the headline breaks after "Bring the", while the call button runs out of room
   for its own phone number. Copy first, then the photograph as a band — the
   left-to-right reading order of the mockup, turned top-to-bottom. */
@media (max-width: 52rem) {
  .chero { grid-template-columns: minmax(0, 1fr); }
  .chero__say {
    justify-self: stretch; max-width: none;
    padding: var(--space-xl) var(--page-gutter) var(--space-lg);
  }
  .chero__lede { max-width: 46ch; }
  .chero__shot { min-height: 0; aspect-ratio: 16 / 10; }
  /* The fade turns with the layout — a left-edge fade under a stacked column
     would lighten the wrong side of the picture. */
  .chero__shot::after {
    background: linear-gradient(to bottom,
      oklch(97.4% 0.006 95 / 1) 0%,
      oklch(97.4% 0.006 95 / 0.6) 9%,
      oklch(97.4% 0.006 95 / 0) 32%);
  }
}

/* The menu head is centred at every width, so it needs no stacking rule — only
   air taken back out of it, and a tab row that stops trying to fill a line it
   can no longer fill. */
@media (max-width: 64rem) {
  /* Three photographed cards run out of measure well before the viewport
     does — two up, then the third full width beneath, turned on its side. */
  .mpicks__inner { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mpicks__inner > :last-child {
    grid-column: 1 / -1;
    flex-direction: row; align-items: stretch;
  }
  /* The photo is taken OUT OF FLOW here, and it has to be. Left in flow at
     38% of a full-width card it is ~450px of 1:1 photograph, and since
     nothing else in the card is that tall the card grows to meet it — a
     500px-tall band holding two lines of text. Absolute inside a stretched
     flex item inverts that: the copy sets the height, the photo fills it. */
  .mpicks__inner > :last-child .mpick__shot {
    position: relative; flex: 0 0 38%; aspect-ratio: auto;
    /* On its side the rounded pair moves from top to left. */
    border-radius: calc(var(--menu-radius) - 1px) 0 0 calc(var(--menu-radius) - 1px);
  }
  .mpicks__inner > :last-child .mpick__shot img { position: absolute; inset: 0; }
  .mpicks__inner > :last-child .mpick__say { flex: 1 1 auto; align-content: center; }
}

@media (max-width: 52rem) {
  /* The masthead wraps to three rows on a phone and eats ~175px before the
     head even starts, so the head gives some of that back. */
  .mhead__aside { margin-top: var(--space-2xs); font-size: var(--text-base); }
  /* A seven-tab row becomes a scroller rather than four ragged lines. Growing
     to fill is what the wide layout wants and exactly what a scroller must
     not do, so the flex-grow comes back off here. */
  .mfilter__inner {
    flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none;
    /* The gutter is on .mfilter, so the scroller's own end needs padding or
       the last tab butts against the viewport edge mid-scroll. */
    scroll-padding-inline: var(--page-gutter);
  }
  .mfilter__inner::-webkit-scrollbar { display: none; }
  .mfilter__tab { flex: 0 0 auto; white-space: nowrap; }
}

/* One up. Everything the 64rem rule did to the third card comes back off —
   it is an ordinary vertical card again. */
/* Short windows — a 1280×720 laptop, a 1440×700 half-height window, a phone
   held sideways. The clamps above already scale the head, but at this height
   the leading and the tab row's own padding are the last places left to take
   the final ~50px from, and both cost nothing legible. */
@media (max-height: 46rem) {
  .mhead__aside { font-size: var(--text-base); }
  .mfilter__inner { padding-block: var(--space-2xs); }
  /* 44svh and 30rem, put through the same ×1.5217 as the base rule. */
  .mhead__cut { width: min(100%, 67svh, 45.65rem); }
}

@media (max-width: 40rem) {
  .mpicks__inner { grid-template-columns: minmax(0, 1fr); }
  .mpicks__inner > :last-child { grid-column: auto; flex-direction: column; }
  .mpicks__inner > :last-child .mpick__shot {
    position: static; flex: none; aspect-ratio: 16 / 10;
    border-radius: calc(var(--menu-radius) - 1px) calc(var(--menu-radius) - 1px) 0 0;
  }
  .mpicks__inner > :last-child .mpick__shot img { position: static; }
}

/* ── Catering · narrow ────────────────────────────────────
   Four promises across a tablet gives each column about eighteen characters,
   which breaks "appreciation" in half. Two by two instead, and the hairlines
   turn with them: the rule between columns 1|2 and 3|4 stays vertical, the
   one between the rows becomes horizontal. */
@media (max-width: 64rem) {
  .expect__row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .promise { padding-block: var(--space-md); }
  .promise + .promise { border-left: 0; }
  .promise:nth-child(even) { border-left: var(--rule-hair) solid var(--color-accent-pale); }
  .promise:nth-child(n + 3) { border-top: var(--rule-hair) solid var(--color-accent-pale); }

  /* The map column is the first thing to go: a 6.6rem silhouette beside two
     squeezed text columns is a decoration taking a third of the row. The
     towns and the phone number are the content. */
  .area__inner { grid-template-columns: minmax(0, 1fr) auto; }
  .area__map { display: none; }
  .area__say { border-inline-start: 0; padding-inline-start: 0; }
}

/* Three format cards run out of measure well before the viewport does. Two up,
   then the third full width beneath — and the third keeps its own centring
   rather than stretching its paragraph across the whole row. */
@media (max-width: 60rem) {
  .fits { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .fits > :last-child { grid-column: 1 / -1; }

  /* The two booking blocks stop being a pair and become a stack. The seal goes
     with them: it is a mark set ON a seam, and once the seam is horizontal it
     would sit in the middle of the reading column, dividing the one thing the
     page is asking the customer to do. */
  .ask__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); }
  .ask__seal { display: none; }
}

@media (max-width: 44rem) {
  .fits { grid-template-columns: minmax(0, 1fr); max-width: 30rem; }
  .fits > :last-child { grid-column: auto; }

  .expect__row { grid-template-columns: minmax(0, 1fr); max-width: 26rem; margin-inline: auto; }
  .promise:nth-child(even) { border-left: 0; }
  .promise:nth-child(n + 2) { border-top: var(--rule-hair) solid var(--color-accent-pale); }

  /* The contact column drops under the towns rather than beside them, and
     centres with everything else once it is no longer a side column. */
  .area__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .area__say { border-inline: 0; padding-inline: 0; }
  .area__ask { text-align: center; }
  .area__contact li { justify-content: center; }

  .ask__col { padding: var(--space-lg) var(--space-md); }
}

/* ── Why people come back · and where to find us ──────────
   Built to Marcus's second mockup (2026-08-09). Replaces the WHERE / WHEN /
   ORDER AHEAD panels — three equal tinted boxes, one of which was a seven-row
   timetable. It answered "when are you open" competently and "why would I go"
   not at all, which is the wrong job for the last screen before the footer.

   Continues the printed-card grammar the menu section above now uses:
   ornamented centred head, hairline frames, line art, no photographic
   furniture beyond the one portrait that carries the whole argument.

   SECOND SCOPED DEPARTURE from the NO-OUTLINES rule in tokens.css, same
   reasoning as the menu card: the plaque and the quote card are framed printed
   objects and the frame is the form. Everywhere else on the site, separation
   is still a change of ground colour. */
.here {
  position: relative;
  padding: var(--space-3xl) var(--page-gutter);
  overflow: hidden;                      /* the olive branch bleeds off-page */
}
.here__inner {
  position: relative;
  max-width: var(--shell); margin-inline: auto;
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--space-2xl);
  align-items: start;
}

/* ── Left · the reason ─────────────────────────────────── */
.here__say { text-align: center; }
.here__crest { width: 2.6rem; height: auto; color: var(--color-accent); }

/* Flanking hairlines are ::before/::after on a flex container, so they become
   flex items and shrink with the line instead of overrunning it. */
.here__kicker {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-sm);
  margin: var(--space-xs) 0 var(--space-sm);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.here__kicker::before,
.here__kicker::after {
  content: "";
  flex: 0 1 4.5rem; min-width: 0.75rem;
  height: var(--rule-hair);
  background: var(--color-accent); opacity: 0.45;
}
/* Caps tracking adds a trailing space that reads as an off-centre gap. */
.here__kicker span { margin-right: calc(var(--track-caps) * -1); }

/* The display face, slanted, like the menu card's masthead. Every page
   masthead now speaks in the truck's lettering; the body face carries
   everything underneath it. */
.here__title {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-display);
  line-height: 1.04;
  max-width: 15ch; margin-inline: auto;
  text-wrap: balance;
}
.here__flourish {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-xs);
  margin: var(--space-md) 0 0;
}
.here__flourish::before,
.here__flourish::after {
  content: "";
  flex: 0 1 4rem; min-width: 0.75rem;
  height: var(--rule-hair);
  background: var(--color-accent); opacity: 0.45;
}
.here__flourish svg { width: 1.9rem; height: auto; color: var(--color-accent); }
.here__sub {
  margin: var(--space-md) auto 0; max-width: 34ch;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  line-height: 1.85; color: var(--color-accent-2);
  text-wrap: balance;
}
.here__sub span { display: inline-block; }

/* ── The quote card ────────────────────────────────────────
   The mockup fills this with an invented five-star review signed by a customer
   who does not exist. What sits here instead is the one piece of social proof
   that is real and independently checkable, plus the portrait: the 4.9 score
   and a link out to the real Google listing. */
.voice {
  margin: var(--space-2xl) 0 0;
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  gap: var(--space-lg);
  align-items: center;
  padding: var(--space-md);
  background: var(--color-surface);
  border: var(--rule-hair) solid var(--color-rule);
  text-align: left;
}
/* `maria-window.jpg` is a 9:16 phone portrait in a square slot, so cover keeps
   only ~56% of its height. 40% pulls the window up onto Maria and off the
   counter and card reader along the bottom — at plain `center` the tray takes
   the lower third of the frame. Re-check this if the photograph is replaced;
   the value is tied to where she stands in THIS one. */
/* The source is now pre-cropped SQUARE and tight on Maria (480x480 out of the
   supplied 574x1020 phone portrait), so there is nothing left for
   object-position to do — a second crop on top of the first only re-introduces
   the counter. Marcus asked for it closer on 2026-08-09; the zoom lives in the
   file, which also stops the browser throwing away two thirds of the pixels. */
.voice__shot {
  display: block; width: 100%;
  aspect-ratio: 1 / 1; object-fit: cover;
}
.voice__say { margin: 0; }
.voice__stars { display: flex; gap: 0.2rem; margin: 0; }
.voice__stars svg { width: 1.2rem; height: 1.2rem; color: var(--color-accent); }
.voice__score {
  margin: var(--space-xs) 0 0;
  font-family: var(--font-body); font-weight: 500;
  font-size: var(--text-md);
  line-height: 1.1; color: var(--color-ink);
}
.voice__score strong { font-weight: 400; font-size: 1.9em; }
.voice__from { margin: var(--space-2xs) 0 0; color: var(--color-ink-2); }
.voice__who {
  margin: var(--space-md) 0 0; padding-top: var(--space-sm);
  border-top: var(--rule-hair) solid var(--color-rule);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}

/* ── The plaque ────────────────────────────────────────────
   Two crossing pairs of hairlines instead of one border, which leaves each
   corner open the way a printed plaque's does. The mockup notches its corners;
   an open corner is the same gesture and needs no mask, so it survives print
   and forced-colours intact. */
.plaque {
  position: relative;
  padding: calc(var(--space-2xl) + var(--space-sm)) var(--space-lg) var(--space-xl);
  text-align: center;
}
.plaque::before,
.plaque::after {
  content: ""; position: absolute; pointer-events: none;
  border: var(--rule-hair) solid var(--color-accent-pale);
}
.plaque::before { inset: 0 1.4rem; border-width: var(--rule-hair) 0; }
.plaque::after  { inset: 1.4rem 0; border-width: 0 var(--rule-hair); }

.plaque__crest {
  position: absolute; top: var(--space-3xs); right: var(--space-2xs);
  width: clamp(4.5rem, 8vw, 6.5rem); height: auto;
  color: var(--color-accent); opacity: 0.4;
  pointer-events: none;
}
/* Held clear of the crest above so the two never collide as the column narrows. */
.plaque__kicker,
.plaque__name,
.plaque__sub { position: relative; max-width: 24ch; margin-inline: auto; }
.plaque__kicker {
  margin-top: 0; margin-bottom: var(--space-xs);
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-ink-2);
}
.plaque__name {
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-xl); line-height: 1.1;
}
.plaque__sub {
  max-width: none;
  margin: var(--space-2xs) auto 0;
  font-size: var(--text-xs); font-weight: 800;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.plaque__rule {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-sm);
  margin: var(--space-lg) 0 0;
}
.plaque__rule::before,
.plaque__rule::after {
  content: "";
  flex: 1 1 auto; min-width: 1rem;
  height: var(--rule-hair);
  background: var(--color-accent); opacity: 0.4;
}
.plaque__rule svg { width: 1.5rem; height: 1.5rem; flex: none; color: var(--color-accent); }

.plaque__facts {
  list-style: none; margin: var(--space-lg) 0 0; padding: 0;
  display: grid; gap: var(--space-md);
  text-align: left;
}
.plaque__facts li {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-sm); align-items: start;
}
.plaque__ic { width: 1.5rem; height: 1.5rem; flex: none; margin-top: 0.15em; color: var(--color-accent); }
/* Serif for the three things people read in order to act on them — the address
   they drive to, the hours they plan around, the number they dial. */
.plaque__facts address,
.plaque__facts b {
  display: block;
  font-style: normal; font-weight: 500;
  font-family: var(--font-body); font-size: var(--text-base);
  line-height: 1.45; color: var(--color-ink);
}
.plaque__tel {
  font-family: var(--font-body); font-weight: 600;
  font-size: var(--text-md);
  color: var(--color-accent); text-decoration: none;
  box-shadow: inset 0 -1px 0 var(--color-accent-pale);
  transition: box-shadow var(--dur-short) var(--ease-out);
}
.plaque__tel:hover { box-shadow: inset 0 -2px 0 var(--color-accent); }
.plaque__aside {
  display: block; margin-top: var(--space-3xs);
  font-size: var(--text-sm); line-height: 1.5; color: var(--color-muted);
}
.plaque__go {
  display: flex; width: 100%;
  margin-top: var(--space-lg);
  gap: var(--space-2xs);
}
.plaque__go svg { width: 1.15rem; height: 1.15rem; flex: none; }
.plaque__foot {
  margin: var(--space-sm) 0 0;
  font-size: var(--text-sm); line-height: 1.5; color: var(--color-muted);
}

.here__olive {
  display: block;
  width: clamp(12rem, 22vw, 19rem); height: auto;
  margin: var(--space-md) calc(var(--page-gutter) * -0.6) 0 auto;
  color: var(--color-accent); opacity: 0.3;
}

/* ── Cross-page CTA ───────────────────────────────────── */
.cta { padding: var(--space-2xl) var(--page-gutter); background: var(--color-paper-2); }
/* On the menu page the board itself is already paper-2, so the closing band
   was dissolving into the bottom of the menu. Reversed to plaster, which is
   the same trick the panels use against the board. */
.board + .cta { background: var(--color-surface); }
.cta__inner {
  max-width: var(--shell); margin: 0 auto;
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: var(--space-xl);
}
.cta h2 { font-size: var(--text-xl); max-width: 18ch; }
.cta p { margin: var(--space-2xs) 0 0; max-width: 48ch; color: var(--color-ink-2); }
.cta__act { display: flex; flex-wrap: wrap; gap: var(--space-sm); }

/* The closing strip, to the mockup: a column ornament at each end with a
   hairline running out toward the page edge, the line and the button between
   them. Scoped to the modifier — menu.html still uses the plain .cta. */
.cta--strip .cta__inner {
  grid-template-columns: minmax(0, 1fr) auto auto minmax(0, 1fr);
  gap: var(--space-lg);
  justify-items: center;
}
.cta--strip .cta__say { text-align: center; }
/* Title case, NOT the mockup's all-caps. A leaning display face set in caps
   turns into a shout — that is written into tokens.css and it is why this
   build stopped shouting. Inherits the display face from the h1,h2 rule. */
.cta--strip .cta__say h2 {
  font-size: var(--text-lg);
  line-height: 1.15; max-width: none;
}
.cta--strip .cta__say p {
  margin-top: var(--space-2xs); max-width: none;
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent);
}
.cta__orn { display: flex; align-items: center; gap: var(--space-sm); width: 100%; }
.cta__orn::before {
  content: ""; flex: 1 1 auto; min-width: 1rem;
  height: var(--rule-hair); background: var(--color-accent); opacity: 0.4;
}
.cta__orn svg { width: 1.6rem; height: 1.6rem; flex: none; color: var(--color-accent); }
/* Mirrored so the hairline always runs toward the outside of the page. */
.cta__orn--end { flex-direction: row-reverse; }

/* ── Gallery ──────────────────────────────────────────────
   A uniform crop grid, NOT masonry.
   Masonry was tried to preserve each photo's true aspect ratio, but eight
   mixed-ratio images balanced badly: one hung below the others and left a
   large dead area. A span grid was tried before that and left holes.
   Cropping here is acceptable precisely because the lightbox shows the full,
   uncropped image — the grid is an index, not the presentation. Eight items
   fill 4, 2 or 1 columns exactly, and 3 columns leaves a tidy short row. */
.gallery {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-xl) var(--page-gutter) var(--space-3xl);
  display: grid;
  /* Fixed 3 across, not auto-fit: six photos then divide exactly at every
     breakpoint (3x2 / 2x3), so the last row is never short. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-2xs);
}
.shot {
  position: relative; display: block; width: 100%;
  overflow: hidden; background: var(--color-paper-2);
  border: 0; padding: 0; cursor: pointer;
}
.shot img {
  width: 100%; height: 100%;
  aspect-ratio: 4 / 3; object-fit: cover;
  transition: opacity var(--dur-short) var(--ease-out);
}
.shot:hover img, .shot:focus-visible img { opacity: 0.86; }
.shot__cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--space-lg) var(--space-sm) var(--space-sm);
  font-size: var(--text-sm); color: var(--color-onphoto); text-align: left;
  background: linear-gradient(to top, var(--color-scrim), transparent);
  opacity: 0; transition: opacity var(--dur-short) var(--ease-out);
}
.shot:hover .shot__cap, .shot:focus-visible .shot__cap { opacity: 1; }

/* ── Lightbox ─────────────────────────────────────────── */
body.is-locked { overflow: hidden; }
.lightbox {
  position: fixed; inset: 0; z-index: var(--z-skip);
  display: grid; grid-template-rows: auto 1fr auto;
  background: oklch(19% 0.055 248);      /* opaque: nothing reads through */
  padding: var(--space-sm);
}
.lightbox[hidden] { display: none; }
.lightbox__bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-sm);
  color: var(--color-onphoto-2);
  font-size: var(--text-sm); letter-spacing: 0.08em;
}
.lightbox__stage { display: grid; place-items: center; min-height: 0; padding: var(--space-sm) 0; }
.lightbox__stage img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.lightbox__foot {
  display: flex; align-items: center; justify-content: center;
  gap: var(--space-md); min-height: 2.5rem;
  color: var(--color-onphoto);
  font-family: var(--font-body); font-size: var(--text-base); text-align: center;
}
.lightbox__btn {
  appearance: none; border: 0;
  background: oklch(100% 0 0 / 0.12); color: var(--color-onphoto);
  font: inherit; font-family: var(--font-body);
  font-size: var(--text-sm); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  padding: var(--space-2xs) var(--space-sm);
  min-height: 44px; cursor: pointer;
  transition: background var(--dur-short) var(--ease-out);
}
.lightbox__btn:hover { background: oklch(100% 0 0 / 0.24); }

/* ── Reviews ──────────────────────────────────────────────
   4.9 from 187 is the strongest asset this business has. It gets the left
   half of the band at full display size rather than being a line of body
   copy — and it fills a band that was previously half empty. */
.praise {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  gap: var(--space-3xl); align-items: center;
}
.praise__score { text-align: center; }
.praise__say { max-width: 46ch; }
.praise__say h2 { margin-bottom: var(--space-md); }
/* Serif figures — script numerals are hard to scan at a glance. */
.rating__score {
  /* Body face at 800. A display figure this large reads as a price on a sign,
     and this is a rating people are meant to trust. */
  font-family: var(--font-body); font-weight: 800;
  font-size: clamp(4rem, 9vw, 7rem); line-height: 0.86;
  color: var(--color-onphoto); margin: 0;
}
.rating__stars {
  color: var(--color-accent-pale); font-size: var(--text-lg);
  letter-spacing: 0.18em; margin: var(--space-2xs) 0 var(--space-3xs);
}
.rating__count {
  font-size: var(--text-xs); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-onphoto-2); margin: 0;
}

/* ── Footer ───────────────────────────────────────────── */
.foot {
  background: var(--color-deep); color: var(--color-onphoto-2);
  padding: 0 0 var(--space-lg);
}
/* NO BAND HERE. There was one — a pale "closing bookend" to the masthead's
   opening band — and Marcus cut it on 2026-08-09, right after cutting the
   second masthead run for the same reason. Which is what the note at the top
   of this file prescribed all along: deep navy meeting plaster is already
   maximum contrast, and the footer needs no ornament to separate it. The
   meander is now a masthead device and nothing else. Do not restore it. */
.foot__top {
  max-width: var(--shell); margin: 0 auto var(--space-xl);
  padding: var(--space-2xl) var(--page-gutter) 0;
  display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: var(--space-xl); align-items: start;
}
.foot__brand {
  /* The brand name set as the brand. */
  font-family: var(--font-display);
  font-weight: var(--weight-display);
  font-size: var(--text-lg);
  color: var(--color-onphoto); text-decoration: none; line-height: 1.1;
}
.foot__blurb {
  margin: var(--space-sm) 0 var(--space-md);
  max-width: 34ch; font-size: var(--text-sm); line-height: 1.65;
}
.foot__head {
  font-family: var(--font-body); font-weight: 700;
  font-size: var(--text-xs); letter-spacing: var(--track-caps); text-transform: uppercase;
  color: var(--color-accent-pale);
  margin: 0 0 var(--space-sm);
  padding-bottom: var(--space-2xs);
  border-bottom: var(--rule-hair) solid oklch(100% 0 0 / 0.22);
}
.foot__list { list-style: none; margin: 0; padding: 0; font-size: var(--text-sm); }
.foot__list li { margin-bottom: var(--space-2xs); line-height: 1.5; }
.foot__list a, .foot__tel {
  color: var(--color-onphoto); text-decoration: none;
  transition: color var(--dur-short) var(--ease-out);
}
.foot__list a:hover, .foot__tel:hover { color: var(--color-accent-pale); }
.foot address { font-style: normal; font-size: var(--text-sm); line-height: 1.65; margin-bottom: var(--space-sm); }
.foot__hours { font-size: var(--text-sm); line-height: 1.75; }
.foot__hours strong { color: var(--color-onphoto); font-weight: 700; }
.foot__legal {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-md) var(--page-gutter) 0;
  border-top: var(--rule-hair) solid oklch(100% 0 0 / 0.18);
  font-size: var(--text-sm); line-height: 1.9;
  color: oklch(74% 0.014 232);
}
.foot__legal p { margin: 0; }
.foot__name { font-weight: 600; color: var(--color-onphoto); }
.foot__sep { padding: 0 var(--space-2xs); color: oklch(100% 0 0 / 0.3); }

/* ── Agency credit ────────────────────────────────────────
   Marcus's byline. It is a credit, not an advert: it sits below the legal
   line, at the smallest size on the site, at 70% — and only comes up to full
   on hover. If it ever competes with the client's own name in that footer it
   has been made too loud. */
.foot__by {
  max-width: var(--shell); margin: 0 auto;
  padding: var(--space-sm) var(--page-gutter) 0;
  text-align: center;
}
.byline {
  display: inline-flex; align-items: center; gap: 0.55em;
  /* Padding is for the finger, not the look — the label alone is a 16px-tall
     target, well under the 24px minimum. */
  padding: var(--space-2xs) var(--space-2xs);
  font-size: var(--text-xs); font-weight: 600; letter-spacing: 0.05em;
  color: var(--color-onphoto-2); text-decoration: none;
  opacity: 0.7;
  transition: opacity var(--dur-short) var(--ease-out);
}
/* The fedora alone. The full lockup carries a "DIGITAL PARTNER" wordmark that
   is illegible under ~60px, and this runs at 18. Height-driven so the mark
   scales with the type rather than to a pixel count. */
.byline__mark { display: block; width: auto; height: 1.15rem; }
.byline:hover { opacity: 1; }
.byline:focus-visible { outline: 2px solid var(--color-focus); outline-offset: 3px; opacity: 1; }

/* ── Sticky call bar · narrow viewports ───────────────── */
.callbar {
  position: fixed; z-index: var(--z-bar); inset: auto 0 0 0;
  display: none; align-items: center; justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-2xs) var(--space-sm);
  padding-bottom: max(var(--space-2xs), env(safe-area-inset-bottom));
  background: var(--color-paper);
  border-top: var(--rule-thin) solid var(--color-accent);
  transform: translateY(100%);
  transition: transform var(--dur-short) var(--ease-out);
}
.callbar.is-up { transform: translateY(0); }
.callbar__note { font-size: var(--text-sm); font-weight: 600; color: var(--color-ink-2); line-height: 1.3; }
.callbar__btn {
  flex: none; white-space: nowrap;
  min-height: 46px; display: inline-flex; align-items: center;
  padding: 0 var(--space-md);
  background: var(--color-accent); color: var(--color-accent-ink);
  font-size: var(--text-sm); font-weight: 700;
  letter-spacing: var(--track-caps); text-transform: uppercase;
  text-decoration: none;
  transition: background var(--dur-short) var(--ease-out);
}
.callbar__btn:hover { background: var(--color-accent-2); }


/* ═══════════════════════════════════════════════════════════════════════
   ORNAMENT
   Craft, not decoration. Everything here is either a material quality
   (plaster grain, glaze lattice) or classical menu typography (leader dots,
   double rule, drop cap). Nothing is a motif applied for its own sake —
   that is the line between "ceramic" and "souvenir".
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Plaster grain ────────────────────────────────────────
   A fixed 3% noise film over the whole page. Two jobs: it gives the flat
   grounds the tooth of limewashed plaster, and it lays a common grain over
   photographs of very different quality, which pulls the scraped listing
   images and the real phone shots into one surface. */
body::after {
  content: "";
  position: fixed; inset: 0; z-index: var(--z-overlay);
  pointer-events: none;
  opacity: 0.02;   /* pulled back — noise reads stronger on the dark bands */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}


/* ── Leader dots ──────────────────────────────────────────
   The oldest ornament in menu setting, and a functional one — it carries the
   eye from a dish to its price across a wide column. The dots grow to fill
   whatever gap is left, so they work at every width. */
.list__item {
  display: flex; align-items: baseline;
  gap: 0 0.45em;
  /* basis 0, NOT auto. A flex line breaks on the items' base sizes, so with
     `auto` the browser compares the dish's full natural width against the
     column and drops the price to a line of its own — never giving min-width:0
     the chance to shrink it. At 0 the pair always shares one line and the name
     wraps to a second line instead, which is what a printed menu does. Grows to
     fill either way, so nothing changes on a wide column. */
  flex: 1 1 0;
}
.list__item::after {
  content: "";
  flex: 1 1 auto;
  min-width: 1.25em;
  align-self: baseline;
  border-bottom: 1px dotted var(--color-rule);
  transform: translateY(-0.3em);
}
/* No leader where there is no price to lead to. */
.list li:not(:has(.list__price)) .list__item::after { display: none; }

/* ── Double rule ──────────────────────────────────────────
   Two lines under a section name, the way a printed menu or a tile border
   band is set. A single 2px rule read like a UI divider. */
.grp__title {
  border-bottom: 4px double var(--color-accent);
  padding-bottom: var(--space-xs);
}

/* ── Drop cap ─────────────────────────────────────────────
   On the story only. */

/* ── Lozenge, for the footer's inline separators ────────── */
.foot__sep { font-size: 0.7em; vertical-align: 0.15em; }

/* ── Responsive ───────────────────────────────────────── */

/* Breakpoints here are measured, not guessed. The binding row is "Spinach Pie
   Platter  VEG ⋯ $16", which needs 280px of column measure before the price
   drops to a line of its own and reads as a stray $16. With a 64px gutter that
   puts three columns at 1052px and two at 678px; both are rounded up for slack.
   The 68rem block comes BEFORE the 44rem one so the single stack still wins. */
@media (max-width: 68rem) {
  .breadth { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* The spit banners across the top — it is the thing she actually sells, so it
     leads rather than sharing a row. The rule belongs on ITS bottom edge, not on
     the tops of the two columns below: as two separate border-tops the line came
     out broken in the middle by the column gutter. */
  .breadth__col:nth-child(1) {
    grid-column: 1 / -1;
    padding-bottom: var(--space-xl);
    border-bottom: var(--rule-hair) solid var(--color-rule);
  }
  /* Its four rows run two-up on the same grid as the columns beneath. Left full
     width they dragged a leader nearly 900px from the dish to its price, which
     stops reading as a menu row; this also lines the halves up with the two
     columns below them. */
  .breadth__col:nth-child(1) .list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: calc(var(--space-lg) * 2);
  }
  .breadth__col:nth-child(2) { border-left: 0; margin-left: 0; padding-left: 0; }
  .breadth__col:nth-child(2),
  .breadth__col:nth-child(3) { padding-top: var(--space-xl); }

  /* Same measured logic as the columns above: "Indian Harbour Beach, FL 32937"
     set in the body face wants ~255px, so the plaque needs ~360px of content,
     and the
     1/2.5 track stops supplying that at about 1060px. Stacking one step early
     is cheaper than a three-line address. */
  .here__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-xl); }
  /* Full bleed leaves both cards sparse — a 1180px-wide plaque holding three
     short rows, and a quote card whose text ends halfway. Matched widths so the
     two stacked cards read as a pair. */
  .voice, .plaque { max-width: 38rem; margin-inline: auto; }
}

@media (max-width: 60rem) {
  /* Higher specificity than the base rule, so it needs restating here. */
  .cta--strip .cta__inner { grid-template-columns: minmax(0, 1fr); }
  .cta__orn { display: none; }        /* two ornaments and no rail to hang on */
  /* Measured, not chosen: the text track needs ~26rem before "Home of Maria's
     famous tzatziki" drops to four script lines, and the 0.54 share of the
     shell stops supplying that at about 960px once the seam padding comes out.
     The four-track bleed grid collapses to one column here, so both children
     have to be released from their explicit tracks or they stay in tracks 2
     and 3 of a one-track grid. */
  .tzat { grid-template-columns: minmax(0, 1fr); }
  .tzat__shot, .tzat__say { grid-column: 1; }
  .tzat__shot { padding: 0 var(--page-gutter); }
  /* Stacked there is no seam to straddle, so it tucks back inside the cut-out's
     own box instead of hanging off the right edge of the page. */
  .tzat__seal { right: var(--page-gutter); bottom: 0; transform: none; }
  .tzat__say {
    padding: var(--space-lg) var(--page-gutter) 0;
  }
  .tzat__title { max-width: 18ch; }
  /* Two-up. The row gap is deliberately tighter than the column gap: the band
     is inside the hero now and every row it grows is a row the photograph
     loses, so the two lines sit close and the dividers do the separating. */
  .proof__list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-md); }
  .proof__list li:nth-child(odd) { border-left: 0; }
  .proof__list li:nth-child(3) { border-left: 0; }
  .hero__proof { padding-block: var(--space-sm) var(--space-md); }
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .board__cols { grid-template-columns: minmax(0, 1fr); }
  .cta__inner { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .praise { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .praise__score { text-align: left; }
  .foot__top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-lg); }
  .foot__col:first-child { grid-column: 1 / -1; }
  /* The floor of this box is now the top of the proof band rather than the
     bottom of the screen, so it gives back most of its lower air. */
  .hero__inner { padding-block: var(--space-2xl) var(--space-lg); }
}

/* 678px is where two columns run out of measure, so the stack starts at 44rem
   rather than sharing the 40rem block below — between 640 and 678 a two-up
   layout was still nominally in force and orphaning prices. */
@media (max-width: 44rem) {
  /* A PHONE NEEDS ITS OWN SCRIM, and this is not laziness about one number.
     On desktop the copy sits in the lower third where the ramp is already
     heavy. On a phone the same copy wraps to roughly twice the lines, so the
     headline ends up ~78% of the way UP the hero — where the desktop ramp has
     faded to almost nothing — and it lands on the white canopy. Measured, it
     was 2.53:1 there against a 3.0 bar.

     It can afford to be flatter and stronger here because a phone only ever
     sees ~33% of the photograph's width anyway: at that crop the picture is
     a texture, not a view, so holding it costs far less than it would at
     1440. Re-measure both widths if either ramp changes. */
  .hero::after {
    background: linear-gradient(to top,
      oklch(16% 0.052 248 / 0.80) 0%,
      oklch(16% 0.052 248 / 0.76) 40%,
      oklch(16% 0.052 248 / 0.70) 70%,
      oklch(16% 0.052 248 / 0.40) 88%,
      oklch(16% 0.052 248 / 0.10) 100%);
  }
  /* One column. Every divider becomes a horizontal rule so the card still reads
     as a card and not as three unrelated lists. */
  .breadth { grid-template-columns: minmax(0, 1fr); margin-top: var(--space-xl); }
  .breadth__col,
  .breadth__col:nth-child(1),
  .breadth__col:nth-child(2),
  .breadth__col:nth-child(3) {
    padding: var(--space-lg) 0; margin-left: 0; border-left: 0;
  }
  .breadth__col:nth-child(1) { padding-top: 0; border-top: 0; border-bottom: 0; }
  .breadth__col:nth-child(1) .list { display: block; }   /* undo the two-up above */
  .breadth__col + .breadth__col { border-top: var(--rule-hair) solid var(--color-rule); }
  /* Nothing sits beside the footnote now, so there is no floor to flush it to
     and the extra padding just opens a hole above it. */
  .breadth__foot { padding-top: var(--space-md); }

  /* The title wraps to two or three lines here, and a sprig sitting beside a
     wrapped block reads as debris left at the margin. Centred above it instead.
     The key runs are down to a couple of tiles by this width, so they go. */
  /* Measured: the one-row bar needs ~650px for two link groups either side of a
     script wordmark, so it holds all the way down to here rather than dropping
     to the stack at the first tablet breakpoint. Flex-wrap rather than a
     one-column grid, so the wordmark takes its own row and BOTH nav groups
     share the row under it — two rows, not three. */
  .mast__bar { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--space-2xs) var(--space-md); }
  .mast__name { flex: 1 0 100%; }
  .mast__nav--start ul, .mast__nav--end ul { justify-content: center; }

  .menuhead { grid-template-columns: minmax(0, 1fr); }
  .menuhead__key { display: none; }
  .menuhead__title { flex-direction: column; gap: var(--space-2xs); }

  /* The plaque's art stacks over and under the copy rather than shrinking to
     two illegible thumbnails either side of a 20ch measure. */
  .commune {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    padding: var(--space-lg) var(--space-md);
    gap: var(--space-md);
  }
  .commune__art { width: min(13rem, 60%); }
}

@media (max-width: 40rem) {
  .callbar { display: flex; }
  body { padding-bottom: 4.5rem; }             /* room for the bar */
  .gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .shot__cap { opacity: 1; }                   /* touch has no hover */
  .lightbox { padding-bottom: 5rem; }
  .foot__top { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .grp { padding: var(--space-md); }
  .plaque { padding: var(--space-2xl) var(--space-md) var(--space-lg); }
  .plaque__crest { width: 4rem; }        /* 2.6rem tall — clears the 4.5rem lead */
  /* Below this the text column runs under ~15ch and the score line breaks. */
  .voice { grid-template-columns: minmax(0, 1fr); }
  /* The file is a tight square now, so a 3:2 letterbox of it cuts Maria's head
     off. It stays square on a phone; the card is narrow enough there that a
     square photo is not too tall. */
  .voice__shot { aspect-ratio: 1 / 1; }
  .cta { padding-block: var(--space-xl); }
  .cta__act .btn { width: 100%; }
  .picks { padding-block: var(--space-2xl); }

  /* The hero is one screen on a phone as well, and a phone has roughly half
     the height to spend. Each line of the block steps down rather than any of
     it collapsing — the headline, the promise, the action and the four facts
     all still make the first view. */
  .hero__title { margin-bottom: var(--space-md); }
  .hero__sub { margin-bottom: var(--space-lg); }
  .hero__status { margin-top: var(--space-md); }
  /* A 163px column will not hold "750 E Eau Gallie Blvd" at 1.5rem, and four
     cells each wrapping to two lines makes the band taller than the headline
     block above it. Both lines step down so every cell stays one line. */
  .proof__list strong { font-size: var(--text-base); }
  .proof__list span { font-size: 0.6875rem; letter-spacing: 0.05em; }
}

/* At 320 the longest rows ran out of room and dropped their price to a line of
   its own, which reads as a stray $13 rather than a menu row. Four small claw-
   backs — pad, gap, leader minimum, price size — buy back the ~30px needed. */
@media (max-width: 24rem) {
  .breadth .list li { gap: 0 var(--space-2xs); }
  .breadth .list__item::after { min-width: 0.5em; }
  .breadth .list__price { font-size: var(--text-base); }
  .breadth .veg { font-size: 0.6875rem; letter-spacing: 0.06em; }
  .tzat__seal { width: 5.6rem; height: 5.6rem; font-size: 0.6875rem; }
  .tzat__seal svg { width: 1.1rem; }
  .kitchen, .slate { padding-block: var(--space-2xl); }
  .phead { padding-top: var(--space-xl); }
  .mast__nav ul { gap: var(--space-3xs) var(--space-2xs); }
  .mast__nav a { padding: var(--space-3xs) var(--space-2xs); letter-spacing: 0.08em; }
  .hero__facts { gap: var(--space-sm) var(--space-lg); }
  /* Stays two-up even at 320. One column is four rows, and four rows of facts
     inside a one-screen hero costs more height than the whole headline block. */
  .proof__list { gap: var(--space-sm) var(--space-md); }
  .proof__list strong { font-size: var(--text-base); }
  /* nowrap is a desktop device to clear the painted sign. On a phone there is
     no room for it, so let it wrap. */
  .hero__title { white-space: normal; font-size: clamp(1.75rem, 8vw, 2.4rem); }
  /* A LANDSCAPE photo in a portrait viewport is the opposite problem to the
     one this line used to solve: the binding axis flips, so only ~42% of the
     frame's WIDTH survives and the vertical bias stops mattering. The painted
     sign and the service window sit left of centre, around 36% across, so the
     crop is pulled that way — centred, it lands on the neighbouring lot. */
  .hero__shot img { object-position: 36% center; }
}

/* ── Short screens ────────────────────────────────────────
   Width is not the constraint here — height is. A 720-tall laptop and a phone
   held in landscape both have to carry the same four parts of the hero, so the
   block gives up its air rather than giving up a part. Last of the queries on
   purpose: it has to outrank the width tiers above, which set the same
   properties for tall phones. */
@media (max-height: 46rem) {
  .hero__inner { padding-block: var(--space-md) var(--space-sm); }
  .hero__title { margin-bottom: var(--space-sm); }
  .hero__sub { margin-bottom: var(--space-md); font-size: var(--text-base); }
  .hero__status { margin-top: var(--space-sm); }
  .hero__proof { padding-block: var(--space-xs) var(--space-sm); }
  /* The base scrim is bottom-weighted for a 700px hero. In half that height the
     copy rides up into the thin part of the gradient and lands on the painted
     sign unheld, so the hold moves up with it. The top stays open — the sky is
     still the best thing in this photograph. */
  .hero::after {
    background: linear-gradient(to top,
      oklch(16% 0.052 248 / 0.94) 0%,
      oklch(16% 0.052 248 / 0.9) 42%,
      oklch(16% 0.052 248 / 0.7) 68%,
      oklch(16% 0.052 248 / 0.3) 88%,
      oklch(16% 0.052 248 / 0.06) 100%);
  }
}

/* ── Motion / print ───────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 120ms !important;
  }
}

@media print {
  /* .hero__status is "Closed — back tomorrow at 10:30am". It is true for about
     an hour and it is a lie on paper, so it never prints. */
  .mast__nav, .callbar, .lightbox, .cta, .foot__top, .foot__by,
  .hero__act, .hero__status { display: none; }
  body { background: var(--color-print-paper); color: var(--color-print-ink); }
  .mast { position: static; }
  .mast::before { display: none; }
  .board, .grp, .picks, .pick, .voice { background: var(--color-print-paper); }
  /* The card is the one part of this page that genuinely wants to be printed,
     so it keeps its whole structure — dividers, leaders, plaque frame, line art
     — and only drops to ink on white. Rules stay translucent so they do not
     print heavier than the type they separate. */
  .menuhead__key,
  .breadth__cap::before, .breadth__cap::after { background-color: var(--color-print-ink); }
  .menuhead__title, .menuhead__sprig, .breadth__cap,
  .breadth .list__price, .breadth .veg, .commune__kicker,
  .menuhead__line, .breadth__foot, .commune__body { color: var(--color-print-ink); }
  .breadth__leaf, .commune__art { color: var(--color-print-ink); opacity: 0.55; }
  .breadth__col + .breadth__col { border-left-color: oklch(0% 0 0 / 0.3); }
  .breadth .list__item::after { border-bottom-color: oklch(0% 0 0 / 0.4); }
  .commune { border-color: oklch(0% 0 0 / 0.45); }
  .picks--board .picks__more { display: none; }

  /* The plaque prints for the same reason the menu card does — an address, a
     schedule and a phone number are exactly what someone puts on the fridge.
     The Get-directions button is the one thing paper cannot honour, so it goes. */
  .here__kicker::before, .here__kicker::after,
  .here__flourish::before, .here__flourish::after,
  .plaque__rule::before, .plaque__rule::after { background: var(--color-print-ink); opacity: 0.45; }
  .here__crest, .here__flourish svg, .plaque__crest,
  .plaque__ic, .plaque__rule svg, .voice__stars svg,
  .here__olive { color: var(--color-print-ink); }
  .here__kicker, .here__sub, .here__title, .plaque__kicker, .plaque__sub,
  .plaque__name, .plaque__tel, .plaque__aside, .plaque__foot,
  .voice__score, .voice__from, .voice__who { color: var(--color-print-ink); }
  .plaque::before, .plaque::after { border-color: oklch(0% 0 0 / 0.45); }
  .voice, .voice__who { border-color: oklch(0% 0 0 / 0.3); }
  .plaque__go { display: none; }
  /* Was never handled while this was a dark band, and a dark band prints as a
     solid rectangle of toner. Photograph and stamp go — a full-bleed half-page
     photo is the single most expensive thing on a printed page — and the two
     prices stay, because those are the reason anyone prints this at all. */
  .tzat {
    background: var(--color-print-paper); color: var(--color-print-ink);
    grid-template-columns: minmax(0, 1fr);
  }
  .tzat__shot, .tzat__tear { display: none; }
  .tzat { padding-block: 0; }
  .tzat__say { max-width: none; padding: var(--space-lg) 0; }
  .tzat__kicker, .tzat__title, .tzat__blurb,
  .tzat__rule svg { color: var(--color-print-ink); }
  .tzat__rule::after { background: var(--color-print-ink); opacity: 0.45; }

  .hero, .kitchen, .slate, .foot { background: var(--color-print-paper); color: var(--color-print-ink); }
  .hero::after, .hero__shot { display: none; }
  .hero__title, .hero__sub,
  .foot__legal, .foot__name { color: var(--color-print-ink); }
  /* A screen-height hero would burn most of a sheet on white space, and the
     proof strip is white type carried by a scrim that does not print. */
  .hero { min-height: 0; }
  .hero__inner { padding-block: var(--space-lg); }
  /* Both of these carry a glow to hold them off the photograph. There is no
     photograph on paper, so the glow is just a smudge around the letters. */
  .hero__title, .proof__list strong { text-shadow: none; }
  .proof__list strong { color: var(--color-print-ink); }
  .proof__list span { color: var(--color-print-ink); }
  /* Hairlines stay light so they do not print heavier than the type between. */
  .hero__proof { border-top-color: var(--color-rule); }
  .proof__list li + li { border-left-color: var(--color-rule); }
  /* Catering page. Same stance as the rest of the sheet: ink on white, no
     photographs, and no ornament that only exists to hold a layout together.
     With the plates gone every card is a single column of text, so the row
     goes two-up — three text columns on a 7in sheet is a 2in measure. */
  .mfilter, .mpicks, .mhead__plate, .mhead__sprig, .mhead__wave,
  .grp__badge, .cta__badge { display: none; }
  .mhead { padding: 0; background: var(--color-print-paper); }
  .mhead__say { max-width: none; padding-inline: 0; }
  .mhead__title, .mhead__aside, .mhead__where, .grp__title { color: var(--color-print-ink); }
  /* Catering. The seal and the Florida silhouette are the two marks here that
     exist only to be looked at, and a sheet someone has printed to hold while
     they call is not the place for either. */
  .chero__shot, .ask__seal, .area__map { display: none; }
  .chero { grid-template-columns: minmax(0, 1fr); }
  .chero__say { justify-self: stretch; max-width: none; padding-inline: 0; }
  .fits { padding-inline: 0; }
  .fit { padding: 0 0 var(--space-md); background: var(--color-print-paper); break-inside: avoid; }
  .expect, .area { padding-inline: 0; background: var(--color-print-paper); }
  .promise { break-inside: avoid; }
  .ask { padding-inline: 0; }
  .ask__inner { gap: var(--space-lg); }
  .ask__col { padding: 0; break-inside: avoid; }
  .ask__col--need, .ask__col--book { background: var(--color-print-paper); }
  .area__inner { grid-template-columns: minmax(0, 1fr) auto; }
  .area__say { border-inline-start: 0; padding-inline-start: 0; }
  .board__cols { grid-template-columns: 1fr 1fr; }
  /* .board__cols--two is multicol on screen, not grid, so grid-template-columns
     no longer reaches it — set the count the way the element is actually laid
     out or the whole 43-item menu prints as one long single file. */
  .board__cols--two { column-count: 2; }
  /* Do not let a group be torn across a sheet. */
  .grp { break-inside: avoid; }
}
