/* ============================================================
   Boubacar Ndiaye — Conteur, Griot du Sénégal
   Feuille de styles unique — vanilla CSS, aucune dépendance.
   DA "terre & oralité" : sable cuit, terracotta, ocre, grain de
   papier, arches-portails (« ma bouche est une porte »).
   Tokens : primitive → sémantique → composant.
   ============================================================ */

/* -----------------------------------------------------------
   0. POLICES — hébergées sur le site (18/10/2026)
   Fraunces (titres) + Mulish (texte), polices libres (licence SIL OFL,
   cf. assets/fonts/OFL-*.txt), auparavant chargées depuis Google Fonts :
   chaque visite transmettait l'adresse IP du visiteur à Google (RGPD).
   Fichiers « variables » (une graisse continue par fichier) ; seuls les
   jeux latin + latin étendu sont gardés (le ŋ du wolof est dans le
   second, que le navigateur ne télécharge que s'il en a besoin).
   ----------------------------------------------------------- */
@font-face {
  font-family: "Fraunces"; font-style: italic; font-weight: 400 600; font-display: swap;
  src: url("/assets/fonts/fraunces-v38-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces"; font-style: italic; font-weight: 400 600; font-display: swap;
  src: url("/assets/fonts/fraunces-v38-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("/assets/fonts/fraunces-v38-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Fraunces"; font-style: normal; font-weight: 400 600; font-display: swap;
  src: url("/assets/fonts/fraunces-v38-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Mulish"; font-style: italic; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/mulish-v18-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Mulish"; font-style: italic; font-weight: 400; font-display: swap;
  src: url("/assets/fonts/mulish-v18-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Mulish"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/mulish-v18-normal-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Mulish"; font-style: normal; font-weight: 400 800; font-display: swap;
  src: url("/assets/fonts/mulish-v18-normal-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* -----------------------------------------------------------
   1. TOKENS — palette terre, réchauffée & assombrie
   ----------------------------------------------------------- */
:root {
  /* Primitives */
  --paper-50:  #FBF1E1;  /* crème chaud */
  --paper-100: #F6E7D2;  /* sable cuit — fond principal */
  --paper-200: #EFDABF;  /* sable doux */
  --paper-300: #E4C9A4;  /* argile claire — cadres, dividers */
  --clay-200:  #E0B488;  /* terre cuite claire */

  --terra-400: #C26A41;
  --terra-500: #B0512F;  /* terracotta — accent principal */
  --terra-600: #8F3E22;  /* terracotta brûlée (contraste/hover) */

  --ochre-400: #D6A648;
  --ochre-500: #C2872E;  /* ocre / curcuma — brush, fil d'or */
  --ochre-600: #9E6C1F;

  --olive-500: #6E6B43;  /* feuille séchée — discret */

  --earth-700: #4A3623;  /* brun moyen */
  --earth-800: #34230F;  /* brun profond */
  --earth-900: #2A1B0D;  /* brun-terre nuit — texte & bandes sombres */

  /* Sémantique */
  --nav-h: 74px;          /* hauteur de la navbar — le hero passe dessous */
  --bg:           var(--paper-100);
  --bg-soft:      var(--paper-200);
  --bg-clay:      var(--clay-200);
  --bg-card:      var(--paper-50);
  --bg-dark:      var(--earth-900);
  --ink:          var(--earth-900);
  --ink-soft:     var(--earth-800);
  --ink-muted:    var(--earth-700);
  --cream:        var(--paper-50);
  --accent:       var(--terra-500);
  --accent-hover: var(--terra-600);
  --accent-2:     var(--ochre-500);
  --divider:      var(--paper-300);
  --on-accent:    var(--paper-50);
  --on-dark:      var(--paper-100);
  --on-dark-mute: #C7AC8C;

  /* Typographie */
  --font-display: "Fraunces", Georgia, "Times New Roman", serif;
  --font-body:    "Mulish", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
  /* ⚠️ Nom historique : ce n'est PLUS la police du logo. Depuis 07/2026 le logo
     est un SVG (calligraphie du 1er site, cf. components/navbar.html). Cette
     variable ne sert plus qu'au grand titre du hero, resté en Fraunces. */
  --font-logo:    var(--font-display);

  --fs-xs:   0.78rem;
  --fs-sm:   0.9rem;
  --fs-base: 1.06rem;
  --fs-md:   1.22rem;
  --fs-lg:   1.6rem;
  --fs-xl:   2.1rem;
  --fs-3xl:  clamp(2.7rem, 6.4vw, 5rem);
  --fs-hero: clamp(3.4rem, 11vw, 8rem);
  --fs-quote: clamp(1.6rem, 3.2vw, 2.7rem);

  --lh-tight: 1.04;
  --lh-snug:  1.22;
  --lh-body:  1.72;

  /* Espacements — base 8px */
  --space-1: 0.25rem; --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem;
  --space-5: 1.5rem;  --space-6: 2rem;   --space-7: 3rem;    --space-8: 4rem;
  --space-9: 6rem;    --space-10: 8rem;

  /* Divers */
  --container:    1200px;
  --container-px: clamp(1.25rem, 5vw, 4rem);
  --measure:      64ch;
  --radius:       4px;
  --radius-lg:    14px;
  --arch:         48% 48% 7% 7% / 36% 36% 5% 5%;  /* cadre-portail */
  --shadow-md:    0 18px 50px -22px rgba(42, 27, 13, 0.45);
  --ease:         cubic-bezier(0.22, 1, 0.36, 1);

  /* Grain de papier (turbulence SVG, gris) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* Trait de pinceau ocre (séparateur / soulignement) */
  --brush: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='16' viewBox='0 0 240 16'%3E%3Cpath d='M2 9 C40 3 70 12 110 8 C150 4 190 13 238 7' stroke='%23C2872E' stroke-width='3.5' stroke-linecap='round' fill='none' opacity='0.9'/%3E%3C/svg%3E");
  /* Arcade ocre (rangée d'arches) — ornement signature */
  --arcade: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 26'%3E%3Cpath d='M8 25V13A12 12 0 0 1 32 13V25M46 25V13A12 12 0 0 1 70 13V25M84 25V13A12 12 0 0 1 108 13V25M122 25V13A12 12 0 0 1 146 13V25M160 25V13A12 12 0 0 1 184 13V25' fill='none' stroke='%23C2872E' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  /* Dôme terre-nuit : ouverture en arche au sommet des bandes sombres */
  --arch-top-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1200 80' preserveAspectRatio='none'%3E%3Cpath d='M0 80 L0 44 C300 -14 900 -14 1200 44 L1200 80 Z' fill='%232A1B0D'/%3E%3C/svg%3E");
}

/* -----------------------------------------------------------
   2. RESET & base
   ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--fs-base);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

/* Grain de papier sur tout le site — matière, chaleur, fait-main */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 9998;
  pointer-events: none;
  background-image: var(--grain);
  opacity: 0.05;
}

img, video, iframe { max-width: 100%; display: block; }
img { height: auto; }

a { color: var(--accent); text-decoration: none; transition: color 0.2s; }
a:hover { color: var(--accent-hover); }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 560;
  line-height: var(--lh-tight);
  /* Répartit les mots sur les lignes plutôt que de laisser un mot seul en
     dernière ligne. C'est en mobile que ça se voit le plus (titres sur 2-3
     lignes). Ignoré en silence par les navigateurs qui ne le connaissent pas. */
  text-wrap: balance;
  color: var(--ink);
  margin: 0 0 var(--space-4);
  font-optical-sizing: auto;
  letter-spacing: -0.01em;
  /* Les titres viennent du CMS : un mot long sans espace (nom de lieu, URL,
     titre à rallonge) faisait déborder la page en largeur sur mobile —
     testé à 715px de large sur un écran de 375. Les <p> étaient déjà protégés. */
  overflow-wrap: break-word;
}
/* Même protection pour les textes courts pilotés par le CMS (titres de cartes,
   noms de lieux, libellés) qui ne sont ni des <p> ni des titres. */
.spectacle__title, .spectacle__desc, .agenda-item__title, .agenda-item__place,
.contact-card, .reference-item, .tag, dd { overflow-wrap: break-word; }

p { margin: 0 0 var(--space-4); overflow-wrap: break-word; }
p:last-child { margin-bottom: 0; }

/* Le JS masque des blocs via l'attribut [hidden] quand un champ CMS est vide.
   Cette règle garantit que ça marche même si une règle de composant pose un
   `display` (un display de classe l'emporterait sinon sur celui du navigateur). */
[hidden] { display: none !important; }

:focus-visible { outline: 3px solid var(--accent); outline-offset: 3px; border-radius: 2px; }
::selection { background: var(--ochre-400); color: var(--earth-900); }

.skip-link {
  position: absolute; left: -999px; top: var(--space-3);
  background: var(--ink); color: var(--cream);
  padding: var(--space-2) var(--space-4); border-radius: var(--radius); z-index: 10000;
}
.skip-link:focus { left: var(--space-3); }

/* Texte lu par Google et les lecteurs d'écran, invisible à l'écran (04/11/2026) :
   le titre de l'accueil est un logo dessiné (SVG) → son nom en vrai texte ici. */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* -----------------------------------------------------------
   3. Layout helpers
   ----------------------------------------------------------- */
.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--container-px); }
.section { padding-block: var(--space-9); }
.section--tight { padding-block: var(--space-7); }
.section--soft { background: var(--bg-soft); }
.section--clay { background: var(--bg-clay); }
.measure { max-width: var(--measure); }

/* Bande terre profonde (drame & chaleur) */
.section--dark { background: var(--bg-dark); color: var(--on-dark); position: relative; }
/* (Dômes retirés — bords nets, plus cohérents. La transition se fait par
   l'ornement arcade.) */
.section--dark h1, .section--dark h2, .section--dark h3 { color: var(--cream); }
.section--dark .eyebrow { color: var(--ochre-400); }
.section--dark .eyebrow::before { background: var(--ochre-400); }
.section--dark .prose p { color: var(--on-dark); }
.section--dark .prose em { color: var(--ochre-400); }

.eyebrow {
  font-family: var(--font-body);
  font-size: var(--fs-sm);
  font-weight: 800;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 0 0 var(--space-4);
  display: flex; width: fit-content; align-items: center; gap: var(--space-3);
}
.eyebrow::before { content: ""; width: 2.2rem; height: 2px; background: var(--accent); border-radius: 2px; flex: none; }
.eyebrow, .hero__role, .spectacle__title, .pullquote q, .pullquote p { text-wrap: balance; }

/* Titre de section + soulignement pinceau ocre */
.section__title { font-size: var(--fs-3xl); margin-bottom: var(--space-6); position: relative; }
.section__title--brushed { display: inline-block; padding-bottom: 0.5rem; }
.section__title--brushed::after {
  content: ""; display: block;
  height: 14px; width: clamp(120px, 40%, 240px);
  margin-top: 0.35rem;
  background: var(--brush) left center / contain no-repeat;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.7s var(--ease) 0.12s;
}
.section__title--brushed.brush-drawn::after { clip-path: inset(0 0 0 0); }

/* -----------------------------------------------------------
   4. Boutons / liens d'action
   ----------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: var(--space-2);
  font-family: var(--font-body); font-weight: 800; font-size: var(--fs-sm);
  letter-spacing: 0.04em; padding: 0.9em 1.7em;
  border-radius: 100px; border: 2px solid transparent; cursor: pointer;
  transition: transform 0.2s var(--ease), background 0.2s, color 0.2s, border-color 0.2s;
}
.btn:hover { transform: translateY(-2px); }
.btn--primary { background: var(--accent); color: var(--on-accent); }
.btn--primary:hover { background: var(--accent-hover); color: var(--on-accent); }
.btn--ghost { border-color: var(--ink); color: var(--ink); }
.btn--ghost:hover { background: var(--ink); color: var(--cream); }
.section--dark .btn--ghost { border-color: var(--on-dark); color: var(--on-dark); }
.section--dark .btn--ghost:hover { background: var(--cream); color: var(--ink); }

.link-arrow {
  font-weight: 800; font-size: var(--fs-sm); letter-spacing: 0.04em;
  display: inline-flex; align-items: center; gap: var(--space-2); color: var(--ink);
}
.link-arrow::after { content: "→"; transition: transform 0.2s var(--ease); }
.link-arrow:hover { color: var(--accent); }
.link-arrow:hover::after { transform: translateX(4px); }

/* -----------------------------------------------------------
   5. Navbar
   ----------------------------------------------------------- */
.nav {
  position: sticky; top: 0; z-index: 1000;
  background: color-mix(in srgb, var(--bg) 90%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--divider);
}

.nav__inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-5); min-height: 74px; }
/* Le nom n'est plus du texte mais le logo vectoriel (cf. components/navbar.html).
   `color` reste indispensable : c'est lui que le SVG capte via currentColor. */
.nav__brand { color: var(--accent); line-height: 1; display: inline-block; }
/* Le logo se dimensionne par la HAUTEUR, la largeur suit le ratio (5.47:1).
   Ne pas fixer de width : le nom serait déformé.
   Hauteurs calées pour que la largeur du logo équilibre le sous-titre en
   capitales dessous (sinon le nom paraît rachitique sous sa propre légende). */
.brand-logo { display: block; height: 2.05rem; width: auto; }
.nav__brand span {
  display: block; font-family: var(--font-body); font-size: 0.6rem; font-weight: 800;
  letter-spacing: 0.24em; text-transform: uppercase; color: var(--accent); margin-top: 3px;
}
.nav__links { display: flex; align-items: center; gap: var(--space-5); list-style: none; margin: 0; padding: 0; }
.nav__links a { font-size: 0.95rem; font-weight: 700; color: var(--ink-soft); position: relative; padding: var(--space-2) 0; }
.nav__links a:hover { color: var(--accent); }
.nav__links a[aria-current="page"] { color: var(--accent); }
.nav__links a[aria-current="page"]::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -2px; height: 9px;
  background: var(--brush) left center / contain no-repeat;
}
.nav__toggle { display: none; background: none; border: 0; cursor: pointer; padding: var(--space-2); width: 44px; height: 44px; }
.nav__toggle span { display: block; width: 24px; height: 2px; background: var(--ink); margin: 5px auto; transition: transform 0.3s var(--ease), opacity 0.3s; }
.nav.is-open .nav__toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav.is-open .nav__toggle span:nth-child(2) { opacity: 0; }
.nav.is-open .nav__toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
/* Petits portables (1024-1100px) : 7 liens + le sélecteur de langue. On
   resserre un peu pour tenir sur une ligne (mesuré en FR, EN et WO).
   En dessous de 1024px, c'est le menu burger (cf. « Menu burger » plus bas) :
   ni le resserrage ni la suppression de la mention sous le logo ne suffisaient
   à faire tenir le menu sur une ligne, il débordait à 721px. */
@media (min-width: 1024px) and (max-width: 1100px) {
  .nav__inner { gap: var(--space-4); }
  /* 0.75rem (et non 0.9rem) depuis l'ajout de « WO » au sélecteur (16/10). */
  .nav__links { gap: 0.75rem; }
  .nav__links > li > a { font-size: 0.85rem; }
}
/* La flèche ▾ ne passe jamais seule à la ligne sous « Spectacles » ou
   « Médiation & Formation » (c'est ce qui arrivait à 1024px avec FR·EN·WO). */
@media (min-width: 1024px) {
  .nav__links > li > a { white-space: nowrap; }
}

/* Sélecteur de langue (rempli par i18n.js). Discret : deux lettres, la
   langue courante en pastille terracotta. */
.lang-switch { display: flex; align-items: center; gap: 2px; flex: none; }
.nav__lang:has(.lang-switch:empty) { display: none; }
/* `.nav__links .lang-switch a` : plus précis que `.nav__links a`, dont il
   hériterait sinon la taille et les marges des liens du menu. */
.nav__links .lang-switch a {
  font-size: 0.72rem; font-weight: 800; letter-spacing: 0.08em; line-height: 1;
  color: var(--ink-muted); padding: 0.4em 0.5em; border-radius: var(--radius);
}
.nav__links .lang-switch a:hover { color: var(--accent); }
.nav__links .lang-switch a.is-current { color: var(--on-accent); background: var(--accent); }
/* Pendant la traduction (anglais / wolof), la page reste masquée : posé par
   le mini-script du <head>, retiré par i18n.js. */
html.i18n-pending body { visibility: hidden; }
/* Bloc affiché seulement hors français (ex. note des mentions légales). */
.i18n-only { display: none; }
html:not([lang="fr"]) .i18n-only { display: block; }

/* Sous-menus déroulants (Spectacles, Médiation) */
.nav__item--has-sub { position: relative; }
.nav__sub { list-style: none; margin: 0; padding: 0; }
.nav__caret { font-size: 0.7em; opacity: 0.65; }
@media (min-width: 1024px) {
  .nav__sub {
    position: absolute; top: calc(100% + 4px); left: 0; min-width: 210px;
    background: var(--bg); border: 1px solid var(--divider); border-radius: var(--radius-lg);
    box-shadow: var(--shadow-md); padding: var(--space-2);
    opacity: 0; visibility: hidden; transform: translateY(8px);
    transition: opacity 0.2s var(--ease), transform 0.2s var(--ease), visibility 0.2s; z-index: 1001;
  }
  .nav__item--has-sub:hover .nav__sub,
  .nav__item--has-sub:focus-within .nav__sub { opacity: 1; visibility: visible; transform: none; }
  .nav__sub a { display: block; padding: 0.55em 0.8em; font-size: 0.92rem; font-weight: 700; color: var(--ink-soft); border-radius: var(--radius); white-space: nowrap; }
  .nav__sub a:hover { background: var(--bg-soft); color: var(--accent); }
}
@media (max-width: 1023px) {
  .nav__caret { display: none; }
  /* Sous-items clairement imbriqués : indentés sous un filet, compacts, discrets. */
  .nav__links .nav__sub { margin: var(--space-1) 0 var(--space-3) var(--space-2); border-left: 2px solid var(--accent-2); }
  /* min-height 44px : cible tactile confortable, et l'écart avec le parent
     (1.45rem / 800) marque la hiérarchie sans avoir besoin d'un filet. */
  .nav__links .nav__sub a {
    display: flex; align-items: center; min-height: 44px;
    padding: 0 0 0 var(--space-4);
    font-size: 1.02rem; font-weight: 600; color: var(--ink-muted); border-bottom: none;
  }
  .nav__links .nav__sub a:hover { color: var(--accent); }
}

/* -----------------------------------------------------------
   6. Cadre-portail (motif signature « ma bouche est une porte »)
   ----------------------------------------------------------- */
.arch {
  position: relative;
  /* height:100% est INDISPENSABLE : le parent (.arch-frame, .hero__media…)
     porte l'aspect-ratio. Sans ça, le height:100% de l'image ne se résout
     pas → l'image reprend ses proportions naturelles → arche trop courte
     (photo paysage : gros vide argile) ou débordante (photo portrait). */
  height: 100%;
  border-radius: var(--arch);
  overflow: hidden;
  background: var(--bg-soft);
}
.arch img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center 32%; }
/* Sans ça, le display:block ci-dessus écraserait l'attribut [hidden] et une
   image non chargée s'afficherait en icône cassée par-dessus le fallback. */
.arch img[hidden] { display: none; }
/* Arche sans photo : placeholder argile chaleureux (pas d'image cassée) */
.arch.is-empty {
  display: grid; place-items: center;
  background: radial-gradient(120% 90% at 50% 28%, var(--clay-200), var(--paper-300) 70%, var(--paper-200));
}
.arch.is-empty::before {
  content: "“"; font-family: var(--font-display); font-style: italic;
  font-size: 9rem; line-height: 0; color: var(--terra-500); opacity: 0.4;
}
/* Halo / cadre décalé derrière l'arche (effet affiche imprimée) */
.arch-frame { position: relative; }
.arch-frame::before {
  content: ""; position: absolute; inset: 18px -18px -18px 18px;
  border-radius: var(--arch);
  background: var(--accent-2); opacity: 0.22; z-index: 0;
}
.arch-frame .arch { position: relative; z-index: 1; box-shadow: var(--shadow-md); }
.arch-frame .arch::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--arch);
  border: 1px solid rgba(42, 27, 13, 0.12); pointer-events: none;
}

/* -----------------------------------------------------------
   7. Hero accueil
   ----------------------------------------------------------- */
.hero { position: relative; padding-block: var(--space-9) var(--space-8); }
.hero__grid { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: var(--space-8); align-items: center; }
.hero__role {
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 800;
  letter-spacing: 0.22em; text-transform: uppercase; color: var(--ink-muted); margin-bottom: var(--space-4);
}
/* Le titre du hero est le logo vectoriel, comme la navbar. `color` sert
   au currentColor du SVG. Ici on pilote par la LARGEUR (et pas la hauteur) :
   le logo est sur une seule ligne, il doit respirer avec la colonne de texte. */
.hero__title { color: var(--accent); margin-bottom: var(--space-5); line-height: 1; }
.brand-logo--hero { height: auto; width: min(100%, 32rem); }
/* (le <em> du titre hero n'existe plus depuis que c'est un logo — règle retirée) */
.hero__quote {
  font-family: var(--font-display); font-style: italic; font-size: var(--fs-lg);
  line-height: var(--lh-snug); color: var(--ink-soft);
  margin: var(--space-5) 0 var(--space-6); max-width: 30ch;
  padding-left: var(--space-5); border-left: 3px solid var(--accent-2);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.hero__media { aspect-ratio: 4 / 5; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; }

/* -----------------------------------------------------------
   7bis. Hero accueil — photo DÉTOURÉE sur le fond sable (05/10/2026)
   Demande de la cliente : « remettre la couleur de fond d'origine de la
   page » avec la photo détourée qu'elle a fournie. Remplace le hero sombre
   plein cadre (16/09 → 04/10), dont tout le code a été retiré (voile,
   navbar transparente, mode plein cadre, point focal).
   Composition : texte à gauche ; à droite, une ARCHE terre (le motif
   « ma bouche est une porte ouverte ») et Boubacar devant, la tête et les
   mains qui débordent du portail. La photo touche le bas du hero : la
   coupe du buste se pose sur la bande sombre qui suit.
   ⚠️ La photo reste pilotée par le CMS (`data-cms-img="hero"`). Elle doit
   être un PNG détouré (fond transparent) — une photo rectangulaire
   marcherait aussi, simplement posée devant l'arche.
   ----------------------------------------------------------- */
.hero--cutout { padding-block: var(--space-8) 0; overflow: hidden; }
.hero--cutout .hero__grid { grid-template-columns: 1.05fr 0.95fr; align-items: end; gap: var(--space-6); }
.hero--cutout .hero__text { align-self: center; padding-bottom: var(--space-8); }
.hero__figure {
  position: relative; margin: 0;
  display: flex; justify-content: center; align-items: flex-end;
  min-height: 420px;
}
/* L'arche derrière Boubacar : terre cuite, avec le même halo ocre décalé que
   les cadres-portails du site (.arch-frame). Ancrée en bas, plus étroite que
   la photo : les mains et le turban en sortent. */
.hero__door {
  position: absolute; z-index: 0; bottom: 0; left: 50%;
  width: 72%; height: 84%; margin-left: -36%;
  border-radius: 999px 999px 0 0;
  background: linear-gradient(180deg, var(--clay-200) 0%, var(--terra-400) 100%);
}
.hero__door::before {
  content: ""; position: absolute; inset: -18px 18px 0 -18px;
  border-radius: inherit; border: 2px solid var(--accent-2); opacity: 0.55;
}
.hero__figure img {
  position: relative; z-index: 1; display: block;
  width: min(100%, 520px); height: auto;
  /* Ombre portée DOUCE qui suit le détourage (drop-shadow, pas box-shadow) :
     la silhouette se détache de l'arche sans effet « autocollant ». */
  filter: drop-shadow(0 18px 28px rgba(42, 27, 13, 0.28));
}
/* Crédit à la VERTICALE, dans le coin haut droit : c'est la seule zone de la
   photo détourée toujours transparente (à droite du turban). En bas, il
   tombait sur la veste blanche et devenait illisible.
   Taille réduite de moitié le 16/10/2026 (« beaucoup plus petit », demande
   cliente) : bas de casse, sans espacement, 8px. */
.hero--cutout .hero__credit {
  position: absolute; z-index: 2; top: var(--space-2); right: 0;
  margin: 0; writing-mode: vertical-rl;
  font-size: 0.5rem; letter-spacing: 0.02em;
  color: var(--ink-muted); opacity: 0.8;
}

/* Variante SANS ARCHE (05/10/2026, demande de la cliente) : Boubacar seul sur
   le sable, rapproché de son nom. Elle tient à la classe `hero--no-door` du
   <header> dans index.html : pour REMETTRE L'ARCHE, il suffit de retirer cette
   classe (l'arche et la mise en page d'origine reviennent telles quelles).
   Rapprochement : les deux colonnes sont plafonnées et centrées ensemble, et la
   photo mord de 4rem sur la gouttière. Le haut gauche du PNG est transparent :
   les mains arrivent ainsi à hauteur du nom, sans rien recouvrir. */
.hero--no-door .hero__door { display: none; }
@media (min-width: 901px) {
  .hero--no-door .hero__grid {
    grid-template-columns: minmax(0, 34rem) minmax(0, 31rem);
    justify-content: center; column-gap: 0;
  }
  .hero--no-door .hero__figure { justify-content: flex-start; margin-left: -4rem; }
  /* Si la photo du CMS n'est pas détourée (rectangle), le texte reste
     au-dessus d'elle et les boutons restent cliquables. */
  .hero--no-door .hero__text { position: relative; z-index: 2; }
}

@media (max-width: 900px) {
  .hero--cutout .hero__grid { grid-template-columns: 1fr; }
  .hero--cutout .hero__text { padding-bottom: 0; }
  .hero__figure { min-height: 0; max-width: 460px; margin-inline: auto; width: 100%; }
}

/* -----------------------------------------------------------
   8. Citation en exergue (la parole du griot)
   ----------------------------------------------------------- */
.pullquote { position: relative; max-width: 40rem; margin-inline: auto; text-align: center; }
.pullquote__mark {
  font-family: var(--font-display); font-size: 3.4rem; line-height: 0.6;
  color: var(--accent-2); display: block; margin-bottom: var(--space-2);
}
/* Ornement arcade (rangée d'arches dessinées) */
.ornament-arcade {
  height: 24px; width: 184px; margin: 0 auto var(--space-5);
  background: var(--arcade) center / contain no-repeat;
}
.pullquote q, .pullquote p {
  font-family: var(--font-display); font-style: italic; font-size: var(--fs-quote);
  line-height: 1.18; color: var(--ink); quotes: none; display: block; margin: 0;
}
.pullquote--accent q, .pullquote--accent p { color: var(--accent); }
.section--dark .pullquote q, .section--dark .pullquote p { color: var(--cream); }
.pullquote__author {
  display: block; font-family: var(--font-body); font-style: normal; font-size: var(--fs-sm);
  font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--ink-muted); margin-top: var(--space-5);
}
.section--dark .pullquote__author { color: var(--on-dark-mute); }

/* -----------------------------------------------------------
   9. Présentation / texte éditorial
   ----------------------------------------------------------- */
.prose p { font-size: var(--fs-md); color: var(--ink-soft); }
.prose em { font-style: italic; color: var(--accent); }
.prose strong { font-weight: 800; color: var(--ink); }
/* Lettrine sur le premier paragraphe de bio */
.prose--drop > p:first-child::first-letter {
  font-family: var(--font-display); font-weight: 600; float: left;
  font-size: 3.6em; line-height: 0.7; padding: 0.05em 0.12em 0 0; color: var(--accent);
}

.split { display: grid; grid-template-columns: 0.82fr 1.18fr; gap: var(--space-8); align-items: center; }
.split__media { aspect-ratio: 3 / 4; }

.tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-5); }
.tag {
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.04em;
  padding: 0.45em 1em; border: 1.5px solid var(--accent); border-radius: 100px;
  color: var(--accent); background: transparent;
}
.section--dark .tag { border-color: var(--ochre-400); color: var(--ochre-400); }

/* -----------------------------------------------------------
   10. Spectacles (rangée d'arches-portails)
   ----------------------------------------------------------- */
.spectacles-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: var(--space-6) var(--space-5); }
.spectacle { display: flex; flex-direction: column; gap: var(--space-3); color: inherit; text-decoration: none; }
.spectacle:hover .spectacle__title { color: var(--accent); }
/* Ligne d'infos sous l'affiche : « N° 01 · 2003 ». Le numéro était incrusté
   en bas de la photo avec un voile sombre ; sur une AFFICHE on ne pose rien
   (elle a déjà son propre texte), il passe donc ici. */
.spectacle__meta { display: flex; align-items: baseline; gap: 0.6em; }
.spectacle__num { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.14em; color: var(--accent-2); }
.spectacle__meta .spectacle__year::before { content: "·"; margin-right: 0.6em; color: var(--ink-muted); }
.spectacle__see {
  font-weight: 800; font-size: var(--fs-xs); letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--accent); display: inline-flex; align-items: center; gap: 0.4em;
}
.spectacle__see::after { content: "→"; transition: transform 0.2s var(--ease); }
.spectacle:hover .spectacle__see::after { transform: translateX(4px); }
/* Visuel d'une carte : depuis le 16/10/2026, une PHOTO de scène (choix de la
   cliente) — sauf Voyage sans Visa et Toute vie conte, qui gardent leur
   AFFICHE. Toutes les cartes ont donc le même cadre paysage 4/3 (les photos
   vont de 1,18 à 1,5 : 4/3 rogne au plus 11 % de chaque côté, sans couper de
   musicien) ; une affiche y est posée en entier (`.is-poster`, posé par
   `fitCardVisuals`), jamais rognée : son texte va jusqu'au bord.
   Rectangle et non arche : le haut arrondi coupait le texte des affiches. */
.spectacle__media {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-lg);
  overflow: hidden; position: relative;
  background: var(--bg-clay);
  box-shadow: var(--shadow-md);
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease);
}
.spectacle:hover .spectacle__media { transform: translateY(-6px); box-shadow: 0 26px 60px -24px rgba(42, 27, 13, 0.55); }
.spectacle__media img {
  display: block; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.4s var(--ease);
}
.spectacle__media.is-ready img { opacity: 1; }
/* Affiche dans un cadre paysage : posée au centre, entière, avec une ombre
   qui suit ses bords (drop-shadow, les bandes latérales sont transparentes),
   sur le fond argile des cadres vides. Comme une affiche au mur. */
.spectacle__media.is-poster { background: radial-gradient(circle at 50% 38%, var(--clay-200), var(--paper-300)); }
.spectacle__media.is-poster img {
  object-fit: contain; padding: 7% 0;
  filter: drop-shadow(0 10px 16px rgba(42, 27, 13, 0.32));
}
.spectacle__fallback {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-family: var(--font-display); font-style: italic; font-size: 3rem; color: var(--terra-400);
  background: radial-gradient(circle at 50% 38%, var(--clay-200), var(--paper-300));
}
.spectacle__year { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.14em; color: var(--accent); }
.spectacle__title { font-size: var(--fs-lg); margin: 0; transition: color 0.2s; }
.spectacle__desc { font-size: var(--fs-sm); color: var(--ink-muted); margin: 0; }

/* --- Fiche spectacle (page dédiée) --- */
.spectacle-back {
  display: inline-flex; align-items: center; gap: 0.5em; font-weight: 800; font-size: var(--fs-sm);
  color: var(--ink-muted); margin-bottom: var(--space-6);
}
.spectacle-back::before { content: "←"; transition: transform 0.2s var(--ease); }
.spectacle-back:hover { color: var(--accent); }
.spectacle-back:hover::before { transform: translateX(-4px); }
.spectacle-detail { display: grid; grid-template-columns: 0.92fr 1.08fr; gap: var(--space-8); align-items: center; }
/* Le ratio s'adapte à la photo (posé en JS via --cover-ar, borné entre 3/4
   et 4/3). Sans ça, une photo de scène large était recadrée en portrait :
   les musiciens disparaissaient du cadre. 3/4 reste le défaut si pas de JS. */
.spectacle-detail__cover { aspect-ratio: var(--cover-ar, 1200 / 1697); align-self: center; }
/* Cadre de l'affiche sur la fiche : rectangle (pas d'arche, qui coupait le
   texte de l'affiche) + le même halo ocre décalé que .arch-frame, pour
   garder la signature visuelle du site. */
.poster-frame { position: relative; }
.poster-frame::before {
  content: ""; position: absolute; inset: 18px -18px -18px 18px;
  border-radius: var(--radius-lg); background: var(--accent-2); opacity: 0.22; z-index: 0;
}
.poster {
  position: relative; z-index: 1; height: 100%;
  border-radius: var(--radius-lg); overflow: hidden;
  background: radial-gradient(circle at 50% 38%, var(--clay-200), var(--paper-300));
  box-shadow: var(--shadow-md);
}
.poster img { display: block; width: 100%; height: 100%; object-fit: cover; }
.spectacle-media { margin-top: var(--space-8); }

/* Teaser (champ CMS `teaser`) : même cadre que le visuel de la fiche (coins
   arrondis + halo ocre décalé), au format vidéo. */
.spectacle-teaser { margin-top: var(--space-8); }
.spectacle-teaser__frame { aspect-ratio: 16 / 9; max-width: 56rem; }
.spectacle-teaser .poster { background: var(--bg-dark); }
.spectacle-teaser iframe { display: block; width: 100%; height: 100%; border: 0; }
/* Avertissement cookies sous le teaser : 18px = le halo ocre qui déborde. */
.video-note { margin: calc(18px + var(--space-3)) 0 0; font-size: var(--fs-xs); color: var(--ink-muted); }
/* Vignette cliquable : le lecteur YouTube ne se charge qu'au clic (script.js). */
.video-facade {
  position: relative; display: block; width: 100%; height: 100%;
  padding: 0; border: 0; background: #000; cursor: pointer; overflow: hidden;
}
.video-facade img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 0.6s var(--ease); }
.video-facade::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 50%, rgba(42, 27, 13, 0.05), rgba(42, 27, 13, 0.4));
}
.video-facade__play {
  position: absolute; z-index: 1; left: 50%; top: 50%;
  width: 76px; height: 76px; margin: -38px 0 0 -38px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent); color: var(--on-accent);
  box-shadow: 0 12px 30px -8px rgba(0, 0, 0, 0.55);
  transition: transform 0.3s var(--ease), background 0.3s var(--ease);
}
.video-facade__play svg { width: 32px; height: 32px; margin-left: 4px; }
.video-facade:focus-visible { outline: 3px solid var(--accent-2); outline-offset: -3px; }
@media (hover: hover) {
  .video-facade:hover img { transform: scale(1.03); }
  .video-facade:hover .video-facade__play { transform: scale(1.08); background: var(--accent-hover); }
}
@media (max-width: 720px) {
  .video-facade__play { width: 60px; height: 60px; margin: -30px 0 0 -30px; }
  .video-facade__play svg { width: 26px; height: 26px; }
}
.spectacle-detail__num {
  font-family: var(--font-display); font-size: clamp(3rem, 7vw, 5.4rem); line-height: 0.9;
  color: var(--accent-2); display: block; margin-bottom: var(--space-3);
}
.spectacle-detail__year { font-size: var(--fs-sm); font-weight: 800; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
.spectacle-detail__title { font-size: var(--fs-3xl); margin: var(--space-2) 0 var(--space-5); }
.spectacle-detail__lede { font-size: var(--fs-md); color: var(--ink-soft); }
.spectacle-nav {
  display: flex; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap;
  border-top: 1px solid var(--divider); margin-top: var(--space-8); padding-top: var(--space-5);
}
.spectacle-nav a { display: inline-flex; flex-direction: column; gap: 2px; color: var(--ink); font-weight: 700; }
.spectacle-nav a span { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); }
.spectacle-nav a:hover { color: var(--accent); }
.spectacle-nav a.is-next { text-align: right; margin-left: auto; }

/* Zone description de la fiche (toujours présente) */
.spectacle-about { margin-top: var(--space-8); padding-top: var(--space-7); border-top: 1px solid var(--divider); }
.spectacle-about .placeholder { color: var(--ink-muted); font-style: italic; }

/* Pages Médiation (Ateliers / Formation / Master-class) : même traitement
   que la zone description d'une fiche spectacle, en colonne unique. */
.offer-detail { margin-top: var(--space-8); padding-top: var(--space-7); border-top: 1px solid var(--divider); }
.offer-detail__title { font-size: var(--fs-xl); margin: 0 0 var(--space-5); }
.offer-detail .placeholder { color: var(--ink-muted); font-style: italic; }

/* Groupes de spectacles (En diffusion / En création) */
.spectacles-group { margin-bottom: var(--space-9); }
.spectacles-group:last-child { margin-bottom: 0; }
.spectacles-group__title { font-size: var(--fs-xl); margin-bottom: var(--space-6); display: inline-block; }

/* Biographie — "Ils ont accueilli Boubacar" */
.reflist { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 0 var(--space-6); }
.reflist__item {
  display: flex; align-items: baseline; gap: var(--space-3);
  padding: var(--space-4) 0; border-bottom: 1px solid var(--divider);
  transition: padding-left 0.25s var(--ease);
}
.reflist__item::before { content: "❯"; color: var(--accent-2); font-size: 0.7em; }
.reflist__item:hover { padding-left: var(--space-3); }
.reflist__name { font-family: var(--font-display); font-size: var(--fs-md); color: var(--ink); }
.reflist__detail { font-size: var(--fs-sm); color: var(--ink-muted); margin-left: auto; }

/* Médiation & Formation — blocs-arches numérotés (éditorial) */
.offers-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); gap: var(--space-6); }
.offer {
  position: relative; overflow: hidden;
  padding: var(--space-7) var(--space-6) var(--space-6);
  background: var(--bg-card);
  border: 1px solid var(--divider);
  border-radius: 96px 96px var(--radius-lg) var(--radius-lg);
  transition: transform 0.4s var(--ease), box-shadow 0.4s;
}
.offer:hover { transform: translateY(-8px); box-shadow: var(--shadow-md); }
.offer::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; height: 5px;
  background: var(--accent-2);
}
.offer__num {
  display: block; font-family: var(--font-display); font-style: italic;
  font-size: 3.4rem; line-height: 0.9; color: var(--clay-200); margin-bottom: var(--space-3);
}
.offer__type { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }
.offer__title { font-size: var(--fs-lg); margin: var(--space-2) 0 var(--space-3); }
.offer__desc { font-size: var(--fs-base); color: var(--ink-muted); margin: 0; }

/* Contact — cartes contacts (Boubacar, Le Puits à Paroles, CRICAO) */
.contacts-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--space-6); }
.contact-card {
  padding: var(--space-7) var(--space-6) var(--space-6);
  background: var(--bg-card); border: 1px solid var(--divider);
  border-radius: 80px 80px var(--radius-lg) var(--radius-lg);
  border-top: 3px solid var(--accent);
  transition: transform 0.4s var(--ease), box-shadow 0.4s;
}
.contact-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); }
.contact-card__name { font-family: var(--font-display); font-size: var(--fs-lg); margin: 0 0 var(--space-1); }
.contact-card__role { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.1em; text-transform: uppercase; color: var(--accent); }
.contact-card__lines { display: flex; flex-direction: column; gap: var(--space-1); margin-top: var(--space-4); font-size: var(--fs-sm); }
.contact-card__lines a { color: var(--ink); border-bottom: 1px solid var(--accent); width: fit-content; }
.contact-card__lines a:hover { color: var(--accent); }
/* Logo de la structure (champ CMS facultatif), calé EN BAS de la carte :
   en haut, les noms ne seraient plus alignés d'une carte à l'autre (la carte
   de Boubacar n'a pas de logo). `order` le déplace sans changer l'ordre de
   lecture. Un logo JPEG a un fond blanc : `multiply` le fond dans la carte. */
.contact-card { display: flex; flex-direction: column; }
.contact-card__logo {
  order: 99; margin-top: auto; padding-top: var(--space-5);
  /* 108px dont 24px de marge haute (padding) : le logo lui-même fait ~84px. */
  display: block; height: 108px; width: auto; max-width: 180px; object-fit: contain; object-position: left bottom;
}
.contact-card__logo[src$=".jpg"], .contact-card__logo[src$=".jpeg"] { mix-blend-mode: multiply; }

/* Entrée douce de la navbar (une fois la page prête) */
html.anim-ready .nav { animation: nav-drop 0.5s var(--ease) both; }
@keyframes nav-drop { from { transform: translateY(-100%); opacity: 0; } }
@keyframes nav-item-in { from { opacity: 0; transform: translateY(-12px); } to { opacity: 1; transform: none; } }

/* -----------------------------------------------------------
   11. Agenda
   ----------------------------------------------------------- */
.agenda-list { display: flex; flex-direction: column; }
.agenda-item {
  display: grid; grid-template-columns: auto 1fr auto; gap: var(--space-5); align-items: center;
  padding: var(--space-5) 0; border-bottom: 1px solid var(--divider);
}
.agenda-item:first-child { border-top: 1px solid var(--divider); }
.agenda-item__date {
  text-align: center; min-width: 76px; line-height: 1;
  border-right: 2px solid var(--accent-2); padding-right: var(--space-4);
}
.agenda-item__day { font-family: var(--font-display); font-size: 2.8rem; color: var(--accent); display: block; }
.agenda-item__month { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--ink-muted); }
.agenda-item__main h3 { font-size: var(--fs-md); margin: 0 0 var(--space-1); }
.agenda-item__meta { font-size: var(--fs-sm); color: var(--ink-muted); margin: 0; }
.agenda-item__cta { white-space: nowrap; }
.agenda-status {
  font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-muted); padding: 0.4em 0.9em; border: 1px solid var(--divider); border-radius: 100px;
}

.empty-state { text-align: center; padding: var(--space-8) var(--space-4); border: 1.5px dashed var(--divider); border-radius: var(--radius-lg); color: var(--ink-muted); }
.empty-state p { font-family: var(--font-display); font-style: italic; font-size: var(--fs-lg); color: var(--ink-muted); }

/* -----------------------------------------------------------
   12. Galerie & presse & liens
   ----------------------------------------------------------- */
.gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-4); }
.gallery figure { margin: 0; border-radius: var(--radius-lg); overflow: hidden; background: var(--bg-soft); aspect-ratio: 4 / 3; box-shadow: var(--shadow-md); }
.gallery figure img, .gallery figure iframe, .gallery figure video { width: 100%; height: 100%; object-fit: cover; border: 0; }

/* Crédit photo sous le visuel d'une fiche spectacle (vide pour les affiches).
   Toujours un champ CMS, jamais en dur. */
.photo-credit {
  /* 18px : le halo ocre de .arch-frame déborde d'autant sous la photo. */
  margin: calc(18px + var(--space-3)) 0 0; text-align: right;
  font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted);
}
.spectacle-detail__figure { margin: 0; align-self: center; }
/* Crédits de la mosaïque « En images » d'une fiche : sous les photos (et non
   seulement dans la visionneuse), comme sur le site du Puits à Paroles. */
.photo-credit.photo-credit--wall { margin: var(--space-2) 0 0; text-align: left; }

/* --- Mosaïque photo (accueil + page Galerie) ---
   Rendu repris du site FEET (retour Gabin : « magnifique ») : mur d'images
   bord à bord, chaque photo garde SES proportions. Couleurs terre.
   ⚠️ Ce n'est PAS `columns: 4` comme sur FEET : en colonnes CSS la mosaïque
   se remplit colonne par colonne dans l'ordre du CMS, et les bas de colonnes
   tombaient jusqu'à 350px d'écart selon les photos choisies par la cliente.
   Ici c'est une grille à rangées de 2px : le JS (`layoutPhotoWall`) donne à
   chaque photo une hauteur en rangées (--span) d'après ses proportions, et le
   placement automatique de la grille la pose dans la colonne la plus courte.
   Équilibré quel que soit l'ordre ou le nombre de photos. */
.photo-wall {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-auto-rows: 2px; column-gap: 10px; padding-inline: 10px;
}
.photo-wall__item {
  position: relative; display: block; width: 100%;
  /* La marge du bas EST l'espace vertical entre deux photos (comptée dans --span). */
  grid-row-end: span var(--span, 120);
  margin: 0 0 10px; padding: 0; border: 0; border-radius: var(--radius);
  /* Fond argile : c'est ce qu'on voit le temps que la photo arrive. */
  background: var(--paper-300); cursor: zoom-in; overflow: hidden;
}
/* Le `hidden` posé en JS (fichier introuvable) doit gagner sur display:block. */
.photo-wall__item[hidden] { display: none; }
.photo-wall__item img {
  /* 100% de la case : --span est arrondi aux 2px, `cover` absorbe l'écart
     (au plus 2px rognés) au lieu de laisser un liseré de fond. */
  display: block; width: 100%; height: 100%; object-fit: cover;
  filter: saturate(0.92);
  transition: transform 0.9s var(--ease), filter 0.4s var(--ease);
}
.photo-wall__item::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(180deg, rgba(42, 27, 13, 0) 55%, rgba(42, 27, 13, 0.6));
  opacity: 0; transition: opacity 0.35s var(--ease);
}
.photo-wall__zoom {
  position: absolute; right: 12px; bottom: 12px; z-index: 1;
  width: 38px; height: 38px; border-radius: 50%;
  background: var(--accent); color: var(--on-accent);
  display: grid; place-items: center;
  opacity: 0; transform: translateY(6px);
  transition: opacity 0.35s var(--ease), transform 0.35s var(--ease);
}
.photo-wall__zoom svg { width: 18px; height: 18px; }
.photo-wall__item:focus-visible { outline: 3px solid var(--accent-2); outline-offset: 3px; }
.photo-wall__item:focus-visible::after,
.photo-wall__item:focus-visible .photo-wall__zoom { opacity: 1; transform: none; }
/* Survol réservé aux vraies souris : sur téléphone un :hover reste « collé »
   après le toucher et laisserait la loupe affichée. */
@media (hover: hover) {
  .photo-wall__item:hover img { transform: scale(1.05); filter: saturate(1.04); }
  .photo-wall__item:hover::after,
  .photo-wall__item:hover .photo-wall__zoom { opacity: 1; transform: none; }
}
@media (max-width: 1100px) { .photo-wall { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (max-width: 720px) {
  .photo-wall { grid-template-columns: repeat(2, minmax(0, 1fr)); column-gap: 6px; padding-inline: 6px; }
  .photo-wall__item { margin-bottom: 6px; }
}
/* Mosaïque dans une fiche spectacle (« En images ») : dans le conteneur et
   non bord à bord, 2 ou 3 colonnes selon le nombre de photos (--cols posé
   en JS). Double classe = plus prioritaire que .photo-wall et ses media
   queries, définis juste au-dessus. */
.photo-wall.photo-wall--inline { padding-inline: 0; grid-template-columns: repeat(var(--cols, 3), minmax(0, 1fr)); }
@media (max-width: 720px) {
  .photo-wall.photo-wall--inline { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* Le titre de la section galerie est dans .container, la mosaïque en dehors
   (bord à bord, comme FEET) : on garde l'air entre les deux. */
.section--gallery .container { margin-bottom: var(--space-6); }

/* --- Visionneuse photo --- */
.lightbox {
  position: fixed; inset: 0; z-index: 5000;
  background: rgba(30, 19, 9, 0.96);
  display: grid; place-items: center;
  padding: clamp(16px, 4vw, 48px);
  opacity: 0; transition: opacity 0.24s var(--ease);
}
.lightbox[hidden] { display: none; }
.lightbox.is-open { opacity: 1; }
.lightbox__figure {
  margin: 0; max-width: min(1200px, 88vw);
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
}
.lightbox__img {
  max-width: 100%; max-height: 74vh; width: auto; height: auto; object-fit: contain;
  box-shadow: 0 30px 80px -30px rgba(0, 0, 0, 0.8);
  transition: opacity 0.2s var(--ease);
}
.lightbox__credit { font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--on-dark-mute); }
.lightbox__credit[hidden] { display: none; }
.lightbox__btn {
  position: absolute; width: 52px; height: 52px; display: grid; place-items: center;
  border-radius: 50%; cursor: pointer;
  background: rgba(246, 231, 210, 0.08); border: 1px solid rgba(246, 231, 210, 0.24); color: var(--cream);
  transition: background 0.2s var(--ease), border-color 0.2s var(--ease), transform 0.15s var(--ease);
}
.lightbox__btn svg { width: 24px; height: 24px; }
.lightbox__btn:hover { background: var(--accent); border-color: var(--accent); }
.lightbox__btn:active { transform: scale(0.94); }
.lightbox__btn:focus-visible { outline: 2px solid var(--ochre-400); outline-offset: 3px; }
.lightbox__close { top: clamp(12px, 3vw, 28px); right: clamp(12px, 3vw, 28px); }
.lightbox__nav { top: 50%; margin-top: -26px; }
.lightbox__nav--prev { left: clamp(8px, 2vw, 28px); }
.lightbox__nav--next { right: clamp(8px, 2vw, 28px); }
.lightbox__counter {
  position: absolute; bottom: clamp(14px, 3vw, 26px); left: 50%; transform: translateX(-50%); margin: 0;
  font-size: 0.75rem; letter-spacing: 0.18em; color: var(--on-dark-mute); font-variant-numeric: tabular-nums;
}
body.is-locked { overflow: hidden; }
/* Téléphone : les flèches passent en bas, de part et d'autre du compteur,
   au lieu de couvrir la photo à mi-hauteur. */
@media (max-width: 720px) {
  .lightbox__btn { width: 46px; height: 46px; }
  .lightbox__nav { top: auto; bottom: 12px; margin-top: 0; }
  .lightbox__img { max-height: 66vh; }
}
@media (prefers-reduced-motion: reduce) {
  .lightbox, .lightbox__img, .photo-wall__item img { transition: none; }
}

.press-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--space-5); }
.press-card { background: var(--bg-card); border: 1px solid var(--divider); border-left: 4px solid var(--accent); border-radius: var(--radius-lg); padding: var(--space-6); }
.press-card blockquote { font-family: var(--font-display); font-style: italic; font-size: var(--fs-md); line-height: var(--lh-snug); margin: 0 0 var(--space-4); color: var(--ink); }
.press-card cite { font-style: normal; font-size: var(--fs-sm); font-weight: 800; color: var(--ink-muted); }

.links-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-4); }
.link-card {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  padding: var(--space-5); background: var(--bg-card); border: 1px solid var(--divider);
  border-radius: var(--radius-lg); transition: border-color 0.2s, transform 0.2s var(--ease);
}
.link-card:hover { border-color: var(--accent); transform: translateY(-2px); }
.link-card__label { font-weight: 800; color: var(--ink); }

/* -----------------------------------------------------------
   13. Partenaires
   ----------------------------------------------------------- */
.partners-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: var(--space-5); }
.partner { padding: var(--space-6); background: var(--bg-card); border: 1px solid var(--divider); border-radius: var(--radius-lg); border-top: 4px solid var(--accent-2); }
.partner__type { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.12em; text-transform: uppercase; color: var(--accent-2); }
.partner h3 { font-size: var(--fs-md); margin: var(--space-2) 0; }
.partner p { font-size: var(--fs-sm); color: var(--ink-muted); }

/* -----------------------------------------------------------
   14. Contact / formulaire
   ----------------------------------------------------------- */
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-8); }
.contact-info dt { font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-muted); margin-top: var(--space-5); }
.contact-info dd { margin: var(--space-1) 0 0; font-size: var(--fs-md); }
.contact-info dd a { color: var(--ink); border-bottom: 2px solid var(--accent); }
.contact-info dd a:hover { color: var(--accent); }

.form-field { margin-bottom: var(--space-4); }
.form-field label { display: block; font-size: var(--fs-sm); font-weight: 800; margin-bottom: var(--space-2); color: var(--ink-soft); }
.form-field input, .form-field textarea {
  width: 100%; font-family: var(--font-body); font-size: var(--fs-base);
  padding: 0.85em 1em; border: 2px solid var(--divider); border-radius: var(--radius);
  background: var(--bg-card); color: var(--ink); transition: border-color 0.2s;
}
.form-field input:focus, .form-field textarea:focus { border-color: var(--accent); outline: none; }
.form-field textarea { min-height: 140px; resize: vertical; }

/* -----------------------------------------------------------
   15. Footer (bande terre nuit)
   ----------------------------------------------------------- */
.footer { background: var(--bg-dark); color: var(--on-dark); padding-block: var(--space-8) var(--space-6); }
.footer a { color: var(--on-dark); }
.footer a:hover { color: var(--ochre-400); }
.footer__grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr; gap: var(--space-7); margin-bottom: var(--space-7); }
/* Idem navbar : `color` en ocre → le logo vire à l'ocre tout seul sur le fond
   sombre, sans second fichier SVG. C'est tout l'intérêt du currentColor. */
.footer__brand { color: var(--ochre-400); }
.footer__brand .brand-logo { height: 2.4rem; }
.footer__brand span { display: block; font-family: var(--font-body); font-size: 0.62rem; font-weight: 800; letter-spacing: 0.24em; text-transform: uppercase; color: var(--ochre-400); margin-top: var(--space-2); }
.footer h4 { color: var(--cream); font-family: var(--font-body); font-size: var(--fs-xs); font-weight: 800; letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: var(--space-4); }
.footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.footer__licences { margin: var(--space-3) 0 0; font-size: var(--fs-xs); color: var(--on-dark-mute); }
.footer__bottom { border-top: 1px solid rgba(246, 231, 210, 0.14); padding-top: var(--space-5); display: flex; justify-content: space-between; flex-wrap: wrap; gap: var(--space-3); font-size: var(--fs-sm); color: var(--on-dark-mute); }

/* -----------------------------------------------------------
   16. Page header (pages secondaires)
   ----------------------------------------------------------- */
.page-head { padding-block: var(--space-8) var(--space-6); }
.page-head h1 { font-size: var(--fs-3xl); }
.page-head h1::after {
  content: ""; display: block; height: 14px; width: clamp(110px, 38%, 220px);
  margin-top: 0.45rem; background: var(--brush) left center / contain no-repeat;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 0.7s var(--ease) 0.12s;
}
.page-head h1.brush-drawn::after { clip-path: inset(0 0 0 0); }
.page-head p { font-size: var(--fs-md); color: var(--ink-muted); max-width: var(--measure); }

/* -----------------------------------------------------------
   17. Scroll reveal
   ----------------------------------------------------------- */
.has-reveal [data-reveal] { opacity: 0; transform: translateY(42px) scale(0.985); transition: opacity 0.85s var(--ease), transform 0.85s var(--ease); }
.has-reveal [data-reveal].is-revealed { opacity: 1; transform: none; }

/* Entrée du hero : le nom brush se lève, l'arche se pose. */
html.anim-ready .hero__role,
html.anim-ready .hero__title,
html.anim-ready .hero__quote,
html.anim-ready .hero__actions { animation: rise-in 0.9s var(--ease) both; }
html.anim-ready .hero__title { animation-delay: 0.08s; }
html.anim-ready .hero__quote { animation-delay: 0.18s; }
html.anim-ready .hero__actions { animation-delay: 0.28s; }
html.anim-ready .hero__media { animation: arch-settle 1s var(--ease) 0.15s both; }
/* Hero détouré : l'arche se pose, puis la photo apparaît en simple fondu.
   Elle ne bouge plus du tout (ni montée à l'arrivée, ni parallaxe à la souris,
   retirée de script.js) : « qu'elle reste fixe », demande cliente du 16/10. */
html.anim-ready .hero__door { animation: arch-settle 1s var(--ease) 0.05s both; }
html.anim-ready .hero__figure img { animation: fade-in 0.9s var(--ease) 0.15s both; }
@keyframes rise-in { from { opacity: 0; transform: translateY(28px); } }
@keyframes fade-in { from { opacity: 0; } }
@keyframes arch-settle { from { opacity: 0; transform: translateY(30px) scale(0.96); } }

/* Respiration organique de l'arche (vie / nature) — coupée si reduce-motion. */
@media (prefers-reduced-motion: no-preference) {
  .hero__media .arch { animation: gentle-float 6.5s ease-in-out infinite; }
  .split__media .arch { animation: gentle-float 7.5s ease-in-out infinite; }
}
@keyframes gentle-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }

/* -----------------------------------------------------------
   18. Responsive
   ----------------------------------------------------------- */
@media (max-width: 900px) {
  .hero__grid { grid-template-columns: 1fr; gap: var(--space-6); }
  .hero__media { max-width: 300px; margin-inline: auto; }
  .arch-frame::before, .poster-frame::before { inset: 12px -12px -12px 12px; }
  .split { grid-template-columns: 1fr; gap: var(--space-6); }
  .split__media { max-width: 360px; }
  .spectacle-detail { grid-template-columns: 1fr; gap: var(--space-6); }
  .spectacle-detail__cover, .spectacle-detail__figure { max-width: 360px; }
  .contact-grid { grid-template-columns: 1fr; gap: var(--space-6); }
  .footer__grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 720px) {
  /* Échelle d'espacement resserrée : --space-9 valait 96px de padding EN HAUT
     ET EN BAS de chaque section, soit près d'un quart d'écran perdu deux fois
     par section. On réduit les tokens plutôt que chaque règle : tout le site
     en profite d'un coup. Ces 4 tokens ne servent qu'à des espacements
     structurels (sections, gaps de grille), jamais à de la typo. */
  :root { --space-7: 2.25rem; --space-8: 3rem; --space-9: 3.75rem; }

  /* Le logo du hero occupait 89% de la largeur d'écran, bord à bord. */
  .brand-logo--hero { width: min(100%, 17rem); }
  .hero__role { font-size: 0.62rem; letter-spacing: 0.18em; }

  /* ---- Hero : recomposition mobile (21/08/2026) ----
     Le portrait arrivait APRÈS toute la colonne de texte, donc très bas, et
     il était centré à 300px sous un texte aligné à gauche sur toute la
     largeur — décalage visible à l'œil. On réordonne :
        sur-titre → nom → PORTRAIT → citation → boutons
     `display:contents` fait remonter les enfants du <div> de texte au rang
     d'items de la grille, ce qui rend `order` utilisable SANS toucher au HTML
     (donc sans rien casser en desktop, où la règle ne s'applique pas). */
  .hero__grid > div:first-child { display: contents; }
  .hero__role    { order: 1; }
  .hero__title   { order: 2; margin-bottom: 0; }
  .hero__media, .hero__figure { order: 3; }
  .hero__quote   { order: 4; }
  .hero__actions { order: 5; }
  /* Les marges propres à chaque élément feraient doublon avec le gap de la
     grille et casseraient le rythme régulier. */
  .hero .hero__quote { margin: 0; }
  .hero__quote { text-wrap: balance; }
  .hero__grid { gap: var(--space-5); }
  .hero { padding-block: var(--space-7) var(--space-8); }
  /* La photo détourée arrive au milieu (après le nom) : son buste coupé net
     et le pied de l'arche se fondent dans le sable au lieu de s'arrêter
     sur une ligne droite en travers de l'écran. */
  /* Un dégradé POSÉ PAR-DESSUS plutôt qu'un mask-image : un masque coupait
     aussi le liseré ocre de l'arche, qui déborde de sa boîte. */
  .hero__figure::after {
    /* -28px : couvre aussi l'ombre portée de la photo, qui dépasse dessous. */
    content: ""; position: absolute; inset: auto 0 -28px 0; height: calc(28% + 28px); z-index: 1;
    background: linear-gradient(to bottom, transparent, var(--bg));
    pointer-events: none;
  }
  /* Sans arche, l'ombre portée débordait du fondu ci-dessus sur les côtés et
     dessinait un rectangle plus clair sous la photo : on s'en passe. */
  .hero--no-door .hero__figure img { filter: none; }
  /* Le portrait prend la largeur de la colonne, comme le texte : il n'y a
     plus de vignette centrée désaxée. Le halo de .arch-frame déborde de 12px
     à droite, ce qui reste dans la gouttière du conteneur. */
  .hero__media { max-width: none; margin-inline: 0; }
  /* Deux boutons de largeurs différentes empilés faisaient désordre.
     Pleine largeur = un bloc net, et une cible tactile pleine. */
  .hero__actions { flex-direction: column; align-items: stretch; gap: var(--space-3); }
  .hero__actions .btn { width: 100%; justify-content: center; padding-block: 1.05em; }

  .agenda-item { grid-template-columns: auto 1fr; gap: var(--space-4); }
  .agenda-item__cta { grid-column: 1 / -1; justify-self: start; }
  .footer__grid { grid-template-columns: 1fr; }
  /* Les liens du pied de page ne faisaient que 21px de haut : trop petits pour
     le pouce. 44px est le minimum recommandé pour une cible tactile. */
  .footer ul { gap: 0; }
  .footer ul a { display: flex; align-items: center; min-height: 44px; }

  /* ---- Répertoire des spectacles : 2 colonnes (21/08/2026) ----
     En une seule colonne, chaque carte faisait ~465px de haut. Les spectacles
     sans visuel (6 sur 9 aujourd'hui) empilaient donc des arches vides de la
     hauteur d'un demi-écran : un mur d'aplats argile qu'il fallait scroller.
     En deux colonnes la page se lit comme une planche d'affiches, et les
     arches vides deviennent un motif au lieu d'un vide.
     La description passe à la trappe à cette largeur — elle est reprise en
     entier sur la fiche du spectacle. */
  .spectacles-grid { grid-template-columns: 1fr 1fr; gap: var(--space-6) var(--space-4); }
  .spectacle { gap: var(--space-2); }
  /* Deux lignes réservées : sans ça, un titre court (« Au fil de l'eau »)
     contre un titre long (« Le pardon de l'araignée ») décalait la rangée
     suivante de 21px, et l'espacement entre rangées devenait irrégulier. */
  .spectacle__title { font-size: 1.14rem; line-height: 1.16; min-height: 2.32em; }
  /* L'affiche ne doit jamais s'étirer quand la carte est plus haute que son
     contenu : son aspect-ratio est le garant de la régularité de la planche. */
  .spectacle__media { flex: none; }
  .spectacle__desc, .spectacle__see { display: none; }
  .spectacle__fallback { font-size: 2rem; }

  /* ---- Sur-titres de section ----
     `.eyebrow` est un flex [trait | texte]. Dès que le libellé passe sur deux
     lignes (« ACTION CULTURELLE & MÉDIATION »), la 2e ligne s'aligne sur le
     texte et laisse le trait orphelin à mi-hauteur. Le trait passe au-dessus :
     le libellé récupère toute la largeur et reste aligné à gauche. */
  .eyebrow { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .eyebrow::before { width: 2.6rem; }
}

/* ---- Écrans mobiles COURTS (iPhone SE et assimilés) ----
   Le menu est calibré pour ~810px de haut. Sous ~700px il demandait 123px de
   scroll et « Contact » tombait pile sur le bord bas. On resserre l'échelle
   et les marges : les 11 entrées tiennent alors sans scroll.
   Ciblé sur la HAUTEUR, pas la largeur — c'est la hauteur qui manque. */
/* -----------------------------------------------------------
   Menu burger — téléphones ET tablettes (≤ 1023px), depuis le 05/10/2026.
   Avant : seulement ≤ 720px, mais avec 7 liens et le sélecteur de langue,
   le menu en ligne passait sur 2 lignes entre 721 et 1000px et débordait
   à 721px. Règles déplacées telles quelles depuis le bloc téléphone.
   ----------------------------------------------------------- */
@media (max-width: 1023px) {
  /* ---- Menu mobile ----
     Refonte esthétique (21/08/2026). Ce qui a changé et POURQUOI :
     - Les `border-bottom` sous chaque lien sont SUPPRIMÉS. Une ligne sous
       chaque entrée donnait un air de liste de réglages système. Ce sont
       maintenant l'échelle et l'espacement qui hiérarchisent.
     - Le panneau occupe toute la hauteur sous la navbar. Avant il s'arrêtait
       au dernier lien : on voyait la page derrière, et « Contact » se faisait
       couper par le `max-height`.
     - `justify-content` reste en flex-start : un `center` sur un conteneur
       scrollable rend le HAUT du contenu inatteignable si ça déborde
       (petits écrans). Piège classique du flex centré. */
  .nav__toggle { display: block; }
  /* Langues en bas du panneau, en pastilles assez grandes pour le pouce. */
  .nav__lang { margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid var(--divider); }
  .nav__links .lang-switch { gap: var(--space-2); }
  .nav__links .lang-switch a { font-size: 0.9rem; padding: 0.7em 0.95em; border: 1px solid var(--divider); }
  .nav__links .lang-switch a.is-current { border-color: var(--accent); }
  .nav__links {
    position: fixed; top: 74px; left: 0; right: 0;
    height: calc(100dvh - 74px);
    flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0;
    background: var(--bg);
    padding: var(--space-6) var(--container-px) var(--space-7);
    /* ⚠️ CE BLOC A DÉJÀ CAUSÉ UN BUG EN PROD (22/08/2026) — ne pas y toucher
       sans tester le menu FERMÉ.
       Le panneau a une hauteur FIXE (plein écran) et un fond OPAQUE, et il vient
       APRÈS le logo et le bouton dans le HTML : tout ce qui dépasse à l'écran
       les recouvre. Avec `translateY(-100%)`, son bord bas retombait pile sur
       les 74px de la navbar → plus de logo, plus de bouton menu, juste le
       dernier lien (« Contact ») en haut de l'écran.
       Deux garde-fous, volontairement redondants :
       1. -120% (et non -100%) : 20% de marge pour sortir franchement de l'écran,
          en tenant compte du `top: 74px`. C'est la valeur qu'avait l'original.
       2. visibility:hidden : même si le calcul du transform déraillait un jour,
          le panneau resterait invisible et hors du parcours clavier. La
          transition sur `visibility` diffère le masquage à la fin de la
          fermeture, sinon le panneau disparaîtrait d'un coup au lieu de
          remonter. */
    transform: translateY(-120%); visibility: hidden;
    transition: transform 0.42s var(--ease), visibility 0.42s var(--ease);
    overflow-y: auto; overscroll-behavior: contain;
  }
  .nav.is-open .nav__links { transform: translateY(0); visibility: visible; }
  /* `display:block` est indispensable : un <a> est inline par défaut, un
     width/padding vertical n'aurait aucun effet (piège déjà rencontré). */
  .nav__links > li > a {
    display: block; width: 100%; border-bottom: 0;
    padding: var(--space-3) 0;
    font-size: 1.45rem; font-weight: 800; letter-spacing: -0.015em;
    color: var(--ink);
  }
  /* Page courante : le trait de pinceau ocre revient. Il était masqué en
     mobile, la page active ne se signalait plus que par sa couleur — trop
     discret. En desktop le ::after est absolu ; ici il repasse dans le flux. */
  .nav__links a[aria-current="page"] { color: var(--accent); }
  .nav__links a[aria-current="page"]::after {
    display: block; position: static; width: 5rem; height: 11px; margin-top: 0.1rem;
  }
  /* Entrée en cascade des entrées : le menu se déplie au lieu d'apparaître
     d'un bloc. Neutralisé par le bloc prefers-reduced-motion en fin de fichier. */
  .nav.is-open .nav__links > li { animation: nav-item-in 0.45s var(--ease) both; }
  .nav.is-open .nav__links > li:nth-child(1) { animation-delay: 0.10s; }
  .nav.is-open .nav__links > li:nth-child(2) { animation-delay: 0.16s; }
  .nav.is-open .nav__links > li:nth-child(3) { animation-delay: 0.22s; }
  .nav.is-open .nav__links > li:nth-child(4) { animation-delay: 0.28s; }
  .nav.is-open .nav__links > li:nth-child(5) { animation-delay: 0.34s; }
  .nav.is-open .nav__links > li:nth-child(6) { animation-delay: 0.40s; }
  .nav.is-open .nav__links > li:nth-child(7) { animation-delay: 0.46s; }
  .nav.is-open .nav__links > li:nth-child(8) { animation-delay: 0.52s; }
}

@media (max-width: 1023px) and (max-height: 700px) {
  .nav__links { padding-top: var(--space-4); padding-bottom: var(--space-5); }
  .nav__links > li > a { font-size: 1.24rem; padding: var(--space-2) 0; }
  .nav__links .nav__sub { margin-bottom: var(--space-2); }
  .nav__links .nav__sub a { min-height: 40px; font-size: 0.96rem; }
  .nav__links a[aria-current="page"]::after { height: 9px; }
}

/* -----------------------------------------------------------
   18b. Transition « entrer dans l'arche » (animation JS maison)
   - .arch-grow : l'overlay qui grossit (créé en JS, styles inline).
   - html.arch-entering::before : voile d'arrivée (anti-flash) qui se
     dissipe pour révéler la fiche, dans la continuité du zoom.
   ----------------------------------------------------------- */
.arch-grow { box-shadow: var(--shadow-md); }

html.arch-entering::before {
  content: ""; position: fixed; inset: 0; z-index: 9999; pointer-events: none;
  background: #E0B488 var(--veil-img, none) center / cover no-repeat;
  opacity: 1; transition: opacity 0.55s ease;
}
html.arch-entering.arch-reveal::before { opacity: 0; }

/* -----------------------------------------------------------
   19. Reduced motion
   ----------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: 0.001ms !important; transition-duration: 0.001ms !important; }
  .has-reveal [data-reveal] { opacity: 1; transform: none; }
}
