@font-face{font-family:'Satoshi';font-style:normal;font-weight:300 900;font-display:swap;src:url(/assets/fonts/satoshi-variable.woff2) format('woff2')}

:root{
  --cream:#FBF7F0; --cream2:#F4EDE0; --sage:#E3EFE4; --sage2:#CDE4D2; --sage3:#8EB69B;
  /* --mut was #6E7362, which lands at 4.29:1 on the cream ground and fails AA
     on every interior page's body copy. It now matches --meta, which is the
     colour the operator's own "one colour for prose" pass already moved to. */
  --ink:#10241D; --mut:#6B6455; --line:#E2DCCB;
  --go:#1E8A4C; --go-d:#235347; --go-t:#DAF1DE;
  --hero1:#2FA05F; --hero2:#1E8A4C; --hero3:#14603A; --hero4:#0E4A2C;
  --r:18px;

  /* ---------- TYPE SCALE ----------
     Seven steps, and nothing outside them. The file previously carried 47
     distinct font sizes accumulated across a dozen passes, including a 1rem
     and a 1.0625rem sitting one pixel apart, which is what made sections read
     as "smaller and a different voice" rather than as a hierarchy.

     The root is 17px, so 1rem is already 17px here, not 16px. Every step below
     is expressed in rem so the whole system moves with that one number and
     with a reader who raises their browser text size.

     The floor is deliberately high. The buyer is 30 to 50, on a phone, at
     arm's length: nothing on this site renders below 14px, and the chips and
     city pills that used to sit at 11.5px are now readable.

     --fs-micro is written as a calc so the intent stays legible: 14px against
     the 17px root. Hard-coding 0.8235rem would work and tell nobody why. */
  --fs-micro:calc(14 / 17 * 1rem); /* 14px - chips, city pills, legal, captions */
  --fs-label:0.9375rem;   /* 15.9px - eyebrows, nav, buttons, small links */
  --fs-body:1.0625rem;    /* 18.1px - every piece of reading text */
  --fs-lead:1.1875rem;    /* 20.2px - section subs and intro lines */
  --fs-title:1.375rem;    /* 23.4px - h3, card titles, stat numerals */
  --fs-h2:clamp(1.75rem,3.2vw,2.375rem);      /* 29.8 - 40.4px section statements */
  --fs-display:clamp(2.375rem,4.2vw,3.25rem); /* 40.4 - 55.3px hero only */
}
*{box-sizing:border-box;margin:0}
/* width/height attributes on an image reserve its space and stop layout shift,
   but wherever CSS sets only the width the attribute height wins and squashes
   or stretches the picture. height:auto lets the ratio win while the attributes
   still reserve. Every rule that wants a fixed height sets one and outranks
   this. Bit .pgrid images once and .gyro-float once. */
img{height:auto}
/* Operator type bump: 1rem is 17px, so every rem-sized element on the site
   scales with it instead of being nudged one rule at a time. */
html{scroll-behavior:smooth;font-size:17px}
/* The face is set once, below, as var(--font-body). This rule used to carry a
   system stack that Hanken Grotesk has superseded everywhere. */
body{background:var(--cream);color:var(--ink);line-height:1.5}
h1,h2,h3{line-height:1.08;letter-spacing:-.015em;text-wrap:balance}
/* Eyebrows. One declaration, not four. Always the body face: Fraunces on a
   tracked eyebrow directly above a Fraunces headline made the pair read as a
   single block. Sits on --fs-label, up from 14px, because a tracked uppercase
   line is the hardest thing on the page to read at arm's length. */
.tag{font-family:var(--font-body);font-size:var(--fs-label);font-weight:600;letter-spacing:.18em;line-height:1.4;text-transform:uppercase;color:var(--hunter)}
/* Section subs and intro lines sit one step above body. They are the line a
   skimmer actually reads, and they were previously the same size as prose. */
.sub{color:var(--mut);font-size:var(--fs-lead)}
.cta{display:inline-block;background:var(--go);color:#fff;font-weight:700;text-decoration:none;border-radius:12px;padding:14px 26px;font-size:var(--fs-body);box-shadow:0 6px 18px rgba(30,138,76,.28)}
.cta:hover{background:var(--go-d)}
.cta.ghost{background:transparent;color:var(--go-d);border:2px solid var(--go);box-shadow:none}
.ic{width:30px;height:30px;stroke:var(--go-d);fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
section{scroll-margin-top:20px}

/* ---------- HERO (Surge) ---------- */
.hero{min-height:84vh;display:flex;flex-direction:column;align-items:flex-start;justify-content:center;text-align:left;
  background-image:url(/assets/img/hero-office-spread.webp);background-size:cover;background-position:center right;
  background-color:#0B2B26;
  color:#fff;position:relative;overflow:hidden;padding:64px 6vw 120px}
.hero .tag{color:#BFE8CC}
.hero h1{font-size:var(--fs-display);margin:12px 0 12px;color:#fff;max-width:16ch}
/* The hero card's frosted-glass treatment was retired when the hero scrim
   landed: the gradient does the legibility work, so the panel is transparent.
   Only the measure survives. */
.hero-copy{max-width:520px}
.hero-cta{background:#fff;color:#14603A;font-size:var(--fs-body);padding:13px 26px;box-shadow:0 10px 26px rgba(8,34,20,.4)}
.hero-cta:hover{background:#E9F6EE;color:#0E4A2C}
.glass-ghost{background:transparent;color:#fff;border:2px solid rgba(255,255,255,.5);box-shadow:none;font-size:var(--fs-body);padding:11px 22px;margin-left:10px}
.glass-ghost:hover{background:rgba(255,255,255,.12)}
.hero .sub{color:#DCEFE2;max-width:40ch;margin:0 0 24px;font-size:var(--fs-lead);line-height:1.5}
.nav{position:sticky;top:0;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;column-gap:24px;padding:13px 4vw;font-size:var(--fs-label);z-index:40;background:rgba(240,247,242,.55);backdrop-filter:blur(10px) saturate(1.35);-webkit-backdrop-filter:blur(10px) saturate(1.35);border-bottom:1px solid rgba(35,83,71,.14);transition:background .3s,box-shadow .3s}
.nav.scrolled{background:rgba(240,247,242,.74);box-shadow:0 6px 22px rgba(5,31,32,.14)}
.nav .links{justify-self:center}
.nav .ncall{justify-self:end}
.nav .links{display:flex;gap:36px;font-weight:700}
.nav .links a{color:#163832;text-decoration:none}
.nav .links a:hover{color:#1E8A4C}
.nav .ncall{background:var(--go);border:none;color:#fff;font-weight:700;text-decoration:none;padding:11px 22px;border-radius:22px}
.nav .ncall:hover{background:#DAF1DE;color:#0B2B26}
.nav .links a{color:inherit;text-decoration:none}
.logo{font-weight:700;letter-spacing:.05em;color:#fff}
.hero>*{position:relative}
@media (max-width:700px){.hero{background-position:72% center;padding:96px 5vw 110px}.hero-copy{max-width:100%;padding:24px 20px}.nav{grid-template-columns:auto auto;justify-content:space-between}.nav .links{display:none}
  /* The hamburger's 6px of side padding is invisible, but the layout spaces
     the padding box rather than the bars, so the icon reads as sitting 6px
     too far right of the call button and 6px too far in from the edge.
     Negative margins on BOTH sides take the padding out of the layout, so
     what gets spaced is the ink: gutters match the logo's and the gap either
     side of the call button comes out equal. Vertical padding takes the tap
     target from 38px to 44px without changing where anything sits. */
  .nav .mtoggle{padding:13px 6px;margin:0 -6px}}

/* ---------- STATS ---------- */
.strip{display:grid;grid-template-columns:repeat(4,1fr);background:#fff;border:1px solid var(--line);max-width:880px;margin:-56px auto 0;position:relative;z-index:6;border-radius:20px;box-shadow:0 22px 46px rgba(34,48,31,.13);overflow:hidden}
.strip div{padding:20px 14px;text-align:center;border-right:1px solid var(--line)}
.strip div:last-child{border-right:none}
.strip b{display:block;font-size:var(--fs-title);color:var(--go-d)}
.strip span{font-size:var(--fs-micro);color:var(--mut)}

/* ---------- TRIAGE (Drop-Off / Hybrid / Full-Service) ---------- */
.triage{padding:80px 5vw 70px;background:var(--cream)}
.triage .head{text-align:center;max-width:60ch;margin:0 auto 46px}
.triage h2{font-size:var(--fs-h2);margin:10px 0 10px}
.lane{max-width:1060px;margin:0 auto;position:relative}
.lane .track{position:absolute;top:34px;left:10%;right:10%;height:2px;background:var(--sage2)}
.lv{display:grid;grid-template-columns:repeat(3,1fr);gap:22px;position:relative}
.lv .step{background:#fff;border:1px solid var(--line);border-radius:26px;padding:26px 24px 22px;text-align:center;position:relative;
  transition:transform .25s,border-color .25s,box-shadow .25s}
.lv .step:hover,.lv .step:focus-within{transform:translateY(-6px);border-color:var(--go);box-shadow:0 14px 34px rgba(34,48,31,.10)}
.lv .dot{width:34px;height:34px;border-radius:50%;background:var(--go-t);color:var(--go-d);font-weight:600;font-size:var(--fs-label);
  display:flex;align-items:center;justify-content:center;margin:0 auto 14px;border:2px solid var(--go)}
.lv h3{font-size:var(--fs-title);margin-bottom:6px}
.lv p{font-size:var(--fs-label);color:var(--mut);max-width:30ch;margin:0 auto}
.lv .more{display:grid;grid-template-rows:0fr;overflow:hidden}
.lv .more>*{min-height:0}
.lv .step:hover .more,.lv .step:focus-within .more{grid-template-rows:1fr}
.lv ul{list-style:none;padding:14px 0 0;font-size:var(--fs-micro);color:var(--ink);display:flex;flex-direction:column;gap:5px}
.lv ul li::before{content:"\00B7 ";color:var(--go)}
.lv .step a{display:inline-block;margin-top:14px;font-size:var(--fs-label);font-weight:700;color:var(--go-d);text-decoration:none}
.triage .foot{text-align:center;margin-top:34px;font-size:var(--fs-label);color:var(--mut)}
.triage .foot a{color:var(--go-d);font-weight:700}

/* ---------- HUB (branching selector) ---------- */
.hub{padding:80px 5vw;background:var(--sage);border-radius:70px 70px 0 0}
.hub .head{text-align:center;max-width:60ch;margin:0 auto 40px}
.hub h2{font-size:var(--fs-h2);margin:10px 0 10px}
.hubwrap{max-width:900px;margin:0 auto}
.tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}
.tile{position:relative;background:#fff;border:2px solid var(--sage2);border-bottom:4px solid var(--sage3);border-radius:20px;padding:24px 14px 20px;text-align:center;cursor:pointer;transition:transform .2s,border-color .2s,box-shadow .2s;font-weight:700;font-size:var(--fs-label);display:flex;flex-direction:column;align-items:center;gap:10px;box-shadow:0 3px 10px rgba(16,36,29,.06)}
.tile .go{position:absolute;top:10px;right:10px;width:24px;height:24px;border-radius:50%;background:var(--go-t);color:var(--go-d);display:flex;align-items:center;justify-content:center;font-weight:600;font-size:var(--fs-label);line-height:1}
.tile:hover .go,.tile.on .go{background:#fff;color:var(--go-d)}
.tile:hover{transform:translateY(-4px);border-color:var(--go);border-bottom-color:var(--go-d);box-shadow:0 12px 26px rgba(16,36,29,.14)}
.tile:active{transform:translateY(-1px)}
.tile.on{background:var(--go);border-color:var(--go);border-bottom-color:var(--go-d);color:#fff}
.tile.on .ic{stroke:#fff}
.branch{margin-top:18px;display:none;position:relative;padding-top:26px}
.branch.show{display:block}
.branch::before{content:"";position:absolute;top:0;left:50%;width:2px;height:26px;background:var(--go);transform:translateX(-50%)}
.branch .opts{display:flex;justify-content:center;gap:12px;flex-wrap:wrap}
.branch .opt{background:#fff;border:2px solid var(--go);color:var(--go-d);border-radius:16px;padding:14px 22px;font-weight:700;
  font-size:var(--fs-label);text-decoration:none;display:flex;align-items:center;gap:9px;
  animation:rise .35s ease both}
.branch .opt:hover{background:var(--go);color:#fff}
.branch .opt:hover .ic{stroke:#fff}
.branch .opt .ic{width:20px;height:20px}
.branch .opt:nth-child(2){animation-delay:.06s}.branch .opt:nth-child(3){animation-delay:.12s}
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){
  .branch .opt{animation:none}
  .lv .step,.tile{transition:none}
}
.hub .path{ text-align:center;margin-top:22px;font-size:var(--fs-micro);color:var(--mut)}

/* ---------- FOOD FLEX ---------- */
.flex{padding:90px 5vw;background:var(--cream);display:grid;grid-template-columns:.9fr 1.1fr;gap:6vw;max-width:1150px;margin:0 auto;align-items:center}
.flex h2{font-size:var(--fs-h2);margin:12px 0 14px}
.flex p{font-size:var(--fs-body);color:var(--mut);max-width:48ch;margin-bottom:14px}
.diet{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 26px}
.diet i{font-style:normal;font-size:var(--fs-micro);font-weight:700;background:var(--go-t);color:var(--go-d);border-radius:16px;padding:6px 13px}

/* ---------- TRUST + FINAL ---------- */
/* The bohemian texture layer behind the trust band was retired with the slab
   pass. Its ::before is gone rather than carried as a display:none override. */
.trust{background:var(--sage);padding:64px 5vw;text-align:center;border-radius:70px 70px 0 0;position:relative;overflow:hidden}
.trust>*{position:relative}
.trust h2{font-size:var(--fs-h2);margin-bottom:10px}
.trust .sub{max-width:52ch;margin:0 auto 26px}
.areas{display:flex;flex-wrap:wrap;gap:7px;justify-content:center;max-width:760px;margin:0 auto 34px}
.areas i,.areas a{font-style:normal;font-size:var(--fs-micro);font-weight:600;background:#fff;border:1px solid var(--line);border-radius:16px;padding:5px 12px}
footer{background:var(--cream);padding:30px 5vw;font-size:var(--fs-micro);color:var(--mut);display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}

@media (max-width:860px){
  .strip{grid-template-columns:repeat(2,1fr);margin:-44px 16px 0}
  .lv,.tiles{grid-template-columns:1fr 1fr}
  .lane .track{display:none}
  .flex{grid-template-columns:1fr}
}
@media (max-width:520px){
  .lv{grid-template-columns:1fr}
}
/* Load feel. Short and quick: 10px over .5s, not 20px over .65s. The longer
   version announced itself identically on every section and read as a template
   rather than as craft. Siblings stagger off --i, which reveal.js numbers per
   parent, so a row of cards arrives one after another instead of as one slab.

   It runs as an animation on `translate`, not a transition on `transform`, for
   two reasons: the hub tiles set an inline transform for the cursor tilt and a
   transition would fight it, and several components redeclare the transition
   shorthand later in this file, which silently dropped the reveal. */
@keyframes rvin{from{opacity:0;translate:0 10px}to{opacity:1;translate:none}}
/* The stagger is a delay on when .in is added, not an animation-delay with a
   fill. That matters for safety: the hidden state hangs off :not(.in), so the
   instant .in lands the element is visible by its own default and the animation
   only supplies the motion. An animation that never runs, in any browser or any
   throttled tab, cannot leave a section stranded at opacity 0. */
.rv:not(.in){opacity:0}
.rv.in{animation:rvin .5s cubic-bezier(.2,.7,.2,1)}
@media (prefers-reduced-motion:reduce){.rv,.rv:not(.in),.rv.in{opacity:1;translate:none;animation:none}}
/* interior page bits */
.page-hero{background:linear-gradient(120deg,#0B2B26,#163832 60%,#235347);color:#fff;padding:72px 6vw 64px}
.page-hero h1{font-size:var(--fs-display);max-width:20ch;margin:10px 0 12px}
.page-hero .sub{color:#DAF1DE;max-width:52ch;font-size:var(--fs-lead)}
.page-hero .tag{color:#8EB69B}
.pgrid{display:grid;grid-template-columns:1.1fr .9fr;gap:5vw;align-items:center;max-width:1150px;margin:0 auto;padding:70px 6vw}
.pgrid img{width:100%;border-radius:24px;display:block}
.pgrid h2{font-size:var(--fs-h2);margin:8px 0 12px}
.pgrid p{color:var(--mut);margin-bottom:12px;max-width:52ch}
/* Occasion list inside a .pgrid text column. Two scannable columns so the
   occasions read as a list instead of a run-on sentence. */
.occl{list-style:none;margin:0 0 16px;padding:0;max-width:52ch;
  display:grid;grid-template-columns:1fr 1fr;gap:8px 20px}
.occl li{color:var(--mut);position:relative;padding-left:18px}
.occl li::before{content:"";position:absolute;left:0;top:.6em;
  width:7px;height:7px;border-radius:50%;background:var(--go-d)}
@media (max-width:420px){.occl{grid-template-columns:1fr}}
.dishrow{display:flex;justify-content:center;gap:26px;flex-wrap:wrap;padding:56px 6vw;max-width:1150px;margin:0 auto}
.dishrow figure{margin:0;text-align:center;width:150px}
.dishrow img{width:150px;height:150px;object-fit:cover;border-radius:50%;display:block;transition:transform .5s cubic-bezier(.2,.8,.2,1)}
.dishrow figure:hover img{transform:rotate(28deg)}
.dishrow figcaption{font-size:var(--fs-micro);font-weight:700;margin-top:10px;color:var(--ink)}
@media (max-width:860px){.pgrid{grid-template-columns:1fr}}

/* mobile hero legibility: scrim + reframed crop (mobile-only) */
@media (max-width:700px){
  .hero{background-position:74% 30%}
  
  .hero-copy{position:relative;z-index:2}
}

/* services index grid */
.sgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:22px;max-width:1150px;margin:0 auto;padding:60px 6vw}
.scard{display:block;background:#fff;border:1px solid var(--line);border-radius:20px;overflow:hidden;text-decoration:none;color:var(--ink);transition:transform .2s,box-shadow .2s,border-color .2s}
.scard:hover{transform:translateY(-5px);border-color:var(--go);box-shadow:0 16px 34px rgba(16,36,29,.13)}
.scard img{width:100%;height:180px;object-fit:cover;display:block}
.scard .scb{padding:16px 18px 18px}
.scard h3{font-size:var(--fs-title);margin-bottom:5px}
.scard p{font-size:var(--fs-label);color:var(--mut);margin-bottom:10px}
.scgo{font-size:var(--fs-label);font-weight:700;color:var(--go-d)}


/* ============================================================
   BRAND KIT v1 (Fresh Modernist) override layer
   ============================================================ */
:root{
  --cream:#FBF7F0; --hunter:#235347; --hunter-d:#1A423B; --sage-k:#8EB69B;
  --gold:#D9A73C; --gold-t:#FCF3DE; --go:#1E8A4C; --go-hover:#187A42;
  --ink:#051F20; --body-tx:#3D4540; --meta:#6B6455; --hairline:#DAD3C4;
  --ondark:#E8E0D2; --mint:#DAF1DE;
  --font-display:'Satoshi',system-ui,sans-serif;
  --font-body:'Satoshi',system-ui,sans-serif;
}
body{font-family:var(--font-body);color:var(--body-tx)}
h1,h2,h3{font-family:var(--font-display);color:var(--ink)}
/* ---------- HEADING WEIGHTS ----------
   One declaration each, not four. These three rules were previously restated
   in four separate passes with contradictory values, so the winner depended on
   source order rather than on a decision.

   Weight steps UP as size goes up. This inverted on 2026-08-15 with the move to
   Satoshi. The old rule stepped down, which is right for a serif with an optical
   size axis, but the site now runs one grotesk for everything. With no second
   face doing the work, a heading separates from body copy only by weight and by
   tracking, so headings take 700 and tighten as they grow. Body stays 400. */
.hero h1,.page-hero h1{color:#FBF7F0;font-weight:700;letter-spacing:-0.03em;font-size:var(--fs-display)}
h2{font-weight:700;letter-spacing:-0.02em;font-size:var(--fs-h2)}
h3{font-weight:700;letter-spacing:-0.015em;font-size:var(--fs-title)}
p,li{font-size:var(--fs-body)}
.sub{color:var(--meta)}
.hero .sub,.page-hero .sub{color:var(--ondark)}

/* eyebrow colour only; face, size and tracking are set once at the top */
.hero .tag,.page-hero .tag,.trust .tag{color:var(--gold)}

/* buttons */
.cta{font-family:var(--font-display);font-weight:600;border-radius:8px;padding:13px 24px;white-space:nowrap;background:var(--go);box-shadow:none}
.cta:hover{background:var(--go-hover)}
.cta.ghost{border:1px solid rgba(35,83,71,.45);color:var(--hunter);background:transparent}
.hero-cta{background:var(--go);color:#FBF7F0}
.hero-cta:hover{background:var(--go-hover);color:#FBF7F0}
.glass-ghost{background:rgba(251,247,240,.08);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);border:1px solid rgba(218,241,222,.25);border-radius:8px;color:#FBF7F0}
.glass-ghost:hover{background:rgba(251,247,240,.16)}
.nav .ncall{font-family:var(--font-display);font-weight:600;border-radius:8px}

/* dark surfaces capped at hunter range */
.hero{background-color:var(--hunter-d)}
.page-hero{background:linear-gradient(115deg,var(--hunter),var(--hunter-d))}
.hero-copy{background:rgba(26,66,59,.45);border:1px solid rgba(218,241,222,.25);border-radius:12px}

/* trust band: dark hunter close (bohemian texture retired) */
.trust{background:linear-gradient(115deg,var(--hunter),var(--hunter-d));border-radius:0}
.trust h2{color:#FBF7F0}
.trust .sub{color:var(--ondark)}
.trust .areas i{background:rgba(251,247,240,.08);border:1px solid rgba(218,241,222,.25);color:var(--mint)}
/* A city with its own location page gets a solid cream chip, so the places
   you can click through to read about stand out from the rest of the
   service area. Set on the pill by src/components/Areas.astro. */
/* Cities with their own location page are links, and read as glossy white
   against the hunter band so they are visibly the clickable ones. */
.trust .areas a{
  background:linear-gradient(180deg,#FFF,#EDF2EE);
  border:1px solid #FFF;
  color:var(--hunter);
  font-weight:700;
  text-decoration:none;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 1px 4px rgba(5,31,32,.22)}
.trust .areas a:hover,.trust .areas a:focus-visible{
  background:#FFF;
  box-shadow:inset 0 1px 0 rgba(255,255,255,1),0 3px 9px rgba(5,31,32,.3);
  transform:translateY(-1px)}
.trust .areas a.all{
  background:transparent;
  border-color:var(--mint);
  color:var(--mint);
  box-shadow:none}
.trust .areas a.all:hover,.trust .areas a.all:focus-visible{
  background:rgba(218,241,222,.14);
  box-shadow:none}
footer{background:var(--hunter-d);color:var(--ondark)}
footer a{color:var(--mint);text-decoration:none}

/* cards, chips, radii per kit */
.lv .step,.scard{border-radius:12px}
.tile{border-radius:12px}
.lv .step{border:1px solid var(--hairline)}
.lv .step:hover,.lv .step:focus-within{border-color:var(--gold);box-shadow:0 10px 26px rgba(16,36,29,.10)}
.lv .dot{background:var(--gold-t);color:var(--ink);border:2px solid var(--gold);font-family:var(--font-display)}
.tile:hover{border-color:var(--gold);border-bottom-color:var(--gold);box-shadow:0 10px 24px rgba(16,36,29,.12)}
.tile .go{background:var(--gold-t);color:var(--ink)}
.tile.on{background:var(--hunter);border-color:var(--hunter);border-bottom-color:var(--hunter-d)}
.branch .opt{border:1px solid #C9C1B0;color:var(--ink);background:#fff;border-radius:999px}
.branch .opt:hover{border-color:var(--gold);background:var(--gold-t);color:var(--ink)}
.branch .opt:hover .ic{stroke:var(--hunter)}
.areas i,.areas a{border-radius:999px;border:1px solid #C9C1B0;color:var(--ink)}

/* icons: 1.5px stroke, hunter on cream / mint on hunter */
.ic{stroke-width:1.5;stroke:var(--hunter)}
.hero .ic,.page-hero .ic,.trust .ic,.tile.on .ic{stroke:var(--mint)}

/* stats strip numerals */
.strip b{font-family:var(--font-display);color:var(--hunter)}
.strip{border-radius:12px}

/* list markers: no dash glyphs */
.lv ul li::before{content:"· ";color:var(--go)}

/* focus + motion discipline (impeccable pass) */
a:focus-visible,button:focus-visible,.tile:focus-visible,.step:focus-visible{outline:2px solid var(--gold);outline-offset:2px;border-radius:8px}
/* Tile stagger now comes from --i on .rv, which every group gets. */


/* ============ operator pass 2026-07-24 pm ============ */
/* The "weights down: bold was bleeding" pass folded into the single heading
   weight block above. */

/* 1rem text floor enforced (kit rule) */
.triage .foot{font-size:var(--fs-body)}
.lv .step p{font-size:var(--fs-body);max-width:32ch}
.lv ul{font-size:var(--fs-body)}
.tile{font-size:var(--fs-body)}
.branch .opt{font-size:var(--fs-body)}

/* warm the sage family: the blue-green cast goes */
:root{--sage:#EDF1E2;--sage2:#DFE8CD;--sage3:#A6BC8B}
.hub{background:var(--sage)}

/* interior page headers: compact band, not a hero */
.page-hero{padding:36px 6vw 30px}
.page-hero h1{font-size:var(--fs-h2)}
.page-hero .sub{font-size:var(--fs-lead);max-width:60ch}


/* ============ operator pass: nav states, floaters, type breathing ============ */
/* The "letters breathe" tracking pass folded into the heading weight block. */

/* reading sizes up for 30-40yo buyers: now the --fs-body step */
.lv .step p{font-size:var(--fs-body)}
.triage .foot{font-size:var(--fs-body)}
.lv ul{font-size:var(--fs-body)}
.strip span{font-size:var(--fs-label)}

/* icons up */
.lv .step .ic{width:42px;height:42px}
.tile .ic{width:38px;height:38px}

/* NAV: green glass over hero at top, white gaussian when scrolled */
.nav{background:rgba(26,66,59,.55);backdrop-filter:blur(8px) saturate(1.2);-webkit-backdrop-filter:blur(8px) saturate(1.2);border-bottom:1px solid rgba(218,241,222,.15);padding:15px 4vw}
.nav .links{font-size:var(--fs-body)}
.nav .links a{color:#FBF7F0}
.nav .links a:hover{color:#DAF1DE}
.nav .ncall{padding:12px 24px;font-size:var(--fs-body)}
.nav .nblogo{display:block}
.nav .logo-light{height:36px;width:auto;display:block}
.nav .logo-dark{height:46px;width:auto;display:none}
.nav.scrolled{background:rgba(240,247,242,.8);border-bottom:1px solid rgba(35,83,71,.14)}
.nav.scrolled .links a{color:#163832}
.nav.scrolled .links a:hover{color:#1E8A4C}
.nav.scrolled .logo-light{display:none}
.nav.scrolled .logo-dark{display:block}

/* hub background: fresh, not puke (yellow pulled back out) */
.hub{background:linear-gradient(180deg,#EBF3EA 0%,#F5F5EE 100%)}

/* phone FAB: mobile only */
.fab{position:fixed;right:18px;bottom:18px;width:58px;height:58px;border-radius:50%;background:var(--go);display:none;align-items:center;justify-content:center;box-shadow:0 10px 26px rgba(5,31,32,.35);z-index:60}
@media (max-width:700px){.fab{display:flex}}

/* back-to-top */
.totop{position:fixed;right:20px;bottom:20px;width:46px;height:46px;border-radius:50%;background:#fff;border:1px solid var(--hairline);color:var(--hunter);display:flex;align-items:center;justify-content:center;box-shadow:0 8px 20px rgba(5,31,32,.18);z-index:59;opacity:0;pointer-events:none;transition:opacity .25s;cursor:pointer}
.totop.show{opacity:1;pointer-events:auto}
@media (max-width:700px){.totop{right:auto;left:18px;bottom:18px}}
@media (prefers-reduced-motion:reduce){.totop{transition:none}}


/* nav floats over the hero: green glass actually glasses the hero */
.nav{position:fixed;top:0;left:0;right:0;width:100%}
.hero{padding-top:150px}
.page-hero{padding-top:120px}
@media (max-width:700px){.hero{padding-top:120px}.page-hero{padding-top:104px}}


/* ============ operator pass: seamless nav, caps, dark hub ============ */
/* nav fully invisible at top: the hero IS the background */
.nav{background:transparent;border-bottom:none;backdrop-filter:none;-webkit-backdrop-filter:none;box-shadow:none}
.nav.scrolled{background:rgba(240,247,242,.82);backdrop-filter:blur(12px) saturate(1.3);-webkit-backdrop-filter:blur(12px) saturate(1.3);border-bottom:1px solid rgba(35,83,71,.12);box-shadow:0 6px 22px rgba(5,31,32,.12)}

/* nav type: branded caps, bigger */
.nav .links{gap:32px}
.nav .links a{font-family:var(--font-display);font-weight:600;font-size:var(--fs-label);text-transform:uppercase;letter-spacing:.08em}
.nav .ncall{text-transform:uppercase;letter-spacing:.06em;font-size:var(--fs-body)}

/* triage detail links up to floor */
.lv .step a{font-size:var(--fs-body)}

/* back-to-top: higher */
.totop{bottom:74px}
@media (max-width:700px){.totop{bottom:74px}}

/* hub goes dark hunter: separates the sections, sage retired here */
.hub{background:linear-gradient(115deg,var(--hunter),var(--hunter-d))}
.hub .head h2{color:#FBF7F0}
.hub .head .sub{color:var(--ondark)}
.hub .path{color:var(--ondark)}
.hub .tag{color:var(--gold)}
.tile{border-color:rgba(218,241,222,.2);border-bottom-color:rgba(5,31,32,.5)}
.tile:hover{border-color:var(--gold);border-bottom-color:var(--gold)}


/* ============ display face -> Satoshi (operator pick, 2026-08-15) ============ */
/* One face for the whole site and every menu, so print and web match. Fraunces
   was cut: it read as newspaper serif and is the default on generated sites.
   Satoshi is a variable grotesk, 300 to 900 in a single 42KB file, so the
   headline separation now comes from weight and tracking, not a second face. */
:root{--font-display:'Satoshi',system-ui,sans-serif}
.strip b{font-weight:600}

/* functional text stays clean grotesk: nav, eyebrows, buttons, chips */
.nav .links a{font-family:var(--font-body);font-weight:600}
.nav .ncall{font-family:var(--font-body);font-weight:600}
.cta{font-family:var(--font-body);font-weight:600}
.tile{font-family:var(--font-body)}
.branch .opt{font-family:var(--font-body);font-weight:600}


/* hero C is a bright office scene: darken the left text zone for contrast */
.hero{background-position:center right}
.hero::after{content:"";position:absolute;inset:0;background:linear-gradient(90deg,rgba(5,31,32,.82) 0%,rgba(5,31,32,.55) 34%,rgba(5,31,32,.10) 58%,rgba(5,31,32,0) 72%);pointer-events:none}
.hero>*{position:relative;z-index:2}
.hero-copy{background:transparent;border:none;box-shadow:none;backdrop-filter:none;-webkit-backdrop-filter:none;padding:0}
@media (max-width:700px){
  /* The copy block runs deeper on a phone now that the type is a step larger,
     so the scrim holds its density further down instead of thinning at 55%. */
  .hero::after{background:linear-gradient(180deg,rgba(5,31,32,.86) 10%,rgba(5,31,32,.78) 55%,rgba(5,31,32,.62) 82%,rgba(5,31,32,.42) 100%)}
}


/* H1 = head term, styled as the eyebrow. Tagline carries the display weight. */
.eyebrow-h1{font-family:var(--font-body);font-weight:600;font-size:var(--fs-label);letter-spacing:0.2em;
  text-transform:uppercase;color:var(--gold);margin:0 0 14px}
.hero-copy .display{font-family:var(--font-display);font-weight:700;letter-spacing:-0.03em;
  font-size:var(--fs-display);line-height:1.08;color:#FBF7F0;margin:0 0 14px;max-width:15ch}


/* specificity: eyebrow-H1 must beat .hero h1 */
.hero .eyebrow-h1,.hero h1.eyebrow-h1{font-family:var(--font-body);font-weight:600;font-size:var(--fs-label);
  letter-spacing:0.2em;text-transform:uppercase;color:var(--gold);margin:0 0 14px;line-height:1.4}

/* nav legibility over a bright hero: top scrim behind the bar */
.nav::before{content:"";position:absolute;inset:0;background:linear-gradient(180deg,rgba(5,31,32,.72),rgba(5,31,32,0));pointer-events:none;z-index:-1}
.nav{position:fixed;isolation:isolate}
.nav.scrolled::before{opacity:0}
.nav .logo-light{filter:drop-shadow(0 1px 3px rgba(5,31,32,.6))}


/* gyro cutout: floats free on the section, oversized, no frame */
.flex .gyro-float{width:118%;max-width:none;margin:-6% 0 -6% -14%;border-radius:0;min-height:0;
  object-fit:contain;filter:drop-shadow(0 26px 46px rgba(5,31,32,.22))}
@media (max-width:860px){.flex .gyro-float{width:100%;margin:0 0 6px 0}}


/* ============ location / map section ============ */
.mapsec{background:var(--cream);padding:70px 6vw}
.mapwrap{max-width:1150px;margin:0 auto;display:grid;grid-template-columns:.85fr 1.15fr;gap:4vw;align-items:center}
.mapinfo h2{margin:10px 0 12px}
.mapinfo .sub{margin-bottom:20px;max-width:44ch}
.nap{font-style:normal;font-size:var(--fs-body);line-height:1.65;color:var(--body-tx);margin-bottom:12px}
.nap strong{font-family:var(--font-display);font-weight:600;font-size:var(--fs-title);color:var(--ink)}
.nap a{color:var(--go);font-weight:600;text-decoration:none}
.nap a:hover{color:var(--go-hover)}
.hours{font-size:var(--fs-body);color:var(--meta);margin-bottom:22px}
.hours strong{color:var(--ink)}

/* facade: a real static map, no third-party request until the user asks for it.
   The gradient stays underneath as the fallback if the image ever goes missing. */
.mapfacade{position:relative;border-radius:14px;overflow:hidden;min-height:340px;
  background:url("/assets/img/orlando-catering-service-area-map.jpg") center/cover no-repeat,
    linear-gradient(135deg,#E3EFE4,#CDE4D2 60%,#A6BC8B);border:1px solid var(--hairline)}
.mapfacade iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
.mapload{position:absolute;inset:0;width:100%;height:100%;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:12px;background:transparent;border:0;cursor:pointer;
  font-family:var(--font-body);font-size:var(--fs-body);font-weight:600;color:var(--hunter)}
.mapload .pin{width:54px;height:54px;border-radius:50%;background:#fff;color:var(--go);
  display:flex;align-items:center;justify-content:center;box-shadow:0 8px 22px rgba(5,31,32,.18);
  transition:transform .2s var(--smooth)}
.mapload .pin svg{width:28px;height:28px}
/* The transition lives on the base rule, not inside :hover. Declared only in
   the hover state it eased in and snapped back on exit. */
.mapload:hover .pin,.mapload:focus-visible .pin{transform:translateY(-3px)}
@media (prefers-reduced-motion:reduce){.mapload .pin{transition:none}}
.mapload .maplabel{background:#fff;padding:9px 18px;border-radius:999px;box-shadow:0 4px 14px rgba(5,31,32,.18)}
@media (max-width:860px){.mapwrap{grid-template-columns:1fr}.mapfacade{min-height:260px}}

/* Real-photo hero candidates staged, not active. See assets/gbp/.
   hero-universal.jpg (Universal Orlando Foundation Theatre) and hero-party.jpg. */

/* ================= NAV + FOOTER REBUILD (operator pass, 2026-07-26) ================= */

/* --- Nav: one logo lockup, white over the hero, dark once scrolled.
   The old build swapped to logo-sq.png (the square favicon with white baked in),
   which read as a white chip on the frosted bar. logo-knockout.png is the same
   lockup with the wordmark knocked to white; the green mark is untouched. --- */
.nav{padding:16px 4vw}
.nav .logo-light,.nav .logo-dark{height:58px;width:auto;display:block}
.nav .logo-dark{display:none}
.nav.scrolled .logo-light{display:none}
.nav.scrolled .logo-dark{display:block}
.nav .logo-light{filter:drop-shadow(0 2px 6px rgba(5,31,32,.55))}

/* --- Call button: a real button. Pill, top-lit gradient, lifts on hover.
   Desktop shows the number so it is always on screen. Mobile stacks
   "Call now" over the number. --- */
.nav .ncall,.fcall{
  display:inline-flex;align-items:center;gap:10px;
  background:linear-gradient(180deg,#2FAE63 0%,#1E8A4C 52%,#16733E 100%);
  color:#fff;text-decoration:none;border:none;border-radius:999px;
  padding:11px 24px;line-height:1.15;
  font-family:var(--font-body);font-weight:700;letter-spacing:.01em;text-transform:none;
  box-shadow:0 1px 0 rgba(255,255,255,.30) inset,0 -1px 0 rgba(0,0,0,.16) inset,0 6px 16px rgba(8,54,30,.32);
  transition:transform .15s ease,box-shadow .15s ease,filter .15s ease}
.nav .ncall:hover,.fcall:hover{
  background:linear-gradient(180deg,#35BB6C 0%,#229755 52%,#1A8046 100%);
  color:#fff;transform:translateY(-1px);
  box-shadow:0 1px 0 rgba(255,255,255,.34) inset,0 -1px 0 rgba(0,0,0,.16) inset,0 10px 22px rgba(8,54,30,.38)}
.nav .ncall:active,.fcall:active{transform:translateY(1px);
  box-shadow:0 2px 5px rgba(8,54,30,.3),0 1px 0 rgba(0,0,0,.18) inset}
.phic{width:17px;height:17px;flex:none;fill:currentColor}
.ncall .ctxt,.fcall .ctxt{display:flex;flex-direction:column}
.ncall .clab,.fcall .clab{display:none}
/* nowrap added 2026-08-15: Satoshi sets a touch wider than Hanken Grotesk did,
   and the number broke onto three lines in the nav. The kit is explicit that
   the call button never wraps. */
.ncall .cnum,.fcall .cnum{font-size:var(--fs-body);font-weight:700;letter-spacing:.01em;white-space:nowrap}

/* --- Footer: full site map. Every page is two clicks from anywhere. --- */
footer{background:var(--hunter-d);color:var(--ondark);padding:0;display:block;font-size:var(--fs-body)}
.fgrid{display:grid;grid-template-columns:1.05fr 1fr 1fr;gap:44px;
  max-width:1240px;margin:0 auto;padding:46px 5vw 34px}
.fcol h2{font-family:var(--font-display);font-weight:600;font-size:var(--fs-body);color:#fff;
  margin:0 0 14px;letter-spacing:.005em}
.fcol h2+ul+h2{margin-top:26px}
.fcol ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.fcol a:not(.fcall){color:#CFE6D5;text-decoration:none;transition:color .15s}
.fcol a:not(.fcall):hover{color:#fff;text-decoration:underline;text-underline-offset:3px}
.flogo{height:56px;width:auto;display:block;margin-bottom:16px}
.fnap{margin:0 0 8px;line-height:1.55;color:#C4DACB}
.fnap strong{color:#fff;font-weight:600}
.fhours{margin:0 0 18px;color:#9FBCA8;font-size:var(--fs-label)}
.fbar{border-top:1px solid rgba(218,241,222,.14);max-width:1240px;margin:0 auto;
  padding:18px 5vw 26px;display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;
  font-size:var(--fs-label);color:#9FBCA8}
.fsocial{display:flex;gap:20px}
.fbar a{color:#9FBCA8;text-decoration:none}
.fbar a:hover{color:#fff}

@media (max-width:700px){
  .nav{padding:12px 5vw}
  .nav .logo-light,.nav .logo-dark{height:44px}
  .nav .ncall{padding:8px 18px;gap:8px}
  .ncall .clab{display:block;font-size:var(--fs-micro);font-weight:700;text-transform:uppercase;
    letter-spacing:.10em;opacity:.85;line-height:1}
  .ncall .cnum{font-size:var(--fs-label);line-height:1.25}
  .fbar{flex-direction:column;gap:12px}
}



/* ================= MOTION LAYER (operator pass, 2026-07-26) =================
   Cursor-reactive micro-interactions. Jelly UI was tested and dropped: its
   button only responds to a press, which is wasted on an element that
   navigates away. Everything here reacts on hover, runs on transform and
   opacity only, and turns off under prefers-reduced-motion. */

:root{--spring:cubic-bezier(.2,1.5,.35,1);--smooth:cubic-bezier(.22,.61,.36,1)}

/* --- Hub tiles: light follows the cursor, tile tilts toward it, arrow slides,
       bottom edge compresses on press. The tilt is applied inline by reveal.js. --- */
.tile{overflow:hidden;
  transition:transform .5s var(--smooth),box-shadow .5s var(--smooth),
    border-color .3s var(--smooth),border-bottom-width .18s var(--smooth)}
/* will-change only while the pointer is on it. Left on permanently it pins a
   compositor layer per tile for the life of the page. */
.tile:hover{will-change:transform}
.tile::before{content:"";position:absolute;inset:0;pointer-events:none;opacity:0;z-index:0;
  transition:opacity .35s var(--smooth);
  background:radial-gradient(220px circle at var(--mx,50%) var(--my,50%),
    rgba(217,167,60,.22),rgba(217,167,60,0) 62%)}
.tile:hover::before{opacity:1}
.tile>*{position:relative;z-index:1}
.tile:hover{box-shadow:0 16px 34px rgba(5,31,32,.20)}
.tile .go{transition:transform .4s var(--spring),background .3s var(--smooth),color .3s var(--smooth)}
.tile:hover .go{transform:translateX(4px);background:var(--gold);color:#fff}
.tile .ic{transition:transform .5s var(--spring)}
.tile:hover .ic{transform:translateY(-3px) scale(1.06)}
.tile.press{border-bottom-width:1px;transform:translateY(2px) scale(.985)!important;
  transition:transform .1s ease-out,border-bottom-width .1s ease-out}

/* --- Call button: squashes wide and flat on press, springs back. --- */
.ncall,.fcall,.hero-cta,.cta{transform:scale(var(--sx,1),var(--sy,1)) translateY(var(--ty,0));
  transition:transform .34s var(--spring),box-shadow .2s var(--smooth),
    background .2s var(--smooth),color .2s var(--smooth)}
.ncall:hover,.fcall:hover{--sx:1.03;--sy:1.03;--ty:-1px}
.ncall.press,.fcall.press,.hero-cta.press,.cta.press{--sx:.94;--sy:1.08;--ty:2px;
  transition:transform .09s ease-out}

/* --- Secondary buttons: fill wipes in from the left, arrow slides. --- */
.glass-ghost,.cta.ghost{position:relative;overflow:hidden;isolation:isolate}
.glass-ghost::before,.cta.ghost::before{content:"";position:absolute;inset:0;z-index:-1;
  background:rgba(251,247,240,.16);transform:scaleX(0);transform-origin:left center;
  transition:transform .42s var(--smooth)}
.glass-ghost:hover::before,.cta.ghost:hover::before{transform:scaleX(1)}

/* --- Triage step cards: lift plus a shadow bloom rather than a flat move. --- */
.lv .step{transition:transform .42s var(--smooth),box-shadow .42s var(--smooth),
  border-color .3s var(--smooth)}
.lv .step .ic{transition:transform .5s var(--spring)}
.lv .step:hover .ic,.lv .step:focus-within .ic{transform:translateY(-3px) scale(1.05)}

/* --- Nav links: underline wipes in from the left. --- */
.nav .links a{position:relative}
.nav .links a::after{content:"";position:absolute;left:0;right:0;bottom:-5px;height:2px;
  background:currentColor;transform:scaleX(0);transform-origin:left center;
  transition:transform .32s var(--smooth)}
.nav .links a:hover::after,.nav .links a:focus-visible::after{transform:scaleX(1)}

@media (prefers-reduced-motion:reduce){
  .tile,.tile .go,.tile .ic,.ncall,.fcall,.hero-cta,.cta,
  .glass-ghost::before,.cta.ghost::before,.lv .step,.lv .step .ic,
  .nav .links a::after{transition:none!important}
  .tile::before{display:none}
  .tile:hover .go,.tile:hover .ic,.lv .step:hover .ic{transform:none}
  .ncall:hover,.fcall:hover{--sx:1;--sy:1;--ty:0}
}

/* ---- Hero eyebrow on one line, and hero copy aligned to the nav logo ----
   The eyebrow was inheriting max-width:16ch from .hero h1, so "CATERING
   ORLANDO" wrapped. Hero padding was 6vw while the nav sits at 4vw, so the
   headline started further right than the logo above it. */
.hero .eyebrow-h1,.hero h1.eyebrow-h1{max-width:none;white-space:nowrap}
.hero{padding-left:4vw;padding-right:4vw}
@media (max-width:700px){
  .hero{padding-left:5vw;padding-right:5vw}
  .hero .eyebrow-h1,.hero h1.eyebrow-h1{font-size:var(--fs-label);letter-spacing:.16em}
}

/* Stat strip: "Daily" fades in after the counters finish. */
.strip b.fadein{opacity:0}
.strip b.fadein.shown{opacity:1;transition:opacity .24s var(--smooth)}

/* Hero CTAs sat on different boxes: the ghost carries a 1px border the solid
   one doesn't, so inline-block baseline alignment offset them. Same box now. */
.hero-copy .cta{display:inline-flex;align-items:center;justify-content:center;
  vertical-align:top;min-height:50px;padding-top:0;padding-bottom:0;box-sizing:border-box}

/* The two hero buttons touched edge to edge on mobile, repeatedly. Root cause,
   found 2026-08-15: they were bare siblings of a display:block .hero-copy, so
   nothing ever owned the space between them. Desktop only looked right because
   inline-block collapsed the markup whitespace into a few pixels, and at 375px
   the line wrapped and that whitespace disappeared. Every earlier fix set a
   margin on one button, which the other breakpoint then had to undo, so it kept
   coming back. They now sit in a flex row that wraps and carries its own gap.
   No media query: one rule is correct at every width.

   `.btnrow` is the same rule anywhere else two buttons sit together. Any pair
   of buttons on this site goes in one of these two, never as bare siblings. */
.hero-actions,.btnrow{display:flex;flex-wrap:wrap;gap:12px;margin-top:22px}
.hero-actions .cta,.btnrow .cta{margin:0}

/* Footer lost its Service areas column; rebalance the remaining three. */

/* ================= FOOTER v2 + SECTION BLENDING (operator pass) ================= */

/* Footer: tighter overall, bigger logo and links, hours read before the name,
   tagline dropped, divider runs edge to edge, social sits last. */
footer{padding:0}
.flogo{height:82px;margin-bottom:18px}
.fhours{margin:0 0 12px;font-size:var(--fs-body);line-height:1.45;color:#DAF1DE}
.fhours strong{display:block;font-family:var(--font-display);font-weight:600;
  font-size:var(--fs-title);color:#fff}
.fnap{margin:0 0 18px;font-size:var(--fs-label);line-height:1.5;color:#9FBCA8}
.fcol h2{font-size:var(--fs-title);margin-bottom:16px}
.fcol ul{gap:11px}
.fcol a:not(.fcall){font-size:var(--fs-body)}
.fcol h2+ul+h2{margin-top:30px}

.fbar{max-width:none;margin:0;padding:0;border-top:1px solid rgba(218,241,222,.16);display:block}
.fbarin{max-width:1240px;margin:0 auto;padding:16px 5vw 22px;display:flex;
  justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap}
@media (max-width:700px){
  .flogo{height:66px}
  .fbarin{flex-direction:column;align-items:flex-start;gap:14px}
  .fsocial{gap:18px}
}

/* ---- Section slabs (operator pick: floating slabs + organic wave + inlays) ----
   The page is now one continuous cream ground. Dark sections are inset rounded
   slabs sitting on it, the stat-strip idea scaled up, which reads app-like and
   holds up better on a phone. Replaces the earlier full-bleed alternating bands
   and the pill-radius "hat" seams. */

body{background:var(--cream)}
.triage,.flex,.mapsec{background:transparent}

/* Faint sage wash so the ground is not flat cream end to end. */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:linear-gradient(180deg,var(--cream) 0%,#F2EDE1 45%,var(--cream) 100%)}

/* The slabs. Outer shadow lifts them off the ground; the inset pair is the
   inlay, a light top edge and a dark bottom edge, so each slab reads as a
   different layer rather than a painted rectangle. */
.hub,.trust{
  margin:0 clamp(14px,3.2vw,34px);
  border-radius:clamp(18px,2.2vw,30px);
  background:linear-gradient(158deg,#2a6153 0%,var(--hunter) 42%,var(--hunter-d) 100%);
  box-shadow:
    0 18px 44px rgba(5,31,32,.24),
    0 2px 6px rgba(5,31,32,.14),
    inset 0 1px 0 rgba(218,241,222,.16),
    inset 0 -1px 0 rgba(0,0,0,.28);
  position:relative;overflow:hidden}

/* No wave inside the slab. A horizontal band across the top read as a seam
   splitting the card in two rather than as an organic accent, so it looked
   like a rendering fault. The 158deg gradient below carries the depth on its
   own. If an organic accent comes back it needs to be a large low-contrast
   shape anchored to a corner, not a band spanning the full width. */
.trust>*{position:relative;z-index:1}

/* Footer closes the page as the last slab: inset sides, rounded shoulders. */
footer{margin:clamp(14px,3.2vw,34px) clamp(14px,3.2vw,34px) 0;
  border-radius:clamp(18px,2.2vw,30px) clamp(18px,2.2vw,30px) 0 0;
  box-shadow:0 -2px 0 rgba(218,241,222,.10) inset,0 18px 44px rgba(5,31,32,.22)}

/* Cards on the slabs get their own inlay so the layering continues inward. */
.tile{box-shadow:0 8px 20px rgba(5,31,32,.20),inset 0 1px 0 rgba(255,255,255,.9)}
.strip{box-shadow:0 22px 46px rgba(34,48,31,.16),inset 0 1px 0 rgba(255,255,255,.9)}

/* Whisper of motion: each section drifts up as it enters. No pinning, no
   scroll hijack. .drift is added by reveal.js so a no-JS page renders at rest. */
.triage,.hub,.roster,.flex,.trust,.mapsec,.plan{transition:transform .7s var(--smooth)}
.drift{transform:translateY(12px)}
.drift.drifted{transform:none}

@media (max-width:700px){
  .hub,.trust{margin:0 12px}
  footer{margin:12px 12px 0}
}
@media (prefers-reduced-motion:reduce){
  .triage,.hub,.roster,.flex,.trust,.mapsec,.plan{transition:none}
  .drift,.drift.drifted{transform:none}
}

/* ---- Footer height (operator pass) ----
   Three problems: at the old 1000px breakpoint it fell to two columns and
   stacked Menus under Company, which made it taller, not shorter; on mobile
   everything ran into one long column; and the link spacing was generous
   enough to compound both. Now it holds three columns down to 760px, then
   goes two-up with the brand spanning the full width, and the eight-item
   services list splits into two columns of its own on mobile. */
@media (max-width:760px){
  .fgrid{grid-template-columns:1fr 1fr;gap:22px 20px;padding:32px 6vw 22px}
  .fbrand{grid-column:1 / -1}
  .flogo{height:58px;margin-bottom:14px}
  .fhours{margin-bottom:8px}
  .fnap{margin-bottom:14px}
  .fcol h2{font-size:var(--fs-body);margin-bottom:10px}
  .fcol ul{gap:8px}
  .fcol a:not(.fcall){font-size:var(--fs-label)}
  .fcol h2+ul+h2{margin-top:20px}
  /* Services stays a single column. Splitting it two-up at 390px made every
     label wrap onto two or three lines, which ate the height it saved and
     read ragged. One column of eight unwrapped links is shorter and cleaner. */
  .fcol ul{gap:9px}
  .fcol a:not(.fcall){line-height:1.25}
  .fbarin{padding:14px 6vw 20px;gap:10px}
}

/* ---- Floating controls ----
   Back-to-top moves to the right and stacks above the call button, so both
   live in the same thumb corner instead of one being marooned bottom-left.
   The call button gets a soft light ring to separate it from dark sections.
   Deliberately not gold: the brand kit bans gold on buttons and CTAs. */
@media (max-width:700px){
  .totop{right:22px;left:auto;bottom:88px;width:42px;height:42px}
}
.fab{border:2px solid rgba(251,247,240,.55);
  box-shadow:0 10px 26px rgba(5,31,32,.38),0 0 0 4px rgba(30,138,76,.16)}

/* ---- Service card reveal (operator pass) ----
   Photos pulled: the three GBP placeholders were shot in different rooms,
   lighting and orientations, so side by side they read as jarring rather than
   as a set. This slot stays empty until three harmonised images exist, ideally
   from one shoot. Full-Service in particular needs a shot of the team.
   razor: .shot styling deleted with them; re-add when the photos land. */

/* The detail list opens slowly enough to read as unfolding. 550ms still
   snapped, so did 900ms. 1.5s is the pace the operator settled on.
   Driven by grid-template-rows rather than max-height: the old version needed
   a guessed 190px ceiling that would clip a longer list, and animating a
   layout property thrashes on every frame. 0fr to 1fr measures itself. */
.lv .more{display:grid;grid-template-rows:0fr;overflow:hidden;opacity:0;
  transition:grid-template-rows 1.5s var(--smooth),opacity 1s var(--smooth)}
/* The list's own top padding kept the collapsed track 14px tall, so every
   closed card carried 14px of invisible dead space. The spacing moves inside,
   onto the first item, where it collapses with the rest. */
.lv .more>*{min-height:0;padding-top:0}
.lv .more li:first-child{padding-top:14px}
.lv .step:hover .more,.lv .step:focus-within .more{grid-template-rows:1fr;opacity:1}
.lv .more ul{transform:translateY(-8px);transition:transform 1.5s var(--smooth)}
.lv .step:hover .more ul,.lv .step:focus-within .more ul{transform:none}

@media (max-width:700px){
  /* No hover on touch, so the list is simply always open. Nothing to discover
     and nothing to tap. */
  .lv .more{grid-template-rows:1fr;opacity:1}
  .lv .more ul{transform:none}
}
@media (prefers-reduced-motion:reduce){
  .lv .more,.lv .more ul{transition:none}
}

/* Footer column headings in caps, per operator. */
.fcol h2{text-transform:uppercase;letter-spacing:.1em;font-family:var(--font-body);
  font-weight:700;font-size:var(--fs-micro);color:#9FBCA8}

/* ---- Testimonials (real Google reviews, pulled via Places API) ----
   Rating and count are live values from the API, refreshed by sync-gbp.py.
   Author names shown as Google requires; avatars are the reviewers' own
   profile photos. Reviews and photos must be refreshed at least every 30 days
   under the Places terms, which is what the sync script is for. */
.proof{padding:74px 5vw 78px;text-align:center}
.proof .head{max-width:60ch;margin:0 auto 30px}
.proof h2{font-size:var(--fs-h2);margin:10px 0 0}

.proofbar{display:flex;align-items:center;justify-content:center;gap:20px;
  flex-wrap:wrap;margin-bottom:38px}
.coins{display:flex;align-items:center}
.coins img,.more-coin{width:52px;height:52px;border-radius:50%;display:block;
  border:3px solid var(--cream);margin-left:-14px;
  box-shadow:0 3px 10px rgba(5,31,32,.22)}
.coins img:first-child,.more-coin:first-child{margin-left:0}
.coins img{object-fit:cover;background:#E4DED0}
.more-coin{background:var(--hunter);color:#fff;display:grid;place-items:center;
  font-family:var(--font-body);font-weight:700;font-size:var(--fs-label);letter-spacing:.01em}
.proofnum{font-size:var(--fs-body);color:var(--mut);display:flex;align-items:center;gap:8px}
.proofnum b{font-family:var(--font-display);font-weight:600;font-size:var(--fs-title);color:var(--ink)}
.stars{color:#D9A73C;letter-spacing:.08em;font-size:var(--fs-title)}

.quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;
  max-width:1120px;margin:0 auto;text-align:left}
.q{margin:0;background:#fff;border:1px solid var(--hairline);border-radius:14px;
  padding:24px 22px 20px;display:flex;flex-direction:column;gap:16px;
  box-shadow:0 8px 22px rgba(5,31,32,.07),inset 0 1px 0 rgba(255,255,255,.9)}
.q blockquote{margin:0;font-size:var(--fs-body);line-height:1.55;color:#3D4540}
.q figcaption{display:flex;align-items:center;gap:11px;margin-top:auto}
.q figcaption img{width:38px;height:38px;border-radius:50%;object-fit:cover;flex:none}
.q figcaption b{display:block;font-size:var(--fs-label);color:var(--ink)}
.q figcaption i{display:block;font-style:normal;font-size:var(--fs-micro);color:var(--mut)}

/* Hero trust line sits under the sub, above the buttons. */
.herotrust{margin:0 0 18px;font-size:var(--fs-body);color:#DAF1DE;display:flex;
  align-items:center;gap:9px;flex-wrap:wrap}
.herotrust .stars{font-size:var(--fs-title);text-shadow:0 1px 3px rgba(5,31,32,.4)}
.herotrust b{font-weight:700;color:#fff;font-size:var(--fs-title)}

@media (max-width:900px){.quotes{grid-template-columns:1fr;max-width:560px}}
@media (max-width:700px){
  .proof{padding:56px 6vw 60px}
  .proofbar{gap:14px;margin-bottom:28px}
  .coins img,.more-coin{width:44px;height:44px;margin-left:-12px}
  .herotrust{font-size:var(--fs-label)}
  .herotrust .stars{font-size:var(--fs-title)}
}

/* ---- Share row ----
   Real, labelled destinations instead of a bare "Copy link", which nobody
   recognises as a share control. Text and Email are first because the actual
   behaviour here is one coworker sending this to another. All plain links and
   mailto/sms, so no Facebook or X scripts run on our pages. On phones the
   native share sheet replaces the row entirely. */
.fshare{max-width:1240px;margin:0 auto;padding:24px 5vw 26px;display:flex;
  align-items:center;gap:18px;flex-wrap:wrap;
  border-top:1px solid rgba(218,241,222,.10)}
.fshare-lede{margin:0;font-size:var(--fs-lead);color:#DAF1DE;font-family:var(--font-display);
  font-weight:600}
.fshare-btns{display:flex;gap:9px;margin-left:auto;flex-wrap:wrap}
.sharebtn{display:inline-flex;align-items:center;gap:8px;
  font-family:var(--font-body);font-weight:600;font-size:var(--fs-label);
  padding:9px 17px;border-radius:999px;cursor:pointer;text-decoration:none;
  border:1px solid rgba(218,241,222,.22);background:rgba(251,247,240,.10);color:#fff;
  transition:background .2s var(--smooth),transform .3s var(--spring),border-color .2s var(--smooth)}
.sharebtn svg{width:17px;height:17px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.sharebtn:hover{background:rgba(251,247,240,.20);border-color:rgba(218,241,222,.42);
  transform:translateY(-1px);color:#fff}
.sharebtn.ghost{background:transparent}
.sharebtn[data-copied]{background:var(--go);border-color:var(--go);color:#fff}

/* Same row, on the cream page body instead of the footer's dark slab. The
   footer palette is tuned for light-on-dark and goes near-invisible up here. */
.fshare.onlight{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  margin-bottom:56px;padding-top:22px;padding-bottom:22px}
.fshare.onlight .fshare-lede{color:var(--ink)}
.fshare.onlight .sharebtn{border-color:var(--line);background:#fff;color:var(--go-d)}
.fshare.onlight .sharebtn:hover{background:var(--sage);border-color:var(--sage3);color:var(--go-d)}
.fshare.onlight .sharebtn.ghost{background:transparent}
.fshare.onlight .sharebtn[data-copied]{background:var(--go);border-color:var(--go);color:#fff}

/* Native share sheet on phones: one button replaces the row. */
.sharenative{display:inline-flex;align-items:center;gap:9px;
  font-family:var(--font-body);font-weight:700;font-size:var(--fs-body);
  padding:11px 24px;border-radius:999px;cursor:pointer;border:none;
  background:rgba(251,247,240,.16);color:#fff}
.sharenative svg{width:18px;height:18px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}

@media (max-width:760px){
  .fshare{padding:20px 6vw 22px;gap:12px;flex-direction:column;align-items:flex-start}
  .fshare-btns{margin-left:0;width:100%}
  .sharebtn{flex:1 1 auto;justify-content:center}
}
@media (prefers-reduced-motion:reduce){.sharebtn{transition:none}}

/* ---- Hero trust: coin row instead of star glyphs ----
   Faces read as people at a glance where five gold stars read as a widget.
   Same avatars as the testimonials section, so the claim and the evidence
   are visibly the same set of humans. */
.herotrust{display:flex;align-items:center;gap:13px;flex-wrap:wrap;margin:0 0 20px}
.herotrust p{margin:0;font-size:var(--fs-body);color:#DAF1DE;line-height:1.4}
.herotrust b{font-weight:700;color:#fff}
.coins-sm img{width:40px;height:40px;border-width:2px;border-color:rgba(251,247,240,.85);
  margin-left:-12px;box-shadow:0 3px 10px rgba(5,31,32,.45)}
.coins-sm img:first-child{margin-left:0}
@media (max-width:700px){
  .herotrust{gap:10px}
  .herotrust p{font-size:var(--fs-label)}
  .coins-sm img{width:34px;height:34px;margin-left:-10px}
}

/* ---- Proof strip: named accounts ----
   Sits on the cream ground between the reviews and the food section, so the
   page runs opinion proof then evidence proof. Deliberately typographic and
   photo-free: the GBP shots were taken in different rooms and read as a
   mismatched set, which is the same failure that killed them in the service
   cards. Names at type scale carry more than five small clashing photos. */
.roster{padding:16px 5vw 78px}
.roster-in{max-width:1100px;margin:0 auto;display:grid;
  grid-template-columns:1fr 1.15fr;gap:clamp(32px,5vw,64px);align-items:start}
.roster-lede h2{font-size:var(--fs-h2);margin:10px 0 14px;max-width:18ch}
.roster-lede p{color:var(--meta);margin:0 0 22px;max-width:42ch}

.roster-names{list-style:none;margin:0;padding:0}
.roster-names li{display:flex;align-items:baseline;justify-content:space-between;
  gap:20px;padding:17px 4px;border-top:1px solid var(--hairline);
  transition:transform .35s var(--smooth),border-color .35s var(--smooth)}
.roster-names li:last-child{border-bottom:1px solid var(--hairline)}
.roster-names b{font-family:var(--font-display);font-weight:600;font-size:var(--fs-title);
  letter-spacing:-0.01em;color:var(--ink);line-height:1.2}
.roster-names i{font-style:normal;flex:none;font-size:var(--fs-micro);font-weight:600;
  letter-spacing:.14em;text-transform:uppercase;color:var(--meta)}
.roster-names li:hover{transform:translateX(5px);border-color:var(--sage-k)}

.roster-note{max-width:1100px;margin:26px auto 0;font-size:var(--fs-label);color:var(--meta)}

@media (max-width:760px){
  .roster{padding:8px 6vw 60px}
  .roster-in{grid-template-columns:1fr;gap:30px}
  .roster-lede h2{max-width:none}
  .roster-names li{flex-direction:column;align-items:flex-start;gap:5px;padding:14px 0}
  .roster-note{margin-top:20px}
}
@media (prefers-reduced-motion:reduce){
  .roster-names li{transition:none}
  .roster-names li:hover{transform:none}
}

/* ---- Hero trust v2: gold stars own the rating ----
   The rating comes out of the "trusted since" sentence and becomes the loud
   thing: coins, then five gold stars, then the number. The since-1996 line
   drops underneath as the quiet second read.

   Gold budget: the hero already spent its one gold element on the "Catering
   Orlando" eyebrow. Stars are the stronger use, so the eyebrow drops to mint
   and the hero still shows exactly one gold moment. */
.hero .eyebrow-h1,.hero h1.eyebrow-h1{color:var(--mint)}
.herotrust{gap:12px}
.herotrust .stars{margin-right:-2px}
.herotrust p b{font-family:var(--font-display);font-weight:600;font-size:var(--fs-title);
  color:#fff;margin-right:2px}
.herotrust p i{display:block;font-style:normal;font-size:var(--fs-body);color:#BFD8C6;
  margin-top:1px}
@media (max-width:700px){
  /* Stars plus "4.8 from 45 Google reviews" no longer fit on one phone line at
     the larger type, and "reviews" was dropping onto the line below where it
     collided with the since-1996 read. The stars come down to body size and the
     sentence to label size, which puts the whole rating back on one line. */
  .herotrust{gap:10px}
  .herotrust p{font-size:var(--fs-label)}
  .herotrust p .stars{font-size:var(--fs-body)}
  .herotrust p b{font-size:var(--fs-lead)}
  .herotrust p i{font-size:var(--fs-label)}
}
/* Stars now sit inline with the number, so the pair wraps as one unit. */
.herotrust p .stars{vertical-align:-1px;margin-right:5px}

/* ---- Testimonials v2: columns that flow upward ----
   The 21st.dev component this came from is React plus Tailwind plus the motion
   library for one translateY. The effect is two CSS rules, so it is two CSS
   rules here: each column holds its reviews twice and slides up by half its
   own height forever, which lands copy two exactly where copy one started.
   The padding-bottom equal to the gap is what makes that landing exact.
   Hovering pauses every column, so nothing scrolls away from a reader. */
.tcols{display:flex;justify-content:center;gap:20px;margin-top:36px;
  max-height:600px;overflow:hidden;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 15%,#000 85%,transparent 100%);
  mask-image:linear-gradient(to bottom,transparent 0,#000 15%,#000 85%,transparent 100%)}
.tcol{flex:0 1 356px;min-width:0}
.ttrack{display:flex;flex-direction:column;gap:20px;padding-bottom:20px;
  animation:tscroll var(--dur,30s) linear infinite}
.tclone{display:contents}
@keyframes tscroll{from{transform:translateY(0)}to{transform:translateY(-50%)}}
.tcols:hover .ttrack,.tcols:focus-within .ttrack{animation-play-state:paused}

.tq{margin:0;background:#fff;border:1px solid var(--hairline);
  border-radius:20px;padding:26px 26px 22px;text-align:left;
  box-shadow:0 8px 22px rgba(34,48,31,.08),inset 0 1px 0 rgba(255,255,255,.9)}
.tq blockquote{margin:0;font-size:var(--fs-body);line-height:1.55;color:var(--body-tx)}
.tq figcaption{display:flex;align-items:center;gap:11px;margin-top:18px}
.tq figcaption img{width:40px;height:40px;border-radius:50%;flex:none}
.tq figcaption span{display:flex;flex-direction:column;line-height:1.25}
.tq figcaption b{font-family:var(--font-display);font-weight:600;font-size:var(--fs-body);color:var(--ink)}
.tq figcaption i{font-style:normal;font-size:var(--fs-micro);color:var(--meta)}

@media (max-width:820px){
  .tcol-2{display:none}
  .tcol{flex:1 1 100%;max-width:420px}
  .tcols{max-height:520px}
}

/* Reduced motion: the columns stop and simply stack. No mask fade either,
   because a fade with nothing moving reads as a rendering fault. */
@media (prefers-reduced-motion:reduce){
  .ttrack{animation:none}
  .tcols{max-height:none;overflow:visible;-webkit-mask-image:none;mask-image:none;
    align-items:flex-start}
  .tclone{display:none}
}

/* ---- Warmer cream ground (operator, after the St Martin QR menu) ----
   Their ground is #F6E3C4, a real tan. Ours was #FBF7F0, an off-white that
   photographs as grey next to it. This lands about halfway: warm enough that
   the white cards read as cards, not as more of the same surface, without
   going yellow. Green stays ours. */
:root{--cream:#F8EFDF; --cream2:#F2E6D2; --hairline:#E3D7C0}
body::before{background:linear-gradient(180deg,var(--cream) 0%,#F4E8D4 45%,var(--cream) 100%)}

/* ---- Section headings: keyword H2 on top, statement underneath ----
   Same shape the hero already uses, where the small eyebrow is the real
   heading and the big line is display text. Each eyebrow now carries a term
   the home page is allowed to own. None of them name a service, so the
   anti-cannibalisation rule in BRIEF 8g still holds. */
.dline{font-family:var(--font-display);font-weight:600;letter-spacing:0;
  line-height:1.08;text-wrap:balance;color:var(--ink);
  font-size:var(--fs-h2);margin:10px 0}
.flex .dline{margin:12px 0 14px}
.trust .dline{font-size:var(--fs-h2);color:#FBF7F0;margin:10px 0}
.hub .dline{color:#FBF7F0}
/* The eyebrow is an h2 now, so the old ".hub h2" and ".trust h2" colour rules
   would repaint it cream. Put the gold back on the eyebrow specifically. */
.hub .head h2.tag,.trust h2.tag{color:var(--gold)}
.triage .head h2.tag,.flex h2.tag{color:var(--hunter)}
h2.tag{display:block;margin:0 0 2px}

/* ---- Ghost buttons: the left wipe was invisible on cream ----
   Now the corners round out toward a pill while a white fill grows from the
   centre, and the button lifts. Uses the existing --ty custom property so it
   composes with the press squash instead of fighting it. */
.cta.ghost{background:rgba(255,255,255,.55);border:1px solid rgba(35,83,71,.30);
  border-radius:10px;box-shadow:0 1px 2px rgba(34,48,31,.06);
  transition:transform .34s var(--spring),border-radius .5s var(--spring),
    border-color .3s var(--smooth),box-shadow .4s var(--smooth),color .25s var(--smooth)}
.cta.ghost::before{background:#fff;border-radius:inherit;
  transform:scale(.25);transform-origin:center;opacity:0;
  transition:transform .45s var(--spring),opacity .3s var(--smooth)}
.cta.ghost:hover,.cta.ghost:focus-visible{--ty:-2px;border-radius:999px;
  border-color:var(--go);color:var(--go-d);
  box-shadow:0 10px 26px rgba(34,48,31,.18)}
.cta.ghost:hover::before,.cta.ghost:focus-visible::before{transform:scale(1);opacity:1}

/* ---- Footer closes as a full card ----
   Cream shows under it and around it, so the page ends on the same floating
   slab language as the hub and the trust band instead of running off the edge. */
footer{margin:clamp(14px,3.2vw,34px);border-radius:clamp(18px,2.2vw,30px);
  overflow:hidden;
  box-shadow:0 -2px 0 rgba(218,241,222,.10) inset,0 18px 44px rgba(5,31,32,.22)}

@media (max-width:700px){footer{margin:12px}}
@media (prefers-reduced-motion:reduce){
  .cta.ghost,.cta.ghost::before{transition:none!important}
  .cta.ghost:hover{border-radius:10px}
}
/* The per-section ".triage h2 / .hub h2 / .trust h2" font-size rules outrank a
   bare ".tag", so the eyebrow rendered at display size. Restate the eyebrow
   type at matching specificity. */
h1.tag,h2.tag{font-family:var(--font-body);font-weight:600;font-size:var(--fs-label);
  letter-spacing:.18em;line-height:1.4;text-transform:uppercase;
  display:block;margin:0 0 2px;text-wrap:wrap}
/* ".flex p" outranks a bare ".dline", so the food headline dropped to body
   size. Raise the display line to element-plus-class specificity. */
p.dline{font-size:var(--fs-h2);line-height:1.05;color:var(--ink);max-width:none}
.flex p.dline{margin:12px 0 14px}
.trust p.dline{font-size:var(--fs-h2);line-height:1.05;color:#FBF7F0}
.hub p.dline{color:#FBF7F0}

/* ---- Ghost buttons v3 (operator: no shape change) ----
   The radius animation was rejected. It rounded on hover and snapped back
   square on release, so the two halves never matched and it read as a glitch
   rather than a transition. Back to a fill that wipes in from the left, but
   with real contrast this time: the old wipe was white at 16 percent over
   cream, which is why it was invisible. Radius never moves. */
.cta.ghost{background:rgba(255,255,255,.62);border:1px solid rgba(35,83,71,.30);
  border-radius:10px;box-shadow:0 1px 2px rgba(34,48,31,.06);
  transition:transform .3s var(--spring),border-color .3s var(--smooth),
    box-shadow .35s var(--smooth),color .25s var(--smooth)}
.cta.ghost::before{background:var(--go-t);border-radius:inherit;
  transform:scaleX(0);transform-origin:left center;opacity:1;
  transition:transform .44s var(--smooth)}
.cta.ghost:hover,.cta.ghost:focus-visible{--ty:-1px;border-color:var(--go);
  color:var(--go-d);box-shadow:0 8px 20px rgba(34,48,31,.14)}
.cta.ghost:hover::before,.cta.ghost:focus-visible::before{transform:scaleX(1)}

/* Eyebrows never share the header face. That decision now lives in the single
   .tag rule at the top of the file. */

/* Contact hero: the keyword H1 sits in the eyebrow slot, so the display line
   below it is a p.dline and has to inherit the .page-hero h1 treatment. */
.page-hero h1.tag{max-width:none}
.page-hero p.dline{font-family:var(--font-display);color:#FBF7F0;font-weight:500;
  letter-spacing:-0.01em;font-size:var(--fs-h2);line-height:1.05;
  margin:10px 0 12px;max-width:24ch}
/* Interior page H1s match the display line beside them. The :not(.tag) matters:
   on contact, about and the location pages the H1 IS the eyebrow, and it has to
   stay at eyebrow size. */
.page-hero h1:not(.tag){font-size:var(--fs-h2);line-height:1.05}

/* ---- Footer sits closer to the page edge (operator) ----
   Sides stay on the slab inset so the footer lines up with the hub and trust
   cards above it. The bottom closes to a sliver: visible, not measurable. */
footer{margin:clamp(14px,3.2vw,34px) clamp(14px,3.2vw,34px) 7px}

@media (max-width:700px){footer{margin:12px 12px 7px}}
@media (prefers-reduced-motion:reduce){
  .cta.ghost,.cta.ghost::before{transition:none!important}
}

/* ---- Ghost button fill v4 (operator: the mint reads as chewing gum) ----
   Mint was rejected on association, not on contrast, and it also matched the
   diet chips so the button stopped looking like a button. Gold was floated as
   "our orange"; there is no orange in this palette, and gold on a button is
   banned outright, so it is not an option. Fill is now the hunter slab colour
   with the label going white. Deep, appetising, unmistakably a fill, and
   distinct from the brighter primary CTA green. */
.cta.ghost::before{background:var(--hunter)}
.cta.ghost:hover,.cta.ghost:focus-visible{color:#FBF7F0;border-color:var(--hunter)}

/* ---- Footer padding restored (operator: it looked better before) ---- */
footer{margin:clamp(14px,3.2vw,34px)}
@media (max-width:700px){footer{margin:12px}}

/* ---- Letter coins for reviewers with no photo ----
   Four of the eight transcribed reviewers use a Google letter circle rather
   than a portrait. Drawn in CSS instead of downloaded, so there is no image
   request and nothing to re-fetch on the 30-day refresh. Tones are hunter,
   olive, warm brown and slate. No teal, no mint. */
.tq figcaption .tcoin,.q figcaption .tcoin{width:40px;height:40px;border-radius:50%;flex:none;
  display:flex;align-items:center;justify-content:center;
  font-family:var(--font-display);font-weight:600;font-size:var(--fs-label);
  color:#FBF7F0;line-height:1}
.tc-1{background:#235347}
.tc-2{background:#6E7362}
.tc-3{background:#7A5C48}
.tc-4{background:#4C5A62}

/* ---- Three columns now that there are eight reviews ---- */
@media (min-width:1080px){.tcols{max-height:640px}}
@media (max-width:1079px){.tcol-3{display:none}}
@media (max-width:820px){.tcol-2{display:none}}
/* Mid-wipe the label is one colour while the background is two, so a slow
   sweep leaves white text sitting on the not-yet-filled white half. Shorten
   the fill and swap the label just past the midpoint: the ambiguous window
   drops to about a tenth of a second and reads as a single motion. */
.cta.ghost{transition:transform .3s var(--spring),border-color .3s var(--smooth),
  box-shadow .3s var(--smooth),color .14s var(--smooth) .15s}
.cta.ghost::before{transition:transform .32s var(--smooth)}

/* ---- Body text floor and one colour for prose (operator) ----
   The food section ran at 15.5px in --mut while every other section ran 1rem
   in --meta, which is why it read as smaller AND as a different voice. Both
   now match. The footer address is real content, so it clears the floor too.
   Chips and city pills stay small: they are labels, not reading text. */
.flex p{font-size:var(--fs-body);color:var(--meta)}
.flex p.dline{color:var(--ink)}
.roster-note{font-size:var(--fs-body);color:var(--meta)}
.fnap{font-size:var(--fs-body)}
.areas i,.areas a{font-size:var(--fs-micro)}

/* The note belongs under the venue list it is counting, not under the lede. */
.roster-note{grid-column:2;margin:22px 0 0;max-width:none}
@media (max-width:760px){.roster-note{grid-column:1;margin-top:16px}}
/* ".flex p" and "p.dline" tie on specificity and ".flex p" lands later, so
   raising the food body copy dragged the food headline down with it. */
.flex p.dline{font-size:var(--fs-h2);color:var(--ink)}
/* Venue list and its note are one column now, so the note sits under the
   names instead of dropping to a second grid row below the taller lede. */
.roster-note{grid-column:auto;margin:18px 0 0}
.roster-lede h2{max-width:24ch}

/* ---------- MENU LISTS (every /catering-menu/ page) ---------- */
/* Top padding carries the whole gap between the hunter hero and "THE LIST" on
   any menu with no image strip between them. 10px read as cramped on the
   breakfast page, which is the only one that goes hero-straight-to-list. */
.mhead{max-width:1150px;margin:0 auto;padding:48px 6vw 6px;text-align:center}
/* The strip already supplies that breathing room on the menus that have one. */
.dishrow + .mhead{padding-top:10px}
.mhead h2{font-size:var(--fs-h2);margin:8px 0 10px}
.mhead .sub{max-width:56ch;margin:0 auto 30px}
.mcols{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:26px 40px;max-width:1000px;margin:0 auto;padding:0 6vw 54px}
.mcols h3{font-size:var(--fs-micro);font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--go-d);margin-bottom:10px}
.mcols ul{list-style:none;padding:0;margin:0}
.mcols li{font-size:var(--fs-body);padding:9px 0;border-bottom:1px solid var(--line)}
.mcols li:last-child{border-bottom:none}
/* A column's own note, and the sub-header a package column uses for its
   optional add-on block. These were four different inline styles across the
   four menu pages before; the pages drift apart the moment they are inline. */
.mcols .mnote{color:var(--meta);font-size:var(--fs-body);margin:-4px 0 10px}
.mcols .msub{font-size:var(--fs-micro);font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--go-d);margin:18px 0 10px;padding-top:14px;border-top:1px solid var(--line)}
/* The closing CTA pair that ends every menu page: PDF, then Call. */
.mcta{text-align:center;padding:0 6vw 60px}
.mcta .btnrow{justify-content:center}
.mcta p{color:var(--meta);font-size:var(--fs-body);margin-top:14px}

/* The phone CTA. Next to the PDF button these were two identical green pills
   and people read them as the same kind of thing, so the one that actually
   books work went unclicked. Gold reads as a different action on both the
   cream body and the dark trust band, which one flat colour swap cannot do. */
.cta.tel{background:var(--gold);color:var(--ink);box-shadow:0 6px 18px rgba(217,167,60,.30)}
.cta.tel:hover{background:#C6932E}
.trust .cta.tel{box-shadow:none}

/* ---------- GALLERY GRID ---------- */
.ggrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:16px;max-width:1150px;margin:0 auto;padding:60px 6vw 20px}
.ggrid figure{margin:0;border-radius:18px;overflow:hidden;background:var(--cream2)}
.ggrid img{width:100%;height:230px;object-fit:cover;display:block;transition:transform .5s cubic-bezier(.2,.8,.2,1)}
.ggrid figure:hover img{transform:scale(1.05)}

/* ---------- LEGAL / LONG-FORM PROSE ---------- */
.prose{max-width:72ch;margin:0 auto;padding:56px 6vw 64px}
.prose h2{font-size:var(--fs-title);margin:34px 0 10px}
.prose p{color:var(--mut);font-size:var(--fs-body);line-height:1.65;margin-bottom:12px}
.prose a{color:var(--go-d)}

/* ---------- QUOTE CTA BAND (every service + location page) ----------
   Sits directly under the two-paragraph intro so the phone number is the
   first thing after the orientation copy. One button, number spelled out. */
.qcta{text-align:center;padding:8px 6vw 64px;max-width:1150px;margin:0 auto}
.qcta h2{font-size:var(--fs-h2);margin-bottom:10px}
.qcta p{color:var(--mut);font-size:var(--fs-body);margin-bottom:22px}
.qcta .cta{font-size:var(--fs-title);padding:16px 34px}
.qcta p{margin-bottom:26px}
/* .qnum display phone line removed sitewide 2026-08-02, operator's call:
   the number was sitting as text directly above a button that already
   spells it out. One CTA in this band, and it is the button. */

/* ---------- FAQ accordion (service + location templates) ----------
   Native <details> so it works with no JS and stays keyboard accessible. */
.faq{margin:18px 0 8px;border-top:1px solid var(--hairline)}
.faq details{border-bottom:1px solid var(--hairline)}
.faq summary{list-style:none;cursor:pointer;padding:16px 34px 16px 0;position:relative;
  font-family:var(--font-display);font-weight:500;font-size:var(--fs-title);color:var(--ink)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:6px;top:50%;width:9px;height:9px;
  border-right:2px solid var(--go-d);border-bottom:2px solid var(--go-d);
  transform:translateY(-70%) rotate(45deg);transition:transform .2s}
.faq details[open] summary::after{transform:translateY(-20%) rotate(225deg)}
.faq summary:focus-visible{outline:2px solid var(--go-d);outline-offset:3px}
.faq details p{margin:0 0 16px}
@media (prefers-reduced-motion:reduce){.faq summary::after{transition:none}}

/* ---------- CONTACT: three-step plan, three across ----------
   Eyebrow banner, short heading, one line each. Reuses .tag and h3 so the
   type matches every other section. auto-fit collapses it on narrow screens. */
.plan{max-width:1150px;margin:0 auto;padding:96px 6vw 80px;text-align:center}
.plan .head{margin-bottom:52px}
.plan ol{list-style:none;padding:0;margin:0;display:grid;
  grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:38px 40px}
/* h3 inherits a smaller size from the card rules elsewhere; the step titles are
   the section's real headings, so they take the standard h3 scale. */
.plan li h3{font-size:var(--fs-title);margin:8px 0 10px}
.plan li p{color:var(--mut);margin:0 auto;max-width:34ch}
.planfoot{color:var(--mut);max-width:62ch;margin:44px auto 26px}

/* Body-copy links inside a .pgrid text column. Contextual internal links only,
   so they have to read as links without shouting. */
.pgrid p a{color:var(--go-d);text-decoration:underline;text-underline-offset:3px;
  text-decoration-thickness:1px}
.pgrid p a:hover{color:var(--go)}

/* ---------- SHARED GUTTER ----------
   The nav and the page hero are full-bleed, but their text used a plain 4vw/6vw
   inset while .pgrid sits in a centred 1150px box. That left the logo and the H1
   ~90px to the left of the body copy below them. This lands all three on one
   line: (100% - 1150px)/2 matches .pgrid's auto margin, + 6vw matches its inset,
   and the max() keeps the plain inset once the viewport drops under 1150px. */
@media (min-width:1150px){
  .nav,.hero,.page-hero{padding-inline:calc((100% - 1150px)/2 + 6vw)}
}
.nav .links{gap:48px}


/* ---------- MAP FACADE SCRIM ----------
   The static map is now real, so the button sits on top of a busy image. A cream
   veil knocks the map back far enough for the pin and pill to read, and lifts on
   hover so the whole panel feels like the control it is. */
.mapload{background:rgba(251,247,240,.42);transition:background .25s}
.mapload:hover,.mapload:focus-visible{background:rgba(251,247,240,.18)}

/* ---------- MINIMUM READABLE SIZE ----------
   Operator: body copy must never drop below 1rem. Interior pages had drifted to
   13.5-15.5px across the prose, card, lane and CTA components, which reads small
   on a phone. Micro-labels keep their size on purpose: the .tag eyebrows, the
   .diet chips and the .areas town pills are furniture, not reading matter. */
.prose p,.prose li,.qcta p,.pgrid p,.flex p,.mcols li,
.lv p,.lv ul,.scard p,.sub,.triage .foot,.strip span,
.q figcaption b,.fcol a:not(.fcall){font-size:var(--fs-body)}
.prose p{line-height:1.7}
.lv ul{line-height:1.5}
.lv .step a,.cta,.hero-cta,.glass-ghost{font-size:var(--fs-body)}
.qcta .cta{font-size:var(--fs-body)}
.q figcaption i{font-size:var(--fs-label)}
.faq summary{font-size:var(--fs-body)}

/* ---------- CORPORATE PAGE COMPONENTS ----------
   Three new components for the corporate spec. Block 3 is a single horizontal
   proof strip, not cards, so the numbers read as one line of evidence. Blocks 6
   and 7 are grids and lists so procurement can scan for their event type and
   their service style without reading prose. */

/* Block 3, proof strip */
.cstrip{max-width:1100px;margin:0 auto;padding:34px 6vw 8px}
.cstrip ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(4,1fr);gap:0;
  border-top:1px solid var(--hairline);border-bottom:1px solid var(--hairline)}
.cstrip li{padding:22px 20px;text-align:center;border-left:1px solid var(--hairline)}
.cstrip li:first-child{border-left:0}
.cstrip b{display:block;font-family:var(--font-display);font-weight:600;
  font-size:var(--fs-h2);color:var(--hunter);
  letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.cstrip i{display:block;font-style:normal;margin-top:6px;
  font-size:var(--fs-micro);font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--meta)}
@media (max-width:760px){
  .cstrip ul{grid-template-columns:1fr 1fr}
  .cstrip li:nth-child(odd){border-left:0}
  .cstrip li:nth-child(-n+2){border-bottom:1px solid var(--hairline)}
  .cstrip li{padding:18px 12px}
}

/* The stat strip runs edge to edge, so the CTA under it needs air */
.cstrip + .qcta{padding-top:56px}

/* Block 6, occasion tiles */
.ctiles{padding:70px 5vw;max-width:1150px;margin:0 auto}
.ctiles .tilefoot{max-width:60ch;margin:28px auto 0;text-align:center;
  font-size:var(--fs-body);color:var(--meta);line-height:1.6}
.ctiles .head{max-width:56ch;margin:0 auto 34px;text-align:center}
.ctiles .head h2{font-size:var(--fs-h2);margin:10px 0 12px}
.ctiles ul{list-style:none;margin:0;padding:0;display:grid;
  grid-template-columns:repeat(3,1fr);gap:16px}
.ctiles li{background:#fff;border:1px solid var(--hairline);border-radius:var(--r);
  padding:24px 22px;transition:transform .34s var(--smooth),border-color .25s var(--smooth)}
.ctiles li:hover{transform:translateY(-3px);border-color:var(--sage-k)}
.ctiles h3{font-family:var(--font-display);font-weight:600;
  font-size:var(--fs-title);margin:0 0 8px;color:var(--hunter)}
.ctiles p{font-size:var(--fs-body);color:var(--meta);margin:0;line-height:1.55}
@media (max-width:900px){.ctiles ul{grid-template-columns:1fr 1fr}}
@media (max-width:620px){.ctiles ul{grid-template-columns:1fr}}

/* Block 7, service style and menu split */
.csplit{padding:10px 5vw 80px;max-width:1150px;margin:0 auto;
  display:grid;grid-template-columns:1fr 1fr;gap:20px}
.csplit .col{background:var(--sage);border:1px solid var(--hairline);
  border-radius:var(--r);padding:30px 28px}
.csplit .col+.col{background:var(--cream2)}
.csplit h2{font-size:var(--fs-title);margin:10px 0 16px;color:var(--hunter)}
.csplit ul{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:2px}
.csplit li{font-size:var(--fs-body);color:var(--body-tx);padding:11px 0;
  border-bottom:1px solid var(--hairline);display:flex;gap:10px;align-items:baseline}
.csplit li:last-of-type{border-bottom:0}
.csplit li::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;
  background:var(--sage-k);transform:translateY(-2px)}
.csplit .foot{margin:16px 0 0;font-size:var(--fs-body);color:var(--meta);line-height:1.6}
@media (max-width:820px){.csplit{grid-template-columns:1fr;padding-bottom:60px}}

/* Corporate page: outcome list under "The best corporate catering is invisible".
   The four outcomes are parallel claims, so they read as a list rather than a
   paragraph, which also keeps each one to a single line on a phone. */
.prose ul{list-style:none;margin:0 0 18px;padding:0;display:flex;flex-direction:column;gap:2px}
.prose ul li{padding:11px 0;border-bottom:1px solid var(--hairline);
  display:flex;gap:10px;align-items:baseline;color:var(--body-tx)}
.prose ul li:last-child{border-bottom:0}
.prose ul li::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;
  background:var(--sage-k);transform:translateY(-2px)}

/* Corporate page: the trust band lost its .sub line, so the town chips were
   sitting straight under the display line with nothing between them. */
.trust .areas{margin:34px auto 38px}

/* "The best corporate catering is invisible" is a section headline, not a
   run-of-prose h2, so it gets display size like the other section heads. */
.prose h2.lede{font-size:var(--fs-h2);margin:0 0 14px}

/* ---------- TOUCH TARGETS ----------
   The footer's site map rendered as 22px-tall links separated by an 11px gap,
   which is under the 24px minimum and fiddly with a thumb. The gap becomes
   padding on the link itself: every target grows to about 32px while the pitch,
   and therefore the footer height the operator spent three passes tuning,
   stays where it was. Same trade on the legal row and the triage card links. */
.fcol ul{gap:0}
.fcol a:not(.fcall){display:block;padding:5px 0}
.fbarin a{display:inline-block;padding:5px 0}
.lv .step a{padding:6px 0;margin-top:8px}
@media (max-width:760px){
  .fcol ul{gap:0}
  .fcol a:not(.fcall){padding:5px 0}
}

/* ================= MOTION PASS: TOUCH, ACCORDION, FAB =================
   The site's motion was all hover-driven, which meant the device most of these
   visitors are holding got almost none of it. Everything below answers one of
   three questions a phone user is actually asking: is this tappable, did my
   tap register, and where did the phone number go.

   Transform and opacity only. Every effect has a reduced-motion off-switch. */

/* ---- 1. Press feedback on everything tappable ----
   .press is set by reveal.js on pointerdown. :active is unreliable on iOS,
   which is exactly the platform this is for, so the class carries it. The
   amounts are deliberately small: a 2 percent squash reads as a response, a
   10 percent one reads as a toy. */
.lv .step.press,.scard.press,.ctiles li.press,.ggrid figure.press{
  transform:scale(.985) translateY(1px);
  transition:transform .09s ease-out}
.diet i.press,.areas i.press,.areas a.press,.sharebtn.press,.branch .opt.press{
  transform:scale(.94);
  transition:transform .09s ease-out}
.roster-names li.press{transform:translateX(3px) scale(.995);transition:transform .09s ease-out}
.faq summary.press{transform:translateX(2px);transition:transform .09s ease-out}
.mapload.press .pin{transform:scale(.92);transition:transform .09s ease-out}
.fab.press,.totop.press{transform:scale(.9);transition:transform .09s ease-out}

/* A resting transition so the release springs back rather than snapping. These
   are written per element rather than as one blanket rule: several of these
   already transition background, border or shadow, and a bare
   "transition:transform" would silently drop those. */
.faq summary,.diet i,.areas i,.areas a,.ggrid figure{transition:transform .34s var(--spring)}
.scard{transition:transform .34s var(--spring),box-shadow .2s,border-color .2s}
.ctiles li{transition:transform .34s var(--spring),border-color .25s var(--smooth)}
.sharebtn{transition:transform .34s var(--spring),background .2s var(--smooth),border-color .2s var(--smooth)}
.totop{transition:transform .34s var(--spring),opacity .25s}

/* Keyboard parity: a focused card gets the same lift a hovered one gets. */
.scard:focus-visible,.ctiles li:focus-visible{transform:translateY(-3px)}

/* ---- 2. FAQ accordion opens instead of snapping ----
   Native <details> with no JS and no wrapper element. ::details-content plus
   interpolate-size is the only way to transition to an unknown height without
   measuring it, and where the browser does not support it the accordion simply
   opens instantly, which is exactly what it does today. Nothing regresses. */
/* The answer fades and rises in when the panel opens, and the chevron sweeps
   round. The height itself still snaps, deliberately: transitioning a <details>
   to its open height needs ::details-content plus interpolate-size, and the
   failure mode when that pair does not run is an answer clipped to zero height.
   A FAQ that can hide its own answers is a worse outcome than one that opens
   instantly, so the height is left alone and only the content is animated.
   Nothing here can hide anything: with no animation support the answer is
   simply visible, which is what it is today. */
@keyframes faqin{from{opacity:0;translate:0 -6px}to{opacity:1;translate:none}}
.faq details[open] > :not(summary){animation:faqin .3s var(--smooth)}
.faq summary::after{transition:transform .3s var(--smooth)}

/* ---- 3. The floating call button arrives when the inline one leaves ----
   reveal.js adds .tuck while a page's own Call button is on screen. Two
   buttons for one action at the same moment is noise; the FAB appearing as the
   inline one scrolls away is the site saying the phone number came with you.
   Tucking rather than revealing keeps the no-JS case unchanged. */
.fab{transition:transform .38s var(--spring),opacity .24s var(--smooth)}
.fab.tuck{transform:scale(.4);opacity:0;pointer-events:none}

@media (prefers-reduced-motion:reduce){
  .lv .step.press,.scard.press,.ctiles li.press,.ggrid figure.press,
  .diet i.press,.areas i.press,.sharebtn.press,
  .branch .opt.press,.roster-names li.press,.faq summary.press,
  .fab.press,.totop.press{transform:none}
  .mapload.press .pin{transform:none}
  .scard,.ctiles li,.ggrid figure,.faq summary,.diet i,.areas i,
  .sharebtn,.fab,.totop{transition:none}
  .faq details[open] > :not(summary){animation:none}
  .faq summary::after{transition:none}
  /* The FAB still hides while the inline button is on screen, it just does not
     animate on the way out. */
  .fab.tuck{transform:none;opacity:0}
}

/* ============================================================
   MOBILE DRAWER
   The page itself is the card that slides. Everything below the
   hamburger lives in .shell, which translates left while the drawer
   comes in from the right, so the two move as one gesture. .fab,
   .totop, the scrim and the drawer sit outside .shell on purpose:
   position:fixed does not survive a transformed ancestor.
   ============================================================ */
.shell{transform:translate3d(0,0,0);transition:transform .44s cubic-bezier(.32,.72,0,1)}
body.mopen .shell{transform:translate3d(calc(-1 * var(--mw)),0,0)}
:root{--mw:min(80vw,330px)}
html.mlock,html.mlock body{overflow:hidden}

.mtoggle{justify-self:end;background:transparent;border:0;padding:10px 6px;
  cursor:pointer;color:#FBF7F0;-webkit-tap-highlight-color:transparent}
.nav.scrolled .mtoggle{color:#163832}
.mtoggle .bars{display:block;width:26px;height:18px;position:relative}
.mtoggle .bars i{position:absolute;left:0;width:100%;height:2px;border-radius:2px;
  background:currentColor;transition:transform .34s cubic-bezier(.32,.72,0,1),opacity .2s}
.mtoggle .bars i:nth-child(1){top:0}
.mtoggle .bars i:nth-child(2){top:8px}
.mtoggle .bars i:nth-child(3){top:16px}
body.mopen .mtoggle .bars i:nth-child(1){transform:translateY(8px) rotate(45deg)}
body.mopen .mtoggle .bars i:nth-child(2){opacity:0}
body.mopen .mtoggle .bars i:nth-child(3){transform:translateY(-8px) rotate(-45deg)}

.mscrim{position:fixed;inset:0;background:rgba(5,31,32,.45);z-index:70;
  opacity:0;pointer-events:none;transition:opacity .44s cubic-bezier(.32,.72,0,1)}
body.mopen .mscrim{opacity:1;pointer-events:auto}
.mscrim[hidden]{display:block}

.mdrawer{position:fixed;top:0;right:0;z-index:80;width:var(--mw);height:100dvh;
  display:flex;flex-direction:column;gap:6px;padding:0 22px 28px;
  background:var(--go-d);color:#FBF7F0;overflow-y:auto;overscroll-behavior:contain;
  box-shadow:-18px 0 40px rgba(5,31,32,.28);
  transform:translate3d(100%,0,0);visibility:hidden;
  transition:transform .44s cubic-bezier(.32,.72,0,1),visibility .44s}
body.mopen .mdrawer{transform:translate3d(0,0,0);visibility:visible}
/* The drawer scrolls on a short phone, so the close button rides with it. */
.mdrawer .mhead{position:sticky;top:0;z-index:1;background:var(--go-d);
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  margin:0 -22px 0;padding:18px 22px 14px;
  border-bottom:1px solid rgba(218,241,222,.18)}
.mdrawer .mhead img{height:42px;width:auto}
.mclose{background:rgba(251,247,240,.1);border:0;border-radius:50%;width:40px;height:40px;
  display:flex;align-items:center;justify-content:center;color:#FBF7F0;cursor:pointer;
  transition:background .2s}
.mclose:hover{background:rgba(251,247,240,.2)}
.mclose svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round}
.mnav{display:flex;flex-direction:column;padding:8px 0 4px}
.mnav a{color:#FBF7F0;text-decoration:none;-webkit-tap-highlight-color:transparent}
.mnav .mtop{font-family:var(--font-display);font-weight:600;font-size:var(--fs-title);
  padding:11px 0;border-bottom:1px solid rgba(218,241,222,.12)}
.mnav .mgroup{display:block;font-family:var(--font-display);font-weight:600;
  font-size:var(--fs-body);color:var(--sage3);letter-spacing:.04em;
  padding:12px 0 2px;border-bottom:1px solid rgba(218,241,222,.12)}
.mnav ul{list-style:none;margin:0;padding:8px 0 12px}
.mnav ul a{display:block;padding:8px 0 8px 14px;font-size:var(--fs-body);color:var(--go-t);
  border-left:2px solid rgba(218,241,222,.2)}
.mnav a[aria-current="page"]{color:var(--sage3)}
.mcall{margin-top:auto;display:flex;align-items:center;gap:12px;text-decoration:none;
  background:var(--go);color:#fff;border-radius:12px;padding:14px 18px}
.mcall .phic{width:22px;height:22px;fill:currentColor}
.mcall b{display:block;font-size:var(--fs-body)}
.mcall i{display:block;font-style:normal;font-size:var(--fs-label);opacity:.9}
.mfoot{margin-top:12px;font-size:var(--fs-label);color:var(--go-t);opacity:.8;text-align:center}

/* The operator wants one menu at every width, so the burger never hides and
   the drawer is not a phone-only component. The desktop nav keeps its inline
   links; the burger sits to the right of the call button. */
.mtoggle{display:inline-flex;align-items:center}
.nav{grid-template-columns:1fr auto 1fr auto}
/* The call FAB and the back-to-top button would sit on top of the scrim. */
body.mopen .fab,body.mopen .totop{opacity:0;pointer-events:none}
/* Below 900 the inline links, the call pill and the burger stop fitting on one
   row and the pill wraps to three lines. The burger covers the same links at
   every width now, so the inline row is the part that goes. */
@media (max-width:900px){
  .nav{grid-template-columns:auto auto auto;column-gap:10px}
  .nav .links{display:none}
}
@media (max-width:700px){
  .nav .ncall{padding:10px 16px}
}

@media (prefers-reduced-motion:reduce){
  .shell,.mdrawer,.mscrim,.mtoggle .bars i{transition:none}
}

/* The client's designed menu card, between the list and the CTA pair on the
   breakfast, Italian and Mexican pages. The HTML list above it stays the
   indexable copy; this is the version people screenshot and text around.
   Sources are 670px wide, so the card caps at 440px to stay sharp. */
.mflyer{max-width:440px;margin:0 auto 44px;padding:0 6vw;box-sizing:content-box}
.mflyer img{display:block;width:100%;padding:12px;background:var(--cream2);border:1px solid var(--line);border-radius:var(--r);
  box-shadow:0 18px 40px -22px rgba(16,36,29,.45)}
