/* ==========================================================================
   Mayback's Pizza and Subs
   Rebuilt from the design language of the old Wix site: warm paper ground,
   crimson doing all the shouting, near-black grounding it. Square corners,
   hard shadows, an opaque panel over the hero photo rather than a scrim.
   Storefront awning, not modern-restaurant.

   Unlike the original this is genuinely responsive - one document, real
   breakpoints - rather than a 980px desktop grid plus a separate mobile DOM.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Self-hosted fonts. No Google CDN request - the files are in /fonts and are
   served from our own origin, so there is no third-party dependency and no
   extra DNS/TLS handshake on first paint.

   Jost ships as a variable font: all three weights are the same file, and the
   declared font-weight selects the instance. Archivo Black has one weight.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Archivo Black";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/archivo-black-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jost-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jost-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jost-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* latin-ext covers accented characters we do not currently use, but keeps
   a name like "Jalapeño" from falling back to a system font. */
@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jost-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jost-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: "Jost";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/jost-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */

/* Two palettes. DARK is the default - it is what ships to anyone who has not
   expressed a preference. LIGHT comes back for devices set to light mode, which
   is most phones in daylight and most older users' defaults.

   Not everything flips. Three surfaces are dark in BOTH schemes because they sit
   on top of photography and have to hold their own against it: the hero panel,
   the CTA band, and the photo caption bars. Those read from --panel / --band-bg /
   --on-dark rather than from --bg / --text, which is why swapping the palette
   does not turn their labels inside out. */

:root {
  color-scheme: dark;

  /* -- brand, identical in both schemes ---------------------------------- */
  --crimson: #B21A34;           /* the action colour */
  --on-crimson: #FFFFFF;        /* label on a crimson fill */

  /* -- always dark: surfaces that sit over photography ------------------- */
  --panel: #121110;             /* the opaque panel over the hero photo */
  --band-bg: #1F1D1B;           /* CTA band */
  --caption-bg: rgba(15, 14, 13, 0.94);
  --spine-bg: #211E1B;          /* the card's vertical label strip */
  --call-bg: #2A2724;           /* the sticky bar's Call button - opaque on purpose */
  --on-dark: #F2EFEA;           /* text on any of the above */
  --on-dark-dim: #BCB5AC;       /* secondary text on those - 9.29:1 on --panel */

  /* -- scheme-dependent -------------------------------------------------- */
  --crimson-hover: #D42342;     /* on dark, hover BRIGHTENS - darkening reads as
                                   the control switching off */
  --btn-edge: #D42342;          /* crimson fill is 2.7:1 on this ground, short of
                                   the 3:1 a control boundary needs, so the edge
                                   does the separating */

  --bg: #141312;                /* page ground - warm near-black, not #000 */
  --surface: #1F1D1B;           /* raised: header, info boxes */
  --surface-2: #2A2724;         /* nav hover */

  --edge: #383430;              /* hairlines */
  --edge-strong: #6E6862;       /* ghost outline - a real 3:1 boundary here */

  --text: #F2EFEA;              /* warm off-white, NOT pure white: #FFF on
                                   near-black haloes for older eyes */
  --text-dim: #BCB5AC;

  /* Photos are all shot on bright white. On this ground they need a frame to
     step the luminance down and a weak vignette to stop the outer edge
     glowing. On paper neither is needed - see the light block. */
  --photo-frame: #6E6862;
  --photo-vignette: 0.18;
  --photo-shadow: none;

  /* Ghost buttons are outlined here; a light fill would be a second bright
     rectangle competing with the photography. */
  --ghost-bg: transparent;
  --ghost-border: #6E6862;
  --ghost-hover-bg: #2A2724;

  /* The footer is a raised surface with a crimson stripe, not a crimson slab:
     on a dark page the slab was the most saturated thing on screen, at the
     bottom, competing with the order buttons. */
  --footer-bg: #1F1D1B;
  --footer-text: #F2EFEA;
  --footer-stripe: 5px solid #B21A34;
  --footer-icon-bg: #2A2724;
  --footer-icon-border: #383430;

  /* Sticky order bar. Only the BAR is translucent; both buttons on it are
     opaque, so their label contrast is fixed no matter what scrolls behind. */
  --bar-bg: rgba(20, 19, 18, 0.72);
  --bar-bg-solid: #141312;      /* used where backdrop-filter is unsupported */
  --bar-edge: rgba(255, 255, 255, 0.14);

  /* Elevation is a hairline of light: a black drop shadow is invisible here. */
  --shadow: 0 0 0 1px rgba(255, 255, 255, 0.09), 0 2px 6px rgba(0, 0, 0, 0.55);
  --shadow-soft: 0 0 0 1px rgba(255, 255, 255, 0.06);

  /* -- type and layout, identical in both -------------------------------- */
  --display: "Archivo Black", "Arial Black", system-ui, sans-serif;
  --body: "Jost", "Century Gothic", "Futura", system-ui, -apple-system, sans-serif;
  --rail: 980px;
  --gutter: 20px;
  --tap: 44px;                  /* the old site's nav was 22px */
}

@media (prefers-color-scheme: light) {
  :root {
    color-scheme: light;

    /* Hover DARKENS on paper - the reverse of the dark scheme. */
    --crimson-hover: #761122;
    /* Crimson is 6.2:1 against paper, well past the 3:1 a boundary needs, so
       the button needs no separating edge. Matching the fill hides it. */
    --btn-edge: #B21A34;

    --bg: #F9F8F6;              /* warm off-white, the original ground */
    --surface: #FFFFFF;
    --surface-2: #EDE9E1;       /* nav hover wash */

    --edge: #DDD8D0;
    --edge-strong: #9C9996;

    --text: #1D1B19;            /* warm near-black */
    --text-dim: #6B6864;

    /* No luminance step is needed between a white-surfaced photo and paper,
       and the vignette would only dirty the edges. Off. The hard drop shadow
       comes back instead - it is the original design language. */
    --photo-frame: #DDD8D0;
    --photo-vignette: 0;
    --photo-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);

    /* Filled white with a hard shadow, as the design had it on paper. */
    --ghost-bg: #FFFFFF;
    --ghost-border: transparent;
    --ghost-hover-bg: #1D1B19;

    /* The crimson slab comes back: on a pale page it is the one big colour
       field, and it is the awning over the door. */
    --footer-bg: #B21A34;
    --footer-text: #F9F8F6;
    --footer-stripe: 0 solid transparent;
    --footer-icon-bg: rgba(0, 0, 0, 0.22);
    --footer-icon-border: transparent;

    --shadow: 0 1px 4px rgba(0, 0, 0, 0.6);
    --shadow-soft: 0 1px 3px rgba(0, 0, 0, 0.28);

    /* Call goes near-black on paper: still the quiet half of the pair, but it
       has to separate from a pale translucent bar rather than a dark one. */
    --call-bg: #1D1B19;
    --bar-bg: rgba(249, 248, 246, 0.72);
    --bar-bg-solid: #F9F8F6;
    --bar-edge: rgba(0, 0, 0, 0.14);
  }
}

/* --------------------------------------------------------------------------
   Reset
   -------------------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

/* figure carries a 40px side margin by default, which stops photos filling
   their grid cells. */
figure { margin: 0; }

/* Crimson text on the page ground is 2.7:1 - it fails at any size. Inline
   links therefore take the body colour (15.9:1) and carry the brand in the
   underline instead, which has no contrast requirement to meet. */
a {
  color: var(--text);
  text-decoration-color: var(--crimson-hover);
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
a:hover, a:focus-visible { text-decoration-color: var(--text); }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 400;           /* Archivo Black ships one weight; never synthesise */
  line-height: 1.12;
  margin: 0;
  letter-spacing: -0.005em;
}

p { margin: 0 0 1em; }

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

/* Respect a reduced-motion preference. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Zeroing the duration is not enough on its own - the card's photo zoom
     would still snap to its hovered size in one frame. Cancel the movement
     itself, not just its timing. */
  .card:hover .card__media img,
  .card:focus-within .card__media img { transform: none !important; }
}

/* Screen-reader-only, still focusable. */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 8px; top: -60px;
  z-index: 200;
  background: var(--surface);
  color: var(--text);
  padding: 12px 18px;
  font-family: var(--display);
  font-size: 13px;
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 8px; }

/* --------------------------------------------------------------------------
   Layout primitives
   -------------------------------------------------------------------------- */

.rail {
  width: 100%;
  max-width: var(--rail);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: 56px; }
.band--tight { padding-block: 36px; }

/* --------------------------------------------------------------------------
   Buttons
   Square corners, hard shadow, no border-radius anywhere. Minimum 44px tall.
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  padding: 12px 26px;
  font-family: var(--display);
  font-size: 15px;
  line-height: 1.2;
  letter-spacing: 0.02em;
  text-align: center;
  text-decoration: none;
  border: 0;
  border-radius: 0;
  box-shadow: var(--shadow);
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease;
}

/* Crimson at #B21A34 is only 2.7:1 against the page ground - enough to see,
   short of the 3:1 WCAG asks for a control's boundary. Rather than shift the
   brand colour, the fill keeps #B21A34 and a 1px brighter-crimson edge does
   the separating (3.6:1). The label is pure white for maximum legibility on
   the fill. */
.btn--primary {
  background: var(--crimson);
  color: var(--on-crimson);
  border: 1px solid var(--btn-edge);
}
.btn--primary:hover,
.btn--primary:focus-visible {
  background: var(--crimson-hover);
  border-color: var(--crimson-hover);
}

/* Outlined rather than filled: a light-filled button on a dark page would be
   a second bright rectangle competing with the photography. */
.btn--ghost {
  background: var(--ghost-bg);
  color: var(--text);
  border: 1px solid var(--ghost-border);
}
.btn--ghost:hover,
.btn--ghost:focus-visible {
  background: var(--ghost-hover-bg);
  border-color: var(--ghost-hover-bg);
  color: var(--on-dark);   /* the hover fill is dark in both schemes */
}

/* Inside a crimson card the neutral outline is only 1.2:1 against the fill,
   so ghost buttons there switch to white. */
.card .btn--ghost {
  background: transparent;
  border-color: rgba(255, 255, 255, 0.85);
  color: var(--on-crimson);
  box-shadow: none;
}
.card .btn--ghost:hover,
.card .btn--ghost:focus-visible {
  background: var(--on-crimson);
  color: var(--crimson);
  border-color: var(--on-crimson);
}

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

/* External-link marker, drawn rather than a glyph so it inherits colour. */
.btn__ext {
  width: 0.72em; height: 0.72em;
  margin-left: 0.55em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.2;
  stroke-linecap: square;
}

/* --------------------------------------------------------------------------
   Header
   -------------------------------------------------------------------------- */

.site-header {
  background: var(--surface);
  border-bottom: 1px solid var(--edge);
  box-shadow: none;
  position: relative;
  z-index: 50;
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 20px;
  padding-block: 12px;
}

/* Transparent - the header uses logo-dark.png, whose badge ring and knocked-out
   lettering are recoloured cream so the mark reads on a dark ground without a
   plate behind it. The original logo.png is kept for print and light mode. */
.site-header__logo {
  display: block;
  flex: none;
  line-height: 0;
}
.site-header__logo img { width: 150px; height: auto; }

.site-nav { margin-left: auto; }

.site-nav__list {
  display: flex;
  align-items: center;
  gap: 2px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav__link {
  display: flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 14px;
  font-family: var(--display);
  font-size: 13.5px;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.2s ease, color 0.2s ease;
}
.site-nav__link:hover,
.site-nav__link:focus-visible { background: var(--surface-2); }

.site-nav__link[aria-current=page] {
  background: var(--surface-2);
  color: var(--text);
  box-shadow: inset 0 -3px 0 var(--crimson);
}

.site-nav__link .btn__ext {
  width: 0.66em; height: 0.66em;
  opacity: 0.75;
  margin-left: 0.4em;
}

.site-header__cta { flex: none; }

/* --------------------------------------------------------------------------
   Hero
   A full-bleed photograph with an OPAQUE charcoal panel sitting on top of it -
   contrast comes from the panel, not from a gradient scrim. That is the single
   most characteristic thing about the original design.
   -------------------------------------------------------------------------- */

.hero { position: relative; background: var(--surface); }

.hero__media { position: absolute; inset: 0; }
.hero__media img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
}

.hero__inner {
  position: relative;
  display: flex;
  justify-content: center;
  padding-block: 48px;
}

.hero__panel {
  background: var(--panel);
  color: var(--on-dark);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 6px 28px rgba(0, 0, 0, 0.5);
  padding: 34px 30px 30px;
  width: 100%;
  max-width: 670px;          /* the original panel width */
  text-align: center;
}

.hero__wordmark {
  font-size: clamp(26px, 6.2vw, 46px);
  color: var(--on-dark);
  margin: 0;
}

.hero__rule {
  width: 100%;
  height: 3px;
  background: var(--crimson);
  border: 0;
  margin: 20px 0;
}

.hero__address {
  font-family: var(--display);
  font-size: clamp(13px, 2.9vw, 18px);
  line-height: 1.35;
  margin: 0 0 14px;
  color: var(--on-dark);
}

/* The phone is the most important control on the page for this business. */
.hero__phone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap);
  padding: 4px 12px;
  font-family: var(--display);
  font-size: clamp(24px, 6.6vw, 36px);
  color: var(--on-dark);
  text-decoration: none;
  border-bottom: 3px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}
.hero__phone:hover,
.hero__phone:focus-visible {
  color: #fff;
  border-bottom-color: var(--crimson);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: center;
  margin-top: 18px;
}
.hero__actions .btn { flex: 1 1 240px; }

/* Hours sit BELOW the buttons. They are reference information rather than an
   action, and putting them here means adding four lines cannot push the order
   button further down the page. Smaller, dimmer, and behind a divider, so the
   panel reads as act-then-look-up rather than one wall of text at one weight. */
.hero__meta {
  margin-top: 20px;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, 0.16);
  text-align: left;
}

.hero__hours {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 13.5px;
  line-height: 1.5;
}
.hero__hours li {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 2px 0;
}
.hero__hours dfn {
  font-style: normal;
  font-weight: 500;
  color: var(--on-dark);
}
.hero__hours span {
  color: var(--on-dark-dim);
  font-variant-numeric: tabular-nums;   /* the two times line up */
}

.hero__delivery {
  margin: 9px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--on-dark-dim);
}
.hero__delivery strong {
  color: var(--on-dark);
  font-weight: 500;
}

/* --------------------------------------------------------------------------
   Section headings
   -------------------------------------------------------------------------- */

.section-head { text-align: center; margin-bottom: 30px; }

.section-head__title {
  font-size: clamp(21px, 4.6vw, 30px);
  color: var(--text);
}

.section-head__sub {
  margin: 12px auto 0;
  max-width: 60ch;
  color: var(--text-dim);
  font-size: 16px;
}

/* --------------------------------------------------------------------------
   Photo strip (homepage teaser) and gallery grid
   -------------------------------------------------------------------------- */

.photo-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
}

/* The gallery is flex rather than grid so a short final row CENTRES instead of
   hanging off the left edge. 25 photos never divide evenly into 2, 3 or 4
   columns, and grid has no way to centre the remainder. Items grow to fill a
   full row but are capped at the column width, so full rows look identical to
   a grid - only the last row differs. */
.photo-grid--gallery {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
}

/* Columns are pinned to an exact width rather than allowed to grow, so a short
   final row keeps the same photo size as every other row and simply centres.
   That is what makes the gallery tolerate any photo count - 25 does not divide
   by 2 or 3, and the leftover would otherwise sit stranded at the left edge or
   balloon to fill the row. */
.photo-grid--gallery .photo {
  flex: 0 0 calc(50% - 4px);   /* 2 columns, 8px gap */
}

/* The homepage teaser is a fixed four, so it gets fixed columns rather than
   auto-fill - otherwise it lands as 3 + 1 and leaves a hole. */
.photo-grid--strip { grid-template-columns: repeat(2, 1fr); }

/* THE GLOWING-RECTANGLE PROBLEM.
   Every one of these photos was shot on a bright white surface. Dropped
   straight onto a near-black page, 25 of them read as a wall of light boxes
   and the food stops being the subject.

   Three things fix it, in order of how much work they do:
   1. A frame that steps the luminance down instead of cutting from white to
      near-black in one edge: photo -> #4A453F border -> #141312 page.
   2. An inset vignette that darkens only the outermost pixels of the image,
      so the white surface falls away at the edges rather than ending hard.
      It is deliberately weak (18%) and feathered over 22px - enough to stop
      the halo, not enough to touch the food, which sits in the middle.
   3. The caption bar, which already anchors the bottom edge.
   The image itself is never dimmed: no filter, no opacity. */
.photo {
  position: relative;
  background: var(--surface-2);
  border: 1px solid var(--photo-frame);
  box-shadow: var(--photo-shadow);
  overflow: hidden;
}
.photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
.photo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  box-shadow: inset 0 0 22px 2px rgba(0, 0, 0, var(--photo-vignette));
}

.photo__caption {
  font-family: var(--display);
  font-size: 12px;
  letter-spacing: 0.02em;
  color: var(--on-dark);
  /* Opaque enough that the label keeps its contrast whatever is behind it. */
  background: var(--caption-bg);
  padding: 9px 12px;
  position: absolute;
  left: 0; right: 0; bottom: 0;
  z-index: 2;                 /* above the vignette */
}

.strip-more { text-align: center; margin-top: 26px; }

/* --------------------------------------------------------------------------
   Feature cards
   The original: a crimson band, a rotated vertical label on a dark strip, copy,
   a CTA, and a photo on the right. Rotation is dropped below the desktop
   breakpoint because vertical text in a narrow column is unreadable.
   -------------------------------------------------------------------------- */

.cards { display: grid; gap: 20px; }

.card {
  display: grid;
  grid-template-columns: 74px 1fr;
  background: var(--crimson);
  color: var(--on-crimson);
  border: 1px solid var(--crimson-hover);
  box-shadow: none;
  overflow: hidden;
}

.card__spine {
  background: var(--spine-bg);
  display: grid;
  place-items: center;
  padding: 12px 0;
}

.card__spine span {
  font-family: var(--display);
  font-size: 15px;
  letter-spacing: 0.06em;
  color: var(--on-dark);   /* the spine is dark in both schemes */
  white-space: nowrap;
  writing-mode: vertical-rl;
  transform: rotate(180deg);
}

.card__body { padding: 26px 24px; }

.card__copy {
  font-size: clamp(18px, 3.6vw, 26px);
  line-height: 1.4;
  margin: 0 0 20px;
  color: var(--on-crimson);   /* the card is crimson in both schemes */
}

/* The second card announces something rather than restating a standing offer,
   so it carries a real headline plus a smaller note, where the first card has
   one line of copy. Different content, different shape. */
.card__title {
  font-size: clamp(19px, 4.2vw, 27px);
  line-height: 1.15;
  margin: 0 0 10px;
  color: var(--on-crimson);
}

.card__note {
  font-size: 15px;
  line-height: 1.5;
  margin: 0 0 20px;
  color: rgba(255, 255, 255, 0.88);
  max-width: 46ch;
}

.card__media { display: none; }

/* --------------------------------------------------------------------------
   Info blocks (contact page)
   -------------------------------------------------------------------------- */

.info-grid {
  display: grid;
  gap: 20px;
  grid-template-columns: 1fr;
}

.info {
  background: var(--surface);
  border: 1px solid var(--edge);
  padding: 24px;
}

.info__title {
  font-size: 17px;
  margin-bottom: 12px;
  color: var(--text);
}

.info__body { font-size: 17px; }
.info__body p:last-child { margin-bottom: 0; }

.hours {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 17px;
}
.hours li {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 9px 0;
  border-bottom: 1px solid var(--edge);
}
.hours li:last-child { border-bottom: 0; }
.hours dfn { font-style: normal; font-weight: 500; }

.hours__note {
  margin-top: 14px;
  padding-top: 14px;
  border-top: 3px solid var(--crimson);
  font-size: 16px;
  color: var(--text);
}

/* A phone number sitting inside a sentence. Padding plus an equal negative
   margin grows the hit area to 44px without moving the surrounding text. */
.phone-inline {
  display: inline-block;
  padding-block: 11px;
  margin-block: -11px;
  font-weight: 500;
}

/* A phone number rendered as a large, obvious control. */
.phone-link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-family: var(--display);
  font-size: clamp(22px, 5.4vw, 30px);
  /* Was crimson on paper. Crimson on this ground is 2.7:1, so the number
     takes the body colour and keeps a crimson rule under it. */
  color: var(--text);
  text-decoration: none;
  border-bottom: 3px solid var(--crimson);
}
.phone-link:hover,
.phone-link:focus-visible {
  color: var(--text);
  border-bottom-color: var(--crimson-hover);
}

/* --------------------------------------------------------------------------
   Call-to-action band, used top and bottom of the gallery
   -------------------------------------------------------------------------- */

.cta-band {
  background: var(--band-bg);
  color: var(--on-dark);
  border-block: 1px solid var(--edge);
  padding-block: 26px;
}

.cta-band__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 14px;
  text-align: center;
}

.cta-band__phone {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 6px;
  font-family: var(--display);
  font-size: clamp(20px, 5vw, 27px);
  color: var(--on-dark);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}
.cta-band__phone:hover,
.cta-band__phone:focus-visible { border-bottom-color: var(--crimson); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */

/* THE FOOTER WAS A CRIMSON SLAB. On paper that worked - it was the one big
   colour field on a pale page, and it read as the awning over the door.
   On a dark page the same slab is the most saturated thing on screen, sitting
   at the bottom where nothing needs attention, and it competes with the
   ORDER ONLINE buttons for the eye. Crimson has to mean "this is the action";
   spending it on the footer devalues every button above it.

   So the slab becomes a raised dark surface and the awning survives as a
   crimson stripe across the top. Same motif, a fraction of the ink.
   To go back to a full crimson footer, set background to var(--crimson) and
   drop the border-top. */
.site-footer {
  background: var(--footer-bg);
  color: var(--footer-text);
  border-top: var(--footer-stripe);
  padding-block: 30px 20px;
}

.site-footer a { color: var(--footer-text); }

/* The rule above catches buttons too. On the light scheme the footer is crimson
   and a ghost button is a white fill, so its label would be painted white on
   white. Restore both button labels explicitly. */
.site-footer .btn--ghost { color: var(--text); }
.site-footer .btn--ghost:hover,
.site-footer .btn--ghost:focus-visible { color: var(--on-dark); }
.site-footer .btn--primary { color: var(--on-crimson); }

.footer-grid {
  display: grid;
  gap: 22px;
  grid-template-columns: 1fr;
}

.footer__heading {
  font-size: 14px;
  letter-spacing: 0.06em;
  margin-bottom: 9px;
  color: var(--footer-text);
}

.footer__body { font-size: 16px; line-height: 1.5; }
.footer__body p { margin: 0 0 0.45em; }

.footer__phone {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  font-family: var(--display);
  font-size: 25px;
  color: var(--footer-text);
  text-decoration: none;
  border-bottom: 3px solid transparent;
}
.footer__phone:hover,
.footer__phone:focus-visible { border-bottom-color: var(--footer-text); }

.footer__hours {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 16px;
}
.footer__hours li {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 2px 0;
}
.footer__hours dfn { font-style: normal; font-weight: 500; }

.social {
  display: flex;
  gap: 8px;
  list-style: none;
  margin: 10px 0 0;
  padding: 0;
}

.social a {
  display: grid;
  place-items: center;
  width: var(--tap);
  height: var(--tap);
  background: var(--footer-icon-bg);
  border: 1px solid var(--footer-icon-border);
  transition: background-color 0.2s ease;
}
.social a:hover,
.social a:focus-visible { background: var(--crimson); }
.social svg { width: 21px; height: 21px; fill: var(--footer-text); }

.footer__legal {
  margin-top: 22px;
  padding-top: 13px;
  border-top: 1px solid rgba(249, 248, 246, 0.35);
  font-size: 14px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px 18px;
  align-items: center;
  justify-content: space-between;
}

/* --------------------------------------------------------------------------
   Sticky order bar (mobile only)

   THE CONTRAST PROBLEM, and how it is dodged rather than solved.
   The bar is translucent over whatever happens to be scrolling behind it -
   often a photograph shot on bright white. Nothing readable can sit directly
   on that: its contrast would swing with the content and there is no value
   that survives both a white plate and a dark crust.

   So no text sits on the translucent surface. Both buttons are OPAQUE fills,
   and every label is measured against its own fill instead of the backdrop:
     ORDER  #FFFFFF on --crimson        6.80:1, fixed
     CALL   --on-dark on --call-bg     12.4:1 dark / 16.5:1 light, fixed
   The translucency only ever shows through in the 8px gutter around and
   between the buttons, which carries no text. The bar's top hairline and the
   button edges do the separating from whatever is behind.
   -------------------------------------------------------------------------- */

.order-bar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 90;
  display: none;                 /* desktop: never */
  gap: 8px;
  padding: 8px 12px;
  /* Clear the iOS home indicator. */
  padding-bottom: max(8px, env(safe-area-inset-bottom));
  background: var(--bar-bg);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-top: 1px solid var(--bar-edge);

  transform: translateY(110%);
  opacity: 0;
  visibility: hidden;
  transition: transform 0.22s ease, opacity 0.22s ease, visibility 0.22s;
}

.order-bar.is-visible {
  transform: none;
  opacity: 1;
  visibility: visible;
}

/* Same breakpoint as the header CTA, which is hidden below it. */
@media (max-width: 899px) {
  .order-bar { display: flex; }
}

/* Equal width, and min-width:0 so a long label cannot push the pair uneven. */
.order-bar .btn {
  flex: 1 1 0;
  min-width: 0;
  padding-inline: 8px;
  /* Sized so "ORDER ONLINE" holds one line at 360px. Two lines made the bar
     60px tall and read as clumsy. */
  font-size: 13px;
  letter-spacing: 0;
  white-space: nowrap;
  box-shadow: none;
}

.order-bar .btn__icon {
  width: 1.05em; height: 1.05em;
  margin-right: 0.42em;
  flex: none;
  fill: currentColor;
}

/* The quiet half of the pair: opaque, and never crimson, so ORDER wins. */
.btn--call {
  background: var(--call-bg);
  color: var(--on-dark);
  border: 1px solid var(--bar-edge);
}
.btn--call:hover,
.btn--call:focus-visible {
  background: var(--panel);
  color: var(--on-dark);
}

/* Without backdrop-filter a 72% wash over a photo is unreadable mush, so fall
   back to the opaque ground rather than leaving it transparent. */
@supports not ((backdrop-filter: blur(2px)) or (-webkit-backdrop-filter: blur(2px))) {
  .order-bar { background: var(--bar-bg-solid); }
}

/* No slide for anyone who asked for less motion - it just appears. The global
   reduced-motion rule zeroes the duration; this also drops the offset so there
   is no chance of a one-frame jump. */
@media (prefers-reduced-motion: reduce) {
  .order-bar { transform: none; }
}

/* --------------------------------------------------------------------------
   404
   -------------------------------------------------------------------------- */

.notfound { text-align: center; padding-block: 80px; }
.notfound h1 { font-size: clamp(30px, 8vw, 56px); }
.notfound p { max-width: 46ch; margin-inline: auto; color: var(--text-dim); }
.notfound__actions {
  display: flex; flex-wrap: wrap; gap: 12px;
  justify-content: center; margin-top: 26px;
}

/* ==========================================================================
   Breakpoints
   Mobile first. Three real breakpoints, one document - no separate mobile DOM.
   ========================================================================== */

/* --- 560px: the nav can sit on one line, cards gain breathing room --------- */
@media (min-width: 560px) {
  .band { padding-block: 68px; }
  /* .band--tight is declared earlier, so restate it here or the rule above
     wins on source order and the tight band stops being tight. */
  .band--tight { padding-block: 40px; }

  /* Gallery goes three-up. Cap = (100% - total gap) / 3. */
  .photo-grid--gallery { gap: 14px; }
  .photo-grid--gallery .photo { flex-basis: calc(33.333% - 9.34px); }  /* 3 columns */
  .hero__inner { padding-block: 64px; }
  .hero__panel { padding: 42px 40px 36px; }
  .card { grid-template-columns: 90px 1fr; }
  .card__body { padding: 32px 30px; }
  .info-grid { grid-template-columns: 1fr 1fr; }
}

/* --- 900px: the desktop composition the original was designed at ---------- */
@media (min-width: 900px) {
  body { font-size: 17px; }

  .site-header__inner { padding-block: 14px; }
  .site-header__logo img { width: 168px; }

  .hero__inner { padding-block: 92px; }

  /* Cards get their photo back, on the right, as in the original. */
  .card { grid-template-columns: 90px 1fr 42%; }
  .card__media { display: block; position: relative; overflow: hidden; }
  .card__media img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
  }

  /* The one bit of movement on the page: hovering a card eases its photograph
     in slightly. Only on devices that genuinely hover, so it never fires as a
     stuck state after a tap. Nothing else on the card moves - the point is the
     food, not the effect. */
  @media (hover: hover) and (pointer: fine) {
    .card__media img {
      transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1);
      will-change: transform;
    }
    .card:hover .card__media img,
    .card:focus-within .card__media img {
      transform: scale(1.045);
    }
  }

  .info-grid { grid-template-columns: repeat(3, 1fr); }

  .footer-grid { grid-template-columns: 1.1fr 1fr 1fr; gap: 30px; }

  .photo-grid { gap: 18px; }
  .photo-grid--strip { grid-template-columns: repeat(4, 1fr); }
  .photo-grid--gallery { gap: 18px; }
  .photo-grid--gallery .photo { flex-basis: calc(33.333% - 12px); }  /* 3 columns */
}

/* --- Below 900px: stack the header ---------------------------------------- */
@media (max-width: 899px) {
  /* Clearance for the sticky order bar. It goes on the footer rather than on
     body so the footer colour runs under the bar instead of leaving a strip of
     page background below it. */
  .site-footer { padding-bottom: calc(20px + 64px + env(safe-area-inset-bottom)); }

  /* The card photo was desktop-only, which left the cup-and-char card with no
     cup-and-char on the device most people read this on. Below the desktop
     breakpoint it becomes a band across the bottom of the card instead.
     grid-column 1/-1 makes it span whether the spine is a left strip (2 cols)
     or a top bar (1 col). */
  .card__media {
    display: block;
    position: relative;
    grid-column: 1 / -1;
    aspect-ratio: 16 / 7;
    overflow: hidden;
  }
  .card__media img {
    position: absolute; inset: 0;
    width: 100%; height: 100%;
    object-fit: cover;
  }

  .site-header__inner {
    flex-direction: column;
    align-items: stretch;
    /* Was 10px. Each nav link is a 44px tap target with its label centred, so
       the row already carries ~14px of visual space above the text - the gap
       was stacking on top of that. Tighten around the row, never the row. */
    gap: 2px;
    padding-block: 8px;
  }
  .site-header__logo {
    align-self: center;
    /* The logo PNG carries ~11px of transparent margin above and below the
       badge at this size. Pull half of it back so the mark sits closer to the
       header edges without resizing the artwork. */
    margin-block: -7px;
  }
  .site-header__logo img { width: 132px; }

  .site-nav { margin-left: 0; }
  .site-nav__list {
    flex-wrap: wrap;
    justify-content: center;
    gap: 4px;
  }
  .site-nav__link {
    padding: 0 12px;
    font-size: 13px;
  }

  /* The header's ORDER ONLINE is hidden below the desktop breakpoint. On a
     phone the header stacks, which put a full-width red bar directly above
     the hero panel's own ORDER ONLINE - two identical buttons a few pixels
     apart. Every page carries an order button in its first screen anyway
     (hero panel on home and contact, CTA band on the gallery, the actions
     row on 404), so nothing is lost. It stays on desktop, where it sits in
     the top-right corner as a persistent CTA and does not collide. */
  .site-header__cta { display: none; }
}

/* --- Narrow phones --------------------------------------------------------- */
@media (max-width: 420px) {
  :root { --gutter: 14px; }

  .hero__panel { padding: 26px 18px 22px; }
  .hero__actions .btn { flex: 1 1 100%; }

  /* Vertical text needs height to work; at this width it does not have any. */
  .card { grid-template-columns: 1fr; }
  .card__spine { padding: 10px 0; }
  .card__spine span {
    writing-mode: horizontal-tb;
    transform: none;
    font-size: 14px;
  }
  .card__body { padding: 20px 16px; }

  .photo-grid { grid-template-columns: 1fr 1fr; gap: 8px; }
  /* The gallery is flex here, so it is sized by cap not by columns. */
  .photo-grid--gallery { gap: 8px; }
  .photo__caption { font-size: 10px; padding: 6px 8px; }

  .site-nav__link { font-size: 12px; padding: 0 9px; }
}

/* --- Print ---------------------------------------------------------------- */
@media print {
  /* A dark page must not be printed dark. Force ink on white. */
  :root { color-scheme: light; }
  .site-header__cta, .site-nav, .cta-band, .hero__media { display: none; }
  body { background: #fff; color: #000; font-size: 12pt; }
  .hero__panel, .site-footer, .info, .cta-band, .card {
    background: #fff; color: #000; border-color: #000;
  }
  .hero__wordmark, .hero__address, .hero__phone, .card__copy,
  .footer__heading, .site-footer a, .phone-link { color: #000; }
  .photo { border-color: #999; }
  .photo::after { display: none; }
}
