/* ==========================================================================
   Alpha Cafe — pink, white, light blue. Simple and modern.

   Positioning: a modern, broad-appeal cafe. At the owner's request the site
   does not lead with Desi or Muslim identity — "Desi" and "Eid" are out of
   visible copy and meta, and halal is mentioned exactly once, as an FAQ answer
   on the homepage using the client's own sourcing wording (no badge, no mark).
   The food itself is unchanged: dish names come live from
   WooCommerce and are not to be reworded. Motifs (ajrakh, khatim, cusped
   arch, truck-art chevron) were retired earlier; don't reintroduce them.

   2026-09-28, at the owner's request: solid #FFFFFF everywhere (no off-white,
   no tinted bands) and ONE typeface. The display serif was removed — it had
   been reviewed and deliberately kept on 2026-09-11, and the owner has now
   asked for it to go, which supersedes that. Every font-family uses --font.
   Type: Karla only   ·   Ground: #FFFFFF only
   ========================================================================== */

/* --- Tokens --------------------------------------------------------------- */
:root {
  /* light grounds — 3 steps. Never had a maroon cast, left as-is. */
  /* Solid white. All three light steps and both sky steps collapse to
     #FFFFFF, so the bands no longer differ by ground: they are separated by
     their hairline borders and by the type instead. The role names are kept
     because ~640 lines reference them. */
  --paper:      #FFFFFF;   /* cards, nav, inputs */
  --ground:     #FFFFFF;   /* page ground */
  --ground-2:   #FFFFFF;   /* was the blush band */

  /* light blue — the third colour. Replaces the old maroon punctuation band;
     used as a ground (never as text — see --blue below for the text-safe tone). */
  --sky:        #FFFFFF;
  --sky-2:      #FFFFFF;

  /* primary — rose, from the logo, the colour of rooh afza and falooda */
  --rose:       #D2325F;   /* display + button fills only (4.48:1 on ground) */
  --rose-dim:   #B02650;   /* body-size text on light (6.03:1) */

  /* secondary */
  --pista:      #436A3C;   /* pistachio — the garnish green (6.11:1 on --paper) */
  --blue:       #1B5C80;   /* text-safe blue — clears every ground incl. the deeper --sky-2 (5.28:1) */
  --blue-soft:  #A8D3EA;   /* DECORATIVE only — fails AA as text on every light ground */

  /* status — colour AND wording, never hue alone.
     All three clear 4.5:1 on every ground incl. the deepest (--sky-2, --ground-2),
     so a status can be dropped onto any band without rechecking. */
  --open:       #286B44;
  --soon:       #85560F;
  --shut:       #735A63;

  /* text on light — neutral slate, no maroon cast. Darkened in step with the
     deeper grounds below: --ink-soft on --sky-2 is 5.53:1, up from 4.64:1. */
  --ink:        #16232C;
  --ink-soft:   #455661;

  /* lines */
  --line:       #EBCCD2;
  --line-sky:   #AECFE3;   /* hairline on the --sky / --sky-2 bands */

  /* Was a cusped Mughal arch; retired for a plain rounded rectangle at the
     client's request — no Desi motifs, simple and modern. */
  /* One typeface sitewide. Every font-family in this file points here, so
     changing the pairing again is a one-line edit. Weights in use: 400, 500,
     700, plus italic 400/700 for .script and .quote__text — the Google Fonts
     link in src/partials/head.html must keep serving all of them. */
  --font: "Karla", system-ui, -apple-system, sans-serif;

  --arch:    20px;
  --arch-sm: 14px;

  /* sticky chrome — single source of truth */
  --nav-h: 136px;
  --catnav-h: 57px;
  /* Sticky mobile nav (spec v1.0). 0 above 760px, where the bar is hidden and
     body needs no bottom padding. Redefined inside the breakpoint below. */
  --snav-h: 0px;
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
/* Form controls do not inherit the page face in any browser by default. */
button, input, select, textarea { font-family: inherit; }
html { background: #FFFFFF; scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: #FFFFFF;
  color: var(--ink);
  font-family: var(--font);
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
h1, h2, h3, h4 { margin: 0; font-family: var(--font); font-weight: 700; line-height: 1.15; text-wrap: balance; }
p { margin: 0; }

/* Invariant 03 — every jump target clears the sticky chrome, not just menu
   categories. #inquire (the target of catering's primary CTA) was landing with
   its first ~40px behind the nav. Declared here, early, so the .menu-cat rule
   further down can override it with the extra category-bar offset. */
[id] { scroll-margin-top: calc(var(--nav-h) + 20px); }
a { color: var(--rose-dim); text-decoration: none; transition: color .18s ease; }
a:hover { color: var(--ink); }

/* --- Focus + skip --------------------------------------------------------- */
:focus-visible { outline: 2px solid var(--rose); outline-offset: 3px; border-radius: 3px; }

.skip {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--rose); color: var(--paper);
  font-weight: 700; font-size: 15px; padding: 13px 22px; border-radius: 3px;
  transition: top .18s ease;
}
.skip:focus { top: 12px; color: var(--paper); }

/* --- Layout --------------------------------------------------------------- */
.container { max-width: 1320px; margin: 0 auto; padding: 0 40px; }
.section { padding: 48px 0; position: relative; }
.section--tight { padding: 36px 0; }

/* All four band classes are the same white now. They are kept as distinct
   classes because all six page sources use them and because they still carry
   the per-band text-colour rules below; only the grounds were flattened. */
.section--cream   { background: #FFFFFF; }
.section--cream-2 { background: #FFFFFF; }
.section--night-2 { background: #FFFFFF; }
.section--night, .section--deep {
  background: #FFFFFF; color: var(--ink);
}
.section--night h1, .section--night h2, .section--night h3 { color: var(--ink); }
.section--night p  { color: var(--ink-soft); }
.section--night-2 h1, .section--night-2 h2, .section--night-2 h3 { color: var(--ink); }
.section--night-2 p { color: var(--ink-soft); }

/* --- Type ----------------------------------------------------------------- */
.eyebrow {
  font-family: var(--font); font-weight: 700; font-size: 12px;
  letter-spacing: .2em; text-transform: uppercase; color: var(--rose-dim);
}
.section--night .eyebrow { color: var(--blue); }
/* Scale pushed ~15% with tighter tracking — the impact in this direction comes
   from type size and contrast, not from new hues. */
.h-hero { font-size: clamp(50px, 7.6vw, 92px); letter-spacing: -.028em; }
.h-page { font-size: clamp(39px, 5.5vw, 64px); letter-spacing: -.022em; }
.h-sec  { font-size: clamp(32px, 3.9vw, 48px); letter-spacing: -.018em; }
.h-card { font-size: 25px; letter-spacing: -.012em; }
.lede { font-size: 20px; line-height: 1.6; color: var(--ink-soft); max-width: 54ch; }
.section--night .lede { color: var(--ink-soft); }
.script { font-family: var(--font); font-style: italic; font-weight: 700; color: var(--rose-dim); }

/* --- Buttons -------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  font-family: var(--font); font-weight: 700; font-size: 15px;
  letter-spacing: .03em; padding: 15px 30px; border-radius: 999px;
  min-height: 44px;                              /* hit-target floor; a no-op on desktop,
                                                    where padding alone already gives ~50px */
  border: 1.5px solid transparent; cursor: pointer; white-space: nowrap;
  transition: background .2s ease, color .2s ease, border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.btn:hover { transform: translateY(-1px); }
.btn--gold {                                   /* primary — rose fill */
  background: var(--rose); color: var(--paper);
  box-shadow: 0 6px 18px rgba(210,50,95,.22);
}
.btn--gold:hover { background: var(--ink); color: var(--paper); box-shadow: 0 8px 22px rgba(31,46,56,.26); }
.btn--ink { background: var(--ink); color: var(--paper); }
.btn--ink:hover { background: var(--rose); color: var(--paper); }
.btn--ghost, .btn--ghost-light { border-color: var(--rose-dim); color: var(--rose-dim); background: transparent; }
.btn--ghost:hover, .btn--ghost-light:hover { background: var(--rose-dim); color: var(--paper); }

.btn[disabled] { opacity: .45; cursor: not-allowed; }
.btn[disabled]:hover { transform: none; background: var(--rose); color: var(--paper); }

.tag {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  padding: 7px 15px; border-radius: 999px;
  border: 1px solid var(--line); background: var(--paper); color: var(--rose-dim);
}
.section--night .tag { border-color: rgba(32,104,143,.35); background: transparent; color: var(--blue); }

/* --- Arch + placeholders -------------------------------------------------- */
.arch { border-radius: var(--arch); overflow: hidden; }
.arch--sm { border-radius: var(--arch-sm); overflow: hidden; }

.ph {
  position: relative; width: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: #FFFFFF;
  border: 1.5px dashed rgba(176,38,80,.32);
  color: rgba(176,38,80,.6); text-align: center;
  transition: border-color .22s ease, transform .22s ease;
}
.ph__label {
  font-family: var(--font); font-style: italic; font-size: 14px;
  color: rgba(122,85,102,.9); padding: 0 24px; line-height: 1.5;
}
.ph--light { background: #FFFFFF; }

/* --- Status --------------------------------------------------------------- */
.status { display: inline-flex; align-items: center; gap: 8px; }
.status__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--shut); flex: none; }
.status--open .status__dot { background: var(--open); }
.status--soon .status__dot { background: var(--soon); }
.status__text { color: var(--ink-soft); }
.status--open .status__text { color: var(--open); font-weight: 700; }
.status--soon .status__text { color: var(--soon); font-weight: 700; }
.status--badge {
  background: var(--paper); border: 1px solid var(--line);
  padding: 11px 18px; border-radius: 999px; font-size: 14.5px;
  box-shadow: 0 10px 26px rgba(31,46,56,.12);
}

/* --- Nav -------------------------------------------------------------------
   Logo left, everything else (phone / Order Now / menu toggle) grouped on the
   right. The logo is a normal flex child now, not absolutely positioned — the
   bar simply grows to fit it, so there is no overhang math to maintain and no
   collision risk at any width. If you resize the logo, update --nav-h (and,
   at each breakpoint that resizes it again, that breakpoint's --nav-h) to
   padding-top + logo-height + padding-bottom; catnav-h does not depend on it. */
.nav {
  position: sticky; top: 0; z-index: 50;
  background: #FFFFFF; backdrop-filter: blur(8px);
}
.nav__in {
  max-width: 1240px; margin: 0 auto; padding: 14px 40px;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
}

/* Bare mark, no circle. It uses logo-mark-nav.png (236×156) rather than
   logo-coin.png, which was the same artwork padded into a square purely so a
   circular mask couldn't clip it — roughly 40% of the coin's height was empty.
   Dropping the circle therefore makes the mark much larger at the SAME nav
   height: the old coin rendered ~84×55, this renders ~163×108.
   The height below is the whole logo box, so --nav-h stays 14 + height + 14. */
.nav__logo {
  flex: none; display: inline-flex; align-items: center;
  transition: transform .2s ease, opacity .2s ease;
}
.nav__logo img { height: 108px; width: auto; }
.nav__logo:hover { transform: translateY(-2px); opacity: .88; }

.nav__end { display: flex; align-items: center; justify-content: flex-end; gap: 12px; }

/* The nav CTA is smaller than the page-body .btn: at 15px/30px padding it
   stands 53px tall, more than the controls either side of it need. */
.nav__end .btn { padding: 11px 22px; font-size: 14px; }

.nav__call, .nav__toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; flex: none;
  border: 1.5px solid var(--line); border-radius: 999px; background: none; cursor: pointer;
}
.nav__toggle { color: var(--ink); }
.nav__call { color: var(--rose-dim); }
.nav__call:hover, .nav__toggle:hover { border-color: var(--rose); color: var(--rose-dim); }
.nav__toggle .icon-close { display: none; }
.nav__toggle[aria-expanded="true"] .icon-open { display: none; }
.nav__toggle[aria-expanded="true"] .icon-close { display: block; }
.nav__toggle[aria-expanded="true"] { border-color: var(--rose); color: var(--rose-dim); }

/* Drawer — the only place nav links live now, at every width */
.nav__panel { display: none; }
.nav__panel.is-open {
  display: flex; flex-direction: column; align-items: stretch; gap: 2px;
  position: absolute; left: 0; right: 0; top: 100%;
  background: var(--paper); border-bottom: 1px solid var(--line);
  padding: 18px 40px 24px; box-shadow: 0 18px 40px -22px rgba(31,46,56,.4);
}
.nav__panel a {
  position: relative; color: var(--ink); font-weight: 600; font-size: 18px;
  padding: 13px 0; border-bottom: 1px solid var(--line);
}
.nav__panel a:hover, .nav__panel a.is-active, .nav__panel a:focus-visible { color: var(--rose-dim); }
.nav__panel a.is-active { color: var(--rose-dim); }
.nav__panel a.is-active::before {
  content: ""; position: absolute; left: -14px; top: 50%; width: 5px; height: 5px;
  margin-top: -2.5px; border-radius: 50%; background: var(--rose);
}
.nav__panel__state {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  padding-bottom: 16px; margin-bottom: 6px; border-bottom: 1px solid var(--line);
}

/* --- Reach: the Call / Text disclosure ------------------------------------
   The header phone control and the homepage hero's "Call or Text Store" are no
   longer direct tel: links — each opens a two-item menu (Call, Text) on the
   chain number 832-643-3499. Owner's request, 2026-09-28.

   Built on native <details>/<summary>, so it opens, takes focus and reports
   its state with no JS. js/main.js only adds the three dismissals a native
   <details> does not do for you: outside click, Escape, and closing any other
   open one (see the reach block there).

   IMPORTANT: neither link carries [data-loc-tel]. These two deliberately stay
   on the chain number whatever branch is selected. Every OTHER phone on the
   site — location cards, location pages, the footer — is still per-branch and
   still rewritten by setLocation(). Don't "fix" this by wiring them up. */
.reach { position: relative; flex: none; }
.reach > summary { list-style: none; cursor: pointer; }
.reach > summary::-webkit-details-marker { display: none; }   /* Safari */
.reach > summary::marker { content: ""; }
.reach__menu {
  position: absolute; z-index: 60; top: calc(100% + 8px); right: 0;
  min-width: 170px; padding: 6px;
  display: flex; flex-direction: column;
  background: #FFFFFF; border: 1px solid var(--line); border-radius: 14px;
  box-shadow: 0 18px 40px -18px rgba(31,46,56,.42);
}
/* Opens upward. The hero clips its own overflow (it has to, to hide the
   off-screen slideshow layers), so a menu dropping DOWN from the quick row —
   the last thing in the hero — would be cut off. Upward it overlays the
   buttons above it, which are inside the hero. */
.reach--up .reach__menu { top: auto; bottom: calc(100% + 8px); }
.reach__link {
  display: flex; align-items: center; gap: 10px;
  min-height: 44px; padding: 8px 14px; border-radius: 10px;
  font-weight: 700; font-size: 15px; color: var(--ink); white-space: nowrap;
}
.reach__link svg { color: var(--rose-dim); flex: none; }
.reach__link:hover, .reach__link:focus-visible {
  background: rgba(210,50,95,.08); color: var(--rose-dim);
}

/* --- Hero -------------------------------------------------------------------
   Shared page-header pattern: .hero/.hero__in/.hero__copy/.hero__lede/
   .hero__actions/.hero__media are used on FIVE other pages (contact,
   locations, story, catering, menu), not just the homepage. Never delete or
   repurpose these — that broke all five once already. Homepage-only overrides
   go under .hero--full, additively, below. */
.hero { position: relative; background: #FFFFFF; overflow: hidden; padding: 56px 0 48px; }
/* The tinted radial wash went with the off-white grounds — the owner asked for
   a solid white page, and a rose/teal bloom is not that. */
.hero::before { content: none; }
.hero__in {
  position: relative; z-index: 1; max-width: 1240px; margin: 0 auto; padding: 0 40px;
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 70px; align-items: center;
}
.hero__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 24px; }
.hero__tags { display: flex; gap: 10px; flex-wrap: wrap; }
.hero h1 { color: var(--ink); }
.hero__lede { font-size: 19.5px; line-height: 1.65; color: var(--ink-soft); max-width: 48ch; }
.hero__actions { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.hero__media { position: relative; }
.hero__media .ph, .hero__media img { aspect-ratio: 4/5; object-fit: cover; }
.hero__stamp { position: absolute; left: -26px; bottom: 34px; }

/* --- Homepage-only: full-bleed editorial hero -------------------------------
   One continuous photo fills the whole section; text sits blended into a
   dark gradient rather than a separate card floating on top of it. Every
   rule here is scoped under .hero--full so the shared pattern above is
   untouched for the other five pages. */
.hero--full {
  overflow: hidden;
  min-height: clamp(560px, 76vh, 760px);
  padding: 0;
  display: flex; align-items: flex-end;
}
.hero--full::before { content: none; }   /* fully covered by the photo — the wash would be invisible */
.hero__bg { position: absolute; inset: 0; z-index: 0; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  /* Measured the eyebrow's actual position across viewports rather than
     eyeballing it: 63% up from the bottom at 1440px, 68% at 1024px, and it
     settles at 80% from ~900px down through 320px (the headline wraps to
     its max lines and stays there). Kept .72+ dark through 80% with margin;
     only the empty top ~15%, which never holds text, fades to clear. */
  background: linear-gradient(0deg,
    rgba(31,46,56,.9) 0%, rgba(31,46,56,.85) 50%,
    rgba(31,46,56,.72) 80%, rgba(31,46,56,0) 97%);
}
.hero--full .hero__in {
  z-index: 2; width: 100%; padding: 0 40px 56px;
  display: flex; grid-template-columns: none; align-items: flex-end; justify-content: space-between; gap: 32px;
}
.hero--full .hero__copy { gap: 18px; max-width: 600px; }
.hero--full .h-hero--onphoto { color: var(--paper); }   /* beats .hero h1's higher specificity */
.hero--full .hero__actions { gap: 22px; }
.hero__link {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--paper); font-weight: 700; font-size: 15px;
  padding-bottom: 3px; border-bottom: 1.5px solid rgba(255,252,251,.5);
  transition: border-color .2s ease, gap .2s ease;
}
/* Vertical-only expansion: the underline must stay tight to the text, and
   widening would reach into the Order Now button 22px to its left. */
.hero__link { position: relative; }
.hero__link::after { content: ""; position: absolute; inset: -8px 0; }
.hero__link:hover, .hero__link:focus-visible { border-color: var(--paper); gap: 9px; }
.hero__meta { color: rgba(255,252,251,.8); }
.status--onphoto .status__dot { background: #C9CDD2; }
.status--onphoto.status--open .status__dot { background: #7FE0AC; }
.status--onphoto.status--soon .status__dot { background: #F4C67A; }
.status--onphoto .status__text { color: rgba(255,252,251,.88); }
.status--onphoto.status--open .status__text { color: #7FE0AC; }
.status--onphoto.status--soon .status__text { color: #F4C67A; }
/* .locpick's base rule (color: var(--rose-dim)) lives later in this file
   than these onphoto overrides, so at equal specificity it would win the
   cascade tie -- scope under .hero--full for a guaranteed-higher specificity
   instead of depending on file position (the same mistake bit .h-hero above). */
.hero--full .locpick--onphoto,
.hero--full .locpick--onphoto span { color: var(--paper); }
.hero--full .locpick--onphoto:hover,
.hero--full .locpick--onphoto:focus-visible { color: #fff; }
.hero--full .locpick--onphoto .locpick__change { color: rgba(255,252,251,.75); }

.hero__controls { display: flex; align-items: center; gap: 16px; flex: none; padding-bottom: 4px; }

/* --- Hero sliding window (homepage only) ------------------------------------
   Flat and minimal: one photo at a time, sliding straight across the full
   frame. No tilt, no perspective, no library — a single translateX
   transition per slide. */
.hs, .hs__stage { position: absolute; inset: 0; }
.hs__slide {
  margin: 0; position: absolute; inset: 0;
  transition: transform .6s cubic-bezier(.22,.7,.3,1);
  transform: translateX(100%);
}
.hs__slide.is-active { transform: translateX(0); z-index: 1; }
.hs__slide.is-prev { transform: translateX(-100%); }
.hs__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

.hs__nav {
  width: 44px; height: 44px; border-radius: 999px; cursor: pointer; flex: none;
  display: grid; place-items: center;
  background: transparent; border: 1.5px solid rgba(255,252,251,.5); color: var(--paper);
  transition: background .2s ease, border-color .2s ease;
}
.hs__nav:hover, .hs__nav:focus-visible { background: rgba(255,252,251,.15); border-color: var(--paper); }

/* Gap is 18px, not 7px, so the expanded hit areas below sit edge to edge
   instead of overlapping — two dots that both claim the same pixel make the
   wrong slide appear on a thumb tap. */
.hs__dots { display: flex; gap: 18px; }
.hs__dot {
  position: relative;
  width: 7px; height: 7px; border-radius: 999px; cursor: pointer; padding: 0;
  border: 1.5px solid rgba(255,252,251,.6); background: none;
}
/* The dot reads as 7px but answers to a 25x43 tap. Expanding with a
   pseudo-element keeps the visual rhythm of the control row unchanged. */
.hs__dot::after { content: ""; position: absolute; inset: -18px -9px; }
.hs__dot[aria-selected="true"] { background: var(--paper); border-color: var(--paper); }

@media (prefers-reduced-motion: reduce) {
  .hs__slide { transition: none; }
}

/* --- Ticker --------------------------------------------------------------- */
/* White ground like everything else, so the type has to carry it: --ink on
   #FFF is 15.3:1. It was a rose band with white text — on white that wording
   would have been invisible. */
.ticker {
  background: #FFFFFF; color: var(--ink);
  padding: 14px 0; overflow: hidden;
}
.ticker__track { display: flex; align-items: center; gap: 26px; width: max-content; animation: slide 46s linear infinite; }
.ticker__item { font-family: var(--font); font-size: 19px; font-weight: 700; white-space: nowrap; }
.ticker__dot { width: 7px; height: 7px; background: var(--ink); transform: rotate(45deg); flex: none; opacity: .8; }
@keyframes slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* --- Split ---------------------------------------------------------------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 72px; align-items: center; }
.split--rev .split__media { order: 2; }
.split__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
.split__media .ph, .split__media img { aspect-ratio: 4/5; object-fit: cover; }
.split__media--wide .ph, .split__media--wide img { aspect-ratio: 5/4; }

/* FAQ — native <details>/<summary>, so it opens, takes focus and reports its
   state without a line of JS. Don't rebuild this as a scripted accordion. */
.faq { max-width: 860px; margin: 0 auto; border-top: 1px solid var(--line); }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding: 24px 0; cursor: pointer; list-style: none;
  font-family: var(--font); font-weight: 700;
  font-size: 20px; line-height: 1.3; color: var(--ink);
  transition: color .18s ease;
}
.faq__q::-webkit-details-marker { display: none; }   /* Safari's default triangle */
.faq__q:hover { color: var(--rose-dim); }
.faq__q::after {
  content: "+"; flex: none; font-family: var(--font); font-weight: 400;
  font-size: 26px; line-height: 1; color: var(--rose-dim);
  transition: transform .2s ease;
}
.faq__item[open] .faq__q::after { content: "\2013"; }   /* en dash */
.faq__a { padding: 0 0 26px; max-width: 68ch; color: var(--ink-soft); line-height: 1.7; }

/* About page — real counts from data/menu.json instead of adjectives. If the
   menu data changes materially, update the numbers in src/pages/story.html. */
.stats {
  display: grid; grid-template-columns: repeat(4, minmax(0,1fr));
  gap: 26px; margin-top: 36px;
}
.stat { display: flex; flex-direction: column; gap: 8px; padding-left: 18px; border-left: 2px solid var(--rose); }
.stat__num {
  font-family: var(--font); font-weight: 700; line-height: 1;
  font-size: clamp(32px, 3.6vw, 44px); letter-spacing: -.02em; color: var(--ink);
}
.stat__label { font-size: 14.5px; line-height: 1.5; color: var(--ink-soft); }

/* "What we bring" on catering. Was built from inline styles with a hardcoded
   font stack and a fixed 18px, so it sat out the type-scale change and had
   drifted smaller than comparable text. .spread__name is an h3, so it inherits
   its face from the global heading rule rather than restating it. */
.spread { display: flex; flex-direction: column; gap: 18px; width: 100%; margin: 6px 0 0; padding: 0; list-style: none; }
.spread__item { display: flex; gap: 14px; align-items: flex-start; }
.spread__item > .divider__mark { margin-top: 9px; flex: none; }
.spread__name { font-size: 20px; letter-spacing: -.01em; color: var(--ink); }
.spread__desc { font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); margin-top: 2px; }

/* --- Grids ---------------------------------------------------------------- */
.grid-4 { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 26px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: 26px; }
.grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 26px; }

.offer { display: flex; flex-direction: column; gap: 14px; text-align: center; align-items: center; }
.offer .ph, .offer img.ph { aspect-ratio: 3/4; }

/* .offers — the homepage Justspresso row ONLY. Square, capped and centred, so
   four drink photos don't run the full container width. Scoped to this class
   rather than .grid-4 because the About page uses .grid-4 for portrait 3/4
   photography that must keep its own crop. */
.grid-4.offers { grid-template-columns: repeat(4, minmax(0, 210px)); justify-content: center; }
.offers .offer .ph, .offers .offer img.ph {
  aspect-ratio: 1/1; object-fit: cover; object-position: center;
}
.offer__name {
  font-family: var(--font); font-size: 20px; font-weight: 700; color: var(--ink);
  display: inline-flex; align-items: center; gap: 7px; transition: color .2s ease;
}
.offer__desc { font-size: 14.5px; line-height: 1.55; color: var(--ink-soft); max-width: 26ch; }
.offer__go { opacity: 0; transform: translateX(-4px); transition: opacity .2s ease, transform .2s ease; flex: none; }
a.offer:hover .ph, a.offer:focus-visible .ph { border-color: var(--rose); transform: translateY(-5px); }
a.offer:hover img, a.offer:focus-visible img { transform: translateY(-5px); }
a.offer img { transition: transform .22s ease; }
a.offer:hover .offer__name, a.offer:focus-visible .offer__name { color: var(--rose-dim); }
a.offer:hover .offer__go, a.offer:focus-visible .offer__go { opacity: 1; transform: none; }

/* --- Popular items (conversion) ------------------------------------------- */
.pop { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 22px; }
.pop__card {
  display: flex; flex-direction: column; background: var(--paper);
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  transition: transform .2s ease, box-shadow .2s ease, border-color .2s ease;
}
.pop__card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px rgba(31,46,56,.10); border-color: var(--rose); }
.pop__img { width: 100%; aspect-ratio: 4/3; object-fit: cover; background: var(--ground-2); }
.pop__body { display: flex; flex-direction: column; gap: 6px; padding: 16px 18px 18px; flex: 1 1 auto; }
.pop__name { font-family: var(--font); font-size: 18px; font-weight: 700; color: var(--ink); line-height: 1.25; }
.pop__desc { font-size: 13.5px; line-height: 1.5; color: var(--ink-soft); flex: 1 1 auto; }

/* --- Section headers + divider -------------------------------------------- */
.sec-head { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 14px; margin-bottom: 32px; }
.sec-head--left { align-items: flex-start; text-align: left; }
.divider { display: flex; align-items: center; gap: 14px; justify-content: center; }
.divider__line { height: 1px; width: 56px; background: currentColor; opacity: .28; }
/* Was a khatim (Islamic 8-point star) via CSS mask; retired for a plain dot
   at the client's request — no Desi motifs, simple and modern. */
.divider__mark {
  width: 8px; height: 8px; flex: none; border-radius: 50%;
  background-color: var(--rose);
}

/* --- Menu ----------------------------------------------------------------- */
.catnav {
  position: sticky; top: var(--nav-h); z-index: 40;
  background: #FFFFFF; backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
.catnav__in {
  max-width: 1240px; margin: 0 auto; padding: 14px 40px;
  display: flex; gap: 28px; flex-wrap: wrap; align-items: center;
}
.catnav a {
  position: relative; font-size: 13.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--ink-soft); padding: 4px 0;
}
.catnav a::before { content: ""; position: absolute; inset: -7px 0; }
.catnav a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 2px;
  background: var(--rose); transform: scaleX(0); transition: transform .22s ease;
}
.catnav a:hover, .catnav a.is-current { color: var(--rose-dim); }
.catnav a:hover::after, .catnav a.is-current::after { transform: scaleX(1); }

.menu-cat {
  display: grid; grid-template-columns: 320px 1fr; gap: 52px; align-items: start;
  padding: 40px 0; border-bottom: 1px solid var(--line);
  /* menu page only — also has to clear the sticky category bar */
  scroll-margin-top: calc(var(--nav-h) + var(--catnav-h) + 20px);
}
.menu-cat:last-child { border-bottom: none; }
.menu-cat__aside { position: sticky; top: calc(var(--nav-h) + var(--catnav-h) + 24px); display: flex; flex-direction: column; gap: 16px; }
.menu-cat__aside .ph { aspect-ratio: 1/1; }
.menu-cat__title { display: flex; align-items: center; gap: 12px; }
.menu-cat__note { font-size: 14.5px; color: var(--ink-soft); line-height: 1.55; }

.menu-list { display: flex; flex-direction: column; }
.menu-item {
  display: flex; justify-content: space-between; align-items: center; gap: 18px;
  padding: 16px 0; border-bottom: 1px solid var(--line);
}
.menu-item:last-child { border-bottom: none; }
.menu-item__img {
  width: 88px; height: 88px; flex: none; border-radius: 10px; object-fit: cover;
  background: var(--ground-2); border: 1px solid var(--line);
}
.menu-item__body { flex: 1 1 auto; min-width: 0; }
.menu-item__name { font-family: var(--font); font-size: 18.5px; font-weight: 700; color: var(--ink); display: block; }
.menu-item__desc { font-size: 14.5px; color: var(--ink-soft); display: block; margin-top: 3px; }
.menu-item__flag {
  display: inline-block; margin-left: 9px; font-family: var(--font);
  font-size: 12px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--pista); border: 1px solid rgba(67,106,60,.45); border-radius: 999px; padding: 1px 9px;
  vertical-align: middle; white-space: nowrap;
}

/* --- Sheets --------------------------------------------------------------- */
.sheet {
  border: none; padding: 0; max-width: 460px; width: calc(100% - 32px);
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 30px 80px rgba(31,46,56,.28);
}
.sheet::backdrop { background: rgba(31,46,56,.5); }
.sheet__in { padding: 26px; display: flex; flex-direction: column; gap: 18px; }
.sheet__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.sheet__head h2 { font-size: 23px; color: var(--ink); }
.sheet__close {
  background: none; border: 1.5px solid var(--line); border-radius: 999px;
  width: 44px; height: 44px; flex: none; color: var(--ink-soft); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.sheet__close:hover { color: var(--rose-dim); border-color: var(--rose); }
/* Sits above the two options. --ink-soft on the sheet's --paper is 7.2:1. */
.sheet__note { font-size: 14px; line-height: 1.5; color: var(--ink-soft); }
.sheet__note em { font-style: normal; font-weight: 700; color: var(--ink); }
.sheet__opts { display: flex; flex-direction: column; gap: 10px; }
.sheet__foot { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; }
/* Last-second location change, inside the order sheet. --rose-dim on the
   sheet's --paper is 6.35:1. */
.sheet__change {
  display: inline-block; margin-top: 8px;
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: var(--font); font-size: 13.5px; font-weight: 700;
  color: var(--rose-dim); text-decoration: underline; text-underline-offset: 3px;
}
.sheet__change:hover { color: var(--ink); }

.opt {
  display: flex; align-items: center; gap: 14px; text-align: left; width: 100%;
  padding: 14px 18px; min-height: 60px; cursor: pointer;
  background: var(--ground); border: 1.5px solid var(--line); border-radius: 12px;
  color: var(--ink); font-family: var(--font);
  transition: border-color .18s ease, background .18s ease;
}
.opt:hover { border-color: var(--rose); background: var(--ground-2); color: var(--ink); }
.opt__icon { color: var(--rose-dim); flex: none; }
.opt__body { flex: 1 1 auto; display: flex; flex-direction: column; gap: 2px; }
.opt__name { font-weight: 700; font-size: 15.5px; }
.opt__meta { font-size: 13px; color: var(--ink-soft); }
.opt__go { color: var(--rose-dim); flex: none; }
/* Spec §3: each location in the picker shows its phone and whether it is open
   right now, alongside the name and address. */
.opt__meta--row { display: flex; align-items: center; flex-wrap: wrap; gap: 6px 14px; margin-top: 3px; }
.opt__meta--row .status { font-size: 13px; }
.opt__phone { font-size: 13px; font-weight: 700; color: var(--rose-dim); }

.opt--off { opacity: .5; cursor: not-allowed; }
.opt--off:hover { border-color: var(--line); background: var(--ground); }

/* --- Category cards (spec v1.0 §2.2 "Explore the Menu") ------------------- */
/* Two per row on mobile is the spec's explicit requirement, so this grid stays
   at 2 columns all the way down rather than collapsing to 1 like .grid-4. */
/* Capped and centred so the four category photos stay small squares rather
   than filling the container. Photo on top, text underneath — the text is
   NEVER laid over the photo (spec §2.2 asks for equal image sizes and a line
   or two of copy beneath). */
.cats { display: grid; grid-template-columns: repeat(4, minmax(0, 200px)); gap: 22px; justify-content: center; }
.cat {
  display: flex; flex-direction: column;
  background: var(--paper); border: 1px solid var(--line); border-radius: 16px;
  overflow: hidden; color: var(--ink);
  transition: border-color .2s ease, transform .2s ease, box-shadow .2s ease;
}
.cat:hover { border-color: var(--rose); transform: translateY(-3px); box-shadow: 0 14px 34px rgba(31,46,56,.12); color: var(--ink); }
/* Equal image sizes across all four cards — spec: "Use equal image sizes." */
.cat__img { display: block; aspect-ratio: 1/1; overflow: hidden; background: var(--ground-2); }
.cat__img img { width: 100%; height: 100%; object-fit: cover; }
.cat__body { display: flex; flex-direction: column; gap: 7px; padding: 18px 18px 20px; flex: 1 1 auto; }
.cat__name { font-family: var(--font); font-size: 20px; font-weight: 700; line-height: 1.2; }
.cat__desc { font-size: 14px; line-height: 1.55; color: var(--ink-soft); flex: 1 1 auto; }
.cat__go {
  display: block; margin-top: 4px;
  font-size: 13.5px; font-weight: 700; letter-spacing: .02em; color: var(--rose-dim);
}
.cat__go svg { vertical-align: -2px; margin-left: 7px; transition: margin-left .2s ease; }
.cat:hover .cat__go svg { margin-left: 11px; }

/* --- Ticked list (catering highlights, spec §2.6) ------------------------- */
.tick { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px 20px; }
.tick li { position: relative; padding-left: 22px; font-size: 15.5px; color: var(--ink-soft); }
.tick li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 9px; height: 9px; border-radius: 999px; background: var(--rose);
}

/* --- Sticky mobile navigation (spec v1.0 §"Website Navigation") ----------- */
/* Three actions: Order, Locations, Catering. Hidden at >=760px. An open
   <dialog> is in the browser's top layer, so the order sheet covers this
   without needing a z-index fight. */
.snav { display: none; }
.snav__item {
  flex: 1 1 0; min-height: 58px; cursor: pointer;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  background: none; border: none; padding: 8px 4px;
  font-family: var(--font); font-size: 12.5px; font-weight: 700;
  letter-spacing: .04em; color: var(--ink-soft);
}
.snav__item svg { color: var(--rose-dim); }
.snav__item:hover, .snav__item:focus-visible { color: var(--rose-dim); }

@media (max-width: 760px) {
  :root { --snav-h: 66px; }
  .snav {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 120;
    display: flex; align-items: stretch;
    background: #FFFFFF; backdrop-filter: blur(8px);
    border-top: 1px solid var(--line);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  /* Content must clear the bar, including the iOS home indicator. */
  body { padding-bottom: calc(var(--snav-h) + env(safe-area-inset-bottom, 0px)); }
  /* The cart-less order sheet and the location sheet sit in the top layer, but
     the floating tally bar (if reinstated) would not — keep it above the snav. */
}

/* --- Hero additions (spec §2.1) ------------------------------------------ */
/* The exact business name sits above the headline inside the same H1. */
.hero__brand {
  display: block; font-family: var(--font);
  font-size: 13px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  color: rgba(255,252,251,.82); margin-bottom: 12px;
}
.hero__lede--onphoto { color: rgba(255,252,251,.92); max-width: 44ch; }
.hero__quick { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; font-size: 14px; }
.hero__quick__a {
  display: inline-flex; align-items: center; gap: 7px; min-height: 44px;
  color: rgba(255,252,251,.92); font-weight: 700; font-size: 13.5px;
}
.hero__quick__a:hover, .hero__quick__a:focus-visible { color: var(--paper); }

/* --- Location card phone (spec §2.5 "Do not hide the phone number.") ----- */
.loc-card__tel { font-size: 15px; font-weight: 700; color: var(--rose-dim); display: inline-block; min-height: 30px; }

/* A plain row of buttons anywhere outside the hero. .hero__actions used to be
   borrowed for this, which meant hero-only rules leaked into page sections. */
.btn-row { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin-top: 4px; }

/* --- Hero on the photo: compactness + contrast (spec v1.0 §2.1) ---------- */
/* "Keep the hero compact" and "Primary buttons must be visible without
   scrolling." Two things were fighting that: the display face at 50px+ over
   three lines, and the supporting paragraph at the full 20px .lede size. */
.hero--full .h-hero { font-size: clamp(38px, 5.4vw, 74px); }
.hero--full .hero__copy { gap: 14px; }
.hero__lede--onphoto { font-size: 16.5px; line-height: 1.5; max-width: 40ch; }

/* .btn--ghost-light is rose-on-transparent, which is designed for the light
   grounds. Over a photo it fails the contrast floor badly, so the hero's
   secondary buttons get a white treatment instead. */
.hero--full .btn--ghost-light {
  border-color: rgba(255,252,251,.7); color: var(--paper); background: rgba(31,46,56,.22);
  backdrop-filter: blur(3px);
}
.hero--full .btn--ghost-light:hover,
.hero--full .btn--ghost-light:focus-visible {
  background: var(--paper); color: var(--ink); border-color: var(--paper);
}

@media (max-width: 560px) {
  /* Three primary buttons cannot sit on one row at phone width, so they are
     allowed to wrap — but tighter, so the whole hero still lands above the
     fold on a 667px screen. */
  .hero--full .hero__actions { gap: 10px; }
  .hero--full .hero__actions .btn { padding: 13px 18px; font-size: 14px; }
  .hero__lede--onphoto { font-size: 15.5px; }
  .hero--full .hero__in { gap: 12px; }
  .hero--full .hero__copy { gap: 12px; }
  .hero__quick { gap: 6px 14px; font-size: 13px; }
}

/* --- Location page map (spec v1.0 §"Local SEO") -------------------------- */
/* Google's keyless embed. Lazy-loaded: it sits well below the fold and is by
   far the heaviest thing on a location page. */
.locmap {
  width: 100%; aspect-ratio: 4/3; border: 1px solid var(--line);
  border-radius: var(--arch); display: block;
}

/* The card heading is a link to that branch's own page. It must not inherit the
   global link colour — the heading still has to read as a heading. */
.loc-card__top h3 a { color: inherit; }
.loc-card__top h3 a:hover, .loc-card__top h3 a:focus-visible { color: var(--rose-dim); }

/* --- Quote ---------------------------------------------------------------- */
.quote { max-width: 760px; margin: 0 auto; text-align: center; display: flex; flex-direction: column; gap: 20px; align-items: center; }
.quote__text { font-family: var(--font); font-size: clamp(23px, 3vw, 34px); font-style: italic; font-weight: 700; line-height: 1.4; color: var(--ink); }
.quote__by { font-size: 12.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--blue); }

/* --- Reviews carousel ------------------------------------------------------
   Same look as a single .quote block, just cycling. A plain crossfade, not
   the hero's 3D coverflow — this is a quiet, ambient section. */
.rev__track { position: relative; }
.rev__slide { display: none; }
.rev__slide.is-active { display: flex; }
.js .rev__slide.is-active { animation: revIn .5s ease both; }
@keyframes revIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Google rating, spec §2.7. Sits above the review carousel. --paper on the
   deep review band; the gold is only the stars, which are decorative. */
.rev__rating {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 6px 14px; margin-bottom: 22px;
}
.rev__rating[hidden] { display: none; }
/* Two stacked rows of the same five stars: a faint one, and a solid one
   clipped by width to the score. Only ★ is used, which every font has. */
.rev__stars { position: relative; display: inline-block; font-size: 19px; letter-spacing: 2px; line-height: 1; }
.rev__stars::before { content: "★★★★★"; color: rgba(31,46,56,.22); }
.rev__stars__on {
  position: absolute; left: 0; top: 0; overflow: hidden; white-space: nowrap;
  color: #E0A53B; width: 0;
}
.rev__stars__on::before { content: "★★★★★"; }
.rev__score { font-size: 17px; }
.rev__score strong { font-size: 21px; font-family: var(--font); }
.rev__count { font-size: 14px; opacity: .85; }

.rev__dots { display: flex; gap: 18px; justify-content: center; margin-top: 28px; }
.rev__dot {
  position: relative;
  width: 8px; height: 8px; border-radius: 999px; cursor: pointer; padding: 0;
  border: 1.5px solid var(--rose); background: none;
}
.rev__dot::after { content: ""; position: absolute; inset: -18px -9px; }   /* 26x44; gap 18 keeps them from overlapping */
.rev__dot[aria-selected="true"] { background: var(--rose); }
@media (prefers-reduced-motion: reduce) {
  .rev__slide { transition: none; }
  .js .rev__slide.is-active { animation: none; }
}

/* --- Info cards ----------------------------------------------------------- */
.info {
  display: flex; flex-direction: column; gap: 12px; padding: 30px;
  background: var(--paper); border: 1px solid var(--line); border-radius: 14px; align-items: flex-start;
}
.info--night { background: var(--sky); border-color: var(--line-sky); }
.info__icon { color: var(--rose-dim); }
.info--night .info__icon { color: var(--blue); }
.info h3 { font-size: 19px; }
.info--night h3 { color: var(--ink); }
.info p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); }
.info--night p { color: var(--ink-soft); }

/* --- Location ------------------------------------------------------------- */
.locpick {
  display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
  background: none; border: none; padding: 0; color: var(--rose-dim);
  font-family: var(--font); font-size: 12.5px; font-weight: 700; letter-spacing: .03em;
}
.locpick { min-height: 44px; }
.locpick:hover { color: var(--ink); }
.locpick svg { flex: none; }
.locpick__change { font-weight: 400; color: var(--ink-soft); text-decoration: underline; text-underline-offset: 2px; }

.loc-card {
  display: flex; flex-direction: column; gap: 12px; align-items: flex-start;
  padding: 28px; background: var(--paper); border: 1px solid var(--line); border-radius: 14px;
}
.loc-card.is-picked { border-color: var(--rose); box-shadow: 0 10px 28px rgba(210,50,95,.12); }

/* Offering "Use this location" on the location you are already using reads as
   a bug, so the active card swaps that button for a state label.

   Visibility is driven by the `hidden` ATTRIBUTE, not by a class, so a stale or
   missing stylesheet can't leak the pill onto every card — which is exactly
   what happened when new markup met a cached stylesheet. Anything that sets
   `display` needs its own [hidden] guard to beat that declaration.
   --rose-dim on --paper is 6.35:1. */
.loc-card__current {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: 12.5px; font-weight: 700; letter-spacing: .13em; text-transform: uppercase;
  padding: 7px 15px; border-radius: 999px;
  border: 1px solid var(--rose); background: var(--paper); color: var(--rose-dim);
}
.loc-card__current[hidden], .btn[hidden] { display: none; }
.loc-card__top { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.loc-card h3 { font-size: 21px; color: var(--ink); }
.loc-card__addr { font-size: 15px; line-height: 1.55; color: var(--ink-soft); }
.loc-card__hours { font-size: 14px; color: var(--ink-soft); }
.loc-card__acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
/* Distance line, written by initNearest(). --blue on the card's --paper is
   7.12:1. Absent until the visitor asks to be located. */
.loc-card__dist { font-size: 13px; font-weight: 700; letter-spacing: .04em; color: var(--blue); }

/* --- Compact page header -------------------------------------------------
   Locations, menu and contact are lookup pages — people arrive with intent.
   The tall centred hero they used to share cost ~440px before any content,
   which under the sticky nav left about one row visible on a laptop. Title
   left, the single most useful control right, then straight into the page.
   Kept off story.html and catering.html, which are read rather than used. */
.pagehead {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px 24px; flex-wrap: wrap; margin-bottom: 30px;
}
.pagehead__title { font-size: clamp(27px, 3.1vw, 36px); letter-spacing: -.02em; }
.pagehead__aside { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.section--head { padding-top: 32px; }

/* A list, not a grid: five locations scan better as full-width rows, and rows
   avoid the orphan a 2-col grid left on the last card. Each row puts the
   details on the left and the actions hard right, collapsing to stacked blocks
   on narrow screens. */
.loc-list { display: flex; flex-direction: column; gap: 16px; }
.loc-list .loc-card {
  flex-direction: row; align-items: center; justify-content: space-between;
  gap: 32px; padding: 24px 28px;
}
.loc-card__info { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; min-width: 0; }
.loc-list .loc-card__acts { flex: none; margin-top: 0; justify-content: flex-end; }

/* Fallback bar, used only when there's no [data-loc-tools] slot in the title. */
.loc-tools { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 28px; }
/* Full-width status line above the list. :empty keeps it at zero height and
   zero margin before the visitor has asked for anything, so it reserves no
   space yet still exists in the DOM as a registered live region. */
.loc-tools__note { font-size: 14px; line-height: 1.5; color: var(--ink-soft); margin-bottom: 18px; }
.loc-tools__note:empty { margin-bottom: 0; }

/* Shown when a deep link points at a category the chosen branch doesn't serve
   (e.g. menu.html#justspresso at Hillcroft). --ink-soft on --ground is 7.08:1. */
.menu-note {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin: 28px 0 4px; padding: 18px 22px;
  background: var(--sky); border: 1px solid var(--line-sky); border-radius: 14px;
  font-size: 15.5px; line-height: 1.6; color: var(--ink-soft);
}

/* --- Menu shell ----------------------------------------------------------- */
.menu-loading, .menu-empty {
  display: flex; flex-direction: column; gap: 14px; align-items: flex-start;
  padding: 44px 0; color: var(--ink-soft); font-size: 16px;
}
/* Homepage only — the menu page's copy stays left-aligned under .menu-head.
   .pop is a 4-column grid, so without the span these land in column 1 and the
   copy overflows that narrow column to the right instead of sitting centred. */
.pop > .menu-empty, .pop > .menu-loading { grid-column: 1 / -1; }
.menu-empty--center { align-items: center; text-align: center; }
.menu-empty--center .loc-card__acts { justify-content: center; }
.menu-empty--center p { max-width: 46ch; }
.menu-empty h3 { font-size: 22px; color: var(--ink); }
.menu-head { display: flex; justify-content: space-between; align-items: flex-end; gap: 24px; flex-wrap: wrap; padding: 36px 0 8px; }
.menu-head__loc { display: flex; flex-direction: column; gap: 5px; }
.menu-head__name { font-family: var(--font); font-size: 28px; font-weight: 700; color: var(--ink); }
.menu-head__meta { font-size: 14.5px; color: var(--ink-soft); }

/* --- Hours ---------------------------------------------------------------- */
.hours { display: flex; flex-direction: column; gap: 5px; width: 100%; padding-top: 24px; border-top: 1px solid var(--line); }
.hours__days { font-family: var(--font); font-size: 25px; font-weight: 700; color: var(--ink); }
.hours__time { font-size: 17px; color: var(--ink-soft); }

/* --- Forms ---------------------------------------------------------------- */
.form { display: flex; flex-direction: column; gap: 18px; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-size: 12.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft); }
.field label .req { color: var(--rose-dim); }
.field input, .field select, .field textarea {
  font-size: 16px; color: var(--ink);
  background: var(--paper); border: 1.5px solid var(--line); border-radius: 10px;
  padding: 13px 16px; min-height: 50px; transition: border-color .18s ease, box-shadow .18s ease;
}
.field textarea { min-height: 130px; resize: vertical; }
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible { border-color: var(--rose); }
.field--error input, .field--error select, .field--error textarea {
  border-color: var(--rose); box-shadow: 0 0 0 3px rgba(210,50,95,.14);
}
.field__error { display: none; font-size: 13.5px; font-weight: 500; color: var(--rose-dim); align-items: center; gap: 6px; }
.field--error .field__error { display: flex; }

.form__result {
  display: none; flex-direction: column; gap: 10px; align-items: flex-start;
  padding: 26px; border-radius: 14px; border: 1px solid var(--line); background: var(--paper);
}
.form__result.is-shown { display: flex; }
.form__result h3 { font-size: 21px; color: var(--ink); }
.form__result p { font-size: 15.5px; line-height: 1.6; color: var(--ink-soft); }
.form__result .info__icon { color: var(--pista); }
.form.is-done { display: none; }
.form__note { font-size: 13.5px; color: var(--ink-soft); }

/* --- Footer --------------------------------------------------------------- */
.footer { background: #FFFFFF; color: var(--ink-soft); padding: 48px 0 24px; position: relative; }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr; gap: 46px; }
.footer__col { display: flex; flex-direction: column; gap: 12px; align-items: flex-start; }
.footer__logo { display: inline-block; background: var(--paper); padding: 12px 16px; border-radius: 12px; }
.footer__logo img { height: 68px; width: auto; }
.footer__head { font-size: 12px; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--blue); margin-bottom: 4px; }
.footer__link { color: var(--ink-soft); font-size: 15px; display: flex; align-items: center; gap: 10px; }
.footer__link:hover { color: var(--rose-dim); }
.footer__link svg { color: var(--blue); flex: none; opacity: .85; }
.footer__bottom {
  margin-top: 32px; padding-top: 20px; border-top: 1px solid var(--line-sky);
  display: flex; justify-content: space-between; gap: 20px; flex-wrap: wrap;
  font-size: 13.5px; color: var(--ink-soft);
}

/* Two submission outcomes. The CF7 POST genuinely sent it, or we fell back to
   the mail app and cannot know if it left — never show "sent" for the latter. */
.form__result [data-when] { display: none; }
.form__result[data-mode="sent"] [data-when="sent"],
.form__result[data-mode="mail-app"] [data-when="mail-app"] { display: block; }

/* --- Reveal --------------------------------------------------------------- */
.js .reveal { opacity: 0; transform: translateY(20px); transition: opacity .7s cubic-bezier(.2,.7,.3,1), transform .7s cubic-bezier(.2,.7,.3,1); }
.js .reveal.is-in { opacity: 1; transform: none; }

/* --- Responsive ----------------------------------------------------------- */
@media (max-width: 1080px) {
  .grid-4, .pop, .stats, .cats { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .cats { grid-template-columns: repeat(2, minmax(0, 200px)); }
  .grid-4.offers { grid-template-columns: repeat(2, minmax(0, 230px)); }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 40px; }
}
@media (max-width: 900px) {
  /* the row splits before the action buttons start wrapping awkwardly */
  .loc-list .loc-card { flex-direction: column; align-items: flex-start; gap: 18px; }
  .loc-list .loc-card__acts { justify-content: flex-start; }
  :root { --nav-h: 120px; }   /* --catnav-h is unchanged: 14px padding, fixed regardless of logo size */
  .container, .nav__in, .bar__in, .hero__in, .catnav__in { padding-left: 22px; padding-right: 22px; }
  .section { padding: 40px 0; }
  .hero { padding: 44px 0 40px; }
  .hero__in { grid-template-columns: 1fr; gap: 42px; }
  .hero__media { order: -1; }
  .hero__media .ph, .hero__media img { aspect-ratio: 5/4; }
  .hero__stamp { left: auto; right: 14px; bottom: -18px; }

  /* Homepage full-bleed hero: the rules above are the shared page-header
     pattern re-asserting itself at this breakpoint (same specificity, later
     in the cascade) -- without this, .hero's padding/grid would silently
     come back and break the full-bleed layout below 900px. */
  .hero--full { padding: 0; min-height: clamp(560px, 82vh, 700px); }
  .hero--full .hero__in {
    flex-direction: column; align-items: flex-start;
    padding: 0 22px calc(26px + var(--snav-h)); gap: 16px;
  }
  .hero__controls { align-self: flex-start; }
  .split, .grid-3, .grid-2 { grid-template-columns: 1fr; gap: 40px; }
  .split--rev .split__media { order: -1; }
  .split__media .ph, .split__media img { aspect-ratio: 5/4; }
  .menu-cat { grid-template-columns: 1fr; gap: 28px; padding: 32px 0; }
  .menu-cat__aside { position: static; }
  .menu-cat__aside .ph { aspect-ratio: 16/9; }
  .form__row { grid-template-columns: 1fr; }

  /* nav-h 120 = 14 + 92 (logo) + 14 */
  .nav__in { padding: 14px 22px; gap: 12px; }
  .nav__logo img { height: 92px; }
  .nav__panel.is-open { padding: 16px 22px 22px; }

  .catnav__in { gap: 20px; overflow-x: auto; flex-wrap: nowrap; }
  .catnav a { white-space: nowrap; }
  /* No flex-wrap here. It existed so .menu-item__end (price + Order button)
     could drop to its own full-width line; both are gone, and leaving wrap on
     pushed the thumbnail onto a line of its own, above the dish name. */
  .menu-item__img { width: 64px; height: 64px; }
  .menu-head { padding-top: 26px; }
}
@media (max-width: 900px) {
  /* Stacked footer links are the last thing a thumb reaches for; 26px is too
     short. The column gap gives back most of what min-height takes. */
  .footer__col { gap: 2px; }
  .footer__link { min-height: 44px; }
}
@media (max-width: 560px) {
  :root { --nav-h: 104px; }   /* 14 + 76 (logo) + 14 */
  /* Spec §2.5 asks for a COMPACT location card. Measured at 442px each, with
     185px of that being three buttons on three separate rows. Same hierarchy
     as the hero: Order Online across the top, the two secondary actions
     sharing the row beneath. Saves ~60px per card, ~300px over the five. */
  .loc-list .loc-card { padding: 18px 20px; gap: 14px; }
  .loc-list .loc-card__acts {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px; width: 100%;
  }
  /* Order Online spanned the full width while there were three buttons, which
     left a 2-col grid filling neatly beneath it. A fourth (View Menu, added
     2026-10-02) turned that into an orphan on its own half-empty row and made
     the card taller again, undoing the compaction documented above. A plain
     2x2 fits all four in the same height as the old three, and it puts View
     Menu directly beside Order Online, which is where it was asked for. Order
     Online keeps the rose fill, so it still reads as the primary action at
     half width. */
  .loc-list .loc-card__acts .btn { width: 100%; padding: 13px 10px; font-size: 14px; }
  .loc-list .loc-card__current { grid-column: 1 / -1; justify-self: start; }

  /* "Compact layout" and "Avoid excessive spacing" (spec §Mobile Design
     Requirements). 76px top and bottom on nine sections is 1,368px of the
     homepage spent on padding alone. */
  .section { padding: 32px 0; }
  .section--tight { padding: 28px 0; }
  .sec-head { margin-bottom: 22px; }
  .footer { padding: 32px 0 20px; }

  .grid-4 { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 16px 14px; }
  /* full half-width at phone size — a 230px cap would leave dead gutters */
  .grid-4.offers { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .offer { gap: 9px; }
  .offer__name { font-size: 16px; }
  .offer__desc { font-size: 13px; line-height: 1.5; max-width: none; }
  /* Guest Favorites becomes a snapping horizontal carousel rather than six
     stacked cards — spec v1.0 §2.3 asks for a carousel, and §2.2 for scrolling
     to be kept to a minimum. The negative margin lets it bleed to the screen
     edge so the next card peeks, which is what signals that it scrolls. */
  .pop {
    display: flex; grid-template-columns: none;
    overflow-x: auto; scroll-snap-type: x mandatory;
    gap: 14px; margin: 0 -16px; padding: 0 16px 6px;
    -webkit-overflow-scrolling: touch;
  }
  .pop > .pop__card { flex: 0 0 72%; scroll-snap-align: start; }
  .pop > .menu-empty, .pop > .menu-loading { flex: 0 0 100%; }
  .cats { grid-template-columns: repeat(2, minmax(0, 160px)); gap: 14px; }
  .cat__body { padding: 14px 14px 16px; gap: 5px; }
  .cat__name { font-size: 17px; }
  .cat__desc { font-size: 13px; }
  /* "Explore Justspresso" is the longest label and wrapped, leaving the arrow
     stranded on its own line at the far right. Smaller type keeps it on one
     line; if it ever does wrap, the arrow now follows the text. */
  .cat__go { font-size: 12.5px; }
  .footer__grid { grid-template-columns: 1fr; gap: 32px; }
  .nav__in { padding: 14px 16px; gap: 8px; }
  .nav__logo img { height: 76px; }
  .nav__call, .nav__toggle { width: 44px; height: 44px; }
  .nav__end { gap: 8px; }
  .nav__end .btn { padding-left: 16px; padding-right: 16px; font-size: 13.5px; }
  .nav__panel.is-open { padding: 14px 16px 20px; }

  /* Hero controls row (caption + dots + arrows) measures 455px wide and
     doesn't fit below ~560px -- the caption text is the least essential
     part, so it's what drops first. */
  .hero__controls { gap: 10px; }
}

@media (max-width: 400px) {
  /* Four items now share the bar: logo, call, CTA, toggle. Controls stay at
     44px — the hit-target floor is not negotiable — so the CTA's own padding
     is what gives a little at this width. */
  :root { --nav-h: 92px; }   /* 14 + 64 (logo) + 14 */
  .nav__in { padding: 14px 12px; gap: 6px; }
  .nav__logo img { height: 64px; }
  .nav__end { gap: 6px; }
  .nav__end .btn { padding-left: 12px; padding-right: 12px; font-size: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker__track { animation: none; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .btn:hover, a.offer:hover .ph, a.offer:hover img, .pop__card:hover { transform: none; }
}

/* Square-source photography — the two real catering photos are 713² and 720²,
   so the 4/5 (and 5/4 on mobile) defaults would crop a fifth off the truck.
   Deliberately last in the file: the responsive blocks above restate the image
   aspect ratios at equal specificity, so this has to follow them to win. */
.hero__media--square img, .split__media--square img { aspect-ratio: 1/1; width: 100%; }
/* --natural: keep the photo's own proportions, no crop at all. For shots where
   neither 4/5 nor 5/4 fits — the Hillcroft interior is 1200×823 (1.46), which
   both defaults would visibly cut into. */
.hero__media--natural img, .split__media--natural img {
  aspect-ratio: auto; width: 100%; height: auto; object-fit: contain;
}

/* --- Mobile hero: a banner, not a stacked page (spec v1.0 §2.1) ---------- */
/* DESKTOP IS UNTOUCHED. Everything here is inside max-width: 760px, and
   tests/desktop-hero.mjs asserts the desktop hero stays full-bleed with its
   arrows and white type.

   Three shapes were tried. Full-bleed portrait showed **32% of a landscape
   photo** — two thirds of every image thrown away. A contained 16/9 box fixed
   the crop but turned the top of the page into a stack of text blocks with a
   picture underneath, which read as cluttered. This is the third: a real
   banner, the same idea as desktop — photo with the headline over it — just
   short enough for a phone.

   The mechanism is a one-column grid where the photo, the scrim, the headline
   and the dots all occupy **grid cell 1/1**, and everything else flows in rows
   beneath. That is what scopes the scrim to the photo instead of the whole
   hero, and it needs `display: contents` on BOTH .hero__in and .hero__copy so
   their children become direct grid items — the desktop layout still needs
   those wrappers, so the markup cannot change. */
@media (max-width: 760px) {
  .hero--full {
    display: grid; grid-template-columns: 100%;
    grid-auto-rows: auto; row-gap: 18px;
    align-items: start;
    min-height: 0; overflow: hidden; padding: 0;
    background: #FFFFFF;
  }
  .hero--full .hero__in,
  .hero--full .hero__copy { display: contents; }

  /* ---- the banner: photo + scrim + headline + dots, all in row 1 ---- */
  .hero__bg {
    grid-area: 1 / 1; position: relative; inset: auto;
    width: 100%; aspect-ratio: 16/9;   /* matches the source — photo shown whole */
  }
  .hero__scrim { display: none; }
  .hero--full .h-hero {
    grid-row: 2; padding: 0 22px; margin: 0;
    color: var(--ink); font-size: clamp(32px, 8.6vw, 42px); line-height: 1.12;
  }
  .hero__brand { color: var(--ink-soft); font-size: 12px; margin-bottom: 8px; }
  .hero--full .hero__controls {
    grid-area: 1 / 1; z-index: 3; align-self: end; justify-self: end;
    padding: 0 22px 22px; position: relative; left: auto; right: auto; bottom: auto;
  }
  .hero--full .hs__nav { display: none; }   /* dots only; they reach any slide */
  .hero--full .hs__dot { border-color: rgba(255,252,251,.9); box-shadow: 0 0 0 1px rgba(31,46,56,.35); }
  .hero--full .hs__dot[aria-selected="true"] { background: var(--paper); border-color: var(--paper); }

  /* ---- everything below the banner sits on the page ground ---- */
  .hero__lede--onphoto {
    grid-row: 3; padding: 0 22px; margin: 0;
    color: var(--ink-soft); font-size: 15px; max-width: none;
  }
  /* Owner's request, 2026-09-28: all THREE on one row, in source order, each
     the same rose fill. This replaces (not extends) the 1 + 2 layout of
     2026-09-24, where Order Online led and the other two were underlined
     links — the old `> .btn:not(:first-child)` rule was 0,3,0 and would have
     out-specified the fill below, so it has to go rather than be overridden.
     The 44px tap floor is restated here because the padding drops to 8px. */
  .hero--full .hero__actions {
    grid-row: 4; padding: 0 22px; margin: 0;
    display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px;
  }
  .hero--full .hero__actions > :first-child { grid-column: auto; }
  .hero--full .hero__actions .btn {
    width: 100%; min-height: 44px;
    padding: 8px 4px; font-size: clamp(11px, 3.4vw, 13px);
    letter-spacing: 0; line-height: 1.15; text-align: center;
    white-space: nowrap;
    background: var(--rose); color: var(--paper);
    border-color: transparent;
    box-shadow: 0 6px 16px rgba(210,50,95,.22);
    text-decoration: none;
  }
  .hero--full .hero__actions .btn:hover,
  .hero--full .hero__actions .btn:focus-visible {
    background: var(--ink); color: var(--paper); border-color: transparent;
    text-decoration: none;
  }
  .hero__quick {
    grid-row: 5; padding: 0 22px; margin: 0;
    display: grid; grid-template-columns: 1fr 1fr;
    align-items: start; gap: 12px 12px;
  }
  .hero__quick .status { align-items: flex-start; }
  .hero__quick .status .status__dot { margin-top: 7px; flex: none; }
  .hero__quick .locpick--onphoto { align-items: flex-start; }
  .hero__quick .locpick--onphoto svg { margin-top: 3px; }

  .hero--full + .section { padding-top: 28px; }

  /* On the cream ground now, so every --onphoto treatment inverts. */
  .hero--full .btn--ghost-light {
    border-color: var(--rose-dim); color: var(--rose-dim);
    background: transparent; backdrop-filter: none;
  }
  .hero--full .btn--ghost-light:hover,
  .hero--full .btn--ghost-light:focus-visible { background: var(--rose-dim); color: var(--paper); border-color: var(--rose-dim); }
  .hero__quick .status, .hero__quick .locpick--onphoto { font-size: 13.5px; }
  .hero--full .status--onphoto .status__text { color: var(--ink-soft); }
  .hero--full .status--onphoto.status--open .status__text { color: var(--open); }
  .hero--full .status--onphoto.status--soon .status__text { color: var(--soon); }
  .hero--full .status--onphoto .status__dot { background: var(--shut); }
  .hero--full .status--onphoto.status--open .status__dot { background: var(--open); }
  .hero--full .status--onphoto.status--soon .status__dot { background: var(--soon); }
  .hero--full .locpick--onphoto,
  .hero--full .locpick--onphoto span { color: var(--rose-dim); }
  .hero--full .locpick--onphoto .locpick__change { color: var(--ink-soft); }
  .hero--full .hero__quick__a {
    border: 1.5px solid var(--line); border-radius: 999px; background: var(--paper);
    padding: 9px 16px; min-height: 44px; font-size: 13.5px; color: var(--rose-dim);
  }
  /* "Call or Text Store" does not fit one line in a half-width grid cell, so
     it wraps inside its own pill rather than overflowing it. */
  .hero--full .reach > .hero__quick__a { white-space: normal; text-align: left; }
  .hero--full .reach { width: 100%; }
  .hero--full .hero__quick__a:hover,
  .hero--full .hero__quick__a:focus-visible { border-color: var(--rose); }
}

/* Back out of the delivery-app step to Pickup | Delivery. Hidden for a branch
   with no Square store, which never sees step one. */
.sheet__back {
  display: inline-flex; align-items: center; gap: 7px; margin-top: 14px;
  background: none; border: none; cursor: pointer; padding: 8px 2px;
  font-family: var(--font); font-size: 14px; font-weight: 700; color: var(--rose-dim);
}
.sheet__back:hover, .sheet__back:focus-visible { color: var(--ink); }
/* `display` in a page stylesheet beats the UA rule the hidden ATTRIBUTE relies
   on, so without this Austin -- which skips straight to the delivery step --
   kept showing a Back button leading to a Pickup option it does not have. The
   element's .hidden property was true the whole time, so a test reading that
   property passed while the button sat there on screen. */
.sheet__back[hidden] { display: none; }
