/* ============================================================
   NADILINI — light editorial theme
   Ivory ground, charcoal type, gold accent. Cormorant Garamond
   for display serif, Jost for every small-caps/label/body use —
   same brand kit as before, laid out the way a heritage maison's
   site is laid out: hairline rules, generous whitespace, photography
   captioned underneath rather than text laid over it.
   ============================================================ */

:root{
  --ivory: #F4F1EA;
  --ivory-2: #EDE9DF;
  --charcoal: #1A1A1A;
  --charcoal-70: rgba(26,26,26,.7);
  --charcoal-50: rgba(26,26,26,.5);
  --gold: #C9A227;
  --gold-antique: #B08D3C;
  /* --gold-antique is ~2.8:1 on ivory — fine for hairlines/large accents,
     fails WCAG AA (4.5:1) as small text. Use --gold-text (4.8:1) wherever
     gold is doing the work of a caption/label/meta line, not a decoration. */
  --gold-text: #86651F;
  --fine: #6b665c;
  --line: rgba(26,26,26,.14);
  --line-soft: rgba(26,26,26,.08);

  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans:  "Jost", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --pad: clamp(1.25rem, 4vw, 3.5rem);
  --nav-h: 7.5rem;
}

*, *::before, *::after{ box-sizing: border-box; }
/* No global scroll-behavior:smooth — it fights the journey stack's
   native scroll-snap below (the two smoothing systems compound and
   the scroll reads as stuck). Anchor-link jumps get their own smooth
   scroll in JS instead, scoped to just that one action.
   scroll-snap-type has to live on html (the actual scrolling element,
   since this page uses plain document scroll, not a nested scroll
   container) — but with nothing else on the page marked scroll-snap-
   align, the six journey cards are the only snap points that exist,
   so nothing outside that section is affected. Proximity, not
   mandatory: mandatory traps scroll at the first/last card, since
   there's no snap point above card 01 or below card 06 to rest on —
   scrolling up off the first card would just pull straight back to
   it. Proximity only snaps when a scroll happens to end near a point,
   so it never fights leaving the stack in either direction. Below
   46rem the stack drops to plain contained cards (see .stack__card's
   mobile override) with no snap points at all, so this is inert
   there regardless. */
html{ scroll-snap-type: y proximity; }
body{
  margin: 0;
  background: var(--ivory);
  color: var(--charcoal);
  font-family: var(--sans);
  font-weight: 400;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img{ max-width: 100%; display: block; }
a{ color: inherit; }
h1,h2,h3,h4,blockquote,p{ margin: 0; }
button{ font: inherit; }

.skip{
  position: absolute; left: -999px; top: 0; z-index: 1000;
  background: var(--charcoal); color: var(--ivory);
  padding: .8rem 1.4rem; font-family: var(--sans); font-size: .8rem;
}
.skip:focus{ left: var(--pad); top: .6rem; }

/* small-caps label used constantly: eyebrows, nav, captions */
.label{
  font-family: var(--sans); font-weight: 400;
  font-size: .68rem; letter-spacing: .22em; text-transform: uppercase;
  color: var(--charcoal-70);
}

/* ── utility bar ─────────────────────────────────────────── */
/* Cartier's masthead runs a thin, plain-text strip above the real
   nav — a country/contact line that scrolls away with the page while
   the category nav below it stays put. Kept deliberately spare: no
   fake wishlist/account/bag icons, since this isn't an e-commerce
   site pretending to be one. */

.utility{ background: var(--ivory); border-bottom: 1px solid var(--line-soft); }
.utility__inner{
  max-width: 90rem; margin-inline: auto; padding: 0 var(--pad);
  display: flex; align-items: center; justify-content: space-between;
  height: 2.4rem;
  font-family: var(--sans); font-size: .66rem; font-weight: 400;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--charcoal-70);
}
.utility__inner a{ text-decoration: none; color: var(--charcoal-70); transition: color .25s ease; }
.utility__inner a:hover{ color: var(--gold-text); }

@media (max-width: 46rem){
  .utility__loc{ display: none; }
  .utility__inner{ justify-content: flex-end; }
}

/* ── nav ─────────────────────────────────────────────────── */

.nav{
  position: sticky; top: 0; z-index: 50;
  background: var(--ivory);
  border-bottom: 1px solid var(--line-soft);
}
.nav__inner{
  max-width: 90rem; margin-inline: auto;
  padding: 0 var(--pad);
  display: grid; grid-template-columns: 1fr auto 1fr;
  align-items: center;
  min-height: var(--nav-h);
}
/* burger and links occupy the same cell — only one is ever visible,
   so they never fight for space at either breakpoint */
.nav__burger, .nav__links{ grid-column: 1; justify-self: start; }
.nav__mark{ grid-column: 2; }
.nav__spacer{ grid-column: 3; }

.nav__links{
  display: flex; gap: 1.8rem; align-items: center;
  font-family: var(--sans); font-size: .74rem; font-weight: 400;
  letter-spacing: .03em; text-transform: uppercase;
}
.nav__links a{
  text-decoration: none; color: var(--charcoal);
  padding: .95rem 0; border-bottom: 1px solid transparent;
  transition: border-color .25s ease, color .25s ease;
}
.nav__links a:hover{ border-color: var(--gold); }
.nav__links a:focus-visible, .nav__mark:focus-visible, .btn:focus-visible,
.nav__burger:focus-visible{
  outline: 2px solid var(--gold-text); outline-offset: 3px;
}

/* the wordmark, recreated in type (not a raster image) so it stays
   crisp and re-flows at any size — matches the approved lockup: serif
   caps wordmark, small gold tracked descriptor flanked by hairlines */
.nav__mark{
  text-decoration: none; text-align: center;
  color: var(--charcoal);
}
.nav__word{
  display: block; font-family: var(--serif); font-weight: 500;
  font-size: 2.6rem; letter-spacing: .16em; text-transform: uppercase;
}
.nav__desc{
  display: flex; align-items: center; gap: .6em; justify-content: center;
  font-family: var(--sans); font-weight: 500; font-size: .78rem;
  letter-spacing: .26em; text-transform: uppercase; color: var(--gold-text);
  margin-top: .45rem;
}
.nav__desc i{
  display: block; width: 2.2rem; height: 1px; font-style: normal;
  background: linear-gradient(to right, transparent, var(--gold), transparent);
}

.nav__burger{ display: none; }
.nav.is-stuck{ box-shadow: 0 1px 0 var(--line); }

@media (max-width: 62rem){
  .nav__links{
    display: none;
    /* the base (desktop) rule sets justify-self: start for the grid
       layout — that survives here and, per spec, overrides the
       left:0/right:0 stretch below (justify-self other than
       'stretch' wins over inset-driven sizing on a grid item, even
       once it's absolutely positioned), so the panel was shrinking
       to content width and hugging the left edge instead of
       spanning the header. stretch puts it back in charge of sizing. */
    justify-self: stretch;
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; align-items: flex-start; gap: 0;
    background: var(--ivory); border-bottom: 1px solid var(--line);
    padding: .5rem var(--pad) 1.2rem;
  }
  .nav__links.is-open{ display: flex; }
  .nav__links a{ padding: .9rem 0; width: 100%; border-bottom: 1px solid var(--line-soft); }
  .nav__burger{
    display: flex; flex-direction: column; justify-content: center; align-items: center;
    min-width: 44px; min-height: 44px;
    background: none; border: 0; padding: .5rem; cursor: pointer;
  }
  .nav__burger span{
    display: block; width: 15px; height: 1px; background: var(--charcoal);
    margin: 4px 0;
    transition: transform .3s cubic-bezier(.2,.8,.2,1), opacity .2s ease;
  }
  /* center-to-center distance between adjacent spans is margin(4) +
     height(1) + margin(4) = 9px — the translateY has to match that
     exactly or the two rotated bars don't actually cross at a shared
     point, which reads as two disjointed ticks instead of a clean X */
  .nav__burger[aria-expanded="true"] span:nth-child(1){ transform: translateY(9px) rotate(45deg); }
  .nav__burger[aria-expanded="true"] span:nth-child(2){ opacity: 0; }
  .nav__burger[aria-expanded="true"] span:nth-child(3){ transform: translateY(-9px) rotate(-45deg); }
  .nav__word{ font-size: 1.9rem; }
  .nav__desc i{ width: 1.4rem; }
  /* the grid's outer columns are meant to mirror each other (1fr each
     side of the centred wordmark), but column 1 carries the 44px
     burger button while column 3's spacer carries nothing — so the
     wordmark was already sitting right of true-centre before any
     extra push. Giving the spacer the same 44px minimum balances the
     two columns so the grid centres the wordmark on its own. */
  .nav__spacer{ min-width: 44px; }
}

/* ── hero ────────────────────────────────────────────────── */

.hero{
  position: relative;
  height: 88svh; min-height: 30rem;
  overflow: hidden;
  /* Matches the hero film's dark studio backdrop, so the pre-load paint
     and any letterbox edge blend into the video rather than flashing a
     pale band behind it. */
  background: var(--charcoal);
}
.hero__stage{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}
.hero__video{
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  /* Ring biased into the right half so the overlaid copy on the left
     never sits on top of it. Mobile re-biases this vertically below. */
  object-position: 74% 50%;
}
/* Deepens the lower frame the copy sits in, so the type holds as the
   ring's highlights and reflection drift underneath it. */
.hero__scrim{
  position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(12,11,9,.72) 0%, transparent 46%);
  pointer-events: none;
}
/* Moved to the right edge: the bottom-left corner now belongs to the
   hero copy's buttons, which this used to sit directly underneath. */
.hero__caption{
  position: absolute; right: var(--pad); bottom: 1.6rem; z-index: 2;
  color: var(--ivory);
}
.hero__caption .label{ color: rgba(244,241,234,.82); }

/* Anchored low-left rather than vertically centred: the ring occupies
   roughly the middle 24–75% of the frame, so centred copy clipped its
   left shank. The lower band is unbroken dark surface, which clears the
   ring without having to zoom or pan the footage away from it. */
.hero__copy{
  position: absolute; z-index: 2;
  left: var(--pad); bottom: clamp(2.5rem, 8vh, 5rem);
  max-width: min(28rem, 44%);
}
.hero__copy .hero__h--single{ color: var(--ivory); }
/* Scoped to the hero: .btn--solid is shared with the contact form,
   which sits on ivory and still wants the charcoal fill. */
.hero__copy .btn--solid{
  background: var(--ivory); color: var(--charcoal); border-color: var(--ivory);
}
.hero__copy .btn--solid:hover{
  background: var(--gold-antique); border-color: var(--gold-antique); color: var(--ivory);
}
.hero__copy .hero__h{ margin-bottom: 1.6rem; }
.hero__copy .hero__actions{ justify-content: flex-start; }
/* Sized down from the standalone-band figure it inherits — the copy is
   in a ~44% column now, not the full page width. */
.hero__copy .hero__h--single{ font-size: clamp(2.15rem, 4.4vw, 3.8rem); }

@media (max-width: 62rem){
  .hero__copy{ max-width: min(24rem, 52%); }
}

/* Narrow screens can't hold a side-by-side split, so the separation
   becomes vertical: ring in the upper frame, copy across the bottom.
   The certified/set-by-hand caption is dropped rather than stacked —
   there's only room for one thing at the bottom edge. */
@media (max-width: 46rem){
  /* cover against the full portrait box crops to roughly the middle
     third of a 16:9 frame, which magnifies the ring hugely. Letting the
     film occupy only the upper band shortens the box it has to cover, so
     far less is cropped away and the ring reads at a sane size; the mask
     feathers its lower edge into the hero background so the shortened
     box doesn't show as a seam. */
  .hero__video{
    inset: 0 0 auto 0;
    height: 66%;
    object-position: 50% 42%;
    -webkit-mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
            mask-image: linear-gradient(to bottom, #000 74%, transparent 100%);
  }
  /* Sits it up off the bottom edge into the band the film's masked
     lower edge has already faded to background, so the block reads as
     centred in the space under the ring rather than pinned to the floor. */
  .hero__copy{
    bottom: clamp(3rem, 8vh, 5rem);
    left: var(--pad); right: var(--pad);
    max-width: none; text-align: center;
  }
  .hero__copy .hero__actions{ justify-content: center; }
  .hero__caption{ display: none; }
}

.hero__band{
  max-width: 46rem; margin-inline: auto;
  text-align: center;
  padding: clamp(3.5rem, 9vw, 6rem) var(--pad) clamp(3rem, 7vw, 4.5rem);
}
.hero__band .label{ display: block; margin-bottom: 1.1rem; }
.hero__h{
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(2.3rem, 5.4vw, 3.6rem);
  line-height: 1.06; margin-bottom: 1.4rem;
}
.hero__h em{ font-style: italic; font-weight: 400; color: var(--gold-text); }
/* Charcoal rather than gold-on-cream (the gold sat too close to the
   film's warm backdrop to hold an edge) and upright rather than italic:
   the italic face is only loaded at weight 300, so asking for a heavier
   italic would get a synthesised fake-bold instead of a real one. */
.hero__h--single{
  font-size: clamp(2.6rem, 6vw, 4.2rem);
  color: var(--charcoal);
  font-weight: 600;
}
.hero__lede{
  font-size: 1rem; color: var(--charcoal-70);
  max-width: 34rem; margin: 0 auto 2.1rem;
}
.hero__actions{ display: flex; gap: .9rem; justify-content: center; flex-wrap: wrap; }

/* ── buttons ─────────────────────────────────────────────── */

.btn{
  display: inline-block;
  font-family: var(--sans); font-size: .72rem; font-weight: 400;
  letter-spacing: .16em; text-transform: uppercase;
  text-decoration: none; cursor: pointer;
  padding: .95rem 2rem;
  transition: background .25s ease, color .25s ease, border-color .25s ease;
}
.btn--solid{ background: var(--charcoal); color: var(--ivory); border: 1px solid var(--charcoal); }
.btn--solid:hover{ background: var(--gold-antique); border-color: var(--gold-antique); }
/* Only used in the hero, which sits on the dark film — so it outlines in
   ivory and fills on hover, rather than the charcoal-on-ivory pairing
   the rest of the page's buttons use. */
.btn--ghost{ background: transparent; color: var(--ivory); border: 1px solid var(--ivory); }
.btn--ghost:hover{ background: var(--ivory); color: var(--charcoal); }

/* ── generic section scaffolding ────────────────────────── */

section{ padding: clamp(4rem, 9vh, 6.5rem) 0; }
.section__inner{ max-width: 90rem; margin-inline: auto; padding: 0 var(--pad); }
.section__head{ max-width: 40rem; margin: 0 auto clamp(2.5rem, 6vw, 3.5rem); text-align: center; }
.section__head .label{ display: block; margin-bottom: 1rem; }
.section__h{
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  line-height: 1.1; margin-bottom: 1rem;
}
.section__h-caps{ text-transform: uppercase; letter-spacing: .04em; }
.section__lede{ color: var(--charcoal-70); font-size: .96rem; }

.rule{
  width: 3.4rem; height: 1px; margin: 0 auto 1.3rem;
  background: linear-gradient(to right, transparent, var(--gold), transparent);
}

section.on-ivory-2{ background: var(--ivory-2); }

/* ── the journey: one scrubbed film, bold labels popping in/out ──
   A single clip stays pinned full-bleed for the entire scroll length
   of .journey-scrub; video.currentTime is driven straight off scroll
   progress (see js/site.js — GSAP ScrollTrigger + Lenis, per
   docs/BUILD_PLAN.md A4). The six chapter labels share one slot: as
   progress crosses into a chapter's sixth of the timeline the label
   swaps text and pops up bold, holds, then drops away before the
   next one arrives — driven every frame by scroll, not CSS transition
   triggers, since it has to reverse cleanly on scroll-up too. */

.journey{ padding-bottom: 0; }

.journey-scrub{
  position: relative;
  /* six chapters' worth of scroll room, one screen-height each */
  height: 600vh;
  background: var(--charcoal);
}

.journey-scrub__pin{
  position: sticky;
  top: 0;
  /* dvh tracks the real visible viewport as mobile browser chrome
     (address bar) shows/hides mid-scroll; plain vh is fixed at
     load-time size, which desyncs the pin height from the document
     height ScrollTrigger measured — that mismatch is what reads as
     the scroll "skipping" chapters on phones. vh stays as the
     fallback for older browsers without dvh support. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  align-items: center;
}

.journey-scrub__video{
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  display: block;
}
/* mobile swaps <video> scrubbing for a pre-extracted WebP frame
   sequence drawn to this canvas — no video decode/seek at all, so
   the same currentTime-per-scroll-tick cost that struggled on real
   phones just doesn't exist here (see js/site.js). Hidden by default;
   JS shows it and hides the video only where it actually initialises
   the canvas path. */
.journey-scrub__canvas{
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  display: none;
  /* belt-and-braces: if the buffer ever briefly lags the box size
     during a resize (see js/site.js), this matches the section's own
     background so any gap is invisible rather than a visible flash */
  background: var(--charcoal);
}
.journey-scrub__scrim{ display: none; }

.journey-scrub__label{
  position: relative;
  z-index: 2;
  max-width: 34rem;
  margin-left: clamp(1.5rem, 8vw, 8rem);
  opacity: 0;
  will-change: opacity, transform;
}
/* no panel, no glow, no scrim on the video — contrast comes purely
   from the type itself: a hard multi-directional outline (several
   1px-offset shadows, more reliable cross-browser than text-stroke)
   plus a soft drop shadow for lift, and real bold weights (loaded
   in the <head> font request) instead of the browser faking bold. */
.journey-scrub__no{
  display: block;
  font-family: var(--serif); font-weight: 600;
  font-size: clamp(1rem, 1.6vw, 1.2rem);
  letter-spacing: .4em;
  color: var(--gold);
  margin-bottom: 1.1rem;
  text-shadow:
    -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000,
    0 3px 16px rgba(0,0,0,.9);
}
.journey-scrub__title{
  font-family: var(--serif); font-weight: 700;
  font-size: clamp(3rem, 8vw, 6.5rem);
  line-height: .98;
  color: #fff;
  margin-bottom: 1.2rem;
  text-shadow:
    -2px -2px 0 #000, 2px -2px 0 #000, -2px 2px 0 #000, 2px 2px 0 #000,
    0 2px 0 #000, 0 -2px 0 #000, 2px 0 0 #000, -2px 0 0 #000,
    0 10px 40px rgba(0,0,0,.85);
}
.journey-scrub__desc{
  max-width: 26rem;
  font-family: var(--sans); font-weight: 600;
  font-size: clamp(1.1rem, 1.35vw, 1.3rem);
  line-height: 1.75;
  letter-spacing: .01em;
  color: #fff;
  text-shadow:
    -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000,
    0 4px 18px rgba(0,0,0,.9);
}

/* scroll-progress rail: a thin fixed-width line that fills as the
   whole chapter sequence scrubs, so there's always a sense of how
   far through the journey the current frame is */
.journey-scrub__track{
  position: absolute;
  right: clamp(1.5rem, 5vw, 4rem);
  top: 50%; transform: translateY(-50%);
  width: 2px; height: 40vh;
  background: rgba(244,241,234,.14);
  z-index: 2;
}
.journey-scrub__fill{
  position: absolute; left: 0; top: 0; width: 100%;
  /* full height + scaleY(progress) from the top, rather than animating
     `height` — transform composites on the GPU, height forces a layout
     pass on every scrub tick. */
  height: 100%;
  transform: scaleY(0);
  transform-origin: 50% 0;
  will-change: transform;
  background: linear-gradient(180deg, var(--gold), var(--gold-antique));
}

@media (max-width: 62rem){
  .journey-scrub{ height: 480vh; height: 480dvh; }
  /* portrait phone crops (object-fit: cover) centre the video's
     subject vertically — the same spot the label sits in on desktop —
     so on narrow screens the label moves to the bottom edge instead,
     clear of whatever the frame is showing, with its own scrim so
     it's still legible over a bright bottom third. */
  .journey-scrub__pin{ align-items: flex-end; }
  .journey-scrub__label{
    margin-left: var(--pad); margin-right: var(--pad); max-width: none;
    padding-bottom: clamp(2rem, 6vh, 3.5rem);
  }
  .journey-scrub__pin::after{
    content: '';
    position: absolute; inset: auto 0 0 0; z-index: 1;
    height: 42%;
    /* Two things caused the visible hard line here:
       1. `transparent` is rgba(0,0,0,0) — transparent *black* — so a
          two-stop ramp to a dark colour interpolates through muddy
          greys and reads as a band with an edge. Using an explicit
          zero-alpha version of the same colour keeps the hue constant.
       2. A linear ramp puts too much of the darkening near the top
          edge. The extra stops approximate an ease-in curve, so the
          scrim is imperceptible where it starts and only gathers
          density behind the text near the bottom. Taller + gentler
          reads as lighter than the short steep version it replaces. */
    background: linear-gradient(180deg,
      rgba(10,10,10,0) 0%,
      rgba(10,10,10,.02) 26%,
      rgba(10,10,10,.07) 44%,
      rgba(10,10,10,.16) 60%,
      rgba(10,10,10,.29) 75%,
      rgba(10,10,10,.45) 88%,
      rgba(10,10,10,.58) 100%);
    pointer-events: none;
  }
  .journey-scrub__title{ font-size: clamp(2.4rem, 12vw, 3.6rem); }
  .journey-scrub__track{ display: none; }
}

/* ── editorial two-up (assembly / fire) ─────────────────── */

.duo{
  display: grid; gap: 1.6rem;
  grid-template-columns: 1fr 1fr;
}
.duo__item{ text-align: center; }
.duo__frame{ aspect-ratio: 4 / 3; overflow: hidden; background: var(--charcoal); }
.duo__frame img, .duo__frame video{ width: 100%; height: 100%; object-fit: cover; }
.duo__cap{
  margin-top: 1.1rem;
  font-family: var(--sans); font-size: .74rem; letter-spacing: .18em;
  text-transform: uppercase; color: var(--charcoal-70);
}
.duo__h{ font-family: var(--serif); font-size: clamp(1.5rem, 2.2vw, 1.9rem); margin: .35rem 0 .5rem; }

/* Third duo item spans both columns — same frame/cap/heading
   treatment as its siblings, just proportioned wider (4/3 at double
   width would read as an oddly tall slab) so it sits underneath them
   as one continuous strip, filling the same width as the two above. */
.duo__item--wide{ grid-column: 1 / -1; }
.duo__item--wide .duo__frame{ aspect-ratio: 21 / 8; }
@media (max-width: 46rem){
  .duo__item--wide .duo__frame{ aspect-ratio: 4 / 3; }
}

/* ── the range: one wide showcase, same raised-card language
   as the maisons grid, just a single wide card instead of four
   narrow ones — so the two sections read as one family. */

.range__card{
  max-width: 82rem;
  margin: 0 auto;
}
.range__shot{
  margin: -2.7rem -2.1rem -2.3rem;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--charcoal);
}
.range__shot picture{ display: block; width: 100%; height: 100%; }
.range__shot img{ width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 46rem){
  .duo{ grid-template-columns: 1fr; max-width: 30rem; margin-inline: auto; gap: 3rem; }
  /* the mobile shot is its own portrait crop (not the wide desktop
     photo squeezed narrower), so it gets a taller aspect ratio to
     match rather than being cover-cropped down to a sliver */
  .range__shot{ aspect-ratio: 3 / 4; }
  /* breaks the card out of .section__inner's side padding so the
     image runs edge-to-edge on mobile instead of sitting inset —
     a noticeably bigger, more prominent showcase on small screens */
  .range__card{
    max-width: none;
    margin-left: calc(-1 * var(--pad));
    margin-right: calc(-1 * var(--pad));
    border-left: 0; border-right: 0;
  }
}

/* ── creed band ──────────────────────────────────────────── */

.creed{
  text-align: center; background: var(--charcoal); color: var(--ivory);
  padding: clamp(6rem, 14vh, 9rem) 0;
}
.creed .rule{ background: linear-gradient(to right, transparent, var(--gold), transparent); }
.creed__inner{ max-width: 40rem; margin: 0 auto; padding: 0 var(--pad); }
.creed__kicker{ font-family: var(--sans); font-size: .68rem; letter-spacing: .24em; text-transform: uppercase; color: rgba(244,241,234,.68); margin-bottom: 1.6rem; }
.creed__q{
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.5rem, 3.4vw, 2.2rem); line-height: 1.32;
  margin-bottom: 1.6rem;
}
.creed__q em{ font-style: italic; color: var(--gold); }
.creed__sub{ font-size: .92rem; color: rgba(244,241,234,.68); }

/* ── raised card: shared "luxury pop-out" treatment ───────
   Used by the maisons grid and the process steps, so the two feel
   like one design language rather than two different card ideas. A
   soft multi-layer shadow gives the panel real depth against the
   ivory ground; the hover lift + slight rotateX sells the "sitting
   just above the page" read without going full skeuomorphic. */

.raised-card{
  position: relative;
  background: linear-gradient(165deg, #fffdf9 0%, var(--ivory) 100%);
  border: 1px solid var(--line-soft);
  padding: 2.7rem 2.1rem 2.3rem;
  display: flex; flex-direction: column;
  box-shadow:
    0 1px 1px rgba(26,26,26,.05),
    0 10px 20px -10px rgba(26,26,26,.18),
    0 26px 40px -20px rgba(26,26,26,.16);
  transform: perspective(1200px) translateY(0) rotateX(0deg);
  transition: transform .5s cubic-bezier(.2,.8,.2,1), box-shadow .5s cubic-bezier(.2,.8,.2,1);
  will-change: transform;
}
.raised-card::before{
  content: ""; position: absolute; top: 0; left: 1.6rem; right: 1.6rem; height: 2px;
  background: linear-gradient(to right, transparent, var(--gold), transparent);
  opacity: .85;
}
.raised-card:hover{
  transform: perspective(1200px) translateY(-.55rem) rotateX(2.5deg);
  box-shadow:
    0 2px 3px rgba(26,26,26,.07),
    0 22px 30px -12px rgba(26,26,26,.24),
    0 44px 64px -24px rgba(26,26,26,.2);
}

/* the maisons cards carry a photograph — the gold top-hairline is
   redundant once a photo already anchors the top of the card, so it's
   the photo's edge that reads as the card's "top" instead */
.mcard.raised-card::before{ display: none; }
.mcard__frame{
  margin: -2.7rem -2.1rem 1.7rem;
  aspect-ratio: 5 / 4; overflow: hidden; background: var(--charcoal);
}
.mcard__frame img{ width: 100%; height: 100%; object-fit: cover; display: block; }

/* the numeral/letter badge shared by both card kinds — a small
   embossed disc rather than flat text, for the same "raised" feel */
.card-badge{
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.7rem; height: 2.7rem; margin-bottom: 1.5rem;
  border-radius: 50%; border: 1px solid var(--line);
  background: radial-gradient(circle at 34% 28%, #fff 0%, var(--ivory) 72%);
  box-shadow: inset 0 1px 1px rgba(255,255,255,.9), inset 0 -1px 2px rgba(26,26,26,.06), 0 3px 6px rgba(26,26,26,.1);
  font-family: var(--serif); font-size: 1.05rem; color: var(--gold-text);
}

/* the "Discover" links — Cartier's own card convention: a plain
   underlined text link, never a boxed button, closing out a card */
.card-link{
  display: inline-block; margin-top: 1.1rem;
  font-family: var(--sans); font-size: .72rem; font-weight: 500;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--charcoal); text-decoration: none;
  border-bottom: 1px solid var(--charcoal);
  padding-bottom: .15rem;
  transition: color .25s ease, border-color .25s ease;
}
.card-link:hover{ color: var(--gold-text); border-color: var(--gold-text); }

@media (max-width: 30rem){
  .raised-card:hover{ transform: none; }
}

/* ── maisons: category cards ────────────────────────────── */

.maisons{
  display: grid; gap: 1.9rem;
  grid-template-columns: repeat(4, 1fr);
}
.mcard__h{ font-family: var(--serif); font-weight: 500; font-size: 1.4rem; margin-bottom: .8rem; }
.mcard__p{ font-size: .87rem; color: var(--charcoal-70); margin-bottom: 1.3rem; flex: 1; }
.mcard__meta{ font-size: .7rem; letter-spacing: .05em; color: var(--gold-text); border-top: 1px solid var(--line); padding-top: 1rem; }

@media (max-width: 62rem){
  .maisons{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 30rem){
  .maisons{ grid-template-columns: 1fr; }
}

/* ── process steps ───────────────────────────────────────── */

.steps{
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1.9rem;
  grid-template-columns: repeat(4, 1fr);
}
.step__h{ font-family: var(--serif); font-weight: 500; font-size: 1.4rem; margin-bottom: .8rem; }
.step__p{ font-size: .86rem; color: var(--charcoal-70); }

@media (max-width: 56rem){
  .steps{ grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 30rem){
  .steps{ grid-template-columns: 1fr; }
}

/* ── contact ─────────────────────────────────────────────── */

.contact{ background: var(--ivory-2); }
.contact__inner{ max-width: 40rem; margin: 0 auto; padding: 0 var(--pad); text-align: center; }
.contact__p{ color: var(--charcoal-70); font-size: .95rem; margin-top: 1rem; }

.form{
  margin-top: 2.8rem; text-align: left;
  display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem 1.4rem;
}
.field{ display: flex; flex-direction: column; gap: .5rem; }
.field--wide{ grid-column: 1 / -1; }
.field label{ font-size: .68rem; letter-spacing: .16em; text-transform: uppercase; color: var(--charcoal-70); }
.field input, .field select, .field textarea{
  width: 100%; background: transparent;
  border: 0; border-bottom: 1px solid var(--line);
  color: var(--charcoal); font-family: var(--sans); font-size: .95rem; font-weight: 400;
  padding: .6rem 0; border-radius: 0;
  transition: border-color .3s ease, box-shadow .3s ease;
}
.field textarea{ resize: vertical; }
.field input:focus, .field select:focus, .field textarea:focus{
  outline: none; border-color: var(--gold-text);
  box-shadow: 0 1px 0 0 var(--gold-text);
}
.field input:focus-visible, .field select:focus-visible, .field textarea:focus-visible{
  outline: 2px solid var(--gold-text); outline-offset: 2px;
}
.field select option{ background: var(--ivory); color: var(--charcoal); }
.field input::placeholder, .field textarea::placeholder{ color: var(--fine); }
.field input[aria-invalid="true"], .field select[aria-invalid="true"], .field textarea[aria-invalid="true"]{
  border-color: #b3402f;
}
.field__error{ font-size: .74rem; color: #b3402f; margin-top: -.15rem; }

.form__foot{ display: flex; align-items: center; gap: 1.2rem; flex-wrap: wrap; }
.form__note{ font-size: .8rem; color: var(--gold-antique); }

.contact__direct{
  list-style: none; margin: 3.2rem 0 0; padding: 2rem 0 0;
  border-top: 1px solid var(--line);
  display: grid; gap: .9rem;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  font-size: .87rem; color: var(--charcoal-70); text-align: left;
}
.contact__direct b{ display: block; color: var(--gold-text); font-size: .64rem; letter-spacing: .2em; text-transform: uppercase; font-weight: 500; margin-bottom: .3rem; }
.contact__direct a{ color: var(--charcoal); text-decoration: none; border-bottom: 1px solid var(--line); }
.contact__direct a:hover{ color: var(--gold-antique); border-color: var(--gold-antique); }

@media (max-width: 34rem){
  .form{ grid-template-columns: 1fr; }
}

/* ── footer ──────────────────────────────────────────────── */

.foot{
  padding: 3.5rem var(--pad) 2.4rem;
  text-align: center;
  border-top: 1px solid var(--line);
  background: var(--ivory);
}
.foot__word{ font-family: var(--serif); font-weight: 500; font-size: 1.15rem; letter-spacing: .16em; text-transform: uppercase; }
.foot__desc{ display: block; font-size: .64rem; font-weight: 500; letter-spacing: .26em; text-transform: uppercase; color: var(--gold-text); margin-top: .3rem; }
.foot__endorse{ font-family: var(--sans); font-weight: 300; font-size: .74rem; letter-spacing: .24em; text-transform: uppercase; color: var(--charcoal-70); margin: 1.1rem 0 0; }
.foot__line{ margin: 1.5rem 0 1.2rem; color: var(--charcoal-70); font-size: .88rem; }
.foot__fine{ margin: 0; color: var(--fine); font-size: .7rem; }

/* ── sister companies: certificate-wall of clickable wax-seal medals ──
   Pure-CSS radio-tab pattern: five hidden radios, one label-medal per
   radio (the visible clickable seal), five stacked panels shown only
   when their matching radio is checked. No JS needed — the file
   already has a global reveal observer (js/site.js) for [data-lift],
   nothing beyond that is required for this to work, including with
   JS disabled entirely (the browser's native radio-button behavior
   drives it). Keeps the whole section to one compact row + one open
   citation at a time, instead of five full paragraphs stacked. */

.seals__input{
  position: absolute; opacity: 0; pointer-events: none;
}

.seals__row{
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  margin-top: clamp(1.5rem, 3vw, 3rem);
}

.seals__medal{
  display: flex; flex-direction: column; align-items: center; gap: 1rem;
  cursor: pointer;
  width: clamp(9rem, 20vw, 13.5rem);
  text-align: center;
}

.seals__ring{
  width: 100%; aspect-ratio: 1; border-radius: 50%;
  background: #fff;
  border: 1px solid var(--line-soft);
  box-shadow:
    0 1px 1px rgba(26,26,26,.05),
    0 8px 18px -10px rgba(26,26,26,.2);
  display: flex; align-items: center; justify-content: center;
  padding: 14%;
  position: relative;
  transition: transform .4s cubic-bezier(.2,.8,.2,1), box-shadow .4s ease, border-color .4s ease;
}
/* the "seal" ring — a thin gold groove just inside the edge, like an
   embossed wax stamp or certificate seal */
.seals__ring::before{
  content: ""; position: absolute; inset: 6%;
  border: 1px solid var(--gold); border-radius: 50%;
  opacity: .35;
  transition: opacity .4s ease;
}
.seals__ring img{
  width: 100%; height: 100%; object-fit: contain;
  position: relative; z-index: 1;
}

.seals__name{
  font-family: var(--sans); font-size: .92rem; font-weight: 500;
  letter-spacing: .04em; color: var(--charcoal-70);
  transition: color .3s ease;
}

.seals__medal:hover .seals__ring{
  transform: translateY(-.2rem);
  box-shadow:
    0 2px 3px rgba(26,26,26,.07),
    0 14px 26px -12px rgba(26,26,26,.24);
}

/* selected state, driven per-company by the matching radio */
#seal-bonas:checked ~ .seals__row label[for="seal-bonas"] .seals__ring,
#seal-mining:checked ~ .seals__row label[for="seal-mining"] .seals__ring,
#seal-cmr:checked ~ .seals__row label[for="seal-cmr"] .seals__ring,
#seal-diamonds:checked ~ .seals__row label[for="seal-diamonds"] .seals__ring,
#seal-refinery:checked ~ .seals__row label[for="seal-refinery"] .seals__ring{
  border-color: var(--gold);
  box-shadow:
    0 2px 3px rgba(26,26,26,.07),
    0 14px 26px -12px rgba(26,26,26,.24),
    0 0 0 3px rgba(201,162,39,.16);
}
#seal-bonas:checked ~ .seals__row label[for="seal-bonas"] .seals__ring::before,
#seal-mining:checked ~ .seals__row label[for="seal-mining"] .seals__ring::before,
#seal-cmr:checked ~ .seals__row label[for="seal-cmr"] .seals__ring::before,
#seal-diamonds:checked ~ .seals__row label[for="seal-diamonds"] .seals__ring::before,
#seal-refinery:checked ~ .seals__row label[for="seal-refinery"] .seals__ring::before{
  opacity: .8;
}
#seal-bonas:checked ~ .seals__row label[for="seal-bonas"] .seals__name,
#seal-mining:checked ~ .seals__row label[for="seal-mining"] .seals__name,
#seal-cmr:checked ~ .seals__row label[for="seal-cmr"] .seals__name,
#seal-diamonds:checked ~ .seals__row label[for="seal-diamonds"] .seals__name,
#seal-refinery:checked ~ .seals__row label[for="seal-refinery"] .seals__name{
  color: var(--gold-text);
}

/* citation panels: stacked in the same grid cell, only the active
   one is visible/interactive — crossfades rather than jumping */
.seals__panels{
  display: grid;
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  max-width: 38rem;
  text-align: center;
  min-height: 6rem;
}
.seals__panel{
  grid-area: 1 / 1;
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity .4s ease, transform .4s cubic-bezier(.2,.8,.2,1), visibility 0s linear .4s;
}
#seal-bonas:checked ~ .seals__panels [data-panel="bonas"],
#seal-mining:checked ~ .seals__panels [data-panel="mining"],
#seal-cmr:checked ~ .seals__panels [data-panel="cmr"],
#seal-diamonds:checked ~ .seals__panels [data-panel="diamonds"],
#seal-refinery:checked ~ .seals__panels [data-panel="refinery"]{
  opacity: 1; visibility: visible; transform: none;
  transition: opacity .4s ease .05s, transform .4s cubic-bezier(.2,.8,.2,1) .05s, visibility 0s linear;
}

.seals__quote{
  font-family: var(--sans);
  font-size: clamp(.9rem, 1.6vw, 1rem); line-height: 1.7;
  color: var(--charcoal-70);
  margin-bottom: 1rem;
}
.seals__visit{
  display: inline-block;
  font-family: var(--sans); font-size: .74rem; letter-spacing: .06em;
  color: var(--gold-text); text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color .25s ease;
}
.seals__visit:hover{ border-color: var(--gold-text); }

/* Mobile-only stacked list: hidden on desktop by default. Everything
   is shown at once (logo, name, quote, link) with no click needed —
   the desktop click-to-reveal medal row saves scroll space on a wide
   screen, but on mobile that same interaction just gets in the way
   of reading five short blurbs, so it's swapped for a plain list. */
.seals__mobile{ display: none; }

@media (max-width: 46rem){
  .seals__row, .seals__panels{ display: none; }

  .seals__mobile{
    display: flex; flex-direction: column;
    gap: 2.5rem;
    margin-top: 2rem;
  }
  .seals__mobile-item{
    display: flex; flex-direction: column; align-items: center;
    text-align: center;
    gap: .9rem;
  }
  /* On mobile, drop the wax-seal circle treatment entirely — show
     each logo as-is (several are already diamond/triangle marks) at
     a large plain size, rather than masking them into a circle. */
  .seals__mobile-item .seals__ring{
    width: clamp(11rem, 48vw, 14rem);
    aspect-ratio: auto;
    background: none; border: none; box-shadow: none;
    border-radius: 0; padding: 0;
  }
  .seals__mobile-item .seals__ring::before{
    content: none;
  }
  .seals__mobile-item .seals__ring img{
    width: 100%; height: auto;
  }
  .seals__mobile-name{
    font-family: var(--serif); font-weight: 600;
    font-size: 1.3rem; color: var(--charcoal);
  }
  .seals__mobile-item .seals__quote{
    font-size: 1rem;
    margin-bottom: .4rem;
  }
}

/* ── mine footage narrative: two-column context beneath the duo grid
   (the video itself now lives as the third, full-width duo__item —
   see .duo__item--wide above). Sits inside the same .section__inner
   as the duo grid, so no separate max-width/padding/background of
   its own is needed here. */
.mine-footage__narrative{
  margin-top: clamp(3rem, 7vw, 5rem);
  padding-top: clamp(2.5rem, 6vw, 4rem);
  border-top: 1px solid var(--line-soft);
}

.mine-footage__narrative-inner{
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  gap: clamp(3rem, 7vw, 5rem);
  max-width: 60rem;
  margin-inline: auto;
}

.mine-footage__narrative-col{
  max-width: 26rem;
  margin-inline: auto;
}

.mine-footage__narrative-h{
  font-family: var(--serif);
  font-weight: 500;
  font-size: clamp(1.4rem, 2.5vw, 1.9rem);
  color: var(--charcoal);
  margin: 0 0 1rem 0;
  line-height: 1.1;
}

.mine-footage__narrative-p{
  font-size: clamp(0.9rem, 1.1vw, 1rem);
  color: var(--charcoal-70);
  line-height: 1.65;
  margin: 0;
}

@media (max-width: 46rem){
  /* Stack narrative on mobile */
  .mine-footage__narrative-inner{
    grid-template-columns: 1fr;
    gap: 2.5rem;
  }

  .mine-footage__narrative-col{
    max-width: none;
  }
}

/* ── scroll reveal ───────────────────────────────────────── */

[data-lift]{
  opacity: 0; transform: translateY(1.1rem);
  transition: opacity .7s ease, transform .7s cubic-bezier(.2,.7,.2,1);
}
[data-lift].is-in{ opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior: auto; scroll-snap-type: none; }
  [data-lift]{ opacity: 1; transform: none; transition: none; }
}
