:root{
  --red:#C8202A; --red-dark:#A2161F; --ink:#141110; --ink-2:#1d1a18;
  --cream:#faf7f2; --paper:#ffffff; --muted:#6b6460; --line:#e7e1d8;
  /* --line is a DECORATIVE rule (card edges, section dividers) at 1.30:1 and
     stays that way. --line-strong is the boundary of an actual UI COMPONENT —
     input, select, textarea, .btn-outline, the qty stepper, the progress track
     — where WCAG 2.2 SC 1.4.11 requires 3:1. Measured: 3.39:1 on --paper,
     3.17:1 on --cream (was 1.30:1 and 1.22:1). Keep the two apart; widening
     --line itself would darken every card border on the site. */
  --line-strong:#948a7e;
  /* The light brand red. Small text and the active nav link sit on the darkened
     page-hero photos, which needs 4.5:1 — see the .pagehero scrim note. */
  --coral:#ff6b62;
  /* "Food minimum met" green. Was #1a8f4c = 4.14:1 on white, under the 4.5:1
     that 13px/600 text needs. #178744 measures 4.58:1. */
  --green:#178744;
  --shadow:0 18px 50px -18px rgba(0,0,0,.35);
  --maxw:1180px;
}
*{box-sizing:border-box;margin:0;padding:0}
/* scroll-padding keeps the fixed header and the sticky order/total bars from
   sitting on top of whatever just took focus (SC 2.4.11). The header is 84px
   unscrolled; the bottom bars are ~70px where they show. */
html{scroll-behavior:smooth;scroll-padding-top:100px;scroll-padding-bottom:88px}
body{font-family:'Inter',system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:var(--ink);background:var(--cream);line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
img{max-width:100%;display:block}
a{color:inherit;text-decoration:none}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 clamp(20px,5vw,40px)}
.wrap.narrow{max-width:760px}
.display{font-family:'Anton',Impact,sans-serif;font-weight:400;text-transform:uppercase;letter-spacing:.01em;line-height:.95}
.eyebrow{font-weight:700;text-transform:uppercase;letter-spacing:.22em;font-size:.78rem;color:var(--red)}

.btn{display:inline-flex;align-items:center;gap:.55em;font-weight:700;font-size:.95rem;letter-spacing:.02em;text-transform:uppercase;padding:.95em 1.7em;border-radius:999px;transition:transform .18s ease,box-shadow .2s ease,background .2s ease;white-space:nowrap;cursor:pointer;border:2px solid transparent}
.btn-red{background:var(--red);color:#fff;box-shadow:0 10px 24px -8px rgba(200,32,42,.6)}
.btn-red:hover{background:var(--red-dark);transform:translateY(-2px);box-shadow:0 16px 30px -10px rgba(200,32,42,.7)}
.btn-ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.55)}
.btn-ghost:hover{background:#fff;color:var(--ink);border-color:#fff;transform:translateY(-2px)}
.btn-dark{background:var(--ink);color:#fff}
.btn-dark:hover{background:#000;transform:translateY(-2px)}
.btn-outline{background:transparent;color:var(--ink);border-color:var(--line-strong)}
.btn-outline:hover{border-color:var(--ink);transform:translateY(-2px)}
.btn-sm{padding:.7em 1.25em;font-size:.82rem}

header{position:fixed;top:0;left:0;right:0;z-index:50;transition:background .3s ease,box-shadow .3s ease,padding .3s ease;padding:16px 0}
/* The open drawer has to sit above .mobile-order (60) and .cbar (55); at
   320x256 those bars were hit-testing over the "Careers" and "Gift Cards"
   links. The drawer is a child of <header>, so the header is what has to lift. */
header:has(#navlinks.open){z-index:80}
header.scrolled,header.solid{background:rgba(20,17,16,.92);backdrop-filter:blur(12px);box-shadow:0 1px 0 rgba(255,255,255,.06);padding:8px 0}
/* flex-wrap + min-width:0: at the browser's 200% font-size preference the nav
   row wanted 1315px in a 1280px viewport and "Order Online" was clipped by 35px
   with no way to scroll to it — SC 1.4.4. It now wraps onto a second line and
   the header grows, which is what the fixed header should have done all along.
   (200% page ZOOM always passed; the two paths are not the same test.) */
.nav{display:flex;align-items:center;justify-content:space-between;gap:12px 20px;flex-wrap:wrap}
.nav-links{min-width:0;flex-wrap:wrap}
.brand{display:flex;align-items:center;gap:12px;font-family:'Anton',sans-serif;text-transform:uppercase;color:#fff;font-size:1.15rem;letter-spacing:.04em}
.brand img{height:52px;width:52px;border-radius:50%;background:#fff;padding:2px;transition:height .3s ease}
header.scrolled .brand img{height:46px;width:46px}
.nav-links{display:flex;align-items:center;gap:30px}
.nav-links a{color:#fff;font-weight:600;font-size:.92rem;letter-spacing:.02em;opacity:.9;transition:opacity .2s}
.nav-links a:hover,.nav-links a.on{opacity:1}
.nav-links a.on{color:#ff6b62}
.nav-cta{display:flex;align-items:center;gap:14px}
.hamb{display:none;flex-direction:column;gap:5px;background:none;border:0;cursor:pointer;padding:8px}
.hamb span{width:26px;height:2.5px;background:#fff;border-radius:2px;transition:.25s}

/* hero (home) */
.hero{position:relative;min-height:100svh;display:flex;align-items:center;overflow:hidden}
.hero video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:0}
/* The veil is the ONLY thing standing between the hero type and a 30-frame
   video whose brightest region measured rgb(163,162,162). At the old
   .55/.35/.82 the white h1 ran 2.55:1, the lede 2.72:1, the badges 2.63:1 and
   the red "Made to Order." a flat 1.00:1 — all below SC 1.4.3. A text colour
   cannot fix that on its own: #C8202A sits at the same luminance as a mid-grey
   frame, so it fails against a bright video AND against a dark scrim. The scrim
   is therefore the fix (Dimitrios asked for "a subtle dark grade so white hero
   text pops more" on Jul 13 2026 — this is that grade, measured). Worst case
   now composites to rgb(67,67,67): white 9.9:1, --coral 3.6:1. */
.hero .veil{position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(20,17,16,.76) 0%,rgba(20,17,16,.80) 50%,rgba(20,17,16,.92) 100%)}
.hero .wrap{position:relative;z-index:2;color:#fff;padding-top:120px;padding-bottom:60px;width:100%}
.hero h1{font-size:clamp(3rem,9vw,7rem);color:#fff;text-shadow:0 6px 40px rgba(0,0,0,.4);max-width:14ch}
/* --coral, not --red: at 112px this needs 3:1 and --red cannot reach it over
   video at any scrim short of opaque. --coral is the same accent the nav and
   the page heroes already use, so the hero still reads brand-red. */
.hero h1 em{color:var(--coral);font-style:normal}
/* 12.5px needs 4.5:1, which no red or coral clears over the video — white does
   (9.9:1). The letter-spaced uppercase treatment is unchanged. */
.hero .eyebrow{color:#fff}
.hero p.lede{margin:22px 0 34px;font-size:clamp(1.05rem,2.2vw,1.35rem);max-width:44ch;color:rgba(255,255,255,.92);font-weight:500}
.hero .cta-row{display:flex;gap:14px;flex-wrap:wrap}
.hero .badges{margin-top:38px;display:flex;gap:26px;flex-wrap:wrap;font-size:.82rem;font-weight:600;letter-spacing:.05em;text-transform:uppercase;color:rgba(255,255,255,.8)}
.hero .badges span{display:flex;align-items:center;gap:8px}
.hero .badges span::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--red)}
.scrollcue{position:absolute;bottom:22px;left:50%;transform:translateX(-50%);z-index:3;color:rgba(255,255,255,.7);font-size:.72rem;letter-spacing:.25em;text-transform:uppercase;display:flex;flex-direction:column;align-items:center;gap:8px}
.scrollcue::after{content:"";width:1px;height:34px;background:linear-gradient(rgba(255,255,255,.7),transparent);animation:pulse 1.8s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:.3}50%{opacity:1}}
/* SC 2.2.2 — the hero video loops for 64s and the Fan Favorites cards re-deal
   every 4.5s, both for longer than 5s and both alongside other content, so
   there has to be a way to stop them. One control stops both. */
.motion-toggle{position:absolute;right:clamp(20px,5vw,40px);bottom:22px;z-index:3;
  font-family:inherit;font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:#fff;background:rgba(20,17,16,.78);border:1px solid rgba(255,255,255,.5);
  border-radius:999px;padding:.7em 1.2em;cursor:pointer}
.motion-toggle:hover{background:rgba(20,17,16,.95);border-color:#fff}
/* Above the fixed .mobile-order bar. At bottom:22px the control took focus
   completely underneath it at 375px (SC 2.4.11), and the hero is at the top of
   the document so there is nowhere to scroll it clear to. */
@media(max-width:720px){ .motion-toggle{bottom:92px} }

/* inner page hero banner */
/* Scrim deepened from .72/.86. The eyebrow (--coral, 17.6px) measured 3.70:1 on
   /menu, /careers and /catering-truck and the active nav link 3.30:1 on /story,
   both under the 4.5:1 SC 1.4.3 wants — the photos underneath are simply too
   bright in places. At .84/.92 the same colour measures 5.2:1 and 4.6:1, so the
   accent survives instead of being bleached out of the design. */
.pagehero{position:relative;padding:180px 0 70px;color:#fff;overflow:hidden;background:linear-gradient(rgba(18,15,14,.84),rgba(18,15,14,.92)),var(--bg) center/cover no-repeat;background-color:var(--ink)}
.pagehero h1{font-size:clamp(2.6rem,7vw,5rem);margin:.2em 0 .25em}
.pagehero p{max-width:52ch;color:rgba(255,255,255,.85);font-size:1.1rem}

section{position:relative}
.pad{padding:clamp(64px,9vw,120px) 0}
.sec-head{text-align:center;max-width:640px;margin:0 auto clamp(38px,5vw,60px)}
.sec-head h2{font-size:clamp(2.2rem,5.5vw,3.6rem);margin:.35em 0 .3em}
.sec-head p{color:var(--muted);font-size:1.08rem}
.lead-p{font-size:1.3rem;font-weight:500;color:var(--ink);margin-bottom:20px;line-height:1.5}
.narrow p{margin-bottom:16px;color:#4b4540;font-size:1.05rem}

/* favorites grid */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.card{position:relative;border-radius:20px;overflow:hidden;background:var(--ink);box-shadow:var(--shadow);aspect-ratio:4/5}
.card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .6s cubic-bezier(.2,.7,.2,1),opacity .45s ease}
.card .cap h3,.card .cap span{transition:opacity .45s ease;will-change:opacity;-webkit-backface-visibility:hidden;backface-visibility:hidden}
.card:hover img{transform:scale(1.06)}
.card .cap{position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;justify-content:flex-end;padding:22px;background:linear-gradient(180deg,transparent 40%,rgba(15,12,11,.85) 100%);color:#fff}
.card .cap h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.5rem;letter-spacing:.02em;line-height:1}
.card .cap span{font-size:.9rem;color:rgba(255,255,255,.82);margin-top:5px}
.menu-cta{text-align:center;margin-top:46px;display:flex;gap:12px;justify-content:center;flex-wrap:wrap}

/* story */
.story{background:var(--ink);color:#fff}
.story .split{display:grid;grid-template-columns:1.05fr 1fr;gap:clamp(30px,6vw,72px);align-items:center}
.story img{border-radius:20px;box-shadow:var(--shadow);aspect-ratio:3/2;object-fit:cover;width:100%}
.story h2{font-size:clamp(2.1rem,5vw,3.4rem);color:#fff;margin:.35em 0 .5em}
.story p{color:rgba(255,255,255,.82);font-size:1.08rem;margin-bottom:16px;max-width:52ch}
.story .eyebrow{color:#ff6b62}

/* values row */
.values{display:grid;grid-template-columns:repeat(3,1fr);gap:24px}
.value{background:var(--paper);border:1px solid var(--line);border-radius:18px;padding:32px 28px}
.value h2,.value h3{font-size:1.5rem;color:var(--red);margin-bottom:10px}
.value p{color:var(--muted)}

/* catering band */
.catering{position:relative;color:#fff;overflow:hidden;background:linear-gradient(120deg,var(--red-dark),var(--red))}
.catering .split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(30px,6vw,60px);align-items:center}
.catering h2{font-size:clamp(2rem,5vw,3.2rem);color:#fff;margin-bottom:.4em}
.catering p{color:rgba(255,255,255,.92);font-size:1.1rem;margin-bottom:26px;max-width:44ch}
.catering img{border-radius:18px;filter:drop-shadow(0 20px 40px rgba(0,0,0,.35))}
.catering-split{align-items:center}
.catering-split img{filter:drop-shadow(0 16px 30px rgba(0,0,0,.25));margin-bottom:8px}
.chk{list-style:none;margin:8px 0 0}
.chk li{position:relative;padding-left:30px;margin:12px 0;color:#4b4540;font-size:1.05rem}
.chk li::before{content:"";position:absolute;left:0;top:2px;width:20px;height:20px;border-radius:50%;background:var(--red);background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'><path d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/></svg>");background-size:14px;background-position:center;background-repeat:no-repeat}

/* menu page */
.menu-wrap .menu-block{margin-bottom:clamp(48px,7vw,84px)}
.mb-head{border-bottom:2px solid var(--line);padding-bottom:16px;margin-bottom:30px}
.mb-head h2{font-size:clamp(1.8rem,4.5vw,2.7rem)}
.mb-head p{color:var(--muted);margin-top:4px}
.menu-list{display:grid;grid-template-columns:1fr 1fr;gap:20px 40px}
.menu-item{display:flex;gap:18px;align-items:center;padding:14px;border-radius:16px;transition:background .2s}
.menu-item:hover{background:#fff}
.menu-item img{width:92px;height:92px;object-fit:cover;border-radius:12px;flex-shrink:0;box-shadow:var(--shadow)}
.menu-item .mi-noimg{width:92px;height:92px;border-radius:12px;flex-shrink:0;background:linear-gradient(135deg,#efe9e0,#e2dacb);display:flex;align-items:center;justify-content:center}
.menu-item .mi-noimg::after{content:"";width:34px;height:34px;background:var(--red);-webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 10h16a0 0 0 0 1 0 0 8 8 0 0 1-8 8 8 8 0 0 1-8-8zM6 14h12M5 20h14'/></svg>") center/contain no-repeat;mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 10h16a8 8 0 0 1-16 0zM6 14h12M5 20h14'/></svg>") center/contain no-repeat;opacity:.5}
/* min-width:0 lets the flex children actually shrink. Without it the 92px photo
   plus a non-wrapping name plus a nowrap price pushed .menu-list to 338px inside
   a 320px viewport and body{overflow-x:hidden} then CLIPPED the price rather
   than scrolling to it — SC 1.4.10 (the $7.40 on the first row was cut off). */
.mi-body{flex:1;min-width:0}
.mi-head{display:flex;justify-content:space-between;align-items:baseline;gap:12px;flex-wrap:wrap}
.mi-head h3{min-width:0}
.mi-head h3{font-size:1.15rem;font-weight:800;letter-spacing:-.01em}
.mi-price{font-family:'Anton',sans-serif;color:var(--red);font-size:1.15rem;white-space:nowrap}
.mi-body p{color:var(--muted);font-size:.92rem;margin-top:2px}

/* locations page */
.loc-list{display:flex;flex-direction:column;gap:34px}
.loc-full{display:grid;grid-template-columns:1.1fr 1fr;gap:0;border:1px solid var(--line);border-radius:22px;overflow:hidden;background:var(--paper);box-shadow:var(--shadow);transition:transform .3s cubic-bezier(.2,.8,.2,1),box-shadow .3s ease}
.loc-full:hover{transform:translateY(-4px);box-shadow:0 18px 40px rgba(0,0,0,.15)}
.loc-full:nth-child(even){grid-template-columns:1fr 1.1fr}
.loc-full:nth-child(even) .loc-map{order:2}
.loc-map{position:relative;min-height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;text-align:center;color:#fff;background:linear-gradient(135deg,#1d1a18,#2c1417);overflow:hidden;transition:filter .2s ease}
.loc-map::before{content:"";position:absolute;inset:0;opacity:.16;background-image:linear-gradient(rgba(255,255,255,.5) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.5) 1px,transparent 1px);background-size:34px 34px}
.loc-map:hover{filter:brightness(1.12)}
.loc-map .pin-xl{width:56px;height:56px;fill:var(--red);position:relative;filter:drop-shadow(0 6px 14px rgba(0,0,0,.5))}
.loc-map .map-name{position:relative;font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.5rem;letter-spacing:.03em}
.loc-map .map-cta{position:relative;font-size:.82rem;font-weight:700;text-transform:uppercase;letter-spacing:.08em;color:rgba(255,255,255,.75)}
.loc-info{padding:clamp(26px,4vw,44px);display:flex;flex-direction:column;justify-content:center}
.loc-info h2{font-size:clamp(1.8rem,4vw,2.6rem);color:var(--ink)}
.loc-info address{font-style:normal;color:var(--muted);font-size:1.1rem;margin:8px 0 18px;line-height:1.5}
.loc-hours{display:flex;flex-direction:column;gap:2px;margin-bottom:24px;color:#4b4540}
.loc-hours strong{text-transform:uppercase;letter-spacing:.1em;font-size:.75rem;color:var(--red);margin-bottom:4px}
.loc-actions{display:flex;gap:12px;flex-wrap:wrap}

/* homepage locations cards */
.locs .grid{grid-template-columns:repeat(3,1fr)}
.loc{background:var(--paper);border:1px solid var(--line);border-radius:20px;padding:30px 28px;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column}
.loc:hover{transform:translateY(-6px);box-shadow:var(--shadow)}
.loc .pin{width:44px;height:44px;border-radius:12px;background:var(--red);display:flex;align-items:center;justify-content:center;margin-bottom:18px}
.loc .pin svg{width:22px;height:22px;fill:#fff}
.loc h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.55rem;letter-spacing:.02em}
.loc address{font-style:normal;color:var(--muted);margin:8px 0 6px;font-size:1rem;line-height:1.5}
.loc .hours{font-size:.9rem;color:var(--muted);margin-bottom:22px}
.loc .loc-actions{margin-top:auto}
.loc .loc-actions .btn{flex:1;justify-content:center}

/* footer */
footer{background:#0d0b0a;color:rgba(255,255,255,.72);padding:64px 0 30px}
.foot-top{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:40px;padding-bottom:40px;border-bottom:1px solid rgba(255,255,255,.1)}
.foot-brand{display:flex;align-items:center;gap:14px;margin-bottom:16px;color:#fff;font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.3rem}
.foot-brand img{height:52px;width:52px;border-radius:50%;background:#fff;padding:2px}
.footcol h2,.footcol h4{color:#fff;font-size:.8rem;text-transform:uppercase;letter-spacing:.18em;margin-bottom:16px}
.footcol a,.footcol p{display:block;color:rgba(255,255,255,.7);font-size:.95rem;margin-bottom:10px;transition:color .2s}
.footcol a:hover{color:#fff}
.foot-bottom{display:flex;justify-content:space-between;align-items:center;gap:14px;padding-top:24px;font-size:.85rem;flex-wrap:wrap}
.footer-credit{margin-top:12px;font-size:12px;color:rgba(255,255,255,.7)}
.footer-credit a{color:inherit;text-decoration:underline}
.footer-credit a:hover{color:#fff}

.mobile-order{position:fixed;left:0;right:0;bottom:0;z-index:60;padding:12px 16px calc(12px + env(safe-area-inset-bottom));background:rgba(20,17,16,.96);backdrop-filter:blur(10px);display:none}
/* The fixed order bar (and .cbar, same height) permanently covers the last
   ~75px of the document, so the final two footer links — "Accessibility" and
   "Earth Tab" — could take focus completely underneath it with nowhere left to
   scroll (SC 2.4.11). Reserving the height inside the footer, which is already
   dark, gives them somewhere to go without opening a pale gap under it. */
@media(max-width:720px){ footer{padding-bottom:calc(30px + 82px)} }
.mobile-order .btn{width:100%;justify-content:center;padding:1em}

.reveal{opacity:0;transform:translateY(28px);transition:opacity .7s ease,transform .7s ease}
.reveal.in{opacity:1;transform:none}

@media(max-width:900px){
  .grid{grid-template-columns:repeat(2,1fr)}
  .story .split,.catering .split,.catering-split{grid-template-columns:1fr}
  .menu-list{grid-template-columns:1fr}
  .values{grid-template-columns:1fr}
  .locs .grid{grid-template-columns:1fr}
  .loc-full,.loc-full:nth-child(even){grid-template-columns:1fr}
  .loc-full:nth-child(even) .loc-map{order:0}
  .foot-top{grid-template-columns:1fr 1fr}
}
@media(max-width:720px){
  /* visibility:hidden, not just translateX(100%). The drawer was still
     display:flex / visibility:visible / opacity:1 when closed, so its 6 links
     kept their tab stops ~300px off the right edge of the screen — SC 2.4.3 —
     and axe measured their contrast against whatever was behind them (97 of the
     142 baseline violation nodes were exactly that). visibility is animatable,
     so the slide-out still slides.
     overflow-y:auto: at 320x256 the six links need 281px and there was no way
     to scroll to the ones that fell outside — SC 1.4.10. `safe center` keeps
     them centred when they fit and stops the overflow being clipped
     unreachably above the top edge when they do not. */
  /* nowrap matters here: a wrapping COLUMN would spill the overflow into a
     second column sideways instead of scrolling it. */
  /* `visibility 0s .3s` on the closed state and `0s` on the open one: visible
     the instant the drawer opens (so focus can be put on the first link right
     away) and hidden only once the slide-out has finished playing. A plain
     `visibility .3s` transition left it unfocusable for the whole 300ms. */
  .nav-links{position:fixed;inset:0 0 0 auto;width:min(78vw,320px);background:var(--ink-2);flex-direction:column;flex-wrap:nowrap;justify-content:safe center;gap:26px;padding:40px;transform:translateX(100%);visibility:hidden;transition:transform .3s ease,visibility 0s linear .3s;box-shadow:-20px 0 60px rgba(0,0,0,.5);overflow-y:auto;overscroll-behavior:contain}
  .nav-links.open{transform:none;visibility:visible;transition:transform .3s ease,visibility 0s}
  /* backdrop-filter makes the header a containing block for its own
     position:fixed descendants, and the drawer is one of them. So once the page
     was scrolled (header.scrolled), `inset:0 0 0 auto` resolved against the
     62px header instead of the viewport: the drawer collapsed to an 80px strip
     (its own 40px top + 40px bottom padding, the content box clamped to 0) with
     387px of links inside it — SC 1.4.10. Dropping the blur only while the
     drawer is open hands the drawer the viewport back and leaves the scrolled
     header's blur untouched the rest of the time. The .92-alpha background
     stays, so the header still reads as solid behind the open drawer.
     Specificity: :has() takes its argument's, so this is (1,1,1) and beats the
     (0,1,1) `header.scrolled,header.solid` blur declaration without !important. */
  header:has(#navlinks.open){backdrop-filter:none;-webkit-backdrop-filter:none}
  .nav-links a{font-size:1.15rem;flex:0 0 auto}
  .nav-cta .btn:not(.hamb){display:none}
  .hamb{display:flex}
  .mobile-order{display:block}
  .foot-top{grid-template-columns:1fr}
  .hero .wrap{padding-bottom:110px}
  .grid{grid-template-columns:1fr}
}

/* ===== catering order builder ===== */
.corder-intro{background:var(--ink);color:#fff;border-radius:20px;padding:clamp(22px,4vw,34px);display:flex;flex-wrap:wrap;gap:20px 40px;align-items:center;justify-content:space-between;margin-bottom:38px}
.corder-intro .ci-min{font-family:'Anton',sans-serif;font-size:clamp(1.6rem,4vw,2.2rem);line-height:1;color:#fff}
.corder-intro .ci-min small{display:block;font-family:'Inter',sans-serif;font-size:.8rem;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:#ff6b62;margin-bottom:6px}
.corder-intro p{color:rgba(255,255,255,.8);max-width:40ch;margin:0}
.corder-intro a{color:#fff;font-weight:700;white-space:nowrap}
.cbuild{display:grid;grid-template-columns:1.5fr .95fr;gap:44px;align-items:start}
.ccat{margin-bottom:30px}
.ccat>h2,.ccat>h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.5rem;letter-spacing:.02em;margin-bottom:4px}
.ccat>.cc-sub{color:var(--muted);font-size:.92rem;margin-bottom:12px}
.citem{display:flex;justify-content:space-between;align-items:center;gap:16px;padding:13px 0;border-bottom:1px solid var(--line)}
.citem .ci-name{font-weight:600;line-height:1.2}
.citem .ci-price{color:var(--muted);font-size:.88rem;margin-top:2px}
/* overflow:hidden was clipping the 3px :focus-visible outline on all 93
   quantity controls down to two slivers — SC 2.4.7 on the page's primary
   widget. The pill is kept by rounding the two end buttons instead. */
.qty{display:flex;align-items:center;border:1px solid var(--line-strong);border-radius:999px;background:#fff;flex:0 0 auto}
.qty button{width:36px;height:36px;background:#fff;border:none;font-size:1.15rem;line-height:1;cursor:pointer;color:var(--ink);transition:background .15s}
.qty button:first-child{border-radius:999px 0 0 999px}
.qty button:last-child{border-radius:0 999px 999px 0}
.qty button:hover{background:var(--cream)}
.qty button:disabled{opacity:.35;cursor:default}
/* The unavailable state is a colour change, not the .35 opacity the :disabled
   rule uses. Every stepper starts at 0, so .35 would have washed out 46 minus
   signs on page load to 2.27:1 — legal under SC 1.4.3's inactive-component
   exemption, but leaning on an exemption when --muted gives 5.79:1 and reads
   just as clearly as "not available yet" is the wrong trade. */
.qty button[aria-disabled="true"]{color:var(--muted);cursor:default}
/* Three white segments inside one white pill gave the − and + buttons a 1.00:1
   boundary — the controls were invisible as controls (SC 1.4.11). The two rules
   are the only thing separating them. */
.qty input{width:42px;text-align:center;border:none;border-left:1px solid var(--line-strong);border-right:1px solid var(--line-strong);font-weight:700;font-size:1rem;background:#fff;-moz-appearance:textfield;color:var(--ink)}
.qty input::-webkit-outer-spin-button,.qty input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
/* summary + form panel */
.cpanel{position:sticky;top:88px;display:flex;flex-direction:column;gap:18px}
.csummary{background:var(--paper);border:1px solid var(--line);border-radius:18px;padding:22px;box-shadow:var(--shadow)}
.csummary h2,.csummary h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.25rem;margin-bottom:12px}
.csum-list{list-style:none;margin:0 0 12px;max-height:210px;overflow:auto}
.csum-list li{display:flex;justify-content:space-between;gap:12px;font-size:.9rem;padding:5px 0;color:var(--ink)}
.csum-list li span:last-child{color:var(--muted);white-space:nowrap}
.csum-empty{color:var(--muted);font-size:.9rem;padding:6px 0}
.csum-total{display:flex;justify-content:space-between;align-items:baseline;border-top:1px solid var(--line);padding-top:12px;margin-top:4px}
.csum-total .ct-label{font-weight:700}
.csum-total .ct-val{font-family:'Anton',sans-serif;font-size:1.6rem;color:var(--red)}
.min-wrap{margin-top:14px}
.min-bar{height:8px;background:var(--line-strong);border-radius:999px;overflow:hidden}
.min-bar>span{display:block;height:100%;width:0;background:var(--red);border-radius:999px;transition:width .35s ease}
.min-note{font-size:.82rem;margin-top:7px;color:var(--muted)}
.min-note.met{color:var(--green);font-weight:600}
/* form */
.cform{background:var(--paper);border:1px solid var(--line);border-radius:18px;padding:22px;box-shadow:var(--shadow)}
.cform h2,.cform h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.25rem;margin-bottom:14px}
.cform .frow{display:grid;gap:12px;margin-bottom:12px}
.cform .frow.two{grid-template-columns:1fr 1fr}
.cform .frow.three{grid-template-columns:2fr 1fr 1fr}
.cf-fieldset{border:1px solid var(--line-strong);border-radius:12px;padding:12px 14px 6px;margin:0}
.cf-fieldset legend{font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--ink);padding:0 6px}
.cf-fieldset legend .req{color:var(--red)}
.cf-radios{display:grid;grid-template-columns:1fr 1fr;gap:8px 16px;margin-top:6px}
.cf-radio{display:flex;align-items:center;gap:8px;font-size:.9rem;font-weight:500;margin-bottom:8px;cursor:pointer}
.cf-radio input{width:auto;margin:0;accent-color:var(--red);flex:0 0 auto}
.cf-radio span{color:var(--ink)}
.cform label{display:block;font-size:.8rem;font-weight:600;letter-spacing:.02em;color:var(--ink);margin-bottom:5px}
.cform label .req{color:var(--red)}
.cform input,.cform select,.cform textarea{width:100%;font-family:inherit;font-size:.95rem;padding:11px 13px;border:1px solid var(--line-strong);border-radius:10px;background:#fff;color:var(--ink)}
.cform input:focus,.cform select:focus,.cform textarea:focus{outline:none;border-color:var(--red);box-shadow:0 0 0 3px rgba(200,32,42,.12)}
.cform textarea{min-height:78px;resize:vertical}
.cform .btn{width:100%;justify-content:center;padding:1em;margin-top:6px}
.cf-hide{display:none}
/* Netlify's honeypot, hidden the way Netlify documents it. It used to be parked
   at left:-9999px, which kept it focusable: a screen-reader or keyboard user
   tabbed into a field labelled "Leave blank", and anything typed there got the
   whole application silently binned as spam. display:none takes it out of the
   tab order and out of the accessibility tree; the bot trap still works. */
.cf-hp{display:none}
.cthanks{background:var(--paper);border:1px solid var(--line);border-radius:18px;padding:40px 26px;text-align:center;box-shadow:var(--shadow)}
.cthanks .ct-ico{width:58px;height:58px;border-radius:999px;background:var(--red);display:flex;align-items:center;justify-content:center;margin:0 auto 16px}
.cthanks .ct-ico svg{width:30px;height:30px;fill:#fff}
.cthanks h2,.cthanks h3{font-family:'Anton',sans-serif;text-transform:uppercase;font-size:1.6rem;margin-bottom:8px}
.cthanks p{color:var(--muted);max-width:40ch;margin:0 auto}
/* mobile sticky total */
.cbar{position:fixed;left:0;right:0;bottom:0;z-index:55;background:rgba(20,17,16,.97);backdrop-filter:blur(10px);color:#fff;display:none;justify-content:space-between;align-items:center;gap:14px;padding:12px 16px calc(12px + env(safe-area-inset-bottom))}
.cbar .cb-total{font-family:'Anton',sans-serif;font-size:1.3rem}
.cbar .cb-total small{display:block;font-family:'Inter',sans-serif;font-size:.68rem;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:rgba(255,255,255,.6)}
.cbar .btn{padding:.8em 1.4em}
@media(max-width:900px){
  .cbuild{grid-template-columns:1fr;gap:28px}
  .cpanel{position:static}
  .csum-list{max-height:none}
}
@media(max-width:720px){
  .cform .frow.two,.cform .frow.three{grid-template-columns:1fr}
  .cf-radios{grid-template-columns:1fr}
  .cbar{display:flex}
  .cbuild{padding-bottom:70px}
}

/* catering: green when food minimum met */
.min-bar>span.met{background:var(--green)}
.csum-total .ct-val.met{color:var(--green)}
.cbar .cb-total.met{color:#54dd8b}
/* clickable store addresses — underlined, not colour-only. SC 1.4.1: the
   address link inherits the surrounding colour, so with no underline there was
   nothing at all to tell a colour-blind reader it was a link (1.00:1 against
   the text around it). */
.addr-link{color:inherit;text-decoration:underline;text-underline-offset:2px;transition:color .18s ease}
.addr-link:hover{color:var(--red)}
/* Same rule for phone and email links sitting inside a block of text — axe's
   link-in-text-block fired 29 times across all 9 routes on these. Buttons are
   excluded: a pill button is already distinguishable without an underline. */
a[href^="tel:"]:not(.btn),a[href^="mailto:"]:not(.btn){text-decoration:underline;text-underline-offset:2px}

/* story page two-column intro (fills dead space) */
.split-2{display:grid;grid-template-columns:1.05fr .95fr;gap:clamp(30px,6vw,64px);align-items:center}
.split-2 img{border-radius:20px;box-shadow:var(--shadow);aspect-ratio:4/5;object-fit:cover;width:100%}
@media(max-width:900px){ .split-2{grid-template-columns:1fr;gap:28px} .split-2 img{aspect-ratio:16/10;order:-1} }

/* ===== homepage: order online band + daily promos ===== */
.order-band{background:var(--cream);border-bottom:1px solid var(--line)}
.order-btns{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;margin-bottom:38px}
.promos{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px;max-width:820px;margin:0 auto}
/* Promo cards read as an OFFER, not a price table (improvement #4).
   A torn-ticket notch on each side plus a dashed rule under the price is the
   visual language of a coupon — it costs nothing, needs no new artwork, and it
   is the difference between "here are three numbers" and "here is a deal". */
.promo{position:relative;background:var(--paper);border:1px solid var(--line);border-radius:18px;padding:30px 20px 26px;text-align:center;box-shadow:var(--shadow);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;overflow:hidden;transition:transform .25s ease,box-shadow .25s ease}
.promo:hover{transform:translateY(-3px);box-shadow:0 14px 30px rgba(0,0,0,.16)}
/* Ticket notches were tried here and removed: rendered at card edges they read
   as stray floating dots — worst of all in the gap between two adjacent cards —
   rather than as a punched ticket. The DAILY pill and the dashed rule under the
   price already do the coupon job without the artefact. */
.promo .promo-price{position:relative;padding-bottom:10px}
.promo .promo-price::after{content:"";position:absolute;left:22%;right:22%;bottom:0;border-bottom:2px dashed rgba(0,0,0,.16)}
.promo-flag{display:inline-block;font-family:'Anton',sans-serif;text-transform:uppercase;letter-spacing:.08em;font-size:.66rem;color:#fff;background:var(--red);padding:4px 12px;border-radius:999px;margin-bottom:10px}
.promo .promo-price{font-family:'Anton',sans-serif;font-size:clamp(2.2rem,5vw,3rem);color:var(--red);line-height:1}
.promo .promo-label{font-weight:700;text-transform:uppercase;letter-spacing:.06em;font-size:.86rem;color:var(--ink)}
.promo.promo-tag{background:var(--ink);border-color:var(--ink)}
.promo.promo-tag .promo-flag{background:#fff;color:var(--ink)}
.promo.promo-tag span{font-family:'Anton',sans-serif;text-transform:uppercase;color:#fff;font-size:clamp(1.4rem,3.4vw,1.9rem);line-height:1.05;letter-spacing:.02em}
.promo.promo-tag span:last-child{color:var(--red)}
@media(max-width:640px){ .promos{grid-template-columns:1fr;max-width:420px} .order-btns .btn{flex:1;justify-content:center} }

/* ===== homepage: we are hiring band ===== */
.hiring{background:var(--paper)}
.hiring .split{display:grid;grid-template-columns:1fr 1.05fr;gap:clamp(30px,6vw,72px);align-items:center}
.hiring img{border-radius:20px;box-shadow:var(--shadow);aspect-ratio:3/2;object-fit:cover;width:100%}
.hiring h2{font-size:clamp(2.1rem,5vw,3.4rem);margin:.3em 0 .5em}
.hiring p{color:#4b4540;font-size:1.08rem;margin-bottom:22px;max-width:48ch}
@media(max-width:900px){ .hiring .split{grid-template-columns:1fr} .hiring img{order:-1} }

/* ===== footer socials ===== */
.socials{display:flex;gap:12px;margin-top:20px}
.socials a{width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.08);border:1px solid rgba(255,255,255,.14);display:flex;align-items:center;justify-content:center;transition:background .2s ease,transform .2s ease}
.socials a:hover{background:var(--red);border-color:var(--red);transform:translateY(-2px)}
.socials svg{width:19px;height:19px;fill:#fff}

/* menu hero — 4-cutout foursome level with the title */
.menuhero-inner{position:relative;z-index:2;display:flex;align-items:flex-start;justify-content:space-between;gap:clamp(24px,5vw,60px)}
.menuhero-foursome{margin-top:-22px}
.menuhero-text{flex:1 1 auto;max-width:56%}
.menuhero-foursome{flex:0 0 auto;width:min(58%,660px);filter:drop-shadow(0 16px 26px rgba(0,0,0,.45))}
@media(max-width:900px){
  .menuhero-inner{flex-direction:column;align-items:flex-start}
  .menuhero-text{max-width:100%}
  .menuhero-foursome{width:min(92%,520px);margin:24px auto 0;filter:drop-shadow(0 10px 18px rgba(0,0,0,.35))}
  .menuhero{padding-bottom:40px}
}

/* ---- Jul 20 2026 audit batch ---- */
/* failsafe: if site.js never ran (load error), force content visible */
html.no-js .reveal, html.nojs-reveal .reveal{opacity:1;transform:none}
/* catering builder page: the generic Order Online bar hid the .cbar total on
   mobile (z 60 vs 55) — the builder's own bar owns the bottom there */
body.page-cbar .mobile-order{display:none!important}
/* menu rows without a real photo read as clean text rows, no placeholder tile */
.menu-item.no-photo{padding-left:20px}
/* footer phone lines */
.foot-phones{margin-top:10px;color:rgba(255,255,255,.6);font-size:.92rem;line-height:1.7}
.foot-phones a{color:rgba(255,255,255,.85)}
.foot-phones a:hover{color:#fff}
/* catering page minimum note */
.cat-note{margin-top:14px;padding:12px 16px;background:#fff;border-left:4px solid var(--red);border-radius:8px;font-size:.98rem}
/* page-hero eyebrow legibility over photos */
.pagehero .eyebrow,.hero .eyebrow{text-shadow:0 1px 10px rgba(0,0,0,.6)}
/* careers résumé picker styled like the rest of the form */
input[type=file]::file-selector-button{font:inherit;font-weight:700;background:var(--ink,#141110);color:#fff;border:0;border-radius:8px;padding:.6em 1.1em;margin-right:12px;cursor:pointer}
input[type=file]::file-selector-button:hover{background:var(--red)}

/* ---- Accessibility (ADA lawsuit remediation, Aug 7 2026) -----------------
   Keyed to "Nexx Burger - ADA Improvements and Violations Explanation".
   .sr-only carries the spoken-only text (item 8, full day names). The skip
   link answers items 3/4 (a banner that trapped the start of the tab order).
   :focus-visible replaces the outlines the design suppresses (WCAG 2.4.7). */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
.skip-link{position:absolute;left:-9999px;top:0;z-index:200;background:var(--red);
  color:#fff;padding:12px 20px;font-weight:700;border-radius:0 0 8px 0;text-decoration:none}
.skip-link:focus{left:0}
/* tabindex="-1" on <main> is what makes the skip link actually MOVE focus
   rather than only scroll (SC 2.4.1). No ring on it: a 3px outline drawn around
   the entire page body is noise, and <main> is not a control. */
main[tabindex]:focus,main[tabindex]:focus-visible{outline:none}
:focus-visible{outline:3px solid var(--red);outline-offset:3px}
header :focus-visible,footer :focus-visible,.hero :focus-visible{outline-color:#fff}
/* A red ring on the red catering band was ~1.2:1 — invisible, which is the same
   as having no focus indicator at all (SC 2.4.7 / 1.4.11). Same reasoning for
   the dark ink panels, where white simply reads better than 3.3:1 red. */
.catering :focus-visible,.story :focus-visible,.corder-intro :focus-visible,
.mobile-order :focus-visible,.cbar :focus-visible{outline-color:#fff}
/* Two places where an OUTSET ring cannot be seen in full, so it is drawn inset
   instead (SC 2.4.7): the map tile fills its card and .loc-full clips at the
   rounded corner, and the skip link sits flush against the top of the viewport.
   White, because both sit on dark panels where the red ring would vanish. */
.loc-map:focus-visible,.skip-link:focus-visible{outline:3px solid #fff;outline-offset:-6px}
.cform input:focus-visible,.cform select:focus-visible,.cform textarea:focus-visible{
  outline:3px solid var(--red);outline-offset:2px}
.field-hint{display:block;font-size:.78rem;color:var(--muted);font-weight:400;margin-top:2px}
/* The visible panel is VISUAL ONLY. Announcing is #form-live's job -- a
   permanently-rendered sr-only region just inside <main> that survives the form
   being replaced by the thank-you panel. This one used to carry role=status
   itself and sat inside the <form>, so .cf-hide took it out of the
   accessibility tree at exactly the moment it had good news to deliver.
   p.form-status, not .form-status: `.narrow p` would otherwise win on
   specificity and repaint the error panel as body copy. */
p.form-status:empty{border:0;padding:0;margin:0;background:none}
p.form-status{display:block;background:#fff4f4;border:2px solid var(--red);border-radius:8px;
  padding:12px 16px;margin-bottom:14px;font-size:.9rem;font-weight:600;color:#8b0000}
p.form-status.ok{background:#f1fbf4;border-color:var(--green);color:#0f5c30}
[aria-invalid="true"]{border-color:var(--red)!important;box-shadow:0 0 0 3px rgba(200,32,42,.14)}

/* SC 2.3.3 — nothing on this site honoured the preference. Everything that
   moves on its own or moves on interaction is covered here; the hero video and
   the Fan Favorites rotator are stopped in JS, which reads the same query. */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    transition-duration:.001ms!important;transition-delay:0ms!important;
    scroll-behavior:auto!important}
  .reveal{opacity:1!important;transform:none!important}
  .card:hover img{transform:none}
  .btn:hover,.promo:hover,.loc:hover,.loc-full:hover,.socials a:hover{transform:none}
}
