/* Typeface loading: Cormorant Garamond (headings/display) and Jost
   (body/UI) are loaded via <link> tags in the shared layouts
   (layout.html, layout_yazol.html, layout_scoopstop.html), not here -
   every page extends one of those three, so that's the single place
   the fonts need to be requested from Google Fonts. MaryKate is a
   self-hosted display font (static/fonts/MaryKate.ttf), loaded here
   instead since it isn't on Google Fonts. */
@font-face {
    /* This file only has one real weight (Medium/500) - declaring a
       single fixed weight here, not a range, so the browser still
       synthesizes (faux-)bold for the many font-weight:600/700 rules
       already written throughout this file, instead of silently
       rendering all of them at the same thin native weight. */
    font-family: 'MaryKate';
    src: url('fonts/MaryKate.ttf') format('truetype');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}

/* ─── TOKENS ──────────────────────────────────────
   Bold, playful palette shared across the WHOLE site,
   Yazol Coffee and Scoop Stop included, mixed rather than
   siloed per brand. Solid colors only, no gradients:
   Onyx #0B0A0E, Indigo Velvet #3D2A91, Deep Purple #5B1E57,
   Dark Magenta #92278F, Frosted Blue #B0E0E6, Gold #FFD700,
   Light Gold #F0E68C, Crimson Carrot #FF4500, Wheat #E9D6AA
   (used sparingly, never as a page background). White stays
   pure white for dense text/product content (cards, panels);
   --cream is a warm off-white for page/section backgrounds
   sitting behind those white cards, the same two-tone pattern
   client referenced from stories.starbucks.ca (their card
   surface is #fff on a #faf8f5 page background). */
:root {
    --font-heading: 'MaryKate', 'Cormorant Garamond', serif;
    --font-body:    'Jost', sans-serif;
    /* Shared type scale: every heading-level and label-level font-size
       on the site should reference one of these five instead of its
       own bespoke number, so "h2-equivalent" (say) is actually the
       same size everywhere it appears. */
    --text-display: clamp(40px, 4.5vw, 56px);
    --text-h1:      clamp(32px, 7vw, 60px);
    --text-h2:      clamp(26px, 5.5vw, 50px);
    --text-h3:      30px;
    --text-label:   13px;
    --text-body:    18px;
    --text-rating:  20px;
    /* Shared spacing scale: standard section vertical padding, denser
       section padding, grid gaps for the three grid roles the site
       actually uses, and the visible gap every "-70px tuck under the
       transparent nav" hero should share (nav height is a fixed 70px,
       so a tucked hero's padding-top is calc(70px + --space-nav-clear)). */
    --space-section:    96px;
    --space-section-sm: 64px;
    --space-gap-lg:     64px;
    --space-gap-md:     32px;
    --space-gap-sm:     24px;
    --space-nav-clear:  24px;
    --ink:        #0B0A0E;
    --white:      #FFFFFF;
    --cream:      #FAF6F0;
    /* Revived on request (2026-08-29, third pass) as its own token,
       distinct from --cream above - card-level surfaces (modals, the
       contact form card, the cart page) that were white/periwinkle. */
    --scoop-cream: #EBE8C8;
    /* Site-wide palette as of 2026-08-29: Scoop Stop's Burgundy/
       Periwinkle/Scoop Cream (originally scoopstop.css-only) promoted
       to the shared default across the entire public site - Yazol
       Coffee, the landing page, Heritage/Market, and checkout/cart/pay
       all inherit these same values now, no per-brand pin-back left
       anywhere. Token NAMES below still say "chocolate"/"spicy-red"/
       "oat-milk" (every selector across style.css/yazol.css already
       references them under those names, hundreds of call sites - not
       worth a rename) but the VALUES are Scoop Stop's burgundy/
       burgundy/scoop-cream; don't be misled by the names when reading
       a hex here. scoopstop.css keeps only what's genuinely still
       brand-unique (the Dark Magenta hero art). */
    --chocolate:      #7A303B;
    --spicy-red:      #7A303B;
    /* Companion to --chocolate, same pattern as --accent-rgb - for
       rgba()-based tints/glows that want burgundy specifically rather
       than whatever --accent currently is (e.g. the size-picker's
       selected-option highlight, kept burgundy on request while
       --accent itself moved to periwinkle). */
    --chocolate-rgb:  122,48,59;
    /* Periwinkle, not Scoop Cream (2026-08-29, second pass): --oat-milk/
       --accent/--nav-panel-bg/--nav-highlight all moved to Periwinkle on
       request, replacing the Burgundy-family values the first pass gave
       them. --accent-contrast flipped white->ink alongside it (white
       text on light periwinkle button fills would be unreadable,
       ~1.1:1) - same "text sitting on its own fill needs a different
       color" pattern already used elsewhere in this file. */
    --oat-milk:       #B0CEFE;
    /* Periwinkle: accent-colored copy sitting directly on --chocolate
       (burgundy) rather than on a button fill - burgundy-on-burgundy
       is 1:1 contrast, not just low, since --accent below is a
       different color now (periwinkle). Verified 5.665:1 against
       --chocolate burgundy, same number scoopstop.css originally
       computed for --periwinkle, reused directly since it's the same
       color. Also happens to still work as plain --accent text
       wherever that sits on a dark/burgundy surface (e.g.
       .footer-partner-link:hover) - periwinkle reads fine there either
       way, so those spots were left on --accent rather than switched
       to this token. */
    --spicy-red-text: #B0CEFE;
    --accent:     #B0CEFE;
    --accent-rgb: 176,206,254;
    /* Derived from the periwinkle --accent, not left over from the
       burgundy direction (that was a live bug in the first draft of
       this pass - hovering a periwinkle button would have jumped to a
       burgundy fill). Same HSL hue/saturation as --accent (217°, 94%),
       lightness stepped down to 74%/42% for a light hover-fill shade
       and a not-currently-used darker one respectively. */
    --accent-hover-light: #7EAEFB;
    --accent-hover-dark:  #1056C6;
    /* Ink, not white - see the --oat-milk note above. */
    --accent-contrast: #0B0A0E;
    /* Text-safe accent for copy/borders sitting directly on a LIGHT
       surface (white/cream/--oat-milk) - the periwinkle --accent itself
       is only ~1.6:1 there (fails even the 3:1 UI-component minimum,
       nowhere close to 4.5:1 for text), the mirror-image problem
       --spicy-red-text solves for accent-on-dark. Same hue as --accent
       (217°), darkened to L 32%/S 70%: 9.37:1 against white, 5.85:1
       against --oat-milk (periwinkle) itself, so it also survives an
       accent-colored border/badge sitting on a periwinkle card. Every
       bare `color: var(--accent)`/`border-color: var(--accent)` text or
       UI-border site in this file already implied a light backdrop by
       construction - anywhere dark-surface support was needed, the
       codebase already reaches for --spicy-red-text instead (that
       convention is what made this token's rollout out safe to do by
       find/replace rather than auditing every call site from scratch). */
    --accent-text: #19448B;
    /* Cart-icon hover color - only ever renders over something dark (a
       hero photo, or a --chocolate/burgundy section), since .on-light
       routes the light-background case to a separate rule
       (nav.navbar.on-light .nav-cart:hover { color: var(--ink); }).
       Periwinkle reads well there (light-on-dark), same reasoning as
       --spicy-red-text above. */
    --nav-highlight: #B0CEFE;
    /* Solid surface for the two floating nav panels (desktop Menu
       dropdown, mobile full-screen menu). Periwinkle, same as above -
       this collides with --accent also being periwinkle now (the
       .nav-links li a / etc. text color rule would otherwise read
       var(--accent), making panel-bg == text-color, literally
       invisible - the same "1:1 contrast" problem --accent-on-its-own-
       -chocolate has elsewhere in this file). Patched at the selector
       itself (further down) to var(--ink) instead of var(--accent). */
    --nav-panel-bg: #B0CEFE;
    --text-muted: rgba(11,10,14,0.62);
    --border:     rgba(11,10,14,0.14);
    --radius:     10px;
    --shadow:       0 4px 24px rgba(11,10,14,0.10);
    --shadow-hover: 0 16px 56px rgba(11,10,14,0.18);
}

/* ─── RESET / BASE ───────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* touch-action removes the ~300ms tap delay mobile browsers otherwise
   insert while waiting to see if a tap becomes a double-tap-to-zoom -
   without it every button/link on a phone felt a beat laggier than the
   same tap on desktop, reading as "unresponsive" rather than instant.
   -webkit-tap-highlight-color: transparent replaces Android/iOS's grey
   flash-on-tap rectangle (which ignores border-radius and looked like a
   glitch on pill/circular buttons) with nothing, since every tappable
   element here already has its own :hover/:active feedback in CSS. */
html { scroll-behavior: smooth; color-scheme: light; -webkit-tap-highlight-color: transparent; }

/* `overflow-x: hidden` here specifically, not on `html` too: per the
   CSS overflow spec, pairing a non-visible overflow-x with the default
   visible overflow-y forces that y-axis to compute as `auto`, turning
   the element into its own scroll container. With BOTH html and body
   doing that at once (as this used to), nav.navbar's `position: sticky`
   loses track of which one is its actual scrolling ancestor and stops
   sticking entirely past a certain scroll distance, the nav just
   scrolls away with the page. `clip` (rather than `hidden`) avoids the
   promotion quirk without giving up the horizontal-overflow guard. */
body {
    font-family: 'Montserrat', sans-serif;
    font-weight: 400;
    background: var(--white);
    color: var(--ink);
    font-size: 16px;
    line-height: 1.65;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    overflow-x: clip;
    max-width: 100vw;
    touch-action: manipulation;
}
/* Any full-screen overlay (mobile nav panel, gallery lightbox, a menu
   item's detail modal) freezes background scroll while it's open -
   without this, iOS in particular lets the page behind a fixed overlay
   rubber-band/scroll on its own touch, which reads as the whole screen
   being "loose" under your finger instead of the overlay being a solid
   surface. */
body.menu-modal-open, body.lightbox-open, body.nav-open { overflow-y: hidden; }
p {
    font-family: 'Montserrat', sans-serif;
    font-weight: 400;
    font-size: 16px;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-heading);
    line-height: 1.1;
    /* Positive, not the old -0.01em - that negative tracking was tuned
       for Montserrat and squeezes MaryKate's cursive letterforms into
       each other instead. */
    letter-spacing: 0.06em;
}
h1 { font-weight: 700; font-size: 60px; text-transform: uppercase; }
h2 { font-weight: 700; font-size: 50px; text-transform: uppercase; }
h3 { font-weight: 300; font-size: 30px; text-transform: uppercase; }
h4 { font-weight: 300; }
h5 { font-weight: 300; }
h6 { font-weight: 300; }
a  { text-decoration: none; }

/* Any inline text link inside a paragraph that isn't part of a styled
   component (nav, footer, button, card) falls back to this instead of
   the browser's default blue/underline. */
p a {
    color: var(--accent-text);
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: opacity 0.15s;
}
p a:hover { opacity: 0.75; }

.eyebrow-size { font-size: 14px; }

/* Keyboard-focus ring, shown only for keyboard/switch navigation
   (:focus-visible, not every mouse/touch tap) - previously most links
   and buttons had no visible focus state at all beyond the browser's
   own inconsistent default, which reads as broken/unfinished for
   anyone tabbing through the site. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--accent-text);
    outline-offset: 2px;
    border-radius: 4px;
}


/* ═══════════════════════════════════════════════
   NAVBAR  -  floating over the page, background painted
   live (site.js) to match whatever section is actually behind
   it - purple hero, white logo band, burgundy, periwinkle, ...
   instead of one fixed color that would clash with some of
   them. `background: transparent` below is just the pre-JS
   fallback. The same live sample also drives `.on-light`, which
   flips nav text/icons to a dark palette whenever that matched
   color is light - plain white/gold text would be invisible
   once the bar itself turns white/periwinkle.
   ═══════════════════════════════════════════════ */

nav.navbar {
    position: sticky;
    top: 0;
    z-index: 1000;
    height: 70px;
    padding: 0 48px;
    display: flex;
    align-items: center;
    background: transparent;
    transition: background-color 0.25s ease;
}
/* While the dropdown panel is open, the bar itself becomes the same
   solid --nav-panel-bg surface as the panel below it, reading as one
   continuous block instead of a scroll-matched color sitting on top
   of an unrelated one. `!important` since site.js's scroll-driven
   color match sets this same property as an inline style, which
   would otherwise always win over a plain class selector. */
nav.navbar.open {
    background-color: var(--nav-panel-bg) !important;
}

.nav-left {
    display: flex;
    align-items: center;
    gap: 16px;
    margin-right: auto;
}
.nav-logo {
    display: flex;
    align-items: center;
    text-decoration: none;
    color: var(--white);
    transition: transform 0.15s ease;
}
.nav-logo:hover { transform: scale(1.08); }
.nav-logo img,
.footer-logo img,
.admin-brand img {
    display: block;
    object-fit: contain;
    flex-shrink: 0;
}
/* home_button.png is a colorful iridescent emblem by default - tinted
   flat --scoop-cream here (filter chain solved empirically: brightness(0)
   collapses it to a black silhouette first, then invert/sepia/saturate/
   hue-rotate/brightness rebuild that black into #EBE8C8, same trick
   .on-light below already used to reach solid black) so the home icon
   matches the rest of the nav's icon/text color on a dark section.
   .on-light overrides back to a plain black silhouette for light
   sections instead, same as before. */
.nav-logo img {
    height: 48px;
    width: auto;
    filter: brightness(0) invert(95%) sepia(22%) saturate(250%) hue-rotate(359deg) brightness(92%);
}

/* Yazol/Scoop Stop switcher, left-aligned right next to the home icon.
   The active one gets a light-flare PNG glowing behind it (a CSS
   drop-shadow glow was tried first but just muddied the wordmark's own
   gradient colors instead of reading as a highlight). */
.nav-brand-group {
    display: flex;
    align-items: center;
    gap: 10px;
}
.nav-brand-link {
    position: relative;
    display: flex;
    align-items: center;
}
.nav-brand-highlight {
    position: absolute;
    left: 50%;
    bottom: -7px;
    width: 135%;
    height: 12px;
    transform: translateX(-50%) scaleX(0.8);
    /* Image itself comes from an inline style now (site_image_url()),
       so it's admin-replaceable from /admin/site-images - this rule
       only sets the non-image parts. */
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease, transform 0.25s ease, filter 0.25s ease;
    z-index: 0;
    filter: drop-shadow(0 0 3px rgba(var(--accent-rgb), 0.9))
            drop-shadow(0 0 8px rgba(var(--accent-rgb), 0.7))
            drop-shadow(0 0 16px rgba(var(--accent-rgb), 0.45));
}
.nav-brand-link.active .nav-brand-highlight { opacity: 1; transform: translateX(-50%) scaleX(1); }
/* Same trigger as every other on-light icon swap (.nav-toggle span,
   .nav-logo img): the glow PNG's own warm/light colouring washes out
   against a light page background, so on-light flattens it to a dark
   silhouette instead - brightness(0) replaces the accent-tinted
   drop-shadow glow entirely (filter isn't additive across rules),
   which is fine here since a glow behind a dark shape wouldn't read
   anyway. */
nav.navbar.on-light .nav-brand-highlight,
nav.navbar.open .nav-brand-highlight { filter: brightness(0); }
.nav-brand-text {
    position: relative;
    z-index: 1;
    display: block;
    color: var(--scoop-cream);
    font-family: 'Montserrat', sans-serif;
    font-weight: 400;
    font-size: 17px;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    white-space: nowrap;
    text-shadow: 0 1px 3px rgba(0,0,0,0.35);
    /* Stretches the letterforms taller without widening them - Montserrat
       has no condensed/tall cut loaded, so this fakes that proportion. */
    transform: scaleY(1.25);
    transition: transform 0.15s ease, color 0.15s ease;
}
.nav-brand-link:hover .nav-brand-text { transform: scaleY(1.25) scale(1.05); }
nav.navbar.on-light .nav-brand-text,
nav.navbar.open .nav-brand-text { color: var(--ink); }
.nav-brand-divider {
    color: var(--scoop-cream);
    opacity: 0.4;
    font-size: 18px;
    line-height: 1;
}
nav.navbar.on-light .nav-brand-divider,
nav.navbar.open .nav-brand-divider { color: var(--ink); }

.nav-toggle {
    display: flex;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px;
}
.nav-toggle span {
    display: block;
    width: 22px;
    height: 2px;
    background: var(--scoop-cream);
    border-radius: 2px;
    transition: transform 0.25s, opacity 0.2s, background 0.15s;
}
/* Hamburger morphs into an X once the panel is open, so the same
   top-right button also serves as the close control. */
nav.navbar.open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
nav.navbar.open .nav-toggle span:nth-child(2) { opacity: 0; }
nav.navbar.open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
nav.navbar.on-light .nav-toggle span,
nav.navbar.open .nav-toggle span { background: var(--ink); }
nav.navbar.on-light .nav-logo,
nav.navbar.open .nav-logo { color: var(--ink); }
/* The home icon is a raster <img>, not an inline SVG, so `color` above
   does nothing to it - force it to a black silhouette with a filter
   instead, same trigger as every other on-light icon swap. */
nav.navbar.on-light .nav-logo img,
nav.navbar.open .nav-logo img { filter: brightness(0); }

/* The link list lives behind the hamburger at every screen size, not
   just on narrow ones: a solid full-width dropdown panel, closed by
   default. It's always its own solid --nav-panel-bg surface regardless
   of `.on-light` (which only governs the transparent bar's own icon
   colors), so its own text stays one fixed color unconditionally, no
   `.on-light` variant needed for anything inside it - --accent (burgundy),
   not white, now that --nav-panel-bg is scoop-cream instead of a dark
   surface: 7.309:1, same number scoopstop.css originally verified for
   this exact pairing before it became the site-wide default. */
.nav-links {
    /* Always rendered (not display:none/flex) so opening/closing can
       transition instead of snapping instantly - position:fixed already
       takes it out of flow, so keeping it in the DOM while hidden costs
       nothing layout-wise. overscroll-behavior-y:contain stops a scroll
       that hits the top/bottom of this panel from "leaking" into the
       page behind it (the classic iOS rubber-band-the-whole-screen feel
       that makes an open menu seem shaky). */
    display: flex;
    position: fixed;
    top: 70px; left: 0; right: 0; bottom: 0;
    list-style: none;
    background: var(--nav-panel-bg);
    flex-direction: column;
    align-items: center;
    padding: 24px 0 max(36px, env(safe-area-inset-bottom));
    z-index: 999;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(-14px);
    transition: opacity 0.22s ease, transform 0.22s ease, visibility 0s linear 0.22s;
}
nav.navbar.open .nav-links {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: none;
    transition: opacity 0.22s ease, transform 0.22s ease;
}
.nav-links li { width: 100%; }
.nav-links li a {
    position: relative;
    /* var(--ink), not var(--accent) - see the --nav-panel-bg note in
       :root above, --accent is periwinkle too, same color as this
       panel's background. */
    color: var(--ink);
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 14px 24px;
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 15px;
    line-height: 1.4;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-shadow: 0 1px 3px rgba(0,0,0,0.35);
    border-radius: 9999px;
    transition: background 0.15s, color 0.15s;
}
/* .nav > li > a doesn't match any element in this codebase's actual nav
   markup (.nav-links li a, above, is what's real) - included anyway to
   match the reference site's selector list. */
.nav > li > a {
    font-family: 'MaryKate', sans-serif;
    font-weight: 700;
}

/* Current-page glow: same purple light-flare PNG as the brand switcher
   (.nav-brand-highlight), swapped in for what used to be a solid
   --nav-highlight pill fill, so "you are here" reads the same way in
   both spots instead of two different highlight languages. Sits as an
   underline glow beneath the text (like .nav-brand-highlight), not a
   bar across the middle of it. */
.nav-link-highlight {
    position: absolute;
    left: 50%;
    bottom: 6px;
    width: 60%;
    height: 10px;
    transform: translateX(-50%) scaleX(0.85);
    background-position: center;
    background-size: 100% 100%;
    background-repeat: no-repeat;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease, transform 0.3s ease;
    z-index: 0;
    filter: drop-shadow(0 0 4px rgba(var(--accent-rgb), 0.85))
            drop-shadow(0 0 10px rgba(var(--accent-rgb), 0.6))
            drop-shadow(0 0 20px rgba(var(--accent-rgb), 0.35));
}
.nav-link-text { position: relative; z-index: 1; }
.nav-links li a.active .nav-link-highlight,
.nav-dropdown-trigger.active .nav-link-highlight,
.nav-dropdown-panel li a.active .nav-link-highlight {
    opacity: 1;
    transform: translateX(-50%) scaleX(1);
}

/* ─── NAV: MENU DROPDOWN ──────────────────────── */
/* Collapses into a plain expanding section of the same full panel
   rather than a floating popover, tap/click to open at every size. */
.nav-dropdown { width: 100%; }
.nav-dropdown-trigger {
    position: relative;
    background: none;
    border: none;
    cursor: pointer;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 6px;
    padding: 14px 24px;
    color: var(--ink);
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 15px;
    line-height: 1.4;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-shadow: 0 1px 3px rgba(0,0,0,0.35);
    border-radius: 9999px;
    transition: background 0.15s, color 0.15s;
}
.nav-dropdown-trigger svg { position: relative; z-index: 1; transition: transform 0.15s; flex-shrink: 0; }
.nav-dropdown.open .nav-dropdown-trigger svg { transform: rotate(180deg); }

.nav-dropdown-panel {
    /* max-height transition instead of display:none/block, so the
       submenu unrolls open rather than popping in - grid-rows collapse
       tricks need a single wrapping child to size against, but this is
       a <ul> of several <li> siblings, so a generous fixed max-height
       (well past the 3 real rows this ever holds) is the simplest way
       to get a genuine transition here. */
    display: block;
    position: static;
    width: 100%;
    list-style: none;
    background: transparent;
    box-shadow: none;
    border-radius: 0;
    padding: 0;
    max-height: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-height 0.3s ease, opacity 0.2s ease;
}
.nav-dropdown.open .nav-dropdown-panel {
    max-height: 320px;
    opacity: 1;
    padding: 0 0 8px;
}
.nav-dropdown-panel li a {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: auto;
    text-align: center;
    padding: 14px 24px;
    color: var(--ink);
    font-family: 'Montserrat', sans-serif;
    font-weight: 700;
    font-size: 15px;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-shadow: none;
    border-bottom: none;
}


/* ═══════════════════════════════════════════════
   HOME HERO  -  full-viewport video
   ═══════════════════════════════════════════════ */

.hero-home {
    margin-top: -70px;
    display: flex;
    flex-direction: column;
    position: relative;
    overflow: hidden;
    background: #0B0A0E;
}

/* Visual block: hero artwork on top (2/3) with a logo band
   underneath (1/3). Sized in its own box rather than the old
   full-viewport cover so a caption/logo strip has somewhere to
   live without sitting on top of the photo. */
.hero-visual {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 82vh;
    min-height: 460px;
    max-height: 780px;
}

.hero-bg-video {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}
.hero-bg-video video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.92;
}

/* object-fit: contain, not cover - the artwork already has its own
   framing/padding baked in, and on wide viewports a cover crop was
   clipping the top of the art (or leaving wildly different amounts
   of headroom between Yazol and Scoop Stop) depending on how far the
   container's aspect ratio drifted from the image's. Contain always
   shows the whole image and keeps that headroom consistent between
   the two domains, at the cost of a little empty space beside it
   that the section's own background already matches. */
.hero-bg-image {
    flex: 2 1 0;
    min-height: 0;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    /* Top padding clears the transparent sticky nav (hero-home's
       -70px margin tucks this band underneath it, and the nav itself
       is 70px tall) - calc(70px + --space-nav-clear) is the shared
       formula every "-70px tuck under nav" hero in this file uses, so
       they all land the same visible distance below the nav. */
    padding: calc(70px + var(--space-nav-clear)) 20px 8px;
}
.hero-bg-image img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    opacity: 0.92;
}

/* Padding kept small and matched to the artwork's own so the two
   bands' rendered logo sizes track their 2:1 flex split instead of
   being independently capped - visually 2/3 vs 1/3, not just in
   box height. min-height: 0 overrides the flex default of
   min-height: auto, which was letting the logo <img>'s own intrinsic
   aspect ratio inflate this band past its 1/3 share regardless of
   flex-grow. */
.hero-logo-band {
    flex: 1 1 0;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: #fff;
    padding: 8px 24px;
    position: relative;
}
.hero-logo-band img {
    max-width: 88%;
    max-height: 90%;
    object-fit: contain;
}

.hero-tagline {
    font-family: var(--font-heading);
    font-style: normal;
    font-weight: 500;
    font-size: clamp(38px, 7vw, 54px);
    letter-spacing: 0.1em;
    line-height: 1.1;
    text-align: center;
    /* Subtitle's fluid size lives here as a variable so the lead line
       below can be defined as a fixed ratio of it (calc(...* 1.44)).
       Independent clamp() ranges on each span used to cross over at
       different viewport widths, so the lead read bigger on desktop
       but smaller than the subtitle on narrow phones - tying them to
       one shared value keeps the lead a fixed ratio bigger everywhere. */
    --tagline-sub-size: clamp(22px, 4.5vw, 34px);
    /* This max-width was sized for the subtitle's reading width, but
       .hero-tagline-lead (the headline span nested inside this <p>)
       shares the same box - a nested inline-block child can never
       render wider than its containing block, so no max-width set on
       the child itself could have decoupled it from this cap. Raised
       here instead (560 -> 900) since that's structurally where the
       constraint actually lives. Harmless to the subtitle lines
       ("Connecting people," / "heritage and culture.") since this <p>
       is an unstretched flex item in .hero-logo-band - it only ever
       grows to fit its widest line, and those two are far short of
       either 560 or 900px regardless. */
    max-width: 900px;
    color: #fff;
    position: relative;
    z-index: 1;
}

.hero-tagline-lead {
    display: inline-block;
    color: #fff;
    /* Always 44% bigger than .hero-tagline-sub's --tagline-sub-size,
       at every viewport width - see the note on .hero-tagline. */
    font-size: calc(var(--tagline-sub-size) * 1.44);
    font-family: var(--font-heading);
    font-weight: 500;
    font-style: normal;
    text-transform: uppercase;
    line-height: 1.025;
    /* Drops the 0.04em inherited from .hero-tagline - small width
       savings, no visual downside at this weight/case. Left in place
       for the subtitle, which still inherits it normally. */
    letter-spacing: normal;
}

.hero-eyebrow {
    display: flex;
    align-items: center;
    gap: 10px;
    font-family: var(--font-body);
    font-size: var(--text-label);
    font-weight: 500;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: var(--accent-text);
    margin-bottom: 24px;
}

/* ═══════════════════════════════════════════════
   SPLIT PAGE HERO  -  text left / photo right
   ═══════════════════════════════════════════════ */

.hero-page {
    min-height: 520px;
    margin-top: -70px;
    display: grid;
    grid-template-columns: 54% 46%;
    background: var(--white);
    align-items: stretch;
}
.hero-page-text {
    background: var(--white);
    padding: calc(70px + var(--space-nav-clear)) 64px 80px 80px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.hero-page h1 {
    font-size: var(--text-display);
    color: var(--ink);
    line-height: 1.1;
    letter-spacing: 0.06em;
    margin-bottom: 16px;
}
.hero-page .hero-eyebrow { color: var(--accent-text); margin-bottom: 14px; }
.hero-page .hero-text {
    color: var(--text-muted);
    font-size: var(--text-body);
    line-height: 1.75;
    max-width: 460px;
    margin-top: 4px;
}
.hero-page-photo {
    /* Same nav-clear formula as .hero-page-text (its sibling column in
       the same -70px-tucked .hero-page grid row) - previously smaller
       than the text column's padding-top, which let the photo tuck
       14px behind the nav instead of clearing it like the text does. */
    padding: calc(70px + var(--space-nav-clear)) 64px 56px 24px;
    display: flex;
    align-items: center;
    background: var(--white);
    overflow: visible;
}
.hero-page-photo img {
    width: 100%;
    height: 100%;
    max-height: 460px;
    object-fit: cover;
    display: block;
    border-radius: 16px;
    box-shadow: 0 24px 64px rgba(43,27,18,0.14);
    opacity: 1;
}

/* Used by Heritage, Market, Our Story AND Scoop Stop's menu page - the
   first three want the new --chocolate direction, Scoop Stop needs to
   stay pixel-identical, so this is a base-level flip with an explicit
   pin-back in scoopstop.css (see the insulation block near the top of
   that file) rather than per-page ID scoping. */
.hero-page-centered {
    margin-top: -70px;
    padding: calc(70px + var(--space-nav-clear)) 40px 80px;
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.hero-page-centered .menu-header-image {
    width: 100%;
    max-width: 300px;
    height: auto;
    margin-bottom: 20px;
}
.hero-page-centered h1 {
    font-size: var(--text-display);
    color: var(--scoop-cream);
    line-height: 1.1;
    letter-spacing: 0.06em;
    margin-bottom: 16px;
    max-width: 760px;
}
/* Scoop Stop's menu header splits "SCOOP STOP" (h1) from "ICE CREAM"
   underneath as a smaller line, rather than one long h1 phrase - so this
   overrides the h1's own margin-bottom (set above) only when a subtitle
   immediately follows it, tightening the gap between the two lines while
   still leaving the same 16px gap before whatever comes next. */
.hero-page-centered h1:has(+ .menu-header-subtitle) { margin-bottom: 2px; }
.hero-page-centered .menu-header-subtitle {
    font-family: var(--font-heading);
    font-weight: 600;
    /* Deliberately not var(--text-h2) - that token is sized for real
       body headings and would render nearly as large as the h1 above.
       This just needs to read as a clearly smaller second line. */
    font-size: clamp(24px, 2.6vw, 32px);
    color: var(--ink);
    letter-spacing: 0.08em;
    line-height: 1.1;
    margin-bottom: 16px;
}
.hero-page-centered .section-eyebrow { justify-content: center; }
.coming-soon-label {
    font-family: var(--font-heading);
    font-weight: 500;
    color: rgba(255,255,255,0.92);
    font-size: var(--text-display);
    line-height: 1.1;
    margin-top: 24px;
}
.hero-page-centered .hero-text {
    color: rgba(255,255,255,0.68);
    font-size: var(--text-body);
    line-height: 1.75;
    max-width: 600px;
    margin-top: 4px;
}


/* ═══════════════════════════════════════════════
   BUTTONS
   ═══════════════════════════════════════════════ */

.button-primary {
    background: var(--accent);
    color: var(--accent-contrast);
    padding: 13px 26px;
    border-radius: 6px;
    font-family: var(--font-body);
    font-weight: 500;
    font-size: var(--text-label);
    border: none;
    cursor: pointer;
    transition: background 0.18s, transform 0.18s, box-shadow 0.18s;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    text-decoration: none;
    position: relative;
    overflow: hidden;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.button-primary:hover {
    background: var(--accent-hover-light);
    transform: translateY(-2px);
    box-shadow: 0 8px 24px rgba(var(--accent-rgb),0.28);
}
/* Touch devices never fire :hover, so without this a tap on a phone
   gave zero visual feedback that the press registered at all - the
   button would just sit still until the next page loaded. */
.button-primary:active {
    transform: translateY(0) scale(0.97);
    box-shadow: 0 4px 14px rgba(var(--accent-rgb),0.22);
    transition-duration: 0.08s;
}
.button-primary::after {
    content: '';
    position: absolute;
    top: 0; left: -100%;
    width: 50%; height: 100%;
    background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
    transform: skewX(-15deg);
    animation: btn-shimmer 5s ease-in-out infinite 2s;
}

.button-outline-white {
    background: transparent;
    color: rgba(255,255,255,0.85);
    padding: 13px 26px;
    border-radius: 6px;
    border: 1px solid rgba(255,255,255,0.25);
    font-family: var(--font-body);
    font-weight: 500;
    font-size: var(--text-label);
    cursor: pointer;
    transition: border-color 0.18s, color 0.18s, background 0.18s;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}
.button-outline-white:hover {
    background: rgba(255,255,255,0.07);
    border-color: rgba(255,255,255,0.45);
    color: var(--white);
}
.button-outline-white:active { transform: scale(0.97); transition-duration: 0.08s; }


/* ═══════════════════════════════════════════════
   SECTION LAYOUT UTILITIES
   ═══════════════════════════════════════════════ */

.page { display: flex; flex-direction: column; flex: 1; }
.main-content { flex: 1; }
.background-color-1 { background: var(--cream); }
.background-color-2 { background: var(--white); }

.centered-grid {
    display: grid;
    gap: var(--space-gap-md);
    padding: var(--space-section-sm) 80px;
    max-width: 1280px;
    margin: 0 auto;
    width: 100%;
}
.grid-same        { grid-template-columns: 1fr 1fr; }
.grid-wider-right { grid-template-columns: 1fr 3fr; }
.grid-wider-left  { grid-template-columns: 3fr 1fr; }

.grid-element {
    background: transparent;
    border: none;
    border-radius: 0;
    overflow: visible;
}
.grid-element-content {
    padding: 8px 0 8px 28px;
    border-left: 2px solid rgba(var(--accent-rgb),0.25);
    margin: 0;
}
.grid-element-content h2 {
    font-size: var(--text-h3);
    color: var(--ink);
    margin-bottom: 14px;
}
.grid-element-content h2 a { color: var(--ink); transition: color 0.15s; }
.grid-element-content h2 a:hover { color: var(--accent-text); }
.grid-element-content p { color: var(--text-muted); line-height: 1.75; font-size: var(--text-body); }

.section-eyebrow {
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--accent-text);
    font-weight: 500;
    font-size: var(--text-label);
    margin-bottom: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: var(--font-body);
}

/* Light, widely-tracked meta/byline text (order meta, pickup time,
   timestamps), the same "airy caption" treatment as .section-eyebrow's
   kicker labels but for lowercase running text instead of all-caps. */
.text-meta {
    font-weight: 300;
    letter-spacing: 0.03em;
}

/* ═══════════════════════════════════════════════
   MENU CATEGORY PREVIEW TILES (home page)
   ═══════════════════════════════════════════════ */

.domain-section-header {
    padding: var(--space-section-sm) 80px 40px;
    border-top: 1px solid var(--border);
    background: var(--white);
}
.domain-section-header-inner {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 20px;
}
.domain-section-header h2 {
    font-size: var(--text-h2);
    color: var(--ink);
    margin-top: 8px;
}
.domain-section-header .section-eyebrow { color: var(--accent-text); }
.domain-section-header-inner .section-eyebrow { justify-content: center; text-align: center; }

.domain-strip {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-gap-sm);
    padding: 32px 80px 72px;
    background: var(--white);
    border-bottom: 1px solid var(--border);
}
/* Scoop Stop has 5 category tiles (Big Tubs split into 500ml/1.5L) where
   every other page using .domain-strip has 4 - a straight 5-across row
   left tiles cramped/cut off at typical desktop widths, so this stacks
   them 2-2-1 instead. Scoped so Yazol's tile count/layout isn't affected.
   Gated to min-width: 1101px (just above the existing 1100px breakpoint
   below) on purpose: #page-scoopstop-home .domain-strip has higher
   specificity than the plain .domain-strip used inside every @media rule
   below, so left unguarded it silently overrode the 768px/480px mobile
   column counts too, forcing 2 columns (and cut-off, overflowing tile
   images) all the way down to phone widths regardless of what those
   breakpoints said. */
@media (min-width: 1101px) {
    #page-scoopstop-home .domain-strip { grid-template-columns: repeat(2, 1fr); }
}
/* The 5th tile is the odd one out in a 2-column grid - span both columns
   and size to its own content instead of stretching full-width, so it
   sits centered under the two rows above it. */
#page-scoopstop-home .domain-strip .domain-tile:last-child {
    grid-column: 1 / -1;
    justify-self: center;
}

.domain-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    text-decoration: none;
    padding: 12px 12px 8px;
    background: transparent;
    border-radius: 20px;
    transition: background 0.22s, transform 0.22s;
    cursor: pointer;
}
.domain-tile:hover { background: rgba(var(--accent-rgb),0.08); transform: translateY(-4px); }

.domain-tile-img {
    width: 320px;
    height: 320px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    margin-bottom: 14px;
    flex-shrink: 0;
}
/* mix-blend-mode: multiply sits a photo's own white/light studio
   background directly on top of this white/cream section's real
   background - anywhere the photo is white, multiplying against a
   matching white page leaves it visually invisible, so a plain product
   photo reads as a transparent-background cutout without needing a
   separate asset. Only works because this section's own background is
   solid (see .domain-strip below) and nothing opaque sits between the
   img and it. */
/* No mix-blend-mode: multiply (dropped 2026-08-29) - this now sits on
   --oat-milk/periwinkle, and multiplying a photo's pixels against a
   saturated blue backdrop tints/darkens the whole photo toward that
   blue instead of just erasing the studio-white background, same
   fix and same reasoning as .menu-flavor-photo img elsewhere in this
   file. Also sidesteps a real hover glitch: with the blend mode still
   on, .domain-tile:hover's own background/transform change altered
   the blend compositing during the transition, reading as the whole
   tile suddenly darkening on hover rather than just scaling up. */
.domain-tile-img img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 8px 16px rgba(0,0,0,0.16));
    transition: transform 0.3s ease-out, filter 0.3s ease-out;
}
/* Burgundy glow on hover, not a darken - stacked on top of the
   always-on black drop-shadow (filter is replaced wholesale, not
   merged, so the base shadow has to be repeated here). Same stacked-
   drop-shadow glow language as .nav-link-highlight elsewhere in this
   file, just applied to a photo instead of a text underline.
   --chocolate-rgb (burgundy), not --accent-rgb (periwinkle) - this
   sits on the periwinkle --oat-milk card, and a periwinkle glow there
   is nearly invisible against its own near-identical backdrop color;
   burgundy is the one that actually contrasts. */
.domain-tile:hover .domain-tile-img img {
    transform: scale(1.06) translateY(-4px);
    filter: drop-shadow(0 8px 16px rgba(0,0,0,0.16))
            drop-shadow(0 0 14px rgba(var(--chocolate-rgb), 0.55))
            drop-shadow(0 0 30px rgba(var(--chocolate-rgb), 0.35));
}

.domain-tile-foot {
    padding: 0;
    border: none;
    background: transparent;
    min-height: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.domain-tile-label {
    font-family: 'MaryKate', sans-serif;
    font-weight: 600;
    /* Not a real heading (this is a <span> caption under a home-page
       category photo) - was just reusing --text-h3 for convenience.
       Decoupled to its own literal value so bumping --text-h3 for the
       Montserrat heading treatment doesn't resize this too. */
    font-size: 27px;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink);
    line-height: 1.3;
    text-align: center;
    max-width: 260px;
    transition: color 0.2s;
}
.domain-tile:hover .domain-tile-label { color: var(--accent-text); }


/* ═══════════════════════════════════════════════
   GALLERY GRID (home page)
   ═══════════════════════════════════════════════ */

/* Bare-base flip to --chocolate, same as .about-section/.name-story -
   used by Heritage's and Market's non-staff teaser galleries (no
   multiply-blend photos, plain object-fit: cover) plus Yazol's home
   page (already chocolate via its own yazol.css rule, now redundant
   but harmless) and Scoop Stop's home page, pinned back to its
   original --cream/--ink in scoopstop.css. This one was actually
   missed in the neutral-pages pass despite that turn's report
   claiming it was done - caught and fixed here while touching the
   same selector for Scoop Stop's own insulation. */
.gallery-section {
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
    padding: 32px 80px 80px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.gallery-section .domain-section-header-inner {
    padding: 40px 0 24px;
}
.gallery-grid {
    max-width: 1280px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--space-gap-sm);
}
.gallery-tile {
    border-radius: 12px;
    overflow: hidden;
    aspect-ratio: 4 / 3;
    box-shadow: var(--shadow);
}
.gallery-tile img { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform 0.4s ease-out; cursor: zoom-in; }
.gallery-tile:hover img { transform: scale(1.06); }

/* Click a gallery photo to see it full-size, since the grid crops
   every tile to a fixed aspect ratio and cuts off real detail. */
.lightbox-overlay {
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 1200;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.85);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}
.lightbox-overlay.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.2s ease;
}
.lightbox-overlay img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 8px;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
    transform: scale(0.96);
    transition: transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.lightbox-overlay.is-open img { transform: scale(1); }
.lightbox-close {
    position: fixed;
    top: 20px;
    right: 24px;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.12);
    color: var(--white);
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
}
.lightbox-close:hover { background: rgba(255, 255, 255, 0.22); }
.lightbox-nav {
    position: fixed;
    top: 50%;
    transform: translateY(-50%);
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    border: none;
    background: rgba(255, 255, 255, 0.12);
    color: var(--white);
    font-size: 30px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
}
.lightbox-nav:hover { background: rgba(255, 255, 255, 0.22); }
.lightbox-prev { left: 12px; }
.lightbox-next { right: 12px; }
.lightbox-counter {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    color: rgba(255, 255, 255, 0.85);
    font-size: 14px;
    letter-spacing: 0.04em;
    z-index: 1;
}


/* ═══════════════════════════════════════════════
   HERITAGE TOPIC PICKER  -  shared layout for the three standalone Yazol
   Heritage / Yazol Culture / Yazol Music pages (heritage_page.html). Back
   to the menu pages' tab-strip + one-topic-at-a-time pattern (render_tabs,
   .menu-category, site.js's generic tab-group handler) rather than the
   earlier continuous scrolling timeline - on request, so a visitor picks
   a topic instead of scrolling past every one. Restyled specifically for
   this page so it doesn't read as "another shop menu": circular photos,
   label above rather than below, no card background behind the strip -
   just sitting on the page's own --chocolate, right under the hero. ═══ */
/* Only rendered when a page has zero topics at all (no picker strip to
   sit on), so it needs its own --chocolate backdrop to stay continuous
   with the hero above it - same reasoning as .menu-category, just for
   the case where there's nothing to put in one yet. */
.heritage-empty-section {
    background: var(--chocolate);
    padding: 64px 40px;
    border-bottom: 1px solid var(--border);
}
.heritage-empty-note {
    text-align: center;
    color: rgba(255,255,255,0.6);
    font-size: var(--text-body);
}
/* --chocolate, not transparent - the strip sits on the bare white body
   between the hero and .menu-category (both --chocolate in their own
   right), so "no background" means no separate card/pill behind the
   circles, not literally see-through to that white gap. This keeps the
   burgundy backdrop continuous from the hero straight through to the
   topic detail below. */
.page-heritage-family .menu-browse-strip {
    background: var(--chocolate);
    border: none;
}
.page-heritage-family .menu-browse-inner {
    padding: 0 40px 40px;
    gap: 32px;
}
.page-heritage-family .menu-cat-tab {
    width: 108px;
    gap: 10px;
    flex-direction: column-reverse;
}
.page-heritage-family .menu-cat-tab-photo {
    width: 92px;
    height: 92px;
    border-radius: 50%;
    overflow: hidden;
    box-shadow: 0 0 0 2px rgba(255,255,255,0.22);
    transition: box-shadow 0.15s ease, transform 0.15s ease;
}
.page-heritage-family .menu-cat-tab.is-active .menu-cat-tab-photo { box-shadow: 0 0 0 3px var(--oat-milk); }
.page-heritage-family .menu-cat-tab-photo img {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    object-fit: cover;
    filter: none;
}
.page-heritage-family .menu-cat-tab:hover .menu-cat-tab-photo img,
.page-heritage-family .menu-cat-tab:hover .menu-cat-tab-photo { filter: none; }
.page-heritage-family .menu-cat-tab-name {
    font-family: var(--font-body);
    font-size: 12.5px;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: rgba(255,255,255,0.8);
}
.page-heritage-family .menu-cat-tab.is-active .menu-cat-tab-name { color: var(--oat-milk); }
/* Every menu page's .menu-category is already --chocolate at the base
   level (see MENU PAGE below) - this page just adds the topic layout
   inside it, no background/padding override needed. */
.heritage-topic-detail {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-items: center;
    gap: var(--space-gap-lg);
}
/* A topic with no photos yet (just created, nothing uploaded) skips the
   media column entirely rather than leaving a blank grid cell - its text
   just runs full width instead. */
.heritage-topic-detail.no-media { grid-template-columns: 1fr; max-width: 640px; margin-left: auto; margin-right: auto; }

/* Also carries the .gallery-grid class (for the lightbox JS's generic
   grid.querySelectorAll('.gallery-tile img') hookup) - display/max-width/
   margin/grid-template-columns reset here since they'd otherwise inherit
   .gallery-grid's own 4-column grid layout, which this collage isn't. */
.heritage-photo-cluster {
    display: block;
    max-width: none;
    margin: 0;
}
.heritage-photo-featured {
    position: relative;
    padding: 0 22px 22px 0;
}
.heritage-photo-primary {
    aspect-ratio: 4 / 3;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: var(--shadow-hover);
}
.heritage-photo-primary img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.heritage-photo-accent {
    position: absolute;
    right: 0;
    bottom: 0;
    width: 46%;
    aspect-ratio: 4 / 3;
    border-radius: 12px;
    overflow: hidden;
    border: 5px solid var(--chocolate);
    box-shadow: var(--shadow-hover);
    transform: rotate(-4deg);
    z-index: 1;
}
.heritage-photo-accent img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
/* An admin can add as many extra photos to a topic as they like (see
   /admin/heritage, /admin/culture, /admin/music) - anything past the
   featured pair above shows here as a plain thumbnail strip instead of
   being hidden, so nothing an admin uploads goes missing from the
   public page. All of it, featured pair included, shares one
   .gallery-grid/.gallery-tile set (see the JSDoc-style comment on
   .heritage-photo-cluster), so the lightbox pages through every photo
   on the topic regardless of which row it's clicked from. */
.heritage-photo-more-strip {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 14px;
}
.heritage-photo-more {
    width: 64px;
    height: 64px;
    flex-shrink: 0;
    border-radius: 8px;
    overflow: hidden;
    box-shadow: var(--shadow);
}
.heritage-photo-more img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }

.heritage-entry-tag {
    display: inline-block;
    font-size: var(--text-label);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: #0B0A0E;
    background: #F0E68C;
    padding: 4px 10px;
    border-radius: 100px;
    margin-bottom: 16px;
}
.heritage-entry-content h2 {
    font-size: var(--text-h2);
    color: rgba(255,255,255,0.92);
    margin-bottom: 14px;
}
.heritage-entry-content p {
    color: rgba(255,255,255,0.68);
    font-size: var(--text-body);
    line-height: 1.75;
}
.heritage-card-source {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin-top: 16px;
    font-weight: 600;
    font-size: var(--text-body);
    color: var(--spicy-red-text);
    text-decoration: none;
}
.heritage-card-source:hover { color: var(--white); text-decoration: underline; }

/* Previous/Next between topics within one Heritage/Culture/Music page
   (Axum -> Lalibela -> ..., not between the Heritage/Culture/Music pages
   themselves). Buttons, not links - clicking one re-triggers the same
   tab-activate JS the .menu-cat-tab strip uses (see site.js), since a
   topic isn't its own page, just a hidden/shown .menu-category section.
   Shares .menu-category-inner's 1100px column so it lines up with the
   topic content above it; the surrounding <section> already supplies the
   --chocolate background and side padding, so no background/padding of
   its own is needed here beyond top spacing. */
.heritage-topic-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 24px;
    margin-top: 40px;
    padding-top: 24px;
    border-top: 1px solid var(--border);
}
.heritage-topic-nav-btn {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    background: none;
    border: none;
    padding: 0;
    font-family: inherit;
    cursor: pointer;
    text-decoration: none;
    color: rgba(255,255,255,0.92);
    transition: opacity 0.15s ease;
}
.heritage-topic-nav-btn:hover { opacity: 0.75; }
.heritage-topic-nav-next { margin-left: auto; text-align: right; }
.heritage-topic-nav-arrow {
    font-size: 22px;
    line-height: 1;
    color: var(--spicy-red-text);
}
.heritage-topic-nav-text {
    display: flex;
    flex-direction: column;
    font-weight: 600;
    font-size: var(--text-body);
    text-align: left;
}
.heritage-topic-nav-next .heritage-topic-nav-text { text-align: right; }
.heritage-topic-nav-label {
    font-size: var(--text-label);
    font-weight: 500;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255,255,255,0.5);
}


/* ═══════════════════════════════════════════════
   NAME STORY  -  placeholder block for "what Yazol means"
   ═══════════════════════════════════════════════ */

/* Bare .name-story only ever renders on Our Story (its own instance)
   and, via the #page-landing override below, the landing page - never
   Scoop Stop - so no pin-back needed here either. */
.name-story {
    background: var(--chocolate);
    padding: var(--space-section) 80px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    text-align: center;
}
.name-story-inner { max-width: 720px; margin: 0 auto; }
.name-story h2 {
    font-size: var(--text-h2);
    color: rgba(255,255,255,0.92);
    margin-bottom: 24px;
}
.name-story-text {
    color: rgba(255,255,255,0.68);
    font-size: var(--text-body);
    line-height: 1.8;
}


/* ═══════════════════════════════════════════════
   ABOUT / STORY SECTIONS  -  photo-left / photo-right
   ═══════════════════════════════════════════════ */

/* .about-section only ever appears on Our Story and, via the
   .section-bg-wheat variant a few rules down, the landing page's
   Market teaser - never on a Scoop Stop page - so this is a plain
   base-level flip with no Scoop Stop pin-back needed. Page-level:
   both stripes collapse onto one --chocolate rather than keeping an
   odd/even split, matching how .menu-category did the same for
   Yazol's card-level sections. */
.about-section {
    padding: var(--space-section) 80px;
    border-bottom: 1px solid var(--border);
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
}
.about-inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    gap: var(--space-gap-lg);
    align-items: center;
}
.about-inner.photo-right { grid-template-columns: 1fr 1fr; }
.about-inner.photo-left  { grid-template-columns: 1fr 1fr; }
.about-inner.photo-left .about-photo-wrap { order: -1; }
.about-text h2 {
    font-size: var(--text-h2);
    color: rgba(255,255,255,0.92);
    margin-bottom: 20px;
    margin-top: 10px;
}
.about-text p { color: rgba(255,255,255,0.68); line-height: 1.8; font-size: var(--text-body); margin-bottom: 14px; }
.about-text p:last-child { margin-bottom: 0; }
/* border-left and .about-link below both used to reference var(--accent)
   directly - fine on the old white/cream background, but --accent only
   measures ~2.13:1 against the section's new --chocolate (fails even
   the 3:1 non-text minimum). --spicy-red-text clears 4.98:1. */
.about-text blockquote {
    border-left: 3px solid var(--spicy-red-text);
    padding-left: 18px;
    margin: 20px 0;
    font-style: italic;
    color: rgba(255,255,255,0.92);
    font-size: var(--text-body);
    line-height: 1.7;
}
.about-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 20px;
    font-weight: 700;
    font-size: var(--text-body);
    color: var(--spicy-red-text);
    text-decoration: none;
    transition: color 0.15s, gap 0.15s;
}
/* Same --accent-on-chocolate contrast fix as the blockquote/link
   above, for the "Two concepts, one family" / "Buna" kicker labels. */
.about-text .section-eyebrow { color: var(--spicy-red-text); }
.about-link::after { content: '→'; transition: transform 0.15s; }
/* var(--accent-hover-dark) darkened further on hover - correct on a
   light page (Our Story's old white/cream), backwards on --chocolate,
   where it just fades toward invisible. White reads unambiguously as
   "brighter" instead. */
.about-link:hover { color: var(--white); gap: 10px; }
.about-link:hover::after { transform: translateX(4px); }

.about-photo-wrap {
    border-radius: 14px;
    overflow: hidden;
    height: 380px;
    box-shadow: var(--shadow);
}
.about-photo-wrap img { width: 100%; height: 100%; object-fit: cover; display: block; }


/* ═══════════════════════════════════════════════
   HOME PAGE  -  clean, full-bleed sections; a shared photo
   backdrop carries the hero, and gold/purple accents thread
   through the content below.
   ═══════════════════════════════════════════════ */

#page-landing .logo-split {
    /* Pulls the section up underneath the sticky transparent nav (nav
       has no background of its own anymore), so this photo is the
       backdrop for both the nav AND the open space above the panels,
       nothing separate for the two to collide with. Padding
       compensates for the reclaimed nav height plus a bit of
       breathing room, so the panels land in the same spot as before. */
    margin-top: -175px;
    padding-top: 110px;
    min-height: 130vh;
    /* Solid fallback behind the photo: paints instantly before the
       image loads, and (just as load-bearing) it's what site.js's
       nav-contrast sampler actually reads, since a `background-image`
       alone has no computed background-color for it to find and would
       fall through to the page's white and wrongly light up the nav. */
    background-color: #0B0A0E;
    /* Image itself is an inline style on the element now (site_image_url()
       in home.html), so it's admin-replaceable from /admin/site-images. */
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
}

@media (max-width: 768px) {
    /* Stacked pair centered as one block, filling the full screen so
       the next section only appears once the visitor actually scrolls
       (100svh - the "small viewport height" unit - guarantees this
       fills the visible area even in the worst case, mobile browser
       chrome like the address bar showing at its largest). The base
       rule's margin-top: -175px pulls this section up so its photo
       shows through behind the transparent nav, but nav only reserves
       70px of flow space for it - so that pull also drags the *next*
       section up by the difference (105px), which a plain 100svh
       doesn't account for. Adding that 105px back to min-height is
       what actually pins the next section to just past one screen.
       Panels size to their own content (no flex:1 stretch-to-fill) so
       they sit close together instead of each claiming half the
       screen regardless of how big the circles actually are. */
    #page-landing .logo-split { min-height: calc(100svh + 105px); display: flex; flex-direction: column; justify-content: center; }
    #page-landing .logo-panel { min-height: 0; }
}

/* Landing page content sections used to each take a genuinely
   different bespoke color as their own background (a leftover from an
   earlier palette this file's own comments never quite matched
   either - see the color audit). Brought in line with the site-wide
   Chocolate/Oat Milk/Spicy Red direction instead: every one of these
   is page-level copy (a photo + a button, or a heading + a
   paragraph), so they all collapse onto the same --chocolate as
   everywhere else rather than keeping their old one-off hues. */
#page-landing .section-bg-wheat,
#page-landing .section-bg-blue {
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
}
/* This button used to be a one-off chartreuse fill with black text,
   unrelated to --accent - removed so it falls back to the standard
   .button-primary (--accent / --accent-contrast) like every other
   button on the site. */

#page-landing .name-story {
    background: var(--chocolate);
    border-color: transparent;
}
#page-landing .name-story .section-eyebrow { color: var(--spicy-red-text); }
#page-landing .name-story h2 { color: #E9D6AA; }
#page-landing .name-story-text { color: rgba(255,255,255,0.68); }


/* ═══════════════════════════════════════════════
   LOGO SPLIT  -  landing hero: two full-logo click targets
   ═══════════════════════════════════════════════ */

.logo-split {
    position: relative;
    overflow: hidden;
    display: grid;
    grid-template-columns: 1fr 1fr;
}
.logo-panel {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px 16px;
    min-height: 0;
}
.logo-panel-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: clamp(280px, 44vw, 600px);
    max-width: 100%;
    transition: filter 0.2s ease, transform 0.15s ease;
}
.logo-panel-button img {
    width: 100%;
    height: auto;
    object-fit: contain;
}
.logo-panel-dark .logo-panel-button:hover,
.logo-panel-dark .logo-panel-button:focus-visible,
.logo-panel-scoop .logo-panel-button:hover,
.logo-panel-scoop .logo-panel-button:focus-visible {
    filter: drop-shadow(0 0 16px rgba(176,224,230,0.9));
    transform: scale(1.03);
}
.logo-panel-button:active {
    transform: scale(0.97);
    transition: transform 0.1s ease, filter 0.1s ease;
}


/* ═══════════════════════════════════════════════
   MOMENT SECTION  -  heritage / ceremony block
   ═══════════════════════════════════════════════ */

.moment-section {
    background: var(--white);
    padding: var(--space-section) 80px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
/* Same "adjacent sections each add their own padding" problem the tab-strip
   comment above describes: the Yazol Coffee home page runs its gallery
   straight into this heritage teaser, so .gallery-section's own bottom
   padding plus this section's full top padding would stack into a
   176px gap - pull this side in to the denser section size instead. */
#page-yazol-home .gallery-section + .moment-section {
    padding-top: var(--space-section-sm);
}
.moment-inner {
    max-width: 1200px;
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-gap-lg);
    align-items: center;
}
.moment-text {
    text-align: center;
}
.moment-text .section-eyebrow { justify-content: center; }
.moment-text h2 {
    font-size: var(--text-h2);
    color: var(--ink);
    margin-bottom: 20px;
    margin-top: 10px;
    line-height: 1.1;
}
.moment-text p {
    color: var(--text-muted);
    line-height: 1.8;
    font-size: var(--text-body);
    margin-bottom: 14px;
}
.moment-text p:last-child { margin-bottom: 0; }
.moment-photo { border-radius: 14px; overflow: hidden; box-shadow: var(--shadow); }
.moment-photo img { width: 100%; height: auto; display: block; }

/* Simplified landing teaser: a single photo and one CTA button, no
   eyebrow/heading/paragraph copy. Heritage and Market both dropped
   their supporting text down to just this, so they now share the
   exact same shape rather than each getting their own variant. */
.teaser-simple {
    max-width: 640px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 36px;
    text-align: center;
}
.teaser-simple-photo {
    width: 100%;
    aspect-ratio: 3 / 2;
    border-radius: 16px;
    overflow: hidden;
    box-shadow: var(--shadow);
}
.teaser-simple-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }




/* ═══════════════════════════════════════════════
   REVIEWS  -  Google reviews teaser, sits right before
   the Visit Us CTA
   ═══════════════════════════════════════════════ */

/* .reviews-section only renders on the landing page - no Scoop Stop
   usage, so bare base-level flip, same as .about-section/.name-story
   above. The "Thank you for supporting us." h2 inside .domain-section-
   header-inner has no color rule of its own here (it's not wrapped by
   .domain-section-header, which does), so the container `color`
   fallback below is what actually flips it, same gap Yazol's
   .gallery-section h2 had. */
.reviews-section {
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
    padding: 32px 80px 80px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}
.reviews-section .domain-section-header-inner { padding: 40px 0 8px; flex-direction: column; align-items: center; gap: 20px; }
.reviews-section .section-eyebrow { color: var(--spicy-red-text); margin-bottom: 0; margin-top: 20px; font-size: 17.55px; justify-content: center; text-align: center; }
.reviews-thankyou { font-size: 37.4px; color: var(--scoop-cream); letter-spacing: 0.06em; word-spacing: -0.14em; text-align: center; margin-bottom: 24px; }
.reviews-thankyou-break { display: none; }
.reviews-cta {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 14px;
}
.reviews-cta-text {
    font-family: var(--font-body);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--spicy-red-text);
    font-size: 17.55px;
}

.reviews-summary {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 0 0 8px;
}
.reviews-summary-text { color: rgba(255,255,255,0.68); font-size: var(--text-body); font-weight: 500; }
.reviews-summary-rating { color: rgba(255,255,255,0.68); font-size: var(--text-rating); font-weight: 700; }
@media (max-width: 480px) {
    .reviews-summary-text-line2 { flex-basis: 100%; text-align: center; color: var(--white); }
}

.reviews-stars {
    --rating: 5;
    position: relative;
    display: inline-block;
    font-size: var(--text-rating);
    font-weight: 700;
    line-height: 1;
    /* Empty-star underlayer: was var(--border) (a dark, ink-based
       rgba) which would have gone almost invisible against
       --chocolate - a light, low-opacity white reads as the same
       "faint outline" role instead. The filled ::after layer below is
       Google's own star yellow, already ~8.4:1 against chocolate,
       untouched. */
    color: rgba(255,255,255,0.25);
    white-space: nowrap;
}
.reviews-stars::before { content: "★★★★★"; }
.reviews-stars::after {
    content: "★★★★★";
    position: absolute;
    top: 0;
    left: 0;
    width: calc(var(--rating) / 5 * 100%);
    overflow: hidden;
    color: #FBBC04;
}
.reviews-stars-sm { font-size: var(--text-rating); margin-bottom: 12px; }

/* One-at-a-time carousel, manual navigation only (no autoplay - a
   timed auto-swipe was distracting, per explicit feedback). site.js
   moves .reviews-track by setting its transform directly; this file
   only supplies the transition and the static box/layout. */
.reviews-carousel {
    position: relative;
    max-width: 640px;
    margin: 0 auto;
}
.reviews-marquee {
    overflow: hidden;
}
.reviews-track {
    display: flex;
    align-items: flex-start;
    transition: transform 0.5s ease;
}
@media (prefers-reduced-motion: reduce) {
    .reviews-track { transition: none; }
}
/* Sit over the card at reading height (not down by the dots) so
   prev/next land where your eye already is. Pinned at a quarter of
   the way down .reviews-carousel (the current card's height) rather
   than dead-center, since center-of-card lands too low once the
   author row's height is counted in - this keeps it up near the
   quote text instead. */
.reviews-nav-btn {
    position: absolute;
    top: 25%;
    transform: translateY(-50%);
    z-index: 1;
    flex-shrink: 0;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    border: 1px solid rgba(255,255,255,0.3);
    background: rgba(255,255,255,0.08);
    backdrop-filter: blur(2px);
    color: var(--white);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}
.reviews-nav-btn:hover { background: rgba(255,255,255,0.18); }
.reviews-nav-prev { left: 4px; }
.reviews-nav-next { right: 4px; }
.reviews-dots {
    display: flex;
    justify-content: center;
    gap: 8px;
    max-width: 640px;
    margin: 0 auto;
    padding-top: 20px;
}
.reviews-dot {
    width: 8px;
    height: 8px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: rgba(255,255,255,0.3);
    cursor: pointer;
}
.reviews-dot.is-active { background: var(--white); }
.review-slide {
    box-sizing: border-box;
    padding: 0 12px;
}
.review-card {
    background: transparent;
    border-radius: 16px;
    padding: 28px;
    display: flex;
    flex-direction: column;
}
.review-text {
    color: var(--white);
    font-size: var(--text-body);
    line-height: 1.7;
    flex-grow: 1;
    margin-bottom: 20px;
}
.review-author { display: flex; align-items: center; gap: 12px; }
.review-avatar { width: 36px; height: 36px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.review-author-name { display: block; font-weight: 600; font-size: 15.5px; color: var(--white); }
.review-time { display: block; font-size: 14px; color: rgba(255,255,255,0.68); }


/* ═══════════════════════════════════════════════
   MENU PAGE
   ═══════════════════════════════════════════════ */

.menu-browse-strip {
    background: var(--white);
    border-bottom: 1px solid var(--border);
    scroll-margin-top: 90px;
}
.menu-browse-inner {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 40px;
    padding: 56px 80px;
    max-width: 1280px;
    margin: 0 auto;
}
/* Every page using this tab-strip pattern (Yazol/Scoop Stop menus,
   Market, Heritage) has the strip sitting right under the hero text
   now (no grid-landing step in between), so pull both sides of that
   gap in - otherwise the hero's own bottom padding plus this strip's
   top padding stack into a big empty gap. Our Story reuses
   .hero-page-centered too but has no tabs, so it's left alone. */
#page-yazol-menu .hero-page-centered,
#page-scoopstop-menu .hero-page-centered,
#page-market .hero-page-centered { padding-bottom: 24px; }
#page-yazol-menu .menu-browse-inner,
#page-scoopstop-menu .menu-browse-inner,
#page-market .menu-browse-inner { padding-top: 24px; }
/* Heritage/Culture/Music (heritage_page.html, shared by all three - see
   HERITAGE TOPIC PICKER below) sit the circular topic strip right under
   the hero with no strip background/padding of its own to create
   separation, so the hero's bottom gap needs to stay tight here too. */
.page-heritage-family .hero-page-centered { padding-bottom: 16px; }
/* The two menu pages' hero-page-centered now shares the same
   calc(70px + --space-nav-clear) padding-top every other tucked-under-
   nav hero uses (previously a bespoke 90px, its own one-off gap) -
   only padding-bottom stays specially tightened here, tighter than
   Market/Heritage's shared 24px, since these two pages specifically
   want the tab strip sitting closer under the hero text. */
#page-yazol-menu .hero-page-centered,
#page-scoopstop-menu .hero-page-centered { padding-bottom: 12px; }
#page-yazol-menu .menu-browse-inner,
#page-scoopstop-menu .menu-browse-inner { padding-top: 12px; }
.menu-cat-tab {
    display: inline-flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    width: 392px;
    flex-shrink: 0;
    padding: 2px;
    background: none;
    border: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.menu-cat-tab-photo {
    width: 392px;
    height: 392px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.15s ease;
}
.menu-cat-tab:hover .menu-cat-tab-photo { transform: translateY(-4px); }
/* No mix-blend-mode: multiply - same fix, same reasoning as
   .domain-tile-img img above (blue tint against periwinkle, plus the
   hover-darkening glitch). The opacity-based active/inactive fade
   below is unrelated and untouched - that's the deliberate "which
   category is selected" indicator, not a photo-quality issue. */
.menu-cat-tab-photo img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 6px 14px rgba(0,0,0,0.16));
    transition: filter 0.3s ease-out;
}
/* Burgundy glow on hover, not a darken - same stacked-drop-shadow
   language and same --chocolate-rgb-not-periwinkle reasoning as
   .domain-tile-img img above (this sits on periwinkle too). */
.menu-cat-tab:hover .menu-cat-tab-photo img {
    filter: drop-shadow(0 6px 14px rgba(0,0,0,0.16))
            drop-shadow(0 0 12px rgba(var(--chocolate-rgb), 0.55))
            drop-shadow(0 0 26px rgba(var(--chocolate-rgb), 0.35));
}
.menu-cat-tab-name {
    font-family: 'MaryKate', sans-serif;
    font-size: 24px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--ink);
    text-align: center;
    transition: color 0.15s ease;
}
.menu-cat-tab.is-active .menu-cat-tab-name { color: var(--accent-text); }
/* The tab strip stays visible permanently on every page using this
   pattern, so the non-active tabs fade to show which category is
   currently open. */
#page-yazol-menu .menu-cat-tab,
#page-scoopstop-menu .menu-cat-tab,
#page-market .menu-cat-tab { opacity: 0.5; transition: opacity 0.15s ease; }
#page-yazol-menu .menu-cat-tab:hover,
#page-scoopstop-menu .menu-cat-tab:hover,
#page-market .menu-cat-tab:hover { opacity: 0.8; }
#page-yazol-menu .menu-cat-tab.is-active,
#page-scoopstop-menu .menu-cat-tab.is-active,
#page-market .menu-cat-tab.is-active { opacity: 1; }

.menu-category {
    padding: var(--space-section-sm) 80px;
    scroll-margin-top: 90px;
}
/* Burgundy, every brand (2026-08-29, on request) - .menu-category used
   to need three different per-page answers here (each brand's product
   photos rely on mix-blend-mode: multiply to fake a transparent
   cutout, which needs a LIGHT backdrop or the photo crushes toward
   black - see .menu-flavor-photo img below for how that's handled
   now instead). Unified to one bare rule: multiply-blend was dropped
   from .menu-flavor-photo img specifically so photos stay their true
   color on this dark background rather than darkening, which is what
   let this become a single base-level rule instead of the previous
   per-page split. .menu-browse-strip (the category tab-strip just
   above this) deliberately stays --oat-milk/periwinkle - see
   yazol.css/scoopstop.css and the #page-market rule further down -
   its job is showing which category is currently selected, not
   product photography, so it wasn't part of this change. */
.menu-category:nth-child(odd),
.menu-category:nth-child(even) {
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
}
#page-market .menu-browse-strip {
    background: var(--oat-milk);
}
/* --accent-text (dark navy) only clears ~1.6:1 against this section's
   burgundy - same reasoning as every other chocolate-background
   :focus-visible fix in this file. */
.menu-category :focus-visible {
    outline-color: var(--spicy-red-text);
}
.menu-category-inner { max-width: 1100px; margin: 0 auto; }
.menu-category-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    margin-bottom: 32px;
}
.menu-category h2 {
    font-size: var(--text-h2);
    color: var(--scoop-cream);
}
/* --spicy-red-text (periwinkle), not --accent-text - this sits
   directly on the section's burgundy, not on a white card, so it
   needs the text-on-dark token, not the text-on-light one. */
.menu-category-price {
    font-family: 'Montserrat', sans-serif;
    color: var(--spicy-red-text);
    font-weight: 700;
    font-size: 17px;
    white-space: nowrap;
}
.menu-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px 48px;
}
.menu-item {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    padding-bottom: 14px;
    border-bottom: 1px dashed var(--border);
}
.menu-item-photo {
    width: 64px;
    height: 64px;
    border-radius: 10px;
    object-fit: cover;
    flex-shrink: 0;
}
.menu-item-name { font-family: 'MaryKate', sans-serif; font-weight: 600; color: var(--ink); font-size: 22px; letter-spacing: 0.09em; text-transform: uppercase; }
.menu-item-desc { color: var(--text-muted); font-size: var(--text-body); line-height: 1.55; margin-top: 3px; }
.menu-item-price { font-family: 'Montserrat', sans-serif; color: var(--accent-text); font-weight: 700; font-size: 17px; white-space: nowrap; flex-shrink: 0; margin-top: 1px; }


/* ═══════════════════════════════════════════════
   MENU FLAVOR GRID  -  Starbucks-style browse: photo
   + name (+ price, only when the category isn't one
   flat price for every item). Qty/Add to Cart and the
   description are revealed on tap instead of sitting
   on every card.
   ═══════════════════════════════════════════════ */

.menu-flavor-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 56px 40px;
}
.menu-flavor-card { display: flex; flex-direction: column; align-items: center; text-align: center; }
.menu-flavor-toggle {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    width: 100%;
    padding: 0;
    background: none;
    border: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
/* Fluid width (not a fixed px) so the photo fills whatever column the
   auto-fill grid above gives it - on a narrow phone that's one wide
   column, so the photo is naturally much bigger there instead of
   needing a separate shrunken mobile size. max-width caps it so it
   doesn't keep growing past a sensible size on very wide desktops. */
.menu-flavor-photo {
    width: 100%;
    max-width: 312px;
    aspect-ratio: 1 / 1;
    margin: 0 auto;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    flex-shrink: 0;
    transition: transform 0.15s ease;
}
/* No mix-blend-mode: multiply here (unlike .menu-flavor-modal-photo
   img below, which stays on a white card) - this photo now sits
   directly on .menu-category's burgundy, and multiply would crush a
   studio-white-background photo toward near-black against a dark
   backdrop instead of erasing it. Photos stay their true color at the
   cost of not faking a transparent cutout here; the drop-shadow still
   gives them a bit of separation from the background. */
.menu-flavor-photo img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 4px 10px rgba(0,0,0,0.35));
    transition: filter 0.3s ease-out;
}
.menu-flavor-toggle:hover .menu-flavor-photo,
.menu-flavor-toggle[aria-expanded="true"] .menu-flavor-photo {
    transform: translateY(-3px);
}
/* Periwinkle glow on hover/open, not a darken - same stacked-drop-
   shadow language as .domain-tile-img img, but periwinkle (not
   burgundy) here since this photo sits on .menu-category's burgundy,
   the opposite backdrop. Covers both ways this photo is reached:
   render_category's collapsed toggle button (.menu-flavor-toggle,
   also fires while its modal is open) and the Scoop Builder's flavor
   button (.scoop-flavor-btn, no modal - see _scoop_builder.html). */
.menu-flavor-toggle:hover .menu-flavor-photo img,
.menu-flavor-toggle[aria-expanded="true"] .menu-flavor-photo img,
.scoop-flavor-btn:hover .menu-flavor-photo img {
    filter: drop-shadow(0 4px 10px rgba(0,0,0,0.35))
            drop-shadow(0 0 12px rgba(var(--accent-rgb), 0.55))
            drop-shadow(0 0 26px rgba(var(--accent-rgb), 0.35));
}
/* Not a real heading (a <span> card caption, see _menu_category.html) -
   decoupled from --text-h3 to its own literal value, same reasoning as
   .domain-tile-label above. rgba white, not --ink - sits directly on
   .menu-category's burgundy now. */
.menu-flavor-name { font-family: 'MaryKate', sans-serif; font-weight: 600; color: var(--scoop-cream); font-size: 29px; line-height: 1.25; letter-spacing: 0.09em; text-transform: uppercase; }
/* --spicy-red-text (periwinkle) - text-on-dark, same reasoning as
   .menu-category-price above. */
.menu-flavor-price { font-family: 'Montserrat', sans-serif; color: var(--spicy-red-text); font-weight: 700; font-size: 24px; }
/* Item detail opens as a fixed-position modal instead of expanding
   inline, so opening/closing an item never reflows the grid around it. */
.menu-flavor-modal {
    /* Always rendered, faded/hidden via opacity+visibility rather than
       display:none/flex - position:fixed keeps it out of flow while
       hidden, and this is what lets the overlay AND its inner card (below)
       actually transition open instead of snapping in. */
    display: flex;
    position: fixed;
    inset: 0;
    z-index: 1100;
    align-items: center;
    justify-content: center;
    padding: 24px;
    background: rgba(0, 0, 0, 0.45);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, visibility 0s linear 0.2s;
}
.menu-flavor-card.is-open .menu-flavor-modal {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transition: opacity 0.2s ease;
}
.menu-flavor-modal-inner {
    position: relative;
    background: var(--scoop-cream);
    border-radius: 20px;
    padding: 52px 28px 28px;
    width: 100%;
    max-width: 360px;
    max-height: 85vh;
    /* iOS Safari sizes `vh` against the "large" viewport (toolbar
       collapsed), not the space actually visible while its address
       bar/toolbar are showing - the modal's bottom (description, Add to
       order button) could render underneath that toolbar. `dvh` tracks
       the real current viewport and is layered on top since older
       browsers that don't understand it just ignore the line, keeping
       the vh fallback above. */
    max-height: 85dvh;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    text-align: center;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);
    transform: translateY(14px) scale(0.97);
    transition: transform 0.24s cubic-bezier(0.22, 1, 0.36, 1);
}
.menu-flavor-card.is-open .menu-flavor-modal-inner { transform: none; }
.menu-flavor-modal-close {
    position: absolute;
    top: 12px;
    right: 12px;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    border: none;
    background: var(--cream);
    color: var(--ink);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
    z-index: 1;
}
.menu-flavor-modal-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    max-width: 272px;
    aspect-ratio: 1 / 1;
    margin: 0 auto 14px;
}
.menu-flavor-modal-photo img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    display: block;
    filter: drop-shadow(0 4px 10px rgba(0,0,0,0.16));
    mix-blend-mode: multiply;
}
/* Not a real heading (a <p>, see _menu_category.html's modal) - same
   decoupling as .domain-tile-label/.menu-flavor-name above. */
.menu-flavor-modal-name { font-family: 'MaryKate', sans-serif; font-weight: 700; font-size: 29px; color: var(--ink); margin-bottom: 10px; letter-spacing: 0.09em; text-transform: uppercase; }
.menu-flavor-desc { color: var(--text-muted); font-size: var(--text-body); line-height: 1.5; margin-bottom: 14px; }
.menu-flavor-card .menu-item-add { justify-content: center; }
.menu-flavor-card .menu-item-unavailable { margin-top: 0; }

.menu-size-picker-label {
    font-size: var(--text-label);
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 6px;
    text-align: left;
}
.menu-size-picker {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 14px;
}
.menu-size-option {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    text-align: left;
    padding: 10px 14px;
    border: 1.5px solid var(--border);
    border-radius: 12px;
    font-size: 16px;
    color: var(--text-muted);
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}
.menu-size-option-main { display: flex; align-items: center; gap: 8px; }
/* Burgundy, not periwinkle --accent - kept on the site's other accent
   color for this one component (size/flavor picker, shared as-is by
   Yazol, Scoop Stop, and Market - no brand file overrides it), on
   request. --chocolate reads 7.313:1 against the --scoop-cream modal
   card this renders on for every regular menu item (render_category's
   .menu-flavor-modal-inner stays --scoop-cream regardless of the
   section change below) - the Scoop Builder's own size picker is the
   one exception, styled separately just below since it sits directly
   on .menu-category's burgundy instead of a scoop-cream card. */
.menu-size-option input[type="radio"] { accent-color: var(--chocolate); margin: 0; }
.menu-size-option-price { font-family: 'Montserrat', sans-serif; font-weight: 700; color: var(--chocolate); font-size: 18px; }
.menu-size-option:has(input:checked) {
    color: var(--ink);
    font-weight: 600;
    border-color: var(--chocolate);
    background: rgba(var(--chocolate-rgb), 0.06);
}
/* Scoop Builder's size picker sits directly on .menu-category's
   burgundy (no white modal card wraps it, unlike every other item's
   size picker) - --chocolate border/text/radio-fill above would be
   1:1 against that same burgundy, so this scope overrides all four
   properties to a filled periwinkle (--accent) treatment instead, with
   --accent-contrast (near-black, real WCAG-picked) for text so it stays
   readable on the light fill. The checked option adds a periwinkle glow
   on top of the same fill, rather than a different fill/border, so it
   reads as "lit up" against the surrounding burgundy. */
.scoop-builder .menu-size-option {
    color: var(--accent-contrast);
    border-color: var(--accent);
    background: var(--accent);
}
.scoop-builder .menu-size-option input[type="radio"] { accent-color: var(--accent-contrast); }
.scoop-builder .menu-size-option-price { color: var(--accent-contrast); }
.scoop-builder .menu-size-option:has(input:checked) {
    color: var(--accent-contrast);
    border-color: var(--accent);
    background: var(--accent);
    box-shadow: 0 0 10px rgba(var(--accent-rgb), 0.8),
                0 0 22px rgba(var(--accent-rgb), 0.55),
                0 0 40px rgba(var(--accent-rgb), 0.3);
}

.menu-flavor-select {
    display: block;
    width: 100%;
    padding: 10px 14px;
    border: 1.5px solid var(--border);
    border-radius: 12px;
    font-family: var(--font-body);
    font-size: 16px;
    color: var(--ink);
    background: var(--white);
    margin-bottom: 14px;
    cursor: pointer;
}


/* ═══════════════════════════════════════════════
   SCOOP BUILDER  -  Scoop Stop's "Scoops" category:
   choose a size (which fixes how many scoops it comes
   with), then tap flavours up to that count. Mirrors
   the in-store poster's "1. Size  2. Flavour" flow.
   ═══════════════════════════════════════════════ */

/* --scoop-cream, not --ink - always renders inline in .menu-category's
   burgundy (the scoop builder has no white-modal step, unlike the
   regular render_category macro). */
.scoop-step-label {
    font-weight: 700;
    font-size: 20px;
    color: var(--scoop-cream);
    margin: 28px 0 12px;
}
.scoop-builder .menu-category-head + .scoop-step-label { margin-top: 8px; }
.scoop-size-picker { max-width: 420px; }
.scoop-counter { color: rgba(255,255,255,0.68); font-size: 16px; margin-bottom: 20px; }
.scoop-flavor-btn {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 100%;
    padding: 0;
    background: none;
    border: none;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.scoop-flavor-btn:disabled { cursor: not-allowed; opacity: 0.4; }
/* rgba white, not --ink - the count number between the two round
   buttons sits directly on .menu-category's burgundy (the buttons
   themselves stay white-filled below, unaffected). */
.scoop-stepper {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    margin-top: 8px;
    font-weight: 700;
    color: rgba(255,255,255,0.92);
    font-size: 15.5px;
}
.scoop-stepper button {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1.5px solid var(--accent-text);
    background: var(--white);
    color: var(--accent-text);
    font-size: 16.5px;
    line-height: 1;
    cursor: pointer;
}
.scoop-stepper button:disabled { opacity: 0.35; cursor: not-allowed; }
.scoop-builder-form { max-width: 420px; margin-top: 28px; }
.scoop-summary { color: var(--text-muted); font-size: 16px; margin-bottom: 10px; }
.scoop-builder-form .menu-item-add { justify-content: flex-start; margin-top: 0; }

/* Once a size's full scoop count is picked, the Add to order button
   pops up as a fixed bottom bar instead of waiting inline at the end
   of the (often long) flavor grid - picking the last scoop can happen
   near the top of the page, so scrolling all the way down just to
   submit was the friction being fixed here. */
.scoop-builder { padding-bottom: 80px; }
.scoop-sticky-add {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    background: var(--white);
    border-top: 1px solid var(--border);
    box-shadow: 0 -6px 20px rgba(0, 0, 0, 0.1);
    padding: 14px 20px calc(14px + env(safe-area-inset-bottom));
}
.scoop-sticky-add-inner {
    max-width: 1100px;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.scoop-sticky-add .scoop-summary {
    margin: 0;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.scoop-sticky-add .menu-item-add { flex-shrink: 0; }
.scoop-sticky-add-enter,
.scoop-sticky-add-leave { transition: opacity 0.22s ease, transform 0.22s ease; }
.scoop-sticky-add-enter-start,
.scoop-sticky-add-leave-end { opacity: 0; transform: translateY(100%); }
.scoop-sticky-add-enter-end,
.scoop-sticky-add-leave-start { opacity: 1; transform: translateY(0); }


/* ═══════════════════════════════════════════════
   REGISTRATION / CONTACT FORM
   ═══════════════════════════════════════════════ */

.form-section { padding: 0 0 3rem; }
.form-card {
    background: var(--white);
    border: 1.5px solid var(--border);
    border-radius: 14px;
    overflow: hidden;
    max-width: 820px;
    width: 100%;
    margin: 0 auto;
}
.form-card__header {
    padding: 2rem 2.5rem 1.5rem;
    border-bottom: 1px solid var(--border);
    background: var(--cream);
}
.form-card__header h2 {
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: var(--text-h3);
    margin-bottom: 0.4rem;
    color: var(--ink);
    letter-spacing: 0.06em;
    font-style: normal;
}
.form-card__header p { color: var(--text-muted); }
.form-success {
    display: flex; align-items: flex-start; gap: 1rem;
    margin: 1.5rem 2.5rem 0; padding: 1rem 1.25rem;
    background: var(--cream); border: 1.5px solid #FFD700; border-radius: 10px;
}
.form-success strong { display: block; color: var(--accent-text); margin-bottom: 0.2rem; }
.form-success p { color: var(--text-muted); margin: 0; }
.form-error-banner {
    background: #fdecea; border: 1.5px solid #f5c2c4; color: #c0303a;
    border-radius: 8px; padding: 0.75rem 1rem; margin: 1.5rem 2.5rem 0;
}
.hub-form { padding: 2rem 2.5rem; display: flex; flex-direction: column; gap: 1.25rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.25rem; }
.form-group { display: flex; flex-direction: column; gap: 0.35rem; }
.form-group--full { grid-column: 1 / -1; }
.form-group label { font-weight: 600; color: var(--ink); font-size: 15.5px; }
.req { color: var(--accent-text); }
.form-group input,
.form-group select,
.form-group textarea {
    font-family: var(--font-body);
    color: var(--ink);
    background: var(--cream);
    border: 1.5px solid var(--border);
    border-radius: 8px;
    padding: 0.6rem 0.9rem;
    outline: none;
    transition: border-color 0.18s, box-shadow 0.18s;
    /* 16px, not the 15.5px every other body-copy size in this file uses:
       iOS Safari auto-zooms the whole page in on focus for any input
       under 16px, then zooms back out on blur - a jarring, "shaky" jump
       every time someone taps into the checkout/contact form on a
       phone. 16px is the one place that trade-off isn't worth it. */
    width: 100%; resize: vertical; font-size: 16px;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
    border-color: var(--accent-text);
    box-shadow: 0 0 0 3px rgba(var(--accent-rgb),0.14);
    background: var(--white);
}
.form-footer { display: flex; align-items: center; justify-content: space-between; padding-top: 0.75rem; border-top: 1px solid var(--border); }
.form-note { color: var(--text-muted); font-size: var(--text-body); }
.consent-label { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; font-weight: 400; width: 100%; }
.consent-checkbox { flex-shrink: 0; margin-top: 3px; accent-color: var(--accent); width: 16px; height: 16px; }
.consent-text { flex: 1; min-width: 0; color: var(--ink); line-height: 1.6; font-size: var(--text-body); }


/* ═══════════════════════════════════════════════
   SITE FOOTER
   ═══════════════════════════════════════════════ */

/* Bare, site-wide - filled --scoop-cream (beige, swapped from periwinkle
   on request) with --accent-contrast (near-black, real WCAG-picked)
   text, same light-fill treatment as the scoop-builder size picker -
   --accent-contrast reads fine against --scoop-cream too, both being
   light surfaces, so it didn't need to change alongside the background.
   Every accent-colored highlight below still reads --accent-text (a
   darkened periwinkle) instead of --accent itself or --spicy-red-text,
   since both of those are periwinkle-family colors that would nearly
   vanish against a light background generally, --scoop-cream included.
   The cart page keeps the old dark burgundy/white footer (override
   below, via body:has(#page-cart)) - left alone on request. */
.site-footer { background: var(--scoop-cream); border-top: 1px solid rgba(11,10,14,0.1); color: var(--accent-contrast); font-size: 15.5px; font-family: var(--font-body); }
.footer-inner { max-width: 1000px; margin: 0 auto; padding: 52px 80px 36px; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 56px; justify-items: center; }
.footer-directions { display: flex; align-items: center; }
.footer-logo { display: flex; align-items: center; gap: 10px; justify-content: center; text-decoration: none; color: var(--accent-contrast); font-family: var(--font-heading); font-weight: 600; font-size: 29px; letter-spacing: 0.09em; margin-bottom: 16px; text-transform: uppercase; }
.footer-tagline { line-height: 1.65; max-width: 280px; margin: 0 auto 8px; font-size: 16px; }
.footer-initiative { color: var(--accent-text); font-size: 15px; font-weight: 600; letter-spacing: 0.03em; }
.footer-col-heading { color: var(--accent-contrast); font-weight: 500; font-size: var(--text-label); letter-spacing: 0.12em; text-transform: uppercase; margin-bottom: 16px; }
.footer-nav ul { list-style: none; display: flex; flex-direction: column; gap: 10px; }
.footer-nav ul a { color: var(--accent-contrast); text-decoration: none; transition: color 0.15s; font-size: 16px; }
.footer-nav ul a:hover { color: var(--accent-text); }
.footer-partner-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.footer-partner-link { display: inline-flex; color: var(--accent-contrast); text-decoration: none; font-weight: 500; transition: color 0.15s; font-size: 16px; }
.footer-partner-link:hover { color: var(--accent-text); }
.footer-address { color: var(--accent-contrast); line-height: 1.6; margin-bottom: 8px; font-size: 16px; }
.footer-email { color: var(--accent-contrast); text-decoration: none; font-weight: 500; transition: opacity 0.15s; font-size: 16px; }
.footer-email:hover { opacity: 0.75; }
.footer-socials { display: flex; gap: 10px; margin-top: 20px; }
.footer-social-link {
    display: flex; align-items: center; justify-content: center;
    background: rgba(11,10,14,0.08);
    color: var(--accent-contrast);
    transition: background 0.15s, color 0.15s;
}
.footer-social-link:hover { background: var(--accent-contrast); color: var(--accent); }
.footer-bottom { border-top: 1px solid rgba(11,10,14,0.1); max-width: 1200px; margin: 0 auto; padding: 16px 80px 22px; color: var(--accent-contrast); font-size: 15px; justify-content: center; display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.footer-bottom a { color: var(--accent-contrast); text-decoration: none; transition: color 0.15s; }
.footer-bottom a:hover { color: var(--accent-text); }
.footer-credit { font-size: 14.4px; opacity: 0.75; }
.footer-credit a { text-decoration: underline; text-underline-offset: 2px; }

/* Cart is the one page whose footer stays the old dark burgundy/white
   treatment instead of the periwinkle fill above - :has() lets this
   target the footer from body level even though <footer> is a sibling
   of <main id="page-cart">, not its descendant (already relied on
   elsewhere in this file, e.g. .menu-size-option:has(input:checked)).
   Duplicates the pre-periwinkle color set verbatim rather than
   introducing a new token, since nothing else needs these colors now. */
body:has(#page-cart) .site-footer { background: var(--chocolate); border-top-color: rgba(255,255,255,0.06); color: var(--white); }
body:has(#page-cart) .footer-logo { color: var(--scoop-cream); }
body:has(#page-cart) .footer-initiative { color: var(--accent); }
body:has(#page-cart) .footer-col-heading,
body:has(#page-cart) .footer-nav ul a,
body:has(#page-cart) .footer-partner-link,
body:has(#page-cart) .footer-address,
body:has(#page-cart) .footer-email,
body:has(#page-cart) .footer-bottom,
body:has(#page-cart) .footer-bottom a { color: var(--white); }
body:has(#page-cart) .footer-nav ul a:hover,
body:has(#page-cart) .footer-bottom a:hover { color: var(--spicy-red-text); }
body:has(#page-cart) .footer-partner-link:hover { color: var(--accent); }
body:has(#page-cart) .footer-social-link { background: rgba(255,255,255,0.06); color: var(--white); }
body:has(#page-cart) .footer-social-link:hover { background: var(--accent); color: var(--accent-contrast); }
body:has(#page-cart) .footer-bottom { border-top-color: rgba(255,255,255,0.06); }

/* The landing page used to get its own bespoke footer here (a navy
   background plus a local --accent/--accent-contrast override to a
   chartreuse/black pair) - a leftover from the pre-chocolate palette,
   same vintage as the #page-landing .section-bg-wheat/.section-bg-blue
   literals removed in the neutral-pages pass. Missed then because it
   lives in this file's SITE FOOTER section rather than its LANDING
   PAGE section - removed now so the landing footer falls through to
   the plain .site-footer rule above like every other neutral page's
   footer already does. */


/* ═══════════════════════════════════════════════
   CONTACT PAGE
   ═══════════════════════════════════════════════ */
/* Contact and Checkout both used to sit on var(--ink) already (a dark
   page with white text, same shape the rest of this pass is moving
   everything else toward), so this is purely the "one dark surface,
   not two" cohesion move, not a genuine light-to-dark flip. Neither
   page renders for Scoop Stop, so no pin-back needed. */
.contact-page {
    background: var(--chocolate);
    min-height: calc(100vh - 70px);
    padding: var(--space-section) 0 100px;
}
.contact-page-inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 80px;
    display: grid;
    grid-template-columns: 1fr 1.15fr;
    gap: var(--space-gap-lg);
    align-items: start;
}
.contact-info { color: var(--white); padding-top: 8px; }
.contact-info .section-eyebrow { color: var(--spicy-red-text); margin-bottom: 12px; }
.contact-info h1 {
    font-size: var(--text-display);
    color: var(--scoop-cream);
    margin-bottom: 20px;
    line-height: 1.1;
}
.contact-info-sub { color: rgba(255,255,255,0.60); line-height: 1.7; max-width: 380px; margin-bottom: 48px; font-size: var(--text-body); }
.contact-info-address {
    display: flex;
    gap: 14px;
    align-items: flex-start;
    color: rgba(255,255,255,0.75);
    font-size: var(--text-body);
    line-height: 1.7;
    margin-bottom: 32px;
}
.contact-pin { color: var(--spicy-red-text); font-size: 8px; margin-top: 6px; flex-shrink: 0; }
.contact-info-address strong { color: var(--white); display: block; font-weight: 600; }
.contact-info-links { display: flex; flex-direction: column; gap: 8px; }
.contact-info-links a { color: var(--spicy-red-text); font-size: var(--text-body); font-weight: 500; text-decoration: none; letter-spacing: 0.02em; }
.contact-info-links a:hover { text-decoration: underline; }
.contact-info-socials { display: flex; gap: 10px; margin-top: 24px; }

.contact-form-card {
    background: var(--scoop-cream);
    border-radius: 16px;
    padding: 48px;
    box-shadow: 0 24px 80px rgba(0,0,0,0.30);
    min-width: 0;
    overflow: hidden;
}
.contact-form-card h2 {
    font-size: var(--text-h3);
    color: var(--ink);
    margin-bottom: 28px;
}
.contact-form { display: flex; flex-direction: column; }
.form-opt-in { padding: 4px 0 8px; width: 100%; }
.contact-form-footer {
    display: flex;
    align-items: center;
    gap: 20px;
    margin-top: 24px;
    flex-wrap: wrap;
}
.contact-privacy { color: var(--text-muted); font-size: var(--text-body); margin: 0; }
.contact-success {
    text-align: center;
    padding: 40px 20px;
}
.contact-success-icon {
    width: 56px; height: 56px;
    border-radius: 50%;
    background: var(--accent);
    color: var(--accent-contrast);
    font-size: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 24px;
}
.contact-success h2 { margin-bottom: 12px; }
.contact-success p { color: var(--text-muted); max-width: 360px; margin: 0 auto; font-size: var(--text-body); }

/* ═══════════════════════════════════════════════
   RESPONSIVE
   ═══════════════════════════════════════════════ */

@media (max-width: 1100px) {
    .centered-grid          { padding: 48px 48px; }
    .hero-page-text         { padding: calc(70px + var(--space-nav-clear)) 48px 56px 56px; }
    .domain-strip           { grid-template-columns: repeat(2, 1fr); padding: 24px 56px 56px; }
    .domain-tile-img         { width: 240px; height: 240px; }
    .gallery-grid           { grid-template-columns: repeat(3, 1fr); }
    .domain-section-header  { padding: 48px 56px 32px; }
    .logo-panel           { padding: 20px 12px; min-height: 0; }
    .moment-section       { padding: 72px 56px; }
    .name-story           { padding: 72px 56px; }
    .about-section        { padding: 72px 56px; }
    .reviews-section       { padding: 24px 56px 56px; }
    .menu-category          { padding-left: 56px; padding-right: 56px; }
    .menu-browse-inner       { padding: 40px 56px; gap: 28px; }
    .menu-cat-tab            { width: 300px; }
    .menu-cat-tab-photo      { width: 300px; height: 300px; }
    .footer-inner           { padding: 44px 56px 32px; gap: 40px; }
    .footer-bottom          { padding: 14px 56px 20px; }
}

@media (max-width: 768px) {
    /* nav */
    nav.navbar { padding: 0 16px; }
    .nav-left { gap: 8px; }
    .nav-logo img { height: 40px; width: auto; }
    .nav-brand-group { gap: 6px; }
    .nav-brand-text { font-size: 13.5px; }
    .nav-brand-divider { font-size: 19px; }

    /* heroes fill the screen on mobile, same "one full screen" goal as
       #page-landing .logo-split below - but unlike that section, no
       +Npx correction is needed here: .hero-home's margin-top is -70px,
       exactly matching the 70px of flow space the transparent nav
       reserves, so the pull-up cancels the nav's reserve precisely
       rather than overshooting it. A plain 100svh already lands right
       at one screen. Both hero images are portrait (~0.8-0.87 w/h), so
       a taller box scales them up cleanly instead of leaving dead
       space beside them. */
    /* var(--vh100) (site.js/layout heads) wins once JS has run - see
       its comment there for why plain 100svh alone left a burgundy
       sliver visible below the hero on some phones until the first
       scroll. */
    .hero-visual { height: var(--vh100, 100svh); aspect-ratio: unset; min-height: 0; max-height: none; }
    .hero-text { font-size: 15.5px; }
    /* sections */
    .about-section { padding: 56px 24px; }
    .centered-grid { padding: 40px 24px; gap: 20px; }
    /* .photo-left/.photo-right variants below carry their own
       grid-template-columns: 1fr 1fr rule outside this media query,
       and two classes beat this bare .about-inner selector on
       specificity regardless of source order - so without repeating
       the variants here, they'd stay two-column on mobile even
       though .about-inner itself switched to one. Every split
       section site-wide (Our Story pages, Market teaser) that
       stayed cramped/two-column on phones traces back to this. */
    .about-inner,
    .about-inner.photo-left,
    .about-inner.photo-right { grid-template-columns: 1fr; gap: 36px; }
    .about-inner.photo-left .about-photo-wrap { order: 0; }

    /* Heritage/Culture/Music's single-topic view collapses to one column
       (photo above text), and the photo collage's overhang shrinks so it
       doesn't crowd the narrower column. */
    .heritage-topic-detail { grid-template-columns: 1fr; gap: 24px; }
    .heritage-topic-detail.no-media { margin-left: 0; margin-right: 0; }
    .heritage-photo-featured { padding: 0 14px 14px 0; }

    .domain-section-header { padding: 48px 24px 28px; }
    .domain-section-header-inner { gap: 12px; }
    .domain-strip { grid-template-columns: 1fr 1fr; gap: 10px; padding: 24px 24px 48px; }
    .domain-tile-img { width: 150px; height: 150px; }
    .gallery-grid { grid-template-columns: 1fr 1fr; padding: 0 24px; }
    .gallery-section { padding: 24px 0 56px; }
    .gallery-section .domain-section-header-inner { padding: 0 24px 24px; }
    .logo-split { grid-template-columns: 1fr; }
    .logo-panel { padding: 16px 28px; min-height: 0; }
    .logo-panel-button { width: min(340px, 66vw); }
    .moment-inner { grid-template-columns: 1fr; gap: 40px; }
    .moment-section { padding: 56px 24px; }
    .name-story { padding: 56px 24px; }
    .reviews-section { padding: 24px 0 48px; }
    .reviews-section .domain-section-header-inner { padding: 0 24px 4px; }
    .reviews-thankyou-break { display: block; }
    .reviews-summary { padding: 0 24px 4px; }
    .reviews-marquee { padding: 0 24px; }
    .reviews-dots { padding-left: 24px; padding-right: 24px; }
    .hero-page { grid-template-columns: 1fr; }
    .hero-page-photo { height: 220px; order: -1; }
    .hero-page-text { padding: 56px 24px 48px; }

    /* menu/heritage/market tab strip: horizontal and scrollable on
       mobile too, same as desktop - it's a pinned "which category am
       I on" nav, not a one-time landing screen, so it stays compact
       rather than unrolling into a full-screen stacked list. */
    .menu-browse-inner {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        justify-content: flex-start;
        gap: 20px;
        padding: 16px 20px;
    }
    .menu-cat-tab {
        gap: 8px;
        width: 152px;
        padding: 2px;
    }
    .menu-cat-tab-photo { width: 128px; height: 128px; }
    .menu-cat-tab-name { font-size: 19px; text-align: center; }

    .menu-category { padding: 48px 24px; }
    .menu-grid { grid-template-columns: 1fr; }
    .menu-category-head { flex-direction: column; align-items: flex-start; gap: 4px; margin-bottom: 24px; }
    /* Column count/photo size aren't set here on purpose - the base
       auto-fill grid + fluid .menu-flavor-photo width already collapse
       to one wide column on a phone-width screen, giving a bigger
       photo than a hand-picked mobile size would. */
    .menu-flavor-grid { gap: 32px 20px; }

    /* contact */
    .contact-page-inner { grid-template-columns: 1fr; padding: 0 24px; gap: 48px; }
    .contact-form-card { padding: 32px 24px; }

    /* grid */
    .grid-same,
    .grid-wider-right,
    .grid-wider-left { grid-template-columns: 1fr; }
    .grid-element-content { padding-left: 18px; }

    /* form */
    .form-row { grid-template-columns: 1fr; }
    .hub-form { padding: 1.25rem; }
    .form-card__header { padding: 1.25rem 1.25rem 1rem; }
    .form-error-banner, .form-success { margin: 1rem 1.25rem 0; }
    .about-photo-wrap { height: 240px; }
    .footer-inner { grid-template-columns: 1fr; padding: 32px 24px 24px; gap: 28px; justify-items: center; text-align: center; }
    .footer-socials { justify-content: center; }
    .footer-bottom { padding: 12px 24px 18px; }
}

@media (max-width: 480px) {
    nav.navbar { padding: 0 12px; }
    .nav-left { gap: 6px; }
    .nav-logo img { height: 36px; }
    .nav-brand-group { gap: 4px; }
    .nav-brand-text { font-size: 13.5px; }
    .nav-brand-divider { font-size: 17px; }
    .logo-panel { padding: 14px 16px; }
    .logo-panel-button { width: min(240px, 66vw); }
    .form-footer { flex-direction: column; gap: 12px; align-items: stretch; }
    .form-footer .button-primary { width: 100%; justify-content: center; }
    .domain-strip { grid-template-columns: 1fr; }
    .domain-tile-img { width: 220px; height: 220px; }
    .gallery-grid { grid-template-columns: 1fr 1fr; }
    /* Doubled on request - the landing page's "Yazol" name-story
       heading reads too small as a page header at phone width, even
       though --text-h2 itself already scales down via vw at this
       breakpoint. */
    #page-landing .name-story h2 { font-size: calc(var(--text-h2) * 2); }
}


/* ═══════════════════════════════════════════════
   ANIMATIONS
   ═══════════════════════════════════════════════ */

.reveal {
    opacity: 0;
    transform: translateY(28px);
    transition: opacity 0.7s cubic-bezier(0.25,0.46,0.45,0.94),
                transform 0.7s cubic-bezier(0.25,0.46,0.45,0.94);
}
.reveal.visible { opacity: 1; transform: none; }
.reveal-d1 { transition-delay: 0.08s; }
.reveal-d2 { transition-delay: 0.18s; }
.reveal-d3 { transition-delay: 0.28s; }
.reveal-d4 { transition-delay: 0.38s; }

@keyframes btn-shimmer {
    0%   { left: -100%; }
    35%  { left: 160%; }
    100% { left: 160%; }
}

@keyframes toast-fade {
    0%   { opacity: 0; transform: translateY(-10px); }
    8%   { opacity: 1; transform: none; }
    88%  { opacity: 1; transform: none; }
    100% { opacity: 0; transform: none; }
}
.cart-toast {
    position: fixed;
    top: 84px;
    right: 24px;
    z-index: 1200;
    background: var(--ink);
    color: var(--white);
    padding: 12px 20px;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 600;
    line-height: 1.4;
    box-shadow: var(--shadow-hover);
    display: flex;
    align-items: center;
    gap: 8px;
    max-width: calc(100vw - 32px);
    opacity: 0;
    pointer-events: none;
}
.cart-toast.show { animation: toast-fade 2.6s ease forwards; }
/* On a narrow phone a long item name ("Ethiopian Spanish Latte" x a
   size label) can nearly fill the available width - centering the
   toast instead of pinning it to the right edge keeps equal breathing
   room on both sides rather than crowding the right edge specifically,
   and respects the safe area on notched phones in landscape. */
@media (max-width: 480px) {
    .cart-toast {
        left: max(16px, env(safe-area-inset-left));
        right: max(16px, env(safe-area-inset-right));
        top: max(84px, calc(env(safe-area-inset-top) + 70px));
        max-width: none;
        justify-content: center;
        text-align: center;
    }
}
.cart-toast-check { color: var(--accent-hover-light); font-weight: 700; }

/* ═══════════════════════════════════════════════
   NAV CART ICON
   ═══════════════════════════════════════════════ */

.nav-cart {
    position: relative;
    display: flex;
    align-items: center;
    color: var(--scoop-cream);
    margin-left: 12px;
    transition: color 0.15s;
}
.nav-cart:hover { color: var(--nav-highlight); }
nav.navbar.on-light .nav-cart,
nav.navbar.open .nav-cart { color: var(--text-muted); }
nav.navbar.on-light .nav-cart:hover,
nav.navbar.open .nav-cart:hover { color: var(--ink); }
.nav-cart-badge {
    position: absolute;
    top: -7px;
    right: -9px;
    background: var(--accent);
    color: var(--accent-contrast);
    font-size: 10px;
    font-weight: 700;
    min-width: 16px;
    height: 16px;
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 4px;
}


/* ═══════════════════════════════════════════════
   ADD TO CART (menu item rows)
   ═══════════════════════════════════════════════ */

.menu-item-add {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
}
.menu-item-add input[type="number"] {
    width: 52px;
    padding: 8px 6px;
    border: 1.5px solid var(--border);
    border-radius: 9999px;
    font-family: var(--font-body);
    font-size: 16px; /* see .form-group input: keeps iOS from zooming on focus */
    text-align: center;
}
.menu-item-add-btn {
    background: var(--accent);
    color: var(--accent-contrast);
    border: none;
    border-radius: 9999px;
    padding: 10px 22px;
    font-size: 15.5px;
    font-weight: 700;
    cursor: pointer;
    transition: background 0.15s, transform 0.15s;
}
.menu-item-add-btn:active { transform: scale(0.97); }
.menu-item-add-btn:hover { background: var(--accent-hover-light); }
.menu-item-unavailable {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-muted);
    margin-top: 8px;
    display: inline-block;
}


/* ═══════════════════════════════════════════════
   CART PAGE
   ═══════════════════════════════════════════════ */

/* htmx cart updates (qty change, remove) swap #cart-container's whole
   innerHTML - without this it just snaps to the new totals/line count
   instantly, which reads as a flicker rather than an update. Paired
   with swap:/settle: timing on the hx-swap attributes in
   _cart_body.html, this fades the old content out and the new content
   in instead. */
#cart-container { transition: opacity 0.15s ease-out; }
#cart-container.htmx-swapping { opacity: 0; }
#cart-container.htmx-added { opacity: 0; }
#cart-container.htmx-settling { opacity: 1; }

/* Cart: reversed from the rest of the site on request (2026-08-29,
   background moved again the same day from periwinkle to
   --scoop-cream) - light page instead of burgundy, dark ink text
   instead of white, burgundy instead of periwinkle for anything
   that's a button/accent fill. Nav bar and footer stay burgundy,
   untouched - this is scoped to .cart-page only. Every piece of what's really a dense
   transactional list (line items, qty steppers, dividers, totals)
   gets its own flip below rather than one container rule catching it
   all - var(--border)/var(--ink)-family dividers work as-is here
   (this is a light page again, same as most of the site pre-palette-
   pass), it's specifically the burgundy/white pairing that reverses.
   .cart-line-qty-btn also renders inside admin's POS screen
   (admin_new_order.html) - already safe, since .admin-shell
   .cart-line-qty-btn (style.css further down) is a more specific
   selector that keeps its own --a-accent-based styling regardless of
   what this bare rule says. */
.cart-page {
    padding: var(--space-section) 80px 100px;
    max-width: 900px;
    margin: 0 auto;
    background: var(--scoop-cream);
    color: var(--ink);
}
.cart-page h1 { font-size: var(--text-h1); color: var(--ink); margin-bottom: 8px; }
.cart-page-sub { color: var(--text-muted); margin-bottom: 40px; }
.cart-empty { padding: 60px 0; text-align: center; color: var(--text-muted); }
.cart-list { display: flex; flex-direction: column; gap: 0; margin-bottom: 32px; }
.cart-line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    padding: 20px 0;
    border-bottom: 1px solid var(--border);
}
.cart-line-info { flex: 1; min-width: 0; }
.cart-line-name { font-family: 'MaryKate', sans-serif; font-weight: 600; color: var(--ink); font-size: 22px; letter-spacing: 0.09em; text-transform: uppercase; }
/* --chocolate (burgundy), not --spicy-red-text (periwinkle) - that
   token is for accent text sitting on a dark/burgundy page, this one
   is a light scoop-cream page now, so it needs the opposite:
   --chocolate reads 7.313:1 against --scoop-cream. */
.cart-line-brand { font-size: 15px; font-weight: 500; letter-spacing: 0.12em; text-transform: uppercase; color: var(--chocolate); margin-bottom: 2px; display: block; }
.cart-line-note { color: var(--text-muted); font-size: 16px; margin-top: 3px; }
.cart-line-qty { display: flex; align-items: center; gap: 6px; }
.cart-line-qty input[type="number"] {
    width: 40px; padding: 6px 2px; border: 1.5px solid var(--border); border-radius: 6px; text-align: center; font-size: 16px; color: var(--ink); background: transparent; /* keeps iOS from zooming on focus, see .form-group input */
    -moz-appearance: textfield;
}
.cart-line-qty input[type="number"]::-webkit-outer-spin-button,
.cart-line-qty input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
/* Burgundy fill, white icon - reversed from the light oat-milk-on-dark
   chip every other page's version of this button uses, since the page
   itself is the light surface here. */
.cart-line-qty-btn {
    width: 28px; height: 28px; flex-shrink: 0;
    background: var(--chocolate); border: 1.5px solid var(--chocolate); border-radius: 6px;
    font-size: 16.5px; font-weight: 600; cursor: pointer; color: var(--white);
    display: flex; align-items: center; justify-content: center; padding: 0;
    transition: filter 0.15s ease;
}
.cart-line-qty-btn:hover { filter: brightness(1.18); }
.cart-line-price { font-family: 'Montserrat', sans-serif; font-weight: 700; color: var(--ink); width: 70px; text-align: right; flex-shrink: 0; font-size: 17px; }
.cart-line-remove { color: var(--text-muted); font-size: 15px; text-decoration: underline; background: none; border: none; cursor: pointer; padding: 0; }
.cart-summary {
    max-width: 380px;
    margin-left: auto;
    border-top: 2px solid var(--border);
    padding-top: 20px;
}
.cart-summary-row { display: flex; justify-content: space-between; margin-bottom: 10px; color: var(--text-muted); font-size: 15.5px; }
.cart-summary-row.total { color: var(--ink); font-weight: 700; font-size: 18px; border-top: 1px solid var(--border); padding-top: 12px; margin-top: 4px; }
/* Burgundy, not the shared .button-primary's periwinkle fill - same
   "buttons reverse too" reasoning as .cart-line-qty-btn above. */
.cart-summary .button-primary {
    width: 100%;
    justify-content: center;
    margin-top: 20px;
    background: var(--chocolate);
    color: var(--white);
}
.cart-summary .button-primary:hover { background: var(--chocolate); filter: brightness(1.15); box-shadow: 0 8px 24px rgba(var(--chocolate-rgb),0.28); }
.cart-summary .button-primary:active { box-shadow: 0 4px 14px rgba(var(--chocolate-rgb),0.22); }


/* ═══════════════════════════════════════════════
   CHECKOUT PAGE
   ═══════════════════════════════════════════════ */

/* Same cohesion move as .contact-page above (--ink -> --chocolate,
   text already white/rgba-white either way); .checkout-form and
   .checkout-summary stay var(--white), unchanged - they're genuine
   floating cards already, exactly the pattern this whole pass is
   pushing every other page toward. */
.checkout-page { background: var(--chocolate); padding: var(--space-section) 0 100px; min-height: calc(100vh - 70px); }
.checkout-inner { max-width: 1100px; margin: 0 auto; padding: 0 80px; display: grid; grid-template-columns: 1fr 380px; gap: var(--space-gap-lg); align-items: start; }
.checkout-inner h1 { color: var(--white); font-size: var(--text-h1); margin-bottom: 28px; }
.checkout-error { background: #3A1620; border: 1px solid #7A2E3E; color: #F87171; border-radius: 8px; padding: 12px 16px; margin-bottom: 20px; font-size: 15.5px; }
.checkout-form { background: var(--white); border-radius: 14px; padding: 36px; }
.checkout-summary { background: var(--white); border-radius: 14px; padding: 28px; position: sticky; top: 90px; }
.checkout-summary h2 { font-size: var(--text-h3); color: var(--ink); margin-bottom: 18px; }
.checkout-summary-line { display: flex; justify-content: space-between; gap: 12px; padding-bottom: 14px; margin-bottom: 14px; border-bottom: 1px solid var(--border); font-size: 16px; }
.checkout-summary-line .name { font-family: 'MaryKate', sans-serif; font-weight: 600; color: var(--ink); font-size: 21px; letter-spacing: 0.09em; text-transform: uppercase; }
.checkout-summary-line .meta { color: var(--text-muted); font-size: 15px; font-weight: 300; letter-spacing: 0.03em; }
.checkout-summary-row { display: flex; justify-content: space-between; font-size: 15.5px; color: var(--text-muted); margin-bottom: 8px; }
.checkout-summary-row.total { color: var(--ink); font-weight: 700; font-size: 17px; border-top: 1px solid var(--border); padding-top: 12px; margin-top: 8px; }


/* ═══════════════════════════════════════════════
   STRIPE PAYMENT PAGE
   ═══════════════════════════════════════════════ */

/* Genuine light-to-dark flip here (was --cream, not already dark like
   Contact/Checkout). .pay-card stays var(--white) on purpose - Stripe
   mounts its own payment element inside it, styled for a light
   surface, so it needs to stay a real light card rather than follow
   the page down to --chocolate. Not used by Scoop Stop. */
.pay-page { background: var(--chocolate); padding: var(--space-section) 24px 100px; min-height: calc(100vh - 70px); }
.pay-inner { max-width: 480px; margin: 0 auto; }
.pay-inner h1 { font-size: var(--text-h1); color: rgba(255,255,255,0.92); margin-bottom: 6px; }
.pay-order-ref { color: rgba(255,255,255,0.68); font-size: 15.5px; margin-bottom: 24px; }
.pay-secure { display: flex; align-items: center; gap: 8px; color: rgba(255,255,255,0.68); font-size: 16px; margin-bottom: 20px; }
.pay-card { background: var(--white); border-radius: 14px; padding: 28px; box-shadow: var(--shadow); }
.pay-error { background: #fdecea; border: 1.5px solid #f5c2c4; color: #c0303a; border-radius: 8px; padding: 12px 16px; margin-bottom: 16px; font-size: 15.5px; }
#payment-element { margin-bottom: 20px; }
.pay-submit { width: 100%; justify-content: center; }
/* The one link sitting directly on --chocolate here (everything else
   interactive is inside the still-white .pay-card) - a plain sibling
   <p><a> shown only in the stripe_error-without-client_secret branch.
   Its color otherwise comes from the generic `p a { color: var(--accent); }`
   fallback near the top of this file, too broadly used (every card-level
   page on the site) to safely change at the base. */
#page-pay .pay-inner > p > a { color: var(--spicy-red-text); }
#page-pay .pay-inner > p > a:focus-visible { outline-color: var(--spicy-red-text); }


/* ═══════════════════════════════════════════════
   :focus-visible ON --chocolate  -  var(--accent) only clears ~2.13:1
   against --chocolate, short of the 3:1 WCAG minimum for focus
   indicators. Scoped to just the containers actually sitting on
   --chocolate (never to `body`, which would also catch the still-light
   .menu-browse-strip card surface and make focus rings worse there
   instead of better - .menu-category itself has its own bare
   :focus-visible fix now, it's --chocolate everywhere too).
   --spicy-red-text clears 4.98:1 wherever it's used below.
   ═══════════════════════════════════════════════ */
#page-landing .name-story :focus-visible,
#page-landing .section-bg-wheat :focus-visible,
#page-landing .section-bg-blue :focus-visible,
#page-landing .reviews-section :focus-visible,
.page-heritage-family .hero-page-centered :focus-visible,
.page-heritage-family .menu-browse-strip :focus-visible,
.page-heritage-family .gallery-section :focus-visible,
#page-market .hero-page-centered :focus-visible,
#page-market .gallery-section :focus-visible,
#page-our-story .hero-page-centered :focus-visible,
#page-our-story .about-section :focus-visible,
#page-our-story .name-story :focus-visible,
#page-contact .contact-info :focus-visible,
#page-confirmation .confirmation-page :focus-visible {
    outline-color: var(--spicy-red-text);
}
/* --accent-text (dark navy), not --spicy-red-text (periwinkle) -
   .cart-page is a light scoop-cream page now, not burgundy, so it
   needs the light-background focus-ring token instead, same as every
   other light surface on the site. */
#page-cart .cart-page :focus-visible {
    outline-color: var(--accent-text);
}


/* ═══════════════════════════════════════════════
   ORDER CONFIRMATION PAGE
   ═══════════════════════════════════════════════ */

.confirmation-page {
    padding: var(--space-section) 24px 100px;
    text-align: center;
    max-width: 560px;
    margin: 0 auto;
    background: var(--chocolate);
    color: rgba(255,255,255,0.92);
}
/* Solid fill, not text-on-chocolate - unaffected either way. */
.confirmation-icon {
    width: 64px; height: 64px; border-radius: 50%; background: var(--accent); color: var(--accent-contrast);
    font-size: 28px; display: flex; align-items: center; justify-content: center; margin: 0 auto 24px;
}
.confirmation-page h1 { font-size: var(--text-h1); color: rgba(255,255,255,0.92); margin-bottom: 12px; }
.confirmation-page p { color: rgba(255,255,255,0.68); margin-bottom: 6px; }
.confirmation-order-number { font-weight: 700; color: rgba(255,255,255,0.92); }
.confirmation-page .button-primary { margin-top: 28px; }


/* ═══════════════════════════════════════════════
   ADMIN DASHBOARD
   ═══════════════════════════════════════════════ */

.admin-shell {
    /* Light theme: kept as its own scoped token set (not the site's
       global :root tokens) specifically so it stays independently
       tunable from the public site's brand colors - same reasoning as
       before, just re-picked for a white background. Every pairing
       below is real WCAG-computed contrast, not eyeballed: a-text/a-muted
       on a-bg or white panels clear 16.6:1/4.6:1+, white text on
       a-accent clears 4.56:1 - see the two .admin-nav a.active /
       .btn-approve rules below, the only places admin text still sits
       directly on the accent fill rather than a-bg/a-panel. */
    --a-bg:      #F5F5F8;
    --a-panel:   #FFFFFF;
    --a-panel-2: #F0F1F5;
    --a-border:  rgba(17,17,17,0.10);
    --a-text:    #14151F;
    --a-muted:   #6B6E85;
    --a-accent:  #6D5DFB;
    display: flex;
    min-height: 100vh;
    background: var(--a-bg);
    color: var(--a-text);
    font-family: 'Inter', sans-serif;
    font-size: 14px;
}

.admin-sidebar {
    width: 240px;
    flex-shrink: 0;
    background: var(--a-panel);
    border-right: 1px solid var(--a-border);
    display: flex;
    flex-direction: column;
    padding: 20px 14px;
}
.admin-brand { display: flex; align-items: center; gap: 10px; padding: 6px 8px 14px; text-decoration: none; }
.admin-brand img { display: block; flex-shrink: 0; }
.admin-brand span { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 16px; color: var(--a-text); }
.admin-view-site {
    display: flex; align-items: center; justify-content: center; gap: 8px;
    margin: 0 8px 18px; padding: 10px 12px; border-radius: 8px;
    background: var(--a-panel-2); border: 1px solid var(--a-border);
    color: var(--a-text); font-size: 13px; font-weight: 600; text-decoration: none;
    transition: border-color 0.15s, color 0.15s;
}
.admin-view-site:hover { border-color: var(--a-accent); color: var(--a-accent); }
.admin-nav-heading { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--a-muted); padding: 0 12px 6px; margin-top: 18px; }
.admin-nav-heading:first-of-type { margin-top: 4px; }
.admin-nav { list-style: none; display: flex; flex-direction: column; gap: 2px; }
.admin-nav a {
    display: flex; align-items: center; gap: 10px; padding: 12px; border-radius: 8px;
    color: var(--a-muted); font-weight: 500; font-size: 14px; transition: background 0.15s, color 0.15s;
}
.admin-nav a:hover { color: var(--a-text); background: var(--a-panel-2); }
.admin-nav a.active { color: var(--white); background: var(--a-accent); font-weight: 600; }
.admin-nav-section { margin-top: auto; padding-top: 20px; border-top: 1px solid var(--a-border); }
.admin-flow-label { font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--a-muted); padding: 0 12px 10px; }
.admin-flow-steps { list-style: none; display: flex; flex-direction: column; gap: 14px; padding: 0 12px; }
.admin-flow-step { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--a-muted); }
.admin-flow-num {
    width: 20px; height: 20px; border-radius: 50%; border: 1px solid var(--a-border);
    display: flex; align-items: center; justify-content: center; font-size: 11px; flex-shrink: 0;
}

/* Hamburger toggle - hidden on desktop, shown only inside the mobile
   breakpoint below. Same 3-span morph-to-X pattern as nav.navbar's
   .nav-toggle on the public site, kept as a separate class since the
   admin shell has its own component names throughout. */
.admin-nav-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 6px;
    margin-right: 4px;
}
.admin-nav-toggle span {
    display: block; width: 20px; height: 2px; background: var(--a-text);
    border-radius: 2px; transition: transform 0.25s, opacity 0.2s;
}
.admin-shell.sidebar-open .admin-nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.admin-shell.sidebar-open .admin-nav-toggle span:nth-child(2) { opacity: 0; }
.admin-shell.sidebar-open .admin-nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
.admin-sidebar-backdrop { display: none; }

.admin-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.admin-topbar {
    height: 60px; flex-shrink: 0; display: flex; align-items: center; justify-content: space-between;
    padding: 0 32px; border-bottom: 1px solid var(--a-border); gap: 12px;
    /* Sticky so the hamburger toggle (mobile/tablet) and sign-out stay
       reachable while scrolling a long admin page, instead of only being
       reachable by scrolling all the way back to the top. Needs its own
       opaque background since sticky content still scrolls underneath it;
       z-index sits below the mobile sidebar/backdrop (200/190) so an open
       sidebar still layers above it. */
    position: sticky; top: 0; z-index: 100; background: var(--a-panel);
}
.admin-topbar-left { display: flex; align-items: center; min-width: 0; }
.admin-topbar-title { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 16px; color: var(--a-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.admin-topbar-user { display: flex; align-items: center; gap: 18px; flex-shrink: 0; }
.admin-role-badge {
    background: rgba(109,93,251,0.10); color: var(--a-accent); border: 1px solid rgba(109,93,251,0.30);
    font-size: 11px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; padding: 4px 10px; border-radius: 20px;
}
.admin-signout { color: var(--a-muted); font-size: 13px; transition: color 0.15s; }
.admin-signout:hover { color: var(--a-text); }

.admin-content { padding: 32px; flex: 1; min-width: 0; }

/* Quick-jump nav + collapsible sections for long grouped admin pages
   (e.g. /admin/site-images' ~34 tiles across 8 page/section groups) -
   without this, finding one specific photo meant scrolling past every
   other section's tiles first. Sticky just below .admin-topbar so it
   stays reachable while scrolling. */
.a-quicknav {
    position: sticky; top: 60px; z-index: 90;
    display: flex; flex-wrap: wrap; gap: 8px;
    background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 10px;
    padding: 12px; margin-bottom: 24px;
}
.a-quicknav-link {
    display: inline-flex; align-items: center; gap: 6px;
    background: var(--a-panel-2); border: 1px solid var(--a-border); border-radius: 20px;
    padding: 6px 12px; font-size: 13px; font-weight: 600; color: var(--a-text);
    text-decoration: none; transition: border-color 0.15s;
}
.a-quicknav-link:hover { border-color: var(--a-accent); }
.a-quicknav-count { color: var(--a-muted); font-weight: 700; font-size: 11px; }

.a-group { margin-bottom: 16px; border-bottom: 1px solid var(--a-border); padding-bottom: 16px; }
.a-group-summary {
    font-family: 'Syne', sans-serif; font-weight: 700; color: var(--a-text); font-size: 17px;
    cursor: pointer; padding: 8px 0; list-style: revert;
}
.a-group-summary::marker { color: var(--a-accent); }
.a-group[open] .a-group-summary { margin-bottom: 4px; }

.admin-stat-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 16px; margin-bottom: 28px; }
.admin-stat-card { background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; padding: 20px 22px; }
.admin-stat-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.admin-stat-label { font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; color: var(--a-muted); font-weight: 700; }
.admin-stat-icon { width: 30px; height: 30px; border-radius: 8px; display: flex; align-items: center; justify-content: center; background: rgba(109,93,251,0.10); color: var(--a-accent); }
.admin-stat-value { font-family: 'Syne', sans-serif; font-size: 26px; font-weight: 700; color: var(--a-text); }
.admin-stat-value.green  { color: #0D9463; }
.admin-stat-value.amber  { color: #B7791F; }
.admin-stat-value.red    { color: #DC2626; }

.admin-section-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 18px; flex-wrap: wrap; gap: 12px; }
.admin-section-head h2 { font-family: 'Syne', sans-serif; font-size: 20px; color: var(--a-text); display: flex; align-items: center; gap: 10px; }
.admin-live-dot { display: inline-flex; align-items: center; gap: 6px; background: rgba(13,148,99,0.12); color: #0D9463; font-size: 13px; font-weight: 700; padding: 3px 10px; border-radius: 20px; }

.admin-search {
    width: 100%; padding: 11px 16px; border-radius: 10px; border: 1px solid var(--a-border);
    background: var(--a-panel); color: var(--a-text); font-size: 14px; margin-bottom: 16px; outline: none;
}
.admin-search:focus { border-color: var(--a-accent); }

.admin-tabs-row { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 24px; }
.admin-status-tab {
    display: inline-flex; align-items: center; gap: 6px; padding: 8px 14px; border-radius: 8px;
    background: var(--a-panel); border: 1px solid var(--a-border); color: var(--a-muted); font-size: 13px; font-weight: 600;
}
.admin-status-tab.active { background: var(--a-accent); color: var(--white); border-color: var(--a-accent); }
.admin-status-dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

.order-card { background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; padding: 20px 22px; margin-bottom: 14px; }
.order-card-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 4px; flex-wrap: wrap; }
.order-id { color: var(--a-muted); font-size: 12px; }
.order-id .order-time { color: #DC2626; margin-left: 8px; }
.order-customer { font-family: 'Syne', sans-serif; font-weight: 700; font-size: 16px; color: var(--a-text); margin-bottom: 2px; }
.order-contact { color: var(--a-muted); font-size: 12px; }
.order-badges { display: flex; gap: 8px; flex-shrink: 0; flex-wrap: wrap; justify-content: flex-end; }
.badge { font-size: 11px; font-weight: 700; letter-spacing: 0.02em; padding: 4px 10px; border-radius: 20px; white-space: nowrap; }
.badge-payment-pending { background: #FDECEC; color: #B91C1C; }
.badge-paid           { background: #E7F8F1; color: #0D9463; }
.badge-pending  { background: #FDF3E0; color: #B7791F; }
.badge-approved { background: #E7F0FD; color: #2563EB; }
.badge-preparing { background: #FDEEE2; color: #C2530B; }
.badge-prepared { background: #E7F8F1; color: #0D9463; }
.badge-completed { background: var(--a-panel-2); color: var(--a-muted); }
.badge-rejected, .badge-cancelled { background: #FDECEC; color: #B91C1C; }

.order-items { border-top: 1px solid var(--a-border); border-bottom: 1px solid var(--a-border); padding: 14px 0; margin: 14px 0; display: flex; flex-direction: column; gap: 10px; }
.order-item-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.order-item-name { color: var(--a-text); font-size: 14px; font-weight: 600; }
.order-item-station { font-size: 10px; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; background: rgba(109,93,251,0.10); color: var(--a-accent); padding: 2px 8px; border-radius: 6px; margin-left: 8px; }
.order-item-note { color: var(--a-muted); font-size: 12px; margin-top: 2px; }
.order-item-price { color: var(--a-text); font-size: 14px; flex-shrink: 0; }

.order-footer { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 12px; }
.order-pickup { color: var(--a-muted); font-size: 13px; }
.order-total { font-family: 'Syne', sans-serif; font-weight: 700; color: var(--a-text); font-size: 17px; margin-left: 10px; }
.order-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-admin { border: none; border-radius: 8px; padding: 10px 18px; font-size: 13px; font-weight: 700; cursor: pointer; transition: opacity 0.15s; min-height: 40px; }
.btn-admin:hover { opacity: 0.85; }
.btn-approve { background: var(--a-accent); color: var(--white); }
.btn-reject  { background: #FDECEC; color: #B91C1C; border: 1px solid #F5C2C2; }
.btn-secondary-admin { background: var(--a-panel-2); color: var(--a-text); border: 1px solid var(--a-border); }

.admin-actions-toggle, .status-history-toggle {
    background: none; border: none; color: var(--a-accent); font-size: 13px; font-weight: 600; cursor: pointer;
    padding: 8px 0; display: block; min-height: 36px;
}
.admin-actions-panel, .status-history-panel { display: none; padding: 10px 0 4px; flex-wrap: wrap; gap: 8px; }
.admin-actions-panel.open, .status-history-panel.open { display: flex; }
.status-history-panel { flex-direction: column; }
.status-history-row { color: var(--a-muted); font-size: 12px; padding: 4px 0; border-bottom: 1px dashed var(--a-border); }

.admin-empty { color: var(--a-muted); text-align: center; padding: 60px 0; }

/* tables (users, inventory, history, analytics, ingredients, menu, audit
   log) - wrapped in .table-scroll (see templates) so a table wider than
   the viewport scrolls horizontally in its own box instead of forcing
   the whole page wider, which used to crop/overflow the entire admin
   page on mobile. */
.table-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 12px; }
.a-table { width: 100%; min-width: 480px; border-collapse: collapse; background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; overflow: hidden; }
.a-table th {
    text-align: left; background: var(--a-panel-2); color: var(--a-muted); font-size: 11px; font-weight: 700;
    letter-spacing: 0.05em; text-transform: uppercase; padding: 12px 16px; border-bottom: 1px solid var(--a-border); white-space: nowrap;
}
.a-table td { padding: 13px 16px; border-bottom: 1px solid var(--a-border); color: var(--a-text); font-size: 13px; vertical-align: middle; }
.a-table tr:last-child td { border-bottom: none; }
.a-table input[type="number"], .a-table input[type="text"] {
    width: 80px; padding: 8px; border-radius: 6px; border: 1px solid var(--a-border);
    background: var(--a-panel); color: var(--a-text); font-size: 13px;
}

/* ticket / kitchen view */
.ticket-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.ticket-card { background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; padding: 18px 20px; }
.ticket-head { display: flex; justify-content: space-between; margin-bottom: 10px; }
.ticket-order-num { font-family: 'Syne', sans-serif; font-weight: 700; color: var(--a-text); }
.ticket-pickup { color: var(--a-muted); font-size: 12px; }
.ticket-item { padding: 6px 0; border-bottom: 1px dashed var(--a-border); font-size: 13px; color: var(--a-text); }
.ticket-item:last-of-type { border-bottom: none; }

/* admin forms reuse .form-group/.form-row, light-mode overrides */
.admin-form-card { background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; padding: 28px; max-width: 640px; }
.admin-shell .form-group label { color: var(--a-text); }
.admin-shell .form-group input, .admin-shell .form-group select, .admin-shell .form-group textarea {
    background: var(--a-panel); border-color: var(--a-border); color: var(--a-text);
}
.admin-shell .form-group input:focus, .admin-shell .form-group select:focus, .admin-shell .form-group textarea:focus {
    border-color: var(--a-accent); box-shadow: 0 0 0 3px rgba(109,93,251,0.15); background: var(--a-panel);
}
.admin-shell .form-footer { border-top-color: var(--a-border); }
.admin-shell .form-note { color: var(--a-muted); }

/* POS new order picker */
.pos-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 24px; align-items: start; }
.pos-menu-category { margin-bottom: 24px; }
.pos-menu-category h3 { color: var(--a-text); font-family: 'Syne', sans-serif; font-size: 15px; margin-bottom: 10px; }
.pos-item-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 0; border-bottom: 1px solid var(--a-border); }
.pos-item-name { color: var(--a-text); font-size: 13px; }
.pos-item-price { color: var(--a-muted); font-size: 12px; }
.pos-item-stepper { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.pos-item-qty {
    width: 40px; padding: 6px 2px; border-radius: 6px; border: 1px solid var(--a-border);
    background: var(--a-panel); color: var(--a-text); text-align: center;
}
.pos-item-qty::-webkit-outer-spin-button, .pos-item-qty::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.admin-shell .cart-line-qty-btn {
    background: var(--a-panel); border-color: var(--a-border); color: var(--a-text);
}
.admin-shell .cart-line-qty-btn:hover { border-color: var(--a-accent); color: var(--a-accent); }
.pos-summary { background: var(--a-panel); border: 1px solid var(--a-border); border-radius: 12px; padding: 22px; position: sticky; top: 20px; }
.pos-live-total { border-top: 1px solid var(--a-border); border-bottom: 1px solid var(--a-border); padding: 14px 0; margin-bottom: 16px; }
.pos-live-total .checkout-summary-row { color: var(--a-muted); }
.pos-live-total .checkout-summary-row.total { color: var(--a-text); font-weight: 700; border-top-color: var(--a-border); }

@media (max-width: 1100px) {
    .checkout-inner { grid-template-columns: 1fr; padding: 0 24px; gap: 32px; }
    .admin-stat-grid { grid-template-columns: repeat(2, 1fr); }
    .pos-grid { grid-template-columns: 1fr; }
}
@media (max-width: 768px) {
    .cart-page { padding: 56px 24px 72px; }
    .cart-line { flex-wrap: wrap; }
    .cart-summary { max-width: none; }
    .checkout-page { padding: 56px 0 72px; }
    .checkout-form { padding: 24px; }

    /* Admin sidebar becomes an off-canvas panel behind a hamburger
       toggle, the same interaction pattern as the public site's nav
       (see .nav-toggle above) rather than the old horizontal-scrolling
       strip, which hid most of the ~13 nav links off-screen with no
       visible indication there was more to scroll to - not discoverable
       for a non-technical user. */
    .admin-nav-toggle { display: flex; }
    .admin-sidebar {
        position: fixed; top: 0; left: 0; bottom: 0; z-index: 200;
        width: 260px; max-width: 82vw; transform: translateX(-100%);
        transition: transform 0.25s ease; overflow-y: auto;
        box-shadow: var(--shadow-hover);
    }
    .admin-shell.sidebar-open .admin-sidebar { transform: translateX(0); }
    .admin-nav-section { display: block; }
    .admin-sidebar-backdrop {
        display: none; position: fixed; inset: 0; z-index: 190;
        background: rgba(11,10,14,0.45);
    }
    .admin-shell.sidebar-open .admin-sidebar-backdrop { display: block; }
    .admin-shell.sidebar-open { overflow: hidden; }

    .admin-topbar { padding: 0 16px; }
    .admin-topbar-user { gap: 10px; }
    .admin-role-badge { display: none; }
    .admin-content { padding: 16px; }
    .admin-stat-grid { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
    .admin-stat-card { padding: 14px 16px; }
    .admin-stat-value { font-size: 21px; }
    .admin-form-card { padding: 18px; max-width: none; }
    .order-actions, .admin-actions-panel { width: 100%; }
    .order-actions .btn-admin, .admin-actions-panel .btn-admin { flex: 1; min-width: 0; }
    .pos-summary { position: static; }
}

@media (prefers-reduced-motion: reduce) {
    .reveal, .reveal.visible { opacity: 1; transform: none; transition: none; }
    .button-primary::after { animation: none; }
    .nav-links,
    .nav-dropdown-panel,
    .menu-flavor-modal,
    .menu-flavor-modal-inner,
    .lightbox-overlay,
    .lightbox-overlay img,
    .button-primary,
    .button-primary:active,
    .button-outline-white,
    .button-outline-white:active,
    #cart-container {
        transition: none;
    }
}
