/* ============================================================
   Site public — Association Itaparica
   ============================================================ */

:root {
  --vert: #0f3d2e;
  --vert-clair: #1b6b4f;
  --or: #e0a526;
  --or-clair: #f5c45e;
  --sable: #faf6ef;
  --encre: #1c1a17;
  --gris: #5d5850;
  --gris-clair: #e6e0d5;
  --blanc: #ffffff;
  --rayon: 10px;
  --ombre: 0 1px 2px rgba(28, 26, 23, .06), 0 8px 24px rgba(28, 26, 23, .08);
  --largeur: 1120px;
}

*, *::before, *::after { box-sizing: border-box; }

/* Doit primer sur les `display` posés plus bas (.formulaire, .bouton…),
   sans quoi un élément masqué par l'attribut `hidden` reste visible. */
[hidden] { display: none !important; }

/* L'en-tête est collant (`position: sticky`, 68 px mesurés à toutes les
   largeurs) : sans cette réserve, une section visée par une ancre commence
   **derrière lui** — son bord haut à 0 px, ses premiers pixels cachés.
   `scroll-padding-top` sur `html` vaut pour tout défilement d'ancre, d'où qu'il
   vienne — un `scroll-margin-top` posé section par section s'oublierait à la
   première section ajoutée.

   Le titre, lui, resterait lisible sans cette règle : toutes les sections du
   site portent 80 px de rembourrage, ce qui le pose à 80 px, douze au-dessus de
   l'en-tête. C'est ce qui a fait qu'un contrôle rédigé « le titre n'est pas
   caché » restait vert une fois la règle retirée — il mesurait le rembourrage
   des sections, pas la réserve. `verif-ancres.mjs` mesure le bord de la
   section. */
html { scroll-behavior: smooth; scroll-padding-top: 84px; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: 17px;
  line-height: 1.65;
  color: var(--encre);
  background: var(--sable);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { line-height: 1.2; margin: 0 0 .5em; font-weight: 700; }
h1 { font-size: clamp(2rem, 5vw, 3.1rem); letter-spacing: -.02em; }
h2 { font-size: clamp(1.5rem, 3.5vw, 2.1rem); letter-spacing: -.01em; }
h3 { font-size: 1.15rem; }
p { margin: 0 0 1em; }
a { color: var(--vert-clair); }
img { max-width: 100%; height: auto; display: block; }

.conteneur {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: 20px;
}

/* ---------- En-tête ---------- */

.entete {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--vert);
  color: var(--blanc);
}

.entete__barre {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 68px;
}

.logo {
  display: flex;
  align-items: center;
  gap: 10px;
  color: var(--blanc);
  text-decoration: none;
  font-weight: 700;
  font-size: 1.15rem;
  letter-spacing: .02em;
}

.logo__marque {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: var(--or);
  color: var(--vert);
  font-size: 1rem;
  font-weight: 800;
}

.nav { display: flex; align-items: center; gap: 2px; }

/* **Un intitulé ne se coupe pas en deux.** « Cours & horaires », « Tutos
   vidéo » et « Espace adhérent » passaient à la ligne dès que la barre était
   un peu juste : trois entrées sur deux lignes au milieu de quatre sur une
   seule, des hauteurs inégales et des écarts qui n'avaient plus rien de
   régulier. C'est ce qui rendait le menu bancal, pas sa couleur.

   `nowrap` règle le rendu ; encore faut-il que l'ensemble tienne. D'où la
   marge prise sur le reste : l'espacement passe de 4 à 2 px, le rembourrage
   horizontal de 12 à 10, et le texte de .95 à .92 rem. Sept entrées, un
   bouton et le logo tiennent alors sur une ligne dès 1000 px de large —
   au-dessous, c'est déjà le menu déroulant qui prend le relais (960 px). */
.nav a {
  color: rgba(255, 255, 255, .85);
  text-decoration: none;
  font-size: .92rem;
  padding: 9px 10px;
  border-radius: var(--rayon);
  white-space: nowrap;
}

.nav a:hover { color: var(--blanc); background: rgba(255, 255, 255, .1); }

/* La page courante était soulignée d'un trait doré collé au bas du lien, que
   le rembourrage éloignait du texte. Un fond discret la désigne mieux, et
   surtout il se voit sur une barre où les entrées se touchent presque. */
.nav a[aria-current="page"] {
  color: var(--blanc);
  background: rgba(255, 255, 255, .14);
  box-shadow: inset 0 -2px 0 var(--or);
}

/* Le bouton d'adhésion ferme la barre : un peu d'air avant lui le sépare des
   liens, sans quoi il se lit comme une entrée de plus. */
.nav .bouton { margin-left: 8px; }

.nav__bouton {
  display: none;
  background: none;
  border: 1px solid rgba(255, 255, 255, .3);
  color: var(--blanc);
  border-radius: var(--rayon);
  padding: 8px 12px;
  font: inherit;
  font-size: .9rem;
  cursor: pointer;
}

/* **Le seuil suit ce que la barre demande, il n'est pas choisi.** Sept
   entrées, un bouton et le logo réclament 1152 px : mesuré, pas estimé.
   Au-dessous, la barre débordait — la page entière se mettait à défiler
   latéralement, et sur un portable de 1024 px c'était le cas le plus courant.
   Le menu déroulant prend donc le relais à 1150 et non plus à 860.

   Corollaire : toucher aux intitulés ou au rembourrage des liens change cette
   largeur. `verif-menu.mjs` la remesure et compare au seuil écrit ici. */
@media (max-width: 1150px) {
  .nav__bouton { display: block; }
  .nav {
    display: none;
    position: absolute;
    inset: 68px 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 8px 20px 16px;
    background: var(--vert);
    border-top: 1px solid rgba(255, 255, 255, .12);
  }
  .nav[data-ouvert="true"] { display: flex; }
  .nav a { padding: 12px 8px; }
  .nav .bouton { margin-top: 8px; text-align: center; }
}

/* ---------- Boutons ---------- */

.bouton {
  display: inline-block;
  padding: 12px 22px;
  border-radius: var(--rayon);
  background: var(--or);
  color: var(--vert);
  font-weight: 700;
  font-size: .98rem;
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
}

.bouton:hover { background: var(--or-clair); }

.bouton--fantome {
  background: transparent;
  color: var(--blanc);
  border-color: rgba(255, 255, 255, .4);
}

.bouton--fantome:hover { background: rgba(255, 255, 255, .12); }

.bouton--sombre { background: var(--vert); color: var(--blanc); }
.bouton--sombre:hover { background: var(--vert-clair); }

/* ---------- Héros ---------- */

/* ---------- Le liseré d'un rendez-vous mis en avant (migration 0083) ----------
   Un bandeau doré au-dessus du héros, avec le nom du rendez-vous et son
   décompte. Il n'est là que quand il a quelque chose à dire — le HTML le pose
   `hidden`, `vitrine-compte-a-rebours.js` le révèle.

   **L'or sur le vert, et pas l'inverse.** Le héros juste dessous est un
   dégradé vert sombre : un liseré vert s'y fondrait et ne se remarquerait pas,
   ce qui est exactement le contraire de ce qu'on lui demande. L'or est la
   couleur d'accent du site, réservée à ce qui appelle — et un rendez-vous
   daté est ce qu'il y a de plus proche d'un appel sur cette page.

   L'encre est **sombre sur l'or**, jamais blanche : sur `#e0a526`, du blanc
   tombe à un contraste de 2,1 quand l'encre du site tient à 8,4. Un fond clair
   impose de poser la couleur du texte, même règle que pour `contenus.fond`. */
.lisere {
  background: linear-gradient(90deg, var(--or) 0%, var(--or-clair) 100%);
  color: var(--vert);
}

.lisere__lien {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: center;
  gap: 6px 18px;
  /* Le liseré suit la largeur de lecture du site, comme tout le reste :
     centré, borné, et respirant sur les côtés au doigt. */
  max-width: 1120px;
  margin: 0 auto;
  padding: 11px 24px;
  color: inherit;
  text-decoration: none;
  font-size: .95rem;
}

/* Souligné au survol seulement : un bandeau entièrement souligné ferait un
   trait de plus sous un trait, même raison qu'au pied de page. */
.lisere__lien:hover .lisere__quoi strong,
.lisere__lien:focus-visible .lisere__quoi strong { text-decoration: underline; }

.lisere__lien:focus-visible {
  outline: 2px solid var(--vert);
  outline-offset: -3px;
}

.lisere__quoi { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; }

/* La date et le lieu sont un complément : ils ne doivent pas peser autant que
   le nom du rendez-vous, qui est ce qu'on lit en premier. */
.lisere__quand { opacity: .78; font-size: .88rem; }

/* Le décompte est ce qui change : il se détache du reste sans crier.
   `tabular-nums` évite que la ligne ne tressaute à chaque seconde — des
   chiffres de largeurs différentes déplacent le texte qui suit, et un bandeau
   qui frémit est un bandeau qu'on finit par ne plus lire. */
.lisere__decompte {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.heros {
  background:
    radial-gradient(1000px 400px at 15% -10%, rgba(224, 165, 38, .22), transparent 60%),
    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
  color: var(--blanc);
  padding: clamp(56px, 9vw, 104px) 0;
}

/* **Une largeur de lecture, pas un carcan.** Un texte qui court sur toute la
   largeur d'un écran de bureau se lit mal : l'œil perd le début de la ligne
   suivante. Mais les valeurs d'origine étaient trop serrées — le texte
   n'occupait que la moitié de la place à côté de grilles pleine largeur, et
   le repli avait l'air d'un accident plutôt que d'un choix. Élargies, elles
   gardent le confort de lecture sans donner cette impression. */
.heros p { color: rgba(255, 255, 255, .82); font-size: 1.1rem; max-width: 72ch; }
.heros h1 { max-width: 24ch; }

.heros__surtitre {
  display: inline-block;
  margin-bottom: 18px;
  padding: 5px 12px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .12);
  color: var(--or-clair);
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
}

.heros__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 28px; }

/* ---------- Bandeau de page interne ---------- */

.bandeau {
  background: linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
  color: var(--blanc);
  padding: clamp(40px, 6vw, 68px) 0;
}

.bandeau p { color: rgba(255, 255, 255, .82); max-width: 88ch; margin: 0; }

/* ---------- Sections ---------- */

.section { padding: clamp(48px, 7vw, 80px) 0; }
.section--claire { background: var(--blanc); }

/* Le chapeau de section surmonte le plus souvent une grille pleine largeur :
   c'est là que l'écart se voyait le plus. */
.section__intro { max-width: 88ch; margin-bottom: 36px; }
.section__intro p { color: var(--gris); }

/* ---------- Grilles / cartes ----------
   `minmax(min(260px, 100%), 1fr)` et non `minmax(260px, 1fr)` : un minimum
   fixe est un plancher, pas un souhait. Sur un écran de 320 px, les deux
   cartes d'adresse de la page contact réclamaient 320 px chacune dans un
   conteneur qui n'en offrait que 280, et la page débordait — donc se
   dézoomait. Le `min()` laisse la piste rétrécir sous la largeur disponible. */

.grille {
  display: grid;
  gap: 20px;
  grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr));
}

.grille--deux { grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); }

/* ---------- Le nombre de colonnes suit le nombre de fiches ----------

   `auto-fit` replie les pistes qu'aucun élément n'occupe, donc une carte seule
   s'étirait sur toute la largeur : une fiche d'instrument de 1080 × 1582 px,
   une page et demie pour un berimbau. Mais la figer à trois colonnes donne le
   défaut inverse — une fiche étroite dans une rangée aux deux tiers vide.

   On **pose** donc le nombre de colonnes, et c'est le module qui le choisit
   d'après le nombre de fiches : une seule s'étale et se lit en deux colonnes,
   photo à gauche ; deux se partagent la ligne ; trois et plus tiennent le rang
   de trois. Même dispositif que la grille de l'équipe, et pour la même raison.

   À réserver aux grilles dont les fiches portent une **image** : ailleurs,
   `auto-fit` reste préférable, une carte de texte seule occupant sa ligne sans
   dommage. */
.grille--colonnes-1 { grid-template-columns: minmax(0, 1fr); }
.grille--colonnes-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grille--colonnes-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }

@media (max-width: 900px) {
  .grille--colonnes-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 620px) {
  .grille--colonnes-2,
  .grille--colonnes-3 { grid-template-columns: minmax(0, 1fr); }
}

/* Seule sur sa ligne et illustrée, une fiche se lit **en deux colonnes** : la
   photo à gauche, le texte à droite. Pleine largeur avec la photo au-dessus,
   elle faisait 1582 px de haut — l'image occupait l'écran et le texte
   commençait en dessous.

   **La photo occupe sa colonne** (`stretch`, et non `start`) : à hauteur
   libre, elle gardait son 4/3 et laissait sous elle un grand blanc dès que le
   texte descendait plus bas — ce qui est le cas courant, une fiche portant
   souvent une démonstration filmée. Le cadrage n'est pas une nouveauté : les
   cartes illustrées imposent déjà un 4/3 en `object-fit: cover`, ici c'est le
   même recadrage dans une colonne plus haute — et un instrument est plutôt
   vertical, donc il y gagne. Ce qui vaut pour les **portraits** de l'équipe ne
   vaut pas ici : on ne rogne pas un visage, on cadre un berimbau. */
@media (min-width: 760px) {
  .grille--colonnes-1 > .carte--illustree {
    display: grid;
    grid-template-columns: minmax(0, 40%) minmax(0, 1fr);
  }

  .grille--colonnes-1 > .carte--illustree > .contenu__media {
    aspect-ratio: auto;
    height: 100%;
    max-height: none;
    min-height: 260px;
  }

  .grille--colonnes-1 > .carte--illustree > .carte__corps { padding: 24px 26px; }
}

/* Les familles se suivent sur la page des instruments : sans air au-dessus,
   « Les percussions » colle à la dernière carte de l'arc musical et se lit
   comme sa légende. */
[data-instruments] > h3 { margin-top: 34px; }
[data-instruments] > h3:first-child { margin-top: 0; }

.carte {
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  padding: 24px;
  box-shadow: var(--ombre);
}

.section--claire .carte { background: var(--sable); }

.carte h3 { margin-bottom: .4em; }
.carte p:last-child { margin-bottom: 0; }
.carte__icone { font-size: 1.6rem; margin-bottom: 10px; }

.carte--lien { text-decoration: none; color: inherit; display: block; }
.carte--lien:hover { border-color: var(--vert-clair); }
.carte--lien .fleche { color: var(--vert-clair); font-weight: 700; }

/* ---------- Tableaux (horaires, tarifs) ---------- */

.tableau-enveloppe { overflow-x: auto; }

.tableau {
  width: 100%;
  border-collapse: collapse;
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  overflow: hidden;
  font-size: .96rem;
}

.tableau th, .tableau td {
  text-align: left;
  padding: 13px 16px;
  border-bottom: 1px solid var(--gris-clair);
}

.tableau th { background: var(--sable); font-size: .82rem; text-transform: uppercase; letter-spacing: .05em; color: var(--gris); }
.tableau tr:last-child td { border-bottom: none; }

/* Le planning : **deux tableaux, une seule grille**
 *
 * Les cours enfants et les cours adultes sont deux `<table>` distincts — ils
 * ont chacun leur intitulé, et l'un peut venir de la base pendant que l'autre
 * garde le planning écrit dans la page. Mais en largeur automatique, chacun
 * répartit ses colonnes d'après **son** contenu : « Contenu » commençait à
 * 297 px dans le premier et à 227 px dans le second, si bien que les deux
 * tableaux, l'un sous l'autre, ne s'alignaient sur rien.
 *
 * `table-layout: fixed` et des proportions imposées les remettent d'accord.
 * Seules les trois premières colonnes sont dimensionnées : la place restante
 * se partage entre celles qui suivent, et la colonne « En images » — qui
 * n'apparaît que si un cours porte un média — n'a donc pas de règle à part.
 *
 * La colonne du lieu était par ailleurs trop étroite pour « Gymnase des
 * Minimes », qui se coupait en deux lignes alors que la colonne voisine avait
 * de la place de reste. */
.tableau--planning { table-layout: fixed; }
/* Les proportions viennent d'une **mesure**, pas d'une estimation : deux
   essais écrits à la main ont chacun déplacé le problème d'une colonne à
   l'autre — les enseignants sur quatre lignes, puis « Gymnase des Minimes »
   coupé en deux sur sept lignes. Ce que chaque colonne demande a donc été
   mesuré au navigateur, texte à texte (`scripts/mesure-planning`), sur une
   largeur de tableau de 1080 px et 32 px de marge intérieure :

     col 1 (quand)       médiane 225 px  →  24 %  — tient sur une ligne
     col 2 (contenu)     médiane 267 px  →  21,5 % — deux lignes, assumé
     col 3 (lieu)        médiane 205 px  →  22,5 % — tient sur une ligne
     col 4 (enseignants) jusqu'à 599 px  →  32 %  — deux lignes

   Ce qui est **tenu sur une ligne** est ce qu'on lit en diagonale : l'horaire
   et le lieu. Le reste peut se replier, et la colonne des enseignants — de
   loin la plus longue — prend la plus grande part parce que c'est elle qui
   décide de la hauteur des rangées.

   Il y avait une cinquième colonne, « En images ». Elle a été retirée avec le
   choix de média d'un créneau : les proportions mesurées sont **conservées**
   entre elles et ramenées à cent — les redistribuer au jugé ferait revenir
   précisément ce que la mesure avait corrigé, « Gymnase des Minimes » coupé
   en deux ou les enseignants sur quatre lignes. */
.tableau--planning th:nth-child(1), .tableau--planning td:nth-child(1) { width: 24%; }
.tableau--planning th:nth-child(2), .tableau--planning td:nth-child(2) { width: 21.5%; }
.tableau--planning th:nth-child(3), .tableau--planning td:nth-child(3) { width: 22.5%; }
.tableau--planning th:nth-child(4), .tableau--planning td:nth-child(4) { width: 32%; }

/* `pretty` évite le mot esseulé en fin de cellule, et surtout garde les deux
   lignes d'une cellule à peu près égales — c'est ce qui rendait le planning
   irrégulier d'une ligne à l'autre.

   **Sous `@supports`, et pas seulement pour la forme** : Firefox ne connaît
   pas `pretty` et écrit dans la console « Erreur d'analyse de la valeur pour
   text-wrap. Déclaration abandonnée. » — signalé, et c'est du bruit dans
   une console qu'on vient de nettoyer. Une déclaration ignorée ne casse
   rien, mais elle se voit ; enveloppée, le navigateur saute le bloc sans
   rien dire, et Chrome garde le bénéfice. */
@supports (text-wrap: pretty) {
  .tableau--planning td { text-wrap: pretty; }
}

/* Sous 760 px, la largeur imposée n'a plus de sens : le tableau défile dans
   son enveloppe, et c'est le contenu qui décide. */
@media (max-width: 760px) {
  .tableau--planning { table-layout: auto; min-width: 640px; }
  .tableau--planning th, .tableau--planning td { width: auto; }
}

/* ---------- Listes ---------- */

.liste-nue { list-style: none; margin: 0; padding: 0; }
.liste-nue li { padding: 8px 0 8px 26px; position: relative; }
.liste-nue li::before { content: "▸"; position: absolute; left: 0; color: var(--or); font-weight: 700; }

/* ---------- Encadré ---------- */

.encadre {
  border-left: 3px solid var(--or);
  background: var(--blanc);
  border-radius: 0 var(--rayon) var(--rayon) 0;
  padding: 18px 22px;
  margin: 28px 0;
}

.encadre p:last-child { margin-bottom: 0; }

/* ---------- Appel à l'action ---------- */

.cta {
  background: var(--vert);
  color: var(--blanc);
  border-radius: var(--rayon);
  padding: clamp(28px, 5vw, 48px);
  text-align: center;
}

.cta p { color: rgba(255, 255, 255, .82); max-width: 64ch; margin-inline: auto; }

/* ---------- Pied de page ---------- */

.pied {
  background: #0a2b20;
  color: rgba(255, 255, 255, .72);
  padding: 48px 0 28px;
  font-size: .94rem;
}

/* **Pas de soulignement dans un pied de page.** Vingt liens soulignés les uns
   sous les autres font un mur de traits : on ne distingue plus les rubriques,
   et rien n'attire l'œil puisque tout est marqué. Le soulignement revient au
   survol et au focus, là où il dit quelque chose. */
.pied a {
  color: rgba(255, 255, 255, .78);
  text-decoration: none;
}

.pied a:hover,
.pied a:focus-visible { color: var(--or); text-decoration: underline; }

.pied h3 {
  color: var(--blanc);
  font-size: .82rem;
  text-transform: uppercase;
  letter-spacing: .09em;
  margin-bottom: 14px;
  /* Un filet sous l'intitulé : c'est ce qui sépare les rubriques une fois le
     soulignement des liens retiré. */
  padding-bottom: 8px;
  border-bottom: 1px solid rgba(255, 255, 255, .14);
}

.pied__grille {
  display: grid;
  gap: 28px 32px;
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
  padding-bottom: 28px;
  align-items: start;
}

/* Les liens d'une rubrique : une liste, pas des `<br>`. C'est ce qui permet
   aux clubs amis de s'étaler en colonnes plutôt que de descendre en file. */
.pied__liens {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 7px;
}

/* **« Voir aussi » prend toute la largeur.** Huit clubs dans une colonne
   étroite descendaient sur huit lignes, seuls sur leur rangée, avec les trois
   quarts de la largeur vides à droite. La rubrique occupe donc la rangée
   entière et ses liens s'y répartissent. */
.pied__grille > [data-liens="ami"] { grid-column: 1 / -1; }

.pied__grille > [data-liens="ami"] .pied__liens {
  grid-template-columns: repeat(auto-fill, minmax(min(230px, 100%), 1fr));
  gap: 7px 32px;
}

.pied p { margin: 0; line-height: 1.7; }

.pied__bas {
  border-top: 1px solid rgba(255, 255, 255, .12);
  padding-top: 20px;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  justify-content: space-between;
  font-size: .86rem;
}

/* ---------- Formulaires ---------- */

.formulaire { display: grid; gap: 16px; max-width: 560px; }

/* `align-content: start` : voir le commentaire d'`admin.css`. Une colonne sans
   texte d'aide se fait sinon étirer par sa voisine, et son champ descend. */
.champ { display: grid; align-content: start; gap: 6px; }
.champ label { font-weight: 600; font-size: .92rem; }

.champ input, .champ textarea, .champ select {
  font: inherit;
  padding: 11px 13px;
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  background: var(--blanc);
  color: inherit;
  width: 100%;
  box-sizing: border-box;
}

.champ textarea { min-height: 140px; resize: vertical; }

.champ input:focus, .champ textarea:focus, .champ select:focus {
  outline: 2px solid var(--vert-clair);
  outline-offset: 1px;
}

.champs-cote { display: grid; gap: 0 14px; grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr)); }

.pot-de-miel { display: none; }

.erreur { color: #b3261e; font-size: .92rem; }
.succes { color: var(--vert-clair); font-size: .92rem; }

/* ---------- Widget HelloAsso ---------- */

/* Le paiement se fait dans le formulaire HelloAsso affiché ici même :
   l'adhérent ne quitte pas le site. */
.widget {
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  overflow: hidden;
  box-shadow: var(--ombre);
}

.widget iframe { display: block; width: 100%; border: none; min-height: 760px; }
.widget__note { padding: 12px 16px; border-top: 1px solid var(--gris-clair); margin: 0; }

/* ---------- Questions fréquentes ---------- */

.faq { display: grid; gap: 10px; }

.faq details {
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  padding: 4px 18px;
}

.faq summary {
  cursor: pointer;
  font-weight: 600;
  padding: 14px 0;
  list-style: none;
}

.faq summary::-webkit-details-marker { display: none; }

.faq summary::after {
  content: '+';
  float: right;
  color: var(--or);
  font-size: 1.3rem;
  line-height: 1;
}

.faq details[open] summary::after { content: '−'; }

.faq details > p { margin: 0 0 16px; }

/* ---------- Divers ---------- */

.centre { text-align: center; }
.discret { color: var(--gris); font-size: .92rem; }

/* ---------- Galerie des articles du groupe (page Boutique) ---------- */

.galerie-articles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 1fr));
  gap: 22px;
}

.article-vitrine {
  margin: 0;
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  transition: transform .18s ease, box-shadow .18s ease;
}

.article-vitrine:hover {
  transform: translateY(-3px);
  box-shadow: 0 10px 26px rgba(15, 61, 46, .12);
}

.article-vitrine img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--sable);
}

.article-vitrine figcaption {
  padding: 14px 16px;
  font-weight: 600;
  color: var(--vert);
}

@media (prefers-reduced-motion: reduce) {
  .article-vitrine { transition: none; }
  .article-vitrine:hover { transform: none; }
}

/* ---------- Événements illustrés ---------- */

.carte--evenement { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.carte--evenement__texte { padding: 22px; }
.carte--evenement__texte > :last-child { margin-bottom: 0; }

.affiche {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  background: var(--sable);
}

.entree-libre {
  margin: 0;
  padding: 10px 14px;
  border-left: 3px solid var(--or);
  background: var(--sable);
  border-radius: 0 8px 8px 0;
}

/* La pastille du logo porte le motif de la section (assets/js/icone.js) : le
   glyphe remplace la lettre, la taille du texte ne le concerne plus. */
.logo__marque--motif { font-size: 0; }
.logo__marque--motif svg { display: block; }

/* ---------- L'écusson du groupe ----------
   Déposé à la main dans `assets/logo-itaparica.png` et posé par `marque.js`
   seulement s'il a chargé : sans lui, la pastille garde sa lettre ou le motif
   de la section. Le fond doré disparaît — l'écusson porte déjà son cercle, et
   deux disques l'un dans l'autre font une cocarde. */
.logo__marque--image {
  background: none;
  padding: 0;
  overflow: hidden;
}

.logo__marque--image img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}


/* ---------- Galerie publique (migration 0044) ---------- */

.galerie {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(260px, 100%), 1fr));
  gap: 16px;
}

.media-public {
  margin: 0;
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--blanc);
  border: 1px solid var(--gris-clair);
  display: block;
  color: inherit;
  text-decoration: none;
}

.media-public img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

/* Une vidéo sans vignette : un aplat et le triangle de lecture, plutôt
   qu'un cadre vide dont on ne saurait pas qu'il est cliquable. */
.media-public--video .media-public__lecture {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  background: var(--vert);
  color: var(--or);
  font-size: 2.4rem;
}

.media-public__legende {
  display: block;
  padding: 12px 14px;
  font-size: .94rem;
  font-weight: 600;
}

.media-public__legende .discret {
  display: block;
  font-weight: 400;
  font-size: .84rem;
}

.media-public--video:hover { border-color: var(--vert-clair); }

/* Média associé à un contenu modifié depuis le backoffice (migration 0047). */
.contenu__media {
  border-radius: var(--rayon);
  margin-top: 18px;
  max-height: 340px;
  object-fit: cover;
  width: 100%;
}

/* **Un visuel illustre, il n'occupe pas la page.**

   Posé dans le flux — pleine largeur, ou sous un texte qu'on n'a pas
   réécrit — le bloc prenait toute la largeur du conteneur : 952 px de large
   et 568 px de haut pour une vidéo sur un écran de bureau, soit plus d'un
   demi-écran pour ce qui accompagne trois lignes de texte. On le borne à une
   largeur de lecture.

   Dans une colonne de `.section-illustree`, la borne saute : c'est la
   colonne qui décide, et elle fait déjà moins que ça. */
.visuel, .carrousel { max-width: 520px; }

.section-illustree__visuel .visuel,
.section-illustree__visuel .carrousel { max-width: none; }

/* ---------- Albums de la galerie (migration 0050) ---------- */

/* Un album n'a pas besoin d'un cadre : le titre et l'espace suffisent à
   dire où il commence, et un encadré autour d'une grille de photos ferait
   une boîte dans une boîte. */
.album-public + .album-public { margin-top: 34px; }

.album-public h2 {
  font-size: 1.35rem;
  margin: 0 0 14px;
}

/* Texte écrit par un adhérent (avis, migration 0049).
   Une adresse collée, ou n'importe quelle suite sans espace, impose sinon sa
   largeur à toute la page : sur un téléphone le navigateur répond en
   dézoomant, et c'est tout l'écran qui devient minuscule. */
.texte-libre {
  overflow-wrap: anywhere;
}

/* ---------- Fiches de l'équipe (migration 0051) ---------- */

/* Le portrait occupe toute la largeur de la carte, en haut : les huit
   encadrés d'origine n'ont pas d'image, une fiche qui en gagne une ne doit
   pas pour autant changer de gabarit. */
.carte--membre { display: flex; flex-direction: column; }

/* La première fiche tient toute la largeur : c'est celle du fondateur, elle
   est la plus longue, et la voir se serrer dans une colonne de 260 px à côté
   des autres ne rendait ni le texte ni la photo. Vaut aussi pour les encadrés
   écrits dans le HTML, qui n'ont pas la classe `carte--membre`.

   **Le nombre de colonnes est fixé, pas déduit.** `auto-fit` replie les pistes
   qu'aucun élément n'occupe — mais une fiche qui s'étend sur toutes les
   occupe justement toutes, donc plus rien ne se replie : avec deux membres,
   la grille restait à trois colonnes et la seconde fiche se retrouvait
   étranglée dans un tiers de largeur, le reste de la rangée vide. Deux
   colonnes conviennent de toute façon mieux à des biographies qu'une
   ribambelle de colonnes étroites. */
[data-equipe] {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

@media (max-width: 700px) {
  [data-equipe] { grid-template-columns: minmax(0, 1fr); }
}

[data-equipe] > .carte:first-child { grid-column: 1 / -1; }

/* En pleine largeur et avec une photo, elle se lit en deux colonnes : le
   portrait à gauche, le texte à droite.

   **Deux cellules, pas davantage.** Le texte forme un seul bloc, ce qui
   évite le défaut qu'on avait : chaque enfant de la carte occupait sa propre
   rangée, le portrait s'étendait sur toutes, et la hauteur en trop se
   répartissait entre le titre, le rôle et les paragraphes — un grand vide
   s'ouvrait sous le nom. `align-items: start` laisse maintenant les deux
   colonnes commencer en haut, chacune de sa hauteur. */
@media (min-width: 700px) {
  .carte--membre--large {
    display: grid;
    /* `auto` et non une largeur fixe : la colonne se règle sur la photo, qui
       se règle sur elle-même. Une colonne de largeur imposée obligerait à
       choisir entre rogner et matelasser. */
    grid-template-columns: auto minmax(0, 1fr);
    gap: 28px;
    align-items: start;
  }
  .carte--membre--large .membre__portrait { margin-bottom: 0; }
}

.membre__texte > :first-child { margin-top: 0; }
.membre__texte p { margin-bottom: .85em; }
.membre__texte p:last-child { margin-bottom: 0; }

/* Le mot personnel est une citation, pas la suite de la biographie : il
   change de voix. Le filet et le retrait le disent sans avoir à l'annoncer. */
.membre__mot {
  margin: 18px 0 0;
  padding: 2px 0 2px 16px;
  border-left: 3px solid var(--or);
  color: var(--gris);
  font-style: italic;
}
.membre__mot p:last-child { margin-bottom: 0; }

/* **On n'impose aucun cadre au portrait.** Un cadre en 4/3 avec
   `object-fit: cover` mangeait 42 % d'une photo verticale — le haut du crâne
   et le menton, précisément ce qu'on vient voir. Passer à `contain` corrigeait
   le rognage mais laissait des bandes qu'il fallait matelasser, c'est-à-dire
   traiter la conséquence d'un cadre dont on n'a pas besoin.

   L'image se dimensionne donc elle-même, simplement bornée : elle garde ses
   proportions exactes, rien n'est coupé ni étiré ni matelassé, et une photo
   très verticale ne pousse pas le texte hors de l'écran. */
.membre__portrait {
  width: auto;
  max-width: 100%;
  max-height: 300px;
  align-self: start;
  border-radius: calc(var(--rayon) - 4px);
  margin-bottom: 14px;
}

.membre__role { margin: -6px 0 10px; }

/* ---------- Vidéos de la galerie : façade puis lecteur ----------
   Rien de YouTube n'est chargé avant le clic (voir `assets/js/video.js`) :
   la façade est une image de notre bucket, ou un simple aplat. */
.video { margin: 0; }

.video__facade,
.video__cadre {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--rayon);
  overflow: hidden;
}

.video__facade {
  position: relative;
  padding: 0;
  background: var(--vert);
  cursor: pointer;
}

.video__facade img {
  width: 100%;
  height: 100%;
  object-fit: cover;   /* une affiche de vidéo est cadrée pour l'être */
}

.video__fond {
  position: absolute;
  inset: 0;
  background: linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}

/* ---------- La façade d'une vidéo sans affiche ----------
   Un aplat vert n'annonçait rien et ressemblait à une panne. Une silhouette
   du groupe dit au moins de quoi il s'agit — et sept figures plutôt qu'une,
   parce qu'une grille de façades identiques fait moins illustration que
   motif de papier peint.

   **Les fichiers sont déposés à la main** dans `assets/motifs/`. Absents, le
   `background-image` ne charge rien et le dégradé reste seul : exactement ce
   que la page montrait avant. Aucune vérification à écrire — c'est le repli
   naturel d'une image de fond, et c'est pourquoi on passe par la CSS ici
   plutôt que par un `<img>`.

   Une affiche déposée (`medias.vignette_url`) l'emporte toujours : elle
   remplace la façade entière, ce bloc ne la concerne pas. */
.video__fond {
  /* **Les deux couches dans la même déclaration.** Écrire `background-image`
     seul écrasait le dégradé posé plus haut par le raccourci `background` :
     fichier absent, la façade devenait vide au lieu de rester verte — c'est
     exactement le repli qu'on croyait avoir. La sonde l'a dit. */
  background-image: url("/assets/motifs/capoeira-1.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
  background-repeat: no-repeat;
  background-position: center;
  /* Assez grande pour se lire, assez petite pour rester un fond. */
  background-size: auto 62%, cover;
  /* La silhouette est noire sur disque clair : sur le vert sombre elle
     disparaîtrait. On l'éclaircit plutôt que de demander sept fichiers de
     plus. */
  filter: invert(1) opacity(.28);
}

.video:nth-of-type(7n + 2) .video__fond {
  background-image: url("/assets/motifs/capoeira-2.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}
.video:nth-of-type(7n + 3) .video__fond {
  background-image: url("/assets/motifs/capoeira-3.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}
.video:nth-of-type(7n + 4) .video__fond {
  background-image: url("/assets/motifs/capoeira-4.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}
.video:nth-of-type(7n + 5) .video__fond {
  background-image: url("/assets/motifs/capoeira-5.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}
.video:nth-of-type(7n + 6) .video__fond {
  background-image: url("/assets/motifs/capoeira-6.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}
.video:nth-of-type(7n + 7) .video__fond {
  background-image: url("/assets/motifs/capoeira-7.png"),
                    linear-gradient(160deg, var(--vert) 0%, #0a2b20 100%);
}

/* Le chevron reste lisible sur n'importe quelle affiche : c'est le seul
   repère qui dit que le bloc se clique. */
.video__lecture {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 64px;
  height: 64px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(224, 165, 38, .92);
  color: var(--vert);
  font-size: 1.5rem;
  padding-left: 4px;   /* le glyphe ▶ n'est pas centré dans sa chasse */
}

.video__facade:hover .video__lecture { background: var(--or-clair); }

.video__legende { margin: 8px 0 0; }

/* ==========================================================
   Les visuels d'une section (migration 0064)
   ========================================================== */

/* ---------- Un visuel à côté du texte ----------
   « Proportionné » : le texte garde la plus grande part — c'est lui qu'on
   vient lire. En dessous de 760 px les deux colonnes s'empilent, le visuel
   après le texte. */
.section-illustree {
  align-items: start;
  display: grid;
  gap: clamp(18px, 3vw, 32px);
}

@media (min-width: 760px) {
  .section-illustree {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  }
  /* Le visuel à gauche : on inverse les pistes plutôt que l'ordre du HTML,
     pour que la lecture au clavier et à l'oreille reste texte puis image. */
  .section-illustree--gauche {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.35fr);
  }
  .section-illustree--gauche .section-illustree__texte { grid-column: 2; grid-row: 1; }
  .section-illustree--gauche .section-illustree__visuel { grid-column: 1; grid-row: 1; }
}

.section-illustree__texte > p:first-child { margin-top: 0; }
.section-illustree__visuel .contenu__media { margin-top: 0; }

/* ---------- Agrandir une photo ----------
   Le bouton n'est qu'une enveloppe : il ne doit rien ajouter visuellement,
   seulement rendre la photo cliquable au clavier comme à la souris. */
.visuel__loupe {
  background: none;
  border: 0;
  cursor: zoom-in;
  display: block;
  padding: 0;
  width: 100%;
}

.visuel__loupe:focus-visible { outline: 3px solid var(--or); outline-offset: 3px; }

.agrandissement {
  background: transparent;
  border: 0;
  max-height: 100%;
  max-width: 100%;
  padding: 0;
}

.agrandissement::backdrop { background: rgba(0, 0, 0, .82); }

.agrandissement img {
  border-radius: var(--rayon);
  display: block;
  margin: 0 auto;
  max-height: 86vh;
  max-width: 92vw;
  object-fit: contain;
}

.agrandissement__legende {
  color: rgba(255, 255, 255, .86);
  margin: 10px 0 0;
  text-align: center;
}

.agrandissement__fermer {
  background: rgba(0, 0, 0, .55);
  border: 0;
  border-radius: 999px;
  color: #fff;
  cursor: pointer;
  font-size: 1.6rem;
  height: 44px;
  line-height: 1;
  position: fixed;
  right: 16px;
  top: 16px;
  width: 44px;
}

/* ---------- Carrousel ----------
   Manuel : rien ne défile tout seul. Une vue à la fois, en `hidden` — pas de
   piste qui glisse, dont la largeur serait à calculer et qui se disloquerait
   dès qu'une vidéo s'y trouve. */
.carrousel__scene { position: relative; }

.carrousel__barre {
  align-items: center;
  display: flex;
  gap: 10px;
  justify-content: center;
  margin-top: 10px;
}

.carrousel__fleche {
  background: var(--gris-clair);
  border: 0;
  border-radius: 999px;
  color: var(--vert);
  cursor: pointer;
  font-size: 1.3rem;
  height: 36px;
  line-height: 1;
  width: 36px;
}

.carrousel__fleche:hover { background: var(--or-clair); }

.carrousel__points { display: flex; gap: 6px; }

.carrousel__point {
  background: var(--gris-clair);
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  height: 9px;
  padding: 0;
  width: 9px;
}

.carrousel__point.est-actif { background: var(--vert); }

/* ---------- Une image en fond d'en-tête ----------
   Le dégradé sombre est conservé **par-dessus** la photo : c'est lui qui
   garde le texte blanc lisible, et on ne peut pas savoir à l'avance si la
   photo déposée est claire ou sombre. */
.a-fond { overflow: hidden; position: relative; }
.a-fond > .conteneur { position: relative; z-index: 2; }

.a-fond__images,
.a-fond__voile { inset: 0; position: absolute; }
.a-fond__images { z-index: 0; }
.a-fond__voile {
  background: linear-gradient(160deg, rgba(6, 42, 31, .84) 0%, rgba(10, 43, 32, .93) 100%);
  z-index: 1;
}

.a-fond__vue {
  background-position: center;
  background-size: cover;
  inset: 0;
  opacity: 0;
  position: absolute;
  transition: opacity 1.4s ease-in-out;
}

.a-fond__vue.est-visible { opacity: 1; }

@media (prefers-reduced-motion: reduce) {
  .a-fond__vue { transition: none; }
}

/* ---------- Un formulaire replié ----------
   Les deux formulaires de la page « Cours & horaires » — l'essai et le code
   famille — font une dizaine de champs à eux deux. Dépliés d'office, ils
   repoussaient hors de l'écran ce qui vient après, sur une page qu'on
   parcourt d'abord pour les horaires. `<details>` fait le repli sans une
   ligne de JavaScript, et reste ouvrable au clavier. */
.deplier {
  border-top: 1px solid var(--gris-clair);
  margin-top: 16px;
  padding-top: 4px;
}

.deplier > summary {
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  padding: 12px 0;
  position: relative;
}

/* Le chevron est écrit ici plutôt que laissé au navigateur : le marqueur
   natif diffère d'un moteur à l'autre, et Safari ne le place pas au même
   endroit. `::-webkit-details-marker` retire celui de WebKit. */
.deplier > summary::-webkit-details-marker { display: none; }

.deplier > summary::after {
  color: var(--vert);
  content: '＋';
  font-weight: 400;
  margin-left: 8px;
}

.deplier[open] > summary::after { content: '−'; }

.deplier > summary:focus-visible {
  border-radius: var(--rayon);
  outline: 3px solid var(--or);
  outline-offset: 2px;
}

.deplier > summary:hover { color: var(--vert); }

/* ---------- Un groupe de champs (une séance d'essai) ----------
   Chaque séance a son cours et sa date (migration 0065) : les regrouper
   évite de laisser croire qu'une seule date se rapporte aux deux. */
.champ-groupe {
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  margin: 0 0 14px;
  padding: 4px 14px 0;
}

.champ-groupe > legend {
  color: var(--vert);
  font-weight: 600;
  padding: 0 6px;
}

/* ---------- Page contact : le formulaire et les moyens de nous joindre ----------

   `.formulaire` est borné à 560 px, et c'est voulu : au-delà, un champ de
   saisie devient une ligne qu'on ne relit pas. Mais placé seul dans une
   section pleine largeur, il laissait la moitié droite vide sous un titre
   qui, lui, allait au bord — d'où l'impression de page inachevée. Les deux
   colonnes remplissent cette moitié avec ce qu'on y cherche justement :
   l'adresse et le numéro.

   L'ordre du HTML est celui de la lecture — comment nous joindre tout de
   suite, puis le formulaire — et il ne s'inverse pas : sur un téléphone les
   trois cartes passent au-dessus, ce qui est le bon ordre là aussi.

   Les minimums de piste sont bornés par `min(…, 100%)` : une piste plus large
   que l'écran fait déborder la page, et le navigateur mobile répond en
   dézoomant tout. */
.contact-double {
  display: grid;
  gap: 28px;
  align-items: start;
  grid-template-columns: minmax(min(300px, 100%), 1fr) minmax(0, 1.4fr);
}

/* Les cartes s'empilent dans leur colonne : côte à côte elles se serraient,
   et la grille les étirait toutes à la hauteur de la plus haute. */
.contact-double__moyens { grid-template-columns: minmax(0, 1fr); }

/* Le formulaire prend la colonne : sa borne de 560 px vaut pour une section
   pleine largeur, pas pour une colonne déjà étroite. */
.contact-double__message .formulaire { max-width: none; }
.contact-double__message > h2 { margin-top: 0; }

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

/* ---------- Couverture d'album et visionneuse ----------

   Un album s'annonce par une image et son nombre de photos : cinquante-neuf
   vignettes les unes sous les autres ne se parcourent pas. Le clic ouvre la
   pile dans une `<dialog>` native — Échap, piège au clavier et fond inerte
   viennent avec, sans une ligne à écrire. */
.galerie--albums {
  grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr));
  /* `.album-public + .album-public` ne s'applique pas au premier bloc qui
     suit les couvertures : sans cette marge, « Autres photos » se collait
     au bas de la dernière couverture. */
  margin-bottom: 34px;
}

.galerie--albums:last-child { margin-bottom: 0; }

.album-couverture {
  position: relative;
  display: block;
  padding: 0;
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
  overflow: hidden;
  background: var(--blanc);
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  width: 100%;
}

.album-couverture img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.album-couverture__texte {
  position: absolute;
  inset: auto 0 0 0;
  padding: 14px;
  /* Le dégradé, et non un aplat : la photo reste lisible sous le nom, et on
     ne sait pas d'avance si elle est claire ou sombre à cet endroit. */
  background: linear-gradient(transparent, rgb(0 0 0 / .75));
  color: #fff;
}

.album-couverture__nom { display: block; font-weight: 700; }
.album-couverture__texte .discret { color: rgb(255 255 255 / .8); }

.album-couverture:hover { border-color: var(--vert-clair); }
.album-couverture:focus-visible { outline: 2px solid var(--vert-clair); outline-offset: 2px; }

.visionneuse {
  border: 0;
  border-radius: var(--rayon);
  padding: 0;
  background: var(--blanc);
  color: inherit;
  max-width: min(1000px, 94vw);
  width: 100%;
}

.visionneuse::backdrop { background: rgb(0 0 0 / .8); }

.visionneuse__barre {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--gris-clair);
}

.visionneuse__titre { flex: 1; }

.visionneuse__fermer, .visionneuse__fleche {
  border: 0;
  background: none;
  font: inherit;
  cursor: pointer;
  color: inherit;
  /* 44 px : une cible qu'on atteint au pouce sans viser. */
  min-width: 44px;
  min-height: 44px;
  font-size: 1.6rem;
  line-height: 1;
}

.visionneuse__scene {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  background: #000;
}

.visionneuse__scene img {
  display: block;
  width: 100%;
  max-height: 74vh;
  object-fit: contain;
}

.visionneuse__fleche {
  color: #fff;
  align-self: stretch;
  padding: 0 8px;
}

.visionneuse__legende { padding: 12px 14px; margin: 0; }

/* ---------- Choix d'un visuel au backoffice ----------

   Quatre-vingts entrées en liste, on ne retrouve pas une photo dont on ne se
   rappelle pas le titre. On les montre. */
.choix-medias {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr));
  gap: 10px;
  max-height: 340px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid var(--gris-clair);
  border-radius: var(--rayon);
}

.choix-media {
  position: relative;
  display: block;
  border: 2px solid transparent;
  border-radius: var(--rayon);
  padding: 4px;
  cursor: pointer;
}

.choix-media img, .choix-media__sans {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 4px;
  background: var(--sable);
}

.choix-media__sans { display: grid; place-items: center; font-size: 1.6rem; }

.choix-media input {
  position: absolute;
  top: 8px;
  left: 8px;
  width: 20px;
  height: 20px;
  accent-color: var(--vert);
}

.choix-media__nom {
  display: block;
  font-size: .82rem;
  line-height: 1.3;
  margin-top: 4px;
  overflow-wrap: anywhere;
}

.choix-media__nom .discret { display: block; font-size: .76rem; }

/* La sélection se voit d'un coup d'œil, sans relire les cases une à une. */
.choix-media:has(input:checked) { border-color: var(--vert); background: var(--sable); }
.choix-media:focus-within { outline: 2px solid var(--vert-clair); outline-offset: 1px; }

/* Un brouillon ne s'affichera pas sur le site : le dire avant de le cocher. */
.choix-media--brouillon img { opacity: .55; }

/* ---------- Fiche illustrée par une photo ----------

   La photo prend la place du pictogramme, en haut de la carte et à ses
   bords : une image cadrée dans le rembourrage de la carte fait une vignette
   posée là, pas une illustration. Le rembourrage passe donc au corps. */
.carte--illustree { padding: 0; overflow: hidden; }

.carte--illustree .visuel,
.carte--illustree .carrousel { max-width: none; }

.carte--illustree .contenu__media {
  aspect-ratio: 4 / 3;
  border-radius: 0;
  margin-top: 0;
  max-height: none;
}

/* Le bouton d'agrandissement n'est qu'une enveloppe : il ne doit pas
   introduire de bord blanc entre la photo et la carte. */
.carte--illustree .visuel__loupe { display: block; }

.carte--illustree .carte__corps { padding: 22px 24px 24px; }
.carte--illustree .carte__corps > :last-child { margin-bottom: 0; }

/* ---------- Fond d'une section ajoutée (migration 0069) ----------

   Un texte d'une autre main — les neuf règles de Mestre Bimba — se lit
   autrement s'il se détache du reste. `accent` le pose sur le vert de
   l'association, avec la nuance de texte qui va avec : un fond sombre sans
   couleur de texte explicite hérite de l'encre du site et devient
   illisible. */
.contenu-ajoute--accent {
  background: var(--vert);
  color: var(--blanc);
}

.contenu-ajoute--accent h2,
.contenu-ajoute--accent h3 { color: var(--blanc); }
.contenu-ajoute--accent p { color: rgb(255 255 255 / .88); }
.contenu-ajoute--accent .discret { color: rgb(255 255 255 / .72); }
.contenu-ajoute--accent a { color: var(--or-clair); }

/* ---------- Aperçu de l'agenda, en page d'accueil ---------- */
.carte--agenda { display: flex; flex-direction: column; padding: 0; overflow: hidden; }

.carte--agenda__affiche {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  width: 100%;
}

.carte--agenda__texte { padding: 20px 22px 22px; }
