/* =========================================================================
   Château de Roche — shared design system
   Airy editorial (Belmond-inspired): white/bone, Montserrat, gold accent,
   full-bleed photography, thin uppercase tracked display.
   ========================================================================= */

@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('/assets/fonts/Montserrat-var.woff2') format('woff2');
}

:root {
  --paper: #ffffff;
  --bone: #f6f2ea;      /* warm off-white section fill */
  --sand: #ece5d8;      /* deeper warm band */
  --ink: #1b1712;       /* warm near-black */
  --muted: #493f36;     /* body text (darkened for readability) */
  --faint: #6f665b;     /* captions, meta */
  --line: rgba(27, 23, 18, 0.14);
  /* @brand:start */
  --gold: #182D48;      /* Alpine Midnight — the Mazots brand navy (brand drive), replaces the château gold; light backgrounds */
  --gold-light: #6A84A8; /* Glacier Blue — the brand's lighter blue, for the accent on dark/transparent backgrounds */
  /* @brand:end */
  --maroon: #5a0e07;    /* deep brand accent, sparing */
  --brick:  #8b1a12;    /* the guide's second red: actions, sparing */
  --carbon: #14110d;    /* dark section */

  --wrap: 1240px;
  --gutter: clamp(1.25rem, 5vw, 5rem);
  --nav-h: 172px;       /* fixed header height — drawings sit clear of it */

  --step: 0.16em;       /* display letter-spacing */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: 'Montserrat', system-ui, sans-serif;
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.75;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

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

/* Display headings follow edenroche.com: Montserrat 700, sentence case, tight
   negative tracking. Small UI labels (eyebrow, nav, buttons, card/footer labels)
   stay uppercase + positive tracking as accents. */
h1, h2, h3, h4 {
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.035em;
  text-transform: none;
  margin: 0;
}

p { margin: 0 0 1.15em; }

/* ---- shared type helpers -------------------------------------------------- */

.eyebrow {
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 1.4rem;
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
}
.eyebrow::before { content: none; }

.lede {
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  line-height: 1.7;
  font-weight: 400;
  color: var(--ink);
}

.muted { color: var(--muted); }

.diamond-rule {
  border: 0;
  text-align: center;
  overflow: visible;
  margin: 3.5rem auto;
  width: 100%;
}
.diamond-rule::before {
  content: '◆';
  color: var(--gold);
  font-size: 0.7rem;
  background: transparent;
  padding: 0 1rem;
  position: relative;
  top: -0.7rem;
}
.diamond-rule::after {
  content: '';
  display: block;
  border-top: 1px solid var(--line);
  margin-top: -0.35rem;
}

/* ---- layout --------------------------------------------------------------- */

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: var(--gutter); }

.section { padding-block: clamp(4rem, 9vw, 8rem); }
.section--bone { background: var(--bone); }
.section--sand { background: var(--sand); }
.section--carbon { background: var(--carbon); color: #efe9de; }
.section--carbon .muted { color: #b3aa9c; }
.section--carbon h1, .section--carbon h2, .section--carbon h3 { color: #f4efe6; }
.section--carbon .link-underline { color: #efe9de; border-bottom-color: var(--gold-light); }
.section--carbon .eyebrow, .section--carbon .eyebrow::before { color: var(--gold-light); }
/* A form dropped onto a --carbon section (the subscription page). The white
   input fields carry themselves on the dark ground; the label, button and inline
   link are the pieces that need lifting to read on it. */
.section--carbon .form label { color: #cfc7b8; }
.section--carbon .btn--gold { border-color: var(--gold-light); color: var(--gold-light); }
.section--carbon .btn--gold:hover { background: var(--gold-light); color: var(--carbon); }
.section--carbon .link-inline { color: var(--gold-light); border-bottom-color: var(--gold-light); }
.section--carbon .link-inline:hover { color: #fff; }

/* full-bleed artwork section: the painting fills the section, text sits over a
   scrim weighted to the side the copy is on, so the artwork still reads. */
.section--art { position: relative; overflow: hidden; }
.section--art__media { position: absolute; inset: 0; z-index: 0; }
.section--art__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
.section--art__media::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(90deg,
    rgba(14,11,8,0.94) 0%, rgba(14,11,8,0.86) 34%,
    rgba(14,11,8,0.46) 62%, rgba(14,11,8,0.22) 100%);
}
.section--art { min-height: 72vh; display: grid; align-items: center; }
.section--art > .wrap { position: relative; z-index: 2; }
.section--art .art__body { max-width: 34rem; }
.section--art .art__body h2 { font-size: clamp(1.7rem, 3vw, 2.6rem); margin-bottom: 1.6rem; }

/* ---- buttons -------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.7em;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  padding: 1.05em 2.2em;
  border: 1px solid var(--ink);
  color: var(--ink);
  background: transparent;
  cursor: pointer;
  /* A label breaking across two lines inside a bordered button looks like a
     mistake. The row it sits in wraps instead, which the French needs: its
     labels run about a third longer than the English. */
  white-space: nowrap;
  transition: background 0.4s var(--ease), color 0.4s var(--ease), border-color 0.4s var(--ease);
}
/* the exception is a screen too narrow for the label at all, where overflowing
   the viewport would be worse than two lines */
@media (max-width: 380px) { .btn { white-space: normal; } }
.btn:hover { background: var(--ink); color: var(--paper); }
.btn--light { border-color: rgba(255,255,255,0.7); color: #fff; }
.btn--light:hover { background: #fff; color: var(--ink); border-color: #fff; }
.btn--gold { border-color: var(--gold); color: var(--gold); }
.btn--gold:hover { background: var(--gold); color: #fff; }

.link-underline {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
  padding-bottom: 0.35em;
  border-bottom: 1px solid var(--gold);
  transition: gap 0.35s var(--ease);
}
.link-underline:hover { gap: 1.1em; }

/* ===========================================================================
   HEADER  (injected by app.js)
   =========================================================================== */

.topbar {
  background: var(--carbon);
  color: #e6ded0;
  font-size: 0.66rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-align: center;
  padding: 0.65rem 1rem;
}
.topbar a { color: var(--gold-light); }

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(255,255,255,0.94);
  backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}
/* hero pages: header overlays the hero (fixed, out of flow) */
.site-header.is-fixed {
  position: fixed;
  top: 0; left: 0; right: 0;
}
/* transparent over hero on home */
.site-header.is-transparent {
  background: transparent;
  backdrop-filter: none;
  border-bottom-color: transparent;
  color: var(--ink);
}
.site-header .topbar { transition: opacity 0.4s var(--ease); }
/* the hero is a LIGHT drawing, so the transparent header uses dark text/logo */
/* The hamburger is a button, not a link, so a rule listing only `a` left it at
   the dark ink colour while the wordmark beside it and every nav link went
   white: a black mark sitting on a photograph. */
.site-header.is-transparent .nav a,
.site-header.is-transparent .header-left a,
.site-header.is-transparent .header-right a,
.site-header.is-transparent .nav-toggle { color: #fff; }
/* monogram follows the nav's colour: white over the hero, maroon once the header is solid.
   Done as an opacity cross-fade between two PNGs (transitioning `filter` back to none
   does not settle reliably). */
.site-header.is-transparent .brand__mark { opacity: 0; }
.site-header.is-transparent .brand__mark--light { opacity: 1; }
.site-header.is-transparent .lang,
.site-header.is-transparent .nav .sep { color: var(--gold-light); }
/* over the hero, drop the topbar so the drawing has the full height */
.site-header.is-transparent .topbar { display: none; }

  /* @brand:start */
/* The home hero is a full-bleed photograph, so its transparent chrome stays
   white like the interior heroes — the generic .is-transparent rules above carry
   it. The only home-specific move is the entrance: a large centred wordmark that
   eases to the compact monogram on scroll (see the min-width:821px block below). */

  /* @brand:end */
/* Everything in the bar is absolutely positioned so the move between the two
   states (big centred wordmark + nav below  <->  small monogram left + nav
   centred inline) can be a smooth transition rather than a flex reflow. */
.site-header__bar {
  position: relative;
  height: 64px;
  padding: 0 var(--gutter);
  transition: height 0.55s var(--ease);
}
/* brand link covers the bar but is click-through; only the marks catch clicks */
.brand { position: absolute; inset: 0; display: block; pointer-events: none; }
.brand__logo, .brand__mark {
  position: absolute; top: 50%; width: auto; pointer-events: auto;
  transition: opacity 0.55s var(--ease), height 0.55s var(--ease), top 0.55s var(--ease), transform 0.55s var(--ease), filter 0.55s var(--ease);
}
/* default (scrolled/interior): monogram pinned left-middle, wordmark faded out */
  /* @brand:start */
.brand__mark { left: var(--gutter); transform: translateY(-50%); height: 34px; opacity: 1; }
/* white twin, cross-faded in over a dark hero: the same black symbol PNG, inverted */
.brand__mark--light { opacity: 0; filter: brightness(0) invert(1); }
.brand__logo { left: 50%; transform: translate(-50%, -50%); height: 44px; opacity: 0; }
  /* @brand:end */
.header-right {
  position: absolute; right: var(--gutter); top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 1.3rem;
  font-size: 0.68rem; font-weight: 600; letter-spacing: 0.2em; text-transform: uppercase;
  transition: top 0.55s var(--ease), transform 0.55s var(--ease);
}
.header-right .lang { color: var(--gold); }
.lang-switch { display: inline-flex; align-items: center; gap: 0.7rem; }

.nav {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  width: max-content; max-width: calc(100vw - 2 * var(--gutter));
  display: flex; justify-content: center; align-items: center;
  gap: clamp(1.2rem, 2vw, 2.2rem);
  transition: top 0.55s var(--ease), transform 0.55s var(--ease), opacity 0.4s var(--ease);
}
.nav a { white-space: nowrap; }

/* HOME ONLY — the entry moment: big centred wordmark, no nav. On scroll it eases
   to monogram-left + nav inline. Interior pages always use the compact header.

   Desktop only, and that matters. Below 820px .nav is not a row in the header at
   all, it is the full-screen menu behind the hamburger, and this block was still
   applying to it: `opacity: 0; pointer-events: none` meant that on the home page
   the menu opened completely invisible and unclickable, and `top: 102px` pushed
   it down the screen. The menu did open. There was simply nothing to see. */
@media (min-width: 821px) {
  body[data-page="home"] .site-header.is-fixed:not(.is-scrolled) .site-header__bar { height: 138px; }
  body[data-page="home"] .site-header.is-fixed:not(.is-scrolled) .brand__mark { opacity: 0; }
  body[data-page="home"] .site-header.is-fixed:not(.is-scrolled) .brand__logo {
    opacity: 1; top: 72px; height: clamp(62px, 7.4vw, 95px);
  }
  body[data-page="home"] .site-header.is-fixed:not(.is-scrolled) .nav { top: 102px; opacity: 0; pointer-events: none; }
  body[data-page="home"] .site-header.is-fixed:not(.is-scrolled) .header-right { top: 30px; }
}
.site-header.is-transparent .nav { border-top-color: rgba(255,255,255,0.28); }
.nav a {
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.4rem 0;
  position: relative;
  transition: color 0.3s var(--ease);
}
/* The section you are in, marked by a rule under it and nothing else. Colour
   was tried and does not carry: gold against a photograph reads as a link that
   happens to be a different colour, not as "you are here". The line inherits
   whatever the header is painting, so it is white over a hero and ink once the
   bar goes solid. */
.nav a[aria-current="page"]::after { content: ''; position: absolute;
  left: 0; right: 0; bottom: 0; height: 1px; background: currentColor; }
.nav a:hover { color: var(--gold); }
.nav .sep { color: var(--gold); font-size: 0.42rem; padding: 0 1.35rem; opacity: 0.8; }

.nav-toggle { display: none; }
.nav-close { display: none; }

/* ===========================================================================
   HERO
   =========================================================================== */

.hero {
  position: relative;
  min-height: 100vh;
  display: grid;
  place-items: center;
  text-align: center;
  color: #fff;
  overflow: hidden;
}
.hero__media, .hero__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.hero__media::after {
  content: '';
  position: absolute; inset: 0;
  /* Two layers: the vertical one holds the header and the scroll cue, the
     centred one is a light falloff so white type keeps its ground on a pale
     photograph. Together they read as the picture being lit, which a shadow
     drawn under the letters does not. */
  background:
    radial-gradient(46% 46% at 50% 46%, rgba(0,0,0,0.34) 0%, rgba(0,0,0,0.16) 55%, rgba(0,0,0,0) 78%),
    linear-gradient(180deg, rgba(0,0,0,0.42) 0%, rgba(0,0,0,0.15) 38%, rgba(0,0,0,0.5) 100%);
}

/* interior page heroes: several images cross-dissolving — and slowly drifting —
   into each other. app.js keeps the outgoing image fully opaque underneath and
   fades the incoming one in on top of it (raising its z-index), then hides the
   outgoing only once the fade is done, so a dissolve is never a see-through
   double exposure. The first image carries .is-active inline, so it shows from
   first paint with no JS and reduced-motion simply holds it still. */
.hero__media[data-hero-slideshow] img {
  opacity: 0;
  will-change: opacity, transform;
  transition: opacity 2.2s ease-in-out;
}
.hero__media[data-hero-slideshow] img.is-active {
  opacity: 1;
  animation: heroKenburns 9s ease-out both;
}
@keyframes heroKenburns {
  from { transform: scale(1); }
  to   { transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .hero__media[data-hero-slideshow] img { transition: none; animation: none; transform: none; }
}
.hero__inner { position: relative; z-index: 2; padding: 8rem 1.5rem 4rem; max-width: 60rem; }
.hero__inner .eyebrow { color: #fff; }
.hero__inner .eyebrow::before { color: var(--gold-light); }
.band .eyebrow::before { color: var(--gold-light); }
.hero h1 {
  font-size: clamp(2rem, 4.6vw, 3.4rem);
  font-weight: 700;
  letter-spacing: -0.035em;
  text-shadow: 0 2px 30px rgba(0,0,0,0.4);
}
.hero__sub {
  max-width: 34rem;
  margin: 1.8rem auto 2.6rem;
  font-weight: 400;
  font-size: 1.02rem;
  line-height: 1.7;
  text-shadow: 0 1px 3px rgba(0,0,0,0.7), 0 2px 22px rgba(0,0,0,0.6);
}
.hero__cta { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; }
/* Two French labels in a row inside the prose column came to 581px against 576
   available, so the pair stacked over five pixels. Slightly tighter side
   padding on a button that shares its row buys 23px and keeps them level, and
   only applies where there is a neighbour, so a lone button is untouched. */
.hero__cta .btn:not(:only-child) { padding-inline: 1.7em; }
/* Below this the labels genuinely do not fit side by side, and stacking is
   right rather than a failure. */
@media (max-width: 620px) {
  .hero__cta .btn:not(:only-child) { padding-inline: 2.2em; }
}

.scroll-cue {
  position: absolute;
  bottom: 2rem; left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  width: 44px; height: 44px;
  border: 1px solid rgba(255,255,255,0.6);
  border-radius: 50%;
  background: rgba(25,20,15,0.28);
  backdrop-filter: blur(2px);
  display: grid; place-items: center;
  color: #fff;
  cursor: pointer;
  animation: bob 2.4s var(--ease) infinite;
}
@keyframes bob { 0%,100%{ transform: translate(-50%, 0);} 50%{ transform: translate(-50%, 8px);} }

/* ===========================================================================
   EDITORIAL BLOCKS
   =========================================================================== */

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 6vw, 5.5rem);
  align-items: center;
}
.split--wide-text { grid-template-columns: 1.1fr 0.9fr; }
/* for sections where the photograph should lead: wider, taller media column */
.split--wide-media { grid-template-columns: 1.5fr 1fr; gap: clamp(2rem, 4.5vw, 4rem); }
.split--wide-media .split__media img { aspect-ratio: 5 / 4; }
.split__media img { width: 100%; height: 100%; object-fit: cover; }
.split__body h2 { font-size: clamp(1.7rem, 3vw, 2.6rem); margin-bottom: 1.6rem; }

.figure-caption { font-size: 0.66rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--faint); margin-top: 0.9rem; }

/* engraving showcase (sepia line art on bone) */
.engraving { background: var(--bone); }
.engraving img { mix-blend-mode: multiply; }

/* ---- label reveal: façade holds; cutaway wipes in from the bottom on scroll --
   A tall section with a pinned stage; the façade sits behind, the cutaway (same
   framing, building locked) is clipped from the top and revealed upward from the
   bottom as you scroll — so the top of the cutaway appears last. */
.label-media { position: absolute; inset: 0; z-index: 0; }
.label-reveal { position: relative; height: 220vh; background: #f9f6f0; }
.label-reveal .label-sticky {
  position: sticky; top: 0;
  height: 100vh;
  min-height: 0;
}
.label-back {
  clip-path: inset(100% 0 0 0);   /* start fully clipped; JS reveals from bottom */
  will-change: clip-path;
}
/* reduced-motion: no wipe — just show the cutaway */
.label-reveal.is-static .label-back { clip-path: inset(0 0 0 0); }
.label-face {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;               /* full-bleed */
  object-position: center 68%;     /* bias down so the building sits higher in frame (no nav to clear); same anchor on both faces keeps the roofs aligned */
  transform: scale(1.16);          /* zoom in past the cream margins: bigger, wider, taller */
  transform-origin: center center; /* identical on both faces, so the building stays registered */
  will-change: opacity;
}
/* lift + soften the engraving on the hero so the title reads cleanly on top */
.hero .label-face { filter: brightness(1.14) contrast(0.78); }
/* soft scrim across the very top only, so the white logo + nav read against the
   light drawing; fades to nothing well before the building so the hero stays airy */
.hero__veil {
  display: block;
  position: absolute; left: 0; right: 0; top: 0; height: 34vh;
  background: linear-gradient(180deg, rgba(24,18,12,0.42) 0%, rgba(24,18,12,0.18) 40%, transparent 100%);
  pointer-events: none;
  z-index: 1;
}
[data-hero-fade] { will-change: opacity; }

/* Accessible/SEO-only text: read by search engines and screen readers, unseen
   on screen. Used for the home page's <h1>, whose wordmark lives in the artwork. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* share this event: a small, left-aligned row at the top of the first section.
   Plain intent links + copy-link, no third-party scripts. */
.share { margin-bottom: 1.8rem; }
.share__label {
  font-size: 0.62rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--faint); margin-bottom: 0.7rem;
}
.share__row { display: flex; gap: 0.5rem; justify-content: flex-start; flex-wrap: wrap; }
.share__link {
  display: grid; place-items: center;
  width: 34px; height: 34px; padding: 0;
  border: 1px solid rgba(21, 0, 109, 0.16);
  border-radius: 50%;
  color: var(--ink); background: transparent;
  cursor: pointer; text-decoration: none;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.share__link svg { width: 15px; height: 15px; display: block; }
.share__link:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.share__copy.is-copied { border-color: var(--gold); color: var(--gold); background: transparent; }

/* ---- estate grid (cards to sections) ------------------------------------- */

.estate-head { text-align: center; max-width: 44rem; margin: 0 auto clamp(2.5rem, 5vw, 4rem); }
.estate-head h2 { font-size: clamp(1.8rem, 3.2vw, 2.8rem); margin-bottom: 1.3rem; }

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.5rem;
}
.card { position: relative; display: block; overflow: hidden; aspect-ratio: 3 / 4; background: var(--sand); }
.card img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease);
}
.card:hover img { transform: scale(1.06); }
.card::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0) 34%, rgba(0,0,0,0.28) 62%, rgba(0,0,0,0.74) 100%);
}
.card__label {
  position: absolute; left: 0; right: 0; bottom: 0;
  z-index: 2;
  padding: 1.6rem 1.5rem;
  color: #fff;
  text-align: center;
}
.card__label .eyebrow { color: rgba(255,255,255,0.8); margin: 0 0 0.5rem; }
.card__label h3 { font-size: 1.15rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; }

/* ---- full-bleed quote band ----------------------------------------------- */

.band {
  position: relative;
  min-height: 68vh;
  display: grid;
  place-items: center;
  text-align: center;
  color: #fff;
  overflow: hidden;
}
.band__media, .band__media img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.band__media::after { content: ''; position: absolute; inset: 0; background: rgba(0,0,0,0.4); }
.band__inner { position: relative; z-index: 2; max-width: 46rem; padding: 3rem 1.5rem; }
.band blockquote {
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  font-weight: 600;
  line-height: 1.32;
  letter-spacing: -0.02em;
  text-transform: none;
  text-shadow: 0 2px 24px rgba(0,0,0,0.4);
}
.band cite { display: block; margin-top: 1.8rem; font-size: 0.68rem; letter-spacing: 0.28em; text-transform: uppercase; font-style: normal; color: rgba(255,255,255,0.85); }

/* Engraved-plate variant: the band's 40% black scrim is built for a photograph
   and turns a pale print to mud. Here a cream veil lifts the paper instead and
   the type goes to ink, so the plate reads as a print rather than a dimmed photo. */
.band--plate { color: var(--muted); }
.band--plate .band__media::after { background: rgba(244,240,232,0.74); }
.band--plate .band__media img { object-position: center 42%; }
/* the quote sits in the engraving's own sepia rather than near-black: at this
   size a hard ink weight fights the plate instead of resting on it */
.band--plate blockquote {
  color: var(--faint); font-weight: 500;
  text-shadow: 0 1px 18px rgba(244,240,232,0.9);
}
.band--plate .eyebrow, .band--plate .eyebrow::before { color: var(--faint); }
.band--plate cite { color: var(--faint); }

/* ---- interior page hero --------------------------------------------------- */

/* full viewport, like the home hero. svh keeps it honest on mobile, where the
   address bar makes 100vh taller than the space actually visible. */
.hero--page { min-height: 100vh; min-height: 100svh; }
.hero--page .hero__inner { padding: 7rem 1.5rem 5rem; }
.hero--page h1 { font-size: clamp(2.2rem, 5vw, 3.8rem); }

/* ---- room / parcel rows (alternating split) ------------------------------- */

.row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 4.5rem); align-items: center; }
.row + .row { margin-top: clamp(3.5rem, 7vw, 6rem); }
.row--flip .row__media { order: 2; }
.row__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.row__body h3 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin-bottom: 1.1rem; }

/* a brand logo standing in for the page title */
.hero__logo { margin: 0; line-height: 0; }
.hero__logo img { width: min(30rem, 72vw); height: auto; display: inline-block; }


/* a link inside running copy: underlined in the text's own colour */
.link-inline {
  color: inherit;
  border-bottom: 1px solid var(--gold);
  padding-bottom: 1px;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.link-inline:hover { color: var(--gold); }

/* ---- getting here: centred travel tables --------------------------------- */

.travel { max-width: 56rem; margin-inline: auto; text-align: center; }
.travel h3 { font-size: 1.1rem; }
.travel .facts { justify-items: center; }
.travel .facts dt { color: var(--gold); }
.travel__air { max-width: 44rem; margin-inline: auto; text-align: center; }

/* ---- map band: the map fills the section, a card sits over it ------------ */

/* 1fr, or the auto column shrinks to the card and centres it over the marker */
.map-band { position: relative; overflow: hidden; min-height: 78vh;
            display: grid; grid-template-columns: 1fr; align-items: center; }
.map-band__media { position: absolute; inset: 0; z-index: 0; }
.map-band__media img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* The live Apple map fades in over the static image once its token is minted;
   until then (or if MapKit is unreachable) the image below is what shows. */
.map-band__map { position: absolute; inset: 0; z-index: 1; opacity: 0;
                 transition: opacity .8s ease; }
.map-band__map.is-ready { opacity: 1; }
/* Apple draws its own attribution on the live map, so drop the image credit. */
.map-band.map-live .map-band__credit { display: none; }
/* width:100% or the grid item sizes to its content and drifts to the middle */
.map-band > .wrap { position: relative; z-index: 2; width: 100%; }
.map-card {
  max-width: 26rem;
  /* semi-transparent: the map reads through, the copy stays legible. The blur
     carries most of the legibility, which is what lets the fill go this light. */
  background: rgba(255,255,255,0.46);
  backdrop-filter: saturate(1.1) blur(4px);
  padding: clamp(1.8rem, 3.5vw, 2.6rem);
}
.map-card h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); margin: 0.5rem 0 1rem; }
.map-card__addr { font-size: 0.92rem; line-height: 1.9; margin: 1.2rem 0 1.4rem; }
.map-band__credit {
  position: absolute; right: var(--gutter); bottom: 0.7rem; z-index: 2;
  font-size: 0.62rem; letter-spacing: 0.08em; color: var(--faint);
  background: rgba(255,255,255,0.7); padding: 0.2rem 0.5rem;
}
@media (max-width: 700px) { .map-card { max-width: none; } }

/* ---- section submenu: jump links, sticky under the header ----------------- */

.submenu {
  position: sticky; top: 64px; z-index: 20;
  background: rgba(255,255,255,0.94); backdrop-filter: saturate(1.4) blur(10px);
  border-bottom: 1px solid var(--line);
}
.submenu__inner {
  display: flex; gap: clamp(1.1rem, 2.4vw, 2.2rem); align-items: center;
  padding: 0.9rem var(--gutter);
  /* Wrap rather than scroll. With overflow-x:auto and no scrollbar, a long
     submenu simply hid its last items with nothing to show they were there. */
  flex-wrap: wrap; row-gap: 0.35rem;
  justify-content: center;
  /* `safe` falls back to flex-start when the row overflows, so the first items
     stay reachable when it scrolls on narrow screens */
  justify-content: safe center;
}
.submenu__inner::-webkit-scrollbar { display: none; }
.submenu a {
  white-space: nowrap; font-size: 0.66rem; font-weight: 600; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--faint);
  padding: 0.2rem 0; border-bottom: 1px solid transparent;
  transition: color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.submenu a:hover { color: var(--ink); }
.submenu a.is-current { color: var(--gold); border-bottom-color: var(--gold); }
/* anchor targets clear the fixed header + submenu */
.room { scroll-margin-top: 128px; }

/* ---- space: full-bleed image carousel on one side, copy on the other ------ */

.space { display: grid; grid-template-columns: 1.2fr 1fr; align-items: center;
         gap: clamp(2rem, 5vw, 5rem); }
.space + .space { margin-top: clamp(4.5rem, 9vw, 8rem); }

.space__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--bone); }
.space__media img { position: absolute; inset: 0; width: 100%; height: 100%;
                    object-fit: cover; opacity: 0; transition: opacity 0.9s var(--ease); }
.space__media img.is-active { opacity: 1; }

.space__nav { position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
              width: 44px; height: 44px; border-radius: 50%; cursor: pointer;
              display: grid; place-items: center;
              background: rgba(255,255,255,0.86); border: 0; color: var(--ink);
              opacity: 0; transition: opacity 0.3s var(--ease), background 0.3s var(--ease); }
.space__media:hover .space__nav, .space__nav:focus-visible { opacity: 1; }
.space__nav:hover { background: #fff; }
.space__nav--prev { left: 1rem; }
.space__nav--next { right: 1rem; }

.space__body { max-width: 34rem; }
.space__body h3 { font-size: clamp(1.5rem, 2.6vw, 2.1rem); margin: 0.6rem 0 1.2rem; }
.space__body .muted { margin-bottom: 0; }

.space__dots { display: flex; gap: 0.7rem; margin-top: 1.8rem; }
.space__dots button { width: 9px; height: 9px; padding: 0; border: 0; cursor: pointer;
                      background: var(--line); transform: rotate(45deg);
                      transition: background 0.3s var(--ease); }
.space__dots button.is-active { background: var(--gold); }
.space__count { font-size: 0.68rem; letter-spacing: 0.2em; color: var(--faint);
                margin-top: 1.4rem; }

/* the image bleeds to the page edge, the copy keeps the gutter */
.spaces { padding-inline: 0; max-width: none; }
.spaces .space__body { padding-right: var(--gutter); }
.spaces .space--flip { direction: rtl; }
.spaces .space--flip > * { direction: ltr; }
.spaces .space--flip .space__body { padding-right: 0; padding-left: var(--gutter); }

@media (max-width: 900px) {
  .space { grid-template-columns: 1fr; gap: 1.6rem; }
  .spaces .space__body, .spaces .space--flip .space__body {
      padding-inline: var(--gutter); }
  .spaces .space--flip { direction: ltr; }
  .space__nav { opacity: 1; }
}

/* ---- photo gallery grid --------------------------------------------------- */

.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 0.9rem; }
.gallery img { width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover; display: block; transition: opacity 0.4s var(--ease); }
.gallery a:hover img, .gallery img:hover { opacity: 0.86; }

/* ---- timeline (history) --------------------------------------------------- */

.era { margin-top: clamp(3rem, 6vw, 4.5rem); scroll-margin-top: 128px; }
.era__head { border-bottom: 1px solid var(--line); padding-bottom: 1rem; margin-bottom: 2.4rem; }
.era__head h2 { font-size: clamp(1.4rem, 2.4vw, 1.9rem); margin: 0; }

/* One continuous line per era rather than a border on each item, so it can carry
   a gradient: gold at the era's first entry, settling to a hairline, then
   dissolving before the last. Sits where the old 1px border sat (x = 0 to 1). */
.timeline { list-style: none; margin: 0; padding: 0; position: relative; }
.timeline::before {
  content: ''; position: absolute; left: 0; top: 4px; bottom: 0.5rem; width: 1px;
  background: linear-gradient(180deg,
    var(--gold) 0, var(--line) 14%, var(--line) 74%, transparent 100%);
}
.timeline li { position: relative; padding: 0 0 2.2rem 2.2rem; }
.timeline li:last-child { padding-bottom: 0; }
/* The line box is 1.02rem x 1.35 = 22px, so its exact centre is 11px. The dot
   sits half a pixel below that: the heading's cap band centres at 10.7px but its
   lowercase mass centres at 12.8px, and the eye splits the two. Geometric centre
   alone reads as too high. left = 0.5 (line centre) - 5 (half the dot). */
.timeline li::before {
  content: ''; position: absolute; left: -4.5px; top: 6.5px;
  width: 10px; height: 10px; border-radius: 50%; background: var(--gold);
}
.timeline h3 { font-size: 1.02rem; line-height: 1.35; margin: 0 0 0.6rem; letter-spacing: -0.01em; }
.timeline p { margin: 0; color: var(--muted); font-size: 0.94rem; line-height: 1.75; }

/* ---- spec / fact lists ---------------------------------------------------- */

.spec { font-size: 0.68rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold); margin-bottom: 0.7rem; }
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)); gap: 2rem 2.5rem; }
.facts dt { font-size: 0.68rem; letter-spacing: 0.22em; text-transform: uppercase; color: var(--gold); margin-bottom: 0.5rem; }
.facts dd { margin: 0 0 0.2rem; font-size: 0.95rem; color: var(--muted); line-height: 1.7; }
.facts--tight dd { font-size: 0.9rem; }

/* ---- cuvée cards ---------------------------------------------------------- */

.cuvees { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 1.6rem; }
/* Solid white cards sat on the label like five stickers and hid the drawing
   exactly where it is most legible. Letting it through keeps the watermark
   continuous across the section, which was the point of putting it there. */
.cuvee { border: 1px solid var(--line); padding: 2rem 1.5rem; background: rgba(255,255,255,0.55); text-align: center; }
.cuvee h3 { font-size: 1.15rem; margin: 0 0 0.35rem; }
/* the grape/site line reads as one unit, so never break it across lines */
.cuvee .spec { margin-bottom: 1rem; white-space: nowrap; font-size: 0.6rem; letter-spacing: 0.12em; }
.cuvee p { margin: 0; font-size: 0.9rem; color: var(--muted); line-height: 1.7; }

/* ---- contact form --------------------------------------------------------- */

.form { display: grid; gap: 1.1rem; max-width: 34rem; }
.form label { display: block; font-size: 0.66rem; letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint); margin-bottom: 0.45rem; }
.form input, .form textarea {
  width: 100%; font: inherit; font-size: 0.95rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line);
  padding: 0.8rem 0.9rem; border-radius: 0;
  transition: border-color 0.3s var(--ease);
}
.form input:focus, .form textarea:focus { outline: none; border-color: var(--gold); }
.form textarea { min-height: 9rem; resize: vertical; }
.form__note { font-size: 0.8rem; color: var(--faint); }
.form__status { font-size: 0.88rem; min-height: 1.2rem; }
.form__status.is-err { color: #a1442f; }
.form__status.is-ok { color: var(--gold); }

/* ===========================================================================
   FOOTER  (injected by app.js)
   =========================================================================== */

.site-footer { background: var(--carbon); color: #cfc7b8; padding-block: clamp(3.5rem, 6vw, 5rem);
  position: relative; overflow: hidden; }
/* monogram watermark, bottom-right. Bled off the corner so it reads as a mark
   pressed into the page rather than a placed logo. */
.site-footer::after {
  content: ''; position: absolute; pointer-events: none;
  right: clamp(0.75rem, 3vw, 3rem); bottom: clamp(0.5rem, 1.5vw, 1.5rem);
  /* @brand:start */
  width: clamp(220px, 24vw, 380px); aspect-ratio: 2500 / 1743;
  /* the LMDC symbol, filled white via a mask so a black-on-transparent PNG reads
     as a pale watermark pressed into the dark ground */
  -webkit-mask: url('/assets/img/logo/symbol-black.png') no-repeat right bottom / contain;
  mask: url('/assets/img/logo/symbol-black.png') no-repeat right bottom / contain;
  background: #fff;
  opacity: 0.06;
  /* @brand:end */
}
.site-footer > .wrap { position: relative; z-index: 1; }
.site-footer a { color: #cfc7b8; transition: color 0.3s var(--ease); }
.site-footer a:hover { color: var(--gold); }
/* Flex, not grid, because the number of columns changes. It was a grid fixed at
   brand plus three, so adding a fourth dropped Visit onto a row of its own; and
   `repeat(auto-fit, ...)` is not a fix, because it may not be combined with a
   flexible track like the brand's, so the whole declaration is discarded and you
   get one column. Flex counts what is there and wraps when it runs out of room. */
/* One grid for the whole footer, so the copyright row lands on the same columns
   as the menus above it. As two separate flex rows they agreed on nothing: the
   columns began at 77, 412, 684 and 955, and the legal links began at 517. */
.site-footer { --footer-cols: 1.5fr 1fr 1fr 1fr; }
.footer-grid,
.footer-bottom {
  display: grid;
  grid-template-columns: var(--footer-cols);
  gap: clamp(1.6rem, 3vw, 2.5rem);
}
/* inline-block so the anchor is the size of the logo and not the line box
   around it: a link you can click above and below the mark is a link that feels
   broken even when it works. */
.footer-brand__link { display: inline-block; }
  /* @brand:start */
.footer-brand__logo { height: 84px; filter: none; opacity: 0.92;
  /* @brand:end */
  transition: opacity 0.3s var(--ease); display: block; }
.footer-brand__link:hover .footer-brand__logo { opacity: 1; }
/* Instagram and Spotify, as plain inline-SVG links: no third-party script, so
   nothing loads until the visitor clicks, and the privacy page stays true. */
.footer-social { display: flex; gap: 0.85rem; }
.footer-social a { display: inline-flex; color: #8b8375; transition: color 0.3s var(--ease); }
.footer-social a:hover { color: var(--gold-light); }
/* Social icons and the language toggle share the last cell of the bottom bar,
   icons first, so the switch sits hard against the right edge, where the header
   puts it too. */
.footer-end { grid-column: 4; grid-row: 1; justify-self: end; display: flex; align-items: center; gap: 1.3rem; }
.footer-col h4 { font-size: 0.68rem; font-weight: 500; letter-spacing: 0.24em; text-transform: uppercase; color: var(--gold-light); margin-bottom: 1.2rem; }
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 0.7rem; font-size: 0.82rem; letter-spacing: 0.06em; }
.footer-bottom {
  margin-top: 3rem;
  align-items: baseline;
  /* The bar's column gap is generous by design; its rows are two lines of the
     same small print and want no more than a line's worth between them. */
  row-gap: 0.75rem;
  font-size: 0.68rem; letter-spacing: 0.16em; text-transform: uppercase; color: #8b8375;
}

/* ===========================================================================
   MOTION
   =========================================================================== */

.reveal { opacity: 0; transform: translateY(26px); transition: opacity 1s var(--ease), transform 1s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

/* ===========================================================================
   RESPONSIVE
   =========================================================================== */

@media (max-width: 900px) {
  /* narrow: the copy sits over the whole width, so darken from the bottom instead */
  .section--art__media::after {
    background: linear-gradient(180deg, rgba(14,11,8,0.55) 0%, rgba(14,11,8,0.86) 55%, rgba(14,11,8,0.94) 100%);
  }
  .section--art .art__body { max-width: none; }
  .row { grid-template-columns: 1fr; }
  .row--flip .row__media { order: 0; }
  .split, .split--wide-text { grid-template-columns: 1fr; }
  .split__media { order: -1; }
  .cards { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 820px) {
  :root { --nav-h: 118px; }
  .nav { display: none; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    background: none; border: 0; cursor: pointer; padding: 0.4rem;
    color: inherit;
  }
  .nav-toggle svg { width: 26px; height: 26px; }
  /* The desktop .nav is centred with left/top 50% and a translate, and sized to
     its content. Going full screen overrode position and inset but not those
     two, so the open menu came out 187px wide in a 375px viewport and shifted
     half its own size up and left: off screen, which is why it looked like
     nothing happened at all. Both have to be undone here. */
  .nav.is-open {
    display: flex; flex-direction: column; gap: 0.4rem;
    position: fixed; inset: 0; z-index: 60;
    transform: none;
    width: auto; max-width: none;
    background: var(--carbon); color: #fff;
    justify-content: center; align-items: center;
    border: 0;
  }
  /* .site-header carries backdrop-filter once it goes solid, and a filtered
     element is a containing block, so the menu's `fixed; inset: 0` was resolving
     against the header bar rather than the viewport: a black strip at the top
     with the links spilling white-on-white onto the page below. At the top of a
     page the header is .is-transparent and sets backdrop-filter: none, so the
     same menu opened correctly there. That is why it only broke after
     scrolling. Dropping the filter while the menu is open costs nothing, since
     the header is behind a full-screen overlay. */
  body.nav-open .site-header { backdrop-filter: none; }
  body.nav-open { overflow: hidden; }
  .nav.is-open a { color: #fff; font-size: 1rem; padding: 0.7rem; }
  .nav.is-open .sep { display: none; }
  .nav.is-open .nav-close { display: block; position: fixed; top: 1.4rem; right: 1.4rem; z-index: 61; background: none; border: 0; color: #fff; cursor: pointer; }
}

@media (max-width: 560px) {
  .cards { grid-template-columns: 1fr; }
  .hero { min-height: 88vh; }
}

@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .scroll-cue { animation: none; }
  .card:hover img { transform: none; }
}

/* ===========================================================================
   LEGAL PAGES  (mentions-legales, confidentialite, conditions)
   Bilingual: French first, English after. No hero — these are documents.
   =========================================================================== */

.legal-head { padding-block: clamp(4rem, 8vw, 6.5rem) clamp(2rem, 4vw, 3rem); background: var(--bone); }
.legal-head h1 { font-size: clamp(1.9rem, 4vw, 3rem); }
.legal-head .muted { max-width: 42rem; margin-top: 1.2rem; }
.legal .legal-lang, .legal-lang { display: flex; gap: 1.1rem; margin-top: 1.8rem;
  font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 500; color: var(--faint); }
.legal .legal-lang a, .legal-lang a { border-bottom: 1px solid var(--gold);
  padding-bottom: 0.25em; color: var(--faint); font-size: inherit; }
.legal .legal-lang a:hover { color: var(--ink); }

.legal { max-width: 46rem; margin-inline: auto; }
.legal h2 { font-size: clamp(1.25rem, 2.2vw, 1.6rem); margin: 3.2rem 0 1rem; }
.legal h2:first-of-type { margin-top: 0; }
.legal h3 { font-size: 0.98rem; margin: 2rem 0 0.5rem; }
.legal p, .legal li { color: var(--muted); font-size: 0.95rem; line-height: 1.85; }
.legal ul { padding-left: 1.15rem; margin: 0 0 1.15em; }
.legal li { margin-bottom: 0.45rem; }
.legal a:not(.btn) { border-bottom: 1px solid var(--gold); }

/* identity block: label above value, same idiom as the fact lists */
.legal dl { margin: 0 0 1.5rem; }
.legal dt { font-size: 0.64rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--faint); margin-top: 1.3rem; }
.legal dd { margin: 0.25rem 0 0; color: var(--muted); font-size: 0.95rem; }

/* Unfilled facts. Deliberately loud: these must not reach production unnoticed. */
.todo { background: rgba(154,123,79,0.18); border-bottom: 1px dashed var(--gold);
  padding: 0.05em 0.35em; color: var(--ink); font-weight: 600; font-style: normal; }

.legal__updated { font-size: 0.82rem; color: var(--faint); margin-top: 3.5rem;
  padding-top: 1.5rem; border-top: 1px solid var(--line); }
.legal__divider { margin: clamp(4rem, 8vw, 6rem) 0; border: 0; border-top: 1px solid var(--line); }

.footer-legal {
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  /* under Discover and What's on, where the eye already has a left edge */
  grid-column: 2 / 4;
}
/* Shown only in the English footer, where these three links lead to pages that
   are French by decision. Quiet enough to read as a note, not a warning. */
.footer-legal__fr {
  font-size: 0.68em;
  letter-spacing: 0.12em;
  opacity: 0.55;
  margin-left: 0.15em;
}


@media (prefers-reduced-motion: reduce) {
  * { scroll-behavior: auto !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
  .scroll-cue { animation: none; }
  .card:hover img { transform: none; }
}

/* ===========================================================================
   LEGAL PAGES  (mentions-legales, confidentialite, conditions)
   Bilingual: French first, English after. No hero — these are documents.
   =========================================================================== */

.legal-head { padding-block: clamp(4rem, 8vw, 6.5rem) clamp(2rem, 4vw, 3rem); background: var(--bone); }
.legal-head h1 { font-size: clamp(1.9rem, 4vw, 3rem); }
.legal-head .muted { max-width: 42rem; margin-top: 1.2rem; }
.legal .legal-lang, .legal-lang { display: flex; gap: 1.1rem; margin-top: 1.8rem;
  font-size: 0.58rem; letter-spacing: 0.16em; text-transform: uppercase;
  font-weight: 500; color: var(--faint); }
.legal .legal-lang a, .legal-lang a { border-bottom: 1px solid var(--gold);
  padding-bottom: 0.25em; color: var(--faint); font-size: inherit; }
.legal .legal-lang a:hover { color: var(--ink); }

.legal { max-width: 46rem; margin-inline: auto; }
.legal h2 { font-size: clamp(1.25rem, 2.2vw, 1.6rem); margin: 3.2rem 0 1rem; }
.legal h2:first-of-type { margin-top: 0; }
.legal h3 { font-size: 0.98rem; margin: 2rem 0 0.5rem; }
.legal p, .legal li { color: var(--muted); font-size: 0.95rem; line-height: 1.85; }
.legal ul { padding-left: 1.15rem; margin: 0 0 1.15em; }
.legal li { margin-bottom: 0.45rem; }
.legal a:not(.btn) { border-bottom: 1px solid var(--gold); }

/* identity block: label above value, same idiom as the fact lists */
.legal dl { margin: 0 0 1.5rem; }
.legal dt { font-size: 0.64rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: var(--faint); margin-top: 1.3rem; }
.legal dd { margin: 0.25rem 0 0; color: var(--muted); font-size: 0.95rem; }

/* Unfilled facts. Deliberately loud: these must not reach production unnoticed. */
.todo { background: rgba(154,123,79,0.18); border-bottom: 1px dashed var(--gold);
  padding: 0.05em 0.35em; color: var(--ink); font-weight: 600; font-style: normal; }

.legal__updated { font-size: 0.82rem; color: var(--faint); margin-top: 3.5rem;
  padding-top: 1.5rem; border-top: 1px solid var(--line); }
.legal__divider { margin: clamp(4rem, 8vw, 6rem) 0; border: 0; border-top: 1px solid var(--line); }

.footer-legal {
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  /* under Discover and What's on, where the eye already has a left edge */
  grid-column: 2 / 4;
}
/* Shown only in the English footer, where these three links lead to pages that
   are French by decision. Quiet enough to read as a note, not a warning. */
.footer-legal__fr {
  font-size: 0.68em;
  letter-spacing: 0.12em;
  opacity: 0.55;
  margin-left: 0.15em;
}
/* ---- the language switch, bottom right ------------------------------------
   The same two letters as the top right, on the same line as the legal links,
   so it sits where the eye has already learned to look for it. */
.footer-switch { display: inline-flex; align-items: center; gap: 0.7rem; }
.footer-switch__link {
  font-size: 0.72rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--gold-light);
  padding: 0.4rem 0.35rem;
  margin: -0.4rem -0.35rem;
}
.footer-switch__link:hover { color: rgb(207,199,184); }


/* Below this the four columns cannot hold their names, so the whole footer goes
   to two and then to one, and the bottom row stacks with them. */
@media (max-width: 900px) {
  .site-footer { --footer-cols: 1fr 1fr; }
  /* Copyright and switch share the first row, legal takes the second. Left to
     auto-placement the spanning legal block pushed the switch onto a third. */
  .footer-legal { grid-column: 1 / 3; grid-row: 2; }
  .footer-end { grid-column: 2; grid-row: 1; }
}
@media (max-width: 560px) {
  /* The three link lists still fit two columns on a phone: the longest name is
     "Événements" and it does not wrap at 160px. One column made the footer a
     very long scroll and gained nothing. The logo spans both, and the bottom
     row keeps its own single column, because a copyright, the legal links and a
     language switch side by side at this width is cramped. */
  .footer-grid { grid-template-columns: 1fr 1fr; column-gap: 1.4rem; }
  .footer-brand { grid-column: 1 / -1; }
  /* Three lists in two columns leaves the third alone in a 156px cell, where
     "Restaurant Jeannette" and "Organiser votre événement" both wrap onto two
     lines beside an empty cell. Full width, they fit on one line each. */
  .footer-col:last-of-type { grid-column: 1 / -1; }
  .footer-bottom { grid-template-columns: 1fr; gap: 0.9rem; }
  .footer-legal, .footer-end, .footer-place, .footer-sisters { grid-column: 1; grid-row: auto; }
  .footer-end { justify-self: start; }
}

/* A film on an event page, given its own wide section (.section--film) rather
   than being forced out of the 44rem text column, which misaligned it. It fills
   that wrap, keeps a black ground while it loads, and is only fetched once the
   visitor presses play. The wrap is capped near the film's native width so it
   never upscales and softens. */
.section--film { padding-block: clamp(1.5rem, 4vw, 2.8rem); }
.event-video video { display: block; width: 100%; height: auto; background: #000;
  border-radius: 2px; }

/* empty state for the Current Events feed */
.event-empty { margin-top: 1.5rem; }
.event-empty p { margin-bottom: 1.6rem; }

/* ---- cookie consent bar --------------------------------------------------
   Hidden entirely while no category is enabled (the bar is never built).
   Refuse and Accept are the same size and weight on purpose: under CNIL rules
   refusing must be as easy as accepting, so neither may be visually demoted. */
.cookie-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 200;
  background: rgba(255,255,255,0.97);
  backdrop-filter: saturate(1.3) blur(10px);
  border-top: 1px solid var(--line);
  box-shadow: 0 -12px 40px rgba(27,23,18,0.10);
}
/* Author `display` beats the UA [hidden] rule, so the customise panel and Save
   button stayed visible. Restore hiding inside the bar. */
.cookie-bar [hidden] { display: none !important; }
/* Single column: with bilingual labels the four buttons have a huge max-content
   width, and an `auto` track sized to it, collapsing the text to a sliver. */
.cookie-bar__inner {
  max-width: var(--wrap); margin-inline: auto; padding: 1.5rem var(--gutter);
  display: grid; gap: 1.2rem;
}
.cookie-bar__text { max-width: 64rem; }
.cookie-bar__text p { margin: 0 0 0.35em; font-size: 0.88rem; line-height: 1.7; color: var(--muted); }
.cookie-bar__text p:last-child { margin-bottom: 0; }
.cookie-bar__text a { border-bottom: 1px solid var(--gold); }
.cookie-bar__actions { display: flex; align-items: center; gap: 0.8rem; flex-wrap: wrap; }
.cookie-btn { font-size: 0.62rem; padding: 0.85em 1.5em; white-space: nowrap; }
.cookie-link {
  background: none; border: 0; cursor: pointer; font: inherit; font-size: 0.62rem;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--faint);
  border-bottom: 1px solid var(--line); padding: 0 0 0.3em;
}
.cookie-link:hover { color: var(--ink); border-bottom-color: var(--gold); }
.cookie-bar__cats { margin-top: 1.1rem; display: grid; gap: 0.9rem; }
.cookie-cat { display: flex; gap: 0.7rem; align-items: start; font-size: 0.84rem;
  line-height: 1.6; color: var(--muted); cursor: pointer; }
.cookie-cat input { margin-top: 0.3rem; accent-color: var(--gold); flex: none; }
@media (max-width: 780px) {
  .cookie-bar__inner { grid-template-columns: 1fr; }
  .cookie-bar { max-height: 80vh; overflow-y: auto; }
}

/* ---- event cards ----------------------------------------------------------
   Reuses .cards/.card, but four across and with a line of copy under the title,
   so the Annual Events list reads as images rather than a definition list. */
.cards--4 { grid-template-columns: repeat(4, 1fr); }
.card__label p {
  margin: 0.55rem 0 0; font-size: 0.8rem; line-height: 1.6; font-weight: 400;
  letter-spacing: 0; text-transform: none; color: rgba(255,255,255,0.88);
}
.card__label p a { border-bottom: 1px solid rgba(255,255,255,0.6); }
/* cards that are not links should not invite a click */
.card:not(a) { cursor: default; }
.card:not(a):hover img { transform: none; }
/* the taller label needs more room to clear the gradient */
.cards--4 .card__label { padding: 1.4rem 1.2rem; }
.cards--4 .card::after {
  background: linear-gradient(180deg, rgba(0,0,0,0) 22%, rgba(0,0,0,0.36) 52%, rgba(0,0,0,0.82) 100%);
}
@media (max-width: 1000px) { .cards--4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .cards--4 { grid-template-columns: 1fr; } }

/* the Current Events empty state is a short announcement, not a full chapter */
.section--tight { padding-block: clamp(2.75rem, 5vw, 4.5rem); }

/* ---- editions list (one row per year of a recurring event) ----------------- */
.editions { list-style: none; margin: 2rem 0 0; padding: 0; }
.editions li { border-top: 1px solid var(--line); }
.editions li:last-child { border-bottom: 1px solid var(--line); }
.editions a {
  display: grid; grid-template-columns: 5rem 1fr auto; gap: 1.5rem; align-items: baseline;
  padding: 1.15rem 0; transition: color 0.3s var(--ease);
}
.editions a:hover { color: var(--gold); }
.editions__year { font-size: 0.7rem; letter-spacing: 0.2em; color: var(--gold); font-weight: 600; }
.editions__title { font-size: 0.98rem; }
.editions__date { font-size: 0.78rem; color: var(--faint); white-space: nowrap; }
@media (max-width: 560px) {
  .editions a { grid-template-columns: 1fr; gap: 0.3rem; }
  .editions__date { white-space: normal; }
}

/* the body paragraph has margin-bottom:0, so the link needs its own separation */
.space__body .link-underline { margin-top: 1.9rem; }

/* ---- what is on right now -------------------------------------------------
   Replaces .event-empty when there is something to announce. Two abreast on a
   wide screen, stacked below; the copy reads left even though the heading above
   it is centred. */
.now__item h3 { font-size: 1.15rem; margin: 0 0 0.7rem; }
.now__item .eyebrow { margin-bottom: 0.6rem; }
.now__item .muted { font-size: 0.92rem; margin-bottom: 0; }
.now__item i { font-style: italic; }
.now__item img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; margin-bottom: 1.2rem; }

/* ---- rail: a row that scrolls sideways when it runs out of room -----------
   Three abreast on a wide screen. The arrows are hidden unless the track
   actually overflows, so two or three items simply sit across the page. */
/* The arrows sit beside the track, not on top of it: [prev][track][next]. They
   used to be absolutely positioned over the first and last card, which hid the
   picture underneath and, at narrow widths, sat squarely on it. */
/* the author `display` below beats the UA [hidden] rule, so the rail needs to be
   told again when the programme switches to a state it has no part in */
.rail[hidden] { display: none; }
.rail { display: flex; align-items: center; gap: clamp(0.6rem, 1.6vw, 1.4rem);
  margin: 2.5rem 0 2.75rem; }
.rail__track {
  --rail-gap: clamp(1.5rem, 3vw, 2.5rem);
  display: flex; gap: var(--rail-gap);
  overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
  text-align: left; scroll-padding-left: 0;
}
.rail__track::-webkit-scrollbar { display: none; }
.rail__track > * { flex: 0 0 calc((100% - 2 * var(--rail-gap)) / 3); scroll-snap-align: start; }
.rail__track { flex: 1 1 auto; min-width: 0; }
/* Centred on the picture, not on the whole card. A card is image plus a column
   of text, so centring on the card drops the arrows level with the paragraphs.
   app.js measures the image and publishes --rail-img-h. */
.rail__nav {
  align-self: flex-start;
  margin-top: max(0px, calc((var(--rail-img-h, 12rem) - 46px) / 2));
  flex: none; width: 46px; height: 46px; border-radius: 50%;
  border: 1px solid var(--ink); background: var(--paper);
  color: var(--ink); display: none; place-items: center; cursor: pointer;
  transition: background 0.3s var(--ease), color 0.3s var(--ease),
              border-color 0.3s var(--ease), opacity 0.3s var(--ease);
}
.rail.is-scrollable .rail__nav { display: grid; }
.rail__nav:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.rail__nav[disabled] { opacity: 0.22; cursor: default; }
.rail__nav[disabled]:hover { background: var(--paper); color: var(--ink); border-color: var(--ink); }
@media (max-width: 1000px) { .rail__track > * { flex-basis: calc((100% - var(--rail-gap)) / 2); } }
/* narrow: the track takes the full width and the arrows sit under it, centred,
   rather than stealing width from the cards */
@media (max-width: 680px) {
  .rail { flex-wrap: wrap; justify-content: center; }
  .rail__track { order: -1; flex-basis: 100%; }
  .rail__track > * { flex-basis: 100%; }
  .rail__nav { align-self: auto; margin-top: 0; }
}

/* ---- anchor offsets -------------------------------------------------------
   The header is fixed (65px) and, where a page has one, the submenu sticks
   beneath it (top 64px + 56px tall = 120px). Without scroll-margin an anchor
   lands underneath both. Only .room and .era ever had this, so every section
   and space anchor added since was landing behind the bars. */
/* --anchor-offset is measured by app.js from the header and the submenu as they
   actually render: the submenu wraps to two or three rows at narrow widths, and
   a fixed guess left anchor targets sitting underneath it. */
[id] { scroll-margin-top: 88px; }

.now__dates { font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--gold); margin: -0.3rem 0 0.8rem; }

/* The four faces of the tetramorph, as small illuminated marks beside a label.
   Must out-rank `.now__item img`, which sets width:100% and a 4:3 ratio and
   would otherwise stretch these into bands across the card. */
/* Line-drawn marks: inline SVG so they take the label's own colour. Sized at
   46px because below roughly 40px the four creatures stop being tellable apart
   — the lion's mane turns into a cog and the eagle into a dragonfly. */
.now__item .face, .face {
  width: 46px; height: 46px; display: block; margin: 0 0 0.9rem;
  color: var(--gold); overflow: visible;
}

.now__item .link-underline { margin-top: 1.2rem; }

/* dates sit under the name as a quiet caption, not a second heading */
.now__dates { font-size: 0.68rem; letter-spacing: 0.14em; }

/* Partner credits sit a fixed distance under the copy they belong to, the same
   gap the links use, rather than being pushed to the foot of the card. The logos
   therefore land at different heights when the copy runs to different lengths. */
.now__item { display: flex; flex-direction: column; }
.partners {
  margin-top: 1.2rem;
  display: flex; align-items: center; gap: 0.9rem; flex-wrap: wrap;
}
.partners__label { font-size: 0.6rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--faint); }
.partners__logo { height: 30px; width: auto; max-width: 130px; color: var(--faint); flex: none; }

/* an edition with no page of its own is a record, not a link */
.editions li > span:first-child { display: contents; }
.editions li:not(:has(a)) { display: grid; grid-template-columns: 5rem 1fr auto; gap: 1.5rem;
  align-items: baseline; padding: 1.15rem 0; text-align: left; }
@media (max-width: 560px) { .editions li:not(:has(a)) { grid-template-columns: 1fr; gap: 0.3rem; } }

/* ---- the programme's three states ----------------------------------------
   Text buttons, not pills: the row reads as a line of labels above the list,
   and the one you are looking at is underlined in gold. */
.states { display: flex; flex-wrap: wrap; justify-content: center;
  gap: 0.4rem 2rem; margin: 1.6rem 0 clamp(2rem, 4vw, 3rem); }
.states button { appearance: none; background: none; border: 0; padding: 0.2rem 0;
  font: inherit; font-size: 0.66rem; letter-spacing: 0.2em; text-transform: uppercase;
  font-weight: 600; color: var(--faint); cursor: pointer;
  border-bottom: 1px solid transparent; transition: color 0.2s, border-color 0.2s; }
.states button:hover { color: var(--ink); }
.states button[aria-current="true"] { color: var(--ink); border-bottom-color: var(--gold); }

/* ---- past events ----------------------------------------------------------
   The same card as the rail, in a grid rather than a scrolling row: three
   across on a wide screen, the way the rail shows three, so a card looks the
   same wherever you meet it. */
.cards { display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem); margin-top: clamp(2rem, 4vw, 3rem);
  text-align: left; }
@media (max-width: 1000px) { .cards { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px)  { .cards { grid-template-columns: 1fr; } }

/* ---- practical information ------------------------------------------------
   A card, not a paragraph. Opening hours are looked up rather than read, so
   each fact gets its own labelled row and the eye can go straight to the one
   it came for. Left-aligned inside a centred section, for the same reason the
   past list is: a column of times centred on the page cannot be scanned. */
.infobox { margin: 2.2rem 0 0; text-align: left;
  border: 1px solid var(--line); border-radius: 3px; background: var(--paper); }
.infobox__row { padding: 1.15rem clamp(1.2rem, 3vw, 1.8rem); }
.infobox__row + .infobox__row { border-top: 1px solid var(--line); }
.infobox__label { display: flex; align-items: center; gap: 0.55rem;
  font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; font-weight: 600; color: var(--gold);
  margin-bottom: 0.45rem; }
/* the mark takes the label's colour, so the row reads as one thing */
.infobox__icon { width: 16px; height: 16px; flex: none; }
.infobox__line { display: block; line-height: 1.55; }
.infobox__line + .infobox__line { color: var(--faint); font-size: 0.9rem; }

/* A button closing a passage of text lines up with it rather than centring
   under it, and needs air above it so it does not crowd the last line. */
.hero__cta--left { justify-content: flex-start; margin-top: 1.8rem; }

/* ---- a menu ---------------------------------------------------------------
   Read as prose, not as a card: no rules, no bold, no dish set as a heading.
   It is a list of what will be handed round during the evening, so it sits in
   the same voice and colour as the paragraph that introduces it. */
.menu { margin: 0.9rem 0 0; padding-left: 1.1rem; color: var(--muted); }
.menu li { margin: 0.35rem 0; line-height: 1.6; }

/* a room's secondary use, under its description */
.space__use { margin: 1.1rem 0 0; font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; font-weight: 600; }
.space__use a { color: var(--gold); border-bottom: 1px solid var(--line);
  padding-bottom: 0.25em; transition: border-color 0.3s var(--ease); }
.space__use a:hover { border-bottom-color: var(--gold); }

/* The Tétramorphe mark is a solid block rather than a line drawing, so it needs
   to be smaller to sit at the same visual weight as the other marks. */
.now__item .face--block, .face--block { width: 30px; height: 30px; }

/* Partner logos link to the partner. They are set in --faint like the label
   beside them, and come up to full ink on hover so it is clear they are live. */
.partners__link { display: inline-flex; color: var(--faint); transition: color 0.3s var(--ease); }
.partners__link:hover, .partners__link:focus-visible { color: var(--ink); }

/* The glyph's viewBox is cropped to its own bounds, so it fills the same 30px
   height as the Tétramorphe block and the eyebrows below line up across cards.
   Only the width differs, since a note is narrower than a square. */
.now__item .face--glyph, .face--glyph { width: 30px; height: 30px; }

/* ---- who runs a room ------------------------------------------------------
   Role above name, in the same hairline-topped columns as the four faces. The
   role leads because it is what a guest is looking for; the name is the answer,
   not the headline. */
.team { list-style: none; margin: 2.4rem 0 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 3vw, 2.75rem); }
.team li { padding-top: 1.5rem; border-top: 2px solid var(--gold); }
.team__role { display: block; font-size: 0.66rem; letter-spacing: 0.24em;
  text-transform: uppercase; font-weight: 600; color: var(--gold); margin-bottom: 0.7rem; }
.team__name { display: block; font-size: 1.05rem; font-weight: 700;
  letter-spacing: -0.02em; }
@media (max-width: 620px) { .team { grid-template-columns: 1fr; } }

/* ---- the four faces (Tétramorphe) ----------------------------------------
   Typographic, no imagery: the identity is the mark, and each face is one line.
   A gold hairline over each column gives the four the rhythm the pictures used
   to, and keeps them reading as one set rather than four stray paragraphs. */
.faces { list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 2.75rem); }
.faces li { padding-top: 1.5rem; border-top: 2px solid var(--gold); }
.faces h3 { font-size: 0.72rem; letter-spacing: 0.24em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); margin: 0 0 0.9rem; }
.faces p { font-size: 1.02rem; line-height: 1.6; margin: 0; }
@media (max-width: 900px) { .faces { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .faces { grid-template-columns: 1fr; } }

/* The Tétramorphe submenu lists editions rather than sections, so it needs a
   year marker to group them. Set apart from the links: not clickable, and it
   should read as a heading in the row rather than a fourth destination. */
.submenu__year { font-size: 0.66rem; letter-spacing: 0.24em; font-weight: 700;
  color: var(--ink); flex: none; }
.submenu__year:not(:first-child) { margin-left: clamp(0.6rem, 1.5vw, 1.4rem); }

/* Tétramorphe wears its own logo in the hero, the way Jeannette does. The
   wordmark is very wide (1696 x 200), so it is capped narrower than the
   Jeannette logo or it would run the full width of the screen. */
.hero__logo--tm img { width: min(26rem, 62vw); }
/* Edition pages carry the mark alone, not the wordmark: the page already names
   the edition underneath it, so the full logo would say it twice. */
.hero__mark { display: block; width: 52px; margin: 0 auto 1.7rem; line-height: 0; }
.hero__mark img { width: 100%; height: auto; display: block; }

/* An artist's name is a heading, not a label: it needs air before the prose. */
.section h2 + .muted { margin-top: 1.4rem; }

/* A work shown whole. The hero is full-bleed and crops to the viewport, so this
   is where a portrait painting is actually seen in full. */
.plate { margin: clamp(2.5rem, 5vw, 3.5rem) 0 0; }
.plate img { width: 100%; height: auto; display: block; }
.plate figcaption { margin-top: 1rem; font-size: 0.8rem; line-height: 1.6;
  color: var(--faint); }

/* Edition heroes fill the viewport like every other hero. The paintings are
   portrait, so `cover` crops top and bottom: the focal point is pulled upward,
   towards the faces, rather than sitting dead centre. */
.hero--artwork .hero__media img { object-position: center 38%; }

/* Everyone who has taken part, by year. Hashtags rather than a list: they read
   as a roll of names at a glance, and the year anchors each group. */
.people { margin-top: clamp(2.5rem, 5vw, 3.5rem); }
.people__year h3 { font-size: 0.66rem; letter-spacing: 0.28em; text-transform: uppercase;
  font-weight: 700; color: var(--ink); margin: 2rem 0 0.9rem; }
.people__year:first-child h3 { margin-top: 0; }
.people__tags { list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.1rem; }
.people__tags li { font-size: 0.94rem; color: var(--gold); white-space: nowrap; }

/* Credits: who took part, by year and by discipline. Replaces the hashtag row,
   which read as social tagging rather than as a record of the programme. */
.credits { margin-top: clamp(2.5rem, 5vw, 3.5rem); text-align: left;
  max-width: 34rem; margin-inline: auto; }
.credits__year + .credits__year { margin-top: 2.2rem; }
.credits__year h3 { font-size: 0.66rem; letter-spacing: 0.28em; text-transform: uppercase;
  font-weight: 700; color: var(--ink); margin: 0 0 1rem; }
.credits dl { display: grid; grid-template-columns: 5.5rem 1fr; gap: 0.55rem 1.4rem; margin: 0; }
.credits dt { font-size: 0.64rem; letter-spacing: 0.2em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); padding-top: 0.28rem; }
.credits dd { margin: 0; font-size: 1rem; line-height: 1.5; color: var(--ink); }
@media (max-width: 520px) { .credits dl { grid-template-columns: 1fr; gap: 0.2rem; }
  .credits dd { margin-bottom: 0.7rem; } }

/* A hero can carry a video instead of a still; it fills the frame the same way. */
.hero__media video { position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; }

/* A portrait beside its text. Squarer and smaller than .row, because a face
   does not need half the page to read. */
.figure-row { display: grid; grid-template-columns: minmax(0, 24rem) 1fr;
  gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
.figure-row__media { margin: 0; }
.figure-row__media img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.figure-row__body .eyebrow { margin-bottom: 0.9rem; }
@media (max-width: 860px) { .figure-row { grid-template-columns: 1fr; }
  .figure-row__media img { max-width: 26rem; } }

/* Third level: the sections of the edition you are reading. Lighter than the
   level above it so the hierarchy is legible at a glance. */
/* Sticks below the edition nav. Its height is measured by app.js, because a
   guess breaks the moment that nav wraps to two rows at narrow widths. */
.submenu--sub { top: calc(64px + var(--submenu-h, 56px)); background: rgba(255,255,255,0.97); }
.submenu--sub .submenu__inner { padding-block: 0.6rem; }
.submenu--sub a { font-size: 0.6rem; color: var(--faint); }
.submenu--sub a:hover { color: var(--ink); }
/* the section being read: quieter than the edition marker a level above,
   but still unmistakable */
.submenu--sub a.is-current { color: var(--ink); font-weight: 600;
  border-bottom: 1px solid var(--gold); padding-bottom: 0.2rem; }

/* The edition you are reading, marked in the nav. aria-current already says so
   for assistive tech; this makes it visible. */
.submenu a[aria-current="page"] { color: var(--ink); font-weight: 600;
  border-bottom: 2px solid var(--gold); padding-bottom: 0.2rem; }

/* A card's picture is part of its link, and lifts a little on hover so it reads
   as one. */
.now__img { display: block; }
.now__img img { transition: opacity 0.35s var(--ease); }
.now__img:hover img { opacity: 0.86; }

/* A quieter link than .link-underline: for "Read more", where the card's own
   heading is already doing the shouting. */
.link-quiet { display: inline-block; font-size: 0.78rem; letter-spacing: 0.04em;
  color: var(--faint); border-bottom: 1px solid var(--line); padding-bottom: 0.15em;
  transition: color 0.25s var(--ease), border-color 0.25s var(--ease); }
.link-quiet:hover { color: var(--ink); border-bottom-color: var(--gold); }
/* The card is a flex column, so a link stretches to its full width unless told
   otherwise, and the underline runs the whole card. Shrink it to its text. */
.now__item .link-quiet { margin-top: 1.1rem; align-self: flex-start; }

/* Work that belongs to the artist above it, not a section of its own. */
.subsection { margin-top: clamp(2.2rem, 4vw, 3rem); max-width: 44rem; }
.subsection h3 { font-size: 1.05rem; margin: 0 0 1rem; letter-spacing: -0.01em; }
.figure-row + .subsection { margin-top: clamp(2.6rem, 5vw, 3.5rem); }

/* Each credit leads to that person's place in the programme. Underlined only on
   hover, so a run of names still reads as a list rather than a row of buttons. */
.credits dd a { border-bottom: 1px solid transparent; padding-bottom: 0.05em;
  /* a line may break between names, never inside one: "Ihab Radwan" split
     across two lines reads as two people */
  white-space: nowrap;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease); }
.credits dd a:hover { border-bottom-color: var(--gold); color: var(--gold); }

/* Three stacked bars means three rules before any content. The two nav levels
   separate by tone instead: the editions sit on the page's own white, the
   sections on a warm band. No hairline between them, and none needed below,
   because the colour change already says where navigation ends. The band is
   --sand rather than --bone so it stays distinct from the bone-filled section
   that usually follows it. */
.submenu:has(+ .submenu--sub) { border-bottom: 0; }
.submenu--sub { background: var(--sand); backdrop-filter: none; border-bottom: 0; }

/* Photographer credit under a portrait: present, and quiet. */
.figure-row__media figcaption { margin-top: 0.6rem; font-size: 0.68rem;
  letter-spacing: 0.04em; color: var(--faint); }

/* What is on right now, at the top of the programme page. */
.now-showing { margin-top: clamp(2.5rem, 5vw, 3.5rem); padding-top: clamp(2rem, 4vw, 2.6rem);
  border-top: 1px solid var(--line); }
.now-showing h3 { font-size: clamp(1.2rem, 2vw, 1.5rem); margin: 0 0 0.6rem; }
.now-showing .now__dates { margin-bottom: 1.4rem; }
/* Newsletter signup that leads with a button and folds the two fields open on
   click. The grid-rows trick animates from nothing to the form's natural height
   without a hard-coded max. Collapsed, it is inert to the eye and the reader. */
.subscribe-fold {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows .42s ease, opacity .42s ease;
}
.subscribe-fold__inner { min-height: 0; overflow: hidden; }
.subscribe-fold.is-open { grid-template-rows: 1fr; opacity: 1; }
/* The opener sits in a .hero__cta (display:flex), which would out-rank the
   plain [hidden] rule and keep showing once clicked; this wins it back. */
[data-subscribe-openwrap][hidden] { display: none; }
@media (prefers-reduced-motion: reduce) {
  .subscribe-fold { transition: opacity .2s ease; }
}

/* More than one edition can be open at once; each is its own item, stacked.
   The title carries the link, so nothing follows the dates: no trailing gap. */
.now-showing__item + .now-showing__item { margin-top: clamp(1.6rem, 3vw, 2.2rem); }
.now-showing__item .now__dates { margin-bottom: 0; }
.now-showing__item h3 a { color: inherit; text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color .2s ease; }
.now-showing__item h3 a:hover { border-bottom-color: var(--gold-light); }

/* the way back to earlier seasons, sitting after the current year's editions */
.submenu__more { margin-left: auto; color: var(--faint); }
.submenu__more:hover { color: var(--ink); }

/* In the hero the block sits on the artwork, so it loses the rule, takes the
   hero's own light type, and gets a panel of its own. The artwork behind it is a
   painting with its own darks and lights, and white text laid straight onto that
   is legible over one edition and not the next. The panel makes it legible over
   any of them. Blur where the browser supports it, a slightly heavier tint where
   it does not, so the fallback is still readable rather than merely different.
   No edge on it: the panel should read as the artwork dimmed, not as a card. */
.hero .now-showing {
  margin-top: clamp(1.8rem, 3.5vw, 2.6rem); padding-top: 0; border-top: 0;
  display: inline-block; text-align: center;
  padding: clamp(1.2rem, 2.5vw, 1.8rem) clamp(1.6rem, 3.5vw, 2.6rem);
  border-radius: 3px;
  background: rgba(20, 17, 13, 0.40);
}
@supports (backdrop-filter: blur(6px)) or (-webkit-backdrop-filter: blur(6px)) {
  .hero .now-showing {
    background: rgba(20, 17, 13, 0.22);
    -webkit-backdrop-filter: blur(7px) saturate(1.1);
    backdrop-filter: blur(7px) saturate(1.1);
  }
}
.hero .now-showing__item + .now-showing__item {
  margin-top: clamp(1.4rem, 2.6vw, 1.9rem);
  padding-top: clamp(1.4rem, 2.6vw, 1.9rem);
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}
.hero .now-showing .eyebrow { color: var(--gold-light); justify-content: center; }
.hero .now-showing h3 { color: #fff; font-size: clamp(1.05rem, 1.8vw, 1.35rem); }
.hero .now-showing .now__dates { color: rgba(255,255,255,0.86); margin-bottom: 1.2rem; }
.hero .now-showing .link-underline { color: #fff; border-bottom-color: var(--gold-light); }

/* What's on, on the visit page. Not the editions list: that one's first column
   is a 5rem slot sized for a year, and an event's kind ("Tétramorphe II · Le
   Taureau") does not fit it. The kind sits on its own line above the title. */
.whatson { list-style: none; margin: 2rem 0 0; padding: 0; }
.whatson li { border-top: 1px solid var(--line); }
.whatson li:last-child { border-bottom: 1px solid var(--line); }
.whatson a { display: grid; grid-template-columns: 1fr auto;
  gap: 0.35rem 1.5rem; padding: 1.2rem 0; align-items: baseline;
  transition: color 0.3s var(--ease); }
.whatson a:hover { color: var(--gold); }
.whatson__kind { grid-column: 1 / -1; font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; font-weight: 600; color: var(--gold); }
.whatson__title { font-size: 1.05rem; }
.whatson__date { font-size: 0.78rem; color: var(--faint); white-space: nowrap; }
@media (max-width: 560px) {
  .whatson a { grid-template-columns: 1fr; }
  .whatson__date { white-space: normal; }
}

/* Tickets in the sticky nav: a filled mark rather than another text link, so it
   reads as an action and not as a fifth section to read. */
/* The strand's mark at the head of the bar. Sized down from the 30px it takes
   on a card: here it sits in a line of 0.66rem capitals and has to read as one
   of them, not as a picture dropped into the row. */
.submenu__mark { display: inline-flex; align-items: center; flex: none;
  margin-right: clamp(0.6rem, 1.6vw, 1.2rem); color: var(--gold); }
/* `.face` carries `margin: 0 0 0.9rem` for the card, where the mark sits above
   the eyebrow. In the bar that margin made the box 32px tall around an 18px
   glyph, so the glyph hung at the top of it and read as misaligned. */
.submenu__mark .face { width: 18px; height: 18px; margin: 0; }

/* `.submenu a` sets padding at specificity (0,2,0), so this has to match it or
   the fill hugs the text with no room either side. */
.submenu a.submenu__ticket { margin-left: clamp(0.8rem, 2vw, 1.8rem);
  background: var(--brick); color: #fff;
  padding: 0.55em 1.2em; border-radius: 2px; border-bottom: 0;
  transition: background 0.3s var(--ease), color 0.3s var(--ease); }
.submenu a.submenu__ticket:hover { background: var(--ink); color: #fff; }

/* The way out of an event that is over. Same shape as the ticket button it
   replaces, but outlined rather than filled: it is a way back to a list, not a
   thing to buy. */
.submenu a.submenu__past { background: none; color: var(--faint);
  box-shadow: inset 0 0 0 1px var(--line); }
.submenu a.submenu__past:hover { background: none; color: var(--ink);
  box-shadow: inset 0 0 0 1px var(--ink); }

/* Said once, under the dates, so it is read before anything else on the page.
   Set like the dates themselves rather than as a badge: it is a fact about the
   event, not a label stuck on top of it. */
.hero__passed { margin-top: 0.6rem; font-size: 0.62rem; letter-spacing: 0.22em;
  text-transform: uppercase; font-weight: 600; color: var(--gold-light); }

/* a ticket button with nothing left to sell */
.submenu a.submenu__ticket.is-soldout { background: var(--faint); cursor: default; }
.submenu a.submenu__ticket.is-soldout:hover { background: var(--faint); }

/* Cards read at a glance, so their copy is clamped to a common depth. The full
   text is a click away: an event with a page of its own already has "Read more",
   and app.js gives a fold-out to any card that is clamped without one. */
.now__item .muted {
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6;
  overflow: hidden;
}
.now__item.is-open .muted { -webkit-line-clamp: unset; overflow: visible; }
.now__more {
  align-self: flex-start; margin-top: 0.7rem; padding: 0;
  appearance: none; background: none; border: 0; border-bottom: 1px solid var(--line);
  font: inherit; font-size: 0.78rem; letter-spacing: 0.04em; color: var(--faint);
  cursor: pointer; transition: color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.now__more:hover { color: var(--ink); border-bottom-color: var(--gold); }

/* ---- the cuvées, over the back label -------------------------------------
   The engraved back label is the estate drawn in cutaway, and it already sits
   on the home page. Behind the cuvées it does the work a photograph would do
   less well: it says wine and it says this house, without competing with the
   five names in front of it.

   Very soft, and edge to edge rather than boxed, so it reads as watermark
   rather than as an image someone placed. `contain` keeps the drawing whole:
   cropping it would cut the towers off, which is the part that makes it the
   château rather than any label. */
.section--label { position: relative; overflow: hidden; }
.section--label::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url('/assets/img/home/label-back.jpg') center / contain no-repeat;
  opacity: 0.07;
  pointer-events: none;
}
.section--label > * { position: relative; }
/* The drawing is wider than it is tall, so on a narrow screen it would shrink
   to a strip across the middle and read as a smudge. Let it fill instead. */
@media (max-width: 700px) {
  .section--label::before { background-size: cover; opacity: 0.05; }
}
@media (prefers-reduced-motion: no-preference) {
  .section--label::before { transition: opacity 0.6s var(--ease); }
}

/* The scores, said plainly and linked to their source. No stars drawn by us:
   the number is the claim, and the link is the proof. */
.ratings { display: grid; gap: clamp(1.6rem, 3vw, 2.6rem);
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  margin-top: clamp(2.2rem, 4vw, 3rem); text-align: center; }
.rating__where { font-size: 0.62rem; letter-spacing: 0.18em; text-transform: uppercase; color: var(--faint); }
.rating__score { display: block; margin: 0.7rem 0 0.2rem;
  font-size: clamp(2rem, 3.4vw, 2.7rem); font-weight: 700; letter-spacing: -0.02em; color: var(--ink); }
.rating__score small { font-size: 0.42em; font-weight: 500; color: var(--faint); letter-spacing: 0; }
.rating__count { font-size: 0.8rem; color: var(--muted); }
.rating__link { display: inline-block; margin-top: 0.9rem; font-size: 0.66rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted);
  border-bottom: 1px solid var(--line); padding-bottom: 2px; }
.rating__link:hover { color: var(--ink); border-bottom-color: currentColor; }

/* Guest reviews, set as the site sets any other quotation. They are quoted in
   full and in the language they were written in: a review is someone's words,
   not copy, and translating or trimming it would make it ours.

   The slider is a scroll-snap track, so it works by dragging or swiping with no
   script at all; the arrows are an enhancement over that rather than the only
   way through. */
.guest-slider { position: relative; margin-top: clamp(2.4rem, 4vw, 3.4rem); }
.guest-quotes {
  display: flex; gap: clamp(1.2rem, 2.4vw, 2rem);
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth;
  -webkit-overflow-scrolling: touch; scrollbar-width: none; padding-bottom: 0.4rem;
}
.guest-quotes::-webkit-scrollbar { display: none; }
.guest-quotes > .guest-quote { flex: 0 0 100%; scroll-snap-align: center; }
.guest-slider__nav { display: flex; gap: 0.7rem; justify-content: center; margin-top: 1.8rem; }
/* The same control the photographs use: a 44px disc, no border, the chevron at
   1.4. Theirs sits on a picture and so is white; this one sits on the page, so
   it takes the warm ground instead. */
.guest-slider__btn {
  width: 44px; height: 44px; border-radius: 50%; display: grid; place-items: center;
  border: 0; background: var(--bone); color: var(--ink); cursor: pointer;
  transition: background 0.3s var(--ease), opacity 0.3s var(--ease);
}
.guest-slider__btn:hover:not([disabled]) { background: var(--sand); }
.guest-slider__btn[disabled] { opacity: 0.3; cursor: default; }
@media (prefers-reduced-motion: reduce) { .guest-quotes { scroll-behavior: auto; } }
/* One at a time, on the page's own ground: no card, no rule, no ornament.
   The words at reading size, the name below them. */
.guest-quote {
  /* the slide is the full width of the track, so one fills the view; the words
     inside it keep a readable measure */
  margin: 0; border: 0; background: none; padding: 0; text-align: center;
}
.guest-quote blockquote {
  margin: 0 auto; max-width: 44rem;
  font-size: clamp(1.05rem, 1.7vw, 1.3rem); line-height: 1.75;
  color: var(--ink); letter-spacing: -0.005em;
}
.guest-quote figcaption {
  margin-top: 1.8rem; font-size: 0.62rem; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--faint);
}
.guest-quote figcaption b { font-weight: 600; color: var(--muted); }

/* ---- the press page -------------------------------------------------------
   A logo needs room around it and a plain ground behind it, so each one sits on
   its own sheet rather than on the page. The sheet is the same bone as the
   section it interrupts, which keeps the marks looking placed rather than
   pasted. */
.press-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 2.4rem;
}
.press-item { margin: 0; }
.press-item__sheet {
  display: grid;
  place-items: center;
  padding: 2.6rem 2rem;
  min-height: 11rem;
  background: var(--paper);
  border: 1px solid var(--line);
}
/* The symbol and the icon are square; the wordmarks are wide. Without this the
   square marks tower over their neighbours in the same row. */
.press-item__sheet--tall img { max-height: 6.5rem; }
.press-item__sheet img { max-width: 100%; height: auto; max-height: 4.5rem; }
.press-item figcaption { padding-top: 1.1rem; }
.press-item h3 { font-size: 1.05rem; margin: 0.2rem 0 0.6rem; }
.press-item__links { display: flex; gap: 1.2rem; flex-wrap: wrap; margin: 0; }
.press-item__links a {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
  padding-bottom: 2px;
}
.press-item__links a:hover { color: var(--ink); border-bottom-color: currentColor; }

/* A brand's own wordmark standing in for a heading. Saskia's and Come & Play
   are marks in their own right, so the page that belongs to them says so with
   the mark rather than with a line of small caps above the title. */
.brand-mark { display: block; margin: 0 auto; height: auto; }
/* Carrying a hero on its own, so sized like a title rather than like a logo,
   and given the air a title would have under it. */
.hero__inner .brand-mark { width: min(34rem, 78vw); margin-bottom: 3.2rem; }
.brand-mark--sm { width: min(16rem, 56vw); }

/* The palette, said on the page. Château's press page carries the same markup
   but never got these rules, so its swatches render as loose text; this belongs
   to the shared shell and should be ported back there. */
.swatches { list-style: none; margin: 0; padding: 0; display: grid;
  gap: 1.6rem 2.4rem; grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr)); }
.swatch { display: grid; grid-template-columns: 3rem 1fr; column-gap: 1.1rem; align-items: start; }
.swatch__chip {
  grid-row: 1 / span 3;
  width: 3rem; height: 3rem;
  /* an inset hairline so the palest colours still read as a square */
  box-shadow: inset 0 0 0 1px rgba(27, 23, 18, 0.14);
}
.swatch__chip--outline { box-shadow: inset 0 0 0 1px rgba(27, 23, 18, 0.22); }
.swatch__name { font-size: 0.98rem; }
.swatch__hex { font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint); }
.swatch__note { font-size: 0.85rem; color: var(--muted); line-height: 1.65; margin-top: 0.4rem; }

/* the facts list, read as a table of two columns rather than as prose */
.facts { display: grid; grid-template-columns: 10rem 1fr; gap: 0.9rem 1.6rem; margin: 0; }
.facts dt {
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding-top: 0.2rem;
}
.facts dd { margin: 0; }
@media (max-width: 560px) {
  .facts { grid-template-columns: 1fr; gap: 0.2rem 0; }
  .facts dd { margin-bottom: 1rem; }
}

/* A telephone number is one thing to read and one thing to tap: never let a
   line break fall inside it. */
a[href^="tel:"] { white-space: nowrap; }

/* The other Edenroche houses, named at the foot of the legal links. They take a
   line of their own rather than joining that row, so they read as a different
   kind of thing, but they keep the row's left edge and its type. */
.footer-sisters {
  grid-column: 2 / 4; grid-row: 2;
  display: flex; gap: 1.5rem; flex-wrap: wrap;
  font-size: 0.66rem; line-height: 2;
}
/* They are names, not labels: the bottom bar's small caps would recast them
   as another row of navigation, and a house is written the way it is written. */
.footer-sister { text-transform: none; letter-spacing: 0.06em; }

/* ---- the footer address --------------------------------------------------
   The last line on the page, and read as a footnote rather than as content:
   one line, smaller than the copyright above it, with the email the only part
   that does anything. It has been a column and a block under the logo; both
   made it look like a menu, which it is not. */
/* The address and the sister houses share the bottom bar's second row, so they
   begin on the same line by construction rather than by matching margins. */
.footer-place {
  grid-column: 1; grid-row: 2;
  margin: 0;
  font-size: 0.66rem;
  letter-spacing: 0.1em;
  line-height: 2;
  color: rgba(207,199,184,0.5);
}

/* The two rules above are placed after the responsive block that stacks this
   bar, and carry the same specificity, so they were winning at every width:
   the bottom bar kept its desktop columns on a phone, the copyright was left
   in a 117px track and broke across three lines. Restate the stacking here,
   where it comes last and therefore holds. */
@media (max-width: 560px) {
  .footer-sisters, .footer-place { grid-column: 1; grid-row: auto; }
}

/* @brand:start */
/* ===========================================================================
   Les Mazots du Clos — dark-surface brand theme.
   The château's dark sections are warm carbon; ours carry the brand's Alpine
   Midnight (#182D48), with cool, light text so the footer links read clearly.
   Fenced as @brand: the shared shell stays identical to Château de Roche.
   =========================================================================== */
:root { --carbon: #182D48; }                 /* Alpine Midnight for every dark surface */
.site-footer { color: #cdd8e6; }
.site-footer a { color: #cdd8e6; }
.site-footer a:hover { color: #ffffff; }
.footer-col h4 { color: #c4d4e8; }           /* Frosted Sky */
.footer-place { color: #aabbd0; }            /* address: cool light, readable on Alpine Midnight */
.footer-bottom { color: #8ba0bb; }
.footer-social a { color: #8ba0bb; }
.footer-social a:hover { color: #c4d4e8; }
/* Eyebrows read as a flat navy on the light grounds and a cold blue on the dark
   ones — a second accent competing with the real one. De-blue them sitewide to a
   quiet warm neutral so they read as labels, not colour. */
.eyebrow { color: var(--faint); }
.section--carbon .eyebrow,
.section--carbon .eyebrow::before { color: #cfc7b8; }
/* Body copy set over a full-bleed photo (Café Littéraire, Breakfast) needs to sit
   brighter than the dim carbon-muted tone so it lifts off the image. */
.section--art .muted { color: #e8e2d6; }
/* A press quote on a plain, light warm ground rather than a photograph, so it
   reads as a quiet card between the two dark photo sections. Dark type. */
.band--solid { background: var(--paper); min-height: 52vh; color: var(--ink); }
.band--solid blockquote { text-shadow: none; color: var(--ink); }
.band--solid cite { color: var(--faint); }
/* Dark sections (e.g. Reserve): the fact labels use --gold (Alpine Midnight) and
   the values use --muted, both of which vanish on the Alpine-Midnight ground.
   Lift them to the cool light tones so the hours read. */
.section--carbon .facts dt { color: #c4d4e8; }
.section--carbon .facts dd { color: #dbe4f0; }
.section--carbon .facts--tight dd { color: #dbe4f0; }
.section--carbon .btn--gold { border-color: #c4d4e8; color: #c4d4e8; }
.section--carbon .btn--gold:hover { background: #c4d4e8; color: var(--gold); }
/* The header "Book" is a solid button, not a text link. Alpine Midnight filled on
   the solid header; inverts to a white fill over a hero so it reads on the photo. */
.header-book {
  display: inline-flex; align-items: center;
  padding: 0.6em 1.3em;
  font-size: 0.64rem; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase;
  background: var(--gold); border: 1px solid var(--gold); color: #fff;
  transition: background 0.3s var(--ease), color 0.3s var(--ease), border-color 0.3s var(--ease);
}
.header-book:hover { background: transparent; color: var(--gold); }
.site-header.is-transparent .header-right a.header-book { background: #fff; border-color: #fff; color: var(--gold); }
.site-header.is-transparent .header-right a.header-book:hover { background: transparent; color: #fff; }
/* @brand:end */
