/* ============ Wadicos - Pages ============ *
 * Page-specific layout overrides. Body classes
 * scope these - .page--home, .page--catalogue, etc.
 * Uses @layer overrides so authoring order is
 * predictable across the cascade.
 * ========================================= */

@layer overrides {
  /* ============ Home - Hero ============ *
   * The .hero <section> is a positioning + spacing wrapper.
   * The visible boxed frame is .hero__frame inside it - this
   * separation lets the section sit flush with surrounding
   * sections while the frame floats inset with margin, border,
   * and radius. Section-wide aria/data attributes stay on the
   * <section>; visual chrome lives on the frame.
   * ===================================================== */
  /* V3 hero recomposition — full-bleed editorial register, no inset
     frame border on the home, mega serif h1 + bottle co-occupying the
     same grid cell on desktop so the bottle interrupts the letterforms
     (the type-on-product overlap from references exemple 4 / 5 / 8).
     The .hero__frame retains its existing wash + shadow but loses its
     border + radius so the composition reads as full-bleed. The frame
     radius retires the raw 25px literal in favor of --radius-frame
     (kept on the frame so non-home pages that reuse this stylesheet
     still get the canonical radius — though _home.css is home-only). */
  .hero {
    position: relative;
    /* Boxed treatment — gives the frame breathing room from the
       viewport edges so the rounded corners read as a card, not a
       full-bleed banner. */
    padding-block: var(--space-4);
    padding-inline: var(--gutter);
  }

  .hero__frame {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    /* The burgundy wine gradient stays as the paint-fail fallback — if
       the bg video fails to load, the maison still reads as itself. */
    background: var(--gradient-wine);
    border: 0;
    border-radius: 20px;
    box-shadow: var(--shadow-lifted);
    max-inline-size: var(--container-wide);
  }

  /* Background loop — red-bubbles atmosphere that fills the whole hero
     frame, behind everything. The dark overlay below it keeps text
     readable against the bright reds. Reduced-motion users get the
     poster still in place of the autoplay (rule lower in this file). */
  .hero__bg {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    z-index: 0;
    pointer-events: none;
  }

  /* Readability overlay — sits between the bg video and the grid copy.
     Stronger darkening on the left where the text column lives, easing
     off toward the right where the arched candle figure carries its
     own internal contrast. */
  .hero__frame::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background:
      linear-gradient(105deg,
        color-mix(in srgb, var(--color-glass-ink) 62%, transparent) 0%,
        color-mix(in srgb, var(--color-glass-ink) 42%, transparent) 45%,
        color-mix(in srgb, var(--color-glass-ink) 38%, transparent) 70%,
        color-mix(in srgb, var(--color-glass-ink) 50%, transparent) 100%);
  }

  /* V3 grid: at mobile + tablet, copy + media stack (copy above the
     bottle). At desktop (≥64em) they co-occupy the same grid cell —
     the bottle z-index 1 sits behind the h1 (z-index 2), and the
     bottle's CSS positioning drops it into the h1's vertical centre
     so the product interrupts the second word of the headline. */
  .hero__grid {
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto auto;
    gap: var(--space-7);
    align-items: center;
    position: relative;
    /* Sits above the bg video (z:0) AND the readability overlay (z:1). */
    z-index: 2;
  }

  @media (min-width: 64em) {
    .hero__grid {
      grid-template-columns: minmax(0, 1fr);
      grid-template-rows: minmax(0, auto);
      gap: 0;
    }
    .hero__copy {
      grid-column: 1;
      grid-row: 1;
      z-index: 2;
      align-self: center;
      padding-inline: var(--space-7);
    }
    .hero__media-slot {
      grid-column: 1;
      grid-row: 1;
      z-index: 1;
      justify-self: end;
      align-self: center;
      transform: translateY(8%);
    }
  }

  .hero__copy { display: flex; flex-direction: column; gap: var(--space-5); }

  /* Brand CTA inside the hero — the .btn--red cream-on-burgundy pill
     would otherwise stretch to the full column width inside the flex
     parent. align-self:flex-start keeps it inline-shaped and pinned
     to the start of the column on every viewport. */
  .hero__cta {
    align-self: flex-start;
  }

  /* nowrap + parent .hero__frame overflow:hidden keeps the brand label
     on one line even when ("Heritage Collection", "Franck Olivier")
     overflow the column at 320 px — §1.5 demands ≤ 2 lines and we
     enforce ≤ 1 for the carousel's brand-only headlines.
     Theme: title pinned to var(--color-cream) (escaping the global
     [data-theme="light"] h1 → burgundy cascade override in base.css)
     because the hero is a "dark theatre" surface in BOTH themes —
     the bubbles video + dark wash overlay dominate the frame, so a
     burgundy heading on a near-black ground reads as a low-contrast
     blur. Cream stays readable on both the dark-theme deep wine and
     the light-theme video composite. */
  .hero__title {
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 1.4rem + 6.5vw, 6rem);
    font-weight: 600;
    color: var(--color-cream);
    line-height: var(--lh-mega-hero);
    letter-spacing: var(--tracking-mega);
    text-transform: none;
    text-wrap: balance;
    white-space: nowrap;
    /* max-inline-size: 24ch; */
    margin: 0;
  }
  /* V3 hero lede: Cormorant italic editorial body-lead register —
     the magazine "lead paragraph" tone the references favour. The
     bridge font ensures Fraunces glyph width doesn't push the lede
     past its 48ch column at 768. Color pinned to cream (same
     theatre-dark rationale as .hero__title above). */
  .hero__lede {
    color: var(--color-cream);
    font-family: var(--font-bridge);
    font-style: italic;
    font-size: var(--fs-body-lead);
    line-height: var(--lh-body-lead);
    max-inline-size: 60ch;
  }

  .hero__media {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    /* Square ratio mirrors the 1000×1000 source files — zero crop and
       it keeps the hero compact (the previous 4/5 made the figure 25%
       taller than wide and dragged the whole section vertical). */
    aspect-ratio: 1 / 1;
    max-block-size: 30rem;
    margin-inline: auto;
    inline-size: 100%;
    max-inline-size: 30rem;
    background-color: var(--color-bg-elev);
    /* Burgundy frame — the maison's seal around the lantern. */
    border: 2px solid color-mix(in srgb, var(--color-red) 55%, transparent);
    /* Cinematic stacked shadow. Order matters: theme-aware tokens first,
       then a deep ambient drop for "floating in a dark room", a crisp
       inner highlight that gives the frame a picture-bevel feel, and a
       faint outer separator so the frame reads against the burgundy
       page wash. */
    box-shadow:
      var(--shadow-lifted),
      var(--shadow-glow-soft),
      0 36px 70px -20px var(--color-shade-strong),
      inset 0 0 0 1px color-mix(in srgb, white 14%, transparent),
      0 0 0 1px var(--color-shade-mid);
    /* Arch dome: wide curves on top, square radius at bottom */
    border-start-start-radius: 50% 38%;
    border-start-end-radius: 50% 38%;
    border-end-start-radius: var(--radius-xl);
    border-end-end-radius: var(--radius-xl);
  }
  /* Looping candle-flame footage fills the figure in BOTH themes — the
     hero is the maison's atelier lantern. Sits behind the burgundy wash
     and the brand-logo image. Reduced-motion users get the poster still
     instead (rule lower in this file). */
  .hero__video {
    position: absolute;
    inset: 0;
    z-index: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    /* Slight knock-down so the flame doesn't overpower the logo glow.
       The burgundy wash on ::before adds further depth. */
    opacity: 0.92;
    pointer-events: none;
  }

  .hero__media::before {
    content: "";
    position: absolute;
    inset: 0;
    background:
      radial-gradient(ellipse 70% 55% at 50% 42%,
        color-mix(in srgb, var(--color-red) 32%, transparent) 0%,
        color-mix(in srgb, var(--color-red) 10%, transparent) 38%,
        transparent 72%);
    z-index: 1;
    pointer-events: none;
    /* Multiply tints the candle warmth toward the maison burgundy without
       washing the flame out — additive composite, not a flat overlay. */
    mix-blend-mode: multiply;
  }

  .hero__image {
    position: relative;
    z-index: 2;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    /* --dur-base mirrors the FADE_MS constant in hero-carousel.js so the
       CSS opacity transition completes in lock-step with the JS swap delay. */
    transition: opacity var(--dur-base) var(--ease-out);
  }

  /* Brand-logo mode — the carousel showcases each maison's monochrome
     logo. The source WebPs ship with a solid white field behind the
     mark; `invert(1)` flips it to black-on-white and `screen` then drops
     the black through to the candle backdrop beneath. Net effect: a
     luminous white mark glowing on the candle-lit dark stage, with the
     arched figure shape preserved (no rectangular halo). Identical in
     both themes — the candle video makes the figure dark either way. */
  .hero__image[data-mode="logo"] {
    object-fit: contain;
    padding: var(--space-7);
    filter: invert(1);
    mix-blend-mode: screen;
  }

  /* Reduced-motion: replace the autoplay loop with the static poster
     so users with vestibular sensitivities see a still flame, not a
     flickering one. The poster lands as a figure background; the
     video element is removed from layout so it never plays. */
  @media (prefers-reduced-motion: reduce) {
    .hero__bg, .hero__video { display: none; }
    .hero__media {
      background-image: url("/assets/video/candle-poster.webp");
      background-size: cover;
      background-position: center;
      background-repeat: no-repeat;
    }
    /* The hero frame's wine-gradient fallback already provides the
       maison's atmosphere when the bg video is suppressed — no extra
       poster swap needed at the section level. */
  }

  .hero__image.is-swapping { opacity: 0; }

  .hero__caption {
    text-align: center; margin-block-start: var(--space-5);
    color: var(--color-ink-soft);
    display: flex; flex-direction: column;
    gap: var(--space-1); align-items: center;
  }
  .hero__caption-name { font-family: var(--font-display); font-size: var(--fs-h4); color: var(--color-ink); }

  /* ─── Eyebrow: "Maison · {Brand}" --------------------- *
   * Uppercased, tracked, peach accent. Only the base
   * .hero__eyebrow shell ships today; the historic
   * label/name sub-spans were retired. */
  .hero__eyebrow {
    display: inline-flex; align-items: center;
    gap: var(--space-2);
    color: var(--color-ink-muted);
    margin-block-end: 0;
  }

  /* ─── Hero carousel controls — see .hero__maisons-rail ─── *
   * 2026-05-14: the bottom dot strip (.hero__controls / .hero__dots /
   * .hero__dot*) is retired. The 9-tile brand-logo rail
   * (.hero__maisons-rail) directly below is the official tablist —
   * active-tile claim and the 5 s progress bar live in the rail
   * block below (.hero__maisons-rail .maison-tile…). */

  /* ─── Hero pause control (WCAG 2.2.2) ───────────────── *
   * The carousel already auto-pauses on hover, focus, document-hidden
   * and prefers-reduced-motion — visible chrome is therefore not the
   * primary surface. Per the brief, the button is kept in the DOM
   * (for screen-reader users and as a programmable affordance) but
   * visually hidden by default. Keyboard users discover it on Tab:
   * :focus-visible re-introduces the cream pill exactly where it was
   * declared, so the control is reachable without inspecting source. */
  .hero__pause {
    position: absolute;
    inset-block-end: var(--space-5);
    inset-inline-end: var(--space-5);
    z-index: 3;
    inline-size: 2.75rem;
    block-size: 2.75rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-pill);
    border: 1px solid var(--color-cream);
    background-color: color-mix(in srgb, var(--color-bg) 60%, transparent);
    color: var(--color-cream);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    /* Visually hidden, layout slot preserved so focus-visible can
       fade the button back in without triggering a reflow. */
    opacity: 0;
    pointer-events: none;
    transition: opacity          var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) var(--ease-out),
                transform        var(--dur-fast) var(--ease-out);
  }
  .hero__pause:focus-visible {
    opacity: 1;
    pointer-events: auto;
    outline: 2px solid var(--color-cream);
    outline-offset: 3px;
  }
  @media (hover: hover) {
    .hero__pause:focus-visible:hover {
      background-color: color-mix(in srgb, var(--color-cream) 18%, transparent);
      transform: scale(1.05);
    }
  }
  .hero__pause-icon--play  { display: none; }
  .hero__pause[aria-pressed="true"] .hero__pause-icon--play  { display: inline; }
  .hero__pause[aria-pressed="true"] .hero__pause-icon--pause { display: none; }

  /* ---- Brand-logo rail inside the hero frame ----
   * The 9-house maisons-rail used to live inside §6 Collections under
   * a "Aperçu — Nos neuf maisons" header. Moved here 2026-05-14 so the
   * brand strip sits at the foot of the hero, immediately after the
   * carousel dots — readers see the full maison roster before the
   * first scroll. Uses the canonical brand logos
   * (/assets/images/Brand-logo/<Brand>.webp) rather than product
   * photos, with the same invert-and-screen treatment the hero
   * .hero__image[data-mode="logo"] uses so the dark logo glyphs flip
   * to luminous white-on-dark glow against the bubbles bg video. */
  .hero__maisons-rail {
    position: relative;
    z-index: 2;
    margin-block: var(--space-7) 0;
    padding-inline: var(--gutter);
    padding-block-start: var(--space-5);
  }
  .hero__maisons-rail .maisons-rail__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
  }
  @media (min-width: 40em) {
    .hero__maisons-rail .maisons-rail__list { grid-template-columns: repeat(5, 1fr); }
  }
  @media (min-width: 64em) {
    .hero__maisons-rail .maisons-rail__list { grid-template-columns: repeat(9, 1fr); }
  }
  /* Tile · transparent ground, contain-fit logo with breathing padding,
     subtle hairline. Hover lifts and intensifies the logo luminance. */
  .hero__maisons-rail .maison-tile {
    position: relative;            /* contains the progress-bar ::after */
    /* Force the tile to fill its grid track. Chromium gives <button>
       shrink-to-fit sizing even at display: block — without inline-size
       the tile collapses to ~2 px and aspect-ratio resolves to 2×2. */
    display: block;
    inline-size: 100%;
    aspect-ratio: 1 / 1;
    /* Reset UA <button> styling — padding, font, line-height all flow
       to the inner image / label. */
    padding: 0;
    margin: 0;
    font: inherit;
    color: inherit;
    line-height: 1;
    background-color: transparent;
    border: 1px solid color-mix(in srgb, var(--color-cream) 10%, transparent);
    border-radius: var(--radius-md);
    overflow: hidden;
    cursor: pointer;
    transition:
      transform var(--dur-fast) var(--ease-out),
      border-color var(--dur-fast) var(--ease-out),
      background-color var(--dur-fast) var(--ease-out),
      box-shadow var(--dur-fast) var(--ease-out);
  }
  .hero__maisons-rail .maison-tile:hover,
  .hero__maisons-rail .maison-tile:focus-visible {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--color-red) 50%, transparent);
    background-color: color-mix(in srgb, var(--color-red) 6%, transparent);
  }
  .hero__maisons-rail .maison-tile__image {
    inline-size: 100%;
    block-size: 100%;
    object-fit: contain;
    padding: var(--space-3);
    /* Same trick the hero logo uses: invert the dark logo glyphs,
       then screen-blend so the inverted black drops through to the
       backdrop and the mark reads as a luminous white glyph on the
       wine ground. */
    filter: invert(1);
    mix-blend-mode: screen;
    transition: opacity var(--dur-fast) var(--ease-out);
  }
  @media (hover: hover) {
    .hero__maisons-rail .maison-tile:hover .maison-tile__image { 
    transform: none;
   }
  }
  /* Hide the printed brand name — the logo glyph already carries it.
     Kept in the DOM for screen-reader parity with the aria-label. */
  .hero__maisons-rail .maison-tile__name {
    position: absolute;
    inline-size: 1px;
    block-size: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }

  /* ─── Active tile — the maison currently on stage ───── *
   * The tile flagged aria-selected="true" is the carousel's
   * current slide. A red border + faint red wash + outer
   * red halo claim it as the chosen maison; the logo's screen
   * blend is preserved so the glyph still reads as luminous
   * white-on-dark inside the lit cell. */
  .hero__maisons-rail .maison-tile[aria-selected="true"] {
    border-color: color-mix(in srgb, var(--color-red) 72%, transparent);
    background-color: color-mix(in srgb, var(--color-red) 10%, transparent);
    box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-red) 40%, transparent),
                0 12px 28px -10px color-mix(in srgb, var(--color-red) 35%, transparent);
  }

  /* ─── Progress bar — the carousel's clock ──────────── *
   * Bottom-anchored 3 px fill bar inside the active tile.
   * The 5 s linear animation is the advance trigger:
   * hero-carousel.js listens for `animationend` and renders
   * the next maison. Pause is mediated by data-hero-paused on
   * the .hero host (WCAG 2.2.2 — hover/focus/document-hidden
   * freeze both the bar AND the advance, single source of
   * timing).
   *
   * Duration here MUST match SLIDE_MS in hero-carousel.js. */
  .hero__maisons-rail .maison-tile--running::after {
    content: "";
    position: absolute;
    inset-inline: 0;
    inset-block-end: 0;
    block-size: 3px;
    background-color: var(--color-red);
    transform-origin: 0 50%;
    transform: scaleX(0);
    pointer-events: none;
    animation: maison-tile-fill 5s linear forwards;
  }
  .hero[data-hero-paused="true"] .hero__maisons-rail .maison-tile--running::after {
    animation-play-state: paused;
  }
  @keyframes maison-tile-fill {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
  }
  @media (prefers-reduced-motion: reduce) {
    .hero__maisons-rail .maison-tile { transition: none; }
    /* Without animationend, the carousel does not auto-advance:
       readers with reduced-motion navigate maisons by click only. */
    .hero__maisons-rail .maison-tile--running::after { display: none; }
  }

  /* V3: drop uppercase on section openers across the home page so the
     Fraunces 600 voice reads as editorial, not as transactional.
     Targets the .section__heading inside the home main sections. */
  [data-page="home"] main .section__heading {
    text-transform: none;
    letter-spacing: var(--tracking-display);
  }
  [data-page="home"] main .section__heading--centered { text-align: center; }

  /* ============ Experience (§5) — editorial commitment ============ *
   * Dark wine wash between the §3.C Spotlight Elles cream interlude
   * and the rest of the journey. Two columns at desktop:
   *   · LEFT  · cinematic wine-bordered hero portrait (cristal-oud)
   *   · RIGHT · editorial header + three numbered commitments
   *
   * Numerals 01/02/03 in champagne display serif replace the prior
   * sprout/beaker/leaf icons — a tonally restrained pattern that
   * matches the maison-of-counsel voice. Hairline rules between
   * commitments give the list an editorial column-of-text rhythm.
   * Two decorative red SVG curves anchor the corners, echoing the
   * elles/eux spotlight decoration but in red on dark rather than
   * rose on cream.
   * ================================================== */
  /* Boxed treatment — the section is pulled inward from the viewport
     edges so the wine wash reads as a framed editorial card rather
     than a full-bleed band. margin-inline holds the gutter on both
     sides, border-radius rounds the corners, and margin-block keeps
     air between the box and the sibling sections above/below. */
  .experience {
    position: relative;
    padding-block: var(--space-9);
  }
  .experience__container {
    position: relative;
    z-index: 1;
  }

  /* Decorative curves — burgundy on the dark theatre. Same SVG shapes
     the elles/eux spotlights use; only the tint flips from rose-on-
     cream to red-on-dark. */
  .experience__curve {
    position: absolute;
    inline-size: 12rem;
    block-size: 12rem;
    color: color-mix(in srgb, var(--color-red) 32%, transparent);
    pointer-events: none;
    z-index: 0;
  }
  .experience__curve svg {
    inline-size: 100%;
    block-size: 100%;
    display: block;
  }
  .experience__curve--start {
    inset-block-start: calc(var(--space-9) * -0.4);
    inset-inline-start: calc(var(--gutter) * -0.6);
  }
  .experience__curve--end {
    inset-block-end: calc(var(--space-9) * -0.4);
    inset-inline-end: calc(var(--gutter) * -0.6);
  }
  @media (min-width: 48em) {
    .experience__curve { inline-size: 16rem; block-size: 16rem; }
  }
  @media (min-width: 64em) {
    .experience__curve { inline-size: 22rem; block-size: 22rem; }
  }

  /* 2-column grid · image left, content right at desktop. The 5/7
     asymmetric split gives the hero portrait a strong vertical claim
     while leaving the commitment list with the wider reading column. */
  .experience__grid {
    display: grid;
    gap: var(--space-8);
    grid-template-columns: 1fr;
    align-items: start;
  }
  @media (min-width: 64em) {
    .experience__grid {
      grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
      gap: var(--space-9);
      align-items: center;
    }
  }

  /* Hero portrait · same cinematic frame the elles/eux product cards
     use: 2 px red border + multi-layer wine shadow. The image always
     reads as a stage portrait, not a thumbnail. */
  .experience__media {
    position: relative;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border-radius: var(--radius-xl);
    border: 2px solid color-mix(in srgb, var(--color-red) 55%, transparent);
    background-color: var(--color-bg-elev);
    box-shadow:
      0 24px 48px -12px var(--color-shade-strong),
      0 0 60px color-mix(in srgb, var(--color-red) 18%, transparent),
      inset 0 0 0 1px var(--color-highlight-soft),
      0 0 0 1px var(--color-shade-mid);
  }
  .experience__image {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    object-position: center;
  }

  /* Content column · header + commitments stack with breathing room. */
  .experience__content {
    display: flex;
    flex-direction: column;
    gap: var(--space-7);
  }
  .experience__header {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
  }
  .experience__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(2rem, 1.3rem + 3.3vw, 4rem);
    font-weight: 600;
    line-height: 1.06;
    letter-spacing: var(--tracking-display);
    color: var(--color-ink);
    text-wrap: balance;
  }
  /* Lede paragraph · paired with the manifesto intro voice for cross-section
     consistency. Same bridge (Cormorant) family, no italic, full --color-ink
     (not muted). Size/measure stays scoped to this section's editorial
     rhythm — the user asked for fonts + colors to match, not sizing. */
  .experience__lede {
    margin: 0;
    font-family: var(--font-bridge);
    font-size: var(--fs-body-lead);
    line-height: var(--lh-body-lead);
    color: var(--color-ink);
    max-inline-size: 52ch;
  }

  /* Numbered commitments · editorial column list. Each item carries
     a champagne display numeral and a body block; a thin top hairline
     separates items (the first item has none). */
  .experience__commitments {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-6);
  }
  .experience__commitment {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--space-5);
    align-items: start;
    padding-block-start: var(--space-6);
    border-block-start: 1px solid var(--color-line-cream);
  }
  .experience__commitment:first-child {
    padding-block-start: 0;
    border-block-start: 0;
  }
  .experience__commitment-number {
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 1.5rem + 2.4vw, 3.5rem);
    font-weight: 400;
    line-height: 1;
    color: var(--color-accent-champagne);
    letter-spacing: var(--tracking-display);
    /* Subtle align the optical baseline of the digits with the title
       below them — display digits tend to sit a hair high, this nudge
       brings them down so the row reads as one editorial line. */
    transform: translateY(0.1em);
  }
  .experience__commitment-body {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
  }
  .experience__commitment-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: var(--fs-h3);
    font-weight: 600;
    line-height: var(--lh-tight);
    color: var(--color-ink);
    text-wrap: balance;
  }
  /* Commitment copy · adopts the manifesto intro voice (bridge family,
     full --color-ink) so the editorial register stays consistent across
     the about / experience / manifesto sections. Body-size scale retained
     because these are item descriptions, not lead paragraphs. */
  .experience__commitment-copy {
    margin: 0;
    font-family: var(--font-bridge);
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    color: var(--color-ink);
    /* Pinned to exactly 111 characters per item — column widened to
       58 ch so all three strings break to TWO lines on the desktop
       grid (55–56 chars per line after balance). text-wrap: balance
       keeps the two lines visually even rather than orphaning the
       trailing run. */
    max-inline-size: 58ch;
    text-wrap: balance;
  }

  /* ============ Collections (§6) — V11 portals rebuild ============ *
   * Three large portal cards (Homme · Femme · Mixtes & Coffrets) +
   * a nine-tile maisons aperçu rail. Replaces the V3 .mosaic 10-tile
   * bento + the .collection-card typographic plates. The portals
   * are the primary CTAs (each is the entry to one collection); the
   * rail is supporting discovery for the 9 maisons.
   *
   * Class map:
   *   .collections__portals       3-col grid host (1-col mobile)
   *   .portal-card                each portal — relative, aspect 4/5
   *     .portal-card__media       full-bleed image layer (z 0)
   *     .portal-card__overlay     gradient + display label (z 1)
   *     .portal-card__display     italic display name ("Homme")
   *     .portal-card__footer      pinned bottom info bar (z 2)
   *       .portal-card__title     eyebrow-style label
   *       .portal-card__count     champagne supporting text
   *       .portal-card__arrow     circular CTA pill
   *   .maisons-rail               supporting strip below the portals
   *     .maisons-rail__header     eyebrow + "see all" CTA
   *     .maisons-rail__list       9 tiles · 3-col mobile → 9-col desk
   *   .maison-tile                square house tile
   *     .maison-tile__image       full-bleed product photo
   *     .maison-tile__name        bottom-pinned name strip
   */

  /* ---- Surface lift (matches .elles / .eux spotlight rhythm) -----
   * Replaces the weak data-surface="wine" tone with the same vivid
   * burgundy ground used by .elles, plus rounded corners + decorative
   * SVG curves so the section reads as a peer of the spotlight rows
   * instead of slipping into surrounding flow. */
  .collections {
    position: relative;
    overflow: hidden;
    background-color: color-mix(in srgb, var(--color-red) 32%, transparent);
    padding: var(--space-5);
    border-radius: 5ch;
    margin: var(--space-5);
    border: 5px solid var(--color-cream);
  }
  .collections__container {
    position: relative;
    z-index: 1;
  }
  .collections__curve {
    position: absolute;
    inline-size: 12rem;
    block-size: 12rem;
    color: color-mix(in srgb, var(--color-decor-coral) 42%, transparent);
    pointer-events: none;
    z-index: 0;
  }
  .collections__curve svg {
    inline-size: 100%;
    block-size: 100%;
    display: block;
  }
  .collections__curve--start {
    inset-block-start: calc(var(--space-9) * -0.4);
    inset-inline-start: calc(var(--gutter) * -0.6);
  }
  .collections__curve--end {
    inset-block-end: calc(var(--space-9) * -0.4);
    inset-inline-end: calc(var(--gutter) * -0.6);
  }
  @media (min-width: 48em) {
    .collections__curve { inline-size: 16rem; block-size: 16rem; }
  }
  @media (min-width: 64em) {
    .collections__curve { inline-size: 20rem; block-size: 20rem; }
  }

  /* Header inks recoloured for the burgundy ground — pinned to literal
     cream tones because the surface is wine in BOTH themes (matches
     the .elles approach). */
  .collections__header .eyebrow,
  .collections__header .section__sub {
    /* var(--color-cream) resolves to the warm cream on dark and the
       soft white on light; both read at AAA on the burgundy ground.
       (The h2 is now .collections__title and inherits cream via the
       shared spotlight-title color rule below.) */
    color: var(--color-cream);
  }
  .collections__header .eyebrow {
    color: color-mix(in srgb, var(--color-cream) 72%, transparent);
  }
  .collections__header .section__sub {
    color: color-mix(in srgb, var(--color-cream) 78%, transparent);
  }
  .collections__header .eyebrow--editorial::before {
    background-color: var(--color-accent-amber);
  }

  /* ---- Portal cards (3 or 4 — see modifier) ----- *
   * Default: 1 col mobile → 3 cols at 48em (legacy layout).
   * .collections__portals--four: 1 col mobile → 2x2 at 40em → 4 cols
   * at 80em. The 4-card variant matches the visual weight of the
   * neighbouring §4 selection / §8 bestsellers carousels by giving
   * each card a slightly slimmer aspect on wide viewports so the
   * row feels deliberate, not crammed. */
  .collections__portals {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--grid-gap);
    margin-block-start: var(--space-7);
  }
  @media (min-width: 48em) {
    .collections__portals { grid-template-columns: repeat(3, 1fr); }
  }

  .collections__portals--four {
    grid-template-columns: 1fr;
  }
  @media (min-width: 40em) {
    .collections__portals--four { grid-template-columns: repeat(2, 1fr); }
  }
  @media (min-width: 80em) {
    .collections__portals--four { grid-template-columns: repeat(4, 1fr); }
  }
  /* On the 4-up layout the cards taper a touch taller so titles read
     well at narrower widths. Matches Aesop / Loro Piana grid rhythm. */
  @media (min-width: 80em) {
    .collections__portals--four .portal-card { aspect-ratio: 3 / 4; }
  }

  .portal-card {
    position: relative;
    display: block;
    aspect-ratio: 4 / 5;
    overflow: hidden;
    border-radius: var(--radius-xl);
    isolation: isolate;
    text-decoration: none;
    background-color: var(--color-bg-elev);
    box-shadow: var(--shadow-card);
    transition:
      transform var(--dur-base) var(--ease-out),
      box-shadow var(--dur-base) var(--ease-out);
  }
  @media (hover: hover) {
    .portal-card:hover { 
    transform: translateY(-4px);
    box-shadow: var(--shadow-lifted), var(--shadow-glow-soft);
   }
  }

  .portal-card__media {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
  }
  .portal-card__media img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform var(--dur-slow) var(--ease-out);
  }
  @media (hover: hover) {
    .portal-card:hover .portal-card__media img {  transform: scale(1.04);  }
  }

  .portal-card__overlay {
    position: absolute;
    inset: 0;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--space-7) var(--space-5) calc(var(--space-9) + var(--space-5));
    background:
      linear-gradient(to top,
        color-mix(in srgb, var(--color-glass-ink) 95%, transparent) 0%,
        color-mix(in srgb, var(--color-glass-ink) 55%, transparent) 35%,
        color-mix(in srgb, var(--color-glass-ink) 10%, transparent) 75%,
        color-mix(in srgb, var(--color-glass-ink)  0%, transparent) 100%);
  }
  .portal-card__display {
    font-family: var(--font-display);
    font-style: italic;
    font-weight: 400;
    font-size: clamp(2.5rem, 1.6rem + 4.5vw, 5rem);
    line-height: var(--lh-tight);
    letter-spacing: var(--tracking-display);
    color: var(--color-cream);
    text-align: center;
    text-wrap: balance;
    text-shadow: 0 2px 12px color-mix(in srgb, var(--color-glass-ink) 55%, transparent);
  }

  .portal-card__footer {
    position: absolute;
    inset-block-end: 0;
    inset-inline: 0;
    z-index: 2;
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-5) var(--space-6);
  }
  .portal-card__title {
    display: block;
    font-family: var(--font-body);
    font-size: var(--fs-eyebrow);
    font-weight: 500;
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    color: var(--color-cream);
    line-height: var(--lh-tight);
  }
  .portal-card__count {
    display: block;
    margin-block-start: var(--space-1);
    font-family: var(--font-body);
    font-size: var(--fs-small);
    color: var(--color-accent-champagne);
  }
  .portal-card__arrow {
    inline-size: 2.5rem;
    block-size: 2.5rem;
    border-radius: var(--radius-pill);
    background-color: var(--color-cream);
    color: var(--color-cta-soft-ink);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition:
      background-color var(--dur-fast) var(--ease-out),
      color var(--dur-fast) var(--ease-out),
      transform var(--dur-fast) var(--ease-out);
  }
  @media (hover: hover) {
    .portal-card:hover .portal-card__arrow { 
    background-color: var(--color-red);
    color: var(--color-cta-ink);
    transform: rotate(-6deg);
   }
  }

  /* ---- Maisons aperçu rail ---------------------- */
  .maisons-rail__list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-3);
  }
  @media (min-width: 40em) {
    .maisons-rail__list { grid-template-columns: repeat(5, 1fr); }
  }
  @media (min-width: 64em) {
    .maisons-rail__list { grid-template-columns: repeat(9, 1fr); }
  }

  .maison-tile {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    border-radius: var(--radius-lg);
    background-color: var(--color-bg-elev);
    text-decoration: none;
    transition: transform var(--dur-base) var(--ease-out);
  }
  @media (hover: hover) {
    .maison-tile:hover {  transform: translateY(-2px);  }
  }
  .maison-tile__image {
    position: absolute;
    inset: 0;
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    transition: transform var(--dur-slow) var(--ease-out);
  }
  @media (hover: hover) {
    .maison-tile:hover .maison-tile__image {  transform: scale(1.06);  }
  }
  .maison-tile__name {
    position: absolute;
    inset-block-end: 0;
    inset-inline: 0;
    padding: var(--space-2);
    background:
      linear-gradient(to top,
        color-mix(in srgb, var(--color-glass-ink) 92%, transparent) 0%,
        color-mix(in srgb, var(--color-glass-ink) 40%, transparent) 70%,
        color-mix(in srgb, var(--color-glass-ink)  0%, transparent) 100%);
    color: var(--color-cream);
    font-family: var(--font-body);
    font-size: var(--fs-eyebrow);
    font-weight: 500;
    letter-spacing: var(--tracking-eyebrow);
    text-transform: uppercase;
    text-align: center;
  }

  /* ============ Essence (§7) — Olfactory pyramid finder ============ *
   * Editorial spread: a triangle pyramid frames a flacon on the left,
   * three note callouts (top / heart / base) anchored to the apex,
   * midpoint and base of the triangle. On the right, a staircase
   * uppercase title and a 4-facet form that submits straight to the
   * boutique pre-filtered. A diagonal pink brushstroke sweeps behind
   * everything for editorial mood — the only piece of pink-on-cream
   * surface in the home composition. Surface stays cream (page bg)
   * so we use literal hex pinks for theme stability — the brushstroke
   * and CTA must read identically in dark and light themes.           */

  /* Surface + brushstroke ------------------------------------------ */
  /* Section ground + brushstroke both flow from theme-aware tokens
     (--gradient-essence-wash, --color-brushstroke) defined in
     tokens.css. The dark default lives in :root; the light override
     lives in [data-theme="light"], so no per-theme rule is needed
     here — the cascade does the right thing. */
  .essence {
    position: relative;
    overflow: hidden;
    isolation: isolate;
    background: var(--gradient-essence-wash);
  }
  .essence__brushstroke {
    position: absolute;
    inset: -10% -5%;
    color: var(--color-brushstroke);
    z-index: 0;
    pointer-events: none;
    transform: rotate(-12deg);
  }
  .essence__brushstroke svg {
    inline-size: 100%; block-size: 100%;
    display: block;
  }

  .essence > .container {
    position: relative;
    z-index: 1;
  }

  .essence__grid {
    display: grid; grid-template-columns: 1fr;
    gap: var(--space-8);
    align-items: center;
  }
  @media (min-width: 64em) {
    .essence__grid {
      grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
      gap: clamp(var(--space-7), 4vw, var(--space-9));
    }
  }

  /* LEFT · pyramid diagram ----------------------------------------
     The container is a 1:1 square. The SVG (viewBox 0 0 100 100)
     fills it edge-to-edge so percentages on labels match SVG coords
     exactly. Triangle sits in the middle of the square (apex 50,10
     → base 25,90 / 75,90). Bottle is centered horizontally and
     anchored low so it reads as "inside" the lower triangle.
     Labels are positioned at the same Y% as the connector endpoints
     and vertically centered with translateY(-50%), so they always
     line up regardless of how many lines the description wraps to.   */
  .essence__pyramid {
    position: relative;
    aspect-ratio: 1 / 1;
    inline-size: 100%;
    max-inline-size: 38rem;
    margin-inline: auto;
    color: rgba(127, 29, 33, 0.55);     /* triangle + connector stroke — Persian Red red-900 */
  }
  [data-theme="dark"] .essence__pyramid,
  :root:not([data-theme="light"]) .essence__pyramid {
    color: rgba(245, 233, 220, 0.45);
  }
  .essence__pyramid-frame {
    position: absolute; inset: 0;
    inline-size: 100%; block-size: 100%;
    display: block;
    z-index: 1;
  }
  /* Bottle is the centerpiece — sized large (44% of container width,
     up from the 26% that read as too small). Anchored low so the
     bottle silhouette fills the lower triangle, while the bottle
     frame's transparent margins extend slightly beyond the triangle
     outline at the top — visually fine because object-fit:contain
     keeps the perfume shape inside the triangle, and the frame's
     empty pixels don't obscure the triangle stroke.                 */
  .essence__pyramid-bottle {
    position: absolute;
    inset-block-end: 8%;
    inset-inline-start: 50%;
    transform: translateX(-50%);
    inline-size: 44%;
    block-size: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
    z-index: 2;
    filter: drop-shadow(0 24px 32px rgba(127, 29, 33, 0.25));
  }

  /* Three note callouts. Width is 23% of the pyramid container.
     Each label sits flush against the gutter edge (left or right)
     and vertically centers on its connector endpoint via translateY,
     so the label moves with description-line wrapping but always
     hugs the line of the connector visually. The connector line
     ends just OUTSIDE each label box so it never crosses through
     the title or description text.                                  */
  .essence__note {
    position: absolute;
    inline-size: 23%;
    color: var(--color-ink);
    font-family: var(--font-body);
    z-index: 3;          /* over the connector line for clean overlap */
  }
  .essence__note-title {
    margin: 0 0 0.3rem;
    font-family: var(--font-display);
    font-size: clamp(0.95rem, 0.85rem + 0.4vw, 1.15rem);
    font-weight: 500;
    letter-spacing: 0.01em;
    color: var(--color-ink);
    line-height: 1.15;
  }
  .essence__note-desc {
    margin: 0;
    font-size: clamp(0.7rem, 0.62rem + 0.3vw, 0.82rem);
    line-height: 1.45;
    color: var(--color-ink-muted);
  }
  /* Connector endpoints in viewBox: top (24, 22), heart (74, 40),
     base (24, 83). Labels align to those Y%s — heart pulled up to
     42% to track the heart connector that had to move above the
     larger bottle. Top stays at 25%, base stays at 85%.            */
  .essence__note--top {
    inset-block-start: 25%;
    inset-inline-start: 0;
    text-align: end;
    transform: translateY(-50%);
  }
  .essence__note--heart {
    inset-block-start: 42%;
    inset-inline-end: 0;
    text-align: start;
    transform: translateY(-50%);
  }
  .essence__note--base {
    inset-block-start: 85%;
    inset-inline-start: 0;
    text-align: end;
    transform: translateY(-50%);
  }

  /* On narrow viewports the side gutters are too tight (24% of a
     320px container = 77px — not enough for the description text).
     Stack vertically: pyramid (with just the triangle + bottle) on
     top, notes underneath as a 3-row caption.                       */
  @media (max-width: 47.99em) {
    .essence__pyramid {
      aspect-ratio: auto;
      max-inline-size: none;
      display: grid;
      grid-template-columns: minmax(0, 18rem) minmax(0, 1fr);
      grid-template-areas:
        "stage top"
        "stage heart"
        "stage base";
      gap: var(--space-4) var(--space-5);
      align-items: center;
    }
    .essence__pyramid-frame,
    .essence__pyramid-bottle {
      grid-area: stage;
      position: relative;
      inset: auto;
      transform: none;
    }
    .essence__pyramid-frame {
      aspect-ratio: 1 / 1;
      inline-size: 100%;
      block-size: auto;
    }
    .essence__pyramid-bottle {
      grid-area: stage;
      position: absolute;
      inset-block-end: 14%;
      inset-inline-start: 50%;
      transform: translateX(-50%);
      inline-size: 26%;
    }
    .essence__note {
      position: static;
      inline-size: auto;
      text-align: start !important;
      transform: none !important;
      max-inline-size: none;
    }
    .essence__note--top    { grid-area: top; }
    .essence__note--heart  { grid-area: heart; }
    .essence__note--base   { grid-area: base; }
  }
  @media (max-width: 32em) {
    .essence__pyramid {
      grid-template-columns: 1fr;
      grid-template-areas:
        "stage"
        "top"
        "heart"
        "base";
      max-inline-size: 22rem;
      margin-inline: auto;
    }
    .essence__pyramid-frame { aspect-ratio: 1 / 1; }
  }

  /* RIGHT · staircase title + facet form -------------------------- */
  .essence__copy {
    display: flex; flex-direction: column;
    gap: clamp(var(--space-5), 3vw, var(--space-7));
    align-items: stretch;
  }
  .essence__title {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 400;
    font-size: clamp(2.25rem, 1.4rem + 4vw, 4.75rem);
    line-height: 1.02;
    letter-spacing: -0.01em;
    text-transform: uppercase;
    color: var(--color-ink);
    text-wrap: balance;
  }
  .essence__title-line {
    display: block;
  }
  .essence__title-line--shift   { padding-inline-start: 1.5ch; }
  .essence__title-line--shift-2 { padding-inline-start: 3ch; }

  /* The facet form — 4 pill-shaped selects in a 2×2 grid on desktop,
     stacked on mobile, then a single big CTA pill spanning underneath. */
  .essence__form {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-3);
    margin: 0;
  }
  @media (min-width: 30em) {
    .essence__form { grid-template-columns: 1fr 1fr; }
  }
  .essence__select-wrap {
    position: relative;
    display: block;
  }
  .essence__select {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    inline-size: 100%;
    padding: 1rem 3rem 1rem 1.4rem;
    font-family: var(--font-body);
    font-size: 0.9rem;
    font-weight: 500;
    letter-spacing: 0.02em;
    color: var(--color-ink);
    background: rgba(255, 248, 248, 0.55);            /* red-tinted, never harsh white */
    border: 1px solid rgba(127, 29, 33, 0.22);         /* red-900 hairline */
    border-radius: 999px;
    cursor: pointer;
    transition: border-color 0.18s ease, background-color 0.18s ease, box-shadow 0.18s ease;
  }
  [data-theme="dark"] .essence__select,
  :root:not([data-theme="light"]) .essence__select {
    background: color-mix(in srgb, var(--color-bg-elev) 45%, transparent);
    border-color: color-mix(in srgb, var(--color-ink) 18%, transparent);
  }
  @media (hover: hover) {
    .essence__select:hover {
    border-color: rgba(127, 29, 33, 0.45);
    background: rgba(254, 242, 242, 0.78);             /* red-50 wash on hover */
   }
  }
  @media (hover: hover) {
    [data-theme="dark"] .essence__select:hover,
    :root:not([data-theme="light"]) .essence__select:hover {
      border-color: color-mix(in srgb, var(--color-ink) 32%, transparent);
      background: color-mix(in srgb, var(--color-bg-elev) 65%, transparent);
    }
  }
  .essence__select:focus-visible {
    /* Outline preserved alongside the box-shadow ring so Windows
       High-Contrast Mode (which ignores box-shadow) still surfaces focus. */
    outline: 2px solid var(--color-red);
    outline-offset: 2px;
    border-color: rgba(127, 29, 33, 0.7);              /* red-900 strong border */
    box-shadow: 0 0 0 3px rgba(185, 28, 34, 0.18);     /* red-700 halo, slightly brighter than border for ring readability */
  }
  [data-theme="dark"] .essence__select:focus-visible,
  :root:not([data-theme="light"]) .essence__select:focus-visible {
    border-color: color-mix(in srgb, var(--color-ink) 55%, transparent);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-ink) 18%, transparent);
  }
  .essence__select-chevron {
    position: absolute;
    inset-block-start: 50%;
    inset-inline-end: 1.25rem;
    transform: translateY(-50%);
    inline-size: 1rem; block-size: 1rem;
    color: var(--color-ink);
    pointer-events: none;
  }

  .essence__submit {
    grid-column: 1 / -1;
    justify-self: end;
    appearance: none;
    border: 0;
    cursor: pointer;
    margin-block-start: var(--space-2);
    padding: 1.05rem 2.4rem;
    font-family: var(--font-body);
    font-size: 0.92rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--color-cream);
    background: linear-gradient(135deg, var(--color-submit-coral-start) 0%, var(--color-submit-coral-end) 100%);
    border-radius: 999px;
    box-shadow:
      0 18px 36px -12px color-mix(in srgb, var(--color-submit-coral-end) 55%, transparent),
      inset 0 1px 0 color-mix(in srgb, white 18%, transparent);
    transition: transform 0.18s ease, box-shadow 0.18s ease, filter 0.18s ease;
  }
  @media (hover: hover) {
    .essence__submit:hover {
    transform: translateY(-2px);
    box-shadow:
      0 24px 44px -14px color-mix(in srgb, var(--color-submit-coral-end) 65%, transparent),
      inset 0 1px 0 var(--color-highlight-mid);
    filter: brightness(1.05);
   }
  }
  .essence__submit:focus-visible {
    /* Outline preserved for forced-colors mode; the box-shadow remains
       as the visual ring on standard displays. */
    outline: 2px solid var(--color-cream);
    outline-offset: 3px;
    box-shadow:
      0 0 0 3px color-mix(in srgb, var(--color-submit-coral-end) 35%, transparent),
      0 18px 36px -12px color-mix(in srgb, var(--color-submit-coral-end) 55%, transparent);
  }
  .essence__submit:active {
    transform: translateY(0);
  }
  @media (max-width: 29.99em) {
    .essence__submit { justify-self: stretch; }
  }
  @media (prefers-reduced-motion: reduce) {
    .essence__submit { transition: none; }
    @media (hover: hover) {
      .essence__submit:hover {  transform: none;  }
    }
  }

  /* ============ Signature (§9) ============ *
   * V3: image-dominant asymmetric. Copy column drops to 1fr, image
   * column lifts to 1.6fr — the inverse of essence. Essence + signature
   * are no longer mirror twins; together they alternate the home page's
   * editorial rhythm (copy-led narrative → image-led manifesto). */
  .signature__grid {
    display: grid; grid-template-columns: 1fr;
    gap: var(--space-7); align-items: stretch;
  }
  @media (min-width: 64em) {
    .signature__grid { grid-template-columns: 1fr 1fr; gap: var(--space-8); }
  }
  /* justify-content: center vertically balances the eyebrow / h2 / lede
     stack inside the cell, which is now stretched to the image's square
     height at desktop (.signature__media has aspect-ratio: 1 / 1). */
  .signature__copy {
    display: flex; flex-direction: column;
    gap: var(--space-4);
    align-items: flex-start;
    justify-content: center;
  }
  /* ---- Framed image · 1:1 with corner brackets extending outside ----
   * The outer figure carries no overflow clipping so the four corner
   * marks can project beyond the image edge. The inner div clips the
   * photo to the rounded silhouette and holds the card shadow. */
  .signature__media {
    position: relative;
    aspect-ratio: 1 / 1;
    isolation: isolate;
    margin: 0;
  }
  .signature__media-inner {
    position: absolute;
    inset: 0;
    border-radius: var(--radius-xl);
    overflow: hidden;
    box-shadow: var(--shadow-card);
  }
  .signature__media-inner img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    display: block;
  }

  /* Decorative L-bracket corners (4×). Pulled outside the image bounds
     by negative inset so the framing reads as an "expanded" editorial
     frame. Border colour adapts per theme via --color-ink-muted. */
  .signature__corner {
    position: absolute;
    inline-size: clamp(1.25rem, 2.5vw, 2.5rem);
    block-size: clamp(1.25rem, 2.5vw, 2.5rem);
    border-color: var(--color-ink-muted);
    border-style: solid;
    border-width: 0;
    pointer-events: none;
    z-index: 1;
  }
  .signature__corner--tl {
    inset-block-start: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    inset-inline-start: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    border-block-start-width: 2px;
    border-inline-start-width: 2px;
  }
  .signature__corner--tr {
    inset-block-start: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    inset-inline-end: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    border-block-start-width: 2px;
    border-inline-end-width: 2px;
  }
  .signature__corner--bl {
    inset-block-end: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    inset-inline-start: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    border-block-end-width: 2px;
    border-inline-start-width: 2px;
  }
  .signature__corner--br {
    inset-block-end: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    inset-inline-end: calc(clamp(0.5rem, 1.4vw, 1.25rem) * -1);
    border-block-end-width: 2px;
    border-inline-end-width: 2px;
  }

  /* ---- Métier ticker · full-bleed marquee under the grid ----------
   * Pattern mirrors .testimonials-marquee: max-content track, edge
   * mask fade, translateX(0 → -50%) keyframe, animation-play-state
   * pause on hover/focus-within, reduced-motion disables the loop.
   * Lives outside .container so it spans the full viewport width. */
  .signature__rail {
    position: relative;
    margin-block-start: clamp(var(--space-7), 6vw, var(--space-9));
    inline-size: 100%;
    overflow: hidden;
    border-block: 1px solid var(--color-line);
    padding-block: clamp(var(--space-3), 1.6vw, var(--space-5));
    mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, black 6%, black 94%, transparent);
  }
  .signature__rail-track {
    display: flex;
    align-items: baseline;
    gap: clamp(var(--space-5), 5vw, var(--space-8));
    inline-size: max-content;
    will-change: transform;
    animation: signature-rail 38s linear infinite;
    margin: 0;
    padding: 0;
    list-style: none;
  }
  .signature__rail-item {
    flex: 0 0 auto;
    font-family: var(--font-display);
    font-size: clamp(1.5rem, 1rem + 2vw, 3.25rem);
    line-height: 1;
    color: var(--color-ink-muted);
    letter-spacing: 0.01em;
    white-space: nowrap;
  }
  .signature__rail-item::before {
    content: "·";
    display: inline-block;
    margin-inline-end: clamp(var(--space-5), 5vw, var(--space-8));
    color: var(--color-red);
    transform: translateY(-0.06em);
  }
  .signature__rail:hover .signature__rail-track,
  .signature__rail:focus-within .signature__rail-track {
    animation-play-state: paused;
  }
  @keyframes signature-rail {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
  }
  @media (prefers-reduced-motion: reduce) {
    .signature__rail-track {
      animation: none;
    }
  }
  /* V3 signature lede: matches the essence lede typography for
     consistency in the editorial body-lead voice. */
  .signature__lede {
    color: var(--color-ink-muted);
    font-family: var(--font-bridge);
    font-style: italic;
    font-size: var(--fs-body-lead);
    line-height: var(--lh-body-lead);
    max-inline-size: 50ch;
    margin: 0;
  }

  /* ---- Champagne hairline · editorial ornament between lede and stats ---- */
  .signature__rule {
    flex: none;
    inline-size: clamp(2.5rem, 4vw, 3.5rem);
    block-size: 1px;
    background-color: var(--color-accent-champagne);
    border: 0;
    margin: 0;
  }

  /* ---- Stats row · three large numerical accents over small-caps labels --
   * Visually echoes the lede phrasing ("quatre métiers sous un même toit").
   * Three columns are left-aligned to share the eyebrow / h2 / lede start
   * edge. Display serif numerals over an Inter small-caps label give the
   * Maison Margiela / Hermès editorial register without invoking prices. */
  .signature__stats {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    gap: clamp(var(--space-5), 4vw, var(--space-7));
    align-items: flex-start;
  }
  .signature__stat {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
  }
  .signature__stat-num {
    font-family: var(--font-display);
    font-size: var(--fs-badge-num);
    font-weight: 400;
    line-height: 1;
    letter-spacing: var(--tracking-display);
    color: var(--color-ink);
  }
  .signature__stat-label {
    font-family: var(--font-body);
    font-size: var(--fs-eyebrow);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-ink-muted);
  }

  /* ---- Secondary note · how Wadicos quotes -----------------------------
   * Sans-serif body voice rather than the lede's serif italic, so the two
   * paragraphs read as complementary registers (editorial narrative above,
   * operational fact below). Reinforces the maison's no-anonymous-cart
   * model without naming prices in the DOM. */
  .signature__note {
    margin: 0;
    font-family: var(--font-body);
    font-size: var(--fs-body);
    line-height: 1.55;
    color: var(--color-ink-muted);
    max-inline-size: 50ch;
  }

  /* ============ Testimonials (§10) — Editorial verbatim wall =====
   * Asymmetric grid: 1 featured card (5 cols × 2 rows) on the
   * top-left, 2 supporting cards stacked in the right column, then
   * 2 more spanning the bottom row. A faint giant quote-mark sits
   * in the section's top-right corner as an editorial watermark.
   * Surface stays vellum (data-surface attribute) — cards float on
   * top with cream backgrounds and a wine hairline border.
   * ================================================================ */
  .testimonials {
    position: relative;
    overflow: hidden;
    isolation: isolate;
  }
  .testimonials__watermark {
    position: absolute;
    inset-block-start: clamp(2rem, 6vw, 5rem);
    inset-inline-end: clamp(-2rem, -1vw, 1rem);
    inline-size: clamp(8rem, 22vw, 20rem);
    block-size: clamp(8rem, 22vw, 20rem);
    color: var(--color-ink);
    opacity: 0.05;
    pointer-events: none;
    z-index: 0;
  }
  .testimonials__watermark svg {
    inline-size: 100%; block-size: 100%;
    display: block;
  }
  .testimonials > .container {
    position: relative;
    z-index: 1;
  }

  .testimonials__header {
    margin-block-end: clamp(var(--space-6), 4vw, var(--space-8));
  }

  /* ---- Two-row marquee ----------------------------------------
   * Row 1 scrolls LEFT, row 2 scrolls RIGHT. Each row has its own
   * <ul class="testimonials-marquee__track"> with N unique cards
   * followed by an aria-hidden duplicate set. The keyframe moves
   * the track by -50% (row 1) or +50% (row 2), which is exactly
   * the width of the duplicate set — yielding a seamless infinite
   * loop. Edge masks fade the cards in/out at the section bounds.
   * ---------------------------------------------------------- */
  .testimonials-marquee {
    position: relative;
    margin-block-start: clamp(var(--space-5), 3vw, var(--space-7));
    inline-size: 100%;
    display: flex;
    flex-direction: column;
    gap: clamp(var(--space-3), 1.5vw, var(--space-4));
    /* Edge fade so cards slide in/out gracefully */
    mask-image: linear-gradient(to right, transparent, black 5%, black 95%, transparent);
    -webkit-mask-image: linear-gradient(to right, transparent, black 5%, black 95%, transparent);
  }
  .testimonials-marquee__row {
    overflow: hidden;
    inline-size: 100%;
  }
  .testimonials-marquee__track {
    list-style: none;
    margin: 0;
    padding-block: var(--space-2);
    padding-inline: 0;
    display: flex;
    gap: clamp(var(--space-3), 1.5vw, var(--space-5));
    inline-size: max-content;
    will-change: transform;
  }
  .testimonials-marquee__track > li {
    flex: 0 0 auto;
    inline-size: clamp(18rem, 26vw, 24rem);
    display: flex;
  }
  .testimonials-marquee__row--left .testimonials-marquee__track {
    animation: testimonials-marquee-left 55s linear infinite;
  }
  .testimonials-marquee__row--right .testimonials-marquee__track {
    animation: testimonials-marquee-right 65s linear infinite;
  }
  .testimonials-marquee:hover .testimonials-marquee__track,
  .testimonials-marquee:focus-within .testimonials-marquee__track {
    animation-play-state: paused;
  }
  @keyframes testimonials-marquee-left {
    from { transform: translateX(0); }
    to   { transform: translateX(-50%); }
  }
  @keyframes testimonials-marquee-right {
    from { transform: translateX(-50%); }
    to   { transform: translateX(0); }
  }
  @media (prefers-reduced-motion: reduce) {
    .testimonials-marquee__row--left .testimonials-marquee__track,
    .testimonials-marquee__row--right .testimonials-marquee__track {
      animation: none;
    }
  }

  /* Trustpilot TrustBox-style review card. The marquee cards adopt
     the same visual idiom as Trustpilot's carousel widget: a flat
     white card with sharp corners and a 1 px neutral border, five
     green star-squares at the top (Trustpilot's signature mark, hex
     #00B67A), a sans-serif quote body (no italic, no display face),
     and a quiet author/date footer with a neutral grey avatar. The
     hard-coded greens, whites and greys here intentionally diverge
     from the Wadicos token palette — they are Trustpilot's brand
     specification, which is the whole point of the look-alike. */
  [data-page="home"] .testimonial-card {
    inline-size: 100%;
    block-size: 100%;
    background-color: var(--color-trustpilot-bg);
    border: 1px solid var(--color-trustpilot-border);
    border-radius: 0;
    padding: clamp(var(--space-4), 2vw, var(--space-5));
    display: flex;
    flex-direction: column;
    gap: var(--space-3);
    position: relative;
    overflow: hidden;
    box-shadow: none;
    color: var(--color-trustpilot-ink);
  }

  /* 5-star rating row — Trustpilot green squares, flush together */
  .testimonial-card__rating {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    color: var(--color-trustpilot-star-glyph);
  }
  .testimonial-card__star {
    inline-size: 1.5rem;
    block-size: 1.5rem;
    background-color: var(--color-trustpilot-green);
    fill: var(--color-trustpilot-star-glyph);
    flex: 0 0 auto;
  }

  /* The decorative pull-quote mark belongs to the Wadicos editorial
     idiom, not to Trustpilot — hide it on the home cards. */
  [data-page="home"] .testimonial-card__quote-mark {
    display: none;
  }

  /* Quote — sans-serif body, normal weight, no italic. Overrides the
     product.css base which uses display italic. */
  [data-page="home"] .testimonial-card__quote,
  [data-page="home"] .testimonial-card__quote p {
    margin: 0;
    font-family: var(--font-body);
    font-style: normal;
    font-weight: 400;
    color: var(--color-trustpilot-ink);
    font-size: clamp(0.875rem, 0.83rem + 0.2vw, 1rem);
    line-height: 1.5;
  }

  /* ============ Manifesto (§3.B) · editorial welcome ============ *
   * Insert between §3 Hero (maison carrousel) and §4 Sélection.
   *
   * Single-block composition: a centred editorial paragraph wrapped
   * in .manifesto__welcome, opened by a short champagne hairline rule
   * and closed by a short rule beneath. Two oval pill-shaped images
   * embed inline mid-sentence to punctuate the four crafts the maison
   * runs (parfumerie · distribution · fabrication · import-export).
   * A visually hidden h2 carries the accessible label so the section
   * stays anchorable by screen-reader navigation.
   *
   * Earlier passes carried an image hero with overlaid copy and four
   * corner notches; that block was retired so the section reads as a
   * pure editorial welcome moment between the maison carrousel and
   * the product selection. No scroll-driven reveal, no audio, no
   * animation: content lands on first paint per feedback_no_scroll_reveals.
   * ================================================== */
  .manifesto { padding: var(--space-7); }

  .manifesto__inner {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
    align-items: center;
  }

  /* ---- Welcome block · editorial lead paragraph ----
   * Wraps the intro paragraph with a thin champagne hairline above so
   * it reads as a magazine "lead" passage rather than ordinary body
   * copy. The hairline + the larger type + the wider measure together
   * promote this paragraph to a welcoming statement that introduces
   * the four Wadicos crafts (perfumery · distribution · fabrication ·
   * import-export) to first-time visitors. */
  .manifesto__welcome {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-6);
    inline-size: 100%;
    max-inline-size: var(--container-narrow);
    margin-inline: auto;
  }
  @media (min-width: 64em) {
    .manifesto__welcome { max-inline-size: 80rem; }
  }
  /* Welcome heading · the visible "Bienvenue chez Wadicos." opener.
     Sized one notch under --fs-mega-hero so it reads as a section
     title rather than a page-hero. Clamp floor 2.25rem keeps it ≤ 2
     lines at 320 px on both the FR ("Bienvenue chez Wadicos.", 22
     chars) and EN ("Welcome to Wadicos.", 19 chars) copy; ceiling
     4.5rem at 1920 px stays inside the section's editorial register
     without overpowering the §3 hero above. */
  .manifesto__welcome-title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(2.25rem, 1.5rem + 3.5vw, 4.5rem);
    font-weight: 600;
    line-height: 1.06;
    letter-spacing: var(--tracking-display);
    color: var(--color-ink);
    text-align: center;
    text-wrap: balance;
    max-inline-size: 24ch;
  }

  .manifesto__welcome-rule {
    inline-size: 3.5rem;
    block-size: 1px;
    background-color: var(--color-accent-champagne);
    /* Champagne hairline as editorial ornament — short rule centred
       between the heading and the lead paragraph. Pure decoration,
       screen-reader hidden via aria-hidden in the markup. */
  }

  /* Lead paragraph itself · serif lead voice, wider measure, larger
     scale than body. Floor 1.1875rem at 320 px so the line still
     resolves to ~2 lines per phrase (paragraph stays scannable on
     phones), ceiling 1.875rem at 1920 px so the type reads with
     editorial weight on wide desktops without crowding the hero
     block above. text-wrap:pretty smooths the rag and avoids orphans
     on the last line. */
  .manifesto__intro {
    margin: 0;
    text-align: center;
    font-family: var(--font-bridge);
    font-size: clamp(1.1875rem, 0.95rem + 1.2vw, 1.875rem);
    line-height: 1.65;
    color: var(--color-ink);
    text-wrap: pretty;
    max-inline-size: 38ch;
  }
  @media (min-width: 48em) {
    .manifesto__intro { max-inline-size: 60ch; line-height: 1.7; }
  }
  @media (min-width: 64em) {
    .manifesto__intro { max-inline-size: 72ch; line-height: 1.75; }
  }
  /* Inline image pill — oval crop of a flacon, embedded mid-sentence.
     Sized to track the lead-paragraph font scale: at the 1.875rem
     ceiling, the pill cap-height (~2.75rem) lines up with two body
     lines so it punctuates the run without disrupting the leading
     rhythm. vertical-align hand-tuned so the pill sits visually
     centred with the surrounding x-height. */
  .manifesto__inline-pill {
    display: inline-block;
    inline-size: clamp(4.5rem, 7vw, 7rem);
    block-size: clamp(1.75rem, 3vw, 2.75rem);
    border-radius: var(--radius-pill);
    object-fit: cover;
    object-position: center;
    vertical-align: middle;
    transform: translateY(-0.06em);
    margin-inline: 0.2em;
    box-shadow:
      inset 0 0 0 1px color-mix(in srgb, white 8%, transparent),
      0 6px 14px var(--color-shade-mid);
    background-color: var(--color-bg-elev);
  }

  /* ============ Spotlights (§3.C + §8) — cream interludes ============ *
   * Two parallel sections use this same ruleset:
   *   .elles · "Parfums pour la femme d'exception" (between §3.B and §5)
   *   .eux   · "Parfums pour l'homme d'exception" (between §7 and §9)
   *
   * Selectors are chained `.elles__X, .eux__X` throughout so a single
   * authoring pass holds both. Variant-specific tweaks (if needed)
   * use the more specific selector under the relevant section.
   *
   * Layout:
   *   .{elles,eux}                cream band breaking the dark theatre.
   *   .{elles,eux}__header        2-col row · title start / arrows end.
   *   .{elles,eux}__title         display serif, 2 lines, inline pill.
   *   .{elles,eux}__controls      reuses .carousel__controls + arrows.
   *   .{elles,eux}__carousel      snap-mandatory horizontal scroll.
   *   .{elles,eux}__product-card  cinematic wine frame on .product-card.
   *   .{elles,eux}__curve         two decorative rose SVG strokes.
   *
   * Surface strategy: paints --color-surface-cream directly. Inks pinned
   * to burgundy/mocha because the interior is cream in BOTH themes,
   * so theme-aware tokens would invert wrong.
   * ================================================== */
  .elles,
  .eux {
    position: relative;
    overflow: hidden;
    background-color: color-mix(in srgb, var(--color-red) 32%, transparent);
    padding: var(--space-5);
    border-radius: 5ch;
    margin: var(--space-5);
    border: 5px solid var(--color-cream);
  }

  .collections__title,
  .collections__title-word,
  .elles__title,
  .elles__title-word,
  .eux__title,
  .eux__title-word {
    /* Token resolves to cream on dark + soft white on light — both
       sit at AAA contrast against the burgundy section ground.
       Shared by the three spotlight headers: collections (§6),
       elles (§3.C) and eux (§8). */
    color: var(--color-cream);
  }

  .elles__container,
  .eux__container {
    position: relative;
    z-index: 1;
  }

  /* ---- Decorative curves · rose-peach SVG strokes ---- */
  .elles__curve,
  .eux__curve {
    position: absolute;
    inline-size: 12rem;
    block-size: 12rem;
    color: color-mix(in srgb, var(--color-decor-coral) 42%, transparent);
    pointer-events: none;
    z-index: 0;
  }
  .elles__curve svg,
  .eux__curve svg {
    inline-size: 100%;
    block-size: 100%;
    display: block;
  }
  .elles__curve--start,
  .eux__curve--start {
    inset-block-start: calc(var(--space-9) * -0.4);
    inset-inline-start: calc(var(--gutter) * -0.6);
  }
  .elles__curve--end,
  .eux__curve--end {
    inset-block-end: calc(var(--space-9) * -0.4);
    inset-inline-end: calc(var(--gutter) * -0.6);
  }
  @media (min-width: 48em) {
    .elles__curve,
    .eux__curve { inline-size: 16rem; block-size: 16rem; }
  }
  @media (min-width: 64em) {
    .elles__curve,
    .eux__curve { inline-size: 20rem; block-size: 20rem; }
  }

  /* ---- Header · title on start, arrows on end ---- */
  .elles__header,
  .eux__header {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-5);
    margin-block-end: var(--space-7);
  }
  @media (min-width: 48em) {
    .elles__header,
    .eux__header {
      flex-direction: row;
      align-items: center;
      justify-content: space-between;
      gap: var(--space-6);
    }
  }

  /* ---- Title · 2-line serif with inline pill (shared by §6 / §3.C / §8) ---- */
  .collections__title,
  .elles__title,
  .eux__title {
    margin: 0;
    font-family: var(--font-display);
    font-size: clamp(1.375rem, 0.7rem + 3.4vw, 4.5rem);
    font-weight: 400;
    line-height: 1.1;
    letter-spacing: var(--tracking-display);
    text-transform: uppercase;
    text-align: center;
    text-wrap: balance;
  }
  /* Elles + Eux flip to start-align at desktop because the carousel
     arrows occupy the row-end. Collections has no right-side controls,
     so it intentionally stays centered at every viewport. */
  @media (min-width: 48em) {
    .elles__title,
    .eux__title { text-align: start; }
  }

  .collections__title-row,
  .elles__title-row,
  .eux__title-row {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: nowrap;
    gap: 0.3em;
    white-space: nowrap;
  }
  @media (min-width: 48em) {
    .elles__title-row,
    .eux__title-row { justify-content: flex-start; gap: 0.35em; }
    .collections__title-row { gap: 0.35em; }
  }

  .collections__title-word,
  .elles__title-word,
  .eux__title-word { display: inline-block; }

  /* Inline title pill — oval frame around a centred flacon crop. */
  .collections__title-pill,
  .elles__title-pill,
  .eux__title-pill {
    display: inline-block;
    flex: none;
    inline-size: clamp(3rem, 8.5vw, 9rem);
    block-size: clamp(1.75rem, 4.5vw, 4.5rem);
    border-radius: var(--radius-pill);
    overflow: hidden;
    background-color: var(--color-cream);
    vertical-align: middle;
    box-shadow: 0 8px 22px color-mix(in srgb, var(--color-brand-burgundy) 18%, transparent);
    transform: translateY(-0.06em);
  }
  .collections__title-pill img,
  .elles__title-pill img,
  .eux__title-pill img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    object-position: center;
    display: block;
  }

  /* ---- Carousel controls · cream-friendly arrow buttons ---- */
  .elles__controls,
  .eux__controls {
    margin: 0;
    justify-content: center;
    gap: var(--space-3);
  }
  @media (min-width: 48em) {
    .elles__controls,
    .eux__controls { justify-content: flex-end; flex: none; }
  }

  .elles__arrow,
  .eux__arrow {
    border: 1px solid rgb(122 30 36 / 0.55);
    color: #7a1e24;
    background-color: transparent;
  }
  .elles__arrow:hover,
  .elles__arrow:focus-visible,
  .eux__arrow:hover,
  .eux__arrow:focus-visible {
    background-color: #7a1e24;
    border-color: #7a1e24;
    color: var(--color-surface-cream);
  }

  /* ---- Carousel · escapes the .container, spans full viewport ---- */
  .elles__carousel,
  .eux__carousel {
    margin-block-start: var(--space-7);
    inline-size: 100%;
  }

  /* Track sizing strategy · exactly N cards per page, no peek ----
   * Two things have to line up for a "clean page" carousel:
   *   1. grid-auto-columns must equal (100% - (N-1) * gap) / N where
   *      100% is the track's content box (already excludes padding).
   *      That makes N cards fill the content area to the pixel.
   *   2. padding-inline-end must be 0 so the next card's left edge,
   *      which sits one gap past content-box-end, falls outside the
   *      padding-box (the scroll viewport for overflow-x: auto).
   *      Without this the +1 card peeks by exactly one gap width.
   *
   * Inline-start padding stays at var(--gutter) so the first card
   * aligns under the title above and the section's start hairline. */
  .elles__track,
  .eux__track {
    grid-auto-columns: 100%;
    gap: var(--space-4);
    padding-inline: var(--gutter) 0;
    /* Block padding gives the cinematic shadow stack + hover lift room
       inside the track's clip box. overflow-x: auto on the parent
       forces overflow-y to auto too per spec, so anything escaping
       vertically gets clipped without this padding. */
    padding-block: var(--space-6);
    /* scroll-padding-inline-start ensures `scroll-snap-type: inline
       mandatory` doesn't snap scrollLeft to `padding-inline-start`,
       which would shift the row left by one gutter and make the
       (N+1)th card peek by one gap. */
    scroll-padding-inline-start: var(--gutter);
  }
  @media (min-width: 30em) {
    .elles__track,
    .eux__track {
      grid-auto-columns: calc((100% - var(--space-4)) / 2);
    }
  }
  @media (min-width: 48em) {
    .elles__track,
    .eux__track {
      grid-auto-columns: calc((100% - var(--space-5) * 2) / 3);
      gap: var(--space-5);
    }
  }
  @media (min-width: 64em) {
    .elles__track,
    .eux__track {
      grid-auto-columns: calc((100% - var(--space-5) * 4) / 5);
      gap: var(--space-5);
    }
  }

  /* ---- Card · cinematic wine frame + isolated hover ----
   * Composes on the established .product-card markup from
   * /assets/css/components/product.css. Two design intents drive the
   * overrides here:
   *
   * (1) CINEMATIC WINE FRAME on the media — a 2px burgundy hairline
   *     plus the same multi-layer shadow stack the .hero__media figure
   *     uses on the maison carrousel (shadow-lifted, glow-soft, deep
   *     ambient drop, inset cream highlight, outer black separator).
   *     This lifts each flacon off the cream interlude like a stage
   *     portrait — the photographic moment the design system reserves
   *     for hero figures, applied here to the home-page femme spotlight.
   *
   * (2) ISOLATED HOVER STATES. The base .product-card:hover lifts the
   *     whole card AND zooms .product-card__image, which means hovering
   *     the CTA below would also fire the image zoom and frame
   *     lift — visually noisy and confusing. Here we NEUTRALIZE the
   *     whole-card hover (transform: none on :hover) and re-apply the
   *     lift + image zoom + deeper shadow only on
   *     .product-card__media:hover. The CTA keeps its own isolated
   *     burgundy-darken hover (rule below). Net effect: hover-on-media
   *     animates the photo only; hover-on-CTA animates the button
   *     only; the two never trigger together. */
  /* ---- Card · cinematic wine frame + isolated hover ---- */
  .elles__product-card,
  .eux__product-card {
    transition: none;
  }
  @media (hover: hover) {
    .elles__product-card:hover,
    .eux__product-card:hover { transform: none; }
    .elles__product-card:hover .product-card__image,
    .eux__product-card:hover .product-card__image { transform: none; }
  }

  .elles__product-card .product-card__media,
  .eux__product-card .product-card__media {
    border: 4px solid var(--color-cream);
    background-color: var(--color-bg-elev);
    box-shadow:
      0 18px 36px -10px rgb(122 30 36 / 0.32),
      0 0 32px rgb(214 35 42 / 0.14),
      inset 0 0 0 1px rgb(255 255 255 / 0.14),
      0 0 0 1px rgb(0 0 0 / 0.25);
    transition:
      transform var(--dur-fast) var(--ease-out),
      box-shadow var(--dur-fast) var(--ease-out),
      border-color var(--dur-fast) var(--ease-out);
  }
  .elles__product-card .product-card__media:hover,
  .elles__product-card .product-card__media:focus-visible,
  .eux__product-card .product-card__media:hover,
  .eux__product-card .product-card__media:focus-visible {
    transform: translateY(-3px);
    border-color: rgb(214 35 42 / 0.85);
    box-shadow:
      0 22px 44px -10px rgb(122 30 36 / 0.42),
      0 0 44px rgb(214 35 42 / 0.22),
      inset 0 0 0 1px rgb(255 255 255 / 0.20),
      0 0 0 1px rgb(0 0 0 / 0.35),
      0 0 0 3px rgb(214 35 42 / 0.20);
  }
  .elles__product-card .product-card__image,
  .eux__product-card .product-card__image {
    transition: transform var(--dur-slow) var(--ease-out);
  }
  @media (hover: hover) {
    .elles__product-card .product-card__media:hover .product-card__image,
    .eux__product-card .product-card__media:hover .product-card__image {
      transform: scale(1.04);
    }
  }

  @media (prefers-reduced-motion: reduce) {
    .elles__product-card .product-card__media,
    .elles__product-card .product-card__image,
    .eux__product-card .product-card__media,
    .eux__product-card .product-card__image { transition: none; }
    .elles__product-card .product-card__media:hover,
    .elles__product-card .product-card__media:focus-visible,
    .eux__product-card .product-card__media:hover,
    .eux__product-card .product-card__media:focus-visible { transform: none; }
    .elles__product-card .product-card__media:hover .product-card__image,
    .eux__product-card .product-card__media:hover .product-card__image { transform: none; }
  }

  /* Card CTA · burgundy fill with cream ink. Pin-to-burgundy because
     the cream interior is constant across themes. */
  .elles .product-card__cta,
  .eux .product-card__cta {
    background-color: #7a1e24;
    color: var(--color-surface-cream);
    border-color: #7a1e24;
  }
  .elles .product-card__cta:hover,
  .elles .product-card__cta:focus-visible,
  .eux .product-card__cta:hover,
  .eux .product-card__cta:focus-visible {
    background-color: #5c161b;
    border-color: #5c161b;
    color: var(--color-surface-cream);
  }
  /* Kill the global .product-card__cta::after underline inside both
     spotlight sections — the burgundy pill reads as a solid button,
     the underline scale-in clashes with the cream ink and the
     contained-hover pattern. */
  .elles__product-card .product-card__cta::after,
  .eux__product-card .product-card__cta::after { content: none; }

  /* ============ Footer (§12) ============ *
   * All footer rules moved to components/footer.css when the
   * footer was extracted into a partial. The home-only scoping
   * ([data-page="home"]) is dropped at the same time, completing
   * the V10 polish migration the original comment noted: the
   * brand block + payments row now render on every page from a
   * single canonical partial.
   * ===================================== */
}
