/* ==========================================================================
   Composants — site public EDEC
   Référence stricte : docs/maquettes/edec-maquette-site.html
   ========================================================================== */

/* ==========================================================================
   1. Barre rythmique — élément signature
   Barres verticales de hauteurs inégales : le pas de danse, la frappe du
   tambour. Trois usages, jamais un autre (CLAUDE.md §4).
   ========================================================================== */

.rythme {
  --rythme-hauteur: 26px;
  --rythme-largeur: 4px;
  --rythme-ecart: 3px;
  --rythme-couleur: var(--laterite);

  display: flex;
  align-items: flex-end;
  gap: var(--rythme-ecart);
  height: var(--rythme-hauteur);
  flex: none;
}

.rythme i {
  display: block;
  width: var(--rythme-largeur);
  background: var(--rythme-couleur);
  border-radius: 1px;
  transform-origin: bottom;
}

/* Hauteurs inégales — sept barres, jamais régulières. */
.rythme i:nth-child(1) { height: 40%; }
.rythme i:nth-child(2) { height: 100%; }
.rythme i:nth-child(3) { height: 55%; }
.rythme i:nth-child(4) { height: 80%; }
.rythme i:nth-child(5) { height: 30%; }
.rythme i:nth-child(6) { height: 70%; }
.rythme i:nth-child(7) { height: 45%; }

@keyframes battement {
  0%,
  100% { transform: scaleY(0.35); }
  50%  { transform: scaleY(1); }
}

/* ---------- Variante 1 : indicateur d'écoute ---------- */

.rythme--lecture i {
  animation: battement var(--duree-rythme) ease-in-out infinite;
  animation-play-state: paused;
}

.rythme--lecture.est-actif i {
  animation-play-state: running;
}

.rythme--lecture i:nth-child(1) { animation-delay: 0s; }
.rythme--lecture i:nth-child(2) { animation-delay: 0.12s; }
.rythme--lecture i:nth-child(3) { animation-delay: 0.05s; }
.rythme--lecture i:nth-child(4) { animation-delay: 0.22s; }
.rythme--lecture i:nth-child(5) { animation-delay: 0.3s; }
.rythme--lecture i:nth-child(6) { animation-delay: 0.16s; }
.rythme--lecture i:nth-child(7) { animation-delay: 0.08s; }

/* Vumètre vif : posé par le JavaScript pendant que le flux joue réellement.
   Le battement passe de 0,9 s à 0,42 s et l'amplitude s'élargit, pour que
   l'animation se lise comme un signal en cours et non comme un ornement. */
.rythme--lecture.rythme--vif i {
  animation-duration: 0.42s;
  animation-name: battement-vif;
}

@keyframes battement-vif {
  0%,
  100% { transform: scaleY(0.18); }
  50%  { transform: scaleY(1); }
}

/* ---------- Variante 2 : séparateur de section ---------- */

.rythme--separateur {
  --rythme-hauteur: 34px;
  --rythme-largeur: 5px;
  --rythme-ecart: 5px;
  --rythme-couleur: var(--encre);

  opacity: 0.5;
  margin-bottom: var(--e-2);
}

.section--sombre .rythme--separateur,
.pied .rythme--separateur {
  --rythme-couleur: var(--kaolin);
}

/* ---------- Variante 3 : progression podcast ----------
   Deux couches superposées : les barres au repos, puis les mêmes barres en
   latérite, rognées à la valeur de --progression. */

.rythme--progression {
  position: relative;
  --progression: 0%;
  --rythme-couleur: var(--kaolin-2);
  width: 100%;
}

.rythme--progression .rythme__couche {
  display: flex;
  align-items: flex-end;
  gap: var(--rythme-ecart);
  height: 100%;
  width: 100%;
}

.rythme--progression .rythme__couche i {
  flex: 1;
  min-width: 2px;
}

/* Le motif de hauteurs de la signature, répété tous les sept barreaux.
   Il prime sur les règles nth-child(1..7) génériques, d'où la répétition
   explicite ci-dessous. */
.rythme--progression i:nth-child(7n + 1) { height: 40%; }
.rythme--progression i:nth-child(7n + 2) { height: 100%; }
.rythme--progression i:nth-child(7n + 3) { height: 55%; }
.rythme--progression i:nth-child(7n + 4) { height: 80%; }
.rythme--progression i:nth-child(7n + 5) { height: 30%; }
.rythme--progression i:nth-child(7n + 6) { height: 70%; }
.rythme--progression i:nth-child(7n + 7) { height: 45%; }

.rythme--progression .rythme__couche--jouee {
  position: absolute;
  inset: 0;
  --rythme-couleur: var(--laterite);
  clip-path: inset(0 calc(100% - var(--progression)) 0 0);
  transition: clip-path var(--duree-courte) linear;
}

.rythme--progression .rythme__couche--jouee i {
  background: var(--laterite);
}

/* ---------- Moins d'animations ----------
   Les barres se figent à leur hauteur de repos : la forme signature reste
   lisible, le mouvement disparaît. */
@media (prefers-reduced-motion: reduce) {
  .rythme--lecture i,
  .rythme--lecture.est-actif i {
    animation: none !important;
    transform: none;
  }
}

/* ==========================================================================
   2. Boutons — trois variantes, pas une de plus
   ========================================================================== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e-3);
  padding: 14px 26px;
  border: 1.5px solid transparent;
  border-radius: var(--r-pilule);
  font-family: var(--police-texte);
  font-size: 0.92rem;
  font-weight: var(--graisse-forte);
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition), border-color var(--transition),
    color var(--transition);
}

/* Action principale : écouter, envoyer, publier. */
.btn--primaire {
  background: var(--laterite);
  border-color: var(--laterite);
  color: var(--texte-sur-laterite);
}

.btn--primaire:hover {
  background: var(--laterite-d);
  border-color: var(--laterite-d);
}

/* Action secondaire sur fond clair. */
.btn--secondaire {
  background: transparent;
  border-color: var(--bordure);
  color: var(--texte);
}

.btn--secondaire:hover {
  border-color: var(--laterite);
  color: var(--laterite);
}

/* Action secondaire sur fond sombre. */
.btn--fantome {
  background: transparent;
  border-color: var(--bordure-sombre);
  color: var(--texte-inverse);
}

.btn--fantome:hover {
  border-color: var(--or);
  color: var(--or);
}

.btn--petit {
  padding: 9px 20px;
  font-size: var(--t-s);
}

.btn[aria-disabled='true'],
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* ==========================================================================
   3. Carte
   ========================================================================== */

.carte {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--fond-carte);
  border: 1px solid var(--bordure);
  border-radius: var(--r-l);
  overflow: hidden;
  transition: transform var(--duree-moyenne) ease,
    border-color var(--duree-moyenne) ease, box-shadow var(--duree-moyenne) ease;
}

.carte:hover,
.carte:focus-within {
  transform: translateY(-4px);
  border-color: var(--laterite);
  box-shadow: var(--ombre-carte);
}

.carte__visuel {
  position: relative;
  aspect-ratio: 16 / 10;
  background: linear-gradient(135deg, var(--kaolin-2), var(--sable));
  display: grid;
  place-items: center;
}

.carte__visuel--sombre {
  background: linear-gradient(135deg, var(--encre-3), var(--encre));
}

.carte__visuel img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.carte__corps {
  display: flex;
  flex-direction: column;
  flex: 1;
  padding: var(--e-6) 22px;
}

.carte__date {
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: 0.08em;
  color: var(--gris);
  margin-bottom: var(--e-3);
}

.carte__titre {
  font-size: var(--t-xl);
  margin-bottom: var(--e-3);
}

.carte__resume {
  flex: 1;
  font-size: var(--t-m);
  color: var(--texte-doux);
}

.carte__suite {
  margin-top: var(--e-4);
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: var(--chasse-donnee);
  text-transform: uppercase;
  font-weight: var(--graisse-forte);
  color: var(--laterite);
}

/* Rend toute la carte cliquable sans imbriquer de lien. */
.carte__lien {
  color: inherit;
  text-decoration: none;
}

.carte__lien::after {
  content: '';
  position: absolute;
  inset: 0;
}

/* Le survol se lit déjà sur la carte entière ; le titre se contente de
   prendre l'accent. */
.carte:hover .carte__lien,
.carte:focus-within .carte__lien {
  color: var(--laterite);
}

/* ==========================================================================
   4. Pastille — catégorie, type de média, état
   ========================================================================== */

.pastille {
  display: inline-flex;
  align-items: center;
  gap: var(--e-1);
  padding: 5px 11px;
  border: 1px solid transparent;
  border-radius: var(--r-pilule);
  background: var(--foret);
  color: var(--texte-sur-foret);
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: var(--chasse-donnee);
  text-transform: uppercase;
  white-space: nowrap;
}

.pastille--or {
  background: var(--or);
  color: var(--texte-sur-or);
}

.pastille--laterite {
  background: var(--laterite);
  color: var(--texte-sur-laterite);
}

.pastille--contour {
  background: transparent;
  border-color: var(--bordure);
  color: var(--texte-doux);
}

/* Posée sur un visuel de carte. */
.pastille--posee {
  position: absolute;
  top: var(--e-3);
  left: var(--e-3);
  z-index: 1;
}

/* Point « en direct » qui bat. */
.direct {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-family: var(--police-donnee);
  font-size: 0.68rem;
  font-weight: var(--graisse-forte);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--laterite);
}

.direct::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: currentcolor;
  animation: pouls var(--duree-pouls) infinite;
}

@keyframes pouls {
  0%,
  100% { opacity: 1; }
  50%  { opacity: 0.25; }
}

@media (prefers-reduced-motion: reduce) {
  .direct::before {
    animation: none !important;
  }
}

/* ==========================================================================
   5. Champ de formulaire
   ========================================================================== */

.champ {
  margin-bottom: 18px;
}

.champ__label {
  display: block;
  margin-bottom: 7px;
  font-family: var(--police-donnee);
  font-size: 0.68rem;
  letter-spacing: var(--chasse-donnee);
  text-transform: uppercase;
  color: var(--texte-doux);
}

.champ__saisie {
  width: 100%;
  padding: 13px 16px;
  background: var(--fond-carte);
  border: 1.5px solid var(--bordure);
  border-radius: var(--r-m);
  font-family: var(--police-texte);
  font-size: 0.95rem;
  color: var(--texte);
  transition: border-color var(--transition);
}

.champ__saisie::placeholder {
  color: var(--gris);
}

.champ__saisie:focus-visible {
  outline: 2px solid var(--laterite);
  outline-offset: 1px;
  border-color: transparent;
}

textarea.champ__saisie {
  min-height: 130px;
  resize: vertical;
}

.champ__aide {
  margin-top: 6px;
  font-size: var(--t-s);
  color: var(--texte-doux);
}

.champ__erreur {
  margin-top: 6px;
  font-size: var(--t-s);
  font-weight: var(--graisse-moyenne);
  color: var(--laterite-d);
}

.champ--en-erreur .champ__saisie {
  border-color: var(--laterite-d);
}

/* ==========================================================================
   6. En-tête
   ========================================================================== */

.entete {
  position: sticky;
  top: 0;
  z-index: var(--z-entete);
  background: rgb(20 16 14 / 96%);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--bordure-sombre);
  color: var(--texte-inverse);
}

.entete__barre {
  display: flex;
  align-items: center;
  gap: var(--e-7);
  height: var(--hauteur-entete);
}

.entete__marque {
  display: flex;
  align-items: center;
  flex: none;
  gap: var(--e-3);
  text-decoration: none;
  color: var(--blanc);
}

.entete__marque svg {
  width: 40px;
  height: 40px;
  flex: none;
}

.entete__nom {
  display: block;
  font-family: var(--police-titre);
  font-size: 1.15rem;
  font-weight: var(--graisse-noire);
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.entete__baseline {
  display: block;
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--or);
}

.entete__menu {
  display: flex;
  gap: 26px;
  margin-left: auto;
}

.entete__lien {
  display: inline-block;
  padding: 6px 0;
  border-bottom: 2px solid transparent;
  font-size: var(--t-m);
  font-weight: var(--graisse-moyenne);
  color: var(--texte-inverse-doux);
  text-decoration: none;
  transition: color var(--transition), border-color var(--transition);
}

.entete__lien:hover {
  color: var(--blanc);
}

.entete__lien.est-actif {
  color: var(--blanc);
  border-bottom-color: var(--laterite);
}

.entete__ecoute {
  display: inline-flex;
  align-items: center;
  flex: none;
  gap: var(--e-3);
  padding: 8px 16px;
  background: var(--laterite);
  color: var(--texte-sur-laterite);
  border-radius: var(--r-pilule);
  font-family: var(--police-donnee);
  font-size: 0.68rem;
  font-weight: var(--graisse-forte);
  letter-spacing: var(--chasse-donnee);
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--transition);
}

.entete__ecoute:hover {
  background: var(--laterite-d);
}

.entete__ecoute .rythme {
  --rythme-hauteur: 16px;
  --rythme-largeur: 3px;
  --rythme-couleur: #fff;
}

.entete__burger {
  display: none;
  margin-left: auto;
  padding: var(--e-2);
  color: var(--blanc);
  line-height: 0;
}

.entete__burger svg {
  width: 24px;
  height: 24px;
}

/* ==========================================================================
   7. Pied de page — quatre colonnes
   ========================================================================== */

.pied {
  background: var(--fond-sombre);
  border-top: 1px solid var(--bordure-sombre);
  color: var(--texte-inverse-gris);
  padding: 60px 0 28px;
}

.pied__grille {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr 1fr;
  gap: var(--e-8);
  margin-bottom: 44px;
}

.pied__titre {
  margin-bottom: var(--e-4);
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  font-weight: var(--graisse-normale);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--or);
}

.pied__texte {
  font-size: var(--t-m);
  max-width: 34ch;
}

.pied li {
  margin-bottom: 9px;
  font-size: var(--t-m);
}

.pied a {
  text-decoration: none;
  transition: color var(--transition);
}

.pied a:hover {
  color: var(--blanc);
}

/* Un lien de pied de page qui déclenche une action plutôt qu'une navigation :
   c'est un bouton, habillé comme les liens voisins. */
.pied__lien-bouton {
  padding: 0;
  font: inherit;
  color: inherit;
  text-align: left;
  transition: color var(--transition);
}

.pied__lien-bouton:hover {
  color: var(--blanc);
}

.pied__reseaux {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
  margin-top: var(--e-4);
  padding-top: var(--e-4);
  border-top: 1px solid var(--bordure-sombre);
}

.direct-barre__format {
  color: var(--gris);
  font-size: var(--t-xs);
  white-space: nowrap;
}

.entete__logo {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.pied__bas {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--e-2);
  text-align: center;
  padding-top: var(--e-6);
  border-top: 1px solid var(--bordure-sombre);
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: 0.06em;
  color: var(--texte-fantome);
}

/* ==========================================================================
   8. Grilles et en-têtes de section
   ========================================================================== */

.grille-3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
}

.section__entete {
  max-width: 60ch;
  margin-bottom: var(--e-8);
}

.section__surtitre {
  display: block;
  margin-bottom: var(--e-3);
  color: var(--laterite);
}

.section--sombre .section__surtitre {
  color: var(--or);
}

/* Les pages de liste ouvrent sur un h1, l'accueil sur un h2 : les deux. */
.section__entete :is(h1, h2, h3) {
  margin-bottom: var(--e-3);
}

.section__entete p {
  color: var(--texte-doux);
}

.section--sombre .section__entete p {
  color: var(--texte-inverse-gris);
}

/* ==========================================================================
   9. État vide
   Un écran vide dit ce qui manque, sans faire croire à une panne.
   ========================================================================== */

.vide {
  padding: var(--e-7) var(--e-6);
  border: 1px dashed var(--bordure);
  border-radius: var(--r-l);
  background: var(--fond-carte);
  color: var(--texte-doux);
  text-align: center;
}

.vide--sombre {
  background: var(--fond-sombre-2);
  border-color: var(--bordure-sombre);
  color: var(--texte-inverse-gris);
}

/* ==========================================================================
   10. Accueil — bandeau d'introduction
   Emplacement du lecteur de direct et de la grille, branchés au lot 5.
   ========================================================================== */

.accueil-intro {
  position: relative;
  overflow: hidden;
}

/* Le filet tricolore qui ferme le bandeau, repris de la maquette. */
.accueil-intro::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 1px;
  background: linear-gradient(90deg, var(--laterite), var(--or), var(--foret));
}

/* Image de couverture choisie dans les paramètres. Elle passe derrière un
   voile sombre : le texte doit rester lisible quelle que soit la photo. */
.accueil-intro--illustree {
  background-image:
    linear-gradient(to right, rgb(20 16 14 / 94%) 0%, rgb(20 16 14 / 78%) 55%, rgb(20 16 14 / 55%) 100%),
    var(--couverture);
  background-size: cover;
  background-position: center;
}

.accueil-oeil {
  display: inline-flex;
  align-items: center;
  gap: var(--e-3);
  margin-bottom: 22px;
  color: var(--or);
}

.accueil-oeil::before {
  content: '';
  width: 28px;
  height: 1px;
  background: currentcolor;
}

.accueil-intro h1 {
  margin-bottom: 22px;
}

.accueil-intro h1 em {
  font-style: normal;
  color: var(--laterite);
}

.chapo--sombre {
  color: var(--texte-inverse-doux);
}

.accueil-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-4);
  margin-top: var(--e-8);
}

/* ==========================================================================
   11. Journal — filtres, pagination, page d'article
   ========================================================================== */

.filtres {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
  margin-bottom: var(--e-8);
}

.accueil-suite {
  margin-top: var(--e-8);
}

/* ---------- Pagination ---------- */

.pagination {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--e-2);
  margin-top: var(--e-9);
}

.pagination__lien {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  padding: 10px 14px;
  border: 1px solid var(--bordure);
  border-radius: var(--r-pilule);
  background: var(--fond-carte);
  font-family: var(--police-donnee);
  font-size: var(--t-s);
  text-decoration: none;
  transition: border-color var(--transition), background var(--transition),
    color var(--transition);
}

.pagination__lien:hover {
  border-color: var(--laterite);
  color: var(--laterite);
}

.pagination__lien.est-actif {
  background: var(--laterite);
  border-color: var(--laterite);
  color: var(--texte-sur-laterite);
}

/* ---------- En-tête d'article ---------- */

.article-entete .pastille {
  margin-bottom: var(--e-5);
}

.article-entete h1 {
  font-size: clamp(2rem, 4.4vw, 3.4rem);
  margin-bottom: var(--e-5);
}

.article-meta {
  margin-top: var(--e-5);
  color: var(--or);
}

.article-couverture {
  margin-top: calc(var(--e-9) * -1);
  margin-bottom: var(--e-8);
}

/* Une photo de 1600 px de large s'affichait sur toute la hauteur qu'elle
   voulait, repoussant le texte hors de l'écran. On borne la hauteur et on
   recadre proprement. */
.article-couverture img {
  width: 100%;
  height: auto;
  max-height: 460px;
  object-fit: cover;
  border-radius: var(--r-l);
  border: 1px solid var(--bordure);
}

.section--liees {
  background: var(--blanc);
  border-top: 1px solid var(--bordure);
}

/* ---------- Corps d'article ----------
   Styles appliqués au HTML de l'éditeur. Comme l'assainissement retire tout
   attribut de classe, la mise en forme repose entièrement sur les balises. */

.prose {
  max-width: 68ch;
  font-size: 1.05rem;
}

.prose > * + * {
  margin-top: var(--e-5);
}

.prose h2 {
  font-size: clamp(1.5rem, 2.6vw, 2rem);
  margin-top: var(--e-9);
}

.prose h3 {
  font-size: 1.35rem;
  margin-top: var(--e-8);
}

.prose h4 {
  font-size: 1.15rem;
  margin-top: var(--e-7);
}

.prose a {
  color: var(--laterite);
  text-decoration: underline;
}

.prose a:hover {
  color: var(--laterite-d);
}

.prose ul,
.prose ol {
  padding-left: var(--e-6);
}

.prose ul {
  list-style: disc;
}

.prose ol {
  list-style: decimal;
}

.prose li + li {
  margin-top: var(--e-2);
}

.prose blockquote {
  padding-left: var(--e-6);
  border-left: 3px solid var(--laterite);
  font-size: 1.15rem;
  color: var(--texte-doux);
}

.prose img {
  width: 100%;
  height: auto;
  border-radius: var(--r-m);
}

.prose figcaption {
  margin-top: var(--e-2);
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  color: var(--gris);
}

.prose table {
  width: 100%;
  font-size: var(--t-m);
}

.prose th,
.prose td {
  padding: var(--e-3);
  border-bottom: 1px solid var(--bordure);
  text-align: left;
}

.prose hr {
  border: 0;
  border-top: 1px solid var(--bordure);
}

/* ---------- Bandeau de prévisualisation ---------- */

.bandeau-previsualisation {
  padding: var(--e-3) 0;
  background: var(--or);
  color: var(--texte-sur-or);
  font-size: var(--t-m);
  text-align: center;
}

/* ==========================================================================
   12. Grille des programmes — « Quatre peuples »
   ========================================================================== */

.peuples {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 2px;
  background: var(--encre);
}

.peuple {
  padding: 30px var(--e-6);
  background: var(--kaolin);
  transition: background var(--duree-moyenne) ease, color var(--duree-moyenne) ease;
}

.peuple:hover {
  background: var(--foret);
  color: var(--texte-sur-foret);
}

.peuple__quand {
  display: block;
  margin-bottom: var(--e-4);
  color: var(--laterite);
}

.peuple:hover .peuple__quand {
  color: var(--or);
}

.peuple__titre {
  margin-bottom: var(--e-2);
  font-size: 1.45rem;
  font-weight: var(--graisse-demi);
}

.peuple p {
  font-size: var(--t-m);
  color: var(--texte-doux);
}

.peuple:hover p {
  color: var(--texte-inverse-doux);
}

/* ==========================================================================
   13. Liste d'épisodes
   ========================================================================== */

.episodes {
  border-top: 1px solid var(--bordure);
}

.episode {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--e-5);
  padding: var(--e-5) 0;
  border-bottom: 1px solid var(--bordure);
  transition: padding-left var(--transition);
}

.episode:hover {
  padding-left: var(--e-3);
}

.episode__jouer {
  display: grid;
  place-items: center;
  flex: none;
  width: 46px;
  height: 46px;
  border: 1.5px solid var(--encre);
  border-radius: 50%;
  font-size: var(--t-m);
  transition: background var(--transition), border-color var(--transition), color var(--transition);
}

.episode:hover .episode__jouer {
  background: var(--laterite);
  border-color: var(--laterite);
  color: var(--texte-sur-laterite);
}

/* Vignette d'épisode. Pour une vidéo, elle est extraite automatiquement du
   fichier ; pour un lien externe, rapatriée sur le serveur. */
.episode__vignette {
  position: relative;
  display: block;
  flex: none;
  width: 112px;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-m);
  overflow: hidden;
  background: var(--kaolin-2);
}

.episode__vignette img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.episode__jouer--sur-image {
  position: absolute;
  inset: 50% auto auto 50%;
  translate: -50% -50%;
  width: 34px;
  height: 34px;
  border: 0;
  background: rgb(20 16 14 / 62%);
  color: #fff;
  font-size: 0.7rem;
}

.episode:hover .episode__jouer--sur-image {
  background: var(--laterite);
}

.episode__corps {
  flex: 1;
  min-width: 0;
}

.episode__serie {
  display: block;
  margin-bottom: var(--e-1);
  color: var(--laterite);
}

.episode__titre {
  font-size: 1.1rem;
  font-weight: var(--graisse-demi);
  letter-spacing: -0.02em;
}

.episode__lien {
  color: inherit;
  text-decoration: none;
}

.episode__lien::after {
  content: '';
  position: absolute;
  inset: 0;
}

.episode__resume {
  margin-top: var(--e-1);
  font-size: var(--t-m);
  color: var(--texte-doux);
}

.episode__duree {
  flex: none;
  font-size: 0.8rem;
  color: var(--gris);
}

.pastille--foret {
  background: var(--foret);
  color: var(--texte-sur-foret);
}

/* ==========================================================================
   14. Lecteur audio
   ========================================================================== */

.lecteur {
  padding: var(--e-6);
  background: var(--fond-sombre-2);
  border: 1px solid var(--bordure-sombre);
  border-radius: var(--r-xl);
  color: var(--texte-inverse);
}

.lecteur__barre {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  margin-bottom: var(--e-5);
}

.lecteur__bouton {
  display: grid;
  place-items: center;
  min-width: 46px;
  height: 46px;
  padding: 0 var(--e-3);
  border: 1.5px solid var(--bordure-sombre);
  border-radius: var(--r-pilule);
  color: var(--texte-inverse);
  font-family: var(--police-donnee);
  font-size: 0.8rem;
  transition: border-color var(--transition), background var(--transition);
}

.lecteur__bouton:hover {
  border-color: var(--or);
  color: var(--or);
}

.lecteur__bouton--principal {
  width: 52px;
  height: 52px;
  background: var(--laterite);
  border-color: var(--laterite);
  color: var(--texte-sur-laterite);
  font-size: 1rem;
}

.lecteur__bouton--principal:hover {
  background: var(--laterite-d);
  border-color: var(--laterite-d);
  color: var(--texte-sur-laterite);
}

.lecteur__rythme {
  margin-left: auto;
}

/* La progression EST la barre rythmique : cliquable et pilotable au clavier. */
.lecteur__progression {
  padding: var(--e-3) 0;
  cursor: pointer;
}

.lecteur__progression .rythme {
  --rythme-hauteur: 34px;
  --rythme-ecart: 3px;
  width: 100%;
}

.lecteur__pied {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--e-4);
  margin-top: var(--e-3);
  font-size: var(--t-s);
  color: var(--texte-inverse-gris);
}

.lecteur__volume {
  display: flex;
  align-items: center;
  gap: var(--e-2);
}

.lecteur__volume input {
  width: 110px;
  accent-color: var(--laterite);
}

.lecteur__vitesse {
  padding: 4px 12px;
  border: 1px solid var(--bordure-sombre);
  border-radius: var(--r-pilule);
  color: var(--texte-inverse);
  font-size: var(--t-xs);
}

.lecteur__telecharger {
  margin-left: auto;
  color: var(--or);
}

/* Le lecteur vidéo occupait toute la largeur de la page sans limite de
   hauteur : sur un grand écran, une captation en 16/9 dépassait la fenêtre.
   Il est désormais borné en hauteur et centré. */
.lecteur-video {
  display: block;
  /* Pas de ratio imposé : les captations au téléphone sont en portrait, et un
     cadre 16/9 les cernerait de bandes noires. On borne seulement la hauteur,
     la vidéo garde ses proportions. */
  max-width: min(100%, 900px);
  max-height: 70vh;
  height: auto;
  margin-inline: auto;
  border-radius: var(--r-l);
  background: var(--encre);
}

/* Même contrainte pour la vidéo externe. */
.video-differee {
  max-width: 900px;
  margin-inline: auto;
}

.episode-entete__serie {
  display: block;
  margin-bottom: var(--e-4);
  color: var(--or);
}

.episode-entete__meta {
  margin-top: var(--e-5);
  color: var(--or);
}

.episode-description {
  margin-top: var(--e-8);
}

/* ---------- Vidéo externe, chargée au clic ---------- */

.video-differee {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--r-l);
  overflow: hidden;
  background: var(--encre);
}

.video-differee iframe {
  width: 100%;
  height: 100%;
  border: 0;
}

.video-differee__lancer {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
}

.video-differee__lancer img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.video-differee__jouer {
  position: relative;
  display: grid;
  place-items: center;
  width: 74px;
  height: 74px;
  border-radius: 50%;
  background: var(--laterite);
  color: var(--texte-sur-laterite);
  font-size: 1.5rem;
  transition: transform var(--transition), background var(--transition);
}

.video-differee__lancer:hover .video-differee__jouer {
  background: var(--laterite-d);
  transform: scale(1.06);
}

.video-differee__note {
  margin-top: var(--e-3);
  font-size: var(--t-s);
  color: var(--texte-doux);
}

/* ==========================================================================
   15. Agenda
   ========================================================================== */

.ev-liste {
  border-top: 1px solid var(--bordure-sombre);
}

.ev-liste--clair {
  border-top-color: var(--bordure);
}

.ev {
  position: relative;
  display: grid;
  grid-template-columns: 110px 1fr auto;
  align-items: center;
  gap: 28px;
  padding: 26px 0;
  border-bottom: 1px solid var(--bordure-sombre);
}

.ev-liste--clair .ev {
  border-bottom-color: var(--bordure);
}

.ev--passe {
  opacity: 0.62;
}

.ev__date {
  padding-right: var(--e-5);
  border-right: 1px solid var(--bordure-sombre);
  text-align: center;
}

.ev-liste--clair .ev__date {
  border-right-color: var(--bordure);
}

.ev__date b {
  display: block;
  font-family: var(--police-titre);
  font-size: 2.3rem;
  font-weight: var(--graisse-noire);
  line-height: 1;
  color: var(--or);
}

.ev__date span {
  font-family: var(--police-donnee);
  font-size: var(--t-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--gris);
}

.ev__titre {
  margin-bottom: 5px;
  font-size: 1.3rem;
  font-weight: var(--graisse-demi);
}

.ev__lien {
  color: inherit;
  text-decoration: none;
}

.ev__lien::after {
  content: '';
  position: absolute;
  inset: 0;
}

.ev__lieu {
  font-size: 0.88rem;
  color: var(--texte-inverse-gris);
}

.ev-liste--clair .ev__lieu {
  color: var(--texte-doux);
}

.ev__etiquette {
  color: var(--gris);
}

/* Les boutons passent au-dessus du lien qui couvre la ligne. */
.ev .btn {
  position: relative;
  z-index: 1;
}

.ev-entete__quand {
  margin-top: var(--e-5);
  color: var(--or);
}

.ev-affiche {
  margin-top: calc(var(--e-9) * -1);
  margin-bottom: var(--e-8);
}

.ev-affiche img {
  width: 100%;
  height: auto;
  max-height: 460px;
  object-fit: cover;
  border-radius: var(--r-l);
  border: 1px solid var(--bordure);
}

.ev-detail {
  display: grid;
  grid-template-columns: 1.6fr 1fr;
  gap: var(--e-9);
  align-items: start;
}

.ev-infos {
  padding: var(--e-6);
  background: var(--fond-carte);
  border: 1px solid var(--bordure);
  border-radius: var(--r-l);
}

.ev-infos__ligne + .ev-infos__ligne {
  margin-top: var(--e-5);
}

.ev-infos__ligne span {
  display: block;
  margin-bottom: var(--e-1);
  color: var(--gris);
}

.ev-infos .btn {
  margin-top: var(--e-6);
  width: 100%;
}

/* ==========================================================================
   16. Lecteur de direct — barre persistante
   ========================================================================== */

.direct-barre {
  position: fixed;
  inset: auto 0 0;
  z-index: var(--z-menu);
  background: rgb(20 16 14 / 97%);
  backdrop-filter: blur(8px);
  border-top: 1px solid var(--bordure-sombre);
  color: var(--texte-inverse);
}

.direct-barre[hidden] {
  display: none;
}

.direct-barre__contenu {
  display: flex;
  align-items: center;
  gap: var(--e-4);
  padding-block: var(--e-3);
}

.direct-barre__bouton {
  display: grid;
  place-items: center;
  flex: none;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: var(--laterite);
  color: var(--texte-sur-laterite);
  font-size: 0.95rem;
  transition: background var(--transition);
}

.direct-barre__bouton:hover:not(:disabled) {
  background: var(--laterite-d);
}

.direct-barre__bouton:disabled {
  background: var(--encre-3);
  color: var(--gris);
  cursor: not-allowed;
}

.direct-barre__infos {
  min-width: 0;
}

.direct-barre__etat {
  display: block;
  color: var(--laterite);
}

.direct-barre--hors-antenne .direct-barre__etat {
  color: var(--gris);
}

.direct-barre__emission {
  display: block;
  font-size: var(--t-m);
  font-weight: var(--graisse-moyenne);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Ces deux blocs sont vides tant que l'information n'est pas connue.
   Vides, ils ne prennent aucune place : jamais de « 0 auditeur ». */
.direct-barre__titre,
.direct-barre__auditeurs {
  color: var(--texte-inverse-gris);
  font-size: var(--t-xs);
  white-space: nowrap;
}

.direct-barre__titre:empty,
.direct-barre__auditeurs:empty {
  display: none;
}

.direct-barre__rythme {
  margin-left: auto;
}

.direct-barre__volume input {
  width: 90px;
  accent-color: var(--laterite);
}

.direct-barre__fermer {
  flex: none;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  color: var(--texte-inverse-gris);
  font-size: 1.2rem;
  line-height: 1;
}

.direct-barre__fermer:hover {
  color: var(--blanc);
}

/* La barre couvre le bas de page : on rend au pied de page la place qu'elle prend. */
body:has(.direct-barre:not([hidden])) .pied {
  padding-bottom: calc(28px + 72px);
}


/* ==========================================================================
   17. Contact, alertes et pages d'erreur
   ========================================================================== */

.contact {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--e-9);
}

/* Le piège à robots : invisible à l'œil, invisible aux lecteurs d'écran,
   mais bien présent dans le document pour qui remplit tout automatiquement.
   On évite display:none, que certains robots savent détecter. */
.piege {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.info-ligne {
  display: flex;
  gap: var(--e-4);
  padding: 18px 0;
  border-bottom: 1px solid var(--bordure);
}

/* Une adresse e-mail ou une URL ne comporte aucune espace : sans autorisation
   explicite de couper, elle pousse toute la page vers la droite sur un
   téléphone. C'est ce qui faisait déborder la page de contact à 360 px. */
.info-ligne > div {
  min-width: 0;
}

.info-ligne a,
.info-ligne span,
.pied a {
  overflow-wrap: anywhere;
}

.info-ligne__icone {
  display: grid;
  place-items: center;
  flex: none;
  width: 38px;
  height: 38px;
  border-radius: var(--r-m);
  background: var(--foret);
  color: var(--texte-sur-foret);
  font-size: var(--t-m);
}

.info-ligne b {
  display: block;
  margin-bottom: 3px;
  color: var(--gris);
}

/* ---------- Icônes SVG en ligne ---------- */

.icone {
  display: block;
  flex: none;
}

.info-ligne--reseaux {
  border-bottom: 0;
}

.reseaux {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-4);
  margin-top: var(--e-2);
}

.reseaux__lien {
  display: inline-flex;
  align-items: center;
  gap: var(--e-2);
  font-size: var(--t-m);
  text-decoration: none;
  transition: color var(--transition);
}

.reseaux__lien:hover {
  color: var(--laterite);
}

/* Réseaux du pied de page : l'icône seule, le nom réservé aux lecteurs d'écran. */
.pied__reseau {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border: 1px solid var(--bordure-sombre);
  border-radius: 50%;
  color: var(--texte-inverse-gris);
  transition: color var(--transition), border-color var(--transition);
}

.pied__reseau:hover {
  color: var(--or);
  border-color: var(--or);
}

/* ---------- Page « À propos » ---------- */

.apropos--illustre {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: var(--e-9);
  align-items: start;
}

.apropos__portrait img {
  width: 100%;
  height: auto;
  max-height: 520px;
  object-fit: cover;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-l);
  border: 1px solid var(--bordure);
}

.alerte {
  padding: var(--e-4) var(--e-5);
  border-radius: var(--r-m);
  margin-bottom: var(--e-6);
  font-size: var(--t-m);
}

.alerte--succes {
  background: rgb(30 59 50 / 10%);
  border: 1px solid var(--foret);
  color: var(--foret);
}

.alerte--erreur {
  background: rgb(217 84 31 / 10%);
  border: 1px solid var(--laterite-d);
  color: var(--laterite-d);
}

.erreur {
  min-height: 60vh;
  display: grid;
  align-content: center;
}

.erreur__code {
  display: block;
  margin-bottom: var(--e-4);
  color: var(--laterite);
}

.erreur__issues {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e-3);
  margin-top: var(--e-8);
}

.erreur__aide {
  margin-top: var(--e-7);
  color: var(--texte-inverse-gris);
  font-size: var(--t-m);
}

.erreur__aide a {
  color: var(--or);
}

/* ==========================================================================
   18. Adaptation — 960 px, puis 680 px
   ========================================================================== */

/* Six entrées de navigation plus le bouton d'écoute ne tiennent plus sur une
   ligne sous 960 px : le menu se replie dès cette largeur, pas à 680. */
@media (max-width: 960px) {
  .grille-3,
  .peuples {
    grid-template-columns: repeat(2, 1fr);
  }

  .pied__grille {
    grid-template-columns: 1fr 1fr;
  }

  .ev-detail,
  .apropos--illustre {
    grid-template-columns: 1fr;
    gap: var(--e-7);
  }

  .entete__barre {
    gap: var(--e-4);
  }

  /* Le repli en menu déroulant suppose JavaScript. La classe « js » est posée
     sur <html> avant le premier rendu. Sans elle, on retombe plus bas sur une
     navigation dépliée, toujours utilisable. */
  .js .entete__burger {
    display: block;
    margin-left: 0;
    order: 3;
  }

  .js .entete__menu {
    display: none;
    position: absolute;
    top: var(--hauteur-entete);
    left: 0;
    right: 0;
    z-index: var(--z-menu);
    flex-direction: column;
    gap: 0;
    padding: var(--e-3) var(--gouttiere);
    background: var(--fond-sombre-2);
    border-bottom: 1px solid var(--bordure-sombre);
  }

  .js .entete__menu.est-ouvert {
    display: flex;
  }

  .js .entete__lien {
    width: 100%;
    padding: var(--e-3) 0;
    border-bottom: 1px solid var(--bordure-sombre);
  }

  .js .entete__lien.est-actif {
    border-bottom-color: var(--laterite);
  }

  /* Le bouton d'écoute reste à gauche du burger. */
  .js .entete__ecoute {
    margin-left: auto;
    order: 2;
  }

  /* Repli sans JavaScript : la barre s'étale sur deux lignes. */
  html:not(.js) .entete__barre {
    height: auto;
    flex-wrap: wrap;
    gap: var(--e-3);
    padding-block: var(--e-3);
  }

  html:not(.js) .entete__menu {
    width: 100%;
    margin-left: 0;
    flex-wrap: wrap;
    gap: var(--e-4);
  }
}

@media (max-width: 680px) {
  .entete__ecoute {
    display: none;
  }

  .js .entete__burger {
    margin-left: auto;
  }

  .grille-3,
  .peuples {
    grid-template-columns: 1fr;
  }

  /* Le pied de page garde deux colonnes : « Le site » et « La radio » sont
     deux listes courtes qui tiennent côte à côte, et les empiler ferait
     défiler inutilement. La présentation et le contact, plus longs, occupent
     toute la largeur. */
  .pied__grille {
    grid-template-columns: 1fr 1fr;
    gap: var(--e-6) var(--e-5);
  }

  .pied__grille > :first-child,
  .pied__grille > :last-child {
    grid-column: 1 / -1;
  }

  /* L'agenda passe sur deux colonnes : la date, puis le reste. */
  .ev {
    grid-template-columns: 80px 1fr;
    gap: 18px;
  }

  .ev__date b {
    font-size: 1.8rem;
  }

  .episode {
    flex-wrap: wrap;
  }

  .episode__vignette {
    width: 84px;
  }

  .episode__duree {
    margin-left: auto;
  }

  .lecteur__telecharger {
    margin-left: 0;
  }

  /* Sur mobile, la barre du direct garde l'essentiel : jouer, savoir quoi,
     régler le son. Le reste passe à la ligne ou disparaît. */
  .direct-barre__contenu {
    flex-wrap: wrap;
    gap: var(--e-3);
  }

  .direct-barre__volume,
  .direct-barre__rythme {
    display: none;
  }

  .direct-barre__infos {
    flex: 1;
  }
}

/* ==========================================================================
   19. Téléphone — sous 480 px
   --------------------------------------------------------------------------
   La majorité des visiteurs arrive d'un téléphone, souvent sur réseau lent.
   Ce palier resserre les marges pour rendre la place au contenu, met les
   actions sur toute la largeur, et garantit une zone tactile d'au moins 44 px
   sur tout ce qui se touche — en dessous, on vise à côté.
   ========================================================================== */

@media (max-width: 480px) {
  :root {
    --gouttiere: 16px;
    --section-y: clamp(36px, 9vw, 52px);
    --hauteur-entete: 60px;
  }

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

  /* Le voile de la couverture passe de latéral à vertical : sur un écran
     étroit, un dégradé de gauche à droite laisse le bas du titre sur la
     partie claire de la photo. */
  .accueil-intro--illustree {
    background-image:
      linear-gradient(to bottom, rgb(20 16 14 / 88%) 0%, rgb(20 16 14 / 82%) 60%, rgb(20 16 14 / 70%) 100%),
      var(--couverture);
  }

  .accueil-oeil {
    margin-bottom: var(--e-4);
  }

  .accueil-intro h1 {
    margin-bottom: var(--e-4);
  }

  /* Deux boutons côte à côte deviennent deux boutons trop étroits pour leur
     libellé : ils passent l'un sous l'autre, sur toute la largeur. */
  .accueil-actions {
    flex-direction: column;
    align-items: stretch;
    margin-top: var(--e-6);
  }

  .accueil-actions .btn {
    justify-content: center;
    width: 100%;
  }

  /* ---------- Cartes d'article ---------- */

  .carte__corps {
    padding: var(--e-5) var(--e-4);
  }

  .carte__visuel {
    aspect-ratio: 16 / 9;
  }

  /* ---------- Cartes de catégorie ---------- */

  .peuple {
    padding: var(--e-6) var(--e-5);
  }

  .peuple__titre {
    font-size: var(--t-2xl);
  }

  /* ---------- Épisodes ---------- */

  /* La vignette et le titre gardent une ligne, la durée et le bouton passent
     dessous : à 360 px, tout sur un rang réduit le titre à deux mots. */
  .episode {
    align-items: flex-start;
    gap: var(--e-4);
    padding: var(--e-4) 0;
  }

  .episode__vignette {
    width: 72px;
  }

  .episode__jouer {
    width: 44px;
    height: 44px;
  }

  /* ---------- Agenda ---------- */

  .ev {
    grid-template-columns: 64px 1fr;
    gap: var(--e-3);
  }

  .ev__date b {
    font-size: var(--t-2xl);
  }

  /* ---------- Filtres et pagination ---------- */

  /* Les filtres défilent horizontalement plutôt que d'empiler six lignes. */
  .filtres {
    flex-wrap: nowrap;
    overflow-x: auto;
    margin-inline: calc(var(--gouttiere) * -1);
    padding-inline: var(--gouttiere);
    scrollbar-width: none;
    margin-bottom: var(--e-6);
  }

  .filtres::-webkit-scrollbar {
    display: none;
  }

  .filtres > * {
    flex: 0 0 auto;
  }

  .pagination__lien {
    min-width: 44px;
    min-height: 44px;
  }

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

  .pied {
    padding: var(--e-8) 0 var(--e-6);
  }

  .pied__grille {
    margin-bottom: var(--e-7);
  }

  .pied__reseau {
    min-width: 44px;
    min-height: 44px;
  }
}

/* Zone tactile minimale sur tout appareil sans souris, quelle que soit la
   largeur : une tablette au doigt a le même besoin qu'un téléphone. */
@media (hover: none) {
  .btn,
  .pagination__lien,
  .episode__jouer,
  .lecteur__bouton,
  .direct-barre__bouton {
    min-height: 44px;
  }
}
