/**
 * Men Shun Fireworks — design system.
 *
 * Extracted from the redesign mockup. Loaded by templates/header.php on every
 * page; there is no build step, so this file is the single source of truth for
 * the site's visual language. Component and token rationale lives in
 * docs/design/design-bible.md.
 *
 * Requires the Syne + DM Sans webfonts, linked from the page head.
 */

*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }

:root {
  /* Brand-derived palette — pulled from the logo */
  --pink: #e91e84;
  --pink-light: #ff4da6;
  --pink-glow: rgba(233, 30, 132, 0.25);
  --blue: #1a4b8c;
  --blue-light: #2563a8;

  --night: #050510;
  --deep: #0a0a1a;
  --surface: #111128;
  --surface-light: #1a1a3e;
  --gold: #ffc857;
  --gold-dim: #c9a23e;
  --ice: #4dd0e1;
  /* Text greys are contrast-checked against --night and --surface. The previous
     values (#8888aa / #555577) put muted text at 2.7:1, well under the 4.5:1
     minimum, which read as dark-on-dark. */
  --smoke: #a6a6c8;
  --ash: #8686a8;
  /* Borders keep the old dim value — it was only ever too dark for text. */
  --line: #3a3a5c;
  --white: #f0f0ff;

  --font-display: 'Syne', sans-serif;
  --font-body: 'DM Sans', sans-serif;
}

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-body);
  background: var(--night);
  color: var(--white);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* Grain overlay */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.025;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ═══ NAV ═══ */
nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 1200;
  padding: 0.8rem 3rem;
  display: flex; align-items: center; justify-content: space-between;
  transition: background 0.4s, backdrop-filter 0.4s;
}
nav.scrolled {
  background: rgba(5, 5, 16, 0.9);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  box-shadow: 0 1px 0 rgba(233, 30, 132, 0.1);
}

.nav-logo img {
  height: 70px;
  width: auto;
  object-fit: contain;
  transition: height 0.3s;
}
nav.scrolled .nav-logo img { height: 50px; }

.nav-links {
  display: flex; align-items: center; gap: 2.5rem; list-style: none;
}
.nav-links a {
  font-family: var(--font-display); font-weight: 500; font-size: 0.86rem;
  letter-spacing: 0.06em; text-transform: uppercase; text-decoration: none;
  color: var(--smoke); transition: color 0.3s; position: relative;
}
.nav-links a:hover { color: var(--white); }
.nav-links a::after {
  content: ''; position: absolute; bottom: -4px; left: 0;
  width: 0; height: 2px; background: var(--pink); transition: width 0.3s;
}
.nav-links a:hover::after { width: 100%; }

.nav-cta {
  font-family: var(--font-display); font-weight: 600; font-size: 0.8rem;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  color: var(--white) !important;
  background: var(--pink); padding: 0.7rem 1.6rem; border-radius: 100px;
  transition: transform 0.3s, box-shadow 0.3s;
}
.nav-cta::after { display: none !important; }
.nav-cta:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 30px var(--pink-glow);
}

/* Skip link — visible only once focused */
.skip-nav {
  position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden;
}
.skip-nav:focus {
  left: 1rem; top: 1rem; width: auto; height: auto; z-index: 2000;
  background: var(--pink); color: var(--white); padding: 0.75rem 1.25rem;
  border-radius: 100px; font-family: var(--font-display); font-size: 0.8rem;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
}

/* Mobile hamburger */
.nav-toggle {
  display: none; background: none; border: none; cursor: pointer; padding: 0.5rem;
}
.nav-toggle span {
  display: block; width: 24px; height: 2px; background: var(--white); margin: 5px 0;
  transition: transform 0.3s, opacity 0.2s;
}
.nav-toggle.open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ═══ MOBILE DRAWER ═══ */
.nav-drawer {
  position: fixed; inset: 0; z-index: 1100;
  background: rgba(5, 5, 16, 0.97);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  display: flex; flex-direction: column; justify-content: center;
  padding: 6rem 2rem 3rem;
  opacity: 0; transition: opacity 0.35s ease;
}
.nav-drawer.open { opacity: 1; }
/* A class-level `display` beats the `hidden` attribute's UA rule, which would
   otherwise leave a transparent full-screen overlay swallowing every click. */
.nav-drawer[hidden] { display: none; }
body.drawer-open { overflow: hidden; }

.nav-drawer-links { list-style: none; display: flex; flex-direction: column; gap: 0.25rem; }
.nav-drawer-links a {
  display: block; padding: 0.6rem 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.4rem, 7vw, 2rem); letter-spacing: -0.02em;
  color: var(--white); text-decoration: none;
  transform: translateY(12px); opacity: 0;
  transition: color 0.3s, transform 0.5s cubic-bezier(0.23,1,0.32,1), opacity 0.5s;
}
.nav-drawer.open .nav-drawer-links a { transform: translateY(0); opacity: 1; }
.nav-drawer-links li:nth-child(1) a { transition-delay: 0.05s; }
.nav-drawer-links li:nth-child(2) a { transition-delay: 0.09s; }
.nav-drawer-links li:nth-child(3) a { transition-delay: 0.13s; }
.nav-drawer-links li:nth-child(4) a { transition-delay: 0.17s; }
.nav-drawer-links li:nth-child(5) a { transition-delay: 0.21s; }
.nav-drawer-links li:nth-child(6) a { transition-delay: 0.25s; }
.nav-drawer-links li:nth-child(7) a { transition-delay: 0.29s; }
.nav-drawer-links li:nth-child(8) a { transition-delay: 0.33s; }
.nav-drawer-links a:hover, .nav-drawer-links a.active { color: var(--pink); }

.nav-drawer-contact {
  margin-top: 2.5rem; padding-top: 1.5rem;
  border-top: 1px solid var(--surface-light);
  display: flex; flex-direction: column; gap: 0.5rem;
}
.nav-drawer-contact a {
  color: var(--smoke); text-decoration: none; font-size: 0.9rem;
}
.nav-drawer-contact a:hover { color: var(--pink-light); }

/* ═══ HERO ═══ */
.hero {
  position: relative;
  min-height: 100vh;
  display: flex; flex-direction: column; justify-content: center; align-items: center;
  text-align: center; padding: 8rem 2rem 6rem; overflow: hidden;
}

/* Fireworks engine mounts its canvases here (js/fireworks.js) */
.hero-fx {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
}
/* Bursts reach the top edge, where they would sit behind the nav text; fade
   them out under it. */
.hero::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 150px;
  z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom, var(--night) 0%, rgba(5, 5, 16, 0.7) 45%, transparent);
}
/* Sparks fall out of the hero; fade them into the next section instead of a hard clip */
.hero::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 22%;
  z-index: 2; pointer-events: none;
  background: linear-gradient(to bottom, transparent, var(--night));
}
.hero > :not(.hero-fx) { position: relative; z-index: 3; }

.hero-kicker {
  font-family: var(--font-display); font-weight: 600; font-size: 0.78rem;
  letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--pink-light);
  margin-bottom: 1.75rem; z-index: 1;
  animation: fadeUp 0.8s ease-out 0.3s both;
}

.hero h1 {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3rem, 9vw, 7rem);
  line-height: 0.95; letter-spacing: -0.03em;
  z-index: 1;
  animation: fadeUp 0.8s ease-out 0.45s both;
}
.hero h1 .line { display: block; }
.hero h1 .accent {
  background: linear-gradient(135deg, var(--pink), var(--pink-light) 40%, var(--gold));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}

.hero-sub {
  font-size: 1.12rem; color: var(--smoke); max-width: 460px;
  line-height: 1.75; margin-top: 1.5rem; z-index: 1;
  animation: fadeUp 0.8s ease-out 0.6s both;
}

.hero-actions {
  display: flex; gap: 1rem; margin-top: 2.5rem; z-index: 1;
  animation: fadeUp 0.8s ease-out 0.75s both;
}

.btn-primary {
  font-family: var(--font-display); font-weight: 600; font-size: 0.85rem;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  color: var(--white);
  background: linear-gradient(135deg, var(--pink), var(--pink-light));
  padding: 1rem 2.5rem; border-radius: 100px; border: none; cursor: pointer;
  transition: transform 0.3s, box-shadow 0.3s;
}
.btn-primary:hover {
  transform: translateY(-3px);
  box-shadow: 0 12px 40px var(--pink-glow);
}

.btn-ghost {
  font-family: var(--font-display); font-weight: 600; font-size: 0.85rem;
  letter-spacing: 0.08em; text-transform: uppercase; text-decoration: none;
  color: var(--white);
  padding: 1rem 2.5rem; border-radius: 100px;
  border: 1px solid var(--line); transition: border-color 0.3s, background 0.3s;
}
.btn-ghost:hover { border-color: var(--white); background: rgba(255,255,255,0.05); }

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Interior pages have no hero, so they clear the fixed nav themselves */
.page-head {
  padding: 11rem 3rem 0; position: relative;
}
.page-head .section-title { max-width: 800px; }
.page-head p {
  color: var(--smoke); line-height: 1.8; max-width: 560px; margin-top: 1.25rem;
}

/* ═══ CATEGORIES ═══ */
.categories {
  padding: 6rem 3rem; position: relative;
}
.categories::before {
  content: ''; position: absolute; top: 0; left: 10%; right: 10%; height: 1px;
  background: linear-gradient(90deg, transparent, var(--surface-light), transparent);
}

.section-label {
  font-family: var(--font-display); font-weight: 600; font-size: 0.76rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--pink-light); margin-bottom: 0.75rem;
}
.section-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 3.4vw, 2.75rem); letter-spacing: -0.02em; line-height: 1.05;
  max-width: 640px;
}
.section-head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 2rem;
  margin-bottom: 2.5rem; position: relative; z-index: 1;
}
.section-head .view-all {
  font-family: var(--font-display); font-weight: 600; font-size: 0.8rem;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  color: var(--pink); display: flex; align-items: center; gap: 0.5rem;
  transition: gap 0.3s; white-space: nowrap; padding-bottom: 0.4rem;
}
.section-head .view-all:hover { gap: 1rem; }

.cat-grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 290px; gap: 1rem; }
.cat-card.wide { grid-column: span 2; }

.cat-card {
  position: relative; border-radius: 16px; overflow: hidden;
  cursor: pointer; text-decoration: none; color: var(--white);
  background: var(--surface); border: 1px solid rgba(255,255,255,0.05);
  padding: 1.5rem; display: flex; flex-direction: column; justify-content: flex-end;
  transition: transform 0.5s cubic-bezier(0.23,1,0.32,1), border-color 0.4s, box-shadow 0.4s;
}
.cat-card:hover {
  transform: translateY(-6px);
  border-color: rgba(233, 30, 132, 0.3);
  box-shadow: 0 20px 60px rgba(0,0,0,0.4), 0 0 40px var(--pink-glow);
}

/* Product shot as card art. Cutout PNGs sit on the dark card; the scrim below
   keeps the copy legible over whatever the image happens to be. */
/* Products are cutouts of wildly different proportions — a tall sparkler pack
   next to a wide barrage box — so the shot itself is contained, never cropped.
   A blurred, saturated copy of the same image fills the card behind it: without
   it a narrow product leaves most of the card empty and reads as clipart. */
.cat-card-art { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

.cat-card-glow {
  position: absolute; inset: -25%;
  background-size: cover; background-position: center;
  filter: blur(48px) saturate(1.7);
  opacity: 0.55; transform: scale(1.05);
  transition: opacity 0.5s, transform 0.7s cubic-bezier(0.23,1,0.32,1);
}
.cat-card:hover .cat-card-glow { opacity: 0.75; transform: scale(1.12); }

.cat-card-img {
  position: absolute; top: 0; left: 0; right: 0;
  width: 100%; height: 78%; object-fit: contain; object-position: center;
  padding: 0.9rem 0.9rem 0;
  /* Grounds the cutout against the blurred wash behind it */
  filter: drop-shadow(0 18px 28px rgba(0, 0, 0, 0.55));
  transform: scale(1.06);
  transition: transform 0.7s cubic-bezier(0.23,1,0.32,1);
}
.cat-card:hover .cat-card-img { transform: scale(1.14); }
/* On a two-column card a narrow product centred leaves the copy floating in
   empty space; pushing it right gives the text its own half. */
.cat-card.wide .cat-card-img {
  height: 86%; object-position: right center; padding-right: 1.75rem;
}

/* Scrim fades the art into the copy below it */
.cat-card.has-image::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to top,
    rgba(5,5,16,0.97) 26%, rgba(5,5,16,0.72) 44%, rgba(5,5,16,0.05) 72%);
}

/* A soft colour bloom in the corner gives each category its own cast without
   turning the card into a tinted rectangle */
.cat-card::before {
  content: ''; position: absolute; width: 320px; height: 320px; border-radius: 50%;
  top: -140px; right: -120px; filter: blur(60px); opacity: 0.35; z-index: 2;
  transition: opacity 0.5s, transform 0.5s; pointer-events: none;
}
.cat-card:hover::before { opacity: 0.6; transform: scale(1.15); }
/* Over a photo the bloom only needs to tint, not light the whole card */
.cat-card.has-image::before { opacity: 0.28; }
.cat-card.has-image:hover::before { opacity: 0.45; }
.cat-card:nth-child(1)::before { background: var(--pink); }
.cat-card:nth-child(2)::before { background: var(--ice); }
.cat-card:nth-child(3)::before { background: var(--gold); }
.cat-card:nth-child(4)::before { background: #ff7a3d; }
.cat-card:nth-child(5)::before { background: #a56cff; }
.cat-card:nth-child(6)::before { background: var(--pink-light); }

.cat-num {
  position: absolute; top: 1.25rem; left: 1.5rem; z-index: 3;
  font-family: var(--font-display); font-weight: 800; font-size: 0.75rem;
  letter-spacing: 0.2em; color: var(--smoke);
}
.cat-card h3 {
  font-family: var(--font-display); font-weight: 700; font-size: 1.35rem;
  letter-spacing: -0.02em; margin-bottom: 0.4rem; position: relative; z-index: 3;
}
.cat-card.wide h3 { font-size: 1.75rem; }
.cat-card p { font-size: 0.9rem; color: var(--smoke); line-height: 1.6; max-width: 34ch; position: relative; z-index: 3; }
.cat-card .cat-count {
  display: block; font-size: 0.78rem; color: var(--ash); margin-top: 0.75rem;
  letter-spacing: 0.06em; text-transform: uppercase; position: relative; z-index: 3;
}

.cat-card .cat-arrow {
  position: absolute; top: 1rem; right: 1rem; z-index: 3;
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid rgba(233, 30, 132, 0.25);
  background: rgba(233, 30, 132, 0.08);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.4s, transform 0.4s, border-color 0.4s;
}
.cat-card:hover .cat-arrow {
  background: var(--pink); border-color: var(--pink); transform: translate(2px, -2px);
}

/* ═══ FEATURED ═══ */
.featured {
  padding: 6rem 3rem; background: var(--deep); position: relative;
}
.featured::before {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(ellipse 40% 50% at 90% 50%, rgba(233,30,132,0.04) 0%, transparent 70%),
    radial-gradient(ellipse 50% 40% at 10% 30%, rgba(26,75,140,0.05) 0%, transparent 70%);
}

.product-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.75rem;
  position: relative; z-index: 1;
}

.product-card {
  background: var(--surface); border-radius: 18px; overflow: hidden;
  border: 1px solid rgba(255,255,255,0.04); cursor: pointer;
  text-decoration: none; color: var(--white);
  display: flex; flex-direction: column;
  transition: transform 0.5s cubic-bezier(0.23,1,0.32,1), border-color 0.4s, box-shadow 0.4s;
}
.product-card:hover {
  transform: translateY(-6px);
  border-color: rgba(233,30,132,0.2);
  box-shadow: 0 20px 60px rgba(0,0,0,0.4), 0 0 40px var(--pink-glow);
}
.product-card:focus-visible {
  outline: 2px solid var(--pink-light); outline-offset: 3px;
}

/* One consistent ground for every product shot. The catalogue mixes cutout PNGs
   with photographs on white, so on a dark panel some cards showed a stark white
   rectangle and others a black one. A light tile makes both read the same: the
   cutouts sit on white exactly as the photographs already do. */
.product-img {
  aspect-ratio: 4/3; position: relative; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  margin: 0.75rem 0.75rem 0; border-radius: 13px;
  background: #ffffff;
}
/* The handful of shots photographed on black get a dark tile instead, so their
   background merges with it rather than sitting on the light one as a block. */
.product-img.tile-dark { background: #000000; }
.product-img img {
  width: 100%; height: 100%; object-fit: contain; padding: 1.1rem;
  transition: transform 0.5s;
}
.product-card:hover .product-img img { transform: scale(1.06); }

.product-tag {
  position: absolute; top: 0.85rem; left: 0.85rem;
  font-family: var(--font-display); font-weight: 700; font-size: 0.72rem;
  letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.35rem 0.8rem; border-radius: 100px; z-index: 1;
}
.product-tag.new { background: var(--pink); color: var(--white); }
.product-tag.popular { background: var(--gold); color: var(--night); }

.product-info { padding: 1.3rem 1.35rem 1.35rem; flex: 1; display: flex; flex-direction: column; }
/* Titles run from one line to three. Two lines are reserved so the meta, rule
   and price line up across a row; a third is allowed rather than clipping the
   words that tell one barrage from the next. */
.product-info h4 {
  font-family: var(--font-display); font-weight: 700; font-size: 1.25rem;
  letter-spacing: -0.025em; margin-bottom: 0.35rem; line-height: 1.05;
  min-height: 2.1em;
  display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3;
  -webkit-box-orient: vertical; overflow: hidden;
  transition: color 0.3s;
}
.product-card:hover .product-info h4 { color: var(--pink-light); }
/* Held open even when a product has no box or carton figures, so the price rule
   sits at the same height on every card. */
.product-meta {
  font-size: 0.9rem; color: var(--smoke); margin-bottom: 0.9rem;
  line-height: 1.3; min-height: 1.3em;
}

.product-footer {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.75rem; margin-top: auto; padding-top: 1rem;
  border-top: 1px solid var(--surface-light);
}
/* The price is the one number a customer has to read at a glance, so it uses
   the body face at high contrast. Syne is a display type with stylised numerals
   and, in mid-pink on a dark card, it was decoration first and information
   second. */
.product-price {
  font-family: var(--font-body); font-weight: 700; font-size: 1.5rem;
  color: var(--white); letter-spacing: -0.02em; line-height: 1.1;
}
.product-price .unit {
  font-size: 0.8rem; font-weight: 500; color: var(--smoke); margin-left: 0.35rem;
  letter-spacing: 0;
}

.product-view {
  width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
  background: rgba(233,30,132,0.1); border: 1px solid rgba(233,30,132,0.25);
  display: flex; align-items: center; justify-content: center;
  transition: background 0.3s, transform 0.3s, border-color 0.3s;
}
.product-card:hover .product-view {
  background: var(--pink); border-color: var(--pink); transform: scale(1.08);
}

/* Arrow icons are SVG, not glyphs: a text arrow in a display face never centres
   in a circle and shifts between fonts and platforms. */
.product-view svg, .cat-arrow svg {
  width: 16px; height: 16px; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}
/* A chevron has no tail to balance it, so it reads as sitting left of centre
   in the circle unless nudged across. It also carries far less ink than the
   arrow it replaced, so it needs a heavier stroke to hold the same weight. */
.product-view svg {
  width: 16px; height: 16px; stroke-width: 2.75; transform: translateX(1px);
}
.back-link svg { stroke-width: 2.5; }
.cat-arrow svg { width: 14px; height: 14px; }

/* ═══ PRODUCT CAROUSEL ═══ */
/* The new-stock strip on the home page holds more products than a row can show,
   so the cards scroll sideways. It is a scroll container first and a carousel
   second: touch and trackpad users swipe it, and the arrows are added by script
   only once there is something off-screen to reach.

   Two things do the telling that this scrolls: the next card is always cut off
   by the edge, and the arrows sit on the cards themselves. Arrows parked above
   the strip read as section furniture and left the row looking like a plain
   four-card grid. */
.product-carousel {
  --carousel-lift-room: 0.5rem;    /* headroom for the card's hover lift */
  --carousel-shadow-room: 1.75rem; /* room below for the shadow it casts */
  position: relative; z-index: 1;
}

.carousel-track {
  --carousel-gap: 1.75rem;
  --carousel-per-view: 4.25;
  display: flex; gap: var(--carousel-gap);
  overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scroll-behavior: smooth;
  /* The scroll box clips at its padding edge, so the lift and shadow need room
     inside it. */
  padding: var(--carousel-lift-room) 0 var(--carousel-shadow-room);
  scrollbar-width: none;
}
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-track:focus-visible { outline: 2px solid var(--pink-light); outline-offset: 4px; border-radius: 18px; }
.carousel-track > .product-card {
  flex: 0 0 calc(
    (100% - (var(--carousel-per-view) - 1) * var(--carousel-gap)) / var(--carousel-per-view)
  );
  scroll-snap-align: start;
}
@media (prefers-reduced-motion: reduce) {
  .carousel-track { scroll-behavior: auto; }
}

.carousel-btn {
  position: absolute; z-index: 2;
  /* Centred on the cards rather than on the scroll box, whose padding sits below
     them. */
  top: calc(
    var(--carousel-lift-room)
    + (100% - var(--carousel-lift-room) - var(--carousel-shadow-room)) / 2
  );
  transform: translateY(-50%);
  width: 48px; height: 48px; border-radius: 50%; padding: 0;
  /* Solid brand pink, not the dark tint the other round controls use: these sit
     over black panels and white product tiles by turns, and a translucent dark
     circle disappeared against half of them. */
  background: var(--pink); border: 1px solid rgba(255,255,255,0.16);
  box-shadow: 0 12px 34px rgba(0,0,0,0.55), 0 0 24px var(--pink-glow);
  color: var(--white); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background 0.3s, opacity 0.3s, transform 0.3s;
}
.carousel-btn.prev { left: -1rem; }
.carousel-btn.next { right: -1rem; }
.carousel-btn:hover:not(:disabled) {
  background: var(--pink-light);
  transform: translateY(-50%) scale(1.08);
}
.carousel-btn:focus-visible { outline: 2px solid var(--pink-light); outline-offset: 3px; }
/* At the ends the arrow points at nothing, and it sits over a product shot, so
   it goes rather than dimming. */
.carousel-btn:disabled { opacity: 0; pointer-events: none; }
.carousel-btn svg {
  width: 18px; height: 18px; display: block;
  fill: none; stroke: currentColor; stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ═══ CONTACT ═══ */
/* Three open blocks on a centred axis rather than boxed cards: the page holds
   three short facts, and framing each one made it read as busier than it is.
   Hierarchy runs eyebrow → value: the number or address is what a visitor came
   for, so it is the white, largest text; the label above it is small and pink. */
.contact-head {
  padding: 12rem 3rem 0; text-align: center; position: relative;
}
/* A soft pink wash behind the title so the head has the hero's depth and the
   page does not open on flat black. */
.contact-head::before {
  content: ''; position: absolute; left: 50%; top: 4rem;
  width: 720px; height: 420px; transform: translateX(-50%);
  background: radial-gradient(ellipse at center, rgba(233, 30, 132, 0.07), transparent 65%);
  pointer-events: none;
}
.contact-head > * { position: relative; }
.contact-head .hero-kicker { animation: none; margin-bottom: 1.25rem; }
.contact-head h1 {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3rem, 6.5vw, 5.25rem);
  line-height: 0.95; letter-spacing: -0.03em;
}
.contact-head h1 .accent {
  background: linear-gradient(135deg, var(--pink), var(--pink-light) 40%, var(--gold));
  -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text;
}
.contact-head p {
  color: var(--smoke); font-size: 1.12rem; line-height: 1.75;
  max-width: 460px; margin: 1.5rem auto 0;
}

.contact-section { padding: 5rem 3rem 6rem; max-width: 1200px; margin: 0 auto; }

.contact-row {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2rem;
  margin-bottom: 5rem; text-align: center;
}

.contact-block {
  position: relative; padding: 1rem 1.5rem;
  display: flex; flex-direction: column; align-items: center;
}
/* A faint rule between columns instead of card borders. */
.contact-block + .contact-block::before {
  content: ''; position: absolute; left: -1rem; top: 8%; height: 84%; width: 1px;
  background: linear-gradient(to bottom, transparent, var(--line), transparent);
}

/* The icon sits in a ring so all three anchors share one footprint whatever
   the glyph's own proportions. */
.contact-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 84px; height: 84px; border-radius: 50%; margin-bottom: 1.75rem;
  color: var(--pink);
  background: radial-gradient(circle at 50% 40%, rgba(233, 30, 132, 0.18), rgba(233, 30, 132, 0.04) 70%);
  border: 1px solid rgba(233, 30, 132, 0.28);
  box-shadow: 0 0 0 6px rgba(233, 30, 132, 0.05), 0 10px 40px rgba(233, 30, 132, 0.12);
  transition: transform 0.4s cubic-bezier(0.23,1,0.32,1), border-color 0.3s, box-shadow 0.3s, color 0.3s;
}
.contact-icon svg { width: 34px; height: 34px; }
.contact-block:hover .contact-icon {
  transform: translateY(-4px); color: var(--pink-light);
  border-color: rgba(255, 77, 166, 0.6);
  box-shadow: 0 0 0 8px rgba(233, 30, 132, 0.07), 0 16px 50px var(--pink-glow);
}

.contact-block h3 {
  font-family: var(--font-display); font-weight: 600; font-size: 0.74rem;
  letter-spacing: 0.18em; text-transform: uppercase; color: var(--pink-light);
  margin-bottom: 0.9rem;
}
.contact-lines { display: flex; flex-direction: column; gap: 0.35rem; }
.contact-line {
  display: block; color: var(--white); text-decoration: none;
  font-family: var(--font-display); font-weight: 600;
  font-size: 1.32rem; letter-spacing: -0.01em; line-height: 1.35;
  font-variant-numeric: tabular-nums;
  transition: color 0.3s;
}
.contact-line:hover { color: var(--pink-light); }
/* Email addresses are the longest values by far, so they step down a size to
   stay on one line inside their column. */
.contact-block:nth-child(3) .contact-line { font-size: 1.02rem; font-weight: 500; }

.contact-map { aspect-ratio: 21/9; }
/* The embed paints Google's own place card in the top-left, which the dark
   filter turns into a black box that fights ours. Overscanning the frame
   upward clips that card off while the attribution along the bottom edge
   stays visible; the pin sits a little above centre as a result. */
/* Doubled selector so this outranks the shared .about-map iframe sizing. */
.about-map.contact-map iframe {
  position: absolute; left: 0; top: calc(-1 * var(--map-overscan));
  height: calc(100% + var(--map-overscan));
}
.contact-map { --map-overscan: 180px; }
/* Our own card on the map rather than relying on Google's, which the dark
   filter inverts. */
.map-cta {
  position: absolute; left: 1.5rem; top: 1.5rem; z-index: 2;
  display: flex; align-items: center; gap: 1.5rem;
  padding: 1rem 1rem 1rem 1.5rem; border-radius: 16px;
  background: rgba(10, 10, 26, 0.88); border: 1px solid rgba(233, 30, 132, 0.25);
  backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px);
  box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
}
.map-cta-text { display: flex; flex-direction: column; gap: 0.2rem; }
.map-cta-text strong { font-family: var(--font-display); font-weight: 700; font-size: 1rem; }
.map-cta-text span { font-size: 0.85rem; color: var(--smoke); }
.map-cta .btn-primary { padding: 0.8rem 1.6rem; font-size: 0.78rem; white-space: nowrap; }

/* ═══ CATEGORY GALLERY ═══ */
.gallery-section { padding: 2.5rem 3rem 6rem; }

.search-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem; flex-wrap: wrap; margin-bottom: 2.5rem;
}

.search-field { position: relative; flex: 1 1 320px; max-width: 460px; }
.search-field input {
  width: 100%; font-family: var(--font-body); font-size: 0.95rem;
  color: var(--white); background: var(--surface);
  border: 1px solid var(--surface-light); border-radius: 100px;
  padding: 0.85rem 2.75rem 0.85rem 1.25rem;
  transition: border-color 0.3s, box-shadow 0.3s;
}
.search-field input::placeholder { color: var(--ash); }
.search-field input:focus {
  outline: none; border-color: var(--pink);
  box-shadow: 0 0 0 4px var(--pink-glow);
}
.search-field input::-webkit-search-cancel-button { display: none; }

.search-clear {
  position: absolute; right: 0.6rem; top: 50%; transform: translateY(-50%);
  width: 28px; height: 28px; border-radius: 50%; border: none; cursor: pointer;
  background: transparent; color: var(--ash); font-size: 1.2rem; line-height: 1;
  transition: color 0.3s, background 0.3s;
}
.search-clear:hover { color: var(--white); background: rgba(255,255,255,0.06); }

.suggestions-dropdown {
  position: absolute; top: calc(100% + 0.5rem); left: 0; right: 0; z-index: 50;
  background: var(--surface); border: 1px solid var(--surface-light);
  border-radius: 14px; overflow: hidden;
  box-shadow: 0 20px 50px rgba(0,0,0,0.5);
}
.suggestion-item {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 0.7rem 1.1rem; border: none; background: transparent;
  font-family: var(--font-body); font-size: 0.9rem; color: var(--smoke);
  transition: background 0.2s, color 0.2s;
}
.suggestion-item:hover, .suggestion-item.active, .suggestion-item:focus {
  background: rgba(233,30,132,0.12); color: var(--white); outline: none;
}

.search-meta { display: flex; align-items: center; gap: 1.5rem; }
.result-count {
  font-family: var(--font-display); font-weight: 600; font-size: 0.78rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash);
  white-space: nowrap;
}
.sort-field { display: flex; align-items: center; gap: 0.6rem; }
.sort-label {
  font-family: var(--font-display); font-weight: 600; font-size: 0.78rem;
  letter-spacing: 0.1em; text-transform: uppercase; color: var(--ash);
}
.sort-field select {
  font-family: var(--font-body); font-size: 0.9rem; color: var(--white);
  background: var(--surface); border: 1px solid var(--surface-light);
  border-radius: 100px; padding: 0.6rem 1rem; cursor: pointer;
  transition: border-color 0.3s;
}
.sort-field select:focus { outline: none; border-color: var(--pink); }

/* Product images arrive from the proxy and occasionally 404 */
.product-img img.img-missing { opacity: 0; }

/* Empty, error and loading states share one centred block */
.gallery-state {
  text-align: center; padding: 5rem 1.5rem; color: var(--smoke);
}
.gallery-state h3 {
  font-family: var(--font-display); font-weight: 700; font-size: 1.3rem;
  color: var(--white); margin-bottom: 0.6rem;
}
.gallery-state p { margin-bottom: 1.5rem; }
.gallery-state .btn-primary { display: inline-block; }

/* Skeletons mirror the product card so the layout does not jump on load */
.skeleton-card { pointer-events: none; }
.skeleton-card .skeleton-img {
  aspect-ratio: 4/3; background: var(--surface-light);
  margin: 0.75rem 0.75rem 0; border-radius: 13px;
}
.skeleton-line {
  height: 12px; border-radius: 6px; background: var(--surface-light);
  margin-bottom: 0.7rem;
}
.skeleton-line.title { height: 18px; width: 75%; }
.skeleton-line.short { width: 40%; }
.skeleton-card .skeleton-img, .skeleton-line { animation: skeletonPulse 1.4s ease-in-out infinite; }
@keyframes skeletonPulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 0.9; } }

/* ═══ PRODUCT DETAIL ═══ */
/* The shot and its facts sit side by side and span the same width as the
   gallery grid they replace. A fixed-width block would have left the page
   hard against the left margin while every other section runs full bleed. */
.product-detail {
  display: grid; grid-template-columns: minmax(0, 1.5fr) minmax(320px, 1fr);
  gap: 2.5rem; align-items: start;
}

/* Same light ground as the cards, for the same reason: the catalogue mixes
   cutout PNGs with photographs, and on a dark panel the photographs showed as
   a white rectangle floating inside the frame. */
.product-detail-media {
  border-radius: 20px; overflow: hidden;
  border: 1px solid var(--surface-light); background: #ffffff;
  box-shadow: 0 30px 80px rgba(0,0,0,0.5), 0 0 60px var(--pink-glow);
}
.product-detail-media.tile-dark { background: #000000; }
/* Video is its own ground and must not sit on a white letterbox. */
.product-detail-media.has-video { background: var(--surface); }
.product-detail-media iframe { width: 100%; aspect-ratio: 16/9; border: 0; display: block; }
/* A fixed frame rather than the shot's own height. The catalogue's photographs
   range from wide box shots to tall rocket shots, and letting each set the
   height left the panel beside it stranded against a block twice its size. */
.product-detail-media img {
  width: 100%; aspect-ratio: 4/3; object-fit: contain;
  display: block; padding: 1.5rem;
}

/* Follows the shot down on tall pages so the price and enquiry link stay in
   view while a long product image scrolls. */
.product-detail-panel {
  background: var(--surface); border: 1px solid rgba(255,255,255,0.05);
  border-radius: 20px; padding: 2rem; position: sticky; top: 7rem;
}
.product-detail-eyebrow {
  display: flex; align-items: center; gap: 0.75rem;
  flex-wrap: wrap; margin-bottom: 0.9rem;
}
.product-detail-eyebrow .section-label { margin-bottom: 0; }
.product-detail-panel .product-tag { position: static; }
.product-detail-title {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.6rem, 2.2vw, 2.1rem); letter-spacing: -0.02em;
  line-height: 1.15; margin-bottom: 1.5rem;
}

.product-spec {
  border-top: 1px solid var(--surface-light); margin-bottom: 1.75rem;
}
.product-spec-row {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; padding: 0.85rem 0;
  border-bottom: 1px solid var(--surface-light);
}
.product-spec-row dt {
  font-family: var(--font-display); font-weight: 600; font-size: 0.76rem;
  letter-spacing: 0.12em; text-transform: uppercase; color: var(--ash);
}
.product-spec-row dd { font-size: 1rem; font-weight: 500; color: var(--white); }

.product-detail-price { margin-bottom: 1.75rem; }
.product-detail-price .price-label {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: 0.76rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ash); margin-bottom: 0.4rem;
}
.product-detail-price .product-price { font-size: clamp(2.2rem, 3vw, 2.8rem); }
.product-detail-price .product-price .unit { font-size: 0.95rem; }

.product-detail-panel .btn-primary { display: block; text-align: center; }

/* Sits above the product so the way back out is the first thing on the page,
   not something to be scrolled to. */
.product-detail-back { margin-bottom: 2rem; }
.back-link {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-display); font-weight: 600; font-size: 0.8rem;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  color: var(--smoke); transition: color 0.3s, gap 0.3s;
}
.back-link:hover { color: var(--white); gap: 0.8rem; }
.back-link svg {
  width: 15px; height: 15px; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ═══ VIDEO ═══ */
.video-section { padding: 6rem 3rem; text-align: center; }
.video-section .section-title { margin-left: auto; margin-right: auto; }
.video-wrap {
  max-width: 900px; margin: 0 auto; border-radius: 20px; overflow: hidden;
  aspect-ratio: 16/9; border: 1px solid var(--surface-light);
  box-shadow: 0 30px 80px rgba(0,0,0,0.5), 0 0 60px var(--pink-glow);
}
.video-wrap iframe { width: 100%; height: 100%; border: 0; }

/* ═══ ABOUT ═══ */
.about {
  padding: 8rem 3rem; display: grid; grid-template-columns: 1fr 1fr;
  gap: 6rem; align-items: center; background: var(--deep);
}
/* Grid and flex children default to min-width:auto, so a wide stat row or a
   long word forces the column past the viewport. Let them shrink instead. */
.about-content, .about-map { min-width: 0; }
.about-content h2 {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 3.5vw, 2.8rem); letter-spacing: -0.02em;
  line-height: 1.15; margin-bottom: 1.5rem;
}
.about-content p {
  color: var(--smoke); line-height: 1.85; font-size: 1.05rem;
  margin-bottom: 1.5rem; max-width: 480px;
}
.about-stats {
  display: flex; flex-wrap: wrap; gap: 1.5rem 3rem; margin-top: 2.5rem; padding-top: 2rem;
  border-top: 1px solid var(--surface-light);
}
.stat-item h3 { font-family: var(--font-display); font-weight: 800; font-size: 2rem; color: var(--pink); }
.stat-item h3 .star { font-size: 1.2rem; color: var(--gold); margin-left: 0.15rem; vertical-align: 0.25rem; }
.stat-item p { font-size: 0.85rem; color: var(--ash); margin-bottom: 0; }

.about-map {
  position: relative; border-radius: 20px; overflow: hidden; aspect-ratio: 3/2;
  border: 1px solid var(--surface-light);
}
.about-map iframe {
  width: 100%; height: 100%; border: 0;
  /* Inverting a light map plus a 180deg hue rotation is what makes it read as
     dark while keeping labels legible. The previous brightness(0.5) applied
     after the invert crushed the whole thing to near-black. */
  /* Fully desaturate BEFORE inverting. The shop sits in farmland, and any
     surviving saturation comes back as a strong green once inverted — a partial
     saturate() only made it olive. Grayscale first gives a neutral dark map;
     contrast is then pushed up, because a map nobody can read is decoration.
     No tint or vignette on top: those looked smoky and cost legibility.
     Inversion is held back from full and brightness pushed instead so roads
     lift to mid-grey on a phone while the marker, a mid tone to begin with,
     stays darker than the roads around it. */
  filter: grayscale(1) invert(0.8) contrast(1.6) brightness(1.3);
  transition: filter 0.5s;
}
.about-map:hover iframe {
  filter: grayscale(1) invert(0.78) contrast(1.65) brightness(1.36);
}
.about-actions {
  display: flex; gap: 1rem; flex-wrap: wrap; margin-top: 2rem;
}

/* ═══ FOOTER ═══ */
footer {
  padding: 5rem 3rem 2rem;
  border-top: 1px solid var(--surface-light);
}
.footer-grid {
  display: grid; grid-template-columns: 2fr 1fr 1fr 1.5fr; gap: 3rem; margin-bottom: 4rem;
}
.footer-brand { display: flex; flex-direction: column; gap: 1rem; }
.footer-brand img { height: 60px; width: auto; object-fit: contain; align-self: flex-start; }
.footer-brand p { color: var(--smoke); font-size: 0.9rem; line-height: 1.7; max-width: 280px; }

.footer-col h4 {
  font-family: var(--font-display); font-weight: 700; font-size: 0.75rem;
  letter-spacing: 0.15em; text-transform: uppercase; color: var(--white); margin-bottom: 1.2rem;
}
.footer-col ul { list-style: none; display: flex; flex-direction: column; gap: 0.6rem; }
.footer-col a {
  color: var(--smoke); text-decoration: none; font-size: 0.9rem; transition: color 0.3s;
}
.footer-col a:hover { color: var(--pink-light); }

.footer-contact a {
  display: flex; align-items: center; gap: 0.6rem;
  color: var(--smoke); text-decoration: none; font-size: 0.9rem;
  transition: color 0.3s; margin-bottom: 0.6rem;
}
.footer-contact a:hover { color: var(--pink-light); }
.footer-contact .icon {
  width: 32px; height: 32px; border-radius: 8px; background: var(--surface);
  display: flex; align-items: center; justify-content: center; font-size: 0.85rem; flex-shrink: 0;
}

.footer-bottom {
  display: flex; justify-content: space-between; align-items: center;
  padding-top: 2rem; border-top: 1px solid var(--surface-light);
  font-size: 0.82rem; color: var(--ash);
}

/* ═══ RESPONSIVE ═══ */
/* Four columns below this width squeeze the title into three or four lines. */
@media (max-width: 1280px) {
  .product-grid { grid-template-columns: repeat(3, 1fr); }
  .carousel-track { --carousel-per-view: 3.25; }
}
@media (max-width: 1024px) {
  .contact-row { grid-template-columns: 1fr; gap: 0.5rem; }
  .contact-block { padding: 2.5rem 1rem; }
  .contact-block:nth-child(3) .contact-line { font-size: 1.1rem; }
  .contact-block + .contact-block::before {
    left: 25%; top: 0; width: 50%; height: 1px;
    background: linear-gradient(to right, transparent, var(--line), transparent);
  }
  .contact-map { aspect-ratio: 4/3; }
  .cat-grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 220px; }
  .product-grid { grid-template-columns: repeat(2, 1fr); }
  .carousel-track { --carousel-per-view: 2.25; }
  .about { grid-template-columns: 1fr; gap: 3rem; }
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
  .product-detail { grid-template-columns: 1fr; gap: 1.75rem; }
  .product-detail-panel { position: static; }
}
@media (max-width: 768px) {
  nav { padding: 0.8rem 1.5rem; }
  .nav-links { display: none; }
  .nav-toggle { display: block; }
  /* svh tracks the visible viewport as mobile browser chrome hides, so the hero
     neither overflows nor leaves a band of dead space under the buttons. */
  .hero { min-height: 100svh; padding: 6rem 1.5rem 3.5rem; }
  /* Sized so "Light Up" and "The Night" each stay on one line at 390px. */
  .hero h1 { font-size: clamp(2.5rem, 11vw, 4.5rem); line-height: 0.92; }
  .hero-kicker {
    font-size: 0.6rem; letter-spacing: 0.16em;
    line-height: 1.6; margin-bottom: 1.25rem;
  }
  .hero-sub { font-size: 1rem; max-width: 34ch; margin-top: 1.25rem; }
  .hero-actions { flex-direction: column; width: 100%; max-width: 320px; margin-top: 2rem; gap: 0.75rem; }
  .hero-actions a { text-align: center; }
  nav { padding: 0.6rem 1.25rem; }
  .nav-logo img { height: 52px; }
  nav.scrolled .nav-logo img { height: 44px; }
  .categories, .featured, .video-section { padding: 4rem 1.5rem; }
  .contact-head { padding: 8rem 1.5rem 0; }
  .contact-head h1 { font-size: clamp(2.6rem, 12vw, 4rem); }
  .contact-head p { font-size: 1rem; }
  .contact-section { padding: 3rem 1.5rem 4rem; }
  .contact-row { margin-bottom: 3rem; }
  .contact-map { aspect-ratio: 1; }
  .contact-map { --map-overscan: 120px; }
  /* The address already sits directly above the map here, and a full card
     would cover the pin, so only the button rides on the map. */
  .map-cta {
    left: 0.75rem; top: auto; bottom: 2.25rem; padding: 0;
    background: none; border: 0; box-shadow: none;
    backdrop-filter: none; -webkit-backdrop-filter: none;
  }
  .map-cta-text { display: none; }
  .map-cta .btn-primary { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); }
  .gallery-section { padding: 1.5rem 1.5rem 4rem; }
  .search-toolbar { gap: 1rem; }
  .search-field { max-width: none; flex-basis: 100%; }
  .search-meta { width: 100%; justify-content: space-between; gap: 1rem; }
  /* Fixed row heights left a dead band above the bottom-aligned text and clipped
     the longest title; sizing to content fixes both. */
  /* Two columns so the six categories fit two screens instead of four. The
     blurb goes; name, qualifier and art carry the card at this width. */
  .cat-grid { grid-template-columns: repeat(2, 1fr); grid-auto-rows: auto; gap: 0.75rem; }
  .cat-card { min-height: 150px; padding: 1rem; }
  .cat-card.has-image { min-height: 205px; }
  .cat-card .cat-card-img, .cat-card.wide .cat-card-img { height: 52%; padding: 0.6rem 0.6rem 0; }
  .cat-card.wide { grid-column: span 1; }
  .cat-card h3, .cat-card.wide h3 { font-size: 1.05rem; }
  .cat-card p { display: none; }
  .cat-card .cat-count { font-size: 0.62rem; }
  .about { padding: 4rem 1.5rem; }
  .about-stats { gap: 1.25rem 1.5rem; }
  .stat-item h3 { font-size: 1.6rem; }
  .stat-item h3 .star { font-size: 1rem; }
  .section-head { flex-direction: column; align-items: flex-start; gap: 1rem; }
  .product-grid { grid-template-columns: 1fr; max-width: 400px; }
  .carousel-track { --carousel-per-view: 1.15; --carousel-gap: 1rem; }
  /* No room to hang outside the track here, so they sit just inside its edges. */
  .carousel-btn { width: 42px; height: 42px; }
  .carousel-btn.prev { left: 0.5rem; }
  .carousel-btn.next { right: 0.5rem; }
  /* Nothing to line up against in a single column, so the reserved title and
     meta lines are only dead space here. */
  .product-info h4, .product-meta { min-height: 0; }
  .product-detail-panel { padding: 1.5rem; }
  .product-detail-media img { padding: 1rem; }
  .about { padding: 4rem 1.5rem; }
  footer { padding: 3rem 1.5rem 2rem; }
  .footer-grid { grid-template-columns: 1fr; gap: 2rem; }
  .footer-bottom { flex-direction: column; gap: 0.5rem; text-align: center; }
}

/* ═══ SCROLL ANIMATIONS ═══ */
.reveal {
  opacity: 0; transform: translateY(40px);
  transition: opacity 0.8s ease-out, transform 0.8s ease-out;
}
.reveal.visible { opacity: 1; transform: translateY(0); }

.reveal-stagger > * {
  opacity: 0; transform: translateY(30px);
  transition: opacity 0.6s ease-out, transform 0.6s ease-out;
}
.reveal-stagger.visible > * { opacity: 1; transform: translateY(0); }
.reveal-stagger.visible > *:nth-child(1) { transition-delay: 0s; }
.reveal-stagger.visible > *:nth-child(2) { transition-delay: 0.08s; }
.reveal-stagger.visible > *:nth-child(3) { transition-delay: 0.16s; }
.reveal-stagger.visible > *:nth-child(4) { transition-delay: 0.24s; }
.reveal-stagger.visible > *:nth-child(5) { transition-delay: 0.32s; }
.reveal-stagger.visible > *:nth-child(6) { transition-delay: 0.4s; }

@media (max-width: 768px) {
  .page-head { padding: 9rem 1.5rem 0; }
}

@media (prefers-reduced-motion: reduce) {
  .nav-drawer-links a { transform: none; opacity: 1; }
  .particle { animation: none !important; }
  .reveal, .reveal-stagger > * { opacity: 1; transform: none; transition: none; }
  * { transition-duration: 0.01ms !important; }
}

