/* ==========================================================================
   MAMUDA CARE - Design System
   Contemporary editorial luxury · corporate authority · human warmth
   Palette: Iconic Black · Radiant White · Eternal Gold
   Fonts: Cormorant Garamond (Royale substitute) · Manrope (Essentielle substitute)
   ========================================================================== */

:root {
  /* Official corporate palette */
  --black:      #000000;   /* Iconic Black */
  --white:      #FFFFFF;   /* Radiant White */
  /* Eternal Gold is the accent. It carries what red used to: the hero keyword,
     the active nav state, the prefooter band, button hovers.
     Gold at full saturation is a LIGHT tone (L* ~70), so it only ever works as a
     FILL behind black text, never as text on white. Hence three steps, not one. */
  --gold:       #E3A535;   /* the brand gold. Fills, hairlines, and anything on black (9.70:1 on black) */
  --gold-deep:  #B8860B;   /* non-text UI on white: underlines, active bars (3.25:1 - clears SC 1.4.11) */
  --gold-text:  #8A6510;   /* any small text or hover state on white (5.32:1 - clears AA) */

  /* Supporting warm editorial neutrals — for LIGHT surfaces only.
     ink-400 is the lightest text tone that still clears WCAG AA (5.1:1 on white).
     Do not reuse these on black; dark surfaces have their own pair below. */
  --ink-800:    #1A1A1A;
  --ink-600:    #4D4D4D;
  --ink-400:    #6E6E6E;
  --line-200:   #D8D8D8;
  --surface-100:#F3F3F1;
  --surface-50: #FAFAF8;

  /* Text tones for DARK surfaces (footer, bands, CTA block) */
  --on-dark:        #CFCFCF;   /* body copy on black */
  --on-dark-muted:  #B5B5B5;   /* labels and secondary copy on black */

  /* Aliases used across components */
  --ink: var(--black);
  --ink-soft: var(--ink-600);
  --ink-faint: var(--ink-400);

  /* Type */
  --font-display: "Cormorant Garamond", "Times New Roman", serif;
  --font-body: "Manrope", -apple-system, "Segoe UI", sans-serif;

  /* Spacing scale (8pt) */
  --s-1: 4px;  --s-2: 8px;  --s-3: 12px; --s-4: 16px; --s-5: 24px;
  --s-6: 32px; --s-7: 48px; --s-8: 64px; --s-9: 96px; --s-10: 128px;

  /* Shape: rectangular, sharp */
  --r-sm: 0; --r-md: 0; --r-lg: 0; --r-xl: 0; --r-pill: 0;

  /* Shadows: minimal by design */
  --sh-header: 0 1px 0 var(--line-200);

  /* Motion: slow, refined */
  --ease-out: cubic-bezier(.33, 1, .68, 1);
  --t-fast: 200ms; --t-med: 300ms; --t-slow: 450ms;

  --header-h: 84px;
  --container: 1360px;
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* The header is sticky, so an in-page anchor would otherwise land underneath
   it. Keeps #baby-jelly, #range and the skip link clear of the bar. */
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 24px); }
body {
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.7;
  color: var(--ink-800);
  background: var(--white);
  overflow-x: hidden;
}
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { font: inherit; background: none; border: 0; cursor: pointer; color: inherit; }
:focus-visible { outline: 2px solid var(--black); outline-offset: 3px; }
.band :focus-visible, .site-footer :focus-visible, .cta-band :focus-visible,
.video-modal :focus-visible { outline-color: var(--white); }
::selection { background: var(--black); color: var(--white); }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ---------- Typography ---------- */
h1, h2, h3, .display { font-family: var(--font-display); color: var(--black); line-height: 1.08; font-weight: 600; letter-spacing: .002em; }
h1 { font-size: clamp(2.75rem, 6vw, 5.2rem); }
h2 { font-size: clamp(2.1rem, 4vw, 3.4rem); }
h3 { font-size: clamp(1.4rem, 2.2vw, 1.8rem); }
h4 { font-family: var(--font-body); font-weight: 700; color: var(--black); font-size: 1rem; }

.lead { font-size: clamp(1.1rem, 1.5vw, 1.35rem); line-height: 1.65; color: var(--ink-600); }
.eyebrow {
  display: inline-flex; align-items: center; gap: 14px;
  font-size: .78rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-600);
}
.eyebrow::before { content: ""; width: 32px; height: 1px; background: var(--gold); }
.eyebrow--center { justify-content: center; }
.eyebrow--center::after { content: ""; width: 32px; height: 1px; background: var(--gold); }
.eyebrow--light { color: var(--on-dark-muted); }

em.script { font-style: italic; font-weight: 500; color: var(--gold-text); }

/* ---------- Layout ---------- */
.container { width: min(var(--container), calc(100% - 48px)); margin-inline: auto; }
.section { padding-block: clamp(80px, 10vw, 128px); }
.section--tint { background: var(--surface-50); }
.section--dark { background: var(--black); color: var(--on-dark); }
.section-head { max-width: 760px; margin-inline: auto; text-align: center; margin-bottom: clamp(48px, 6vw, 80px); }
.section-head > * + * { margin-top: var(--s-4); }

/* ---------- Buttons: editorial, rectangular ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  padding: 18px 36px;
  font-weight: 700; font-size: .82rem; letter-spacing: .14em; text-transform: uppercase;
  cursor: pointer; position: relative;
  transition: background var(--t-med) var(--ease-out), color var(--t-med) var(--ease-out), border-color var(--t-med);
}
.btn svg { width: 16px; height: 16px; flex: none; transition: transform var(--t-fast) var(--ease-out); }
.btn:hover svg { transform: translateX(5px); }

.btn--primary { background: var(--black); color: var(--white); }
/* Gold fill takes BLACK text (9.70:1). White on gold would be 2.16:1. */
.btn--primary:hover { background: var(--gold); color: var(--black); }

.btn--light { background: var(--white); color: var(--black); }
.btn--light:hover { background: var(--gold); color: var(--black); }

.btn--ghost { background: transparent; color: var(--black); border: 1px solid var(--black); }
.btn--ghost:hover { background: var(--black); color: var(--white); }

/* Text link */
.link {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; font-size: .8rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--black); border-bottom: 1px solid var(--black); padding-bottom: 4px;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.link svg { width: 15px; height: 15px; transition: transform var(--t-fast) var(--ease-out); }
.link:hover { color: var(--gold-text); border-color: var(--gold-text); }
.link:hover svg { transform: translateX(4px); }

/* ==========================================================================
   HEADER
   ========================================================================== */
.topbar {
  background: var(--black); color: var(--on-dark-muted);
  font-size: .76rem; letter-spacing: .12em; text-transform: uppercase;
  text-align: center; padding: 10px 16px;
}
.topbar strong { color: var(--white); font-weight: 700; }
.topbar .heart { display: inline-block; width: 11px; height: 11px; vertical-align: -1px; }
.topbar .heart path { fill: var(--gold); }

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: var(--white);
  border-bottom: 1px solid var(--line-200);
  transition: box-shadow var(--t-med);
}
.site-header.is-scrolled { box-shadow: 0 1px 0 var(--black); }
.header-inner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s-5);
  height: var(--header-h);
}
.brand { display: inline-flex; align-items: center; flex: none; }

/* The wordmark is 5.36:1, so height drives a lot of width - at 44px it is
   236px across. `.brand` is `flex: none` and will not shrink, so between the
   mobile breakpoint and ~1080px the header cannot afford full height:
   at 901px the row leaves only 171px for the logo (838 container - 406 nav
   - 213 CTA - 48 gaps). Step the height down rather than let it push the nav. */
.brand img { height: clamp(30px, 3.3vw, 44px); width: auto; }
/* Tighten the row gap where the nav is widest relative to the viewport.
   With a hard 34px step this band had only 5px of slack at 901px, which one
   extra nav item or a longer translation would blow out; the fluid height
   plus the smaller gap takes it to ~26px. */
@media (max-width: 1080px) and (min-width: 901px) {
  .header-inner { gap: var(--s-4); }
}

/* Nav links are styled by CLASS, never by element. A `.nav a` selector would
   cascade into every mega-panel link, and would also stop matching once
   wp_nav_menu() emits its own <ul><li><a> markup. Keep it class-based. */
.nav-list { display: flex; align-items: center; gap: clamp(24px, 3vw, 44px); }
.nav-item { position: static; }   /* must stay static: see the .mega note below */
.nav-link {
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px;                /* WCAG 2.2 SC 2.5.8 target size */
  font-family: var(--font-body);
  font-weight: 700; font-size: .8rem; letter-spacing: .14em; text-transform: uppercase;
  color: var(--black); background: none; border: 0; cursor: pointer;
  padding: 8px 0; transition: color var(--t-fast);
}
.nav-link::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  /* gold-deep, not gold: this bar is the sole visual carrier of the active-page
     state, so it owes 3:1 against white (SC 1.4.11). Brand gold is 2.16:1. */
  height: 2px; background: var(--gold-deep);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--t-med) var(--ease-out);
}
.nav-link:hover::after,
.nav-link[aria-current="page"]::after,
.nav-trigger[aria-expanded="true"]::after { transform: scaleX(1); }

.nav-chev { width: 12px; height: 12px; stroke: currentColor; stroke-width: 2.5; fill: none; transition: transform var(--t-med) var(--ease-out); }
.nav-trigger[aria-expanded="true"] .nav-chev { transform: rotate(180deg); }

.header-actions { display: flex; align-items: center; gap: 12px; flex: none; }
.header-cta { display: inline-flex; align-items: center; gap: 10px; padding: 14px 22px; font-size: .78rem; }

/* Mobile nav */
.nav-toggle { display: none; width: 48px; height: 48px; place-items: center; }
.nav-toggle span, .nav-toggle span::before, .nav-toggle span::after {
  content: ""; display: block; width: 24px; height: 2px;
  background: var(--black); position: relative;
  transition: transform var(--t-med) var(--ease-out), opacity var(--t-fast);
}
.nav-toggle span::before { position: absolute; top: -7px; }
.nav-toggle span::after { position: absolute; top: 7px; }
.nav-toggle[aria-expanded="true"] span { background: transparent; }
.nav-toggle[aria-expanded="true"] span::before { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span::after { transform: translateY(-7px) rotate(-45deg); }

@media (max-width: 900px) {
  .nav-toggle { display: grid; }
  .header-cta .header-cta-label { display: none; }
  .header-cta { padding: 14px; }
  .nav {
    /* Anchored to the header itself, not a hardcoded offset. `top: calc(var(--header-h))`
       assumed the header sat at the viewport top and so overlapped it by the height
       of the topbar whenever the page was scrolled to the top. */
    position: absolute; top: 100%; left: 0; right: 0; z-index: 99;
    background: var(--white); border-bottom: 1px solid var(--black);
    padding: 8px 24px 32px;
    /* With Products expanded the panel runs ~11 rows and would clip on a short
       phone, so it scrolls internally rather than off-screen. */
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto; overscroll-behavior: contain;
    transform: translateY(-12px); opacity: 0; visibility: hidden; pointer-events: none;
    transition: transform var(--t-med) var(--ease-out), opacity var(--t-med), visibility 0s var(--t-med);
  }
  .nav.is-open { transform: none; opacity: 1; visibility: visible; pointer-events: auto; transition-delay: 0s; }
  .nav-list { flex-direction: column; align-items: stretch; gap: 0; }
  .nav-link {
    width: 100%; padding: 18px 0; font-size: .9rem;
    border-bottom: 1px solid var(--line-200);
  }
  .nav-link::after { display: none; }
  .nav-link[aria-current="page"] { color: var(--gold-text); }
  .nav-trigger { justify-content: space-between; }
}

/* ==========================================================================
   PRODUCTS MEGA PANEL
   ========================================================================== */
/* The panel is absolutely positioned against `.site-header`, which is the
   nearest positioned ancestor (position: sticky). That gives it full-bleed
   width, the header's z-index, and zero layout shift.
   DO NOT add `position` or `transform` to .header-inner, .nav, .nav-list or
   .nav-item — any of those becomes the containing block and collapses the
   panel to the width of the trigger. */
.mega {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 1;
  background: var(--white);
  border-top: 1px solid var(--line-200);
  border-bottom: 1px solid var(--black);
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(-8px);
  transition: opacity var(--t-fast) var(--ease-out),
              transform var(--t-fast) var(--ease-out),
              visibility 0s var(--t-fast);
}
.mega.is-open {
  opacity: 1; visibility: visible; pointer-events: auto;
  transform: none; transition-delay: 0s;
}
/* Four columns carry six category groups: two of the columns stack a pair
   (Detergents + Household soaps, Skincare + Baby care). At the 1360 container
   this leaves ~211px per column, which keeps "Mamuda Laundry Soap" on one
   line — re-measure before adding a fifth column or a longer product name. */
.mega-inner {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)) 300px;
  gap: clamp(24px, 3vw, 48px);
  padding-block: 48px 56px;
  align-items: start;
}
.mega-col { opacity: 1; }
.mega.is-open .mega-col:nth-child(1) { transition-delay: 0ms; }
.mega.is-open .mega-col:nth-child(2) { transition-delay: 40ms; }
.mega.is-open .mega-col:nth-child(3) { transition-delay: 80ms; }
.mega.is-open .mega-col:nth-child(4) { transition-delay: 120ms; }

.mega-head {
  font-family: var(--font-body);
  font-size: .72rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--ink-400);
  border-top: 1px solid var(--gold);   /* gold appears here only, as a hairline */
  padding-top: 14px; margin-bottom: var(--s-4);
}
.mega-list { display: flex; flex-direction: column; }
/* A second group stacked inside the same column needs its own air above it */
.mega-list + .mega-head { margin-top: var(--s-6); }
.mega-link {
  display: block; padding-block: 10px;   /* ≥44px row for SC 2.5.8 */
  font-size: 1.05rem; font-weight: 600; color: var(--black);
  border-bottom: 1px solid transparent;
  transition: color var(--t-fast), border-color var(--t-fast);
}
.mega-link:hover { color: var(--gold-text); border-bottom-color: var(--gold-text); }
.mega-note {
  display: block; margin-top: 3px;
  font-size: .8rem; font-weight: 400; letter-spacing: .02em; color: var(--ink-400);
}
.mega-link:hover .mega-note { color: var(--ink-600); }

.mega-rail {
  border-left: 1px solid var(--line-200);
  background: var(--surface-50);
  padding: var(--s-5) 0 var(--s-5) var(--s-6);
  margin-block: calc(var(--s-5) * -1);
  align-self: stretch;
}
.mega-rail img { width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: contain; mix-blend-mode: multiply; }
.mega-rail-copy {
  font-family: var(--font-display); font-size: 1.25rem; line-height: 1.25;
  color: var(--black); margin-block: var(--s-4);
}

/* The rail has to go earlier than it used to: four columns plus a 300px rail
   only breathes above ~1240px. */
@media (max-width: 1240px) {
  .mega-inner { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .mega-rail { display: none; }
}

/* Mobile: the panel becomes an inline accordion inside the existing nav panel.
   0fr -> 1fr animates real height with no JS measurement. */
@media (max-width: 900px) {
  .mega {
    position: static; z-index: auto;
    border: 0; background: var(--surface-50);
    opacity: 1; visibility: visible; pointer-events: auto; transform: none;
    display: grid; grid-template-rows: 0fr;
    transition: grid-template-rows var(--t-med) var(--ease-out);
  }
  .mega.is-open { grid-template-rows: 1fr; }
  .mega-inner {
    display: block; overflow: hidden;    /* required for the 0fr->1fr trick */
    padding: 8px 20px 20px; width: 100%;
  }
  .mega-col + .mega-col { margin-top: var(--s-5); }
  .mega-head { margin-bottom: var(--s-3); }
  .mega-link { font-size: .95rem; }
}

/* The global reduced-motion block resets transition-duration but not
   transition-delay, which would leave the panel invisible-but-clickable. */
@media (prefers-reduced-motion: reduce) {
  .mega, .mega-col { transition-delay: 0s !important; }
}

/* Breadcrumb (catalogue pages) */
.crumbs {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  font-size: .72rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-400); margin-bottom: var(--s-5);
}
.crumbs a { color: var(--ink-400); transition: color var(--t-fast); }
.crumbs a:hover { color: var(--black); }
.crumbs [aria-current="page"] { color: var(--black); }
.crumbs .sep { color: var(--line-200); }

/* ==========================================================================
   HERO
   ========================================================================== */
.hero {
  position: relative; overflow: hidden;
  background: var(--surface-50);
  border-bottom: 1px solid var(--line-200);
}
.hero-inner {
  display: grid; grid-template-columns: 1.05fr .95fr; align-items: center;
  gap: clamp(40px, 5vw, 80px);
  padding-block: clamp(64px, 8vw, 128px);
  position: relative; z-index: 2;
}
.hero-copy > * + * { margin-top: var(--s-5); }
.hero-copy .lead { max-width: 52ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }

.hero-visual { position: relative; }
.hero-visual > img { position: relative; z-index: 2; margin-inline: auto; }

/* Photographic hero images: dissolve into the page instead of sitting as a cut-out rectangle */
.hero-photo {
  mix-blend-mode: multiply;
  -webkit-mask-image:
    linear-gradient(to right, transparent, #000 9%, #000 91%, transparent),
    linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent);
  mask-image:
    linear-gradient(to right, transparent, #000 9%, #000 91%, transparent),
    linear-gradient(to bottom, transparent, #000 9%, #000 91%, transparent);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

@media (max-width: 900px) {
  .hero-inner { grid-template-columns: 1fr; text-align: center; }
  .hero-copy .lead { margin-inline: auto; }
  .hero-actions { justify-content: center; }
  .hero-visual { max-width: 440px; margin-inline: auto; }
}

/* ==========================================================================
   CARDS & GRIDS - editorial modules
   ========================================================================== */
.card {
  background: var(--white); border: 1px solid var(--line-200);
  transition: border-color var(--t-med) var(--ease-out);
}
.card:hover { border-color: var(--black); }

/* Product highlight cards.
   One card per product line, so the count here must stay at seven. Packs are
   transparent PNG cutouts (thumb-*.png / below-heroslider-*.png) — a shot with
   a white ground would print a white box on the tinted plinth. */
.highlight-card { padding: var(--s-6); display: flex; flex-direction: column; gap: var(--s-3); position: relative; overflow: hidden; }
.highlight-card .thumb {
  height: 176px; display: grid; place-items: center; margin: calc(var(--s-6) * -1) calc(var(--s-6) * -1) var(--s-3);
  background: var(--surface-100); padding: var(--s-4);
}
/* Bounded on BOTH axes: the seven packs range from a tall 153x272 sachet to a
   wide 320x160 wrapper, and a height-only cap would let the wide ones spill.
   The cap is 176px - 2x16px padding stated in px, not 100%: a percentage
   max-height on a centred grid item resolves against an indefinite block and
   is dropped, which lets the tall packs render at full 272px. */
.highlight-card .thumb img {
  max-height: 144px; max-width: 100%; width: auto; height: auto; object-fit: contain;
  transition: transform var(--t-slow) var(--ease-out);
}
.highlight-card:hover .thumb img { transform: scale(1.05); }
.highlight-card .tag { font-size: .72rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-400); }
.highlight-card p { font-size: .92rem; color: var(--ink-600); }
.highlight-card .link { margin-top: auto; align-self: flex-start; }

/* --- Carousel ------------------------------------------------------------
   The track is a real scroll container, so touch, trackpad, keyboard and
   assistive tech all work with JS disabled; the arrows and the rail only
   automate and describe what a drag already does. --per sets cards-in-view. */
.hl-head { display: flex; align-items: flex-end; justify-content: space-between; gap: var(--s-6); margin-bottom: clamp(32px, 4vw, 48px); }
.hl-head h2 { margin-top: var(--s-4); }
.hl-head p { color: var(--ink-600); margin-top: var(--s-3); max-width: 54ch; }

.carousel-nav { display: flex; gap: var(--s-2); flex: none; }
.carousel-btn {
  width: 44px; height: 44px; display: grid; place-items: center; cursor: pointer;
  background: var(--white); border: 1px solid var(--line-200); color: var(--black);
  transition: border-color var(--t-fast) var(--ease-out), background var(--t-fast) var(--ease-out);
}
.carousel-btn svg { width: 18px; height: 18px; }
.carousel-btn:hover:not(:disabled) { border-color: var(--black); background: var(--surface-100); }
/* Disabled controls are exempt from SC 1.4.11, and the arrows are never the
   only way to reach a card — the track scrolls and every card is in the DOM. */
.carousel-btn:disabled { color: var(--line-200); cursor: default; }

.hl-track {
  --per: 4;
  display: flex; gap: var(--s-5); overflow-x: auto; scroll-behavior: smooth;
  scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none;
}
.hl-track::-webkit-scrollbar { display: none; }
.hl-track > * { flex: 0 0 calc((100% - (var(--per) - 1) * var(--s-5)) / var(--per)); scroll-snap-align: start; }

.carousel-rail { position: relative; height: 1px; background: var(--line-200); margin-top: var(--s-6); }
.carousel-rail span {
  position: absolute; top: -1px; height: 3px; background: var(--gold-deep);
  transition: left var(--t-fast) var(--ease-out);
}
/* Nothing to page through once every card fits */
.hl-carousel.is-static .carousel-nav,
.hl-carousel.is-static .carousel-rail { display: none; }

@media (prefers-reduced-motion: reduce) { .hl-track { scroll-behavior: auto; } }
@media (max-width: 1180px) { .hl-track { --per: 3; } }
@media (max-width: 900px)  { .hl-track { --per: 2; } }
@media (max-width: 620px)  {
  .hl-track { --per: 1; }
  .hl-head { flex-direction: column; align-items: flex-start; gap: var(--s-5); }
}

/* Split feature */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(48px, 6vw, 96px); align-items: center; }
.split-copy > * + * { margin-top: var(--s-5); }
.split-copy p { color: var(--ink-600); }
.split--rev .split-visual { order: 2; }
@media (max-width: 900px) {
  .split, .split--rev { grid-template-columns: 1fr; }
  .split--rev .split-visual { order: 0; }
}

.split-visual { position: relative; }
.split-visual .frame { position: relative; z-index: 1; overflow: hidden; }
.split-visual .frame img { width: 100%; object-fit: cover; transition: transform 1.2s var(--ease-out); }
.split-visual:hover .frame img { transform: scale(1.03); }
/* Cropped gold arc behind imagery */

/* Floating stat chip → static editorial marker */
.chip-float {
  position: absolute; z-index: 3; background: var(--white);
  border: 1px solid var(--black);
  padding: 16px 20px;
  display: flex; align-items: center; gap: 14px;
}
.chip-float .num { font-family: var(--font-display); font-weight: 700; font-size: 1.5rem; color: var(--black); line-height: 1; }
.chip-float .lbl { font-size: .72rem; letter-spacing: .06em; text-transform: uppercase; color: var(--ink-400); line-height: 1.5; }
.chip-float .ico { width: 40px; height: 40px; border: 1px solid var(--line-200); border-radius: 50%; display: grid; place-items: center; flex: none; }
.chip-float .ico svg { width: 18px; height: 18px; stroke: var(--black); }

/* Checklist */
.checklist li { display: flex; gap: 16px; align-items: flex-start; padding-block: 12px; color: var(--ink-600); }
.checklist li + li { border-top: 1px solid var(--line-200); }
.checklist .tick {
  flex: none; width: 26px; height: 26px; border-radius: 50%; margin-top: 2px;
  border: 1px solid var(--black); display: grid; place-items: center;
}
.checklist .tick svg { width: 13px; height: 13px; stroke: var(--black); }
.checklist strong { color: var(--black); font-weight: 700; }

/* Quote module - large serif, gold mark, generous space */
.quote {
  position: relative; margin-top: var(--s-6); padding: var(--s-5) 0 var(--s-5) 64px;
  font-family: var(--font-display); font-style: italic; font-size: 1.35rem; line-height: 1.5;
  color: var(--black);
}
.quote::before {
  content: "\201C"; position: absolute; left: 0; top: 8px;
  font-family: var(--font-display); font-style: normal; font-size: 4.4rem; line-height: 1; color: var(--gold);
}
.quote footer {
  margin-top: var(--s-4); font-family: var(--font-body); font-style: normal;
  font-size: .76rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-600);
}

/* ==========================================================================
   FULL-BLEED BAND (factory / statements)
   ========================================================================== */
.band {
  position: relative; overflow: hidden; color: var(--white);
  padding-block: clamp(96px, 12vw, 168px);
}
.band .band-bg {
  position: absolute; inset: 0; z-index: 0;
  background-size: cover; background-position: center;
}
.band .band-scrim { position: absolute; inset: 0; z-index: 1; background: linear-gradient(180deg, rgba(0,0,0,.82), rgba(0,0,0,.7)); }
.band .container { position: relative; z-index: 2; }
.band h2 { color: var(--white); }
.band .lead { color: var(--on-dark); }

/* Stats row - large serif numbers over thin gold rules */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(32px, 4vw, 64px); margin-top: clamp(48px, 6vw, 80px); text-align: left; }
.stat { padding-top: var(--s-4); border-top: 1px solid var(--gold); background: none; border-radius: 0; }
.stat .num { font-family: var(--font-display); font-size: clamp(2.4rem, 4.4vw, 3.6rem); font-weight: 600; color: var(--white); line-height: 1; }
.stat .num sup { font-size: .5em; color: var(--gold-text); }
.stat .lbl { font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--on-dark-muted); margin-top: 10px; }
@media (max-width: 800px) { .stats { grid-template-columns: repeat(2, 1fr); } }

/* Certification strip — the compliance proof a trade buyer looks for, sitting at
   the foot of the factory band so scale and certification read as one argument.
   Deliberately sans, not the serif used by .stat: these are regulatory marks,
   not figures, and they must not compete with the statistics above them. */
.cert-strip {
  margin-top: clamp(48px, 6vw, 72px);
  padding-top: var(--s-5);
  border-top: 1px solid rgba(227, 165, 53, .45);
  display: flex; flex-wrap: wrap; align-items: baseline;
  gap: var(--s-4) clamp(28px, 4vw, 56px);
  text-align: left;
}
.cert-strip-label {
  flex: none;
  font-size: .72rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--on-dark-muted);
}
.cert-list {
  display: flex; flex-wrap: wrap;
  gap: var(--s-4) clamp(24px, 3.5vw, 48px);
}
.cert { display: flex; flex-direction: column; gap: 5px; }
.cert-name {
  font-size: .95rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--white); line-height: 1;
}
.cert-ref {
  font-size: .7rem; letter-spacing: .12em;
  color: var(--on-dark-muted); line-height: 1;
}
@media (max-width: 640px) {
  .cert-strip { flex-direction: column; gap: var(--s-4); }
}

/* ==========================================================================
   FAQ
   ========================================================================== */
.faq-wrap { display: grid; grid-template-columns: .9fr 1.1fr; gap: clamp(48px, 6vw, 88px); align-items: start; }
/* minmax(0,1fr), not 1fr: a grid item defaults to min-width:auto and so
   refuses to shrink below its content's min-content width, which pushed this
   column to 360px inside a 327px container and gave the page a horizontal
   scrollbar on a 375px phone. */
@media (max-width: 900px) { .faq-wrap { grid-template-columns: minmax(0, 1fr); } }
.faq-list { border-top: 1px solid var(--black); }
.faq-item { border-bottom: 1px solid var(--line-200); background: none; }
.faq-q {
  width: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--s-4);
  padding: 26px 4px; text-align: left; font-weight: 700; color: var(--black); font-size: 1.02rem;
}
.faq-q .faq-ico {
  flex: none; width: 34px; height: 34px; border-radius: 50%; border: 1px solid var(--black);
  display: grid; place-items: center; transition: transform var(--t-med) var(--ease-out), background var(--t-med);
}
.faq-q .faq-ico svg { width: 14px; height: 14px; stroke: var(--black); transition: stroke var(--t-med); }
.faq-item.is-open .faq-ico { transform: rotate(45deg); background: var(--black); }
.faq-item.is-open .faq-ico svg { stroke: var(--white); }
.faq-a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--t-slow) var(--ease-out); }
.faq-item.is-open .faq-a { grid-template-rows: 1fr; }
.faq-a-inner { overflow: hidden; }
.faq-a-inner p { padding: 0 56px 26px 4px; font-size: .96rem; color: var(--ink-600); }

/* ==========================================================================
   CTA BAND - black editorial statement with gold arc
   ========================================================================== */
.cta-band { position: relative; overflow: hidden; background: var(--black); color: var(--white); padding: clamp(56px, 7vw, 96px); }
.cta-band h2 { color: var(--white); }
.cta-band .lead { color: var(--on-dark-muted); }
.cta-band-inner { display: grid; grid-template-columns: 1.2fr .8fr; gap: var(--s-7); align-items: center; position: relative; z-index: 2; }
.cta-band .checklist li { color: var(--on-dark); padding-block: 10px; }
.cta-band .checklist li + li { border-top-color: #333; }
.cta-band .checklist .tick { border-color: var(--gold); }
.cta-band .checklist .tick svg { stroke: var(--gold); }
.cta-band .checklist strong { color: var(--white); }
.cta-band .deco {
  position: absolute; border-radius: 50%; border: 1px solid var(--gold); background: none;
  opacity: .6; pointer-events: none; z-index: 1;
}
@media (max-width: 900px) { .cta-band-inner { grid-template-columns: minmax(0, 1fr); } }

/* ==========================================================================
   NEWS / UPDATES CARDS
   ========================================================================== */
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
.news-card { overflow: hidden; display: flex; flex-direction: column; border: 0; }
.news-card .cover { position: relative; overflow: hidden; aspect-ratio: 16 / 10; background: var(--surface-100); }
.news-card .cover img { width: 100%; height: 100%; object-fit: cover; transition: transform 1.2s var(--ease-out); }
.news-card:hover .cover img { transform: scale(1.04); }
.news-card .body { padding: var(--s-5) 0 0; display: flex; flex-direction: column; gap: var(--s-3); flex: 1; }
.news-card .body h3 { font-size: 1.45rem; }
.news-card .body p { font-size: .93rem; color: var(--ink-600); }
.news-card .play {
  position: absolute; inset: 0; margin: auto; width: 64px; height: 64px; border-radius: 50%;
  background: var(--white); display: grid; place-items: center;
  transition: transform var(--t-med) var(--ease-out);
}
.news-card .play svg { width: 20px; height: 20px; fill: var(--black); margin-left: 3px; }
.news-card:hover .play { transform: scale(1.06); }
a.news-card { color: inherit; text-decoration: none; }
@media (max-width: 900px) { .news-grid { grid-template-columns: 1fr; max-width: 480px; margin-inline: auto; } }

/* Video lightbox.
   The cards are ordinary links to youtube.com, so they still work with
   main.js absent — the dialog is an upgrade, not the mechanism. The iframe is
   built on click and destroyed on close, so no request reaches YouTube until
   a visitor asks for a video, and closing genuinely stops playback. */
.video-modal {
  width: 100%; max-width: none; height: 100%; max-height: none;
  margin: 0; padding: 0; border: 0; background: transparent; overflow: hidden;
}
.video-modal::backdrop { background: rgba(0, 0, 0, .92); }
.video-modal-inner { width: 100%; height: 100%; display: grid; place-items: center; padding: clamp(16px, 4vw, 64px); }
.video-modal-frame { width: min(1120px, 100%); aspect-ratio: 16 / 9; background: var(--black); position: relative; }
.video-modal-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.video-modal-close {
  position: absolute; top: 16px; right: 16px;
  width: 48px; height: 48px; display: grid; place-items: center; cursor: pointer;
  background: transparent; border: 1px solid rgba(255, 255, 255, .45); color: var(--white);
  transition: background var(--t-fast) var(--ease-out), border-color var(--t-fast) var(--ease-out), color var(--t-fast) var(--ease-out);
}
.video-modal-close svg { width: 20px; height: 20px; }
/* Black on gold, never white — gold is only 2.16:1 against white */
.video-modal-close:hover { background: var(--gold); border-color: var(--gold); color: var(--black); }

/* ==========================================================================
   PRODUCTS PAGE
   ========================================================================== */
/* Stain ticker */
.ticker-band { background: var(--black); border-block: 1px solid var(--black); padding-block: 16px; overflow: hidden; }
.ticker { display: flex; width: max-content; animation: ticker-scroll 30s linear infinite; }
.ticker-band:hover .ticker { animation-play-state: paused; }
.ticker span {
  display: inline-flex; align-items: center; gap: 28px; padding-inline: 28px;
  color: var(--on-dark-muted); font-weight: 700; letter-spacing: .22em; text-transform: uppercase; font-size: .78rem;
  white-space: nowrap;
}
.ticker span::after { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--gold); }
@keyframes ticker-scroll { to { transform: translateX(-50%); } }

/* Before / after stain demo */
.ba-demo {
  position: relative; overflow: hidden; border: 1px solid var(--line-200);
  touch-action: none; user-select: none; background: var(--surface-100);
}
.ba-demo img { width: 100%; display: block; pointer-events: none; }
.ba-after { position: absolute; inset: 0; overflow: hidden; }
.ba-after img { height: 100%; width: 100%; object-fit: cover; object-position: left center; }
.ba-handle {
  position: absolute; top: 0; bottom: 0; width: 1px; background: var(--black);
  cursor: ew-resize;
}
.ba-handle::after {
  content: ""; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: 52px; height: 52px; border-radius: 50%; background: var(--white); border: 1px solid var(--black);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 8l-4 4 4 4M16 8l4 4-4 4'/%3E%3C/svg%3E");
  background-size: 22px; background-position: center; background-repeat: no-repeat;
}
.ba-label {
  position: absolute; top: 16px; padding: 8px 16px;
  font-size: .72rem; font-weight: 700; letter-spacing: .18em; text-transform: uppercase;
  background: var(--white); color: var(--black); z-index: 2;
}
.ba-label--before { left: 16px; }
.ba-label--after { right: 16px; background: var(--black); color: var(--white); }

/* 5-in-1 power */
.power { display: grid; grid-template-columns: .95fr 1.05fr; gap: clamp(48px, 6vw, 96px); align-items: center; }
@media (max-width: 900px) { .power { grid-template-columns: 1fr; } }
.power-list { margin-top: var(--s-5); border-top: 1px solid var(--black); }
.power-item {
  display: flex; align-items: center; gap: 18px; padding: 18px 4px;
  background: none; border-bottom: 1px solid var(--line-200);
  transition: transform var(--t-med) var(--ease-out);
}
.power-item:hover { transform: translateX(6px); }
.power-item .ico { flex: none; width: 44px; height: 44px; border: 1px solid var(--black); border-radius: 50%; display: grid; place-items: center; }
.power-item .ico svg { width: 20px; height: 20px; stroke: var(--black); }
.power-item p { color: var(--ink-600); }

/* Range tabs + pickers - rectangular, underline-active */
/* DORMANT. The Too Clean / Mama Joy tab switcher moved off the range hub when
   each line got its own page, so no markup currently uses these. Kept because
   the JS hook in main.js still binds them and a future multi-line page would
   want them back. NOTE the trap: `.range-panel` is display:none until
   `.is-active`, which is why the catalogue configurators deliberately omit
   that class - add it without the tabs and the picker disappears. */
.range-tabs { display: flex; flex-wrap: wrap; gap: var(--s-6); justify-content: center; margin-bottom: var(--s-7); border-bottom: 1px solid var(--line-200); }
.range-tab {
  padding: 14px 4px; font-weight: 700; font-size: .82rem; letter-spacing: .18em; text-transform: uppercase;
  color: var(--ink-400); border-bottom: 2px solid transparent; margin-bottom: -1px;
  transition: color var(--t-med);
}
.range-tab:hover { color: var(--black); }
.range-tab.is-active { color: var(--black); border-bottom-color: var(--gold-deep); }

.range-panel { display: none; }
.range-panel.is-active { display: block; animation: panel-in var(--t-slow) var(--ease-out); }
@keyframes panel-in { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }

.range-stage { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(40px, 5vw, 80px); align-items: center; }
@media (max-width: 900px) { .range-stage { grid-template-columns: 1fr; } }
.range-stage .stage {
  position: relative; display: grid; place-items: center; padding: var(--s-6);
  min-height: 400px;
}
/* True circle, never an ellipse - the motif depends on precision */
.range-stage .stage::before {
  content: ""; position: absolute;
  top: 50%; left: 50%; transform: translate(-50%, -50%);
  width: min(86%, 420px); aspect-ratio: 1; border-radius: 50%;
  border: 1px solid var(--gold);
}
.range-stage .stage img {
  position: relative; z-index: 1; max-height: 400px; width: auto; max-width: 100%;
  /* Product shots are white-background JPGs: multiply drops the white into the page */
  mix-blend-mode: multiply;
  transition: opacity var(--t-med) ease, transform var(--t-med) var(--ease-out);
}
.range-stage .stage img.is-swapping { opacity: 0; transform: scale(.97); }

.size-picker { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-4); }
.size-btn {
  padding: 11px 20px; font-weight: 700; font-size: .8rem; letter-spacing: .08em;
  border: 1px solid var(--line-200); color: var(--ink-600); background: var(--white);
  transition: all var(--t-fast) var(--ease-out);
}
.size-btn:hover { border-color: var(--black); color: var(--black); }
.size-btn.is-active { background: var(--black); border-color: var(--black); color: var(--white); }

.variant-picker { display: flex; flex-wrap: wrap; gap: var(--s-2); margin-top: var(--s-2); }
.variant-btn {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 11px 20px; font-weight: 700; font-size: .8rem; letter-spacing: .08em;
  border: 1px solid var(--line-200); color: var(--ink-600); background: var(--white);
  transition: all var(--t-fast) var(--ease-out);
}
.variant-btn .swatch { width: 10px; height: 10px; border-radius: 50%; }
.variant-btn:hover { border-color: var(--black); color: var(--black); }
.variant-btn.is-active { border-color: var(--black); color: var(--black); box-shadow: inset 0 0 0 1px var(--black); }

/* Soap gallery */
/* Category groups on the range hub. The gold hairline above the label is the
   same device as .mega-head in the nav, so the two indexes of the range read
   as the same system. */
.line-group + .line-group { margin-top: clamp(56px, 7vw, 88px); }
.line-group-head {
  border-top: 1px solid var(--gold);
  padding-top: 18px; margin-bottom: var(--s-6);
  display: flex; align-items: baseline; gap: clamp(16px, 3vw, 40px); flex-wrap: wrap;
}
.line-group-head h3 {
  font-family: var(--font-body);
  font-size: .78rem; font-weight: 700; letter-spacing: .22em; text-transform: uppercase;
  color: var(--black); flex: none;
}
.line-group-head p { font-size: .95rem; color: var(--ink-600); max-width: 62ch; }

/* ---------------------------------------------------------------------------
   THE SPECIMEN SHEET

   This replaced a card grid that stacked three boxes inside one another: the
   .card border, then a tinted .cover plinth, then — the one invisible in the
   CSS — the pack photograph's OWN white rectangle, because the range shots are
   white-ground JPGs. Three frames around every product.

   All three are gone. The packs now sit directly on the page and are separated
   by a shared hairline rule and space, so the grid reads as one ruled sheet
   rather than a row of disconnected tiles. Structure comes from alignment and
   type; the only ink spent on chrome is a 1px rule.

   The class names are unchanged because .soap-card is used across sixteen
   files — `.cover` and `.body` are now composition slots, not boxes.
   --------------------------------------------------------------------------- */
.soap-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(32px, 4vw, 56px) clamp(24px, 3vw, 48px); }
/* Variant sheets (Nova 10, She 9, Classy 7) carry a name and a weight and
   nothing else, so they take a denser self-balancing track and avoid the
   orphan row a fixed three columns leaves behind. */
.soap-grid--specimens { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); }
@media (max-width: 1000px) { .soap-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px)  { .soap-grid { grid-template-columns: 1fr; } }
@media (max-width: 620px)  { .soap-grid--specimens { grid-template-columns: repeat(2, 1fr); } }

/* Out-specify `.card` (0,1,0) to strip the frame without touching the markup */
.card.soap-card,
.card.soap-card:hover {
  /* One source of truth for the shelf height. The cover and the image cap must
     agree exactly, and a percentage cannot do it — see the note on the img. */
  --cover-h: clamp(150px, 17vw, 210px);
  background: transparent; border: 0; border-top: 1px solid var(--line-200);
  overflow: visible; display: flex; flex-direction: column;
  padding-top: var(--s-5);
}
a.soap-card { color: inherit; text-decoration: none; }

/* A common floor line: every pack stands on the same baseline whatever its
   shape, the way objects sit on a shelf. `place-items: end center` is doing
   the whole job — a tall 80g carton and a wide 180g bar still line up. */
.soap-card .cover {
  aspect-ratio: auto; background: none; padding: 0; overflow: visible;
  height: var(--cover-h);
  display: grid; place-items: end center;
  margin-bottom: var(--s-5);
}
.soap-card .cover img {
  /* The cap must be a LENGTH, not `max-height: 100%`. A percentage max-height
     on a centred grid item resolves against an indefinite block and is
     silently dropped — the 222x356 Mama Joy pack rendered at its full natural
     height and collided with the copy below it. Same trap as the home
     carousel thumbs. */
  max-height: var(--cover-h); max-width: 100%; width: auto; height: auto; object-fit: contain;
  /* Dissolves the white ground the range JPGs are shot on. A no-op for the
     cut-out PNGs, so one rule covers both kinds of source. */
  mix-blend-mode: multiply;
  transition: transform var(--t-slow) var(--ease-out);
}
/* Lift, not zoom — the pack keeps its true size and simply rises */
.soap-card:hover .cover img { transform: translateY(-8px); }

.soap-card .body { padding: 0; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.soap-card .body .tag {
  font-size: .68rem; letter-spacing: .2em; text-transform: uppercase;
  font-weight: 700; color: var(--ink-400);
}
.soap-card .body h3 {
  font-size: clamp(1.2rem, 1.5vw, 1.45rem); line-height: 1.2;
  transition: color var(--t-fast) var(--ease-out);
}
.soap-card:hover .body h3 { color: var(--gold-text); }
.soap-card .body p { font-size: .92rem; line-height: 1.7; color: var(--ink-600); margin-top: 4px; }
.soap-card .body .link { margin-top: auto; padding-top: var(--s-4); align-self: flex-start; }

/* The stockist invite is a call to action, not a specimen: it keeps its panel.
   Its `p` rule must out-specify `.soap-card .body p` above, or the
   light-surface ink token wins the cascade and lands on black at 2.5:1. */
.card.soap-card--invite,
.card.soap-card--invite:hover {
  background: var(--black); border: 0; padding-top: 0; color: var(--white);
}
.soap-card--invite .body h3 { color: var(--white); }
.soap-card--invite:hover .body h3 { color: var(--white); }
.soap-card--invite .body p { color: var(--on-dark-muted); }

/* ==========================================================================
   ABOUT PAGE
   ========================================================================== */
.values-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s-5); }
@media (max-width: 1000px) { .values-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 620px) { .values-grid { grid-template-columns: 1fr; } }
.value-card { padding: var(--s-6); display: flex; flex-direction: column; gap: var(--s-3); position: relative; overflow: hidden; }
.value-card h3 { font-size: 1.4rem; }
.value-card .ico {
  width: 52px; height: 52px; border: 1px solid var(--black); border-radius: 50%;
  display: grid; place-items: center; transition: background var(--t-med), transform var(--t-med) var(--ease-out);
}
.value-card .ico svg { width: 24px; height: 24px; stroke: var(--black); transition: stroke var(--t-med); }
.value-card:hover .ico { background: var(--black); }
.value-card:hover .ico svg { stroke: var(--white); }
.value-card p { font-size: .93rem; color: var(--ink-600); }
.value-card .corner {
  position: absolute; top: -46px; right: -46px; width: 120px; height: 120px; border-radius: 50%;
  border: 1px solid var(--gold); opacity: .55;
}

/* Testimonial orbit */
.orbit-section { position: relative; }
.orbit-visual { position: relative; max-width: 860px; margin-inline: auto; }
.orbit-visual .orbit-img { margin-inline: auto; }
.testi-card { max-width: 680px; margin: 0 auto var(--s-7); text-align: center; }
.testi-card p { font-family: var(--font-display); font-size: clamp(1.3rem, 2vw, 1.7rem); font-style: italic; color: var(--black); line-height: 1.5; }
.testi-card footer { margin-top: var(--s-4); font-weight: 700; font-size: .76rem; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-600); }
.testi-card .stars { display: flex; justify-content: center; gap: 5px; margin-bottom: var(--s-4); }
/* gold-deep: the rating is read by counting shapes, so they need 3:1 against
   the card. The aria-label carries the meaning; this carries the countability. */
.testi-card .stars svg { width: 17px; height: 17px; fill: var(--gold-deep); }

/* About hero: cut-out portrait standing on a warm editorial plane */
.about-hero-visual { position: relative; }
.portrait-stage { position: relative; display: flex; justify-content: center; }
/* The plane the figure stands in front of - a flat rectangle, not a shape */
.portrait-plane {
  position: absolute; z-index: 0;
  left: 6%; right: 6%; top: 14%; bottom: 0;
  background: var(--surface-100);
  border-top: 1px solid var(--gold);
}
.portrait-cutout {
  position: relative; z-index: 1;
  width: 100%; max-width: 460px; height: auto;
  margin-inline: auto;
}

/* Statistic row - very large serif numerals over thin gold rules */
.portrait-stats {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(16px, 2.5vw, 32px);
  margin-top: var(--s-5);
}
.portrait-stats li { border-top: 1px solid var(--gold); padding-top: var(--s-3); }
.portrait-stats .num {
  display: block; font-family: var(--font-display); font-weight: 600;
  font-size: clamp(1.6rem, 2.6vw, 2.2rem); line-height: 1; color: var(--black);
}
.portrait-stats .num sup { font-size: .5em; color: var(--gold-text); }
.portrait-stats .lbl {
  display: block; margin-top: 8px;
  font-size: .7rem; font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink-400);
}
@media (max-width: 900px) {
  .about-hero-visual { max-width: 460px; margin-inline: auto; }
  .portrait-stats { text-align: left; }
}

.badge-pill {
  display: inline-flex; align-items: center; gap: 12px;
  background: var(--black); color: var(--white);
  padding: 16px 28px; font-weight: 700; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase;
}
.badge-pill svg { stroke: var(--gold); }

/* ==========================================================================
   CONTACT PAGE
   ========================================================================== */
.contact-hero-panel { display: grid; grid-template-columns: 1fr 1.1fr; overflow: hidden; }
@media (max-width: 900px) { .contact-hero-panel { grid-template-columns: 1fr; } }
.contact-hero-copy { background: var(--black); color: var(--white); padding: clamp(40px, 5vw, 72px); display: flex; flex-direction: column; gap: var(--s-4); justify-content: center; }
.contact-hero-copy h1 { color: var(--white); }
.contact-hero-copy p { color: var(--on-dark-muted); }
.contact-hero-img { min-height: 320px; }
.contact-hero-img img { width: 100%; height: 100%; object-fit: cover; }

.contact-layout { display: grid; grid-template-columns: 1.1fr .9fr; gap: clamp(48px, 5vw, 80px); align-items: start; }
@media (max-width: 900px) { .contact-layout { grid-template-columns: 1fr; } }

/* Form */
.form-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-5) var(--s-4); }
.form-grid .full { grid-column: 1 / -1; }
/* Honeypot. Taken out of flow and off-screen rather than display:none, because
   some bots skip fields that are display:none but still fill everything else.
   A real person never sees it; contact.php discards any post that fills it. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
@media (max-width: 560px) { .form-grid { grid-template-columns: 1fr; } }
.field label { display: block; font-weight: 700; font-size: .74rem; letter-spacing: .14em; text-transform: uppercase; color: var(--black); margin-bottom: 10px; }
.field label .req { color: var(--gold-text); }
.field input, .field textarea, .field select {
  width: 100%; padding: 14px 16px;
  border: 1px solid var(--line-200); background: var(--white);
  font: inherit; font-size: .95rem; color: var(--black); min-height: 52px;
  transition: border-color var(--t-fast);
}
.field textarea { min-height: 140px; resize: vertical; }
/* Explicit placeholder tone: the UA default varies by browser (Firefox applies
   its own opacity) and can fall under AA. opacity:1 defeats that. */
.field input::placeholder, .field textarea::placeholder { color: var(--ink-400); opacity: 1; }
.field input:focus, .field textarea:focus, .field select:focus {
  outline: none; border-color: var(--black); box-shadow: inset 0 0 0 1px var(--black);
}
/* Errors are gold, not red, because the palette has no red left. Gold alone
   reads as a hint rather than a fault, so the "!" badge carries the alarm and
   the message text carries the meaning - colour is never the only signal
   (SC 1.4.1), which is what makes a red-free error state legitimate. */
.field .error-msg { display: none; font-size: .82rem; font-weight: 600; color: var(--gold-text); margin-top: 8px; }
.field.has-error .error-msg { display: flex; align-items: center; gap: 8px; }
.field .error-msg::before {
  content: "!"; flex: none;
  width: 16px; height: 16px; display: grid; place-items: center;
  background: var(--gold-text); color: var(--white);
  font-size: .7rem; font-weight: 800; line-height: 1;
}
.field.has-error input, .field.has-error textarea { border-color: var(--gold-text); box-shadow: inset 0 0 0 1px var(--gold-text); }
.form-status { display: none; margin-top: var(--s-4); padding: 16px 20px; font-weight: 600; font-size: .92rem; }
.form-status.is-success,
.form-status.is-error { display: flex; gap: 12px; align-items: center; background: var(--surface-100); color: var(--black); }
.form-status.is-success { border-left: 1px solid var(--gold); }
/* Error stays inside the red-free system: gold-deep rule + gold-text label,
   same language as the per-field errors. The success tick is hidden so a
   checkmark never sits beside a failure message. */
.form-status.is-error { border-left: 1px solid var(--gold-deep); color: var(--gold-text); }
.form-status.is-error svg { display: none; }

/* Contact info cards */
.info-cards { display: grid; gap: var(--s-4); }
.info-card { display: flex; gap: 18px; align-items: center; padding: var(--s-5); }
.info-card .ico { flex: none; width: 52px; height: 52px; border: 1px solid var(--black); border-radius: 50%; display: grid; place-items: center; }
.info-card .ico svg { width: 22px; height: 22px; stroke: var(--black); }
.info-card h4 { margin-bottom: 4px; font-size: .78rem; letter-spacing: .14em; text-transform: uppercase; }
/* `anywhere` also shrinks min-content width, so the address broke eagerly and
   orphaned its TLD. `break-word` only breaks when there is genuinely no room. */
.info-card a { color: var(--ink-600); font-weight: 600; overflow-wrap: break-word; }
.info-card a:hover { color: var(--black); text-decoration: underline; }

.mosaic { display: grid; grid-template-columns: 1fr 1fr; gap: var(--s-3); margin-top: var(--s-4); }
.mosaic img { aspect-ratio: 4/3; object-fit: cover; width: 100%; filter: none; transition: transform var(--t-slow) var(--ease-out); }
.mosaic img:hover { transform: scale(1.02); }

.social-row { display: flex; gap: var(--s-3); }
.social-row a {
  width: 44px; height: 44px; display: grid; place-items: center;
  border: 1px solid var(--line-200); transition: all var(--t-med) var(--ease-out);
}
.social-row a svg { width: 18px; height: 18px; fill: var(--black); transition: fill var(--t-med); }
.social-row a:hover { background: var(--black); border-color: var(--black); }
.social-row a:hover svg { fill: var(--white); }

.map-frame { overflow: hidden; border: 1px solid var(--line-200); line-height: 0; }
.map-frame iframe { width: 100%; height: 440px; border: 0; filter: grayscale(1) contrast(1.04); }

/* ==========================================================================
   FOOTER
   ========================================================================== */
/* Pre-footer: the gold editorial moment.
   Everything on this band is BLACK, not white. Gold is a light tone, so it
   behaves like a pale surface: black type reads 9.70:1, white would be 2.16:1.
   This is the one place gold appears as a large field rather than a hairline -
   it is the band that separates the page from the black footer. */
.prefooter {
  position: relative; overflow: hidden;
  background: var(--gold); padding-block: var(--s-7);
  border-top: 1px solid var(--black);   /* depth from rules, not shadows */
}

/* --- The ornament ------------------------------------------------------
   Two devices, both drawn entirely in pseudo-elements so the 11 duplicated
   prefooter blocks need no markup change:

   1. Engraved diagonal hairlines - the visual language of banknotes and
      share certificates. Hard stops, so it reads as line art rather than a
      gradient, which the brand system bans.
   2. Two oversized cropped arcs - the brand's circle motif, inverted to
      black on gold. The radius has to be roughly 7x the band height or the
      circle crops into two near-vertical lines and the motif is lost.

   Both are masked away from the left so the display type always sits on
   clean gold. Worst case, black type over an engraved line is 7.30:1.
   ---------------------------------------------------------------------- */
.prefooter::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background-image: repeating-linear-gradient(
    -45deg,
    rgba(0, 0, 0, .14) 0 1px,
    transparent 1px 10px
  );
  -webkit-mask-image: linear-gradient(to right, transparent 20%, #000 46%);
  mask-image: linear-gradient(to right, transparent 20%, #000 46%);
}
.prefooter::after {
  content: ""; position: absolute; pointer-events: none;
  width: 1180px; aspect-ratio: 1; border-radius: 50%;
  border: 1px solid var(--black);
  right: 3%; bottom: -84%;
  -webkit-mask-image: linear-gradient(to right, transparent 22%, #000 52%);
  mask-image: linear-gradient(to right, transparent 22%, #000 52%);
}
.prefooter-inner::before {
  content: ""; position: absolute; pointer-events: none;
  width: 1480px; aspect-ratio: 1; border-radius: 50%;
  border: 1px solid rgba(0, 0, 0, .38);
  right: -14%; bottom: -112%; z-index: -1;
  -webkit-mask-image: linear-gradient(to right, transparent 30%, #000 60%);
  mask-image: linear-gradient(to right, transparent 30%, #000 60%);
}

/* z-index 2 keeps the type and button above every ornament layer. */
.prefooter-inner {
  position: relative; z-index: 2;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s-5); flex-wrap: wrap;
}

/* The band stacks below 900px, so it becomes proportionally taller and much
   narrower. The arcs then show a tight, crowded portion of curve instead of a
   sweep, and they cross the type. Texture alone carries the band at this size. */
@media (max-width: 900px) {
  .prefooter::after,
  .prefooter-inner::before { display: none; }
  .prefooter::before {
    -webkit-mask-image: linear-gradient(to bottom right, transparent 18%, #000 55%);
    mask-image: linear-gradient(to bottom right, transparent 18%, #000 55%);
  }
}
.prefooter .talk { display: flex; align-items: center; gap: 16px; color: var(--black); font-family: var(--font-display); font-size: clamp(2rem, 3.4vw, 2.9rem); font-weight: 600; font-style: italic; }
.prefooter .talk .heart { width: 26px; height: 26px; }
.prefooter .talk .heart path { fill: var(--black); }
.prefooter .btn--light { background: var(--black); color: var(--white); }
.prefooter .btn--light:hover { background: var(--white); color: var(--black); }
.prefooter :focus-visible { outline-color: var(--black); }

.site-footer { background: var(--black); color: var(--on-dark-muted); padding: clamp(64px, 8vw, 96px) 0 0; }
.footer-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: var(--s-7); padding-bottom: var(--s-8); }
@media (max-width: 1000px) { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .footer-grid { grid-template-columns: 1fr; } }
/* No white chip: that existed only because the old red mark needed a light
   ground. The gold wordmark sits straight on the black at 9.70:1. */
.footer-brand img { height: 46px; width: auto; }
.footer-brand p { margin-top: var(--s-4); font-size: .9rem; color: var(--on-dark-muted); max-width: 34ch; }
.site-footer h5 {
  color: var(--white); font-size: .76rem; font-weight: 700; letter-spacing: .2em; text-transform: uppercase;
  margin-bottom: var(--s-4); padding-bottom: 12px; position: relative;
}
.site-footer h5::after { content: ""; position: absolute; left: 0; bottom: 0; width: 28px; height: 1px; background: var(--gold); }
.footer-links li { margin-bottom: 12px; }
.footer-links a { display: inline-block; font-size: .92rem; color: var(--on-dark-muted); transition: color var(--t-fast), transform var(--t-fast) var(--ease-out); }
.footer-links a:hover { color: var(--white); transform: translateX(6px); }
.footer-contact li { display: flex; gap: 12px; align-items: flex-start; margin-bottom: 14px; font-size: .92rem; color: var(--on-dark-muted); }
.footer-contact svg { flex: none; width: 17px; height: 17px; stroke: var(--gold); margin-top: 4px; }
.footer-contact a:hover { color: var(--white); }
.footer-social { display: flex; gap: 12px; margin-top: var(--s-5); }
.footer-social a { width: 42px; height: 42px; display: grid; place-items: center; border: 1px solid #333; transition: all var(--t-med) var(--ease-out); }
.footer-social a svg { width: 17px; height: 17px; fill: var(--on-dark-muted); }
.footer-social a:hover { background: var(--white); border-color: var(--white); }
.footer-social a:hover svg { fill: var(--black); }
/* The trailing bottom padding clears the fixed .to-top button, which floats
   over the bottom-right corner (24px offset + 52px tall = 76px) and was
   covering the last credit in this row once the page was scrolled to the end.
   Padding the row down keeps the credits aligned with the columns above,
   which a right-inset would not. */
.footer-bottom { border-top: 1px solid #262626; padding-block: var(--s-5) 84px; font-size: .8rem; display: flex; justify-content: space-between; gap: var(--s-4); flex-wrap: wrap; }
.footer-bottom a { color: var(--on-dark-muted); } .footer-bottom a:hover { color: var(--white); }
/* Stack rather than spread on narrow screens. Spread puts the last credit in
   the bottom-right corner, which is exactly where the fixed .to-top button
   floats - it was covering "Ciatek" entirely at 375px. Left-aligned lines keep
   that corner clear. */
@media (max-width: 700px) {
  .footer-bottom { flex-direction: column; gap: 10px; }
}

/* ==========================================================================
   ANIMATION UTILITIES
   ========================================================================== */
.gs-reveal { opacity: 0; }
html.no-js .gs-reveal, html.reduced-motion .gs-reveal { opacity: 1; }

/* Page-load veil */
.page-veil {
  position: fixed; inset: 0; z-index: 999; background: var(--white);
  display: grid; place-items: center; pointer-events: none;
  transition: opacity .6s ease, visibility 0s .6s;
}
.page-veil.is-done { opacity: 0; visibility: hidden; }
/* clamp, not a fixed height: at 5.36:1 a 60px mark is 322px wide and would
   nearly span a 375px phone. */
.page-veil img { height: clamp(30px, 8vw, 46px); width: auto; }

/* Back-to-top */
.to-top {
  position: fixed; right: 24px; bottom: 24px; z-index: 90;
  width: 52px; height: 52px; background: var(--black); color: var(--white);
  display: grid; place-items: center;
  opacity: 0; visibility: hidden; transform: translateY(12px);
  transition: all var(--t-med) var(--ease-out);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: none; }
.to-top:hover { background: var(--gold); }
.to-top svg { width: 20px; height: 20px; stroke: var(--white); transition: stroke var(--t-med) var(--ease-out); }
.to-top:hover svg { stroke: var(--black); }   /* white on gold would be 2.16:1 */

/* Skip link */
.skip-link {
  position: absolute; left: 16px; top: -60px; z-index: 200;
  background: var(--black); color: var(--white); padding: 12px 20px;
  font-weight: 700; font-size: .8rem; letter-spacing: .1em; text-transform: uppercase;
  transition: top var(--t-med);
}
.skip-link:focus { top: 0; }

/* Utility */
.text-center { text-align: center; }
.mt-6 { margin-top: var(--s-6); }
.mt-7 { margin-top: var(--s-7); }
