/* ==========================================================================
   École Lerel, feuille de style principale
   ========================================================================== */

:root {
  /* Piles de polices, une seule source de vérité, cf. body et h1-h4 */
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-serif: Georgia, "Iowan Old Style", "Palatino Linotype", "Book Antiqua", "Noto Serif", serif;

  --bg: #121013;
  --bg-elevated: #1a171d;
  --bg-elevated-2: #221e26;
  --line: rgba(244, 242, 247, 0.1);
  --text: #f4f2f7;
  --text-muted: #b3aebd;
  --text-faint: #8a8494;
  --accent: #a855f7;
  --accent-soft: #c084fc;
  --accent-dim: rgba(168, 85, 247, 0.14);
  /* Fond du bandeau d'annonce, OPAQUE. Depuis qu'il est fixé, le contenu de la
     page passe derrière : une couleur translucide laissait lire le titre du
     hero à travers. Ces valeurs sont le mélange exact des teintes translucides
     d'origine sur --bg, l'aspect ne change donc pas, seule la transparence
     disparaît. Recalculer si --bg change. */
  --annonce-fond: #271a33;
  --on-accent: #14101a;
  --shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.6);
  --radius-s: 10px;
  --radius-m: 18px;
  --radius-l: 28px;
  --container: 1360px;
  /* Marge latérale de l'en-tête et de l'accueil, qui courent sur toute la
     largeur de l'écran au lieu de la colonne --container. Jusque vers 1500px,
     elle vaut exactement le bord des autres sections (marge de la colonne plus
     sa gouttière), rien ne bouge. Au-delà, elle ne grandit plus que de 2,5vw :
     l'en-tête et l'accueil s'ouvrent vers les bords pendant que les sections
     restent dans leur colonne. Le % est résolu là où la variable est employée,
     sur la largeur du parent du .container. */
  --gouttiere-large: max(clamp(20px, 5vw, 48px),
                         min((100% - var(--container)) / 2 + clamp(20px, 5vw, 48px),
                             80px + 2.5vw));
  --nav-h: 84px;
  /* Hauteur encore visible du bandeau d'annonce. Vaut 0 sans bandeau, et le JS
     la fait décroître au défilement pour que l'en-tête vienne se caler en haut
     sans laisser de vide derrière lui. */
  /* Hauteur de la barre fixée en haut : l'en-tête seul, ou l'annonce plus
     l'en-tête quand une annonce est affichée. Mesurée par le script et
     republiée ici ; la valeur par défaut couvre le cas sans annonce, et le
     temps que le script s'exécute. Tout ce qui doit passer dessous s'y réfère. */
  --haut-fixe: var(--nav-h);
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Le sélecteur universel ne désigne que des éléments : le ::backdrop des
     popups, qui est un pseudo-élément, lui échappe. Son animation d'apparition
     doit donc être neutralisée nommément. */
  .modal::backdrop {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

/* Un élément porteur de l'attribut hidden doit le rester : aucune règle
   display, si spécifique soit-elle, ne doit pouvoir le neutraliser. */
[hidden] {
  display: none !important;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-serif);
  font-weight: 600;
  line-height: 1.15;
  margin: 0 0 0.5em;
  letter-spacing: 0.01em;
}

h1 { font-size: clamp(2.4rem, 5vw + 1rem, 4.4rem); font-weight: 500; }
h2 { font-size: clamp(1.9rem, 3vw + 1rem, 2.8rem); font-weight: 500; }
h3 { font-size: clamp(1.25rem, 1vw + 1rem, 1.6rem); }
h4 { font-size: 1.1rem; }

p { margin: 0 0 1.1em; color: var(--text-muted); }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.78rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--accent-soft);
  font-weight: 600;
  margin-bottom: 1.1em;
}

.eyebrow::before {
  content: "";
  width: 28px;
  height: 1px;
  background: var(--accent-soft);
  display: inline-block;
}

.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 48px);
}

section {
  position: relative;
}

.section-pad {
  padding: clamp(56px, 7vw, 100px) 0;
}

.text-center { text-align: center; }

.lede {
  font-size: clamp(1.05rem, 0.4vw + 1rem, 1.25rem);
  color: var(--text-muted);
}

/* ---------- Ancres de section ---------- */

/* .site-header est en position: fixed sur toute la hauteur var(--nav-h) : sans
   marge de défilement, un saut vers #horaires ou #contact déposerait le titre
   de la section juste dessous, donc hors de vue. Les 24 px supplémentaires
   évitent l'atterrissage au ras de l'en-tête. */
#cours,
#laurence,
#horaires,
#contact {
  scroll-margin-top: calc(var(--haut-fixe) + 24px);
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.55em;
  padding: 0.95em 1.9em;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  border: 1px solid transparent;
  cursor: pointer;
  transition: transform 0.35s var(--ease), background-color 0.35s var(--ease), border-color 0.35s var(--ease), color 0.35s var(--ease);
  white-space: nowrap;
}

.btn-primary {
  background: var(--accent);
  color: var(--on-accent);
}
.btn-primary:hover {
  background: var(--accent-soft);
  transform: translateY(-2px);
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line);
}
.btn-ghost:hover {
  border-color: var(--accent-soft);
  color: var(--accent-soft);
  transform: translateY(-2px);
}

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  color: var(--accent-soft);
  font-weight: 600;
  font-size: 0.95rem;
  position: relative;
}
.link-arrow svg {
  transition: transform 0.3s var(--ease);
  width: 16px;
  height: 16px;
}
.link-arrow:hover svg {
  transform: translateX(5px);
}

/* ---------- Accessibilité : lien d'évitement ---------- */

/* Sorti du flux vers le haut plutôt que masqué : display:none ou
   visibility:hidden le retireraient de l'ordre de tabulation. */
.skip-link {
  position: absolute;
  top: -120px;
  left: 12px;
  z-index: 200;
  padding: 0.85em 1.7em;
  border-radius: 0 0 var(--radius-s) var(--radius-s);
  background: var(--accent);
  color: var(--on-accent);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.skip-link:focus {
  position: fixed;
  top: 12px;
  outline: 3px solid var(--accent-soft);
  outline-offset: 3px;
}

/* Cible du lien d'évitement : le focus s'y pose par programme (tabindex="-1"),
   inutile d'y dessiner un cadre. */
main:focus {
  outline: none;
}

/* ---------- Bandeau d'annonce ---------- */

/* La barre haute contient l'annonce, quand il y en a une, et l'en-tête. Une
   SEULE boîte fixée, et non deux empilées à la main : l'en-tête ne peut donc
   jamais recouvrir l'annonce, quelle que soit la hauteur du texte. C'est
   exactement ce qui arrivait sur mobile, où l'annonce passe à trois lignes
   pendant que l'en-tête restait calé sur la hauteur d'une seule. */
.barre-haute {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 130;
}

/* Piloté par l'administration : fermeture, vacances, rentrée. Il reste
   visible pendant tout le défilement, puisque la barre qui le porte est
   fixée. Une annonce qui disparaît au premier mouvement de molette ne
   prévient personne.
   Prix à payer, assumé : une bande d'écran en moins, mais seulement quand une
   annonce est affichée. */
.annonce {
  position: relative;
  padding: 12px 0;
  background: var(--annonce-fond);
  border-bottom: 1px solid rgba(168, 85, 247, 0.35);
}

.annonce p {
  margin: 0;
  text-align: center;
  color: var(--text);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* Teinte du bandeau, choisie depuis l'administration (annonce.couleur). Le
   gabarit émet « annonce--<couleur> » ; sans ces règles, l'admin proposerait un
   choix sans effet. Fond translucide et filet plein : le texte reste lisible
   quelle que soit la teinte. La règle .annonce ci-dessus tient lieu de violet
   par défaut, y compris si la clé est absente ou inconnue. */
.annonce--ambre  { --annonce-fond: #332915; border-bottom-color: rgba(251, 191, 36, 0.55); }
.annonce--vert   { --annonce-fond: #1a2d22; border-bottom-color: rgba(74, 222, 128, 0.55); }
.annonce--rouge  { --annonce-fond: #331d22; border-bottom-color: rgba(255, 107, 129, 0.6); }
.annonce--neutre { --annonce-fond: #252327; border-bottom-color: rgba(179, 174, 189, 0.5); }

/* ---------- Header / Nav ---------- */

.site-header {
  /* Dans le flux de la barre haute, qui porte le position: fixed. */
  position: relative;
  z-index: 100;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  transition: background-color 0.4s var(--ease), border-color 0.4s var(--ease), backdrop-filter 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}

.site-header.is-scrolled {
  background: rgba(18, 16, 19, 0.82);
  backdrop-filter: blur(14px) saturate(140%);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  border-color: var(--line);
}

.site-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.brand {
  display: flex;
  align-items: center;
  gap: 12px;
  font-family: var(--font-serif);
  font-size: 1.15rem;
  letter-spacing: 0.02em;
  z-index: 110;
}

/* <picture> remplace <img> comme élément flex : sans display, l'inline par
   défaut réintroduit l'interlignage sous le logo. */
.brand picture {
  display: flex;
}

.brand img {
  height: 40px;
  width: auto;
}

.brand-word {
  display: flex;
  flex-direction: column;
  line-height: 1.05;
}

.brand-word small {
  font-family: var(--font-sans);
  font-size: 0.6rem;
  letter-spacing: 0.18em;
  color: var(--text-faint);
  text-transform: uppercase;
  font-weight: 600;
  margin-top: 3px;
}

.main-nav {
  display: flex;
  align-items: center;
  gap: clamp(18px, 2.4vw, 38px);
}

.main-nav a {
  font-size: 1rem;
  font-weight: 500;
  color: var(--text-muted);
  position: relative;
  padding: 6px 0;
  transition: color 0.3s var(--ease);
}

.main-nav a:hover,
.main-nav a.is-active {
  color: var(--text);
}

.main-nav a.is-active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2px;
  background: var(--accent);
  border-radius: 2px;
}

/* Le bouton Contact porte .btn.btn-primary, mais il est AUSSI un .main-nav a ,
   sélecteur plus spécifique (0,1,1) que .btn et .btn-primary (0,1,0). Il perdait
   donc les deux réglages qui font un bouton :
     padding  -> 6px 0, soit aucun rembourrage horizontal, la pilule collait au
                 texte ;
     color    -> var(--text) au lieu de var(--on-accent), ce qui donnait du blanc
                 sur violet à 3,56:1, sous le seuil AA de 4,5:1, quand le noir
                 prévu atteint 4,74:1.
   On les rétablit avec une spécificité suffisante, le :hover doit être repris
   nommément, sinon .main-nav a:hover, de spécificité égale mais déclaré plus
   haut, reprendrait la main au survol.
   Le line-height de 1,65 hérité du body, ajouté au rembourrage, gonflait la
   pilule à 52px de haut quand les autres liens en font 38 : on le resserre pour
   qu'elle garde la hauteur de la barre de liens. */
.nav-cta {
  margin-left: 6px;
}

.main-nav a.nav-cta,
.main-nav a.nav-cta:hover {
  padding: 0.5em 1.2em;
  line-height: 1.2;
  color: var(--on-accent);
}

.nav-toggle {
  display: none;
  z-index: 110;
  background: none;
  border: none;
  width: 40px;
  height: 40px;
  padding: 0;
  cursor: pointer;
  position: relative;
}

.nav-toggle span {
  position: absolute;
  left: 8px;
  right: 8px;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform 0.35s var(--ease), opacity 0.35s var(--ease), top 0.35s var(--ease);
}

.nav-toggle span:nth-child(1) { top: 14px; }
.nav-toggle span:nth-child(2) { top: 20px; }
.nav-toggle span:nth-child(3) { top: 26px; }

.nav-open .nav-toggle span:nth-child(1) { top: 20px; transform: rotate(45deg); }
.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
.nav-open .nav-toggle span:nth-child(3) { top: 20px; transform: rotate(-45deg); }

/* Verrou de défilement du fond pendant que le menu mobile est ouvert.
   Le JS ajoute un padding-right compensatoire pour éviter le saut de mise en page. */
body.nav-open {
  overflow: hidden;
}

@media (max-width: 900px) {
  .nav-toggle { display: block; }

  .main-nav {
    position: fixed;
    inset: 0;
    background: #0d0b0f;
    flex-direction: column;
    justify-content: center;
    gap: 28px;
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.4s var(--ease), transform 0.4s var(--ease), visibility 0.4s;
  }

  .nav-open .main-nav {
    opacity: 1;
    transform: translateY(0);
    visibility: visible;
  }

  .main-nav a { font-size: 1.4rem; color: var(--text); }
  .nav-cta { margin: 10px 0 0; }
}

/* ---------- Hero ---------- */

.hero {
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-top: var(--haut-fixe);
  position: relative;
  isolation: isolate;
}

/* .hero est un flex : son .container, simple élément flex, se rétrécissait à la
   largeur de son contenu et margin: auto le centrait, d'où width: 100%.
   L'accueil et l'en-tête quittent ensuite la colonne de 1360px : sur un grand
   écran elle restait centrée, avec des centaines de pixels vides de chaque
   côté, et le texte de l'accueil avait l'air perdu au milieu. Ils courent sur
   toute la largeur, avec la marge --gouttiere-large. */
.hero > .container,
.site-header .container {
  width: 100%;
  max-width: none;
  padding-inline: var(--gouttiere-large);
}

.hero-bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Déclarée ici et non en style inline : le preload scanner du navigateur
     peut ainsi la découvrir tôt (LCP). Chemin relatif à assets/css/. */
  background-image: url('../img/theatre-ambiance.jpg');
  background-image: -webkit-image-set(url('../img/theatre-ambiance.webp') type('image/webp'),
                                      url('../img/theatre-ambiance.jpg') type('image/jpeg'));
  background-image: image-set(url('../img/theatre-ambiance.webp') type('image/webp'),
                              url('../img/theatre-ambiance.jpg') type('image/jpeg'));
  background-size: cover;
  background-position: center 30%;
}

.hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(18,16,19,0.55) 0%, rgba(18,16,19,0.86) 60%, var(--bg) 100%),
    radial-gradient(60% 60% at 15% 15%, rgba(168,85,247,0.22), transparent 70%);
}

.hero-content {
  max-width: 720px;
  animation: rise 1s var(--ease) both;
}

.hero h1 {
  margin-bottom: 0.35em;
}

.hero h1 em {
  font-style: italic;
  color: var(--accent-soft);
}

.hero-actions {
  display: flex;
  gap: 16px;
  margin-top: 2.2em;
  flex-wrap: wrap;
}

.hero-meta {
  display: flex;
  gap: 28px;
  margin-top: 4rem;
  flex-wrap: wrap;
}

.hero-meta div {
  border-left: 1px solid var(--line);
  padding-left: 16px;
}

.hero-meta strong {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.5rem;
  color: var(--text);
}

.hero-meta span {
  font-size: 0.82rem;
  color: var(--text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Grand écran : le bloc de l'accueil grandit avec la place qu'on lui donne,
   au même seuil que --gouttiere-large. Chaque formule part, à 1500px, de la
   valeur qu'elle avait en dessous : pas de saut au passage du seuil. La
   largeur de l'introduction reste bornée en em, pour des lignes lisibles.
   Déclaré après les règles de base du hero, qu'il doit surcharger à
   spécificité égale. */
@media (min-width: 1500px) {
  .hero-content { max-width: none; }
  .hero h1 { font-size: clamp(4.4rem, 6vw - 20px, 7rem); }
  .hero .lede { font-size: clamp(1.25rem, 1.2vw - 2px, 1.5rem); max-width: 36em; }
  .hero-meta strong { font-size: clamp(1.5rem, 2vw - 6px, 2.1rem); }
}

/* ---------- Page header (404) ---------- */

/* Seule rescapée de l'arborescence d'origine : la page 404, qui ouvre toujours
   sur une <section class="page-hero">. Le fil d'ariane qui l'accompagnait a
   disparu avec les pages internes. */
.page-hero {
  padding: calc(var(--haut-fixe) + 70px) 0 60px;
  position: relative;
}

.page-hero::before {
  content: "";
  position: absolute;
  top: 0; left: 50%;
  transform: translateX(-50%);
  width: 900px; height: 500px;
  background: radial-gradient(closest-side, rgba(168,85,247,0.16), transparent);
  z-index: -1;
  pointer-events: none;
}

/* ---------- Cards / Grid ---------- */

.grid-2 {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(20px, 3vw, 36px);
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 3vw, 32px);
}

@media (max-width: 860px) {
  .grid-2, .grid-3 { grid-template-columns: 1fr; }
}

.course-card {
  background: linear-gradient(180deg, var(--bg-elevated), var(--bg-elevated-2));
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  padding: clamp(28px, 3vw, 44px);
  position: relative;
  overflow: hidden;
  transition: transform 0.5s var(--ease), border-color 0.5s var(--ease);
}

.course-card:hover {
  transform: translateY(-6px);
  border-color: rgba(168,85,247,0.4);
}

.course-card .num {
  font-family: var(--font-serif);
  font-size: 0.85rem;
  color: var(--accent-soft);
  letter-spacing: 0.15em;
  text-transform: uppercase;
}

.course-card h3 {
  margin: 0.6em 0 0.4em;
}

.course-card .quote {
  font-style: italic;
  color: var(--text-faint);
  margin-bottom: 1em;
}

.feature-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
}

@media (max-width: 900px) {
  .feature-row { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .feature-row { grid-template-columns: 1fr; }
}

.feature-item {
  padding: 26px 4px;
  border-top: 1px solid var(--line);
}

.feature-item .icon {
  width: 38px;
  height: 38px;
  border-radius: 10px;
  background: var(--accent-dim);
  color: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
}

.feature-item h4 {
  margin-bottom: 0.4em;
}
.feature-item p {
  font-size: 0.94rem;
  margin: 0;
}

/* ---------- Founder / media-text ---------- */

.split {
  display: grid;
  grid-template-columns: 0.85fr 1.15fr;
  gap: clamp(30px, 5vw, 70px);
  align-items: center;
}

.split.reverse { grid-template-columns: 1.15fr 0.85fr; }
.split.reverse .split-media { order: 2; }

@media (max-width: 860px) {
  .split, .split.reverse { grid-template-columns: 1fr; }
  .split.reverse .split-media { order: 0; }
}

.split-media {
  position: relative;
  border-radius: var(--radius-l);
  overflow: hidden;
}

/* Même raison que .brand picture : le wrapper doit reprendre le comportement
   bloc de l'<img> qu'il remplace, sinon interlignage parasite dans le cadre. */
.split-media picture {
  display: block;
  height: 100%;
}

.split-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  aspect-ratio: 4/5;
}

.split-media::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  z-index: 2;
  pointer-events: none;
}

.frame-tag {
  position: absolute;
  bottom: 18px;
  left: 18px;
  background: rgba(18,16,19,0.7);
  backdrop-filter: blur(6px);
  border: 1px solid var(--line);
  padding: 10px 16px;
  border-radius: 999px;
  font-size: 0.8rem;
  letter-spacing: 0.05em;
  z-index: 3;
}

/* ---------- Timeline (bio) ---------- */

.timeline {
  border-left: 1px solid var(--line);
  padding-left: 32px;
  display: flex;
  flex-direction: column;
  gap: 34px;
}

.timeline-item {
  position: relative;
}

.timeline-item::before {
  content: "";
  position: absolute;
  left: -37px;
  top: 4px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 4px var(--accent-dim);
}

.timeline-item .year {
  font-family: var(--font-serif);
  color: var(--accent-soft);
  font-size: 0.95rem;
  letter-spacing: 0.06em;
  margin-bottom: 0.3em;
  display: block;
}

/* ---------- Reviews / CTA banner ---------- */

.cta-banner {
  background: linear-gradient(135deg, var(--bg-elevated), #26202c);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  padding: clamp(36px, 5vw, 60px);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  flex-wrap: wrap;
}

.cta-banner h3 { margin-bottom: 0.3em; }
.cta-banner p { margin: 0; }

.stars {
  color: var(--accent-soft);
  letter-spacing: 3px;
  font-size: 1.1rem;
}

/* En-tête réservé à la feuille imprimée : sur écran, l'identité de l'école est
   déjà partout (en-tête, pied de page, section contact). */
.impression-seule {
  display: none;
}

/* ---------- Horaires : semainier ---------- */

/* Une semaine, cinq colonnes. La version précédente empilait trois listes sur
   toute la largeur du conteneur : l'horaire à gauche, l'activité contre le bord
   opposé, et près de 700 px de vide au milieu. Ici chaque créneau est une carte
   étroite où le contenu s'empile, il n'y a plus de place pour du vide, et la
   lecture suit la question que se pose le visiteur : quel soir puis-je venir ? */
.semaine {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}

/* Les jours ne portent pas tous le même nombre de créneaux : on réduit le
   nombre de colonnes par paliers plutôt que de laisser les cartes se tasser. */
@media (max-width: 1000px) {
  .semaine { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
  .semaine { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 460px) {
  .semaine { grid-template-columns: 1fr; }
}

.jour {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.jour-nom {
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 700;
  color: var(--text-muted);
  margin: 0;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

/* Colonne flex : elle permet de pousser le badge d'âge en bas de carte. */
.creneau {
  display: flex;
  flex-direction: column;
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  /* Le grand rayon des cartes de contenu paraît boursouflé sur un bloc de
     200 px de large : on descend d'un cran. */
  border-radius: var(--radius-s);
  padding: 16px;
  transition: transform 0.4s var(--ease), border-color 0.4s var(--ease);
}

.creneau:hover {
  transform: translateY(-3px);
  border-color: rgba(168, 85, 247, 0.4);
}

/* Les cartes doivent s'aligner d'une colonne à l'autre, sinon les badges d'âge
   flottent à des hauteurs différentes et la grille prend un aspect d'escalier.

   subgrid le fait sans hauteur devinée : chaque jour reprend les lignes de la
   grille parente, si bien que les noms de jour, les premiers créneaux et les
   seconds s'alignent chacun sur leur propre ligne, dont la hauteur est celle du
   contenu le plus haut. Un jour qui n'a qu'un créneau laisse simplement sa
   troisième ligne vide. */
/* Réservé à la disposition en cinq colonnes. En dessous, les colonnes
   s'élargissent, plus aucune activité ne passe à la ligne et les cartes sont
   naturellement de même hauteur, l'alignement n'a plus rien à corriger.
   Ce cadrage n'est pas cosmétique : grid-row: 1 / -1 fixe la ligne et laisse la
   colonne automatique, ce qui fait placer chaque jour dans une colonne
   IMPLICITE. Hors du palier à cinq colonnes, le passage en colonne unique était
   donc annulé et la page débordait de 218 px en 390 px de large. */
@media (min-width: 1001px) {
  @supports (grid-template-rows: subgrid) {
    .semaine {
      /* nom du jour, puis au plus deux créneaux */
      grid-template-rows: auto auto auto;
      align-items: stretch;
    }

    .jour {
      display: grid;
      grid-row: 1 / -1;
      grid-template-rows: subgrid;
    }
  }

  /* Repli sans subgrid : une hauteur plancher, faute de mieux. */
  @supports not (grid-template-rows: subgrid) {
    .creneau { min-height: 152px; }
  }
}

.creneau-heure {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text);
}

.creneau-quoi {
  display: block;
  margin: 6px 0 14px;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--text-muted);
}

/* margin-top: auto colle le badge au bas de la carte : quelle que soit la
   longueur de l'activité, tous les badges s'alignent sur une même ligne. La
   marge basse de .creneau-quoi garantit l'écart minimal quand il n'y a pas
   d'espace libre à absorber.
   Libellé complet et sans majuscules forcées, « Adultes, 18 ans et + » en
   capitales déborderait d'une colonne de 200 px. */
.creneau-age {
  align-self: flex-start;
  margin-top: auto;
  padding: 4px 11px;
  border-radius: 999px;
  background: var(--accent-dim);
  color: var(--accent-soft);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.03em;
}

/* ---------- Tarifs ---------- */

/* Horaires et tarifs vivent dans une même section : ce filet les sépare sans
   ouvrir une seconde bande pleine largeur. */
.bloc-tarifs {
  margin-top: clamp(44px, 5vw, 68px);
  padding-top: clamp(40px, 4.5vw, 60px);
  border-top: 1px solid var(--line);
}

.price-card {
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  padding: clamp(28px, 3vw, 40px);
  display: flex;
  flex-direction: column;
}

/* Décalage de l'apparition, repris du style en ligne que portait la seconde
   carte. Il vit ici plutôt que dans tarifs.json : c'est de la présentation, et
   les données n'ont pas à transporter des millisecondes d'animation. */
.grid-2 .price-card:nth-child(2) {
  transition-delay: 0.08s;
}


/* Plafonné : le corps par défaut d'un h3 monte jusqu'à 1.6rem, trop imposant
   pour un titre de carte placé sous « Un abonnement par trimestre ». */
.price-card h3 {
  font-size: 1.35rem;
  margin-bottom: 0.9em;
}

/* Le montant reste aligné à droite : sur une colonne de prix, c'est ce qui
   permet de comparer les trois lignes d'un coup d'oeil. */
/* Trois colonnes : le libellé prend la place restante, les deux montants la
   leur. Une grille et non un flex, pour que les montants des trois trimestres
   s'alignent verticalement d'une ligne à l'autre. */
.price-row {
  display: grid;
  /* Largeur FIXE pour les deux colonnes de montants, et non « auto ». En auto,
     la colonne prend la largeur de son plus long contenu, c'est à dire du
     plus long titre de colonne, qui écraserait le libellé du
     trimestre. Ici le titre passe à la ligne et les montants restent alignés.

     En REM et non en EM : « em » se calcule sur la taille de police de
     l'élément, et la ligne de titres est plus petite que les autres. Ses
     colonnes étaient donc plus étroites, et les titres ne tombaient pas au
     dessus des montants qu'ils nomment. */
  grid-template-columns: minmax(0, 1fr) 6.6rem 6.6rem;
  align-items: baseline;
  gap: 6px 16px;
  padding: 14px 0;
  border-top: 1px solid var(--line);
}

/* Masque à l'oeil sans masquer aux lecteurs d'écran. Chaque montant porte
   ainsi le public auquel il s'applique, information que la colonne donne
   visuellement mais qu'une lecture linéaire perdrait. */
.invisible {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* La ligne de titres. Elle nomme les deux publics une fois par carte, ce qui
   évite une légende à part et la gymnastique d'aller-retour qu'elle impose.
   aria-hidden dans le gabarit : les lecteurs d'écran reçoivent le public dans
   chaque montant, où l'information a un sens hors contexte visuel. */
.price-head {
  border-top: none;
  padding-bottom: 6px;
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-faint);
}
.price-head + .price-row { border-top: 1px solid var(--line); }

/* Les deux colonnes de montants gardent la même largeur d'une ligne à l'autre,
   sinon « 400.- » et « 30.- » décaleraient la colonne voisine. */
.price-row .amount,
.price-head > span:not(:first-child) {
  text-align: right;
}

/* Sous cette largeur, trois colonnes ne tiennent plus : les deux montants
   laissaient 91px au libellé, qui s'étalait sur cinq lignes. Le trimestre
   prend donc toute la largeur, et les montants passent dessous, toujours dans
   leurs colonnes pour rester alignés d'une ligne à l'autre. */
@media (max-width: 560px) {
  .price-row {
    grid-template-columns: minmax(0, 1fr) 5rem 5rem;
    gap: 2px 10px;
  }
  .price-row > *:nth-child(1) { grid-column: 1 / -1; }
  .price-row > *:nth-child(2) { grid-column: 2; }
  .price-row > *:nth-child(3) { grid-column: 3; }
  .price-head > *:nth-child(1) { display: none; }
  .price-head { font-size: 0.64rem; letter-spacing: 0.03em; }
}
.price-row:first-of-type { border-top: none; }

.price-row .amount {
  font-family: var(--font-serif);
  color: var(--text);
  font-weight: 600;
  white-space: nowrap;
}

/* Cette ligne flottait nue sous les deux cartes, « mal intégrée ». Elle
   reprend leur vocabulaire visuel (même fond, même bordure, même rayon) pour
   se lire comme la troisième pièce du bloc plutôt qu'en marge. Les deux
   informations sont séparées : le prix à gauche, la réassurance à droite. */
.price-extra {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 6px 32px;
  margin-top: 20px;
  padding: clamp(20px, 2.5vw, 26px) clamp(22px, 3vw, 34px);
  background: var(--bg-elevated);
  border: 1px solid var(--line);
  border-radius: var(--radius-m);
}

.price-extra p {
  margin: 0;
  color: var(--text-muted);
}

.price-extra strong {
  font-family: var(--font-serif);
  font-weight: 600;
  color: var(--text);
}

/* ---------- Contact ---------- */

.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: clamp(30px, 5vw, 60px);
}

@media (max-width: 860px) {
  .contact-grid { grid-template-columns: 1fr; }
}

.contact-item {
  display: flex;
  gap: 16px;
  padding: 20px 0;
  border-top: 1px solid var(--line);
}
.contact-item:first-child { border-top: none; padding-top: 0; }

.contact-item .icon {
  width: 42px;
  height: 42px;
  border-radius: 12px;
  background: var(--accent-dim);
  color: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.contact-item h4 { margin-bottom: 0.2em; }
.contact-item p { margin: 0; }
.contact-item a:hover { color: var(--accent-soft); }

.map-frame {
  border-radius: var(--radius-l);
  overflow: hidden;
  border: 1px solid var(--line);
  margin-top: 30px;
}

/* La carte occupe désormais sa propre colonne : ce retrait, prévu quand elle
   suivait les coordonnées, la ferait descendre plus bas que le premier bloc
   de la colonne voisine. */
.map-frame:first-child {
  margin-top: 0;
}
/* Le filtre d'assombrissement ne vise que la carte Google une fois chargée :
   appliqué au conteneur, il inverserait aussi le texte du placeholder. */
.map-frame iframe {
  width: 100%;
  height: 320px;
  border: 0;
  display: block;
  filter: grayscale(0.4) invert(0.92) contrast(0.9);
}

.map-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 320px;
  padding: clamp(28px, 4vw, 44px);
  background: var(--bg-elevated);
  color: var(--text-muted);
  text-align: center;
}

.map-placeholder p {
  margin: 0;
}

.map-address {
  color: var(--text-faint);
  font-size: 0.88rem;
  margin-bottom: 0;
}

/* ---------- Footer ---------- */

.site-footer {
  border-top: 1px solid var(--line);
  padding: 60px 0 30px;
  margin-top: 60px;
}

.footer-top {
  display: flex;
  justify-content: space-between;
  gap: 40px;
  flex-wrap: wrap;
  margin-bottom: 40px;
}

.footer-brand {
  max-width: 320px;
}

.footer-brand .brand {
  margin-bottom: 14px;
}

.footer-cols {
  display: flex;
  gap: 60px;
  flex-wrap: wrap;
}

.footer-col h4 {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-faint);
  margin-bottom: 1.1em;
}

.footer-col a, .footer-col span {
  display: block;
  color: var(--text-muted);
  font-size: 0.95rem;
  margin-bottom: 0.8em;
  transition: color 0.3s var(--ease);
}
.footer-col a:hover { color: var(--accent-soft); }

.footer-bottom {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding-top: 24px;
  border-top: 1px solid var(--line);
  font-size: 0.82rem;
  color: var(--text-faint);
}

/* ---------- Reveal on scroll ---------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

@keyframes rise {
  from { opacity: 0; transform: translateY(30px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- Misc page-specific content blocks ---------- */

.prose p { color: var(--text-muted); }
.prose h2, .prose h3 { color: var(--text); margin-top: 1.4em; }

.pull-quote {
  border-left: 3px solid var(--accent);
  padding-left: 24px;
  font-family: var(--font-serif);
  font-size: 1.3rem;
  font-style: italic;
  color: var(--text);
  margin: 2em 0;
}

.badge-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 1.6em 0;
}
.badge-row span {
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 8px 16px;
  font-size: 0.82rem;
  color: var(--text-muted);
}

/* ==========================================================================
   Popups (dialog)
   ========================================================================== */

/* Trois popups, improvisation, cinéma, à propos, bâties sur <dialog> natif.
   Le piège à focus, la fermeture par Échap, l'inertie de l'arrière-plan et le
   ::backdrop sont fournis par le navigateur ; main.js ne fait qu'ouvrir, fermer
   et tenir l'URL à jour. Le contenu est écrit dans le HTML, jamais injecté.

   display: none plutôt que block : un <dialog> fermé doit le rester, faute de
   quoi les trois popups s'empileraient en clair dans le flux de l'accueil. On
   ne le réaffiche que sur .modal[open], l'attribut posé par showModal(), et
   sur .modal:target, le repli sans JavaScript décrit plus bas. Ce display:none
   explicite rend en prime service aux navigateurs qui ignorent <dialog> : chez
   eux l'élément est inconnu, donc affiché en ligne par défaut. */
.modal {
  /* Rembourrage de référence de la popup, relu par .modal-inner et .modal-close. */
  --modal-pad: clamp(28px, 4vw, 56px);

  display: none;
  position: fixed;
  /* inset + margin: auto reproduit le centrage du dialogue natif. On le réécrit
     au lieu de s'y fier : en mode dégradé la popup n'est pas dans le top layer
     et ne bénéficie donc pas des règles dialog:modal du navigateur.
     height: fit-content est la pièce qui permet aux marges automatiques de se
     partager l'espace vertical restant, avec height: auto, top et bottom à 0
     étireraient la popup sur toute la fenêtre. */
  inset: 0;
  margin: auto;
  width: min(900px, 92vw);
  max-width: none;
  height: fit-content;
  max-height: min(88vh, 960px);
  max-height: min(88svh, 960px);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius-l);
  /* var(--bg) et non var(--bg-elevated) : le contenu déplacé vient de pages qui
     s'affichaient sur ce fond, et il embarque ses propres cartes en
     var(--bg-elevated) (.course-card notamment). Une popup
     du même ton les ferait disparaître. L'effet de surélévation est porté par
     le ::backdrop, la bordure et l'ombre. */
  background: var(--bg);
  color: var(--text);
  box-shadow: var(--shadow);
  /* Le défilement est interne à .modal-body ; ici on se contente de rogner aux
     coins arrondis. */
  overflow: hidden;
}

/* Uniquement [open] : avec JavaScript, c'est showModal() qui fait foi. Ajouter
   :target ici rouvrirait la popup après sa fermeture, car history.replaceState
   retire bien le fragment de l'URL mais ne réinitialise PAS l'élément cible du
   document, dialog.matches(':target') reste vrai. */
.modal[open] {
  display: flex;
  flex-direction: column;
}

/* Assombrissement et flou du fond, dans le même registre que
   .site-header.is-scrolled. */
.modal::backdrop {
  background: rgba(6, 5, 8, 0.78);
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
}

.modal-inner {
  display: flex;
  flex-direction: column;
  /* min-height: 0 lève le minimum automatique des éléments flex : sans lui, la
     colonne refuse de descendre sous la hauteur de son contenu et la popup
     déborde au lieu de faire défiler. */
  min-height: 0;
  flex: 1 1 auto;
  padding: var(--modal-pad);
}

/* Le défilement est porté par .modal-body, pas par .modal-inner : le bouton de
   fermeture vit donc au-dessus, dans un conteneur immobile, et reste visible en
   permanence sans position: sticky ni position: absolute. C'est le montage le
   plus sûr des trois, un bouton collé en haut à droite se ferait rogner par le
   coin arrondi de la popup et laisserait défiler une bande de texte au-dessus
   de lui ; un bouton absolu passerait sous la barre de défilement du contenu. */
.modal-close {
  /* Tire le bouton dans la gouttière pour le caler vers l'angle. */
  --pull: calc(var(--modal-pad) * -0.4);

  display: flex;
  align-items: center;
  justify-content: center;
  align-self: flex-end;
  flex: 0 0 auto;
  /* 44x44 : cible tactile minimale recommandée. */
  width: 44px;
  height: 44px;
  margin: var(--pull) var(--pull) clamp(12px, 2vw, 22px) 0;
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--bg-elevated-2);
  color: var(--text-muted);
  cursor: pointer;
  transition: color 0.3s var(--ease), background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.modal-close svg {
  display: block;
  width: 20px;
  height: 20px;
}

.modal-close:hover {
  color: var(--accent-soft);
  border-color: var(--accent-soft);
  background: var(--accent-dim);
}

.modal-close:focus-visible {
  color: var(--accent-soft);
  outline: 3px solid var(--accent-soft);
  outline-offset: 3px;
}

.modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Une fois la popup lue jusqu'au bout, la molette ne doit pas entraîner la
     page derrière. */
  overscroll-behavior: contain;
  /* Gouttière de 6 px reprise en marge négative : le rendu ne bouge pas, mais
     le conteneur défilant cesse de rogner les anneaux de focus des éléments
     collés au bord. */
  padding: 6px;
  margin: -6px;
}

.modal-body > :first-child { margin-top: 0; }
.modal-body > :last-child { margin-bottom: 0; }

/* .btn interdit le retour à la ligne, réglage pensé pour des libellés courts sur
   des pages pleine largeur. Dans une popup de 92vw, « Découvrir le cours
   d'improvisation » réclame 302 px pour 287 px disponibles et déborde sur le
   côté. Sur mobile on préfère deux lignes à un débordement horizontal. */
@media (max-width: 560px) {
  .modal .btn {
    white-space: normal;
  }
}

/* Apparition sobre, dans le vocabulaire du reste du site (cf. @keyframes rise
   du hero) : fondu court et légère montée. Le bloc prefers-reduced-motion en
   tête de fichier neutralise l'animation de l'élément ; celle du ::backdrop,
   pseudo-élément hors de portée du sélecteur universel, y est traitée à part. */
.modal[open] {
  animation: modal-in 0.34s var(--ease) both;
}

.modal[open]::backdrop {
  animation: modal-backdrop-in 0.34s var(--ease) both;
}

@keyframes modal-in {
  from { opacity: 0; transform: translateY(18px) scale(0.985); }
  to { opacity: 1; transform: none; }
}

@keyframes modal-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* ---------- Repli sans JavaScript ---------- */

/* Les déclencheurs sont des <a href="#improvisation"> : sans JavaScript, ou
   avant qu'il ne s'exécute, l'ancre doit tout de même livrer le contenu, sinon
   c'est un tiers du site qui reste invisible.

   Le repli ne rejoue pas la fenêtre modale. Hors du top layer il n'y a ni
   ::backdrop, ni fermeture par Échap, et le bouton de fermeture est inerte
   faute de JS : une carte fixée par-dessus la page serait un piège dont on ne
   sortirait pas. On déroule donc la popup dans le flux, à sa place en fin de
   page, le navigateur y amène le visiteur par l'ancre, il lit, il repart.
   Le repli est cadré par html:not(.js), et NON par :not([open]). main.js pose
   la classe « js » sur <html> dès son exécution : le repli est donc strictement
   réservé au cas où le script ne tourne pas. Se fier à :not([open]) ne suffisait
   pas : après fermeture d'une popup ouverte via /#cinema, le dialogue n'est plus
   [open] mais reste :target, et il se dépliait en clair dans la page. */
html:not(.js) .modal:target {
  display: block;
  position: static;
  width: auto;
  max-width: none;
  height: auto;
  max-height: none;
  margin: 0;
  /* Même respiration verticale que .section-pad : la popup dépliée se lit comme
     une section de la page. */
  padding: clamp(64px, 10vw, 130px) 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  overflow: visible;
  scroll-margin-top: calc(var(--haut-fixe) + 24px);
  animation: none;
}

/* Reprend la gouttière de .container pour aligner le texte sur le reste. */
html:not(.js) .modal:target .modal-inner {
  display: block;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 clamp(20px, 5vw, 48px);
}

html:not(.js) .modal:target .modal-body {
  overflow: visible;
  margin: 0;
  padding: 0;
}

/* Sans JavaScript, ce bouton n'a rien à fermer. */
html:not(.js) .modal:target .modal-close {
  display: none;
}

/* ==========================================================================
   Impression
   ========================================================================== */

@media print {
  /* Tout le thème passe par les variables : on bascule la palette d'un bloc
     plutôt que de neutraliser chaque règle une par une. */
  :root {
    --bg: #ffffff;
    --bg-elevated: #ffffff;
    --bg-elevated-2: #ffffff;
    --line: #bbbbbb;
    --text: #000000;
    --text-muted: #1a1a1a;
    --text-faint: #444444;
    --accent: #000000;
    --accent-soft: #000000;
    --accent-dim: transparent;
    --annonce-fond: transparent;
    --shadow: none;
  }

  html,
  body {
    background: #ffffff;
    color: #000000;
    overflow: visible;
  }

  body {
    font-size: 11pt;
  }

  .site-header,
  .nav-toggle,
  .skip-link,
  .hero-bg,
  .map-frame,
  .cta-banner,
  .btn {
    display: none !important;
  }

  /* Halo violet écrit en dur : visible si l'utilisateur coche
     « Graphiques d'arrière-plan » dans la boîte d'impression. */
  .page-hero::before {
    display: none;
  }

  /* Une popup ouverte est promue dans le top layer : elle se peindrait
     par-dessus la page imprimée, et aucune propriété, ni position, ni z-index ,
     ne l'en délogerait. Seul display: none l'en retire. Le !important couvre du
     même coup .modal[open] et le repli .modal:target, plus spécifiques.
     L'impression rend donc la page telle qu'elle se lit d'un bout à l'autre :
     hero, cours, laurence, horaires, tarifs, contact. */
  .modal {
    display: none !important;
  }

  /* Un élément fixe se répète en tête de CHAQUE page imprimée. La barre
     reprend donc sa place dans le flux, où elle ne sort qu'une fois. Son
     en-tête est masqué juste au-dessus, il ne reste que l'annonce s'il y en
     a une, ce qui a du sens sur un planning affiché au mur. */
  .barre-haute {
    position: static;
  }

  .impression-seule {
    display: block;
    margin-bottom: 1.6em;
    font-size: 10pt;
    color: #444444;
  }

  /* Mode « imprimer le planning », posé par le bouton dédié le temps de
     l'impression. Sans lui, demander le planning imprimerait les six sections
     de la page pour obtenir un tableau d'horaires. On ne masque donc pas des
     éléments un par un : on ne garde que <main>, puis que #horaires à
     l'intérieur, ce qui reste juste même si des sections sont ajoutées plus tard.
     Les tarifs sont exclus : le bouton annonce le planning, pas les prix. */
  body.impression-planning > *:not(main),
  body.impression-planning main > *:not(#horaires),
  body.impression-planning #horaires .bloc-tarifs {
    display: none !important;
  }

  body.impression-planning .section-pad {
    padding: 0;
  }

  /* Le semainier est large : cinq colonnes de jours, chacune avec des horaires,
     une activité et une tranche d'âge. En portrait il se comprime au point de
     couper les libellés. Le bouton « imprimer le planning » demande donc du
     paysage, par une page nommée qui ne s'applique qu'à lui.

     La page entière garde le portrait : c'est un texte qui se lit de haut en
     bas, le paysage n'y gagnerait rien et doublerait le nombre de feuilles. */
  @page paysage {
    size: A4 landscape;
    margin: 12mm;
  }
  body.impression-planning {
    page: paysage;
  }

  /* Sans ça, toute section non encore révélée par l'observateur s'imprime
     blanche : c'est le cas dès que l'on imprime sans avoir fait défiler. */
  [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }

  /* Même piège pour le hero, dont l'apparition passe par une animation. */
  .hero-content {
    animation: none !important;
  }

  /* Fonds sombres et ombres écrits en dur, hors variables. */
  .frame-tag,
  .main-nav {
    background: #ffffff !important;
    border-color: #bbbbbb !important;
    box-shadow: none !important;
  }

  .course-card,
  .price-card,
  .creneau,
  .split-media {
    box-shadow: none !important;
  }

  .course-card,
  .price-card,
  .creneau,
  .jour,
  .timeline-item {
    page-break-inside: avoid;
    break-inside: avoid;
  }

  h2, h3, h4 {
    page-break-after: avoid;
    break-after: avoid;
  }

  .hero {
    min-height: 0;
    padding-top: 0;
  }

  .page-hero {
    padding-top: 0;
  }

  .section-pad {
    padding: 22px 0;
  }

  .site-footer {
    margin-top: 24px;
    padding-top: 24px;
  }

  /* Les liens du contenu exposent leur destination, la navigation non :
     y répéter les URL n'apporterait rien sur papier. */
  a[href^="http"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    word-break: break-all;
  }

  .brand[href^="http"]::after,
  .main-nav a[href^="http"]::after,
  .footer-cols a[href^="http"]::after {
    content: "";
  }
}
