/* ==========================================================================
   Rebels Country Dancers 37 — feuille de style du site public

   Parti pris : sobre et moderne. Une seule famille de caractères, différenciée
   par la graisse et la taille ; l'or du logo en accent, jamais en aplat ; une
   couleur par niveau de cours, qui garde le même sens sur tout le site.

   Conçu pour le téléphone d'abord, et pour être lu sans effort à partir de
   50 ans : corps de texte généreux, contrastes francs, cibles tactiles larges.
   ========================================================================== */

:root {
    /* --- Couleurs ------------------------------------------------------- */

    /* Fonds : un blanc cassé chaud pour la page, du blanc pur pour ce qui
       se détache. */
    --page:      #faf8f5;
    --surface:   #ffffff;
    --surface-2: #f3efe8;

    /* Textes. --encre-2 tient le 4,5:1 sur --page comme sur --surface. */
    --encre:     #191712;
    --encre-2:   #56504a;

    --trait:     #e3ded4;
    --trait-net: #cec6b8;

    /* L'or du logo. --or sert aux aplats et aux filets ; --or-texte est la
       seule déclinaison qui passe le contraste sur fond clair. */
    --or:        #b8912f;
    --or-clair:  #e8c86a;
    --or-pale:   #f7edd6;
    --or-texte:  #7c5e13;

    /* Une couleur par niveau : même sens partout, du répertoire aux filtres. */
    --debutant:      #1f7a4c;
    --novice:        #1f5f94;
    --intermediaire: #a8501b;
    --pot-commun:    #6b4e9b;

    /* Les mêmes teintes éclaircies, pour les fonds sombres : sur l'encre du
       pied de page, les valeurs ci-dessus deviennent illisibles. */
    --debutant-clair:      #63c795;
    --novice-clair:        #72b8ec;
    --intermediaire-clair: #e6a173;
    --pot-commun-clair:    #b79ce3;

    --succes:      #1f6b45;
    --succes-fond: #e8f3ec;
    --alerte:      #a13a22;
    --alerte-fond: #fbeae5;

    /* --- Typographie ---------------------------------------------------- */

    --texte: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
             Arial, sans-serif;

    /* --- Mesures -------------------------------------------------------- */

    --largeur:  1120px;
    --lecture:  68ch;   /* longueur de ligne confortable */

    --r-carte:    14px;
    --r-controle: 10px;
    --r-pilule:   999px;

    /* Une seule ombre, réservée à ce qui flotte réellement au-dessus du
       contenu : la barre de filtres collante et l'en-tête au défilement. */
    --ombre-flottante: 0 1px 2px rgb(25 23 18 / 5%), 0 8px 24px rgb(25 23 18 / 8%);

    /* --- Mouvement ------------------------------------------------------ */

    --duree: 220ms;
    --sortie: cubic-bezier(.16, 1, .3, 1);   /* décélération franche */
}

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */

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

html {
    scroll-behavior: smooth;
    /* Compense la hauteur de l'en-tête collant lors des sauts d'ancre. */
    scroll-padding-top: 6rem;
}

body {
    margin: 0;
    font-family: var(--texte);
    font-size: 1.125rem;      /* 18 px : lisible sans zoomer */
    line-height: 1.6;
    color: var(--encre);
    background: var(--page);
    -webkit-text-size-adjust: 100%;
    text-rendering: optimizeLegibility;
}

h1, h2, h3, h4 {
    margin: 0 0 .5em;
    line-height: 1.15;
    font-weight: 700;
    letter-spacing: -.02em;
    color: var(--encre);
    text-wrap: balance;
}

h1 { font-size: clamp(2rem, 1.4rem + 2.6vw, 2.9rem); }
h2 { font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2rem); }
h3 { font-size: 1.25rem; letter-spacing: -.015em; }
h4 { font-size: 1.0625rem; letter-spacing: -.01em; }

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a {
    color: var(--or-texte);
    text-underline-offset: .18em;
    text-decoration-thickness: 1px;
}
a:hover { color: var(--encre); text-decoration-thickness: 2px; }

strong { font-weight: 600; }

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

hr {
    border: 0;
    border-top: 1px solid var(--trait);
    margin: 3rem 0;
}

/* Les chiffres alignés verticalement : dates, compteurs, tarifs. */
time, .compteur-resultats, .danse-annee, .sortie-date {
    font-variant-numeric: tabular-nums;
}

/* --- Surfaces du navigateur : elles font partie du dessin ---------------- */

::selection { background: var(--or-pale); color: var(--encre); }

:root {
    accent-color: var(--or-texte);   /* cases à cocher, curseurs natifs */
    caret-color: var(--or-texte);
    scrollbar-color: var(--trait-net) transparent;
    scrollbar-width: thin;
}

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
    background: var(--trait-net);
    border: 3px solid var(--page);
    border-radius: var(--r-pilule);
}
::-webkit-scrollbar-thumb:hover { background: var(--or); }

:focus-visible {
    outline: 3px solid var(--or-texte);
    outline-offset: 2px;
    border-radius: 4px;
}

/* Sur fond sombre, l'or de texte ne fait que 2,96:1 contre l'encre : l'anneau
   de focus y serait invisible. Il passe à l'or clair (11:1). */
.bandeau :focus-visible,
.pied :focus-visible,
.saut-contenu:focus-visible {
    outline-color: var(--or-clair);
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
    }
}

/* Lien d'évitement pour la navigation au clavier */
.saut-contenu {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    background: var(--encre);
    color: var(--surface);
    padding: .85rem 1.25rem;
    font-weight: 600;
    text-decoration: none;
}
.saut-contenu:focus { left: 0; }

/* Texte destiné aux seuls lecteurs d'écran : il nomme un bouton dont le sens
   n'est porté que par un signe (les flèches d'ordre, en administration). */
.visuellement-cache {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   Icônes
   Dessinées à trait constant, jamais remplacées par un caractère Unicode.
   -------------------------------------------------------------------------- */

.icone {
    width: 1.25em;
    height: 1.25em;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.75;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.icone-pleine { fill: currentColor; stroke: none; }

/* --------------------------------------------------------------------------
   Mise en page
   -------------------------------------------------------------------------- */

.contenant {
    width: min(100% - 2rem, var(--largeur));
    margin-inline: auto;
}

main { min-height: 60vh; padding-bottom: 5rem; }

.section { padding: 3.5rem 0 0; }
.section:first-child { padding-top: 2.5rem; }

/* Un filet entre chaque section, pour les pages longues dont les sections
   changent de forme (« Notre club »). Porté par la section plutôt que par des
   <hr> répétés : il en manquerait un tôt ou tard. L'espace est symétrique de
   part et d'autre du trait. */
.sections-separees .section + .section {
    margin-top: 3.5rem;
    border-top: 1px solid var(--trait);
}

/* Plus d'air au-dessus d'un titre qu'en dessous. */
.entete-section {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: .35rem 1.5rem;
    margin-bottom: 1.5rem;
}
.entete-section h2 { margin: 0; }
.entete-section a { font-weight: 600; }

.titre-page {
    padding: 2.5rem 0 2rem;
    border-bottom: 1px solid var(--trait);
    /* Même espace sous ce filet que sous celui qui sépare deux sections. */
    margin-bottom: 3.5rem;
}

/* Le filet du titre de page tient lieu de filet inter-sections : la première
   section n'ajoute donc pas le sien, sans quoi son titre descendrait deux fois
   plus bas que tous les suivants. */
.titre-page + .section { padding-top: 0; }
.titre-page h1 { margin-bottom: .25em; }
/* Le chapô sous le titre d'une page s'aligne sur le bord droit du contenu qui
   le suit — la carte de recherche, les cartes du club, l'agenda — au lieu de
   s'arrêter à la mesure de lecture. Le décrochage laissait 424 px de vide à
   droite sur la première chose que voit le visiteur, et se répétait sur les
   cinq pages secondaires.

   Ce que ça coûte, et comment c'est payé : la ligne passe de 68 à ~109
   caractères, au-delà de la mesure confortable. L'interligne est donc relevé,
   parce que ce qui rend une ligne longue pénible n'est pas sa longueur mais le
   retour à la ligne suivante — l'œil doit retrouver le début de la bonne ligne,
   et un peu d'air le lui garantit.

   Le procédé ne vaut que pour un chapô de deux phrases. Il NE SE GÉNÉRALISE PAS
   au texte courant, qui garde `--lecture` — voir `.prose` juste en dessous. */
.titre-page p {
    margin: 0;
    font-size: 1.1875rem;
    line-height: 1.75;
    color: var(--encre-2);
}

.prose { max-width: var(--lecture); }

/* --------------------------------------------------------------------------
   Bandeau de contact et en-tête
   -------------------------------------------------------------------------- */

.bandeau {
    background: var(--encre);
    color: var(--or-pale);
    font-size: .9375rem;
    padding: .5rem 0;
}
.bandeau .contenant {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: .25rem 1.75rem;
}
.bandeau a {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--or-clair);
    text-decoration: none;
    padding: .5rem 0;   /* porte la cible tactile à 40 px */
}
.bandeau a:hover { color: var(--surface); text-decoration: underline; }
.bandeau-lieu {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}

.entete {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--surface);
    border-bottom: 1px solid var(--trait);
}

.entete .contenant {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .75rem 0;
}

/* Marque et bouton Menu forment une rangée qui ne se scinde jamais : c'est
   elle qui garantit la hauteur de l'en-tête sur téléphone. */
.entete-rangee {
    display: flex;
    align-items: center;
    gap: .75rem;
    min-width: 0;
}

.marque {
    display: flex;
    align-items: center;
    gap: .8rem;
    text-decoration: none;
    color: inherit;
}
.marque img {
    width: 54px;
    height: 54px;
    flex: none;
}
.marque-nom {
    display: block;
    font-size: 1.0625rem;
    font-weight: 700;
    letter-spacing: -.015em;
    line-height: 1.15;
    color: var(--encre);
}
.marque-lieu {
    display: block;
    font-size: .8125rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--or-texte);
}

.navigation ul {
    display: flex;
    flex-wrap: wrap;
    gap: .125rem;
    list-style: none;
    margin: 0;
    padding: 0;
}
.navigation a {
    display: block;
    padding: .6rem .85rem;
    border-radius: var(--r-controle);
    font-weight: 600;
    color: var(--encre);
    text-decoration: none;
    transition: background var(--duree) var(--sortie);
}
.navigation a:hover { background: var(--surface-2); }

/* La page courante : un filet plein sous le libellé, pas une pastille noire. */
.navigation a[aria-current="page"] {
    color: var(--or-texte);
    box-shadow: inset 0 -3px 0 var(--or);
    border-radius: var(--r-controle) var(--r-controle) 0 0;
}

.bouton-menu {
    display: none;
    align-items: center;
    gap: .5rem;
    padding: .65rem 1rem;
    border: 1px solid var(--trait-net);
    border-radius: var(--r-controle);
    background: var(--surface);
    color: var(--encre);
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}
.bouton-menu:hover { background: var(--surface-2); }
.bouton-menu .icone-fermer { display: none; }

/* La case à cocher pilote le menu : le repli fonctionne sans JavaScript. */
#menu {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
    pointer-events: none;
}
#menu:focus-visible ~ .entete-rangee .bouton-menu {
    outline: 3px solid var(--or-texte);
    outline-offset: 2px;
}

/* 1170 px, et le seuil se mesure : les sept entrées portent le menu à 836 px,
   qui, avec la marque (251 px) et leur écart (16 px), réclame 1104 px de
   conteneur — soit 1153 px de fenêtre, barre de défilement comprise. La marge
   jusqu'à 1170 px couvre les barres de défilement plus larges. Un en-tête à
   deux rangées ferait glisser la barre de filtres du répertoire dessous.

   Le conteneur du site plafonne à 1120 px (--largeur) : il ne reste donc que
   853 px de menu, et ce seuil ne peut pas monter indéfiniment. Passé ce
   budget, aucune largeur d'écran ne rattrape rien — c'est pourquoi l'arrivée
   de « Nous rejoindre » a ramené « Nous contacter » à « Contact » (30 août
   2026). Il était à 1080 px avec six entrées. */
@media (max-width: 1170px) {
    .bouton-menu { display: inline-flex; }
    .entete .contenant { flex-wrap: wrap; gap: .5rem; }
    .marque img { width: 46px; height: 46px; }

    /* Le nom du club se replie sur deux lignes plutôt que de repousser le
       bouton Menu sur une deuxième rangée : l'en-tête garde sa hauteur. */
    .entete-rangee { flex: 1 1 100%; justify-content: space-between; }
    .marque { flex: 0 1 auto; min-width: 0; gap: .65rem; }
    .marque > span { min-width: 0; }
    .marque-nom { font-size: 1rem; }
    .bouton-menu { flex: none; padding: .65rem .85rem; }

    /* Repli par l'affichage : c'est le seul mécanisme qui tienne sans
       JavaScript sur un élément flexible de hauteur indéfinie. */
    .navigation {
        display: none;
        width: 100%;
        padding-bottom: .5rem;
    }
    .navigation > ul {
        flex-direction: column;
        gap: 0;
    }
    .navigation a {
        padding: .9rem .5rem;
        border-radius: 0;
        border-top: 1px solid var(--trait);
    }
    /* Page courante : un aplat pâle, pas un liseré latéral. */
    .navigation a[aria-current="page"] {
        background: var(--or-pale);
        color: var(--or-texte);
        box-shadow: none;
        border-radius: 0;
    }

    #menu:checked ~ .navigation { display: block; }

    /* Le seul mouvement orchestré du site : les entrées du menu se posent
       l'une après l'autre à l'ouverture.

       Sans « both » et sans opacité nulle au repos : le menu part d'un état
       déjà visible. Si l'animation ne tourne pas — onglet en arrière-plan,
       rendu suspendu, moteur restreint — les liens restent lisibles. */
    @keyframes entree-menu {
        from { opacity: 0; transform: translateY(-.4rem); }
        to   { opacity: 1; transform: none; }
    }
    #menu:checked ~ .navigation a {
        animation: entree-menu var(--duree) var(--sortie);
    }
    #menu:checked ~ .navigation li:nth-child(1) a { animation-delay: 40ms; }
    #menu:checked ~ .navigation li:nth-child(2) a { animation-delay: 80ms; }
    #menu:checked ~ .navigation li:nth-child(3) a { animation-delay: 120ms; }
    #menu:checked ~ .navigation li:nth-child(4) a { animation-delay: 160ms; }
    #menu:checked ~ .navigation li:nth-child(5) a { animation-delay: 200ms; }

    #menu:checked ~ .entete-rangee .icone-menu { display: none; }
    #menu:checked ~ .entete-rangee .icone-fermer { display: block; }
}

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

.bouton {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    min-height: 48px;               /* cible tactile confortable */
    padding: .7rem 1.35rem;
    border: 1px solid transparent;
    border-radius: var(--r-controle);
    background: var(--encre);
    color: var(--surface);
    font: inherit;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    line-height: 1;
    transition: background var(--duree) var(--sortie),
                border-color var(--duree) var(--sortie),
                color var(--duree) var(--sortie);
}
.bouton:hover { background: #322d24; color: var(--surface); }

.bouton-secondaire {
    background: var(--surface);
    border-color: var(--trait-net);
    color: var(--encre);
}
.bouton-secondaire:hover {
    background: var(--surface);
    border-color: var(--or);
    color: var(--or-texte);
}

.bouton-danger {
    background: var(--surface);
    border-color: var(--alerte);
    color: var(--alerte);
}
.bouton-danger:hover { background: var(--alerte); color: var(--surface); }

.bouton-petit {
    min-height: 40px;
    padding: .45rem .9rem;
    font-size: .9375rem;
}

.bouton[disabled], .bouton[aria-disabled="true"] {
    background: var(--surface-2);
    border-color: var(--trait);
    color: var(--encre-2);
    cursor: not-allowed;
}

.rangee-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
}

/* Retour au toucher : le survol n'existe pas sur l'appareil de référence.
   Sans état pressé, aucune action du site n'accuse réception du doigt. */
.bouton:active { background: #0f0e0b; }
.bouton-secondaire:active { background: var(--or-pale); border-color: var(--or); }
.bouton-danger:active { background: var(--alerte); color: var(--surface); }
.navigation a:active { background: var(--trait); }
.danse:focus-within { border-color: var(--or); }

/* --------------------------------------------------------------------------
   Bannière d'ambiance
   --------------------------------------------------------------------------
   Une image décorative en tête de page, déposée en administration. Ce qui
   s'affiche n'est pas le fichier mais la ZONE que le club y a choisie : un
   rectangle verrouillé à la proportion de la page, tracé à la souris dans
   l'administration. Le fichier n'est jamais recoupé — la sélection est une
   donnée, ce qui la rend modifiable indéfiniment et évite d'exiger GD.

   Une seule mise en page, donc, et deux proportions : l'ACCUEIL est le plus
   haut (12/5, soit 600 px sur un écran de 1440) parce que le club y met une
   composition — nom, baseline, animatrices, logo — qui se lit en entier ou pas
   du tout ; une PAGE SECONDAIRE est plus plate (4/1, soit 360 px) parce qu'on
   n'y vient pas pour regarder une photo et que chaque pixel de hauteur retarde
   la liste. Les deux valeurs viennent de PHP par `--format` : elles se règlent
   dans inc/config.php, pas ici.

   `.banniere` est le cadre PLEINE LARGEUR : c'est lui qui porte le filet et le
   fond, de sorte qu'ils traversent l'écran même quand l'image, elle, s'arrête
   avant — ce qui n'arrive que sur une sélection trop petite pour l'écran. */

.banniere {
    width: 100%;
    position: relative;
    background: var(--page);
    border-bottom: 1px solid var(--trait);
    display: flex;
    justify-content: center;
}

/* Le cadre porte la forme et la limite de largeur ; l'image se place dedans.
   `--largeur-max` vaut la largeur en pixels de la ZONE choisie, pas celle du
   fichier : au-delà on n'obtiendrait pas plus d'image, on agrandirait celle
   qu'on a — donc on la ramollirait — en payant ce flou en hauteur d'écran. Les
   marges claires de chaque côté sont le bon arrêt, pas un pis-aller. */
.banniere-cadre {
    position: relative;
    overflow: hidden;
    width: 100%;
    max-width: var(--largeur-max, 1800px);
    aspect-ratio: var(--format, 4 / 1);
}

/* Repli sans sélection exploitable — image que le serveur n'a pas su mesurer.
   Un recadrage centré n'a besoin d'aucun chiffre, et vaut mieux qu'un cadre
   vide. C'est aussi la base sur laquelle `.cadree` écrit. */
.banniere-cadre img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* --- La zone choisie, placée dans le cadre --------------------------------
   L'image est agrandie du facteur qu'il faut pour que la zone remplisse la
   largeur (`--l` est sa largeur en fraction de l'image), puis décalée de la
   position de la zone (`--x`, `--y`, mêmes fractions).

   La hauteur n'apparaît pas, et ce n'est pas un oubli : la zone ayant la
   proportion EXACTE du cadre, l'agrandissement est uniforme — la hauteur suit
   d'elle-même par la proportion propre du fichier. C'est aussi ce qui interdit
   à l'image de se déformer, et la raison pour laquelle `cadre_banniere()`
   déduit la hauteur au lieu de la stocker.

   Le décalage passe par `translate` et non par `top`/`left` : les pourcentages
   d'un `translate` se comptent sur la taille de l'ÉLÉMENT, ce qui donne
   directement « recule de --x fois ta propre largeur ». Avec `left`, ils se
   compteraient sur le cadre, et il faudrait diviser par `--l` — un calcul de
   plus, et une dépendance à la résolution des pourcentages de hauteur sur une
   boîte dimensionnée par `aspect-ratio`, terrain glissant.

   `max-width: none` n'est PAS décoratif : la règle générale de ce fichier pose
   `img { max-width: 100% }`, et une largeur d'agrandissement — qui dépasse 100 %
   par construction, puisque la zone est une PARTIE de l'image — s'y faisait
   rabattre en silence. L'image arrivait alors trop petite pour son cadre et
   laissait une bande de fond en dessous. Le défaut est resté invisible tant que
   toutes les bannières gardaient la zone maximale (`--l: 1`, agrandissement de
   1) : il n'apparaît qu'à la première zone plus étroite que le fichier, et il
   revient au premier `max-width` reposé sur cette image. */
.banniere-cadre.cadree img {
    inset: 0 auto auto 0;
    max-width: none;
    width: calc(100% / var(--l));
    height: auto;
    transform: translate(calc(var(--x) * -100%), calc(var(--y) * -100%));
}

/* Une bannière coûte exactement sa hauteur au premier écran, et sur l'accueil
   c'est le champ de recherche qui recule d'autant. Ce qu'elle prend, la page
   en rend une partie : l'espace au-dessus du titre était là pour détacher le
   titre du menu, or la bannière le fait désormais mieux qu'un blanc. */
.banniere + main .accueil-entree { padding-top: 1.25rem; }
.banniere + main .titre-page { padding-top: 1.25rem; }

/* Le bas de l'image se fond dans la page plutôt que de s'arrêter net : la
   bannière est un fond, pas un cadre posé sur le contenu. */
.banniere::after {
    content: "";
    position: absolute;
    inset: auto 0 0;
    height: 3.5rem;
    background: linear-gradient(to bottom, transparent, var(--page));
    pointer-events: none;
}

/* --------------------------------------------------------------------------
   Accueil
   -------------------------------------------------------------------------- */

.accueil-entree {
    padding: 3rem 0 2.5rem;
    border-bottom: 1px solid var(--trait);
}
.accueil-entree h1 { max-width: 20ch; }
.accueil-entree p {
    max-width: var(--lecture);
    font-size: 1.1875rem;
    color: var(--encre-2);
}

/* Même traitement que le chapô des pages secondaires — voir `.titre-page p`,
   qui porte l'explication : aligné sur le bord droit des deux panneaux qui le
   suivent, interligne relevé pour compenser la ligne longue. L'accueil a son
   propre sélecteur parce qu'il n'a pas de `.titre-page`, et il vise le seul
   texte posé directement dans le conteneur : ceux des panneaux gardent leur
   mesure. */
.accueil-entree > .contenant > .texte p {
    max-width: none;
    line-height: 1.75;
}

/* La recherche de danse : première chose atteignable, y compris sur
   téléphone. C'est le trajet le plus emprunté du site. */
.recherche-rapide {
    margin: 0;
    max-width: 34rem;
}

/* Le champ et son bouton tiennent une seule rangée. « stretch » plutôt qu'un
   « center » : les deux prennent la hauteur de la rangée, sans qu'une valeur
   de hauteur ait à être répétée de part et d'autre. */
.recherche-champ {
    display: flex;
    align-items: stretch;
    gap: .5rem;
}
.recherche-champ .bouton { flex: none; }

/* Sous 420 px, « Chercher » ne laisse plus assez de champ pour lire ce qu'on
   tape : il passe sous le champ, sur toute la largeur. */
@media (max-width: 420px) {
    .recherche-champ { flex-wrap: wrap; }
    .recherche-champ .bouton { flex: 1 1 100%; }
}

.recherche-repere {
    margin: 1rem 0 .75rem;
    font-size: .9375rem;
    color: var(--encre-2);
}

.recherche-niveaux {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}

/* Les danses entrées récemment au répertoire. Même matière que les lignes de
   « Les chorégraphies » — filet, fond de surface, pastilles de niveau — mais
   la carte entière est le lien : sur téléphone, la cible fait toute la
   largeur. */
.nouveautes {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .75rem;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
}

.nouveaute {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .5rem;
    height: 100%;
    padding: .9rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    color: var(--encre);
    text-decoration: none;
}
.nouveaute:hover {
    border-color: var(--trait-net);
    color: var(--encre);
}
.nouveaute:hover .nouveaute-nom { text-decoration: underline; }

.nouveaute-nom {
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -.01em;
}

/* La flèche dit au repos que la carte mène quelque part. Le filet et le
   soulignement du survol ne le disent qu'à la souris — sur téléphone, rien ne
   l'annonçait. Elle est décorative au sens strict : le lien porte déjà le nom
   de la danse, un lecteur d'écran n'a rien à lire de plus, d'où aria-hidden. */
.nouveaute-pied {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .75rem;
    width: 100%;
    margin-top: auto;
}

.nouveaute-date {
    font-size: .9375rem;
    color: var(--encre-2);
    font-variant-numeric: tabular-nums;
}

.nouveaute-fleche {
    color: var(--or-texte);
    transition: transform var(--duree) var(--sortie);
}
/* Le pas de côté au survol : la flèche part dans le sens du lien. */
.nouveaute:hover .nouveaute-fleche { transform: translateX(.25rem); }

/* --------------------------------------------------------------------------
   Listes de contenu
   -------------------------------------------------------------------------- */

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

/* Élévation déclarée une seule fois : un filet, pas d'ombre. */
.carte {
    display: flex;
    flex-direction: column;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    overflow: hidden;
}
.carte-corps { padding: 1.35rem; flex: 1; }
.carte h3 { margin-bottom: .35rem; }
.carte img {
    width: 100%;
    aspect-ratio: 16 / 10;
    object-fit: cover;
    background: var(--surface-2);
}

.carte-date {
    display: block;
    margin-top: .5rem;
    font-size: .9375rem;
    color: var(--encre-2);
    font-variant-numeric: tabular-nums;
}

.sorties-list {
    display: flex;
    flex-direction: column;
    gap: .75rem;
}

.sortie-compact {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 1.5rem;
    align-items: start;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.15rem;
}

.sortie-compact img {
    width: 140px;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: 8px;
    background: var(--surface-2);
    cursor: pointer;
}

.sortie-compact img:hover {
    filter: brightness(0.95);
}

/* Le titre d'une carte compacte suit le degré « title small », quel que soit
   son niveau de titre : celui-ci découle de la structure du document (h2 de
   section → h3 de carte), pas de la taille voulue. */
.sortie-compact h3,
.sortie-compact h4 {
    margin-bottom: .15rem;
    font-size: 1.0625rem;
    letter-spacing: -.01em;
}

.pastilles-sortie-compacte {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin: .5rem 0 .6rem;
}

/* Plus serrées dans une carte compacte, mais jamais plus petites : le corps
   reste au plancher du système. */
.pastilles-sortie-compacte .pastille {
    padding: .25rem .65rem;
}

@media (max-width: 560px) {
    .sortie-compact {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .sortie-compact img {
        width: 100%;
        aspect-ratio: 16 / 9;
    }
}

/* Actualités : liste verticale avec image plus large qu'un événement */
.actualites-list {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.actualite {
    display: grid;
    grid-template-columns: 220px 1fr;
    gap: 1.5rem;
    align-items: start;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.15rem;
}

/* Sans illustration, la carte n'a plus de vignette à loger : le texte occupe
   toute sa largeur. Sans cette règle, `display: contents` fait tomber le corps
   dans la colonne de 220 px réservée à l'image, et le message se lit dans une
   colonne trois fois trop étroite. */
.actualite-sans-image { grid-template-columns: 1fr; }

.actualite-flex {
    display: contents;
}

.actualite-image {
    width: 220px;
    aspect-ratio: 4 / 3;
    object-fit: contain;
    background: var(--surface-2);
    border-radius: 8px;
    cursor: pointer;
}

.actualite-image:hover {
    filter: brightness(0.95);
}

.actualite-corps {
    display: flex;
    flex-direction: column;
    gap: .4rem;
}

.actualite-corps h3 {
    margin: 0 0 .35rem 0;
}

.actualite-texte {
    flex: 1;
    line-height: 1.6;
}

.lire-suite-btn {
    align-self: flex-start;
    margin-top: .5rem;
    padding: .5rem 1rem;
    background: transparent;
    border: 1px solid var(--trait);
    border-radius: var(--r-controle);
    color: var(--or-texte);
    font-weight: 600;
    cursor: pointer;
    transition: background var(--duree) var(--sortie),
                border-color var(--duree) var(--sortie);
}

.lire-suite-btn:hover {
    background: var(--or-pale);
    border-color: var(--or);
}

.actualite-date {
    display: block;
    margin-top: .5rem;
    font-size: .9375rem;
    color: var(--encre-2);
    font-variant-numeric: tabular-nums;
}

.actualite-epinglee {
    border-color: var(--or);
    background: var(--or-pale);
}

@media (max-width: 560px) {
    .actualite {
        grid-template-columns: 1fr;
        gap: 1rem;
    }

    .actualite-image {
        width: 100%;
    }
}

.carte-epinglee { border-color: var(--or); }
.carte-epinglee .carte-corps { background: var(--or-pale); }

.etiquette {
    display: inline-flex;
    align-items: center;
    padding: .25rem .7rem;
    border-radius: var(--r-pilule);
    background: var(--surface-2);
    color: var(--encre);
    font-size: .875rem;
    font-weight: 600;
    white-space: nowrap;
}
.etiquette-or { background: var(--or-pale); color: var(--or-texte); }

/* --------------------------------------------------------------------------
   Les tarifs

   Deux formules, donc deux cartes — et la réduction famille en note sous
   elles. Ce n'est pas une troisième formule mais une condition qui s'applique
   aux deux : lui donner une carte la ferait lire comme un choix possible.
   -------------------------------------------------------------------------- */

.tarifs-intro {
    max-width: var(--lecture);
    margin-bottom: 1.25rem;
    color: var(--encre-2);
}

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

.tarif {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .3rem;
    padding: 1.75rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    text-align: center;
}

.tarif-libelle {
    font-weight: 600;
    color: var(--encre-2);
}

/* Le prix est l'information que l'on vient chercher : il porte la taille. */
.tarif-prix {
    font-size: clamp(2.2rem, 1.6rem + 2vw, 2.9rem);
    font-weight: 700;
    line-height: 1.05;
    letter-spacing: -.03em;
    color: var(--encre);
    font-variant-numeric: tabular-nums;
}

/* La réduction famille n'est pas une troisième formule : c'est une condition
   qui s'applique aux deux. Elle prend donc la grammaire du message
   d'information — teinte cernée d'un filet complet — et non un liseré
   latéral, que le système refuse au-delà de 1 px. */
.tarif-note {
    margin-top: 1.25rem;
    padding: 1rem 1.25rem;
    background: var(--or-pale);
    border: 1px solid #e6d3a4;
    border-radius: var(--r-controle);
    color: #5c4715;
}
.tarif-note strong { color: #5c4715; }

/* --------------------------------------------------------------------------
   Les cours de la semaine
   -------------------------------------------------------------------------- */

.jour-cours {
    margin: 0 0 .35rem;
    padding-bottom: .4rem;
    border-bottom: 2px solid var(--trait);
    color: var(--encre-2);
    font-size: 1rem;
    text-transform: uppercase;
    letter-spacing: .06em;
}

/* La respiration entre deux jours. Elle doit être portée par « .panneau > … » :
   la règle générale « .panneau > h3 { margin-top: 0 } » est plus spécifique
   que « .jour-cours » seul et l'emporterait. */
.panneau > .jour-cours { margin-top: 3.25rem; }
.panneau > .jour-cours:first-child { margin-top: 0; }

.liste-cours {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Sur téléphone chaque information passe à la ligne ; à partir de 700 px les
   quatre colonnes s'alignent d'un cours à l'autre, ce qui rend la lecture du
   planning bien plus rapide. */
.cours {
    display: grid;
    gap: .3rem .9rem;
    padding: .9rem 0;
    border-bottom: 1px solid var(--trait);
}
.cours:last-child { border-bottom: 0; }
.cours .niveau { justify-self: start; }

.cours-horaire {
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}
.cours-lieu, .cours-animatrice {
    display: flex;
    align-items: center;
    gap: .35rem;
    color: var(--encre-2);
    font-size: .9375rem;
}
.cours-lieu:empty, .cours-animatrice:empty { display: none; }

/* Le visage de l'animatrice, repris de sa fiche : c'est le même repère que
   dans la section « Les animatrices », en plus petit. */
.cours-portrait {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: var(--r-pilule);
    object-fit: cover;
    background: var(--surface-2);
}
.cours-initiales {
    display: grid;
    place-items: center;
    font-size: .8125rem;
    font-weight: 700;
    color: var(--or-texte);
    background: var(--or-pale);
}

@media (min-width: 700px) {
    /* La dernière colonne a une largeur fixe plutôt que « auto » : c'est ce qui
       aligne les portraits et les noms d'un cours à l'autre, au lieu de les
       caler à droite sur une largeur qui dépend du nom. */
    .cours {
        grid-template-columns: 11rem 9rem 1fr 14rem;
        align-items: center;
    }
    /* Les cellules vides gardent leur place : sans quoi une ligne sans lieu
       ferait glisser l'animatrice sous la colonne du lieu. */
    .cours-lieu:empty, .cours-animatrice:empty { display: block; }
}

/* --------------------------------------------------------------------------
   L'équipe : animatrices et bureau
   -------------------------------------------------------------------------- */

.equipe {
    display: grid;
    gap: 1.25rem;
    /* Deux colonnes au plus : les descriptions sont du texte suivi, et sur
       trois colonnes les lignes cassaient au bout de quatre ou cinq mots. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 440px), 1fr));
    /* Les fiches d'une même rangée gardent la même hauteur, quelle que soit la
       longueur des descriptions : une rangée irrégulière se voit tout de suite.
       Sans effet sur téléphone, où chaque fiche occupe sa propre rangée. */
    align-items: stretch;
    list-style: none;
    margin: 1.25rem 0 0;
    padding: 0;
}

/* Portrait à gauche, texte à droite : la même fiche tient aussi bien une ligne
   de bureau (« Muriel — présidente ») qu'une animatrice et son parcours. */
.membre {
    display: flex;
    gap: 1.1rem;
    align-items: flex-start;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.35rem;
}

.membre-portrait {
    flex: none;
    width: 88px;
    height: 88px;
    border-radius: var(--r-pilule);
    object-fit: cover;
    background: var(--surface-2);
}

/* Le club n'a pas de photo de tout le monde : les initiales occupent la même
   place, plutôt que de laisser un trou dans la grille. */
.membre-initiales {
    display: grid;
    place-items: center;
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: 0;
    color: var(--or-texte);
    background: var(--or-pale);
}

.membre h3 { margin-bottom: .15rem; }

.membre-role {
    margin-bottom: .5rem;
    font-weight: 600;
    color: var(--or-texte);
}

.membre-description { color: var(--encre-2); }

@media (max-width: 420px) {
    .membre { padding: 1.1rem; gap: .9rem; }
    .membre-portrait { width: 66px; height: 66px; }
    .membre-initiales { font-size: 1.35rem; }
}

/* --------------------------------------------------------------------------
   Chorégraphies
   -------------------------------------------------------------------------- */

/* Élévation déclarée une seule fois : cette barre flotte, donc elle prend
   l'ombre — et pas de filet en plus. */
.filtres {
    position: sticky;
    top: 5.25rem;
    z-index: 10;
    background: var(--surface);
    border-radius: var(--r-carte);
    padding: 1.25rem;
    margin-bottom: 1.5rem;
    box-shadow: var(--ombre-flottante);
}
/* L'en-tête collant est plus haut sur téléphone (la marque passe sur deux
   lignes) : la barre de filtres se pose dessous, sans jamais s'y glisser.
   Ce seuil est celui du repli du menu, et se déplace avec lui. */
@media (max-width: 1170px) {
    .filtres { top: 6.75rem; }
}

/* Sur téléphone : la recherche occupe la largeur, les deux listes se
   partagent la ligne suivante. La barre reste sous le quart de l'écran. */
.filtres-ligne {
    display: grid;
    gap: 1rem;
    grid-template-columns: 1fr 1fr;
}
.filtres .champ { margin: 0; }
.champ-large { grid-column: 1 / -1; }

/* Sur écran étroit, les listes se décrivent elles-mêmes (« Tous les
   niveaux ») : leur intitulé sort de l'affichage sans sortir de
   l'accessibilité. */
@media (max-width: 699px) {
    .filtres select + label,
    .filtres label[for="filtre-niveau"],
    .filtres label[for="filtre-annee"] {
        position: absolute;
        width: 1px;
        height: 1px;
        margin: -1px;
        padding: 0;
        overflow: hidden;
        clip-path: inset(50%);
        white-space: nowrap;
    }
}

@media (min-width: 700px) {
    .filtres-ligne { grid-template-columns: 2fr 1fr 1fr; }
    .champ-large { grid-column: auto; }
}

/* La loupe se pose à l'intérieur du champ : ce conteneur est donc le bloc
   qui la porte, et il doit rester une vraie boîte positionnée. En
   « display: contents » il sortait de la mise en page, l'icône se calait sur
   un ancêtre quelconque et le champ perdait sa place dans la rangée. */
.champ-recherche {
    position: relative;
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
}
.champ-recherche .icone {
    position: absolute;
    left: .95rem;
    top: 50%;
    transform: translateY(-50%);
    color: var(--encre-2);
    pointer-events: none;
}
/* Spécificité volontairement renforcée : la règle générale des champs, plus
   bas dans le fichier, écraserait sinon ce retrait et le texte passerait
   sous la loupe. */
.champ-recherche input[type="search"] {
    flex: 1 1 auto;
    min-width: 0;
    padding-left: 2.75rem;
}

/* Une liste dont le filtre est actif se signale par son contour, sans
   qu'aucun script n'ait à l'annoncer. */
.filtres select:not(:has(option[value=""]:checked)) {
    border-color: var(--or);
    font-weight: 600;
}

/* Même mécanique pour la sortie de secours : le bouton n'apparaît que s'il y
   a quelque chose à effacer, et c'est le sélecteur qui le sait — pas un état
   tenu en JavaScript.

   On interroge ici l'option cochée et non la liste elle-même : « :has() » ne
   peut pas être imbriqué dans un autre « :has() », et un sélecteur invalide
   dans un groupe emporte tout le groupe. */
.effacer-filtres {
    display: none;
    margin-top: 1rem;
}
.filtres:has(option:not([value=""]):checked) .effacer-filtres,
.filtres:has(input[type="search"]:not(:placeholder-shown)) .effacer-filtres {
    display: inline-flex;
}

.compteur-resultats {
    margin: 0 0 1rem;
    font-size: .9375rem;
    color: var(--encre-2);
}
.compteur-resultats strong { color: var(--encre); }

.liste-danses {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: .5rem;
}

/* --- Les danses sans niveau enregistré ------------------------------------

   Un filtre de classement ne les efface pas : il les relègue sous ce
   séparateur. Leur place est tenue par « order » plutôt que par un
   déplacement dans le DOM — 234 lignes déplacées à chaque frappe se
   sentiraient sur un téléphone.

   Elles gardent exactement le dessin d'une ligne de danse : ce sont des
   danses du répertoire, pas un état dégradé. Seule leur position change. */

.danse-separateur {
    order: 1;
    margin-top: 1.25rem;
    padding-top: 1.25rem;
    border-top: 1px solid var(--trait);
}
.danse-ancienne { order: 2; }
.liste-danses.anciennes-repliees .danse-ancienne { display: none; }

.separateur-bascule {
    display: flex;
    align-items: center;
    gap: .5rem;
    width: 100%;
    min-height: 48px;
    padding: .35rem 0;
    border: 0;
    background: none;
    font: inherit;
    font-weight: 600;
    color: var(--encre);
    text-align: left;
    cursor: pointer;
}
.separateur-bascule:hover { color: var(--or-texte); }
.separateur-bascule .icone {
    transition: transform var(--duree) var(--sortie);
}
.separateur-bascule[aria-expanded="true"] .icone { transform: rotate(180deg); }

.separateur-aide {
    max-width: var(--lecture);
    margin: 0;
    font-size: .9375rem;
    color: var(--encre-2);
}

.danse {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem 1rem;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: .9rem 1.1rem;
}
/* Le liseré au survol ne se pose que sur les tuiles qui répondent au clic :
   sur une danse sans vidéo, il promettrait une action qui n'existe pas. */
.danse-cliquable:hover { border-color: var(--trait-net); }

.danse-nom {
    flex: 1 1 14rem;
    margin: 0;
    font-size: 1.125rem;
    font-weight: 600;
    letter-spacing: -.01em;
    color: var(--encre);
}

.danse-classements {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem;
}

/* Le niveau porte sa couleur sur la pastille elle-même : le sens est le
   même partout, et il ne dépend pas d'un liseré décoratif. */
.niveau {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .25rem .7rem;
    border-radius: var(--r-pilule);
    background: var(--surface-2);
    color: var(--encre-2);
    font-size: .875rem;
    font-weight: 600;
    white-space: nowrap;
}
.niveau::before {
    content: "";
    width: .5rem;
    height: .5rem;
    border-radius: 50%;
    background: currentColor;
}
.niveau-debutant      { color: var(--debutant);      background: #e9f3ed; }
.niveau-novice        { color: var(--novice);        background: #e7f0f7; }
.niveau-intermediaire { color: var(--intermediaire); background: #f8ece4; }
.niveau-pot-commun    { color: var(--pot-commun);    background: #efeaf6; }

.danse-annee {
    font-weight: 600;
    color: var(--encre-2);
}

.danse-actions {
    margin-left: auto;
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
}
.danse-sans-fiche {
    font-size: .9375rem;
    color: var(--encre-2);
}

/* La tuile entière lance la vidéo, sur téléphone comme sur grand écran : un
   seul geste, un seul résultat. C'est la vidéo qui a droit à cette surface et
   non la fiche, parce qu'elle est la seule des deux à se défaire — un appui
   par mégarde se rattrape d'un second appui, là où la fiche ouvrirait un
   onglet.

   La classe est posée par le script, jamais par le HTML : sans JavaScript la
   tuile ne fait rien, et rien ne doit alors laisser croire le contraire. */
.danse-cliquable { cursor: pointer; }

/* La fiche n'a plus la tuile pour cible : elle a droit sur petit écran à un
   bouton qu'on atteint au doigt, au-dessus du plancher des 44 px. */
@media (max-width: 699px) {
    .danse-actions .bouton-petit { min-height: 44px; }
}

/* Le lecteur se déplie sous la ligne, sur toute sa largeur : il pousse le
   reste du répertoire vers le bas plutôt que de le recouvrir. Pas de filet,
   le fond sombre du lecteur suffit à le poser.

   La largeur maximale est portée par le lecteur, jamais par ce conteneur :
   un `max-width` sur un enfant flex borne aussi la taille que le navigateur
   utilise pour décider du retour à la ligne. Le conteneur ne pesait donc pas
   100 % mais 44 rem, et sur une ligne courte — une danse sans pastille de
   niveau ni fiche — il remontait se placer à côté du nom. Ici il vaut
   toujours une ligne entière ; le lecteur se cale au milieu plutôt que de
   laisser un grand vide sur la droite. */
.danse-video {
    flex: 1 1 100%;
    display: flex;
    justify-content: center;
    margin-top: .35rem;
}
/* `display: flex` l'emporterait sur le `display: none` que le navigateur
   attache à [hidden] : sans cette ligne, un cadre vide reste ouvert. */
.danse-video[hidden] { display: none; }

.danse-video iframe {
    display: block;
    width: 100%;
    max-width: 44rem;
    aspect-ratio: 16 / 9;
    border: 0;
    border-radius: var(--r-carte);
    background: var(--encre);
}

.aucun-resultat {
    text-align: center;
    padding: 3.5rem 1.5rem;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    color: var(--encre-2);
}
.aucun-resultat strong { color: var(--encre); }
.aucun-resultat p { margin: 0; max-width: var(--lecture); margin-inline: auto; }

/* Une impasse sans sortie est une impasse : le message nomme ce qui a été
   cherché, ces boutons rouvrent le répertoire. */
.aucun-resultat-actions {
    display: flex;
    flex-wrap: wrap;
    gap: .75rem;
    justify-content: center;
    margin-top: 1.5rem;
}
.aucun-resultat-actions:empty { display: none; }

/* --------------------------------------------------------------------------
   Le pot commun 37
   -------------------------------------------------------------------------- */

/* Une année, un document, empilés du plus récent au plus ancien. La colonne
   reste en deçà du conteneur, mais assez large pour qu'un tableau de danses
   scanné se lise sans être ouvert : ces documents font autour de 1000 px de
   large, et les réduire davantage rendrait leurs colonnes illisibles. */
/* Toute la largeur du conteneur, alignée sur le titre de la page comme partout
   ailleurs sur le site. La colonne de 960 px qui tenait ici jusqu'au
   21 août 2026 laissait 80 px de blanc de chaque côté, sans que rien ne les
   justifie à l'œil : le titre commençait avant, la liste après. Ce que la
   colonne protégeait — la lisibilité d'un tableau de danses scanné — n'y perd
   rien, elle l'élargit. */
.pot-annee {
    margin: 3.5rem 0 0;
}
.pot-annee:first-child { margin-top: 0; }

.pot-annee h2 {
    margin-bottom: .75rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--trait);
}

.pot-document {
    display: block;
    width: 100%;
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    background: var(--surface);
}

/* Une image porte ses propres proportions, et s'ouvre en grand d'un clic sur
   elle-même : elle est sa propre commande, sans bouton pour le redire. */
img.pot-document { height: auto; }

.pot-lien-image { display: block; cursor: zoom-in; }
.pot-lien-image:hover .pot-document { border-color: var(--trait-net); filter: brightness(.97); }
.pot-lien-image:focus-visible .pot-document { border-color: var(--or); }

/* Un PDF n'a pas de cadre : trop de navigateurs — ceux des téléphones, ceux
   qui sont intégrés à une autre application — ne savent pas le rendre en
   place, et n'affichent alors qu'un rectangle vide. La carte annonce le
   document et porte son bouton : elle se suffit, et rien ne la suit. */
.pot-carte {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: .85rem 1.1rem;
    padding: 1.35rem;
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    background: var(--surface);
}
.pot-carte .icone {
    width: 1.75rem;
    height: 1.75rem;
    color: var(--or-texte);
}
/* Le texte pousse le bouton à droite tant que la ligne tient ; sous 14rem il
   passe à la ligne, et le bouton le suit. */
.pot-carte p {
    flex: 1 1 14rem;
    margin: 0;
    color: var(--encre-2);
}
.pot-carte .bouton { flex: none; }

/* --------------------------------------------------------------------------
   Agenda des sorties
   -------------------------------------------------------------------------- */

.mois {
    margin: 2.5rem 0 1rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid var(--trait);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--or-texte);
}
.mois:first-of-type { margin-top: 0; }

.sortie {
    display: grid;
    grid-template-columns: 140px 1fr;
    gap: 1.5rem;
    align-items: start;
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.15rem;
    margin-bottom: .75rem;
}
.sortie img {
    width: 140px;
    aspect-ratio: 3 / 4;
    object-fit: cover;
    border-radius: 8px;
    background: var(--surface-2);
    cursor: pointer;
}
.sortie img:hover { filter: brightness(0.95); }
.sortie-sans-affiche { grid-template-columns: 1fr; }
.sortie h3, .sortie h4 { margin-bottom: .15rem; font-size: 1.25rem; letter-spacing: -.015em; }
.sortie-date {
    display: block;
    font-weight: 600;
    color: var(--or-texte);
    margin-bottom: .35rem;
}

.pastilles-sortie {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: .8rem;
}

.pastille {
    display: inline-flex;
    align-items: center;
    padding: .35rem .8rem;
    border-radius: var(--r-pilule);
    font-size: .875rem;   /* le plancher du système, pas en dessous */
    font-weight: 600;
    white-space: nowrap;
}

/* Les pastilles de sortie n'empruntent que les deux étiquettes du système :
   l'or pour ce que le club organise lui-même, le neutre pour la condition
   d'accès. Elles portaient jusqu'ici les couleurs des niveaux de cours — un
   vert « débutant » pour « Organisé par les Rebels », un bleu « novice » pour
   « Ouvert au public » — à quelques centimètres d'une vraie pastille de
   niveau, ce qui cassait la règle du sens constant.

   « Ouvert au public » et « Réservé aux membres » ne paraissent jamais
   ensemble : c'est le mot qui les distingue, la couleur n'a rien à en dire. */
.pastille-club {
    background: var(--or-pale);
    color: var(--or-texte);
}

.pastille-public,
.pastille-membres {
    background: var(--surface-2);
    color: var(--encre);
}

.sortie-lieu {
    display: flex;
    align-items: center;
    gap: .4rem;
    margin-bottom: .6rem;
    color: var(--encre-2);
}

.passee { opacity: .75; }
.passee img { filter: saturate(.6); }

/* Lightbox pour agrandir les affiches */
.lightbox {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1000;
    background: rgba(25, 23, 18, 0.95);
    display: flex;
    align-items: center;
    justify-content: center;
}

.lightbox-contenu {
    position: relative;
    max-width: 90vw;
    max-height: 90vh;
}

.lightbox-contenu img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.lightbox-fermer {
    position: absolute;
    top: -3.5rem;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 48px;
    height: 48px;
    padding: 0;
    background: none;
    border: none;
    border-radius: var(--r-controle);
    color: var(--surface);
    cursor: pointer;
}
.lightbox-fermer .icone { width: 1.75rem; height: 1.75rem; }

.lightbox-fermer:hover {
    color: var(--or-clair);
}

/* Sur fond sombre, l'anneau de focus doit passer à l'or clair pour rester
   visible, comme au pied de page et dans le bandeau. */
.lightbox-fermer:focus-visible { outline-color: var(--or-clair); }

@media (max-width: 560px) {
    .lightbox-fermer {
        top: 1rem;
        right: 1rem;
        background: rgb(25 23 18 / 80%);
    }
}

@media (max-width: 560px) {
    .sortie { grid-template-columns: 1fr; gap: 1rem; }
    .sortie img { width: 100%; aspect-ratio: 16 / 9; }
}

/* --------------------------------------------------------------------------
   Panneaux d'information
   -------------------------------------------------------------------------- */

.panneau {
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
}

/* Un panneau qui occupe toute la largeur laisserait courir des lignes de
   120 caractères : le texte y garde la mesure de lecture. */
.panneau > p { max-width: var(--lecture); }
.panneau > h3 { margin-top: 0; }
/* Enfant direct seulement : ce détachement vaut pour l'action isolée en pied
   de panneau, pas pour un bouton pris dans une rangée (recherche, groupe
   d'actions), qu'il décalerait de ses voisins. */
.panneau > .bouton { align-self: flex-start; margin-top: 1rem; }

.panneau-boutons {
    display: flex;
    gap: 0.75rem;
    margin-top: auto;
    flex-wrap: wrap;
}

.infos-pratiques {
    list-style: none;
    margin: 0;
    padding: 0;
}
.infos-pratiques li {
    display: flex;
    gap: .85rem;
    align-items: baseline;
    padding: .7rem 0;
    border-bottom: 1px solid var(--trait);
}
.infos-pratiques li:first-child { padding-top: 0; }
.infos-pratiques li:last-child { padding-bottom: 0; border-bottom: 0; }

/* --------------------------------------------------------------------------
   Cartes de contact
   -------------------------------------------------------------------------- */

.contact-grille {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1.5rem;
    margin-bottom: 1.5rem;
}

.contact-carte {
    background: var(--surface);
    border: 1px solid var(--trait);
    border-radius: var(--r-carte);
    padding: 1.5rem;
    text-decoration: none;
    color: inherit;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    transition: border-color 200ms ease-out;
}

.contact-carte:hover {
    border-color: var(--trait-net);
}

.contact-carte .icone {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--surface-2);
    border-radius: var(--r-controle);
    color: var(--encre);
}

.contact-label {
    font-size: .9375rem;
    font-weight: 600;
    color: var(--encre-2);
    text-transform: uppercase;
    letter-spacing: .06em;
    margin: 0;
}

.contact-valeur {
    font-size: 1.125rem;
    color: var(--encre);
    margin: 0;
    line-height: 1.5;
    white-space: nowrap;
}

.contact-hint {
    font-size: .9375rem;
    color: var(--encre-2);
    margin: 0;
    line-height: 1.5;
}

.contact-carte-pleine {
    grid-column: 1 / -1;
}

.contact-carte-pleine .contact-valeur {
    white-space: normal;
}

@media (max-width: 600px) {
    .contact-grille {
        grid-template-columns: 1fr;
    }
    .contact-carte-pleine {
        grid-column: auto;
    }
}

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

.champ { margin-bottom: 1.5rem; }
.champ label {
    display: block;
    font-weight: 600;
    margin-bottom: .5rem;
}
.champ .aide {
    display: block;
    margin-top: .4rem;
    font-size: .9375rem;
    color: var(--encre-2);
}

input[type="text"], input[type="email"], input[type="url"], input[type="date"],
input[type="password"], input[type="search"], input[type="file"],
select, textarea {
    width: 100%;
    min-height: 48px;
    padding: .7rem .9rem;
    border: 1px solid var(--trait-net);
    border-radius: var(--r-controle);
    background: var(--surface);
    font: inherit;
    color: var(--encre);
    transition: border-color var(--duree) var(--sortie);
}
/* 4,5:1 sur fond blanc : le texte indicatif du champ le plus utilisé du site
   doit rester lisible à 60 ans. */
input::placeholder, textarea::placeholder { color: #6a645b; }

input:hover, select:hover, textarea:hover { border-color: var(--or); }
input:focus, select:focus, textarea:focus {
    border-color: var(--or-texte);
    outline: 3px solid var(--or-pale);
    outline-offset: 0;
}
textarea { min-height: 10rem; resize: vertical; line-height: 1.55; }

/* La croix native du champ de recherche, invisible sur fond clair. */
input[type="search"]::-webkit-search-cancel-button {
    -webkit-appearance: none;
    height: 1.1em;
    width: 1.1em;
    background: var(--encre-2);
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E") center / contain no-repeat;
    cursor: pointer;
}

.case {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
}
.case input { width: auto; min-height: 0; margin-top: .3rem; }

/* Piège à robots : invisible pour les humains, rempli par les automates */
.pot-de-miel {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* --------------------------------------------------------------------------
   Messages
   -------------------------------------------------------------------------- */

.message {
    display: flex;
    align-items: flex-start;
    gap: .7rem;
    padding: .9rem 1.15rem;
    border: 1px solid;
    border-radius: var(--r-controle);
    margin-bottom: 1.25rem;
}
.message-succes { background: var(--succes-fond); border-color: #b9d8c6; color: #14472e; }
.message-erreur { background: var(--alerte-fond); border-color: #eabfb4; color: #7a2a17; }
.message-info   { background: var(--or-pale);    border-color: #e6d3a4; color: #5c4715; }

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

   Trois blocs de renseignements — qui sommes-nous, quand, où — puis le plan du
   site et la mention légale. Les colonnes de liens qui doublaient le menu ont
   disparu : sur un téléphone, elles s'empilaient en un mur de liens qu'il
   fallait franchir pour atteindre le numéro de téléphone.
   -------------------------------------------------------------------------- */

.pied {
    margin-top: 5rem;
    padding: 3.5rem 0 1.75rem;
    background: var(--encre);
    color: #d9d3c6;
}
.pied a { color: var(--or-clair); text-decoration: none; }
.pied a:hover { color: var(--surface); text-decoration: underline; }
.pied ul { list-style: none; margin: 0; padding: 0; }

/* Le label du site, à l'identique : le pied ne se donne pas une échelle
   typographique à lui. */
.pied-titre {
    margin: 0 0 1rem;
    color: var(--surface);
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
}

/* Le bloc d'identité est le plus large : il porte un paragraphe, les deux
   autres des listes courtes. En dessous de 900 px, tout s'empile. */
.pied-blocs {
    display: grid;
    gap: 2.75rem;
    grid-template-columns: 1.5fr 1fr 1.1fr;
}
@media (max-width: 900px) {
    .pied-blocs { grid-template-columns: 1fr; gap: 2.25rem; }
}

/* Pas de logo ici : c'est un médaillon sombre cerné d'or, qui se dissout sur
   l'encre du pied. L'en-tête le porte déjà sur chaque page. */
.pied-nom {
    margin: 0 0 .5rem;
    color: var(--surface);
    font-size: 1.125rem;
    font-weight: 700;
    line-height: 1.3;
}
.pied-texte {
    margin: 0;
    max-width: 42ch;
    line-height: 1.6;
}

/* --- Les cours ------------------------------------------------------------
   Le niveau sur une ligne, ses créneaux sur la suivante : deux informations de
   nature différente ne se lisent pas d'un seul tenant, et la mise en colonne
   supporte « lundi 20h et jeudi 18h45 » sans le couper n'importe où. */
.pied-cours li + li { margin-top: .9rem; }
.pied-niveau {
    display: flex;
    align-items: center;
    gap: .5rem;
    /* La classe de niveau apporte sa teinte claire de pilule : sur l'encre,
       elle n'a rien à faire. Seule la couleur du texte est reprise. */
    background: none;
    color: var(--surface);
    font-weight: 600;
}
/* La pastille seule, sans le fond clair de la pilule `.niveau` : sur l'encre
   du pied, c'est le point de couleur qui porte le sens. */
.pied-niveau::before {
    content: "";
    flex: none;
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    background: currentColor;
}
.pied-niveau.niveau-debutant      { color: var(--debutant-clair); }
.pied-niveau.niveau-novice        { color: var(--novice-clair); }
.pied-niveau.niveau-intermediaire { color: var(--intermediaire-clair); }
.pied-niveau.niveau-pot-commun    { color: var(--pot-commun-clair); }
.pied-creneaux {
    display: block;
    padding-left: 1.05rem;   /* aligné sur le texte, pas sur la pastille */
    color: #b3ac9d;
}

/* --- Nous trouver --------------------------------------------------------- */
.pied-contact li {
    display: flex;
    align-items: flex-start;
    gap: .65rem;
}
.pied-contact .icone {
    flex: none;
    margin-top: .85rem;
    color: var(--or);
}
/* Le téléphone et le courriel se composent au doigt : 44 px de haut au moins,
   d'où le rembourrage porté par le lien lui-même et non par la ligne. */
.pied-contact a,
.pied-contact span {
    display: inline-block;
    padding: .65rem 0;
    word-break: break-word;
}

/* --- Plan du site ---------------------------------------------------------
   Une seule rangée de liens, reprise du menu : le pied ne réinvente pas une
   navigation, il la rappelle. */
.pied-plan {
    margin-top: 2.75rem;
    padding-top: 1.5rem;
    border-top: 1px solid rgb(232 200 106 / 18%);
}
.pied-plan ul {
    display: flex;
    flex-wrap: wrap;
    gap: .25rem 1.75rem;
}
.pied-plan a {
    display: inline-block;
    padding: .65rem 0;
    color: #d9d3c6;
    font-weight: 600;
}
.pied-plan a:hover { color: var(--surface); }
/* La page où l'on se trouve garde son repère jusqu'en bas. */
.pied-plan a[aria-current="page"] {
    color: var(--or-clair);
    text-decoration: none;
}

.pied-bas {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: .35rem 1.5rem;
    margin-top: 1.25rem;
    font-size: .9375rem;
    color: #b3ac9d;
}

/* --------------------------------------------------------------------------
   Textes mis en forme en administration

   Le club a le gras, l'italique, les listes et une couleur prise dans la
   charte (voir COULEURS_TEXTE, inc/texte_riche.php). Ce que rend
   `texte_en_html()` est toujours posé dans un `.texte` : c'est ici, et nulle
   part ailleurs, que ces balises reçoivent leur mise en page.

   La même classe habille l'éditeur de l'administration : ce qu'on y voit en
   tapant est ce que la page affichera, jusqu'à la couleur des puces.
   -------------------------------------------------------------------------- */

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

/* Le bloc prend la place d'un paragraphe et doit donc laisser le même blanc
   derrière lui : ses enfants sont à ras bord — c'est la règle juste au-dessus,
   sans quoi tout `.texte` finirait par un blanc qu'il ne doit pas au dernier
   d'une boîte — et c'est le bloc lui-même qui porte la respiration lorsqu'il a
   quelque chose après lui. Sans cette règle, le texte d'accueil touchait les
   deux cartes qui le suivent. */
.texte:not(:last-child) { margin-bottom: 1em; }

/* Deux endroits gardaient déjà leur propre mesure, avant que le paragraphe ne
   devienne un bloc : ils la gardent. Le message d'actualité est de surcroît
   coupé en deux boîtes — l'extrait et le texte complet, dont l'une est
   masquée : la mise à ras bord vaut pour les deux, sinon « Lire la suite »
   s'éloigne du texte qu'il déplie. */
.texte.tarifs-intro    { margin-bottom: 1.25rem; }
.texte.actualite-texte { margin-bottom: 0; }
.texte-reduit > :last-child, .texte-complet > :last-child { margin-bottom: 0; }

/* Le paragraphe d'un texte saisi garde la typographie de l'endroit où il est
   posé — `.titre-page p`, `.accueil-entree p`, le pied de page — mais c'est
   ici qu'il prend sa respiration : plusieurs de ces règles posent `margin: 0`,
   écrites du temps où un bloc n'avait qu'un paragraphe. */
.texte p { margin: 0 0 .9em; }

.texte ul, .texte ol {
    margin: 0 0 .9em;
    padding-left: 1.4em;
}
.texte ul { list-style: disc; }
.texte ol { list-style: decimal; }
.texte li { margin: .3em 0; }

/* La puce prend l'or du site : c'est la seule marque de couleur d'un texte
   courant, autant que ce soit celle de la charte. */
.texte li::marker { color: var(--or); }

/* Le souligné passe sous les jambages, comme celui des liens : c'est le même
   trait, il n'y a pas deux façons de souligner sur ce site. Attention en s'en
   servant — un texte souligné annonce un lien au lecteur. */
.texte u { text-underline-offset: .18em; text-decoration-thickness: 1px; }

/* Le texte d'un panneau prend toute sa largeur — demandé par le club le
   21 août 2026, qui voyait un panneau à moitié vide : la liste des documents et
   le bouton allaient au bord, le texte s'arrêtait au tiers.

   Ce que ça coûte, et comment c'est payé : la ligne passe de 68 à ~120
   caractères, bien au-delà de la mesure confortable. La compensation est celle
   que le chapô des pages emploie déjà (voir `.titre-page p`) — ce qui rend une
   ligne longue pénible n'est pas sa longueur mais le retour à la ligne
   suivante, où l'œil doit retrouver le bon début : on lui donne de l'air. La
   justification et la césure, posées plus bas, tiennent le bord droit propre.

   `--lecture` continue de valoir partout ailleurs, `.panneau > p` compris. */
.panneau > .texte { line-height: 1.75; }

/* Texte justifié, demandé par le club le 21 août 2026. Deux garde-fous, sans
   lesquels la justification dessert la lecture qu'elle est censée servir :

   - **la césure** (`hyphens: auto` ; la page est en `lang="fr"`, sans quoi le
     navigateur ne sait pas où couper). Sans elle, un mot long repoussé à la
     ligne suivante laisse derrière lui une ligne trouée de blancs — les
     « rivières » verticales qui font sauter l'œil d'une ligne à l'autre. C'est
     le défaut classique du texte justifié sur écran, et la première raison de
     ne pas le faire sans précaution ;
   - **une largeur minimale**. Sous 700 px, une ligne ne porte plus assez de
     mots pour que les blancs se répartissent sans se voir : chaque ligne
     devient un compromis visible. En dessous, le texte reste au fer à gauche —
     c'est la lecture au téléphone que le site protège en premier.

   Les colonnes étroites en sont exclues à toute taille d'écran, pour la même
   raison de mots par ligne : le pied de page (42 caractères) et les fiches de
   l'équipe (une colonne de carte, portrait déduit). Le message d'une actualité,
   lui, dispose de toute la largeur de sa carte moins la vignette : il se
   justifie comme le reste. */
@media (min-width: 700px) {
    .texte {
        text-align: justify;
        -webkit-hyphens: auto;
        hyphens: auto;
    }

    .pied-texte, .membre-description {
        text-align: left;
        -webkit-hyphens: manual;
        hyphens: manual;
    }
}

/* Les couleurs de texte. La palette est fermée côté PHP : ces six classes sont
   les seules qui traversent le nettoyage. Elles reprennent l'accent du site et
   les couleurs de niveau, pour qu'une couleur ne dise pas ici autre chose que
   dans le répertoire ou le planning. */
.encre-or     { color: var(--or-texte); }
.encre-vert   { color: var(--debutant); }
.encre-bleu   { color: var(--novice); }
.encre-orange { color: var(--intermediaire); }
.encre-violet { color: var(--pot-commun); }
.encre-rouge  { color: var(--alerte); }

/* Sur l'encre du pied de page, ces teintes tombent sous le contraste lisible :
   il prend les déclinaisons claires, comme le font déjà ses pastilles de
   niveau. Le rouge n'en avait pas encore. */
.pied .encre-or     { color: var(--or-clair); }
.pied .encre-vert   { color: var(--debutant-clair); }
.pied .encre-bleu   { color: var(--novice-clair); }
.pied .encre-orange { color: var(--intermediaire-clair); }
.pied .encre-violet { color: var(--pot-commun-clair); }
.pied .encre-rouge  { color: #ef9c85; }

/* --------------------------------------------------------------------------
   Impression
   -------------------------------------------------------------------------- */

@media print {
    .bandeau, .banniere, .entete, .pied, .filtres, .recherche-rapide,
    .rangee-actions, .danse-actions, .danse-video { display: none; }

    body { background: #fff; font-size: 11pt; color: #000; }
    .danse, .sortie, .carte, .panneau {
        break-inside: avoid;
        border: 0;
        border-bottom: 1px solid #ccc;
        border-radius: 0;
        padding-inline: 0;
    }
}

[hidden] {
    display: none !important;
}
