/* ==========================================================================
   T'Dori Takeout — design system
   Direction C, "Fresh" — bright, roomy, conversion-first.
   Made Visible · tdoritakeout.com

   This file is the whole site's skin. Page markup carries the class hooks;
   nothing here depends on a build step or a third-party request.
   ========================================================================== */

/* ==========================================================================
   1. TYPE — three families, self-hosted. No third-party font request is made.
   Latin subsets only. Two of the three are variable fonts, so one file each
   covers every weight the system asks for:

     Plus Jakarta Sans  700–800   display: hero headlines, section titles,
                                  large statements, important numbers
     Inter              400–700   everything else: body, nav, buttons, labels,
                                  menus, supporting headlines
     Mate Italic        400       the editorial accent, used sparingly —
                                  ingredient statements, food callouts,
                                  handwritten-style moments. Never paragraphs.
   ========================================================================== */

@font-face {
  font-family: 'Plus Jakarta Sans';
  font-style: normal;
  font-weight: 700 800;
  font-display: swap;
  src: url(../fonts/PlusJakartaSans-normal-700800-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: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url(../fonts/Inter-normal-400700-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: 'Mate';
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url(../fonts/Mate-italic-400-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;
}

/* ==========================================================================
   2. TOKENS — the T'dori palette.
   Warm cream ground, white cards, two tomatoes, two greens, one warm grey.
   Every contrast figure below is against the ground the colour actually
   lands on; the sage-ground overrides at the end of this section exist
   because one grey cannot clear AA on both cream and sage.
   ========================================================================== */

:root {
  /* ground */
  --w:        #FFFFFF;   /* Pure White — buttons, cards */
  --cream:    #F7F7F0;   /* Warm Cream — the main background */
  --off:      #E8E9DC;   /* Soft Sage Cream — alternate sections, cards */
  --sink:     #EEF2E8;   /* Sage Tint — hero backgrounds */

  /* text */
  --ink:      #0E1113;   /* T'dori Charcoal — headlines, navigation, dark text */
  /* Warm Gray is the body copy: 5.40:1 on white, 5.02:1 on cream. */
  --body:     #666B6D;
  /* Secondary text: menu descriptions, hours, stat captions, fine print.
     One step lighter than body; 5.02:1 on white and 4.67:1 on cream. */
  --muted:    #6C7173;
  --line:     #DADDD5;   /* Light Border — borders, dividers */

  /* accents */
  --basil:    #31563A;   /* Deep Italian Green — secondary brand accent, 8.3:1 with white */
  --basil-dk: #26452E;   /* hover / pressed step */
  --olive:    #47501C;   /* Olive Green — handwritten notes, accent details */
  /* Tomato Red is the brand accent: 4.89:1 with white, so it carries small
     tags, numbers and links. Bright Tomato is for buttons and emphasised
     headline words — as accent type it is always large, and on a button it
     reads 4.21:1 against a white label, which the client's palette accepts. */
  --tom:      #CE3C26;
  --tom-br:   #E53B25;   /* Bright Tomato — buttons, emphasised headline words */
  --tom-dk:   #B8321E;   /* pressed step, 5.98:1 */
  --tom-ink:  #9A2E1B;   /* tomato as small text on a tint */
  --sun:      #F2A93B;   /* functional amber: "opening soon", the GF tag, the deal strip */
  --sun-ink:  #8A5D06;

  /* the same accents as channels, for tints and shadows */
  --tom-rgb:   206, 60, 38;
  --basil-rgb: 49, 86, 58;
  --ink-rgb:   14, 17, 19;

  /* shape */
  --r:        18px;      /* card radius */
  --r-sm:     12px;      /* input / small surface radius */
  --pill:     999px;
  --wrap:     1200px;
  --read:     64ch;

  /* motion */
  --spring:   cubic-bezier(.34, 1.56, .64, 1);
  --ease:     cubic-bezier(.22, .61, .36, 1);

  /* type — the three families and their fallbacks */
  --f-body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --f-display: "Plus Jakarta Sans", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --f-accent:  "Mate", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;

  /* type scale
     step-4  hero            48px on a phone → 88px on a desktop
     step-3  section titles  28px → 44px
     step-2  menu sections   22px → 30px
     step-1  ledes           18px → 22px
     body                    17px → 18.4px, set on <body> below              */
  --step--1: 0.86rem;
  --step-0:  1rem;
  --step-1:  clamp(1.125rem, 1.05rem + 0.45vw, 1.375rem);
  --step-2:  clamp(1.4rem, 1.2rem + 0.8vw, 1.9rem);
  --step-3:  clamp(1.75rem, 1.35rem + 1.8vw, 2.75rem);
  --step-4:  clamp(3rem, 2.1rem + 4.2vw, 5.5rem);

  /* offset for anything fixed to the bottom of the viewport; the concept
     presentation bar publishes its own height here, the live site does not. */
  --pv-inset: 0px;

  /* ---- legacy aliases -------------------------------------------------
     Earlier pages carry inline styles referencing the old palette. They are
     remapped onto the current tokens so no page goes unreadable.          */
  --cream-2:   var(--off);
  --cream-3:   var(--sink);
  --ink-soft:  #262B2D;
  --rule:      var(--line);
  --rule-dk:   rgba(255, 255, 255, .24);
  --tomato:    var(--tom);
  --tomato-dk: var(--tom-dk);
  --amber:     var(--sun);
}

/* Sage ground. Warm Gray reads 4.40:1 on Soft Sage Cream, a hair under AA,
   so every surface painted --off takes a grey one step darker: 4.96:1 for
   body copy and 4.82:1 for the secondary grey. Visually the same grey. */
.soft, .stat, .strip-item, .step, .legend, .form-shell, .site-foot, .ticker,
.new-feature, .rail-cta, .plug, .band .step {
  --body:  #5E6365;
  --muted: #606567;
}

/* ==========================================================================
   3. BASE
   ========================================================================== */

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--cream);
  color: var(--body);
  font-family: var(--f-body);
  font-size: clamp(1.0625rem, 1.02rem + 0.2vw, 1.15rem);   /* 17px → 18.4px */
  line-height: 1.55;
  letter-spacing: -0.01em;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* Display type: Plus Jakarta Sans ExtraBold, tight and close-set, for the
   hero and the section titles. Supporting heads — cards, steps, menu
   sections, FAQ — stay in Inter Bold so the display face keeps its weight. */
h1, h2, h3, h4 {
  color: var(--ink);
  margin: 0 0 0.5em;
}
h1, h2 {
  font-family: var(--f-display);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
}
h1 { font-size: var(--step-4); }
h2 { font-size: var(--step-3); line-height: 1.05; letter-spacing: -0.035em; }
h3, h4 { font-family: var(--f-body); font-weight: 700; }
h3 { font-size: var(--step-1); letter-spacing: -0.02em; line-height: 1.25; }
h4 { font-size: 1rem; letter-spacing: -0.015em; }

/* the emphasised word in a headline — Bright Tomato, upright */
h1 em, h1 .accent, h2 em, h2 .accent { font-style: normal; color: var(--tom-br); }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--basil); text-underline-offset: 3px; }
a:hover { color: var(--basil-dk); }

a:focus-visible,
button:focus-visible,
summary:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: 2px solid var(--tom);
  outline-offset: 3px;
  border-radius: 4px;
}

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

strong, b { color: var(--ink); font-weight: 700; }
hr { border: 0; border-top: 1px solid var(--line); margin: 40px 0; }

::selection { background: rgba(var(--tom-rgb), .16); color: var(--ink); }

/* ==========================================================================
   4. LAYOUT
   ========================================================================== */

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.read { max-width: var(--read); }
.center { text-align: center; margin-left: auto; margin-right: auto; }

section { padding: clamp(54px, 6.5vw, 96px) 0; }
.tight { padding: clamp(38px, 4.5vw, 62px) 0; }
.flush-top { padding-top: 0; }

[id] { scroll-margin-top: 108px; }

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(30px, 4vw, 64px);
  align-items: center;
}
.split.lean { grid-template-columns: 1.05fr .95fr; }
@media (max-width: 860px) { .split, .split.lean { grid-template-columns: 1fr; } }

.row, .btn-row { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }

/* ==========================================================================
   5. EYEBROW / LEDE
   ========================================================================== */

.eyebrow, .kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  /* --basil-dk on the pill's own 9% tint: 8.65:1 on the cream ground, and
     the base green would already clear it at 6.76:1. */
  color: var(--basil-dk);
  background: rgba(var(--basil-rgb), .09);
  padding: 7px 14px;
  border-radius: var(--pill);
  margin: 0 0 20px;
  line-height: 1.3;
}
.eyebrow::before, .kicker::before {
  content: "";
  width: 7px; height: 7px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}
.kicker.center { margin-left: auto; margin-right: auto; }

/* live open/closed state, painted by main.js */
.eyebrow[data-state="open"],   .kicker[data-state="open"]   { color: var(--basil-dk); background: rgba(var(--basil-rgb), .09); }
.eyebrow[data-state="soon"],   .kicker[data-state="soon"]   { color: var(--sun-ink); background: rgba(242, 169, 59, .18); }
.eyebrow[data-state="closed"], .kicker[data-state="closed"] { color: var(--tom-ink); background: rgba(var(--tom-rgb), .10); }

.lede {
  font-size: var(--step-1);
  line-height: 1.5;
  color: var(--body);
  max-width: 46ch;
}

.section-head { max-width: 46ch; margin-bottom: 34px; }

/* The editorial accent: Mate Italic in olive, one line at a time. For an
   ingredient statement, a food callout, a handwritten-style moment between a
   headline and its copy — never a paragraph. The contrast with the display
   face is the whole point, so it is rationed. */
.hand {
  font-family: var(--f-accent);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.75rem, 1.3rem + 1.9vw, 3.25rem);   /* 28px → 52px */
  line-height: 1.1;
  letter-spacing: 0;
  color: var(--olive);
  max-width: 24ch;
  margin: 0 0 .55em;
}
.band .hand, .cta .hand { color: #fff; }

/* ==========================================================================
   6. BUTTONS
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 16px 30px;
  border-radius: var(--pill);
  font-family: inherit;
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  border: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  transition: transform .18s var(--ease), background-color .18s, border-color .18s, box-shadow .2s, color .18s;
}

/* primary — Bright Tomato, darkening to Tomato Red under the pointer. The one
   CTA colour on the site. */
.btn-p, .btn-solid {
  background: var(--tom-br);
  color: #fff;
  box-shadow: 0 6px 18px rgba(var(--tom-rgb), .26);
}
.btn-p:hover, .btn-solid:hover {
  background: var(--tom);
  color: #fff;
  transform: translateY(-2px);
  box-shadow: 0 10px 26px rgba(var(--tom-rgb), .34);
}

/* outline — the quiet second action */
.btn-o, .btn-line, .btn-ghost {
  border-color: var(--line);
  color: var(--ink);
  background: var(--w);
}
.btn-o:hover, .btn-line:hover, .btn-ghost:hover {
  border-color: var(--ink);
  color: var(--ink);
  transform: translateY(-2px);
}

/* green — catering's own action */
.btn-g {
  background: var(--basil);
  color: #fff;
  box-shadow: 0 6px 18px rgba(var(--basil-rgb), .22);
}
.btn-g:hover { background: var(--basil-dk); color: #fff; transform: translateY(-2px); }

.btn-sm { padding: 11px 20px; font-size: .85rem; }
.btn-lg { padding: 19px 36px; font-size: 1.02rem; }

@media (prefers-reduced-motion: reduce) {
  .btn, .btn:hover { transform: none; transition: background-color .18s, color .18s, border-color .18s; }
}

/* ==========================================================================
   7. CHIPS & TAGS
   ========================================================================== */

.chips {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 4px 2px 12px;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.chips::-webkit-scrollbar { display: none; }

.chip {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 11px 20px;
  border-radius: var(--pill);
  border: 1px solid var(--line);
  background: var(--w);
  color: var(--ink);
  text-decoration: none;
  font-size: .92rem;
  font-weight: 600;
  white-space: nowrap;
  transition: transform .34s var(--spring), border-color .18s, background-color .18s;
}
.chip:hover {
  color: var(--ink);
  border-color: var(--basil);
  background: rgba(var(--basil-rgb), .06);
  transform: translateY(-3px) scale(1.03);
}
@media (prefers-reduced-motion: reduce) { .chip, .chip:hover { transform: none; transition: border-color .18s, background-color .18s; } }

/* dietary tags on menu rows */
.tags { display: inline-flex; gap: 5px; margin-left: 8px; vertical-align: middle; }
.tag {
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .09em;
  padding: 3px 8px;
  border-radius: var(--pill);
  line-height: 1.35;
  border: 1px solid transparent;
}
.tag-v  { color: var(--basil);   background: rgba(var(--basil-rgb), .10); }
.tag-gf { color: var(--sun-ink); background: rgba(242, 169, 59, .18); }
.tag-sp { color: var(--tom-ink);        background: rgba(var(--tom-rgb), .10); }

.legend {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 18px;
  align-items: center;
  padding: 16px 22px;
  background: var(--off);
  border: 1px solid var(--line);
  border-radius: var(--r);
  font-size: .85rem;
  margin-bottom: 36px;
}

/* ==========================================================================
   8. HEADER
   ========================================================================== */

.site-head {
  position: sticky;
  top: 0;
  z-index: 60;
  background: rgba(247, 247, 240, .9);   /* the cream ground, translucent */
  -webkit-backdrop-filter: saturate(1.4) blur(12px);
          backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow .25s ease, transform .4s var(--ease);
  view-transition-name: site-head;
}
.site-head.stuck { box-shadow: 0 1px 20px rgba(var(--ink-rgb), .07); }
.site-head.hide { transform: translateY(-102%); }
@media (prefers-reduced-motion: reduce) { .site-head.hide { transform: none; } }

.head-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  min-height: 74px;
  transition: min-height .25s ease;
}
.site-head.stuck .head-inner { min-height: 64px; }

.brand {
  text-decoration: none;
  display: block;
  margin-right: auto;
  line-height: 1;
}
.brand-name {
  display: block;
  font-family: var(--f-display);
  font-size: 1.5rem;
  font-weight: 800;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.04em;
}
.brand-name .dot-mark { color: var(--tom); }
.brand-sub {
  display: block;
  font-size: .56rem;
  font-weight: 700;
  letter-spacing: .22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-top: 5px;
}

.nav { display: flex; gap: 26px; }
.nav a {
  color: var(--ink);
  text-decoration: none;
  font-size: .93rem;
  font-weight: 500;
  padding: 6px 0;
  position: relative;
  transition: color .18s;
}
.nav a:hover { color: var(--tom); }
.nav a::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  width: 0; height: 2px;
  border-radius: 2px;
  background: var(--tom);
  transition: width .22s var(--ease);
}
.nav a:hover::after,
.nav a[aria-current="page"]::after { width: 100%; }
.nav a[aria-current="page"] { color: var(--tom); }

.head-cta { display: flex; align-items: center; gap: 16px; }
.tel {
  font-size: .9rem;
  font-weight: 600;
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}
.tel:hover { color: var(--tom); }

.burger {
  display: none;
  width: 44px; height: 44px;
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--pill);
  cursor: pointer;
  padding: 0;
  position: relative;
}
.burger span {
  position: absolute; left: 12px;
  width: 18px; height: 2px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform .2s ease, opacity .2s ease;
}
.burger span:nth-child(1) { top: 16px; }
.burger span:nth-child(2) { top: 21px; }
.burger span:nth-child(3) { top: 26px; }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

.mnav { display: none; border-top: 1px solid var(--line); background: var(--w); }
.mnav.open { display: block; }
.mnav a {
  display: block;
  padding: 15px 24px;
  color: var(--ink);
  text-decoration: none;
  font-weight: 500;
  border-bottom: 1px solid var(--line);
}
.mnav a:hover { background: var(--off); color: var(--tom); }

@media (max-width: 900px) {
  .nav, .head-cta .tel { display: none; }
  .burger { display: block; }
}
@media (max-width: 420px) {
  .head-cta .btn { padding: 10px 15px; font-size: .8rem; }
  .head-inner { gap: 14px; }
}

/* ==========================================================================
   9. HERO
   ========================================================================== */

.hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(180deg, var(--sink), var(--cream));
  color: var(--body);
  padding: clamp(46px, 6vw, 86px) 0 clamp(46px, 6vw, 80px);
}
.hero .wrap { position: relative; z-index: 2; }
.hero h1 { color: var(--ink); }

/* soft out-of-focus colour behind the hero */
.blob {
  position: absolute;
  border-radius: 50%;
  filter: blur(64px);
  pointer-events: none;
  z-index: 0;
  opacity: .5;
}
.blob.a { width: 520px; height: 520px; background: #CFE0CC; top: -180px; left: -120px; }
.blob.b { width: 460px; height: 460px; background: #F6D9C6; bottom: -220px; right: -80px; }
.blob.c { width: 300px; height: 300px; background: #F3C9BE; top: 38%; left: 46%; }

.hgrid {
  display: grid;
  grid-template-columns: 1.02fr .98fr;
  gap: clamp(30px, 4vw, 64px);
  align-items: center;
}
@media (max-width: 900px) { .hgrid { grid-template-columns: 1fr; } }

.hero-sub {
  font-size: var(--step-1);
  color: var(--body);
  max-width: 42ch;
  margin: 0 0 30px;
  line-height: 1.55;
}

.hnote, .hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 24px;
  margin-top: 26px;
  font-size: .88rem;
  color: var(--muted);
  align-items: center;
}
.hnote b, .hero-meta b { color: var(--ink); font-weight: 700; }
.hero-meta .sep { color: var(--muted); font-size: .86rem; }

/* legacy open pill, used by pages not yet migrated */
.open-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: .84rem;
  font-weight: 600;
  color: var(--ink);
}
.dot {
  width: 8px; height: 8px;
  border-radius: 50%;
  background: var(--basil);
  box-shadow: 0 0 0 4px rgba(var(--basil-rgb), .16);
  flex: none;
}

/* the hero plate */
.hshot {
  position: relative;
  isolation: isolate;
  border-radius: 26px;
  overflow: hidden;
  aspect-ratio: 1 / 1;
  background: linear-gradient(150deg, var(--sink), var(--cream) 52%, #EFE7DC);
  border: 1px solid var(--line);
  display: grid;
  place-items: center;
  padding: 30px;
  text-align: center;
}
.hshot > img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  z-index: 1;
}
.hshot .cam {
  display: block;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--basil-dk); /* 9.4:1 on the sage plate */
  margin-bottom: 9px;
}
.hshot .cap { color: var(--muted); font-size: .95rem; max-width: 26ch; line-height: 1.45; }

/* the floating "Tonight" card */
.float {
  position: absolute;
  left: 18px; right: 18px; bottom: 18px;
  z-index: 3;
  background: var(--w);
  border-radius: 16px;
  padding: 15px 16px;
  box-shadow: 0 12px 34px rgba(var(--ink-rgb), .13);
  display: flex;
  align-items: center;
  gap: 12px;
  text-align: left;
  transition: transform .3s var(--spring), box-shadow .3s ease;
}
.hshot:hover .float { transform: translateY(-4px); box-shadow: 0 18px 44px rgba(var(--ink-rgb), .18); }
.float .lbl {
  display: block;
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}
.float .big {
  display: block;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.02em;
  line-height: 1.25;
}
.float .go { margin-left: auto; flex: none; }
@media (max-width: 420px) {
  .float { padding: 12px 13px; gap: 9px; }
  .float .big { font-size: .95rem; }
  .float .go { padding: 9px 15px; font-size: .78rem; }
}
@media (prefers-reduced-motion: reduce) { .float, .hshot:hover .float { transform: none; transition: none; } }

/* ==========================================================================
   10. STATS
   ========================================================================== */

.stats, .strip-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
}
@media (max-width: 760px) { .stats, .strip-grid { grid-template-columns: 1fr; } }

.stat, .strip-item {
  background: var(--off);
  border-radius: var(--r);
  padding: 26px 24px;
}
.stat b, .strip-item .n {
  display: block;
  font-family: var(--f-display);
  font-size: 2.1rem;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: -0.04em;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}
.stat > span, .strip-item .t {
  display: block;
  font-size: .86rem;
  color: var(--muted);
  margin-top: 7px;
  letter-spacing: 0;
  text-transform: none;
}
.strip { background: transparent; padding: 0 0 clamp(38px, 4.5vw, 62px); border: 0; }

/* ==========================================================================
   11. CARDS
   ========================================================================== */

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px;
}
@media (max-width: 900px) { .cards { grid-template-columns: 1fr; } }
.cards.two { grid-template-columns: repeat(2, 1fr); }
@media (max-width: 760px) { .cards.two { grid-template-columns: 1fr; } }

.card, .c {
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--r);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .38s var(--spring), box-shadow .28s ease;
}
.card:hover, .c:hover { transform: translateY(-4px); box-shadow: 0 16px 38px rgba(var(--ink-rgb), .09); }
@media (prefers-reduced-motion: reduce) {
  .card, .c, .card:hover, .c:hover { transform: none; transition: none; }
}

.c .img {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--off);
  border-bottom: 1px solid var(--line);
  overflow: hidden;
  display: grid;
  place-items: center;
  text-align: center;
}
/* Positioned out of the grid, like .hshot > img and .shot > img. As a grid item
   the `height: 100%` was cyclic against an auto-sized row, so it resolved to
   auto: the image rendered at its own intrinsic height, the row grew with it,
   and `overflow: hidden` clipped the bottom off instead of cropping centred.
   A portrait photograph lost its lower half that way - the cheese pizza card
   was two thirds box lid. Absolute makes the 4/3 frame the crop box again. */
.c .img > img {
  position: absolute;
  inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
/* an art-direction caption instead of a photograph still needs breathing room */
.c .img > *:not(img) { padding-inline: 18px; }
.c .img .cam {
  display: block;
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--basil);
  margin-bottom: 7px;
}
.c .img .cap { font-size: .86rem; color: var(--muted); max-width: 24ch; line-height: 1.4; }
.c .b { padding: 22px 22px 24px; }
.c p { font-size: .92rem; }
.c .price, .card .price {
  display: block;
  margin-top: 12px;
  font-weight: 700;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

/* the numbered "how it works" flavour of .card */
.card { padding: 0; }
.card > * { margin-left: 26px; margin-right: 26px; }
.card > *:first-child { margin-top: 28px; }
.card > *:last-child { margin-bottom: 28px; }
.card .num {
  display: block;
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .12em;
  color: var(--tom);
  margin-bottom: 14px;
}
.card p { font-size: .95rem; }
.card .card-link {
  margin-top: auto;
  padding-top: 18px;
  font-size: .88rem;
  font-weight: 700;
  color: var(--basil);
  text-decoration: none;
  transition: color .2s ease;
}
.card .card-link::after {
  content: " \2192";
  display: inline-block;
  transition: transform .25s var(--ease);
}
.card:hover .card-link::after { transform: translateX(5px); }
@media (prefers-reduced-motion: reduce) { .card:hover .card-link::after { transform: none; } }

/* ==========================================================================
   12. PHOTOGRAPHY SLOTS (art-direction placeholders / shoot brief)
   ========================================================================== */

.shot {
  position: relative;
  background: linear-gradient(150deg, var(--sink), var(--cream) 55%, #EFE7DC);
  border: 1px solid var(--line);
  border-radius: var(--r);
  display: grid;
  place-items: center;
  padding: 26px;
  overflow: hidden;
}
.shot.tall   { aspect-ratio: 4 / 5; }
.shot.wide   { aspect-ratio: 16 / 9; }
.shot.square { aspect-ratio: 1 / 1; }
.shot > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.shot-label { text-align: center; max-width: 30ch; position: relative; z-index: 2; }
.shot-label .cam {
  display: block;
  font-size: .62rem;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--basil-dk); /* 9.4:1 on the sage plate */
  margin-bottom: 9px;
  font-weight: 700;
}
.shot-label .desc {
  font-size: .95rem;
  line-height: 1.45;
  /* --body, not --muted: this caption doubles as the shoot brief and sits on a
     gradient plate rather than a flat ground, so it takes the darker of the two
     secondary greys and clears AA with margin wherever the plate lands. */
  color: var(--body);
}

/* ---- art direction on the client's portrait food photographs ---------------
   The pizzas were shot 4:5 with the open box lid filling the top of the frame.
   A centred crop into a landscape slot therefore spends its top band on
   cardboard and clips the far crust. cheese-pizza.jpg sits lowest of the three
   (the pie starts about 27% down), so its crop is pulled toward the food. The
   other four photographs centre acceptably and are left alone.               */
img[src$="cheese-pizza.jpg"] { object-position: 50% 64%; }

/* ==========================================================================
   13. BANDS & THE CATERING CTA
   ========================================================================== */

/* .band — the green slab. Catering lives here across the site. */
/* The shared green slab. Everything that sits on it is measured against basil
   rather than against white — #DCE9DE, the colour this band shipped with, is
   4.05:1 there and under AA for body copy, and a 16%-white eyebrow pill puts
   white type at 3.7:1. The home page had already been given the corrected
   treatment through .band-cater / .eyebrow-solid hooks; the numbers are the
   same on the other four bands, so the fix belongs on the component. */
.band {
  background: var(--basil);
  color: #F2F7F3;            /* 7.68:1 on the deep green */
}
.band h1, .band h2, .band h3, .band h4, .band strong, .band b { color: #fff; }
.band .lede, .band p { color: #F2F7F3; }
.band a { color: #fff; }
.band .eyebrow, .band .kicker, .band .kicker.on-dark {
  color: var(--basil-dk);    /* solid white pill, basil-dark type: 7.6:1 */
  background: var(--w);
}
.band .btn-p, .band .btn-solid {
  background: #fff;
  color: var(--basil-dk);
  box-shadow: none;
}
.band .btn-p:hover, .band .btn-solid:hover { background: #fff; color: var(--basil-dk); box-shadow: 0 10px 26px rgba(0, 0, 0, .16); }
.band .btn-o, .band .btn-line, .band .btn-ghost { background: transparent; border-color: rgba(255, 255, 255, .5); color: #fff; }
.band .btn-o:hover, .band .btn-line:hover, .band .btn-ghost:hover { border-color: #fff; background: rgba(255, 255, 255, .1); color: #fff; }
.band .shot { border-color: rgba(255, 255, 255, .28); }
.band .step { border-top-color: rgba(255, 255, 255, .35); }
.band .areas li { color: #F2F7F3; border-right-color: rgba(255, 255, 255, .28); }

.kicker.on-dark { color: var(--sun-ink); background: rgba(242, 169, 59, .18); }

/* the rounded catering banner — same green ground and body colour as .band */
.cta {
  background: var(--basil);
  color: #F2F7F3;
  border-radius: 26px;
  padding: clamp(34px, 4vw, 60px);
  display: grid;
  grid-template-columns: 1.2fr .8fr;
  gap: 32px;
  align-items: center;
}
@media (max-width: 860px) { .cta { grid-template-columns: 1fr; } }
.cta h2, .cta h3 { color: #fff; }
.cta p { color: #F2F7F3; }
.cta .btn-p, .cta .btn-solid { background: #fff; color: var(--basil-dk); box-shadow: none; }
.cta .btn-p:hover, .cta .btn-solid:hover { background: #fff; color: var(--basil-dk); box-shadow: 0 10px 26px rgba(0, 0, 0, .16); }
.cta .btn-o, .cta .btn-line, .cta .btn-ghost { background: transparent; border-color: rgba(255, 255, 255, .5); color: #fff; }
.cta .btn-o:hover, .cta .btn-line:hover, .cta .btn-ghost:hover { border-color: #fff; background: rgba(255, 255, 255, .1); color: #fff; }

/* an off-white section, for rhythm between white ones */
.soft { background: var(--off); }

/* ==========================================================================
   14. MENU / PRICE LISTS
   ========================================================================== */

.menu-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 48px;
  align-items: start;
}
@media (max-width: 900px) {
  .menu-layout { grid-template-columns: 1fr; gap: 26px; }
}

.menu-sec {
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: clamp(22px, 3vw, 32px);
  margin-bottom: 20px;
  scroll-margin-top: 110px;
}
.menu-sec > h3 {
  font-size: var(--step-2);
  margin: 0 0 4px;
  padding: 0;
  border: 0;
}

/* The badge above a section heading that says, in words rather than colour
   alone, that the whole section is new. Written page-scoped twice — once on the
   takeout menu for pizza, once on the catering menu for pizza trays — and
   identical both times, so it lives here. Distinct from .flag-new, which is the
   small inline pill on a single row, chip or card. */
.sec-flag {
  display: inline-block;
  margin: 0 0 12px;
  padding: 6px 14px;
  border-radius: var(--pill);
  background: var(--tom);      /* 4.89:1 with white — AA for this size */
  color: #fff;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
}

/* A section heading with its photograph beside it rather than above it, so a
   source only ~440px wide is never asked to fill a full-width band. Written
   page-scoped and identically on both the takeout menu and the catering menu,
   so it lives here. */
.sec-head {
  display: grid;
  grid-template-columns: 1fr 200px;
  gap: 22px;
  align-items: start;
}
.sec-head img {
  width: 100%;
  /* The HTML width/height attributes are there so the browser reserves the
     right box before the file lands. The width attribute is overridden above;
     the height attribute has to be too, or it stays a definite height, the
     aspect-ratio below is ignored as a result, and every section photograph
     renders at its own full pixel height in a 200px column. */
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 14px;
  border: 1px solid var(--line);
}
@media (max-width: 620px) {
  .sec-head { grid-template-columns: 1fr; gap: 14px; }
  .sec-head img { aspect-ratio: 16 / 9; }
}

.menu-note {
  font-size: .88rem;
  color: var(--muted);
  margin: 0 0 18px;
}

.menu-list { list-style: none; margin: 0; padding: 0; }
.menu-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0 10px;
  padding: 14px 0;
  border-bottom: 1px solid var(--line);
}
.menu-item:last-child { border-bottom: 0; padding-bottom: 0; }
.menu-item .mi-name {
  font-weight: 700;
  color: var(--ink);
  font-size: 1rem;
  letter-spacing: -0.015em;
  flex: none;
  max-width: 66%;
}
.menu-item .mi-fill {
  flex: 1;
  border-bottom: 1px dotted var(--line);
  transform: translateY(-4px);
  min-width: 18px;
}
.menu-item .mi-price {
  font-weight: 700;
  color: var(--ink);
  flex: none;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
}
.menu-item .mi-desc {
  flex-basis: 100%;
  font-size: .89rem;
  color: var(--muted);
  margin-top: 4px;
  line-height: 1.5;
}

/* category rail
   Every rule here is scoped `a:not(.btn)`. A bare `.rail a` (0,1,1) out-weighs
   `.btn-p` (0,1,0), so a button dropped into the rail would be repainted as a
   rail link — grey label on a tomato ground. Excluding buttons from the match
   removes the trap rather than fighting it with more specificity. */
.rail { position: sticky; top: 96px; align-self: start; }
.rail ul { list-style: none; margin: 0; padding: 0; }
.rail li { margin-bottom: 4px; }
.rail a:not(.btn) {
  display: block;
  padding: 9px 16px;
  border-radius: var(--pill);
  color: var(--body);
  text-decoration: none;
  font-size: .9rem;
  font-weight: 500;
  transition: background-color .2s ease, color .2s ease;
}
.rail a:not(.btn):hover, .rail a:not(.btn).active {
  background: rgba(var(--basil-rgb), .09);
  color: var(--basil-dk);
  font-weight: 700;
}
@media (max-width: 900px) {
  .rail { position: static; }
  .rail ul { display: flex; flex-wrap: wrap; gap: 8px; }
  .rail li { margin: 0; }
  .rail a:not(.btn) { border: 1px solid var(--line); padding: 9px 16px; }
}

/* generic tables, price lists included */
table { border-collapse: collapse; width: 100%; }
th, td { text-align: left; padding: 11px 0; border-bottom: 1px solid var(--line); }
th { color: var(--ink); font-weight: 700; font-size: .9rem; }
td { font-size: .93rem; }
td.num, .num-col { text-align: right; font-variant-numeric: tabular-nums; }

/* ==========================================================================
   15. PACKAGES / OCCASIONS / STEPS
   ========================================================================== */

.pkg {
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 30px 28px;
  display: flex;
  flex-direction: column;
  transition: transform .38s var(--spring), box-shadow .28s ease;
}
.pkg:hover { transform: translateY(-4px); box-shadow: 0 16px 38px rgba(var(--ink-rgb), .09); }
@media (prefers-reduced-motion: reduce) { .pkg, .pkg:hover { transform: none; transition: none; } }
.pkg.feature { border: 2px solid var(--tom); position: relative; }
.pkg.feature::before {
  content: "Most requested";
  position: absolute;
  top: -13px; left: 24px;
  background: var(--tom);
  color: #fff;
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  padding: 5px 13px;
  border-radius: var(--pill);
}
.pkg .price {
  font-family: var(--f-display);
  font-size: 2.3rem;
  font-weight: 800;
  color: var(--ink);
  line-height: 1;
  letter-spacing: -0.04em;
  margin: 4px 0 3px;
  font-variant-numeric: tabular-nums;
}
/* The qualifier sits on its own line and reserves two of them, so every package
   card keeps the same price-block height whether its qualifier is a short
   "for your headcount" or a longer one that wraps at narrow three-column widths. */
.pkg .price small {
  display: block;
  margin-top: 7px;
  min-height: calc(2 * 1.35em);
  font-family: var(--f-body);
  font-size: .9rem;
  font-weight: 500;
  line-height: 1.35;
  color: var(--muted);
  letter-spacing: 0;
}
.pkg ul { list-style: none; margin: 20px 0 0; padding: 0; }
.pkg li {
  padding: 10px 0 10px 26px;
  position: relative;
  font-size: .92rem;
  border-top: 1px solid var(--line);
}
.pkg li::before {
  content: "";
  position: absolute;
  left: 4px; top: 18px;
  width: 7px; height: 7px;
  border-right: 2px solid var(--basil);
  border-bottom: 2px solid var(--basil);
  transform: rotate(45deg);
}

.occasions { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; }
.occasions li {
  list-style: none;
  border: 1px solid var(--line);
  background: var(--w);
  padding: 10px 18px;
  font-size: .9rem;
  border-radius: var(--pill);
}

.steps { counter-reset: s; display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
@media (max-width: 860px) { .steps { grid-template-columns: 1fr; } }
.step {
  counter-increment: s;
  background: var(--off);
  border-radius: var(--r);
  padding: 26px 24px;
}
.step::before {
  content: "0" counter(s);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--tom);
  color: #fff;
  font-size: .78rem;
  font-weight: 700;
  margin-bottom: 14px;
  letter-spacing: 0;
}
.step h3 { font-size: 1.15rem; }
.step p { font-size: .93rem; margin: 0; }
/* Recessed rather than raised, so the card separates from the slab without
   lifting the ground under the type: white heads read 9.47:1 on it and the
   body copy 8.73:1. */
.band .step { background: rgba(0, 0, 0, .10); }

/* ==========================================================================
   16. FORMS
   ========================================================================== */

.form-shell {
  background: var(--off);
  border: 1px solid var(--line);
  border-radius: 26px;
  padding: clamp(26px, 4vw, 48px);
}
.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
@media (max-width: 700px) { .field-grid { grid-template-columns: 1fr; } }

fieldset {
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 24px 22px;
  margin: 0 0 22px;
  background: var(--w);
}
fieldset legend {
  padding: 0 10px;
  font-size: .74rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--basil);
}

.field { display: flex; flex-direction: column; }
.field.full { grid-column: 1 / -1; }
.field label {
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--ink);
  margin-bottom: 8px;
}
.field .req { color: var(--tom); }
.field .opt { color: var(--muted); font-weight: 500; letter-spacing: 0; }
.field .hint { font-size: .8rem; color: var(--muted); margin-top: 6px; }

.field input,
.field select,
.field textarea,
input[type="text"], input[type="email"], input[type="tel"],
input[type="date"], input[type="number"], select, textarea {
  font-family: inherit;
  font-size: .95rem;
  color: var(--ink);
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 14px 15px;
  width: 100%;
  transition: border-color .18s ease, box-shadow .18s ease;
  -webkit-appearance: none;
          appearance: none;
}
select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--muted) 50%),
    linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-position: calc(100% - 20px) 52%, calc(100% - 14px) 52%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 40px;
}
.field textarea, textarea { resize: vertical; min-height: 128px; line-height: 1.55; }
::placeholder { color: var(--muted); opacity: 1; }

.field input:focus, .field select:focus, .field textarea:focus,
input:focus, select:focus, textarea:focus {
  outline: none;
  border-color: var(--basil);
  box-shadow: 0 0 0 3px rgba(var(--basil-rgb), .14);
}
.field .err { font-size: .8rem; color: var(--tom); margin-top: 6px; display: none; }
.field.invalid input, .field.invalid select, .field.invalid textarea { border-color: var(--tom); }
.field.invalid input:focus, .field.invalid select:focus, .field.invalid textarea:focus { box-shadow: 0 0 0 3px rgba(var(--tom-rgb), .14); }
.field.invalid .err { display: block; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form-foot {
  margin-top: 26px;
  display: flex;
  flex-wrap: wrap;
  gap: 18px;
  align-items: center;
  justify-content: space-between;
}
.form-foot .fine { font-size: .84rem; color: var(--muted); margin: 0; max-width: 42ch; }

.form-msg {
  margin-top: 20px;
  padding: 16px 20px;
  border-radius: var(--r-sm);
  border: 1px solid rgba(var(--basil-rgb), .3);
  background: rgba(var(--basil-rgb), .08);
  color: var(--basil-dk);
  font-size: .92rem;
  display: none;
}
.form-msg.show { display: block; }

/* ==========================================================================
   17. FAQ
   ========================================================================== */

.faq { display: grid; gap: 12px; }
.faq details {
  background: var(--w);
  border: 1px solid var(--line);
  border-radius: var(--r);
  padding: 2px 22px;
  transition: border-color .2s ease, box-shadow .2s ease;
}
.faq details[open] { border-color: rgba(var(--basil-rgb), .35); box-shadow: 0 10px 26px rgba(var(--ink-rgb), .06); }
.faq summary {
  cursor: pointer;
  list-style: none;
  padding: 20px 40px 20px 0;
  font-size: 1.05rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--ink);
  position: relative;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "";
  position: absolute;
  right: 4px; top: 50%;
  width: 22px; height: 22px;
  margin-top: -11px;
  border-radius: 50%;
  background: rgba(var(--tom-rgb), .1);
}
.faq summary::before {
  content: "";
  position: absolute;
  right: 9px; top: 50%;
  width: 12px; height: 12px;
  margin-top: -6px;
  z-index: 2;
  background:
    linear-gradient(var(--tom), var(--tom)) center/12px 2px no-repeat,
    linear-gradient(var(--tom), var(--tom)) center/2px 12px no-repeat;
  transition: transform .3s var(--ease);
}
.faq details[open] summary::before { transform: rotate(90deg); background: linear-gradient(var(--tom), var(--tom)) center/12px 2px no-repeat; }
.faq details > div { padding: 0 40px 22px 0; font-size: .95rem; overflow: hidden; }
.faq details.animating > div { transition: height .38s var(--ease), opacity .3s ease; }
@media (prefers-reduced-motion: reduce) {
  .faq summary::before, .faq details.animating > div { transition: none; }
}

/* ==========================================================================
   18. SERVICE AREA & TICKER
   ========================================================================== */

.areas { display: flex; flex-wrap: wrap; gap: 8px 10px; margin: 0; padding: 0; }
.areas li {
  list-style: none;
  font-size: .92rem;
  color: var(--body);
  padding-right: 10px;
  border-right: 1px solid var(--line);
}
.areas li:last-child { border-right: none; }

.ticker {
  overflow: hidden;
  background: var(--off);
  border-block: 1px solid var(--line);
  padding: 15px 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 9%, #000 91%, transparent);
}
.ticker-track { display: flex; width: max-content; animation: ticker 46s linear infinite; }
.ticker:hover .ticker-track,
.ticker:focus-within .ticker-track { animation-play-state: paused; }
.ticker-item {
  display: flex;
  align-items: center;
  gap: 28px;
  padding-right: 28px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}
.ticker-item::after {
  content: "";
  width: 5px; height: 5px;
  border-radius: 50%;
  background: var(--tom);
  flex: none;
}
@keyframes ticker { to { transform: translateX(-50%); } }

/* ==========================================================================
   19. FOOTER
   ========================================================================== */

.site-foot {
  background: var(--off);
  border-top: 1px solid var(--line);
  color: var(--body);
  padding: clamp(48px, 6vw, 72px) 0 26px;
  font-size: .93rem;
}
.foot-grid {
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr;
  gap: 40px;
  padding-bottom: 32px;
  border-bottom: 1px solid var(--line);
}
@media (max-width: 860px) { .foot-grid { grid-template-columns: 1fr; gap: 30px; } }

.site-foot h4 {
  color: var(--ink);
  font-size: .74rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin: 0 0 14px;
  font-weight: 700;
}
.site-foot a { color: var(--body); text-decoration: none; }
.site-foot a:hover { color: var(--tom); text-decoration: underline; }
.site-foot .brand-name { color: var(--ink); font-size: 1.4rem; }
.site-foot address { font-style: normal; line-height: 1.8; }

.hours { width: 100%; border-collapse: collapse; }
.hours th, .hours td {
  text-align: left;
  padding: 6px 0;
  font-weight: 400;
  font-size: .89rem;
  border-bottom: 1px solid var(--line);
}
.hours th { color: var(--body); font-weight: 500; }
.hours td { text-align: right; color: var(--muted); font-variant-numeric: tabular-nums; }
.hours tr.today th, .hours tr.today td { color: var(--basil-dk); font-weight: 700; }

.foot-links { list-style: none; margin: 0; padding: 0; }
.foot-links li { margin-bottom: 9px; }

.socials { display: flex; gap: 10px; margin-top: 18px; }
.socials a {
  width: 40px; height: 40px;
  border: 1px solid var(--line);
  background: var(--w);
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: var(--ink);
  transition: background-color .2s ease, border-color .2s ease, color .2s ease, transform .3s var(--spring);
}
.socials a:hover {
  background: var(--tom);
  border-color: var(--tom);
  color: #fff;
  transform: translateY(-2px);
}
.socials svg { width: 17px; height: 17px; fill: currentColor; }
@media (prefers-reduced-motion: reduce) { .socials a:hover { transform: none; } }

.foot-base {
  padding-top: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 10px 22px;
  justify-content: space-between;
  font-size: .8rem;
  color: var(--muted);
}
.foot-base a { color: var(--muted); }

/* leave room for the sticky order bar where it shows */
@media (max-width: 760px) { .site-foot { padding-bottom: 96px; } }

/* ==========================================================================
   20. STICKY ORDER BAR — direction C's signature move.
   Slides up on small screens once the hero CTA has scrolled away, and carries
   the same live open/closed status as the hero.
   ========================================================================== */

.obar {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(var(--pv-inset, 0px) + 12px);
  z-index: 70;
  display: none;
  align-items: center;
  gap: 12px;
  background: var(--ink);
  color: #fff;
  border-radius: var(--pill);
  padding: 11px 12px 11px 22px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, .28);
  transform: translateY(140%);
  transition: transform .35s var(--ease);
}
.obar.up { transform: none; }
.obar .t { font-size: .86rem; font-weight: 600; min-width: 0; }
.obar .t span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.obar .t small {
  display: block;
  font-size: .7rem;
  opacity: .62;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}
.obar a {
  margin-left: auto;
  flex: none;
  background: var(--tom-br);
  color: #fff;
  border-radius: var(--pill);
  padding: 11px 20px;
  font-size: .85rem;
  font-weight: 700;
  text-decoration: none;
}
.obar a:hover { background: var(--tom); color: #fff; }
@media (max-width: 760px) { .obar { display: flex; } }
@media (prefers-reduced-motion: reduce) { .obar { transition: none; } }

/* ==========================================================================
   21. CALL PANEL — the catering enquiry page.
   Replaced the form when catering moved to phone-only. Reuses .form-shell,
   fieldset/legend and .form-foot, so this section only carries what is new:
   the oversized number, the hours line and the checklist.
   ========================================================================== */

.call-panel > h3 {
  font-family: var(--f-disp);
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  line-height: 1.15;
  margin: 10px 0 14px;
}
.call-panel > p { color: var(--muted); max-width: 46ch; }

.call-cta {
  display: block;
  width: 100%;
  margin: 26px 0 10px;
  text-align: center;
  font-size: clamp(1.05rem, 2vw, 1.3rem);
  padding: 18px 22px;
  letter-spacing: .01em;
}
.call-hours { margin: 0 0 26px; }

.call-list { list-style: none; margin: 0 0 18px; padding: 0; }
.call-list li {
  position: relative;
  padding: 0 0 0 26px;
  margin-bottom: 12px;
  color: var(--muted);
  line-height: 1.5;
}
.call-list li:last-child { margin-bottom: 0; }
.call-list li::before {
  content: "";
  position: absolute;
  left: 6px; top: .55em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--tom);
}
.call-list b { color: var(--ink); font-weight: 700; }

.call-panel .form-foot { justify-content: flex-start; }

/* ==========================================================================
   22. MOTION SYSTEM
   Everything below is progressive enhancement. With JavaScript off, or with
   `prefers-reduced-motion: reduce`, every element sits in its final state —
   nothing is hidden behind an animation that might never run.
   ========================================================================== */

@view-transition { navigation: auto; }
::view-transition-old(root) { animation: vt-out .22s cubic-bezier(.4, 0, 1, 1) both; }
::view-transition-new(root) { animation: vt-in .34s cubic-bezier(0, 0, .2, 1) both; }
@keyframes vt-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vt-in { from { opacity: 0; transform: translateY(10px); } }

/* ---------- scroll progress ---------- */

#progress {
  position: fixed;
  inset: 0 0 auto 0;
  height: 2.5px;
  background: var(--tom);
  transform: scaleX(0);
  transform-origin: 0 50%;
  z-index: 90;
  pointer-events: none;
  will-change: transform;
}

/* ---------- generic reveal ---------- */

[data-anim], [data-a] {
  --d: 0ms;
  opacity: 0;
  will-change: opacity, transform;
}
[data-anim], [data-anim="up"], [data-a] { transform: translateY(20px); }
[data-anim="down"]  { transform: translateY(-18px); }
[data-anim="left"]  { transform: translateX(-26px); }
[data-anim="right"] { transform: translateX(26px); }
[data-anim="scale"] { transform: scale(.96); }
/* Sideways reveals become vertical once the layout stacks: a 26px horizontal
   offset on a full-bleed column is 2px of scrollable overflow, and no reveal
   is worth a page that can shimmy. */
@media (max-width: 900px) {
  [data-anim="left"], [data-anim="right"] { transform: translateY(20px); }
}
[data-anim="fade"]  { transform: none; }
[data-anim="wipe"]  { clip-path: inset(0 0 100% 0); opacity: 1; transform: none; }

[data-anim].in, [data-a].in {
  opacity: 1;
  transform: none;
  transition:
    opacity .7s var(--ease) var(--d),
    transform .7s var(--ease) var(--d),
    clip-path 1s cubic-bezier(.76, 0, .24, 1) var(--d);
}
/* The open clip belongs to the wipe variant alone. Set on every revealed
   element it silently cropped everything that legitimately sits outside its
   own border box: the "Most requested" badge on the catering package card was
   sheared in half, and every card's hover shadow was clipped flat. Only the
   variant that animates a clip-path gets one. */
[data-anim="wipe"].in { clip-path: inset(0 0 0 0); }

/* ---------- word-by-word headline reveal ---------- */

.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
.w-i {
  display: inline-block;
  transform: translateY(108%);
  transition: transform .95s cubic-bezier(.16, 1, .3, 1) var(--wd, 0ms);
}
[data-split].in .w-i { transform: none; }

/* ---------- parallax ---------- */

.px { will-change: transform; }

/* ---------- no-JS safety net ---------- */

.no-js [data-anim],
.no-js [data-a],
.no-js [data-split] .w-i {
  opacity: 1;
  transform: none;
  clip-path: none;
}

/* ---------- the global off switch ---------- */

@media (prefers-reduced-motion: reduce) {
  [data-anim], [data-anim].in,
  [data-a], [data-a].in {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
    transition: none !important;
  }
  .w-i { transform: none !important; transition: none !important; }
  .ticker-track { animation: none; }
  #progress { display: none; }
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* ==========================================================================
   23. PRINT
   ========================================================================== */

@media print {
  * {
    background: #fff !important;
    color: #111 !important;
    box-shadow: none !important;
    -webkit-backdrop-filter: none !important;
            backdrop-filter: none !important;
  }
  body { font-size: 11pt; }
  a { color: #111 !important; text-decoration: underline; }
  .site-head { position: static; border-bottom: 1px solid #bbb; }
  .site-foot { border-top: 1px solid #bbb; padding-bottom: 0; }
  section { padding: 18px 0 !important; break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }
  .menu-sec, .pkg, .card, .c, .faq details { border: 1px solid #ccc !important; break-inside: avoid; }
  .shot, .hshot { border: 1px solid #bbb !important; min-height: 140px; }
  .cta, .band { border: 1px solid #bbb !important; }
  .faq details > div { display: block !important; height: auto !important; }
  [data-anim], [data-anim].in, [data-a], [data-a].in, .w-i {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
  .obar, #progress, .ticker, .blob, .burger, .mnav, .chips { display: none !important; }
}

/* ==========================================================================
   24. HOME PAGE — NEW-PIZZA FEATURE & CATERING BAND
   Added when the food photography landed. Everything in this section is new
   and additive: no rule above was rewritten or reflowed, and every selector
   here is a class the home page carries and no other page does. Tokens only —
   no new colours are invented.
   ========================================================================== */

/* ---------- hero flag row --------------------------------------------------
   The live open/closed eyebrow and the "New — Pizza" flag sit on one line and
   share the eyebrow's 20px gap to the headline, so neither doubles the space. */

.hero-flags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 0 0 20px;
}
.hero-flags > .eyebrow { margin-bottom: 0; }

/* The pizza announcement. Same pill shape as .eyebrow so it reads as a sibling,
   but tomato rather than basil, and a link rather than a label because it goes
   somewhere. Ink on white for the sentence (14.9:1), white on tomato for the
   tag (4.89:1) — both clear AA. */
.new-flag {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 4px 16px 4px 4px;
  border-radius: var(--pill);
  border: 1px solid rgba(var(--tom-rgb), .3);
  background: var(--w);
  color: var(--ink);
  text-decoration: none;
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.3;
  transition: transform .34s var(--spring), border-color .18s, box-shadow .22s;
}
.new-flag:hover {
  color: var(--ink);
  border-color: var(--tom);
  box-shadow: 0 8px 20px rgba(var(--tom-rgb), .18);
  transform: translateY(-2px);
}
.new-flag .nf-tag {
  position: relative;
  flex: none;
  background: var(--tom);
  color: #fff;
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  padding: 5px 11px;
  border-radius: var(--pill);
  line-height: 1.35;
}
/* one slow ring off the tag, so "new" registers without nagging */
.new-flag .nf-tag::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--pill);
  border: 1.5px solid var(--tom);
  animation: nf-ring 3.2s var(--ease) infinite;
  pointer-events: none;
}
@keyframes nf-ring {
  0%   { opacity: .55; transform: scale(1); }
  62%  { opacity: 0;   transform: scale(1.45); }
  100% { opacity: 0;   transform: scale(1.45); }
}
.new-flag .nf-go::after {
  content: " \2192";
  display: inline-block;
  color: var(--tom);
  transition: transform .25s var(--ease);
}
.new-flag:hover .nf-go::after { transform: translateX(4px); }
@media (prefers-reduced-motion: reduce) {
  .new-flag, .new-flag:hover { transform: none; transition: border-color .18s; }
  .new-flag .nf-tag::after { animation: none; opacity: 0; }
  .new-flag:hover .nf-go::after { transform: none; }
}

/* ---------- the small "New" pill, on the pizza chip and the pizza card ---- */

.flag-new {
  display: inline-block;
  vertical-align: middle;
  margin-left: 2px;
  background: var(--tom);
  color: #fff;
  font-size: .58rem;
  font-weight: 700;
  letter-spacing: .13em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--pill);
  line-height: 1.4;
}
.c .b h3 .flag-new { margin-left: 6px; position: relative; top: -2px; }

/* ---------- the pizza feature block -------------------------------------- */

.new-feature {
  display: grid;
  grid-template-columns: .92fr 1.08fr;
  gap: clamp(24px, 3.2vw, 52px);
  align-items: center;
  background: var(--off);
  border: 1px solid var(--line);
  border-radius: 26px;
  padding: clamp(18px, 2.2vw, 26px);
}
@media (max-width: 900px) { .new-feature { grid-template-columns: 1fr; } }

/* The art panel. The art sits on a tomato band with display type behind it
   rather than being floated in an empty box. */
.new-feature-art {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 20px;
  aspect-ratio: 5 / 4;
  display: grid;
  place-items: center;
  background: radial-gradient(125% 125% at 20% 10%, var(--tom-br) 0%, var(--tom) 44%, var(--tom-ink) 100%);
}
.new-feature-art .nf-word {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  z-index: 0;
  font-family: var(--f-display);
  font-size: clamp(4rem, 14vw, 8.5rem);
  font-weight: 800;
  letter-spacing: -0.055em;
  line-height: .8;
  color: rgba(255, 255, 255, .17);
  white-space: nowrap;
  -webkit-user-select: none;
          user-select: none;
}
.new-feature-art > img {
  position: relative;
  z-index: 1;
  width: 66%;
  max-width: 310px;
  /* Without this the height attribute (400) survives as a definite height and
     the square illustration is stretched into a tall oval — on the one panel
     the whole page is built around. */
  height: auto;
  transform: rotate(-6deg);
  filter: drop-shadow(0 20px 34px rgba(0, 0, 0, .34));
  transition: transform .55s var(--spring);
}
.new-feature:hover .new-feature-art > img { transform: rotate(-2deg) scale(1.04); }
@media (prefers-reduced-motion: reduce) {
  .new-feature-art > img,
  .new-feature:hover .new-feature-art > img { transform: rotate(-6deg); transition: none; }
}
/* .has-photo: a photograph is a rectangle with no alpha, so the drop shadow has
   nothing to trace and a portrait source would run past the 5/4 panel. Cropped
   square and given a print edge instead — the tilt still reads, and the word
   behind it stays visible. 68% keeps the rotated corners inside the panel. */
.new-feature-art.has-photo > img {
  width: 68%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 14px;
  border: 5px solid var(--w);
  filter: drop-shadow(0 18px 30px rgba(0, 0, 0, .32));
}

.new-feature-stamp {
  position: absolute;
  z-index: 2;
  top: 16px; left: 16px;
  background: var(--w);
  color: var(--tom-dk);          /* 5.98:1 on white */
  font-size: .62rem;
  font-weight: 700;
  letter-spacing: .17em;
  text-transform: uppercase;
  padding: 7px 14px;
  border-radius: var(--pill);
  box-shadow: 0 6px 16px rgba(0, 0, 0, .2);
}

/* .new-feature-note — the "Illustration · photography to come" caption — was
   removed with the illustration in August 2026, when the client's pizza
   photographs landed. Nothing captions this panel any more. */

.new-feature-body { padding: clamp(4px, 1.2vw, 14px) clamp(4px, 1.4vw, 20px) clamp(4px, 1.2vw, 14px) 0; }
@media (max-width: 900px) { .new-feature-body { padding: 0 6px 10px; } }
.new-feature-body h2 { margin-bottom: .34em; }
.new-feature-body .lede { max-width: 44ch; }

/* the Pizza Night callout — the one deal price the menu page already publishes */
.deal-strip {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 9px 13px;
  margin: 22px 0 26px;
  padding: 14px 18px;
  background: var(--w);
  border: 1px solid var(--line);
  border-left: 4px solid var(--sun);
  border-radius: var(--r-sm);
  font-size: .94rem;
  line-height: 1.5;
}
.deal-strip .deal-tag {
  flex: none;
  font-size: .6rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--sun-ink);                      /* 4.95:1 on the tinted pill */
  background: rgba(242, 169, 59, .22);
  padding: 4px 11px;
  border-radius: var(--pill);
}

/* ---------- catering band ------------------------------------------------
   The solid white eyebrow pill and the #F2F7F3 body copy that used to be
   scoped to this one band are now the shared .band treatment in section 13,
   because the same two contrast numbers applied to all five green bands and
   not only to this one. Nothing is left here to override; .eyebrow-solid
   stays a valid class on the home page markup and simply matches. */

.cater-points {
  list-style: none;
  margin: 24px 0 30px;
  padding: 0;
  display: grid;
  gap: 11px;
  max-width: 46ch;
}
.cater-points li {
  position: relative;
  padding-left: 30px;
  font-size: .96rem;
  line-height: 1.5;
  color: var(--body);
}
/* White on the deep green is 8.32:1 against the band copy's 7.68:1, and the
   ticks take the same currentColor, so the list reads a step ahead. */
.band .cater-points li { color: #fff; }
.cater-points li::before {
  content: "";
  position: absolute;
  left: 5px; top: .42em;
  width: 8px; height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: rotate(45deg);
  opacity: .85;
}

/* ---------- print --------------------------------------------------------- */

@media print {
  .new-feature { border: 1px solid #bbb !important; break-inside: avoid; }
  .new-feature-art { border: 1px solid #bbb !important; min-height: 140px; }
  .new-feature-art .nf-word { display: none !important; }
  .new-feature-art > img { transform: none !important; filter: none !important; }
  .new-flag .nf-tag::after { display: none !important; }
  .deal-strip { border: 1px solid #ccc !important; }
}

/* ==========================================================================
   25. MOTION — EXTENDED
   Added in the animation pass. Everything here is additive: no rule above was
   rewritten or reflowed. It extends the two engines that already exist rather
   than introducing a third — the IntersectionObserver reveal and the .px
   parallax — and every single thing in it is switched off further down under
   `prefers-reduced-motion: reduce`, neutralised for `.no-js`, and flattened
   for print. Transform and opacity only; nothing here can trigger layout.
   ========================================================================== */

/* ---------- two more reveal variants -------------------------------------
   `pop`  — springs up in scale, for a small card or badge that should land
            rather than slide. No translation, so it is safe inside a
            horizontally scrolling strip.
   `lift` — a taller travel with a touch of scale, for the big photographic
            and feature blocks that need more weight than a 20px nudge.      */

[data-anim="pop"]  { transform: scale(.94); }
[data-anim="lift"] { transform: translateY(30px) scale(.978); }

[data-anim="pop"].in {
  transition:
    opacity .5s var(--ease) var(--d),
    transform .62s var(--spring) var(--d);
}
[data-anim="lift"].in {
  transition:
    opacity .8s var(--ease) var(--d),
    transform .9s cubic-bezier(.16, 1, .3, 1) var(--d);
}

/* ---------- group stagger -------------------------------------------------
   `data-anim-list` on a container; its direct children cascade. The container
   is the only thing JavaScript observes or writes a class to, so a grid, a
   chip row, a menu list or a field group is staggered by one attribute on one
   structural element — no per-child markup, and nothing to keep in sync when
   an item is added or removed.

   The ladder is plain nth-child so it costs nothing at runtime; anything past
   the fourteenth child lands on the shared cap rather than trailing forever. */

[data-anim-list] > * {
  --sd: 700ms;                 /* the cap, overridden by the ladder below */
  opacity: 0;
  transform: translateY(14px);
}
[data-anim-list="pop"]  > * { transform: scale(.94); transform-origin: 50% 65%; }
[data-anim-list="fade"] > * { transform: none; }

[data-anim-list].in > * {
  opacity: 1;
  transform: none;
  transition:
    opacity .55s var(--ease) var(--sd),
    transform .6s var(--ease) var(--sd);
}
[data-anim-list="pop"].in > * {
  transition:
    opacity .42s var(--ease) var(--sd),
    transform .55s var(--spring) var(--sd);
}

[data-anim-list] > *:nth-child(1)  { --sd: 0ms; }
[data-anim-list] > *:nth-child(2)  { --sd: 50ms; }
[data-anim-list] > *:nth-child(3)  { --sd: 100ms; }
[data-anim-list] > *:nth-child(4)  { --sd: 150ms; }
[data-anim-list] > *:nth-child(5)  { --sd: 200ms; }
[data-anim-list] > *:nth-child(6)  { --sd: 250ms; }
[data-anim-list] > *:nth-child(7)  { --sd: 300ms; }
[data-anim-list] > *:nth-child(8)  { --sd: 350ms; }
[data-anim-list] > *:nth-child(9)  { --sd: 400ms; }
[data-anim-list] > *:nth-child(10) { --sd: 450ms; }
[data-anim-list] > *:nth-child(11) { --sd: 500ms; }
[data-anim-list] > *:nth-child(12) { --sd: 550ms; }
[data-anim-list] > *:nth-child(13) { --sd: 600ms; }
[data-anim-list] > *:nth-child(14) { --sd: 650ms; }

/* ---------- parallax inside the frame -------------------------------------
   `data-px-inner` on a .px block moves the photograph rather than the plate,
   so the layout never shifts and only the image drifts inside its own crop.
   The engine writes a small scale alongside the drift, which is what keeps it
   safe: an image magnified 8% has roughly four times the margin the drift can
   ever consume, so no edge can pull into view at either end of the scroll.

   Deliberately a transform and not a change of box: the picture's own width,
   height, inset and object-position are untouched, so an art-directed crop
   stays exactly as it was framed. With no JavaScript, reduced motion, or in
   print, no transform is written at all and the image is simply itself.      */

[data-px-inner] > img { will-change: transform; }

/* ---------- micro-interactions --------------------------------------------
   Hover and focus feedback on the things that are actually pressable. Each is
   a transform, so none of them can cost a layout pass, and each has a
   deliberate resting state to return to.                                     */

/* buttons press in when held */
.btn:active { transform: translateY(0) scale(.975); }

/* chips: the lift already exists above; this is the press that answers it */
.chip:active { transform: translateY(-1px) scale(.985); }

/* ---- keeping the hover states that the reveal would otherwise flatten ----
   `[data-anim].in` and `[data-anim-list].in > *` both resolve to
   `transform: none`, and both out-rank a hover rule written earlier in this
   sheet at equal specificity. These two put the hover back for the only
   elements where a reveal and a hover transform land on the same node. */
[data-anim-list].in > .chip:hover  { transform: translateY(-3px) scale(1.03); }
[data-anim-list].in > .chip:active { transform: translateY(-1px) scale(.985); }

.hshot:hover .float[data-anim].in {
  transform: translateY(-4px);
  box-shadow: 0 18px 44px rgba(var(--ink-rgb), .18);
}

/* dish cards — the photograph eases in behind its own crop on hover */
.c .img > img { transition: transform .65s var(--ease); }
.c:hover .img > img,
.c:focus-within .img > img { transform: scale(1.045); }

/* menu rows: a soft band that reaches past the text column, and a price that
   steps toward it. Nothing moves the row itself, so a long list stays still. */
.menu-item { transition: background-color .2s var(--ease), box-shadow .2s var(--ease); }
.menu-item:hover {
  background-color: rgba(var(--basil-rgb), .05);
  box-shadow: -14px 0 rgba(var(--basil-rgb), .05), 14px 0 rgba(var(--basil-rgb), .05);
}
.menu-item .mi-price { transition: transform .3s var(--spring); }
.menu-item:hover .mi-price { transform: translateX(-4px); }

/* the sticky menu rail marks the section you are actually in */
.rail a:not(.btn) { position: relative; }
.rail a:not(.btn)::before {
  content: "";
  position: absolute;
  left: 6px; top: 50%;
  width: 5px; height: 5px;
  margin-top: -2.5px;
  border-radius: 50%;
  background: var(--tom);
  transform: scale(0);
  transition: transform .32s var(--spring);
}
.rail a:not(.btn).active::before { transform: scale(1); }

/* numbered and occasion blocks answer the pointer like the cards do */
.step { transition: transform .38s var(--spring); }
.step:hover { transform: translateY(-3px); }

.occasions li { transition: transform .32s var(--spring), border-color .2s ease, background-color .2s ease; }
.occasions li:hover {
  transform: translateY(-2px);
  border-color: var(--basil);
  background: rgba(var(--basil-rgb), .06);
}

/* the FAQ's plus sign swells slightly under the pointer */
.faq summary::after { transition: transform .3s var(--spring); }
.faq summary:hover::after { transform: scale(1.16); }

/* the brand's full stop hops. One character, once, on hover. */
.brand .dot-mark { display: inline-block; transition: transform .45s var(--spring); }
.brand:hover .dot-mark { transform: translateY(-4px); }

/* ---------- form feedback -------------------------------------------------
   The enquiry form is the one place on the site where motion carries meaning
   rather than polish, so it is the one place that animates on its own.       */

@keyframes field-shake {
  20% { transform: translateX(-3px); }
  40% { transform: translateX(4px); }
  60% { transform: translateX(-3px); }
  80% { transform: translateX(2px); }
}
.field.invalid input,
.field.invalid select,
.field.invalid textarea { animation: field-shake .4s var(--ease); }

@keyframes err-in { from { opacity: 0; transform: translateY(-3px); } }
.field.invalid .err { animation: err-in .26s var(--ease) both; }

@keyframes msg-in { from { opacity: 0; transform: translateY(10px); } }
.form-msg.show { animation: msg-in .45s var(--ease) both; }

/* ---------- no-JS safety net ----------------------------------------------
   Same contract as the original: with no JavaScript nothing is ever left
   hidden behind a class that will not arrive.                                */

.no-js [data-anim-list] > * {
  opacity: 1;
  transform: none;
  transition: none;
}
.no-js [data-px-inner] > img { will-change: auto; }

/* ---------- the off switch ------------------------------------------------ */

@media (prefers-reduced-motion: reduce) {
  [data-anim="pop"], [data-anim="pop"].in,
  [data-anim="lift"], [data-anim="lift"].in {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  [data-anim-list] > *,
  [data-anim-list].in > * {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* the picture sits square in its frame; the engine never runs to move it */
  .px, [data-px-inner] > img {
    transform: none !important;
    will-change: auto;
  }

  .btn:active,
  .chip:active,
  .c:hover .img > img,
  .c:focus-within .img > img,
  .menu-item:hover .mi-price,
  .step:hover,
  .occasions li:hover,
  .faq summary:hover::after,
  .brand:hover .dot-mark { transform: none; }

  .c .img > img,
  .menu-item, .menu-item .mi-price,
  .step, .occasions li,
  .faq summary::after,
  .brand .dot-mark,
  .rail a:not(.btn)::before { transition: none; }

  /* the rail marker is a state, not a flourish: it appears, it does not grow */
  .rail a:not(.btn)::before { transform: scale(0); }
  .rail a:not(.btn).active::before { transform: scale(1); }

  .field.invalid input,
  .field.invalid select,
  .field.invalid textarea,
  .field.invalid .err,
  .form-msg.show { animation: none; }
}

/* ---------- print --------------------------------------------------------- */

@media print {
  [data-anim="pop"], [data-anim="pop"].in,
  [data-anim="lift"], [data-anim="lift"].in,
  [data-anim-list] > *,
  [data-anim-list].in > * {
    opacity: 1 !important;
    transform: none !important;
  }
  /* the engine leaves an inline transform behind, which only !important can
     undo: on paper every parallax block sits exactly where the layout put it */
  .px, [data-px-inner] > img { transform: none !important; }
  .menu-item { box-shadow: none !important; }
  .rail a:not(.btn)::before { display: none !important; }
  .field.invalid input,
  .field.invalid select,
  .field.invalid textarea,
  .field.invalid .err,
  .form-msg.show { animation: none !important; }
}
