/* ==========================================================================
   Maharaj Pyrotech — storefront styles
   Palette sampled directly from the shop's own promotional poster
   (public/images/pyro2.jpg): black night ground, gold lion-crest gold,
   and a spectrum of firework colours used as signature hues per category.
   Authored mobile-first: base rules target phones, desktop layers on at
   min-width breakpoints (640 / 860 / 1024px).
   ========================================================================== */

:root {
  /* Brand tokens (Part 0b) — this is the dark theme, and stays the
     default (no data-theme attribute) so a cached page or JS-disabled
     visitor still gets the shop's intended look. See the [data-theme
     ="light"] block below for the alternate palette and THEME.md-style
     notes on what had to change beyond a straight variable swap. */
  --night: #08060a;
  --night-2: #120a1b;
  --panel: #17111f;
  --panel-2: #1d1526;
  --tile: #efe6d8; /* warm, light product-photo background — most source photos are shot on white/cream, so this is what shows around a contained (not cropped) image instead of a bright white flash against the dark theme */
  --panel-border: rgba(242, 178, 26, 0.16);
  --ink: #f6f1e8;
  --muted: rgba(246, 241, 232, 0.68);
  --gold: #f2b21a;
  --gold-lit: #ffd35c;
  --red: #e0212b;
  --magenta: #c42bd6;
  --violet: #8e2de2;
  --emerald: #17b978;
  --cyan: #16a9c9;
  --paper: #ffffff; /* the brightest heading tone — white on this dark theme, but this is NOT literally "white": light theme below repoints it to its darkest ink so headings stay readable rather than turning invisible-white-on-white */
  --header-blur-bg: rgba(8, 6, 10, 0.9); /* sticky header's translucent backdrop, tied to the page background rather than any single surface token */
  --header-h: 74px; /* measured live by chrome-scroll.js; this is only the pre-JS/no-JS fallback */

  --burst: linear-gradient(90deg, var(--gold), var(--red), var(--magenta), var(--violet), var(--cyan));

  --shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
  --shadow-sm: 0 10px 24px rgba(0, 0, 0, 0.4);
  --radius-xl: 26px;
  --radius-lg: 18px;
  --radius-md: 12px;
  --wrap: 1180px;
  --gutter: 20px;

  --font-display: "Manrope", system-ui, sans-serif;
  --font-script: "DM Serif Display", Georgia, serif;

  color-scheme: dark;
}

/* ---- Light theme --------------------------------------------------------
   Toggled by theme.js via [data-theme="light"] on <html> (persisted in
   localStorage) — an explicit opt-in for anyone who finds the dark theme
   hard on the eyes, not a replacement for it. Re-pointing this fixed list
   of tokens covers the large majority of the page, since nearly every rule
   in this file already reads its colour from one of them — a few spots
   that hardcoded a dark-surface-specific tone instead (mainly --paper's
   old "just use white" assumption, and the two other properties redefined
   here) needed the explicit fix above rather than a token alone. */
[data-theme="light"] {
  --night: #f7f4ef;
  --night-2: #ffffff;
  --panel: #ffffff;
  --panel-2: #f2eee5;
  --tile: #f2eee5;
  --panel-border: rgba(40, 28, 12, 0.14);
  --ink: #221a12;
  --muted: rgba(34, 26, 18, 0.64);
  --gold-lit: #a3690a; /* the dark palette's pale near-white gold (#ffd35c) is price/accent TEXT throughout the site — unreadably faint on white, so light mode gets its own deep amber for that same role. --gold itself (used mostly as a background/border fill, not text) is kept as-is */
  --paper: var(--ink); /* headings that were "bright white on dark" become "darkest ink on light" instead of vanishing */
  --header-blur-bg: rgba(255, 255, 255, 0.86);

  --shadow: 0 24px 60px rgba(30, 20, 10, 0.14);
  --shadow-sm: 0 10px 24px rgba(30, 20, 10, 0.1);

  color-scheme: light;
}

/* Per-category signature colours, applied via [data-color="..."] on chips,
   product cards, badges and artwork wrappers. */
[data-color="gold"] { --cat: var(--gold-lit); }
[data-color="red"] { --cat: var(--red); }
[data-color="magenta"] { --cat: var(--magenta); }
[data-color="violet"] { --cat: var(--violet); }
[data-color="emerald"] { --cat: var(--emerald); }
[data-color="cyan"] { --cat: var(--cyan); }

* {
  box-sizing: border-box;
}

/* Author `display` rules (e.g. `.price-list{display:table}` — a table's
   own default display) beat the browser's default `[hidden]{display:none}`
   at equal specificity, so any element toggled via the `hidden` property
   needs this to actually disappear — confirmed broken for #priceList
   without it, since JS sets `table.hidden = true` for an empty search but
   the table's own default display silently overrode it. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-display);
  color: var(--ink);
  background: var(--night);
  min-height: 100vh;
  overflow-x: hidden;
  -webkit-tap-highlight-color: transparent;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: 0;
}

.wrap {
  width: min(calc(100% - var(--gutter) * 2), var(--wrap));
  margin: 0 auto;
}

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

:focus-visible {
  outline: 2px solid var(--gold-lit);
  outline-offset: 2px;
  border-radius: 4px;
}

h1, h2, h3 {
  margin: 0;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: -0.01em;
  line-height: 1.05;
}

h1 i, h2 i {
  font-family: var(--font-script);
  font-style: italic;
  font-weight: 400;
  text-transform: none;
  color: var(--gold-lit);
  display: inline-block;
}

.eyebrow {
  margin: 0 0 12px;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  font-size: 0.75rem;
  font-weight: 800;
}
.eyebrow.gold { color: var(--gold-lit); }
.eyebrow.red { color: var(--red); }

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 14px 22px;
  min-height: 48px;
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.92rem;
  transition: transform 160ms ease, box-shadow 160ms ease, filter 160ms ease;
}
.button:hover, .button:focus-visible { transform: translateY(-2px); }
.button.light {
  background: var(--burst);
  color: #140a06;
  box-shadow: 0 14px 30px rgba(224, 33, 43, 0.35);
}
.button.dark {
  background: var(--panel-2);
  color: var(--ink);
  border: 1px solid var(--panel-border);
}
.button.red-button {
  background: linear-gradient(145deg, var(--red), #ff5a63);
  color: #fff;
  box-shadow: 0 14px 26px rgba(224, 33, 43, 0.4);
}

.text-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  color: var(--gold-lit);
  min-height: 44px;
}
.text-link.pale { color: var(--muted); }
.under-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-weight: 600;
  min-height: 44px;
}

.section-heading { margin-bottom: 22px; }
.section-heading h2 { font-size: clamp(1.5rem, 4vw, 1.9rem); max-width: 16ch; }
.section-heading.split {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* ---- Offer strip (marquee) --------------------------------------------- */

.offer-strip {
  background: linear-gradient(90deg, #7a0f16, var(--red), #7a0f16);
  overflow: hidden;
  white-space: nowrap;
  padding: 8px 0;
}
.offer-strip div {
  display: inline-block;
  padding-left: 100%;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: #fff5df;
  animation: marquee 26s linear infinite;
}
@keyframes marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}

/* ---- Header / nav ------------------------------------------------------- */

.header {
  position: sticky;
  top: 0;
  /* Above .nav-clip (45) so the hamburger button stays visible and
     clickable — to close the drawer, not just to open it — while the
     off-canvas nav is open; below the assistant panel (50) so it still
     overlays the header. */
  z-index: 46;
  border-bottom: 1px solid var(--panel-border);
  /* `none`, not `translateY(0)` — the two look equivalent at rest but are
     not: ANY transform value, including a zero one, makes the element a
     containing block for its own `position: fixed` descendants. #mainNav's
     off-canvas drawer (`.nav-clip`, `inset: 0`) lives inside this header,
     and `translateY(0)` here previously trapped that `inset: 0` inside the
     header's own ~70px box instead of the viewport — the exact bug
     .header::before's comment already warns about for backdrop-filter.
     `none` still transitions to `translateY(-100%)` below just fine (`none`
     interpolates as the identity matrix), without ever creating that
     containing block. */
  transform: none;
  transition: transform 220ms ease;
}
/* Slides the whole header off-screen while scrolling down (see
   chrome-scroll.js). Once scrolled past its own natural position, a
   sticky element is purely a viewport overlay — this reserves no ongoing
   layout space at the current scroll position, so hiding it via transform
   genuinely reveals the content it was covering rather than leaving a
   blank gap. .catalogue-tools below relies on the same property. */
body.chrome-hidden .header { transform: translateY(-100%); }
.header::before {
  /* The blurred glass background lives on a pseudo-element, not on
     .header itself: an element with `backdrop-filter` becomes a new
     containing block for its own `position: fixed` descendants (same
     category as `transform`/`filter`), which would trap .nav-clip's
     `inset: 0` inside the header's own ~70px box instead of the
     viewport — confirmed by measuring it collapse to exactly the
     header's height, clipping every nav link out of view. */
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--header-blur-bg);
  backdrop-filter: blur(14px);
}
.header-top {
  display: none;
  gap: 20px;
  padding: 8px 0;
  font-size: 0.78rem;
  color: var(--muted);
}
.header-top a:hover { color: var(--gold-lit); }

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 0;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}
.logo .crest {
  width: 34px;
  height: 34px;
  color: var(--gold-lit);
  flex: none;
}
/* The crest artwork is a circle already touching every edge of its own
   (cropped) square image, so a round mask removes the square corner
   entirely without needing a transparent source file. */
.crest img, .login-crest img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}
.logo strong {
  display: flex;
  flex-direction: column;
  font-size: 0.98rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  line-height: 1.15;
}
.logo strong b { color: var(--gold-lit); font-weight: 800; }
.logo strong small {
  text-transform: none;
  font-weight: 500;
  font-size: 0.68rem;
  color: var(--muted);
  letter-spacing: 0;
}

.menu-button {
  display: grid;
  place-items: center;
  gap: 4px;
  width: 44px;
  height: 44px;
  border-radius: 12px;
  /* .nav-clip is a sibling with z-index:45 inside this same .header
     stacking context, so without its own stacking position the button
     would paint underneath the open drawer and become unclickable —
     this keeps the hamburger tappable to close the drawer, not just open it. */
  position: relative;
  z-index: 46;
}
.menu-button i {
  display: block;
  width: 20px;
  height: 2px;
  background: var(--ink);
  border-radius: 2px;
  transition: transform 200ms ease, opacity 200ms ease;
}
.menu-button[aria-expanded="true"] i:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.menu-button[aria-expanded="true"] i:nth-child(2) { opacity: 0; }
.menu-button[aria-expanded="true"] i:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* .nav-clip is a viewport-sized, overflow-hidden, click-through wrapper.
   #mainNav slides inside it via `position: absolute` (not fixed) so its
   translated-off-screen geometry is clipped by the wrapper rather than
   escaping into the document — a bare `position: fixed` + `transform`
   drawer here would otherwise force mobile browsers (confirmed in Chromium)
   to grow the layout viewport to fit the off-screen box, breaking every
   other percentage/vw-based measurement on the page. */
.nav-clip {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 45;
}
#mainNav {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(84vw, 340px);
  height: 100%;
  background: var(--night-2);
  border-left: 1px solid var(--panel-border);
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 90px 28px 28px;
  transform: translateX(100%);
  transition: transform 240ms ease;
  pointer-events: auto;
}
#mainNav.open { transform: translateX(0); }
#mainNav a {
  padding: 14px 4px;
  font-weight: 700;
  font-size: 1.05rem;
  border-bottom: 1px solid var(--panel-border);
  min-height: 44px;
  display: flex;
  align-items: center;
}
#mainNav a:hover, #mainNav a:focus-visible { color: var(--gold-lit); }

.theme-toggle {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  border-radius: 50%;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
}
.theme-toggle svg { width: 19px; height: 19px; stroke: var(--gold-lit); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.theme-toggle .icon-moon { display: none; fill: var(--gold-lit); stroke: none; }
[data-theme="light"] .theme-toggle .icon-sun { display: none; }
[data-theme="light"] .theme-toggle .icon-moon { display: block; }

.cart-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 14px;
  min-height: 44px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
}
.cart-button svg { width: 18px; height: 18px; stroke: var(--gold-lit); fill: none; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.cart-button span { display: none; font-weight: 700; font-size: 0.85rem; }
.cart-button b {
  display: inline-grid;
  place-items: center;
  min-width: 22px;
  height: 22px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--burst);
  color: #140a06;
  font-size: 0.75rem;
  font-weight: 800;
}

/* ---- Hero ---------------------------------------------------------------- */

/* Minimal hero — just the two entry actions, nothing above them, so the
   page reaches the catalogue immediately with no scrolling.
   The shop's own Diwali poster (the full image, not a cropped watermark)
   appears here as a real, contained <img> on mobile only — see
   .hero-poster below and its display:none override at 860px, where the
   poster instead lives further down in the About section. */
.hero {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(ellipse at 15% 0%, rgba(196, 43, 214, 0.22), transparent 50%),
    radial-gradient(ellipse at 85% 10%, rgba(22, 169, 201, 0.18), transparent 50%),
    var(--night);
}
.hero-content {
  padding: 28px 0 36px;
}
.hero-poster {
  /* Fills the same width as .about-image below (its wrap's full content
     width) rather than an arbitrary smaller cap — a fixed max-width here
     left it looking like a small floating card with excess dark space
     around it, while the About section's copy of this same poster (no
     such cap) properly fills its container. */
  display: block;
  width: 100%;
  height: auto;
  margin: 0 auto 24px;
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
}
.hero-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.hero-actions .button { width: 100%; }
.hero-actions .under-link { justify-content: center; }

/* ---- Ordering ------------------------------------------------------------ */

.ordering { padding: 56px 0 24px; }
.section-number {
  display: flex;
  align-items: baseline;
  gap: 12px;
  margin-bottom: 20px;
  color: var(--muted);
}
.section-number b { font-size: 1.6rem; color: var(--gold-lit); font-weight: 800; }
.section-number span { font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.1em; }

.ordering-copy h2 { font-size: clamp(1.5rem, 4vw, 1.9rem); max-width: 16ch; }
.ordering-copy p { color: var(--muted); line-height: 1.7; margin: 14px 0; }

.order-steps {
  display: grid;
  gap: 14px;
  margin-top: 28px;
}
.order-steps article {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.order-steps b { color: var(--gold-lit); font-size: 1.3rem; font-weight: 800; }
.order-steps h3 { margin: 10px 0 6px; font-size: 1rem; }
.order-steps p { margin: 0; color: var(--muted); font-size: 0.9rem; line-height: 1.55; }

/* ---- Catalogue ------------------------------------------------------------ */

.catalogue { padding: 24px 0 60px; }

/* Sticks the search/category/sort row under the header as the product list
   scrolls, so changing filter never needs a scroll back to the top. This
   replaced a sticky category chip row + a 220px desktop sidebar, both of
   which permanently occupied layout space; the category picker is now the
   floating dropdown below, so this compact row is all that stays on screen. */
.catalogue-tools {
  position: sticky;
  top: var(--header-h); /* set live by chrome-scroll.js; :root's fallback covers pre-JS */
  z-index: 6;
  background: var(--night);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 10px 0;
  margin-bottom: 8px;
  transform: translateY(0);
  transition: transform 220ms ease;
}
/* Moves as one block with .header (same reasoning: translateY(-100%) on
   its own would only clear its own height, leaving it parked in the
   header-height gap left behind — this adds that gap's height too). */
body.chrome-hidden .catalogue-tools { transform: translateY(calc(-100% - var(--header-h))); }

/* Collapsed: a round icon button, sized and styled like .category-trigger
   so the row reads as one pair of matching controls rather than a text
   box next to a pill. Expanded: grows to fill the row (the category
   dropdown yields — see .catalogue-tools.search-open below) with the
   real input and a clear/close button, all still inside the same
   pill so nothing visually jumps between the two states. */
.search-box {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  min-height: 48px;
  width: 48px;
  overflow: hidden;
  transition: width 200ms ease;
  flex: none;
}
.search-box.expanded { width: 100%; flex: 1; padding-right: 6px; }
.search-toggle {
  width: 48px;
  height: 48px;
  flex: none;
  display: grid;
  place-items: center;
}
.search-toggle svg { width: 18px; height: 18px; stroke: var(--muted); fill: none; stroke-width: 2; }
.search-box input {
  border: 0;
  background: none;
  outline: none;
  flex: 1;
  min-width: 0;
  width: 0; /* collapsed by default; .expanded below is what actually gives it room */
  opacity: 0;
  font-size: 16px; /* prevents iOS zoom-on-focus */
  color: var(--ink);
  transition: opacity 160ms ease;
}
.search-box.expanded input { width: auto; opacity: 1; }
.search-box input::placeholder { color: var(--muted); }
.search-clear {
  width: 32px;
  height: 32px;
  flex: none;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: 1.2rem;
  line-height: 1;
  color: var(--muted);
  border-radius: 50%;
}
.search-box.expanded .search-clear:not([hidden]) { display: flex; }
.search-clear:hover { color: var(--red); }

/* The search box and the category trigger share one row; when search is
   open there isn't room for both, and the category picker is the one that
   yields — search is the transient action, category is the standing
   filter, so it's the one worth keeping visually stable when both aren't
   needed at once. */
.catalogue-tools.search-open .category-dropdown { display: none; }

.catalogue-layout {
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* Category picker: a compact trigger that opens a floating panel, rather
   than a permanently-parked chip row (mobile) / 220px sidebar (desktop).
   The panel is absolutely positioned so it overlays the product list
   instead of pushing it down, and closes on pick / outside click / Escape
   (see wireCategoryDropdown in script.js). */
.category-dropdown { position: relative; }
.category-trigger {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 0 16px;
  min-height: 48px;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--muted);
  text-align: left;
}
.category-trigger > span {
  flex: none;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 800;
}
.category-trigger b {
  flex: 1;
  min-width: 0;
  color: var(--ink);
  font-size: 0.9rem; /* not 16px like the inputs — this is a button, so it can't trigger iOS zoom-on-focus, and the longest category name ("One Sound Crackers") only fits unclipped below 16px */
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.category-trigger .chev {
  width: 16px;
  height: 16px;
  flex: none;
  stroke: var(--muted);
  fill: none;
  stroke-width: 2.4;
  transition: transform 160ms ease;
}
.category-trigger[aria-expanded="true"] { border-color: var(--gold); }
.category-trigger[aria-expanded="true"] .chev { transform: rotate(180deg); }
.category-menu {
  position: absolute;
  z-index: 20;
  top: calc(100% + 6px);
  left: 0;
  right: 0;
  min-width: 240px;
  max-height: min(58vh, 420px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--night-2);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  padding: 8px;
  box-shadow: 0 20px 46px rgba(0, 0, 0, 0.5);
}
#categoryFilters {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.filter-chip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  width: 100%;
  padding: 9px 14px;
  min-height: 42px;
  border-radius: var(--radius-md);
  background: var(--panel);
  border: 1px solid var(--panel-border);
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted);
  text-align: left;
}
.filter-chip b {
  font-weight: 800;
  font-size: 0.72rem;
  color: var(--night);
  background: var(--muted);
  border-radius: 999px;
  padding: 1px 7px;
}
.filter-chip[aria-pressed="true"] {
  color: var(--night);
  background: var(--cat, var(--gold-lit));
  border-color: transparent;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.35);
}
.filter-chip[aria-pressed="true"] b { background: rgba(8, 6, 10, 0.25); color: inherit; }

.product-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 0.82rem;
  color: var(--muted);
}
#clearFilters {
  color: var(--gold-lit);
  font-weight: 700;
  min-height: 44px;
}

/* Shared badge look — "Best seller" and the discount pill appear both
   inline in a price-list row and floated over the standalone product
   page's photo, so the position rule (absolute, for the photo overlay) is
   kept separate from the shared colour/shape rule below rather than
   duplicated per context. */
.badge-best {
  display: inline-block;
  background: var(--burst);
  color: #140a06;
  font-size: 0.55rem;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 999px;
  text-transform: uppercase;
}
.badge-discount {
  display: inline-block;
  background: var(--night);
  color: var(--gold-lit);
  border: 1px solid var(--cat, var(--gold));
  font-size: 0.58rem;
  font-weight: 800;
  padding: 2px 6px;
  border-radius: 999px;
}
.product-page-image .badge-best, .product-page-image .badge-discount {
  position: absolute;
  top: 6px;
}
.product-page-image .badge-best { left: 6px; }
.product-page-image .badge-discount { right: 6px; }

/* ---- Catalogue price list ---------------------------------------------
   A compact table — thumbnail, name/Tamil/pack-size, struck MRP over the
   offer price, a −/qty/+ box, and a row total — grouped under category
   header bands, matching how Sivakasi cracker sites conventionally list
   their catalogue. Deliberately dense: the target is several rows visible
   on screen at once rather than one large card per product. Mobile-first,
   with the wider desktop columns layered on at 640px below. */

.price-list-scroll {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.price-list {
  width: 100%;
  /* Fixed layout so the column widths below are authoritative — with the
     browser's default auto layout, a long product name pushed .col-title
     wider than intended, forcing the table past 390px and hiding the Qty
     and Total columns behind an unwanted internal horizontal scroll.
     Fixed layout instead makes the title column wrap and every row still
     shows its price/qty/total without scrolling, even on a small phone. */
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.price-list thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--night-2);
  color: var(--muted);
  text-transform: uppercase;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  font-weight: 800;
  text-align: left;
  padding: 7px 6px;
  border-bottom: 1px solid var(--panel-border);
}
.price-list thead .col-price, .price-list thead .col-amount { text-align: right; }
.price-list thead .col-qty { text-align: center; }

.cat-row th {
  text-align: left;
  padding: 7px 8px;
  background: linear-gradient(90deg, rgba(224, 33, 43, 0.92), rgba(224, 33, 43, 0.5));
  /* Always light text: this band's own red background is a fixed brand
     colour, not theme-dependent (unlike --paper, which now flips to a
     dark ink in the light theme for headings that sit on the page's own
     surface instead) — the two must stay decoupled. */
  color: #fff5df;
  font-weight: 800;
  font-size: 0.74rem;
  letter-spacing: 0.02em;
  border-top: 1px solid var(--panel-border);
  border-bottom: 1px solid var(--panel-border);
}
.cat-row .cat-tamil {
  display: block;
  font-weight: 600;
  font-size: 0.66rem;
  color: rgba(255, 255, 255, 0.85);
  margin-top: 1px;
}

.price-row { background: var(--panel); border-bottom: 1px solid var(--panel-border); }
.price-row.odd { background: var(--panel-2); }
.price-row.in-cart { box-shadow: inset 3px 0 0 var(--cat, var(--gold)); }
.price-row td { padding: 5px; vertical-align: middle; }

.col-image { width: 32px; }
.row-thumb {
  display: block;
  width: 28px;
  height: 28px;
  border-radius: 6px;
  overflow: hidden;
  background: var(--tile);
  padding: 2px;
}
.row-thumb img { width: 100%; height: 100%; object-fit: contain; }

/* No width set — table-layout:fixed gives every column with an explicit
   width exactly that, and hands this one column whatever's left over. */
.col-title { overflow-wrap: break-word; }
.row-title-link {
  display: block;
  color: var(--ink);
  font-weight: 700;
  font-size: 0.76rem;
  line-height: 1.2;
}
.row-title-link:hover, .row-title-link:focus-visible { color: var(--gold-lit); }
.row-tamil { display: block; color: var(--muted); font-size: 0.64rem; margin-top: 1px; }
.row-pack-size {
  display: inline-block;
  margin-top: 2px;
  font-size: 0.58rem;
  font-weight: 700;
  color: var(--gold-lit);
  background: rgba(242, 178, 26, 0.12);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 1px 6px;
}
.col-title .badge-best { margin-top: 2px; }

.col-price { width: 56px; text-align: right; }
.col-price .list-price { display: block; text-decoration: line-through; color: var(--muted); font-size: 0.58rem; }
.col-price .offer-price { display: block; color: var(--gold-lit); font-weight: 800; font-size: 0.72rem; }
.col-price .badge-discount { margin-top: 2px; font-size: 0.5rem; padding: 1px 4px; }

.col-qty { width: 82px; }
.qty-stepper { display: flex; align-items: center; justify-content: center; gap: 1px; }
.qty-stepper button {
  width: 22px;
  height: 22px;
  min-width: 22px;
  border-radius: 6px;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
  color: var(--ink);
  font-weight: 800;
  font-size: 0.82rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 140ms ease, color 140ms ease;
}
.qty-stepper button:hover { background: var(--cat, var(--gold)); color: var(--night); border-color: transparent; }
.qty-input {
  width: 26px;
  height: 22px;
  border-radius: 6px;
  border: 1px solid var(--panel-border);
  background: var(--night-2);
  color: var(--ink);
  text-align: center;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 0;
  -moz-appearance: textfield;
}
.qty-input::-webkit-outer-spin-button, .qty-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.col-amount { width: 48px; text-align: right; }
.amount-value { font-weight: 800; color: var(--ink); font-size: 0.78rem; }
.price-row.in-cart .amount-value { color: var(--gold-lit); }

/* ---- Sticky Grand Total bar --------------------------------------------
   Fixed to the viewport bottom like the reference sites' summary bar.
   Sits below the cart/assistant panels and their shared scrim (see the
   z-index scale near those rules) so it never competes with an open
   overlay, and stays clear of the assistant launcher FAB at bottom-right. */
.grand-total-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 28; /* below the assistant launcher FAB (30) and the scrim (35), same as everything that must yield to an open overlay */
  background: var(--night-2);
  border-top: 1px solid var(--panel-border);
  box-shadow: 0 -10px 24px rgba(0, 0, 0, 0.4);
  padding: 10px 0;
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  transform: translateY(0);
  transition: transform 220ms ease;
}
/* Fixed (not sticky), so — unlike .header/.catalogue-tools above — this
   never reserved layout space to begin with; sliding it off never leaves
   a gap. The reserved `body:has(#grandTotalBar:not([hidden]))` padding a
   little further down stays constant regardless of hidden/visible, which
   is what stops the page height (and scroll position) jumping every time
   this toggles. */
body.chrome-hidden .grand-total-bar { transform: translateY(100%); }
.grand-total-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-right: 76px; /* clears the assistant launcher FAB */
}
.grand-total-figures { display: flex; flex-direction: column; min-width: 0; }
.grand-total-figures span { font-size: 0.64rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--muted); font-weight: 800; }
.grand-total-figures b { font-size: 1.1rem; color: var(--gold-lit); }
.grand-total-figures small { color: var(--muted); font-size: 0.68rem; }
.grand-total-bar .button { flex: none; white-space: nowrap; }
/* A visible Grand Total bar reserves its own height at the foot of the
   page so the last catalogue row is never hidden behind it. */
body:has(#grandTotalBar:not([hidden])) { padding-bottom: 64px; }

.empty {
  text-align: center;
  padding: 60px 20px;
  color: var(--muted);
}
.empty b { display: block; color: var(--ink); font-size: 1.1rem; margin-bottom: 8px; }

/* ---- Notice ---------------------------------------------------------------- */

.notice {
  background: var(--night-2);
  border-top: 1px solid var(--panel-border);
  border-bottom: 1px solid var(--panel-border);
  padding: 36px 0;
}
.notice .wrap {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.notice > .wrap > span {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--red);
  color: #fff;
  font-weight: 900;
  font-size: 1.3rem;
}
.notice h2 { font-size: clamp(1.25rem, 3.5vw, 1.5rem); max-width: 20ch; }
.notice > .wrap > p { color: var(--muted); line-height: 1.7; margin: 0; }

/* ---- About ------------------------------------------------------------- */

.about { padding: 48px 0; display: flex; flex-direction: column; gap: 26px; }
.about-image {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.about-poster { display: block; width: 100%; height: auto; }
.about h2 { font-size: clamp(1.5rem, 4vw, 1.8rem); max-width: 16ch; }
.about p { color: var(--muted); line-height: 1.7; }
.brands-stocked { font-size: 0.9rem; }
.brands-stocked b { color: var(--gold-lit); }
.qualities {
  display: grid;
  gap: 12px;
  margin-top: 20px;
}
.qualities b {
  display: block;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 14px 16px;
  font-size: 0.92rem;
}
.qualities small { display: block; margin-top: 4px; font-weight: 500; color: var(--muted); }

/* ---- Safety ------------------------------------------------------------- */

.safety { background: var(--night-2); padding: 48px 0; }
.safety .wrap { display: flex; flex-direction: column; gap: 26px; }
.safety-copy h2 { font-size: clamp(1.5rem, 4vw, 1.8rem); max-width: 16ch; }
.safety-copy p { color: var(--muted); line-height: 1.7; margin: 14px 0 20px; }
.safety-list { display: grid; gap: 10px; }
.safety-list p {
  margin: 0;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 14px;
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.55;
  display: flex;
  gap: 10px;
}
.safety-list b { color: var(--gold-lit); flex: none; }

/* ---- Contact ------------------------------------------------------------- */

.contact { padding: 48px 0 60px; display: flex; flex-direction: column; gap: 30px; }
.contact h2 { font-size: clamp(1.5rem, 4vw, 1.8rem); max-width: 16ch; }
.contact > div > p { color: var(--muted); line-height: 1.7; }
.contact-details { display: grid; gap: 10px; margin: 16px 0; }
.contact-details a, .contact-details span {
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  font-weight: 700;
}
.contact-details small { color: var(--muted); font-weight: 500; font-size: 0.75rem; margin-bottom: 2px; }
.whatsapp {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: #25d366;
  font-weight: 800;
  min-height: 44px;
}

.contact-form, #checkoutForm {
  display: flex;
  flex-direction: column;
  gap: 14px;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.form-row { display: flex; flex-direction: column; gap: 14px; }
.contact-form label, #checkoutForm label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--muted);
}
.contact-form input, .contact-form textarea,
#checkoutForm input, #checkoutForm textarea {
  width: 100%; /* belt-and-braces alongside the flex-stretch parent — a bare <input> has its own browser-default min-content width that ignores flex shrinking otherwise */
  box-sizing: border-box;
  background: var(--night-2);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  font-size: 16px;
  color: var(--ink);
  outline: none;
}
.contact-form input:focus, #checkoutForm input:focus,
.contact-form textarea:focus, #checkoutForm textarea:focus {
  border-color: var(--gold);
}
.check {
  flex-direction: row !important;
  align-items: flex-start;
  gap: 10px !important;
}
.check input { width: 20px; height: 20px; flex: none; margin-top: 2px; }
.form-error {
  color: var(--red);
  background: rgba(224, 33, 43, 0.12);
  border: 1px solid rgba(224, 33, 43, 0.35);
  border-radius: var(--radius-md);
  padding: 10px 14px;
  font-size: 0.85rem;
}

/* ---- Footer --------------------------------------------------------------- */

footer {
  background: var(--night-2);
  border-top: 1px solid var(--panel-border);
  padding: 40px 0 20px;
}
.footer-grid {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.footer-grid .crest { width: 30px; height: 30px; color: var(--gold-lit); }
.footer-grid > p { color: var(--muted); font-size: 0.88rem; line-height: 1.6; margin: 0; }
.footer-grid nav { display: flex; flex-wrap: wrap; gap: 16px; }
.footer-grid nav a { color: var(--muted); font-size: 0.88rem; min-height: 44px; display: flex; align-items: center; }
.footer-phone { color: var(--gold-lit); font-weight: 800; min-height: 44px; display: flex; align-items: center; gap: 6px; }
.footer-bottom {
  margin-top: 26px;
  padding-top: 18px;
  border-top: 1px solid var(--panel-border);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.75rem;
  color: var(--muted);
}

/* ---- Cart panel ------------------------------------------------------------- */

.scrim {
  position: fixed;
  inset: 0;
  background: rgba(4, 3, 6, 0.65);
  backdrop-filter: blur(3px);
  /* Below the header (40) and nav drawer (45) so the sticky header stays
     clickable (the hamburger still works to close the drawer) and the open
     drawer itself isn't dimmed by its own backdrop; still above ordinary
     page content so that content reads as non-interactive while it's up. */
  z-index: 35;
}

.region {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 14px 0;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--muted);
}
.region select {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  font-size: 16px;
  color: var(--ink);
}
.qty-stepper {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: none;
}
.qty-stepper button {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--panel-2);
  font-weight: 800;
  font-size: 0.85rem;
  display: grid;
  place-items: center;
}
.qty-stepper span { min-width: 16px; text-align: center; font-weight: 700; font-size: 0.8rem; }
.order-minimum {
  margin: 10px 0;
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: var(--panel);
  border: 1px solid var(--panel-border);
  font-size: 0.82rem;
  color: var(--muted);
}
.order-minimum.met { color: var(--emerald); border-color: rgba(23,185,120,0.4); }
.cart-total {
  padding-top: 12px;
  border-top: 1px solid var(--panel-border);
}
.cart-total > div {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 8px;
}
.cart-total b { font-size: 1.3rem; color: var(--gold-lit); }
.cart-total p { margin: 0 0 12px; font-size: 0.75rem; color: var(--muted); }

/* ---- Cart page (cart.html) ---------------------------------------------
   A full page, not a slide-in panel, specifically so there's real vertical
   room: each row is a fixed, compact height and the list itself scrolls,
   which is what makes 8+ rows fit inside a 390x844 viewport (verified) —
   the old panel's own chrome (header, region select, totals, all sharing
   one 88dvh sheet) left room for about 6 at best. */
.cart-page { padding: 32px 0 60px; }
.cart-page h1 { font-size: clamp(1.4rem, 4vw, 1.8rem); margin: 4px 0 18px; }
.cart-page-empty { text-align: center; padding: 60px 10px; color: var(--muted); }
.cart-page-empty .button { margin-top: 16px; }
.cart-page-toolbar { display: flex; align-items: flex-end; justify-content: space-between; gap: 12px; }
.cart-page-toolbar .region { margin: 14px 0 0; flex: 1; }
.text-link.danger { color: var(--red); }
.cart-page-items {
  display: grid;
  grid-template-columns: minmax(0, 1fr); /* without an explicit track, an implicit grid column auto-sizes to its widest row's max-content instead of the container width, letting rows overflow sideways */
  gap: 6px;
  margin: 14px 0;
  max-height: 60vh;
  overflow-y: auto;
  padding: 2px;
}
.cart-page-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-md);
  padding: 6px 8px;
}
.cart-page-row img { width: 36px; height: 36px; border-radius: 7px; object-fit: contain; background: var(--tile); padding: 2px; flex: none; }
.cart-page-row .info { flex: 1; min-width: 0; display: flex; flex-direction: column; justify-content: center; text-decoration: none; }
.cart-page-row .info b {
  display: block;
  color: var(--ink);
  font-size: 0.82rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cart-page-row .info small { color: var(--muted); font-size: 0.7rem; white-space: nowrap; }
.cart-page-row-price {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  row-gap: 1px;
  column-gap: 5px;
}
.cart-page-row-price .list-price { text-decoration: line-through; color: var(--muted); font-size: 0.64rem; flex: none; }
.cart-page-row-price .offer-price { color: var(--gold-lit); font-weight: 700; font-size: 0.7rem; flex: none; }
.cart-page-row-price .badge-discount { font-size: 0.54rem; padding: 1px 5px; flex: none; }
.cart-page-row .qty-stepper button { width: 22px; height: 22px; font-size: 0.78rem; }
.cart-page-row-amount { flex: none; width: 58px; text-align: right; color: var(--gold-lit); font-size: 0.78rem; }
.cart-page-row .remove {
  color: var(--muted);
  font-size: 1.1rem;
  font-weight: 700;
  line-height: 1;
  width: 24px;
  height: 24px;
  flex: none;
  display: grid;
  place-items: center;
}
.cart-page-row .remove:hover { color: var(--red); }
#placeOrderButton { width: 100%; text-align: center; }

/* ---- Checkout page (checkout.html) -------------------------------------- */
.checkout-page { padding: 32px 0 60px; }
.checkout-page h1 { font-size: clamp(1.4rem, 4vw, 1.8rem); margin: 4px 0 10px; }
.checkout-layout { display: flex; flex-direction: column; gap: 20px; margin-top: 20px; }
.checkout-summary {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: var(--radius-lg);
  padding: 20px;
}
.checkout-summary h2 { font-size: 1.2rem; margin: 0 0 10px; }
.checkout-done { max-width: 560px; }
.checkout-done .enquiry-summary { margin: 16px 0; }
.pdf-auto-note { margin: 0 0 12px; color: var(--muted); }

/* ---- Shopping assistant ------------------------------------------------ */

.assistant-launcher {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--burst);
  color: #140a06;
  display: grid;
  place-items: center;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  z-index: 30;
  transform: translateY(0);
  opacity: 1;
  transition: transform 220ms ease, opacity 220ms ease;
}
/* Scoped to the visible state only — .assistant-launcher:hover below also
   sets `transform`, and the two would otherwise fight over which wins
   while chrome is hidden (hover only matters while it's actually
   reachable anyway, so no functional loss in the hidden state). */
body:not(.chrome-hidden) .assistant-launcher:hover,
body:not(.chrome-hidden) .assistant-launcher:focus-visible { transform: scale(1.06); }
body.chrome-hidden .assistant-launcher {
  transform: translateY(calc(100% + 24px));
  opacity: 0;
  pointer-events: none;
}
.assistant-launcher svg { width: 26px; height: 26px; fill: currentColor; }

.assistant-panel {
  position: fixed;
  z-index: 50;
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 82dvh;
  background: var(--night-2);
  border-top: 1px solid var(--panel-border);
  border-radius: 22px 22px 0 0;
  display: flex;
  flex-direction: column;
  transform: translateY(105%);
  transition: transform 260ms ease;
  box-shadow: 0 -20px 60px rgba(0, 0, 0, 0.5);
}
.assistant-panel.open { transform: translateY(0); }
.assistant-panel header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 18px 18px 12px;
  border-bottom: 1px solid var(--panel-border);
}
.assistant-panel h2 { font-size: 1.3rem; margin-top: 2px; }
.assistant-panel .close {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: var(--panel);
  font-size: 1.3rem;
  flex: none;
}
.assistant-messages {
  flex: 1;
  overflow-y: auto;
  padding: 16px 18px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.assistant-msg { display: flex; }
.assistant-msg p { margin: 0; }
.assistant-msg.bot { justify-content: flex-start; }
.assistant-msg.user { justify-content: flex-end; }
/* .bubble, not a `> *` wildcard: addMessage() always wraps a message's
   content in exactly one bubble div, so this can style that one element
   directly rather than accidentally matching (and fighting the layout
   of) every top-level piece a message happens to append — a grid, a list,
   a button — which would otherwise each become their own bubble. */
.assistant-msg.bot .bubble {
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 14px 14px 14px 4px;
  padding: 10px 12px;
  max-width: 88%;
  font-size: 0.86rem;
  line-height: 1.5;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.assistant-msg.user .bubble {
  background: var(--burst);
  color: #140a06;
  border-radius: 14px 14px 4px 14px;
  padding: 10px 12px;
  max-width: 88%;
  font-size: 0.86rem;
  font-weight: 600;
}
.assistant-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.assistant-product {
  display: flex;
  flex-direction: column;
  background: var(--night);
  border: 1px solid var(--panel-border);
  border-radius: 10px;
  overflow: hidden;
}
.assistant-product img { width: 100%; aspect-ratio: 4 / 3; object-fit: contain; background: var(--tile); padding: 6px; }
.assistant-product .info { padding: 6px 7px 0; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.assistant-product .info b {
  font-size: 0.68rem;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.assistant-product .info span { font-size: 0.6rem; display: flex; gap: 4px; align-items: baseline; flex-wrap: wrap; }
.assistant-product .info s { color: var(--muted); }
.assistant-product .info strong { color: var(--gold-lit); font-size: 0.68rem; }
.assistant-add {
  margin: 6px 7px 7px;
  min-height: 26px;
  border-radius: 999px;
  background: var(--panel-2);
  border: 1px solid var(--panel-border);
  color: var(--ink);
  font-weight: 700;
  font-size: 0.62rem;
}
.assistant-add:hover { background: var(--cat, var(--gold)); color: var(--night); border-color: transparent; }
.assistant-link {
  align-self: flex-start;
  color: var(--gold-lit);
  font-weight: 700;
  font-size: 0.8rem;
  text-decoration: underline;
}
.assistant-link.add-all {
  align-self: stretch;
  text-align: center;
  text-decoration: none;
  background: var(--burst);
  color: #140a06;
  border-radius: 999px;
  padding: 10px 14px;
  min-height: 40px;
}
.assistant-link.add-all:disabled { opacity: 0.7; cursor: default; }
.assistant-combo-list {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-height: 220px;
  overflow-y: auto;
  padding-right: 2px;
}
.assistant-combo-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 0.78rem;
  padding: 3px 0;
  border-bottom: 1px dashed var(--panel-border);
}
.assistant-combo-row span { color: var(--ink); min-width: 0; }
.assistant-combo-row b { color: var(--gold-lit); flex: none; }
.assistant-combo-row.total {
  border-bottom: 0;
  border-top: 1px solid var(--panel-border);
  margin-top: 2px;
  padding-top: 6px;
  font-weight: 800;
}
.assistant-combo-row.total span { color: var(--muted); font-weight: 700; text-transform: uppercase; font-size: 0.68rem; letter-spacing: 0.05em; }
.assistant-combo-row.total b { font-size: 0.95rem; }
.assistant-input {
  display: flex;
  gap: 8px;
  padding: 12px 18px calc(12px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--panel-border);
}
.assistant-input input {
  flex: 1;
  min-width: 0;
  background: var(--panel);
  border: 1px solid var(--panel-border);
  border-radius: 999px;
  padding: 0 16px;
  min-height: 44px;
  font-size: 16px; /* prevents iOS zoom-on-focus */
  color: var(--ink);
}
.assistant-input input::placeholder { color: var(--muted); }
.assistant-input button {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--burst);
  color: #140a06;
  flex: none;
  display: grid;
  place-items: center;
}
.assistant-input button svg { width: 18px; height: 18px; fill: currentColor; }

/* ---- Modals (dialog) --------------------------------------------------- */

dialog {
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--ink);
}
dialog::backdrop { background: rgba(4, 3, 6, 0.7); backdrop-filter: blur(3px); }

/* ---- Standalone product page (product.html, opened in a new tab) ------- */

.product-page { padding: 32px 0 60px; }
.product-page-layout {
  display: flex;
  flex-direction: column;
  gap: 26px;
  margin-top: 20px;
}
.product-page-image {
  position: relative;
  border-radius: var(--radius-xl);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.product-page-image { background: var(--tile); }
.product-page-image img { width: 100%; aspect-ratio: 4/3; object-fit: contain; padding: 16px; }
.product-page-details .cat-tag {
  color: var(--cat, var(--gold-lit));
  font-weight: 800;
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin: 0 0 6px;
}
.product-page-details h1 {
  font-size: clamp(1.6rem, 4vw, 2rem);
  text-transform: none;
  font-family: var(--font-script);
  font-style: italic;
  font-weight: 400;
  color: var(--paper);
}
.product-page-details .tamil { color: var(--muted); font-size: 1rem; margin: 6px 0 18px; }
.product-page-details .prices { display: flex; align-items: baseline; gap: 12px; margin-bottom: 20px; }
.product-page-details .list-price { text-decoration: line-through; color: var(--muted); font-size: 1rem; }
.product-page-details .offer-price { color: var(--gold-lit); font-weight: 800; font-size: 1.8rem; }
.product-page-details .button { width: 100%; }
.muted-note { color: var(--muted); font-size: 0.82rem; margin-top: 16px; line-height: 1.6; }
#productLoading { color: var(--muted); padding: 60px 0; text-align: center; }

.enquiry-summary {
  margin: 14px 0;
  display: grid;
  gap: 10px;
  max-height: 46vh; /* was 30vh — with a handful of items in the cart the old cap left only 2-3 rows visible before scrolling */
  overflow-y: auto;
}
.enquiry-summary .row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 1rem; /* was 0.85rem */
  padding: 12px 14px;
  background: var(--panel);
  border-radius: var(--radius-md);
}
.enquiry-summary .row b { color: var(--gold-lit); }
.enquiry-summary .total-row { font-weight: 800; border: 1px solid var(--gold); }

#checkoutDone #orderRef { color: var(--gold-lit); }
.enquiry-done-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 20px 0;
}
.enquiry-done-actions .button { width: 100%; }

/* ---- Toast --------------------------------------------------------------- */

.toast {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translate(-50%, 140%);
  background: var(--panel);
  border: 1px solid var(--gold);
  color: var(--ink);
  padding: 12px 20px;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 700;
  z-index: 60;
  box-shadow: var(--shadow-sm);
  transition: transform 240ms ease;
  max-width: calc(100vw - 40px);
  text-align: center;
}
.toast.show { transform: translate(-50%, 0); }

/* ---- Body scroll lock (when cart/nav/dialog open) --------------------------- */
body.locked { overflow: hidden; }

/* ==========================================================================
   Desktop layers
   ========================================================================== */

@media (min-width: 640px) {
  .header-top { display: flex; }
  .cart-button span { display: inline; }
  .hero-actions { flex-direction: row; }
  .hero-actions .button { width: auto; }
  .form-row { flex-direction: row; }
  .form-row label { flex: 1; min-width: 0; }
  .product-page-layout { flex-direction: row; align-items: flex-start; gap: 36px; }
  .product-page-image { flex: 0 0 48%; }
  .product-page-details { flex: 1; padding-top: 6px; }
  .checkout-layout { flex-direction: row; align-items: flex-start; }
  .checkout-form { flex: 1; min-width: 0; }
  .checkout-summary { width: min(360px, 40vw); flex: none; }
  .cart-page-items { max-height: 70vh; } /* more vertical room once the sticky mobile chrome is gone */
  .assistant-panel {
    left: auto;
    top: 0;
    right: 0;
    bottom: 0;
    width: min(380px, 100vw);
    max-height: 100dvh;
    border-radius: 0;
    border-left: 1px solid var(--panel-border);
    border-top: none;
    transform: translateX(105%);
  }
  .assistant-panel.open { transform: translateX(0); }
  .assistant-launcher { right: 24px; bottom: 24px; }
  .enquiry-done-actions { flex-direction: row; }
  .enquiry-done-actions .button { width: auto; flex: 1; }

  /* Tablet/desktop: only a touch roomier than the mobile sizing, not a big
     step up — a bigger bump here (previously up to 0.9rem/44px thumbnails)
     read as oversized against the density everywhere else on desktop. */
  .price-list { font-size: 0.78rem; }
  .col-image { width: 36px; }
  .row-thumb { width: 30px; height: 30px; }
  .row-title-link { font-size: 0.78rem; }
  .row-tamil { font-size: 0.66rem; }
  .col-price { width: 62px; }
  .col-price .offer-price { font-size: 0.76rem; }
  .col-qty { width: 90px; }
  .qty-stepper button { width: 24px; height: 24px; }
  .qty-input { width: 28px; height: 24px; }
  .col-amount { width: 54px; }
  .amount-value { font-size: 0.76rem; }
}

@media (min-width: 860px) {
  /* Desktop keeps the poster in the About section instead — a tall
     portrait image at the top of a wide screen would waste the fold. */
  .hero-poster { display: none; }
  .menu-button { display: none; }
  .nav-clip {
    position: static;
    inset: auto;
    overflow: visible;
    pointer-events: auto;
    z-index: auto;
  }
  #mainNav {
    position: static;
    width: auto;
    height: auto;
    transform: none;
    flex-direction: row;
    align-items: center;
    padding: 0;
    background: none;
    border: 0;
    gap: 28px;
  }
  #mainNav a { border-bottom: 0; padding: 4px 0; font-size: 0.92rem; }
  .scrim { display: none; }
  /* Every full-page overlay that lays this shared scrim over the page
     must be listed here, or its scrim stays display:none at this width and
     an outside click silently does nothing to close it (the confirmed bug
     with the assistant panel before it was added below). */
  body:has(#mainNav.open) .scrim,
  body:has(.assistant-panel.open) .scrim { display: block; }

  .hero-content { padding: 56px 0 48px; }

  .ordering {
    display: grid;
    grid-template-columns: 0.7fr 1.3fr;
    gap: 40px;
    align-items: start;
  }
  .section-number { grid-column: 1; margin-bottom: 0; }
  .ordering-copy { grid-column: 2; }
  .order-steps { grid-column: 1 / -1; grid-template-columns: repeat(3, 1fr); }

  .section-heading.split { flex-direction: row; align-items: flex-end; justify-content: space-between; }

  .catalogue-tools { flex-direction: row; align-items: center; }
  /* Desktop has the room a phone doesn't, so the search field goes back to
     being permanently open rather than an icon that expands on tap — the
     collapse exists purely to buy back space on a small screen. Overrides
     the mobile-only collapsed/expandable rules above; nothing here is
     conditional on JS, it's pure width-based CSS. */
  .search-box { width: auto; flex: 1; }
  .search-box input { width: auto; opacity: 1; }
  .search-box .search-clear:not([hidden]) { display: flex; }
  /* Cancels the mobile-only "category yields to search" rule — both fit
     comfortably side by side at this width, so search opening should never
     hide Category on desktop. */
  .catalogue-tools.search-open .category-dropdown { display: block; }
  /* Anchored to the trigger rather than stretched across the tools row —
     at this width the row is horizontal, so `right: 0` would otherwise
     stretch the panel across the whole row. */
  .category-dropdown { flex: none; width: 300px; }
  .category-menu { right: auto; width: 300px; }
  .catalogue-layout { flex-direction: row; align-items: flex-start; }
  .products-wrap { flex: 1; min-width: 0; }

  .notice .wrap { flex-direction: row; align-items: flex-start; }
  .notice > .wrap > p { flex: 1; align-self: center; }

  .about { flex-direction: row; align-items: center; gap: 40px; }
  .about-image { flex: 0 0 42%; }
  .about > div { flex: 1; }

  .safety .wrap { flex-direction: row; gap: 40px; }
  .safety-copy { flex: 0 0 40%; }
  .safety-list { flex: 1; }

  .contact { flex-direction: row; gap: 40px; }
  .contact > div:first-child { flex: 0 0 42%; }
  .contact-form { flex: 1; min-width: 0; }

  .footer-grid { flex-direction: row; align-items: center; justify-content: space-between; }
  .footer-bottom { flex-direction: row; justify-content: space-between; }
}

/* ==========================================================================
   Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .offer-strip div { animation: none; }
  .button, .price-row, #mainNav, .assistant-panel, .toast,
  .header, .catalogue-tools, .grand-total-bar, .assistant-launcher, .search-box, .search-box input {
    transition: none !important;
  }
}
