/* ==========================================================================
   La Pizza Ristorante — public site styles (v2)
   Mobile-first: base rules target phones, min-width breakpoints layer on
   tablet/desktop refinements. No CSS framework — kept small for mobile data.
   Fonts are self-hosted (assets/fonts/fonts.css) — see build notes there.
   ========================================================================== */

@import url('../fonts/fonts.css');

:root {
  --color-bg:        #F5EAD6; /* warm cream/beige field — client reversed the earlier "no beige" rule 2026-08-15, reference: gold-bordered Italian menu card look */
  --color-surface:    #FFFFFF; /* cards stay white/near-white so they read as a lighter panel against the beige page, separated by the gold border below instead of a tone shift */
  --color-surface-2:  #EFEFEF; /* neutral grey for placeholder media tiles / chip backgrounds */
  --color-primary:    #A71F24; /* logo red */
  --color-primary-dk: #7E1519;
  --color-ink:        #231F20; /* logo near-black */
  --color-ink-soft:   #635F5C;
  --color-ink-faint:  #9B9794;
  --color-border:     #E6E6E6; /* neutral grey, no warm tint */
  --color-gold:       #B4893C;
  --color-campaign-was: #999999; /* struck-through original price — neutral grey */
  --color-info:       #2E6C9E; /* soft blue accent — for neutral/informational badges (prep time), never for price */
  --color-info-bg:    rgba(46,108,158,0.09);
  --color-it-green:   #009246; /* Italian flag stripe — small decorative accent under the logo, see .flag-stripe */
  --color-it-white:   #F4F4F4;
  --color-it-red:     #CE2B37;
  --color-flame:      #D9762E; /* "Meest besteld" badge — warm orange, distinct from --color-primary (campaign-only red) */

  --radius-md: 14px;
  --radius-lg: 20px;
  --radius-pill: 999px;

  --shadow-sm: 0 1px 2px rgba(35, 31, 32, 0.05), 0 4px 14px rgba(35, 31, 32, 0.06);
  --shadow-md: 0 8px 28px rgba(35, 31, 32, 0.12);

  --nav-height: 72px;
  --nav-radius: 26px;
  --topbar-height: 52px;

  --font-heading: 'Fraunces', Georgia, 'Iowan Old Style', serif;
  --font-body: 'Public Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { background: var(--color-ink); } /* iOS notch/status-bar safe-area strip (viewport-fit=cover) — body's own background still paints everywhere body actually covers */

body {
  background: var(--color-bg);
  color: var(--color-ink);
  font-family: var(--font-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  padding-bottom: calc(var(--nav-height) + env(safe-area-inset-bottom, 0px) + 28px);
  min-height: 100vh;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }

.container {
  max-width: 640px;
  margin: 0 auto;
  padding: 0 16px;
}

@media (min-width: 768px) {
  .container { max-width: 720px; }
}
@media (min-width: 1024px) {
  .container { max-width: 1080px; }
}

/* The real page-width cap for tablet/desktop is `<main>` itself, not
   .container above — .container was defined but never actually applied
   to any element in the templates, so every page rendered edge-to-edge
   at any width. Every top-level content block (.category-grid,
   .product-list, .search-form, .campaigns-intro, .info-block, etc.)
   already carries its own 16px horizontal gutter, so this deliberately
   has NO padding of its own — same breakpoint values as .container,
   just centers + caps the whole content column so rows/cards stop
   stretching edge-to-edge on a tablet/laptop screen. Full-bleed chrome
   (.topbar, .hero, .page-title-bar, .bottom-nav) stays outside this cap
   on purpose — only the scrollable content column narrows. */
main {
  max-width: 640px;
  margin: 0 auto;
}
@media (min-width: 768px) {
  main { max-width: 720px; }
}
@media (min-width: 1024px) {
  /* 1080 -> 1240 (2026-08-19, owner report: long-name/dual-price rows —
     e.g. Carta dei Vini's "Montepulciano d'Abruzzo DOC (Huiswijn, Rosso)"
     + "€ 6,50 / € 29,50" — were ellipsis-truncating harder than
     necessary at 1080px). Safe to widen because the actual overflow bug
     (see .product-list > li below) is fixed independently of this value;
     this is just breathing room, not a fix on its own. */
  main { max-width: 1240px; }
}

/* ---------------------------------------------------------------------
   Top bar — present on EVERY page. Solid dark strip on inner pages;
   transparent/overlaid on the photo hero on the homepage.
   --------------------------------------------------------------------- */
.topbar {
  position: relative;
  z-index: 2;
  height: var(--topbar-height);
  background: var(--color-ink);
}

.topbar--overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  background: transparent;
}

/* The bar itself (.topbar, above) stays full-bleed for its background;
   its actual content (back button, logo, language switcher) is centered
   and width-capped to the same measure as `main` below, so on tablet/
   desktop they line up with the page content instead of pinning to the
   viewport's physical edges while the content column sits narrower and
   centered. Same breakpoint values as `main`. */
.topbar__inner {
  position: relative;
  height: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding: 0 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}
@media (min-width: 768px) {
  .topbar__inner { max-width: 720px; }
}
@media (min-width: 1024px) {
  /* Keep this in sync with `main`'s own 1024px value above — 2026-08-19,
     owner report: after main widened to 1240px this was left at 1080px,
     so the header/title text no longer lined up with the wider product
     grid below it. */
  .topbar__inner { max-width: 1240px; }
}

.topbar__back {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-pill);
  background: rgba(255,255,255,0.12);
  color: #fff;
  flex-shrink: 0;
}

/* Absolutely positioned + centered on the topbar itself (not flex "margin:
   auto" centering) so it sits exactly in the middle regardless of the
   back-button vs. language-switcher widths differing on either side —
   those two are unequal, so flex auto-margin centering nudged the logo
   slightly off true center. */
.topbar__logo {
  display: flex;
  align-items: center;
  height: 32px;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  -webkit-tap-highlight-color: transparent;
}
.topbar__logo img { height: 100%; width: auto; }
.topbar--home .topbar__logo,
.topbar--overlay .topbar__logo { visibility: hidden; } /* the hero shows the big logotype instead */

.topbar__spacer { width: 34px; flex-shrink: 0; } /* balances the back button so the logo stays centered */

/* Language switcher — custom flag-only dropdown built on <details>/<summary>
   (opens/closes natively, no JS required; see footer.php for the small
   outside-click-close enhancement). Deliberately not styled like a native
   <select> — a rounded pill that opens a small floating flag panel. */
.flag-icon {
  width: 20px;
  height: 14px;
  border-radius: 3px;
  display: block;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.35);
}

.lang-menu {
  position: relative;
  flex-shrink: 0;
}
.lang-menu__current {
  display: flex;
  align-items: center;
  gap: 5px;
  list-style: none;
  background: rgba(255,255,255,0.14);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-radius: var(--radius-pill);
  padding: 9px 12px;
  cursor: pointer;
  color: #fff;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.12s ease, transform 0.1s ease;
}
.lang-menu__current::-webkit-details-marker { display: none; }
.lang-menu__current::marker { content: ''; }
.lang-menu__current:focus-visible {
  outline: 2px solid var(--color-gold);
  outline-offset: 2px;
}
.lang-menu__current:active { transform: scale(0.94); background: rgba(255,255,255,0.24); }
@media (prefers-reduced-transparency: reduce) {
  .lang-menu__current { background: rgba(35,31,32,0.55); backdrop-filter: none; -webkit-backdrop-filter: none; }
}
.lang-menu__chevron { transition: transform 0.15s ease; flex-shrink: 0; }
.lang-menu[open] .lang-menu__chevron { transform: rotate(180deg); }

.lang-menu__panel {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  background: var(--color-ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 8px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 44px;
  z-index: 10;
  animation: lang-menu-in 0.14s ease;
}
/* Symmetric open/close (see §7 "enter and exit along the same path") —
   native <details> has no closing transition at all on its own (it just
   vanishes), so templates/layout/footer.php intercepts the close and
   adds .is-closing, plays this reverse animation, then actually closes
   the element once it finishes. */
.lang-menu__panel.is-closing { animation: lang-menu-out 0.14s ease forwards; }
@keyframes lang-menu-in {
  from { opacity: 0; transform: translateY(-4px); }
  to { opacity: 1; transform: translateY(0); }
}
@keyframes lang-menu-out {
  from { opacity: 1; transform: translateY(0); }
  to { opacity: 0; transform: translateY(-4px); }
}
@media (prefers-reduced-motion: reduce) {
  /* Same names, re-declared under the media query — this overrides the
     slide with a plain fade for anyone who wants less motion, without
     the JS or the .is-closing wiring needing to know or care. */
  @keyframes lang-menu-in { from { opacity: 0; } to { opacity: 1; } }
  @keyframes lang-menu-out { from { opacity: 1; } to { opacity: 0; } }
}
.lang-menu__option {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  min-height: 24px;
  border-radius: 8px;
}
.lang-menu__option:hover {
  background: rgba(255,255,255,0.12);
}
.lang-menu__option:focus-visible {
  background: rgba(255,255,255,0.12);
  outline: 2px solid var(--color-gold);
  outline-offset: 1px;
}

/* ---------------------------------------------------------------------
   Hero — homepage only. Real background photo (admin-uploadable), dark
   gradient for legibility, big logotype + tagline centered within it.
   --------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 375px; /* was 300px — +25% per client request, more photo presence */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 20px 16px 32px;
  background-color: var(--color-ink);
  background-size: cover;
  background-position: center;
  overflow: hidden;
  /* True transparency instead of a painted white gradient: the whole hero
     (photo + dark overlay together) fades to fully see-through in the
     last few percent, revealing the page's own white body background
     underneath rather than an explicit color being drawn over the photo.
     Reads as lighter/more subtle than a gradient-to-white overlay, since
     nothing is actively lightening the photo's own colors — it's just
     increasingly transparent. Safari still needs the -webkit- prefix. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 94%, transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, #000 94%, transparent 100%);
}
/* Darkens the photo for text legibility only — no longer also needs to
   fade to var(--color-bg) at the bottom, .hero's own mask-image above
   handles the dissolve into the page now. */
.hero::before {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg,
    rgba(20,17,15,0.55) 0%,
    rgba(20,17,15,0.72) 55%,
    rgba(20,17,15,0.78) 100%);
}
.hero--no-photo::before {
  background: linear-gradient(160deg, #2A2320 0%, var(--color-ink) 100%);
}
.hero__content {
  position: relative;
  z-index: 1;
  max-width: 340px;
}
.hero__logotype {
  max-width: 240px;
  margin: 0 auto 8px;
}
.hero__logotype img { width: 100%; height: auto; }

/* Small Italian-flag accent stripe — a nod to "Ristorante Italiano" under
   the wordmark (client reference). Homepage: small and centered under the
   big hero logotype. Inner pages get the same three colors adapted into
   the thin separator line between the topbar and page-title-bar instead
   (see .page-title-bar's border-image below) rather than repeating this
   exact small bar under the tiny topbar logo, where it wouldn't have
   room to read clearly. */
.flag-stripe {
  width: 52px;
  height: 4px;
  margin: 0 auto;
  border-radius: 2px;
  overflow: hidden;
  background: linear-gradient(to right,
    var(--color-it-green) 0 33.33%,
    var(--color-it-white) 33.33% 66.66%,
    var(--color-it-red) 66.66% 100%);
}
.hero__tagline {
  font-family: var(--font-heading);
  font-style: italic;
  font-weight: 400;
  font-size: 15px;
  color: var(--color-gold);
  letter-spacing: 0.02em;
  margin: 0;
}

/* The separator between the topbar and this bar (inner pages) doubles as
   the header's adaptation of the Italian-flag stripe motif — thicker than
   the old plain faint line, colored instead of neutral, full-width
   instead of the small centered bar under the homepage's big logo. */
.page-title-bar {
  background: var(--color-ink);
  border-top: 3px solid transparent;
  border-image: linear-gradient(to right,
    var(--color-it-green) 0 33.33%,
    var(--color-it-white) 33.33% 66.66%,
    var(--color-it-red) 66.66% 100%) 1;
}
/* Same full-bleed-background/capped-content split as .topbar__inner above —
   the gradient strip + dark fill stay full width, the heading text lines
   up with the page content column instead of the viewport edge. */
.page-title-bar__inner {
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px;
}
@media (min-width: 768px) {
  .page-title-bar__inner { max-width: 720px; }
}
@media (min-width: 1024px) {
  /* Keep in sync with `main` / .topbar__inner above — see 2026-08-19 note there. */
  .page-title-bar__inner { max-width: 1240px; }
}

.page-title-bar h1 {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 19px;
  color: #fff;
  margin: 0;
  flex: 1;
  text-wrap: balance;
}

/* ---------------------------------------------------------------------
   Category grid (homepage)
   --------------------------------------------------------------------- */
.category-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 14px;
  padding: 0 16px 8px;
}
.category-grid--top { padding-top: 18px; } /* homepage grid sits directly under the hero, no heading above it anymore */

@media (min-width: 640px) {
  .category-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 1024px) {
  .category-grid { grid-template-columns: repeat(4, 1fr); gap: 18px; }
}

/* Portrait photo cards, generously rounded on all 4 corners (not just the
   top, and not a full pill either — a soft "half-oval" corner), with the
   category name overlaid directly on the photo in white instead of sitting
   in its own text block below it. */
.category-tile {
  border-radius: 15px; /* was --radius-lg (20px) — kept as its own value here so other --radius-lg users (product gallery corners) are unaffected */
  overflow: hidden;
  border: 1px solid var(--color-gold); /* matches .product-row's gold border, same thin-line treatment */
  box-shadow: var(--shadow-sm);
  transition: transform 0.15s ease, box-shadow 0.15s ease;
  display: block;
}
.category-tile:active { transform: scale(0.97); }

.category-tile__media {
  position: relative;
  aspect-ratio: 3 / 4;
  width: 100%;
  background: var(--color-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.category-tile__media img { width: 100%; height: 100%; object-fit: cover; }
.category-tile__media .cat-icon { width: 38%; height: 38%; color: var(--color-primary); opacity: 0.55; }
/* Dark scrim fading up from the bottom so white text stays legible over any
   photo, without needing a solid bar behind it. */
.category-tile__media::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(20,16,14,0.72) 0%, rgba(20,16,14,0.28) 42%, rgba(20,16,14,0) 68%);
  pointer-events: none;
}

.category-tile__label {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 12px;
  z-index: 1;
  font-family: var(--font-heading);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: #fff;
  text-shadow: 0 1px 4px rgba(0,0,0,0.35);
}

/* ---------------------------------------------------------------------
   Ingredient chips — replaces the old flat comma-separated description line.
   --------------------------------------------------------------------- */
.chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: 5px;
  margin: 4px 0 0;
  padding: 0;
  list-style: none;
}
.ingredient-chip {
  display: inline-block;
  background: var(--color-surface-2);
  color: var(--color-ink-soft);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  white-space: nowrap;
}
.product-detail .ingredient-chip {
  font-size: 12.5px;
  padding: 5px 12px;
}

/* ---------------------------------------------------------------------
   Product list (category page)
   --------------------------------------------------------------------- */
.product-list {
  list-style: none;
  margin: 0;
  padding: 16px 16px; /* top padding so the first row doesn't sit flush against the dark page-title-bar above it */
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.product-row {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Same beige as the page (--color-bg, not --color-surface) — owner
     wants the row blending into the page, distinguished only by the gold
     border/shadow below, not a lighter panel (2026-08-15 follow-up). */
  background: var(--color-bg);
  /* Thin gold line instead of the neutral grey border — matches the
     gold-bordered Italian menu-card reference (2026-08-15), shared with
     .bottom-nav's border below so both read as one consistent line style. */
  border: 1px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: 10px;
  box-shadow: var(--shadow-sm);
  position: relative;
  transition: transform 0.1s ease;
}
.product-row:active { transform: scale(0.98); }

.product-row__media {
  width: 66px;
  height: 66px;
  border-radius: 10px;
  overflow: hidden;
  flex-shrink: 0;
  background: none; /* see .product-detail__media comment — transparent AI product photos, page beige shows through */
  display: flex;
  align-items: center;
  justify-content: center;
}
.product-row__media img { width: 100%; height: 100%; object-fit: cover; }
.product-row__media .cat-icon { width: 52%; height: 52%; color: var(--color-primary); opacity: 0.5; }

.product-row__body { flex: 1; min-width: 0; }
.product-row__name {
  display: flex;
  align-items: center;
  font-weight: 600;
  font-size: 15px;
  margin: 0;
  color: var(--color-ink);
}
/* Name text truncates with an ellipsis instead of wrapping, so the badge
   icons right after it (.product-row__featured-star/chef-icon/etc, all
   flex-shrink:0) always stay pinned on the same line instead of a lone
   icon dropping to its own line when name+icons don't quite fit. */
.product-row__name-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
/* "Aanrader"/featured indicator on list rows — a small gold star right
   after the name instead of a text pill (see render_featured_star_icon()
   in functions.php). The product detail page keeps its own separate
   .badge-featured pill, untouched. */
/* Sized in em, not a fixed px, so the icon always matches whatever text
   it's sitting next to — 1:1 with the name's own font-size, on both the
   15px list-row name and the 25px product-detail name, with no separate
   per-context override needed. Overrides the width/height HTML attrs
   render_badge_icon() also writes (CSS wins over those either way). */
.product-row__featured-star {
  width: 1em;
  height: 1em;
  color: var(--color-gold);
  vertical-align: -0.1em;
  margin-left: 0.3em;
  flex-shrink: 0;
}
/* Chef's Keuze / Meest Besteld / Vegetarisch — same inline-after-name
   treatment as the featured star, one distinct color per concept (see
   render_product_badges() in functions.php). */
.product-row__chef-icon,
.product-row__flame-icon,
.product-row__leaf-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.1em;
  margin-left: 0.3em;
  flex-shrink: 0;
}
.product-row__chef-icon  { color: var(--color-ink-soft); }
.product-row__flame-icon { color: var(--color-flame); }
.product-row__leaf-icon  { color: var(--color-it-green); }
/* Prep-time pill under the name on list rows — same component as the
   product detail page's .prep-time-pill, just smaller to fit the tighter
   row and with its own top margin since there's no .product-meta-row
   wrapper here to provide one. */
.product-row .prep-time-pill {
  font-size: 10.5px;
  padding: 3px 8px;
  margin: 4px 0 0;
}
.product-row .chip-list { overflow: hidden; max-height: 24px; }
/* Red/--color-primary is reserved for campaign (discounted) pricing only
   (see .price-now below) — a product's regular price is neutral ink, not
   red, so red keeps its "this one's on sale" meaning instead of being the
   color of every price on the site. */
.product-row__price {
  font-weight: 700;
  font-size: 13.5px;
  color: var(--color-ink);
  white-space: nowrap;
  margin-left: auto;
  padding-left: 8px;
  text-align: right;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
/* Groups a was/now pair (small OR large) into a single flex item, so a
   campaign small/large row stacks into exactly 2 clean lines instead of
   every <span> (and the bare "/" text node between them) becoming its own
   anonymous flex item under flex-direction:column — real bug, caught via
   a client screenshot showing a campaign pizza's price broken into 5
   stacked lines. See product_price_compact_html() in price.php. */
.product-row__price .price-row { display: block; white-space: nowrap; }

/* .badge-campaign is unused as of this list-row redesign — a campaign
   product's price is already red (see .price-now below), which reads as
   a clearer, less noisy signal than a duplicate text pill. Left in place,
   dormant, same deprecate-don't-delete precedent as elsewhere on this
   site, in case a future page wants an explicit campaign badge again. */
.badge-sold-out, .badge-campaign {
  display: inline-block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  margin-top: 5px;
}
.badge-sold-out { background: var(--color-ink); color: #fff; }
.badge-campaign { background: var(--color-primary); color: #fff; }

/* "Aanrader" / chef's pick — sits inline right after the product name,
   unlike the sold-out/campaign badges which sit below it in their own line. */
.badge-featured {
  display: inline-block;
  vertical-align: middle;
  background: var(--color-gold);
  color: #fff;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 3px 8px;
  border-radius: var(--radius-pill);
  margin-left: 6px;
}
.product-detail__name .badge-featured { font-size: 11px; margin-left: 8px; vertical-align: middle; }

/* Spice level — 1-3 chili-pepper icons; pale/muted (same hue, low
   opacity) when inactive, solid/vivid when active, so the degree reads
   at a glance rather than just "on/off". */
.spice-level { display: flex; align-items: center; gap: 3px; margin: 0 0 12px; }
.spice-level__icon { fill: #919191; }
.spice-level__icon.is-active { fill: var(--color-primary); }
/* When the Owner uploads a custom spice icon (Setting 'badge_icon_spice'),
   render_spice_level() swaps the <svg> above for an <img> — fill can't
   recolor a raster image, so the active/inactive states differentiate via
   opacity instead. Scoped to img only; the default SVG's fill-based
   look above is untouched. */
img.spice-level__icon { opacity: 0.35; }
img.spice-level__icon.is-active { opacity: 1; }

/* Campaign price treatment — struck-through original + red discounted price,
   wherever a price is shown (list rows, detail, campaigns page, search). */
.price-was {
  text-decoration: line-through;
  color: var(--color-campaign-was);
  font-weight: 500;
  font-size: 0.85em;
}
.price-now {
  color: var(--color-primary);
  font-weight: 700;
}
.product-row__price .price-was { font-size: 11px; }

@media (min-width: 768px) {
  .product-list { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
}
@media (min-width: 1024px) {
  .product-list { grid-template-columns: 1fr 1fr 1fr; }
}
/* Grid item blowout fix (2026-08-19, owner report — screenshot showed the
   whole 3-column grid pushed off-center on desktop/tablet, worst on
   Carta dei Vini). Root cause: a grid item's default min-width is `auto`,
   i.e. it never shrinks below its own unwrappable content width. Nothing
   here forces .product-row__price ("€ 6,50 / € 29,50" etc, white-space:
   nowrap, no overflow/ellipsis) to shrink, so on long-name/dual-price
   rows the resulting min-content width blows the grid track past main's
   1240px cap — main itself stays correctly centered, but the grid
   overflows out its right edge, which is what read as "not centered."
   (.product-row__name-text already has its own min-width:0 + ellipsis —
   this was never a name-wrapping problem, only the price column plus the
   missing min-width:0 on the grid item itself.) Confirmed live via
   getBoundingClientRect() before/after on localhost. */
.product-list > li { min-width: 0; }

/* ---------------------------------------------------------------------
   Product detail (v5 redesign — see templates/public/product.php)
   --------------------------------------------------------------------- */
.product-detail__media {
  position: relative;
  width: 100%;
  /* Square — a wide/rectangular photo scaled to `main`'s full cap looked
     like an oddly cropped panorama once the page itself got wider on
     tablet/desktop (client feedback). 1:1 stays coherent at any size the
     surrounding layout gives it, mobile included. */
  aspect-ratio: 1 / 1;
  /* No painted background (2026-08-15, AI photo rollout) — product photos
     are now transparent-PNG cutouts (dish floats with no plate/table
     backdrop), so the page's own beige should show straight through
     instead of a grey placeholder tint. Still fine for the no-photo-yet
     placeholder-icon case too (just renders on bare page background now). */
  background: none;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  /* Mobile: flush against the header, no gap — sharp top corners, only
     the bottom two rounded to soften the hard edge into the white body
     below (client request — a gap read as unwanted dead space on a
     phone screen). Tablet/desktop get a real gap instead, from
     .product-detail__layout's own margin-top, with all 4 corners
     rounded to match — see the 768px breakpoint below. */
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}
.product-detail__media img { width: 100%; height: 100%; object-fit: cover; }
.product-detail__media .cat-icon { width: 28%; height: 28%; color: var(--color-primary); opacity: 0.45; }

/* Real side margins instead of edge-to-edge — simplicity/whitespace per
   the brief, not full-bleed. Centered + width-capped on larger screens,
   matching the existing .product-list grid breakpoints. */
.product-detail__body {
  padding: 24px 24px 8px;
  max-width: 640px;
  margin: 0 auto;
}
.product-detail__links { max-width: 640px; margin: 0 auto; }

/* Tablet/desktop: photo and body sit side by side instead of stacked —
   the square photo in a capped-width column on the left (it can only
   ever get SMALLER than this cap on a narrower tablet, flex-grow:0 means
   it never gets bigger), the body taking whatever width is left on the
   right, both starting at the same top line (client request). */
@media (min-width: 768px) {
  .product-detail__layout {
    display: flex;
    align-items: flex-start;
    gap: 24px;
    margin-top: 16px;
    /* Matches .page-title-bar__inner's own 16px left padding above, so the
       photo's left edge lines up with the "K" of the category heading
       instead of bleeding out to main's true edge (that full-bleed-under-
       inset-header look is fine on mobile where nothing sits beside the
       photo to invite the comparison, but reads as misaligned once the
       photo become a column in a side-by-side layout — client feedback). */
    padding-left: 16px;
  }
  .product-detail__media-col {
    flex: 0 1 380px;
    min-width: 220px;
  }
  .product-detail__media,
  .product-gallery {
    /* Mobile keeps these flush/bottom-radius-only (see their base rules
       above) — from here up there's a real gap again (.product-detail__
       layout's own margin-top, not the photo's), so all 4 corners round. */
    border-radius: var(--radius-lg);
  }
  .product-detail__body {
    flex: 1 1 320px;
    min-width: 280px;
    max-width: none;
    margin: 0;
    padding-left: 0; /* the row's own 24px gap already separates it from the photo */
  }
  /* Was centered under the old single-column 640px body — now that the
     photo sits in its own flush-left column (.product-detail__media-col),
     centering independently left these adrift from the photo's left edge.
     Flush-left instead, at the same 16px inset as .product-detail__layout
     above, so it lines up with both the photo and the category heading. */
  .product-detail__links {
    max-width: none;
    margin: 0;
    padding-left: 16px;
  }
}

/* Labeled badge pills, above the product name (see render_product_badge_
   pills() in functions.php) — a bigger, text-carrying treatment than the
   bare inline icons list rows use, since there's real room here. */
.product-badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0 0 12px;
}
.product-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: var(--color-surface-2);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  color: var(--color-ink);
  white-space: nowrap;
}
.product-badge__icon { width: 1em; height: 1em; flex-shrink: 0; }
.product-badge__icon--chef       { color: var(--color-ink-soft); }
.product-badge__icon--bestseller { color: var(--color-flame); }
.product-badge__icon--vegetarian { color: var(--color-it-green); }

/* Signature gets its own gold-tinted pill instead of the neutral shell —
   same gold accent as .badge-featured elsewhere, just as a pill, not a
   solid fill (a solid gold pill this size read as too heavy/loud next to
   the plain-neutral pills beside it). Icon inherits the pill's own gold
   text color via currentColor, no separate icon color class needed. */
.product-badge--signature {
  background: color-mix(in srgb, var(--color-gold) 14%, var(--color-surface));
  border-color: var(--color-gold);
  color: var(--color-gold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Product name + prep-time pill share one row, pill directly opposite the
   name (client request — it used to sit lower, paired with spice level).
   flex-start (not center) so the pill aligns with the name's first line
   instead of drifting to the vertical middle when a long name wraps to
   two lines; the pill gets a small top nudge to optically match the
   name's cap-height on that first line. */
.product-detail__name-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  /* Tightened from 10px — the name-row's own height is already tall
     (25px name text), so its old 10px bottom margin on top of that made
     the prep-time pill and the spice-level row right below (in
     .product-detail__top-row) read as two disconnected clusters instead
     of one related pair (client feedback: "bring the time and spice
     indicators closer together"). */
  margin: 0 0 2px;
}
.product-detail__name-row .product-detail__name { margin: 0; }
.product-detail__name-row .prep-time-pill { flex-shrink: 0; margin-top: 3px; }

.product-detail__name {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 25px;
  letter-spacing: -0.015em;
  margin: 0 0 10px;
  color: var(--color-ink);
}

.product-detail__description {
  color: var(--color-ink-soft);
  font-size: 14px;
  line-height: 1.55;
  margin: 0 0 16px;
}

/* Sits right under the product name for single-price products (moved up
   from the bottom of the page per client feedback — small_large/variant
   products keep their price at the bottom instead, in the Size selector).
   No border/background pill anymore — just the price itself, since a
   boxed price directly under the title read as visually heavy this close
   to the name. Neutral ink by default — red is reserved for campaign
   (discounted) pricing only, see .price-now below. */
.product-detail__price {
  display: block;
  color: var(--color-ink);
  font-weight: 700;
  font-size: 19px;
  margin: 0 0 14px;
}
.product-detail__price .price-was { font-size: 0.7em; }
.product-detail__price .price-now { color: var(--color-primary); }

/* Single-price products: price on the left, prep-time/spice meta row on
   the opposite side of the same row (client spec) — wraps back to two
   stacked lines only if it genuinely doesn't fit (very narrow screen +
   long price). The row itself carries the bottom margin the two children
   normally have on their own, so it isn't doubled. */
.product-detail__top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin: 0 0 14px;
}
.product-detail__top-row .product-detail__price,
.product-detail__top-row .product-meta-row {
  margin: 0;
}

.product-detail__soldout {
  display: inline-block;
  background: var(--color-ink);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  padding: 8px 16px;
  border-radius: var(--radius-pill);
  margin: 4px 0 14px;
}

.product-detail__links {
  padding: 12px 24px 24px;
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.product-detail__links a {
  font-size: 13.5px;
  font-weight: 600;
  color: var(--color-primary-dk);
  border-bottom: 1px solid var(--color-primary-dk);
  padding-bottom: 1px;
}

/* ---------------------------------------------------------------------
   Product photo gallery (product detail, 2+ photos) — horizontal CSS
   scroll-snap, no JS required to swipe/scroll through it. footer.php adds
   a small optional enhancement that highlights the active dot.
   --------------------------------------------------------------------- */
.product-gallery {
  width: 100%;
  aspect-ratio: 1 / 1;
  position: relative;
  background: none; /* see .product-detail__media comment above — transparent AI product photos, page beige shows through */
  overflow: hidden;
  /* Same square ratio + flush-against-header + bottom-only rounding on
     mobile as .product-detail__media above (the single-photo case) — see
     its comment for why. */
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}
/* No photo-to-white fade here either — same client rejection as the
   single-photo .product-detail__media (see project history), just never
   caught on this second, separate gallery rule until now. The dots'
   legibility doesn't depend on it: .product-gallery__dot already carries
   its own dark box-shadow ring + white fill for contrast against any
   photo, fade or not. */
.product-gallery__dots { z-index: 2; }
.product-gallery__track {
  display: flex;
  width: 100%;
  height: 100%;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.product-gallery__track::-webkit-scrollbar { display: none; }
.product-gallery__item { flex: 0 0 100%; height: 100%; scroll-snap-align: start; }
.product-gallery__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.product-gallery__dots {
  position: absolute;
  bottom: 10px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 6px;
}
.product-gallery__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255,255,255,0.55);
  box-shadow: 0 0 0 1px rgba(0,0,0,0.08);
  transition: width 0.15s ease, border-radius 0.15s ease;
}
.product-gallery__dot.is-active { background: #fff; width: 16px; border-radius: 3px; }

/* Meta row — prep time + spice level combined on one line under the name. */
.product-meta-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 0 14px;
  flex-wrap: wrap;
}
/* No background fill (owner feedback, 2026-08-19 — this instruction
   briefly got applied to .allergen-block above by mistake, reverted
   there) — just the clock icon + text, colored Italian red, directly
   against the page, matching .nutrition-card's own "no fill" ending
   point for the same reason. */
.prep-time-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  color: var(--color-it-red);
  font-size: 12px;
  font-weight: 700;
  padding: 5px 11px;
  border-radius: var(--radius-pill);
}
.spice-level { display: flex; align-items: center; gap: 3px; margin: 0; }

/* Allergens — icon sits on a soft circular badge, visually consistent with
   the ingredient icon cards below (this is a disclosure/warning, not a
   flavor description, so it stays a compact inline pill rather than the
   bigger ingredient cards). */
.allergen-block { margin: 0 0 16px; }
.allergen-block__heading, .ingredient-block__heading {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-ink-faint);
  margin: 0 0 8px;
}
.allergen-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: var(--color-surface);
  color: var(--color-ink-soft);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: 0.01em;
  padding: 4px 12px 4px 4px;
  border-radius: var(--radius-pill);
  /* Gold, not neutral grey — see .nutrition-card's same 2026-08-19 note. */
  border: 1px solid var(--color-gold);
  white-space: nowrap;
}
.allergen-chip svg {
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  padding: 5px;
  border-radius: 50%;
  background: rgba(167,31,36,0.08);
  color: var(--color-primary-dk);
  box-sizing: border-box;
}

/* Ingredients — icon-grid cards (uploaded PNG or the neutral fallback),
   name underneath. 5 per row on mobile, wraps to additional rows via CSS
   grid (never horizontal scroll) — per the client's own spec. */
.ingredient-block { margin: 0 0 16px; }
.ingredient-icon-grid {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 10px;
}
/* The fixed-5-equal-columns grid above is tuned for mobile's narrow body
   width, where each 1fr column ends up close to the 64px icon itself —
   snug by construction. In the wider two-column desktop layout
   (.product-detail__body, ~650-680px there) the same 5 columns each
   stretch far past 64px, centering each icon in a lot of dead space and
   reading as "misaligned"/"too much gap" (client feedback) even though
   the grid's own `gap` never changed. Fixed 64px columns instead — packs
   however many icons there are tightly from the left edge, only wrapping
   once an actual row of them doesn't fit. */
@media (min-width: 768px) {
  .ingredient-icon-grid { grid-template-columns: repeat(auto-fill, 64px); }
}
.ingredient-icon-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
.ingredient-icon-card img,
.ingredient-icon-card svg {
  width: 100%;
  aspect-ratio: 1;
  max-width: 64px;
  border-radius: var(--radius-md);
  background: var(--color-surface-2);
  padding: 10px;
  box-sizing: border-box;
  object-fit: contain;
}
.ingredient-icon-card svg { color: var(--color-ink-faint); stroke-width: 1.4; }
/* Allergen tiles specifically (not the dormant general-ingredient grid —
   see render_ingredient_icon_group()'s docblock, unreachable from
   product.php as of v7, so this is the only live use of
   .ingredient-icon-card today). Went through solid Italian-flag red fill
   (owner feedback, 2026-08-19) to white + gold border, matching
   .nutrition-card / .allergen-chip (owner's explicit request, 2026-08-25). */
.allergen-block .ingredient-icon-card img,
.allergen-block .ingredient-icon-card svg {
  background: var(--color-surface);
  border: 1px solid var(--color-gold);
}
.allergen-block .ingredient-icon-card svg { color: var(--color-primary-dk); }
.allergen-block .ingredient-icon-card span { color: var(--color-ink-soft); }
.ingredient-icon-card span {
  font-size: 10.5px;
  font-weight: 600;
  color: var(--color-ink-soft);
  line-height: 1.2;
  word-break: break-word;
}

/* Nutrition — always 4 fixed columns side by side, even on narrow phones
   (client spec: all cards on one row, never wrapping) — cards shrink
   rather than wrap, so padding/font-size stay tight on purpose. */
.nutrition-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
  margin: 0 0 16px;
}
.nutrition-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  /* Went through grey border -> gold border -> dark-ink fill -> no
     border (owner feedback, 2026-08-19), then back to gold border
     (owner's explicit request, 2026-08-25). */
  background: var(--color-surface);
  border: 1px solid var(--color-gold);
  border-radius: var(--radius-md);
  padding: 8px 6px;
}
.nutrition-card__label {
  font-size: 9.5px;
  font-weight: 600;
  color: var(--color-ink-faint);
  overflow-wrap: break-word;
}
.nutrition-card__value {
  font-size: 12.5px;
  font-weight: 700;
  color: var(--color-ink);
  white-space: nowrap;
}

@media (min-width: 420px) {
  .nutrition-card { padding: 10px 12px; }
  .nutrition-card__label { font-size: 11px; }
  .nutrition-card__value { font-size: 15px; }
}

/* Size selector — native radio+label cards, zero JS required. Purely
   cosmetic (no cart on this site); :checked drives the selected look. */
.size-selector__heading {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--color-ink-faint);
  margin: 4px 0 8px;
}
.size-selector { display: flex; gap: 10px; margin-bottom: 16px; }
.size-card {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 14px 10px;
  /* Static white/red form-field look, always — same for both cards,
     regardless of :checked, and no hover/transition color change (owner's
     explicit request 2026-08-25: no state-dependent styling at all, just
     a plain field). */
  border: 1.5px solid var(--color-primary);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.size-card input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.size-card__label { font-size: 12.5px; font-weight: 700; color: var(--color-primary-dk); }
.size-card__price { font-size: 15px; font-weight: 700; color: var(--color-ink); }
.size-card .price-was { font-size: 0.7em; }
.size-card .price-now { color: var(--color-primary); }
.size-card:has(input:focus-visible) { outline: 2px solid var(--color-gold); outline-offset: 2px; }

/* ---------------------------------------------------------------------
   Search
   --------------------------------------------------------------------- */
.search-form {
  display: flex;
  gap: 8px;
  padding: 16px;
}
.search-form input[type="search"] {
  flex: 1;
  padding: 12px 14px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  font-size: 15px;
  font-family: var(--font-body);
  background: var(--color-surface);
  color: var(--color-ink);
}
.search-form input[type="search"]:focus { outline: 2px solid var(--color-primary); }
.search-form button {
  background: var(--color-primary);
  color: #fff;
  border: none;
  border-radius: var(--radius-pill);
  padding: 0 18px;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

.search-hint, .empty-state {
  padding: 8px 16px 24px;
  color: var(--color-ink-soft);
  font-size: 14px;
}

.search-result__category {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-primary-dk);
  font-weight: 700;
  margin: 0 0 2px;
}

/* ---------------------------------------------------------------------
   Campaigns page
   --------------------------------------------------------------------- */
.campaigns-intro {
  padding: 16px 16px 4px;
  color: var(--color-ink-soft);
  font-size: 14px;
}

/* ---------------------------------------------------------------------
   Info page
   --------------------------------------------------------------------- */
.info-block {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: 16px;
  margin: 0 16px 12px;
  box-shadow: var(--shadow-sm);
}
.info-block h2 {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: 15px;
  margin: 0 0 6px;
  color: var(--color-primary-dk);
}
.info-block p { margin: 0; font-size: 14.5px; color: var(--color-ink-soft); white-space: pre-line; }
.info-block a { color: var(--color-primary-dk); font-weight: 600; }

/* Badge legend ("what do our icons mean?") — same .info-block card shell
   as the rest of this page, a responsive icon-tile grid inside matching
   the existing ingredient/allergen icon-card language (round tile +
   label underneath) so it reads as the same design system, not a
   one-off. See templates/public/info.php + render_badge_icon() /
   chili_icon_svg() in functions.php for the icons themselves. */
.badge-legend-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
  gap: 14px;
  margin-top: 10px;
}
.badge-legend-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  text-align: center;
}
.badge-legend-card__icon {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--color-surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.badge-legend-card__icon svg { width: 20px; height: 20px; }
.badge-legend-card--star  .badge-legend-card__icon { color: var(--color-gold); }
.badge-legend-card--chef  .badge-legend-card__icon { color: var(--color-ink-soft); }
.badge-legend-card--flame .badge-legend-card__icon { color: var(--color-flame); }
.badge-legend-card--leaf  .badge-legend-card__icon { color: var(--color-it-green); }
.badge-legend-card--pepper .badge-legend-card__icon { color: var(--color-primary); }
.badge-legend-card__label {
  font-weight: 700;
  font-size: 12px;
  color: var(--color-ink);
}
.badge-legend-card__desc {
  font-size: 11px;
  color: var(--color-ink-soft);
  line-height: 1.3;
}

/* ---------------------------------------------------------------------
   Bottom navigation (data-driven — see templates/layout/bottom-nav.php)
   --------------------------------------------------------------------- */
.bottom-nav {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 40;
  display: flex;
  justify-content: space-around;
  align-items: center;
  height: var(--nav-height);
  /* Dark ink bar (2026-08-15 follow-up) — same background color as
     .topbar/.page-title-bar, not white. A white pill read as disconnected
     floating over the new beige page; matching the header's dark tone
     bookends the page (dark header at top, dark nav at bottom) and is
     the exact combo .page-title-bar already proves works well with the
     tricolor stripe. No glass/blur — a soft shadow underneath is what
     lifts it off the page. Tricolor border is drawn as a double-background
     (padding-box fill + border-box gradient) instead of border-image —
     border-image ignores border-radius and squared off this bar's rounded
     corners, caught via screenshot. This layered-background technique
     respects border-radius on both layers, so the tricolor ring stays
     curved with the pill shape. */
  background:
    linear-gradient(var(--color-ink), var(--color-ink)) padding-box,
    linear-gradient(to right,
      var(--color-it-green) 0 33.33%,
      var(--color-it-white) 33.33% 66.66%,
      var(--color-it-red) 66.66% 100%) border-box;
  border: 1px solid transparent;
  border-radius: var(--nav-radius);
  /* Lift shadow (unchanged) + a subtle tricolor glow bleeding outward from
     each side, via box-shadow — NOT the earlier filter:blur() pseudo-
     element, which broke on the owner's phone (position:fixed + a blurred
     ::before is a known bad combo in mobile Safari: it visibly knocked out
     the bar's own ink background instead of sitting behind it, screenshot
     confirmed 2026-08-15). box-shadow's own blur is a much more robust,
     widely-supported mechanism with none of that compositing risk, and is
     literally what was asked for ("dışarıya gölge gibi renkli" — a
     colored shadow-like effect outward), so this is simpler AND safer. */
  box-shadow:
    0 6px 18px rgba(35,31,32,0.22),
    -5px 0 12px -3px rgba(0,146,70,0.4),
    5px 0 12px -3px rgba(206,43,55,0.4);
}

.bottom-nav__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  /* Light on the dark bar, same muted-white treatment as .topbar__back
     etc. — var(--color-ink-soft) (a dark grey) was tuned for a white
     bar and disappeared once the background went dark. */
  color: rgba(255,255,255,0.75);
  font-size: 10.5px;
  font-weight: 600;
  flex: 1;
  padding: 6px 0;
  transition: transform 0.1s ease, color 0.15s ease;
}
.bottom-nav__item:active { transform: scale(0.92); }
.bottom-nav__item svg { width: 22px; height: 22px; transition: transform 0.15s ease; }
/* Gold, not red, for the selected tab (2026-08-15 follow-up) — red is
   reserved sitewide for campaign/discount pricing (see .product-row__price
   comment above), so reusing it here both blurs that meaning and, sitting
   next to the border's own red third, read as "too much red" on this bar.
   Gold is the site's other standing accent (badges, card borders) and
   reads calmer against the dark ink + tricolor combination. */
.bottom-nav__item.is-active { color: var(--color-gold); }
.bottom-nav__item.is-active svg { transform: translateY(-1px); }

/* Hover affordance for pointer devices only (trackpad/mouse on the
   tablet widths where this bar is still shown — @media(hover:hover)
   keeps it from "sticking" on a touch tap, which has no true hover
   state). Inactive icons lighten from the muted 0.75 opacity to full
   white; kept short of gold so hover and "current page" stay visually
   distinct from each other. */
@media (hover: hover) {
  .bottom-nav__item:not(.is-active):hover { color: #fff; }
}

/* Icon-only at rest — the label and its little indicator bar only appear
   on whichever tab is currently active, per the reference "expand on
   select" nav pattern. Each is a full page navigation (not an SPA), so
   the state change is just which item the server marks .is-active — no
   JS or transition choreography needed for the click itself. */
.bottom-nav__item-label { display: none; }
.bottom-nav__item.is-active .bottom-nav__item-label { display: block; }

.bottom-nav__item-indicator {
  display: none;
  width: 20px;
  height: 3px;
  border-radius: var(--radius-pill);
  background: var(--color-gold); /* matches .is-active icon color, see above */
  margin-top: 2px;
}
.bottom-nav__item.is-active .bottom-nav__item-indicator { display: block; }

/* Desktop drops the bottom nav entirely (client decision — mouse/keyboard
   users navigate via the topbar back button + logo + clicking through
   category/product cards, no nav menu is added in its place). Tablet
   (768–1023px) keeps the mobile bottom-nav bar as-is, same threshold the
   rest of this stylesheet already uses for "desktop". body's reserved
   bottom padding (see the base `body` rule) existed only to clear the
   fixed nav, so it's reset to plain breathing room once the nav is gone. */
@media (min-width: 1024px) {
  .bottom-nav { display: none; }
  body { padding-bottom: 32px; }
}

/* ---------------------------------------------------------------------
   404
   --------------------------------------------------------------------- */
.not-found {
  padding: 60px 16px;
  text-align: center;
}
.not-found h1 { font-family: var(--font-heading); font-weight: 600; font-size: 28px; }

/* ---------------------------------------------------------------------
   Utility
   --------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* ---------------------------------------------------------------------
   Reduced motion — every transform-based transition/animation on the
   public site neutralized in one place, rather than scattered per rule.
   Simple opacity/color transitions are left alone (they're not
   vestibular-triggering and still help comprehension — e.g. hover
   states, the language chevron's color). Anything that scales, slides,
   or rotates is dropped to an instant or opacity-only equivalent.
   --------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .lang-menu__chevron { transition: none; }
  .category-tile { transition: box-shadow 0.15s ease; }
  .category-tile:active,
  .bottom-nav__item:active,
  .product-row:active,
  .lang-menu__current:active { transform: none; }
  .bottom-nav__item, .bottom-nav__item svg { transition: none; }
  .bottom-nav__item.is-active svg { transform: none; }
  .product-gallery__dot { transition: none; }
  .product-row { transition: none; }
}
