/*
 * CHLONEO — le système visuel du site de radio.
 *
 * CE QUI EST FIXE ICI, CE QUI VIENT DE L'ANTENNE
 *   Ce fichier porte les constantes du PRODUIT : le fond sombre, les surfaces,
 *   la trame d'espacement, les rayons, les ombres, la typographie. Elles ne
 *   changent pas d'une radio à l'autre — c'est ce qui fait qu'on reconnaît le
 *   même site derrière deux antennes.
 *
 *   Les couleurs lumineuses, elles, arrivent après, dans un `:root` écrit par
 *   `charte_css()` à partir de ce que Phoenix a poussé. D'où l'ordre dans la
 *   page : cette feuille, puis le bloc de l'antenne, qui l'emporte.
 *
 * POURQUOI SI SOMBRE
 *   Un site de radio se consulte le soir, souvent en écoutant. Le fond très
 *   sombre n'est pas un goût : c'est le contexte d'usage, et c'est lui qui fait
 *   ressortir les pochettes — le vrai contenu de la page.
 *
 * LA LUEUR EST TENUE COURTE
 *   Le néon fait la différence entre « site de radio » et « tableau de bord ».
 *   Mal dosé, il fait la différence entre « premium » et « kitsch ». Une seule
 *   règle tient tout le fichier : la lumière n'éclaire QUE ce sur quoi on peut
 *   cliquer, ou ce qui est en train de passer à l'antenne. Jamais une carte au
 *   repos, jamais un bloc de texte.
 *
 * ET RIEN NE BOUGE POUR RIEN
 *   Toutes les animations tiennent en 150-250 ms et s'effacent devant
 *   `prefers-reduced-motion`. Une page de radio est consultée en conduisant,
 *   en cuisinant, entre deux choses : elle doit être calme.
 */

/* ── La typographie, servie par nous ─────────────────────────────────────────
 *
 * CELLE DE LA SUITE (audit E-25, 29/09/2026)
 *   Inter pour le texte, IBM Plex Mono pour les chiffres (heures, durées,
 *   compteurs) : les polices d'Onyx, de Phoenix et de chloneo.com. Le site
 *   public garde les COULEURS de sa radio ; il partage avec les applications la
 *   typographie, la trame d'espacement et les composants. Aucun texte sous
 *   13 px (0,8125rem).
 *
 * Chargées depuis CE serveur, pas depuis Google Fonts. Une feuille de style
 * distante ferait partir l'adresse IP de chaque auditeur chez un tiers, à
 * chaque page — exactement ce qu'on évite déjà en recopiant les pochettes au
 * lieu de les afficher depuis le catalogue. Licences : polices/OFL-*.txt.
 */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;          /* fichier variable : une seule requête */
  font-display: swap;
  src: url('/assets/polices/inter-latin.woff2') format('woff2');
  /* Le sous-ensemble latin suffit au français : accents, cédille, œ et € y
     sont tous. Charger davantage ferait payer à chaque auditeur des alphabets
     que le site n'affiche jamais. */
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
                 U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Les noms d'artistes venus d'ailleurs (Ł, ő, ș…) : chargé seulement si la
   page en affiche un. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/assets/polices/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308,
                 U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
                 U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/assets/polices/ibm-plex-mono-400-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/assets/polices/ibm-plex-mono-500-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}
@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 600 700;
  font-display: swap;
  src: url('/assets/polices/ibm-plex-mono-600-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2212;
}

:root {
  /* Le socle sombre. */
  --fond: #0a0f1a;
  --fond-profond: #060911;
  --surface: #111827;
  --surface-haute: #161f33;
  --voile: rgba(255, 255, 255, .04);
  --trait: rgba(255, 255, 255, .08);
  --trait-fort: rgba(255, 255, 255, .16);

  /* L'encre. Trois niveaux, pas davantage : au-delà, la hiérarchie se dilue. */
  --encre: #e5e7eb;
  --encre-fort: #f8fafc;
  --discret: #94a3b8;

  /* Les états. Ils ne dépendent pas de la radio : rouge veut dire direct
     partout, et une antenne dont la couleur est rouge ne doit pas rendre le
     badge « en direct » indistinct du reste. */
  --direct: #ef4444;
  --succes: #22c55e;
  /* Les messages (composants communs) : fond sombre teinté, encre claire. */
  --ok-fond: rgba(34, 197, 94, .12);     --ok-encre: #4ade80;
  --veille-fond: rgba(251, 191, 36, .12); --veille-encre: #fbbf24;
  --erreur-fond: rgba(239, 68, 68, .12);  --erreur-encre: #fca5a5;
  /* Le contour d'un champ de saisie : 3:1 sur la surface (WCAG 1.4.11). */
  --trait-controle: rgba(255, 255, 255, .34);

  /* La trame d'espacement, base 8. */
  --e1: 8px;  --e2: 16px;  --e3: 24px;  --e4: 32px;  --e5: 48px;  --e6: 64px;

  /* Les rayons. */
  --r1: 8px;  --r2: 12px;  --r3: 16px;  --r4: 24px;  --rond: 999px;

  /* Les ombres neutres — la profondeur, pas la couleur. */
  --ombre: 0 8px 32px rgba(0, 0, 0, .35);
  --ombre-haute: 0 16px 48px rgba(0, 0, 0, .5);

  /* Le rythme des transitions. */
  --vite: 150ms cubic-bezier(.4, 0, .2, 1);
  --doux: 250ms cubic-bezier(.4, 0, .2, 1);

  /* Les polices de la suite : le texte, puis les chiffres. */
  --police: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --police-chiffres: 'IBM Plex Mono', 'Cascadia Mono', Consolas, Menlo, monospace;

  /* ── LA CHARTE CHLONEO ────────────────────────────────────────────────
     Fixe, et c'est un choix. Le site public porte l'identite de la RADIO et
     ne prend pas celle de la suite (audit E-25 : seules la typographie, la
     trame et les composants sont communs). Le studio, lui, porte la charte
     de la suite (studio.css) ; la couleur que chaque radio saisit dans
     Phoenix n'y marque plus que l'antenne en cours. */
  --primaire: #00e5ff;
  --secondaire: #ff2ebd;
  --accent: #ff9f1c;
  --primaire-lisible: #00e5ff;
  --secondaire-lisible: #ff2ebd;
  --accent-lisible: #ff9f1c;
  --sur-primaire: #06131a;
  --sur-secondaire: #ffffff;
  --primaire-canaux: 0, 229, 255;
  --secondaire-canaux: 255, 46, 189;
  --accent-canaux: 255, 159, 28;
  --degrade: linear-gradient(135deg, #00e5ff 0%, #ff2ebd 100%);
  --degrade-doux: linear-gradient(135deg, #00e5ff 0%, #ff2ebd 60%, #ff9f1c 100%);
  --degrade-audio: linear-gradient(90deg, #00e5ff 0%, #ff2ebd 55%, #ff9f1c 100%);

  /* Les lueurs, composées à partir des canaux : une seule définition pour
     toutes les radios. */
  --lueur-p: 0 0 20px rgba(var(--primaire-canaux), .25);
  --lueur-s: 0 0 24px rgba(var(--secondaire-canaux), .25);
  --lueur-forte: 0 0 32px rgba(var(--primaire-canaux), .4),
                 0 0 64px rgba(var(--secondaire-canaux), .2);

  color-scheme: dark;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le socle
   ═══════════════════════════════════════════════════════════════════════════ */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--fond);
  color: var(--encre);
  font: 400 16px/1.65 var(--police);
  -webkit-font-smoothing: antialiased;
  /* Deux halos très étalés : ils donnent la profondeur sans qu'on les voie.
     Fixés, pour ne pas défiler avec le contenu et se transformer en décor. */
  background-image:
    radial-gradient(900px 500px at 12% -8%, rgba(var(--primaire-canaux), .10), transparent 60%),
    radial-gradient(800px 480px at 92% 4%, rgba(var(--secondaire-canaux), .09), transparent 62%);
  background-attachment: fixed;
}

body.avec-lecteur { padding-bottom: 108px; }

h1, h2, h3 { color: var(--encre-fort); text-wrap: balance; margin: 0; }
h1 { font-size: clamp(2rem, 4.5vw, 3.25rem); font-weight: 700; line-height: 1.1; letter-spacing: -.02em; }
h2 {
  font-size: clamp(1.15rem, 2vw, 1.5rem); font-weight: 600;
  letter-spacing: .02em; margin: var(--e5) 0 var(--e3);
  display: flex; align-items: center; gap: var(--e2);
}
/* Le trait qui prolonge chaque titre de section : c'est lui qui donne le
   rythme de la page, et il coûte moins qu'une bordure sur chaque bloc. */
h2::after {
  content: ''; flex: 1; height: 1px;
  background: linear-gradient(90deg, var(--trait-fort), transparent);
}
h3 { font-size: 1rem; font-weight: 600; }

a { color: var(--primaire-lisible); text-decoration: none; transition: color var(--vite); }
a:hover { color: var(--secondaire-lisible); }

:focus-visible {
  outline: 2px solid var(--primaire-lisible);
  outline-offset: 3px;
  border-radius: var(--r1);
}

img { max-width: 100%; display: block; }

.page {
  max-width: 1280px;
  margin: 0 auto;
  padding: var(--e3) var(--e3) var(--e6);
}

.sous { color: var(--discret); max-width: 62ch; margin: var(--e1) 0 var(--e4); }

/* ═══════════════════════════════════════════════════════════════════════════
   L'en-tête
   ═══════════════════════════════════════════════════════════════════════════ */

.entete {
  position: sticky; top: 0; z-index: 40;
  display: flex; align-items: center; gap: var(--e3);
  padding: var(--e2) var(--e3);
  background: rgba(10, 15, 26, .82);
  /* Le verre reste très léger : au-delà, le texte derrière transparaît et la
     barre devient sale dès qu'une pochette passe dessous. */
  backdrop-filter: blur(16px) saturate(140%);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--trait);
}

.marque { display: flex; align-items: baseline; gap: var(--e1); min-width: 0; }
.marque-nom {
  font-weight: 700; font-size: 1.25rem; letter-spacing: .04em;
  text-transform: uppercase;
  background: var(--degrade);
  -webkit-background-clip: text; background-clip: text;
  color: transparent;
  white-space: nowrap;
}
.marque-freq {
  font-size: .8125rem; font-weight: 600; letter-spacing: .1em;
  color: var(--discret); border: 1px solid var(--trait);
  padding: 2px 8px; border-radius: var(--rond);
}

.nav { display: flex; gap: var(--e1); flex: 1; flex-wrap: wrap; }
.nav a {
  position: relative;
  color: var(--encre); font-size: .9rem; font-weight: 500;
  padding: 6px 12px; border-radius: var(--r1);
  transition: color var(--vite), background var(--vite);
}
.nav a:hover { background: var(--voile); color: var(--encre-fort); }
.nav a[aria-current='page'] { color: var(--encre-fort); }
/* L'onglet actif est souligné par le dégradé de l'antenne — le seul endroit de
   la navigation où la couleur de la radio apparaît. */
.nav a[aria-current='page']::after {
  content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px;
  height: 2px; border-radius: var(--rond); background: var(--degrade);
  box-shadow: var(--lueur-p);
}

/* Le bouton d'écoute : le CTA principal du site, présent sur chaque page. */
.ecouter {
  display: inline-flex; align-items: center; gap: var(--e1);
  padding: 10px 20px; border: 0; border-radius: var(--rond);
  background: var(--degrade); color: var(--sur-primaire);
  font: inherit; font-weight: 600; font-size: .9rem;
  cursor: pointer; white-space: nowrap;
  box-shadow: 0 4px 16px rgba(var(--primaire-canaux), .25);
  transition: transform var(--vite), box-shadow var(--vite), filter var(--vite);
}
.ecouter:hover { transform: translateY(-1px); box-shadow: var(--lueur-forte); filter: brightness(1.06); }
.ecouter:active { transform: translateY(0); }
.ecouter .fleche { transition: transform var(--doux); }
.ecouter:hover .fleche { transform: translateX(3px); }

/* ═══════════════════════════════════════════════════════════════════════════
   Le hero
   ═══════════════════════════════════════════════════════════════════════════ */

.hero {
  position: relative; overflow: hidden;
  border: 1px solid var(--trait); border-radius: var(--r4);
  padding: clamp(var(--e4), 5vw, var(--e6));
  margin-bottom: var(--e5);
  background:
    radial-gradient(700px 380px at 88% 22%, rgba(var(--secondaire-canaux), .22), transparent 64%),
    radial-gradient(620px 340px at 8% 88%, rgba(var(--primaire-canaux), .18), transparent 62%),
    linear-gradient(160deg, var(--surface-haute), var(--fond-profond));
}


.hero-eyebrow {
  font-size: .8125rem; font-weight: 600; letter-spacing: .22em;
  text-transform: uppercase; color: var(--discret); margin-bottom: var(--e2);
}
/* Le slogan porte le dégradé complet : c'est la seule phrase du site qui le
   fait, et c'est ce qui la rend inoubliable. */
.hero h1 .chaud {
  background: var(--degrade-doux);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.hero-phrase { color: var(--encre); font-size: 1.06rem; max-width: 46ch; margin: var(--e3) 0 var(--e4); }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--e2); }
.hero .ecouter { padding: 14px 28px; font-size: 1rem; }

.bouton-2 {
  display: inline-flex; align-items: center; gap: var(--e1);
  padding: 14px 24px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); background: transparent;
  color: var(--encre-fort); font: inherit; font-weight: 500; cursor: pointer;
  transition: border-color var(--vite), background var(--vite), transform var(--vite);
}
.bouton-2:hover {
  border-color: var(--primaire-lisible); background: var(--voile);
  transform: translateY(-1px);
}

/* ═══════════════════════════════════════════════════════════════════════════
   À l'antenne
   ═══════════════════════════════════════════════════════════════════════════ */

.direct {
  position: relative;
  display: grid; grid-template-columns: auto 1fr; gap: var(--e4);
  align-items: center;
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r4);
  background: linear-gradient(135deg, var(--surface-haute), var(--surface));
  box-shadow: var(--ombre);
}
/* Un filet lumineux court le long de la carte quand l'antenne diffuse : c'est
   le seul décor animé de la page, et il ne s'affiche que s'il est vrai. */
.direct.en-direct::before {
  content: ''; position: absolute; inset: -1px; border-radius: inherit;
  padding: 1px; background: var(--degrade);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor; mask-composite: exclude;
  opacity: .55; pointer-events: none;
}

.direct-pochette {
  width: 168px; height: 168px; border-radius: var(--r3); object-fit: cover;
  box-shadow: var(--ombre-haute), var(--lueur-p);
}
.titre-sans-pochette.direct-pochette {
  display: grid; place-items: center;
  font-size: 3.5rem; font-weight: 700; color: var(--encre-fort);
  background: var(--degrade-doux);
}

.direct-infos { min-width: 0; }
.direct-etiquette {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .8125rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
  color: #fff; background: var(--direct);
  padding: 5px 12px; border-radius: var(--rond); margin-bottom: var(--e2);
}
.direct-etiquette::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: #fff; animation: pouls 2s ease-in-out infinite;
}
@keyframes pouls { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.direct-titre {
  font-size: clamp(1.5rem, 3vw, 2.25rem); font-weight: 700;
  color: var(--encre-fort); line-height: 1.15; letter-spacing: -.01em;
}
.direct-artiste {
  font-size: 1.15rem; font-weight: 600; margin-top: 4px;
  background: var(--degrade); -webkit-background-clip: text; background-clip: text;
  color: transparent;
}
.direct-album { color: var(--discret); font-size: .9rem; margin-top: var(--e1); }
.direct-repos { color: var(--discret); margin-top: var(--e1); }

/* Le spectre : douze barres animées, purement décoratives — d'où
   aria-hidden dans le gabarit. Elles disent « ça joue », ce qu'aucun texte
   ne dit aussi vite. */
.spectre { display: flex; align-items: flex-end; gap: 3px; height: 32px; margin-top: var(--e2); }
.spectre span {
  width: 4px; border-radius: 2px; background: var(--degrade-audio);
  background-size: 400% 100%;
  animation: spectre 1.1s ease-in-out infinite alternate;
}
.spectre span:nth-child(3n)   { animation-duration: 1.5s; }
.spectre span:nth-child(3n+1) { animation-duration: .9s; }
.spectre span:nth-child(4n)   { animation-delay: .25s; }
.spectre span:nth-child(5n)   { animation-delay: .5s; }
@keyframes spectre { from { height: 15%; } to { height: 100%; } }

/* ═══════════════════════════════════════════════════════════════════════════
   Les grilles de titres
   ═══════════════════════════════════════════════════════════════════════════ */

/* La grille de vignettes carrees a disparu : les titres se lisent en LIGNES,
   sur l'accueil comme sur `/titres.php`. Ce qui restait ici — `.titres`,
   `.titre-carte`, `.titre-pochette` et leurs textes — n'etait plus ecrit par
   aucune page.

   `.titre-sans-pochette` survit, mais accolee a `.direct-pochette` seulement.
   La regle generale qui la dimensionnait posait `width: 100%` APRES le
   `width: 168px` de `.direct-pochette`, a specificite egale : elle l'emportait.
   Rien ne se voyait — les deux endroits qui affichent ce carre passent par
   `.direct.grand` ou `.direct-bloc`, plus specifiques — mais le premier qui
   aurait ecrit `.direct-pochette` seul aurait eu un carre pleine largeur sans
   comprendre pourquoi. */


/* ═══════════════════════════════════════════════════════════════════════════
   Les composants communs — studio et formulaires publics (audit E-25)
   ═══════════════════════════════════════════════════════════════════════════
   Une seule structure pour les messages, les boutons, les tableaux, les
   panneaux et les champs. Sur le site public, ils prennent les couleurs de la
   radio (:root ci-dessus) ; au studio, celles de la suite (studio.css). */

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
/* Le champ piège des formulaires publics (core/garde.php) : hors de la vue
   et des lecteurs d'écran, pas des robots. */
.piege { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ═══════════════════════════════════════════════════════════════════════════
   Les messages
   ═══════════════════════════════════════════════════════════════════════════ */

.message {
  padding: 12px var(--e2); border-radius: var(--r2);
  margin-bottom: var(--e3); font-size: .92rem;
  border: 1px solid var(--ok-encre); color: var(--ok-encre);
  background: var(--ok-fond);
}
.message.erreur {
  border-color: var(--erreur-encre); color: var(--erreur-encre);
  background: var(--erreur-fond);
}
.message.attention {
  border-color: var(--veille-encre); color: var(--veille-encre);
  background: var(--veille-fond);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les barres d'action
   ═══════════════════════════════════════════════════════════════════════════ */

.actions {
  display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
  margin: var(--e3) 0;
}
.actions .grandir { flex: 1; }

.bouton {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 20px; border: 0; border-radius: var(--rond);
  background: var(--degrade); color: var(--sur-primaire);
  font: inherit; font-weight: 600; font-size: .88rem; cursor: pointer;
  transition: filter var(--vite), box-shadow var(--vite), transform var(--vite);
}
.bouton:hover { filter: brightness(1.07); box-shadow: var(--lueur-p); transform: translateY(-1px); }
.bouton.fantome {
  background: transparent; border: 1px solid var(--trait-fort); color: var(--encre);
}
.bouton.fantome:hover { border-color: var(--primaire-lisible); box-shadow: none; }
.bouton.danger {
  background: transparent; border: 1px solid var(--trait); color: var(--discret);
}
.bouton.danger:hover { border-color: var(--erreur-encre); color: var(--erreur-encre); box-shadow: none; }
/* `hidden` doit cacher un bouton : sans cela, `display: inline-flex` l'emporte. */
.bouton[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   Les tableaux
   ═══════════════════════════════════════════════════════════════════════════ */

.tableau { width: 100%; border-collapse: collapse; font-size: .9rem; }
.tableau th {
  text-align: left; padding: 10px var(--e2);
  font-size: .8125rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  color: var(--discret); border-bottom: 1px solid var(--trait);
}
.tableau td {
  padding: 10px var(--e2); border-bottom: 1px solid var(--trait);
  vertical-align: middle;
}
.tableau tr:hover td { background: var(--voile); }
.tableau .num { text-align: right; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; }
.tableau .fin { text-align: right; white-space: nowrap; }
.tableau a { color: var(--encre-fort); font-weight: 500; }
.tableau a:hover { color: var(--primaire-lisible); }
.tableau .vignette {
  width: 48px; height: 48px; border-radius: var(--r1); object-fit: cover;
  background: var(--surface-haute); border: 1px solid var(--trait);
}
.enveloppe {
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); overflow-x: auto;
}

/* `.enveloppe` est le cadre d'un TABLEAU : sans marge, pour que les lignes
   touchent ses bords. Un formulaire ou un bloc de texte dedans colle au
   cadre. Le panneau, lui, est fait pour eux. */
.panneau {
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
  padding: var(--e3);
  margin-bottom: var(--e3);
  min-width: 0;
}
.panneau > h2:first-child, .panneau > .bloc-tete:first-child h2 { margin-top: 0; }
.panneau .enveloppe-tableau { margin: 0 calc(-1 * var(--e3)); }
.panneau .enveloppe-tableau .tableau th:first-child,
.panneau .enveloppe-tableau .tableau td:first-child { padding-left: var(--e3); }

/* Publié / brouillon : la couleur seule ne suffit pas, le mot est là aussi. */
.etat { font-size: .8125rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; }
.etat.publie { color: var(--ok-encre); }
.etat.brouillon { color: var(--discret); }

/* ═══════════════════════════════════════════════════════════════════════════
   Les formulaires
   ═══════════════════════════════════════════════════════════════════════════ */

.formulaire {
  display: grid; gap: var(--e3);
  /* min(280px, 100%) : sur un écran plus étroit que deux colonnes, une seule,
     sans jamais élargir la page. */
  grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
}
.formulaire .large { grid-column: 1 / -1; }

.champ { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.champ label {
  font-size: .8125rem; font-weight: 600; letter-spacing: .06em;
  text-transform: uppercase; color: var(--discret);
}
.champ .requis { color: var(--secondaire-lisible); }
.champ input[type='text'], .champ input[type='email'], .champ input[type='url'],
.champ input[type='tel'], .champ input[type='search'],
.champ input[type='password'], .champ input[type='number'], .champ input[type='date'],
.champ input[type='datetime-local'], .champ select, .champ textarea {
  font: inherit; font-size: .95rem; color: var(--encre-fort);
  background: var(--fond-profond); border: 1px solid var(--trait-controle);
  border-radius: var(--r1); padding: 10px 14px;
  transition: border-color var(--vite), box-shadow var(--vite);
}
.champ textarea { resize: vertical; line-height: 1.6; }
.champ input:focus, .champ select:focus, .champ textarea:focus {
  outline: none; border-color: var(--primaire-lisible); box-shadow: var(--lueur-p);
}
.champ small { color: var(--discret); font-size: .8125rem; }
.champ.case label {
  display: flex; align-items: center; gap: 10px;
  text-transform: none; letter-spacing: 0; font-size: .92rem;
  color: var(--encre); font-weight: 500; cursor: pointer;
}
.champ.case input { width: 18px; height: 18px; accent-color: var(--primaire); }

/* ═══════════════════════════════════════════════════════════════════════════
   Les listes — historique et classement
   ═══════════════════════════════════════════════════════════════════════════ */

.liste {
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); overflow: hidden;
}
.ligne {
  display: grid; grid-template-columns: auto auto 1fr auto;
  align-items: center; gap: var(--e2);
  padding: 10px var(--e2);
  border-bottom: 1px solid var(--trait);
  transition: background var(--vite);
}
.ligne:last-child { border-bottom: 0; }
.ligne:hover { background: var(--voile); }

/* Le rang du classement. Les trois premiers portent la couleur de l'antenne :
   au-delà, un podium de dix places ne veut plus rien dire. */
.rang {
  width: 28px; text-align: center;
  font-size: 1.05rem; font-weight: 700; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
  color: var(--discret);
}
.ligne:nth-child(-n+3) .rang {
  background: var(--degrade-doux);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.ligne-pochette {
  width: 48px; height: 48px; border-radius: var(--r1); object-fit: cover;
  background: var(--surface-haute); border: 1px solid var(--trait);
}
.ligne-texte { min-width: 0; }
.ligne-titre {
  font-weight: 600; color: var(--encre-fort); font-size: .95rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ligne-artiste {
  color: var(--discret); font-size: .85rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ligne-heure, .ligne-passages {
  font-size: .82rem; font-weight: 500; color: var(--discret);
  font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.ligne-passages { color: var(--accent-lisible); font-weight: 600; }

/* La liste de l'historique n'a pas de rang : on garde la même grille en
   neutralisant la première colonne, plutôt que d'écrire deux mises en page. */
.liste.sans-rang .ligne { grid-template-columns: auto 1fr auto; }

/* ═══════════════════════════════════════════════════════════════════════════
   La recherche et la pagination
   ═══════════════════════════════════════════════════════════════════════════ */

.recherche {
  display: flex; flex-wrap: wrap; gap: var(--e2);
  margin-bottom: var(--e4);
}
.recherche input[type='search'], .recherche select {
  font: inherit; font-size: .95rem; color: var(--encre-fort);
  background: var(--surface); border: 1px solid var(--trait);
  border-radius: var(--rond); padding: 12px 20px;
  transition: border-color var(--vite), box-shadow var(--vite);
}
.recherche input[type='search'] { flex: 1; min-width: 220px; }
.recherche input[type='search']::placeholder { color: var(--discret); }
.recherche input:focus, .recherche select:focus {
  outline: none; border-color: var(--primaire-lisible);
  box-shadow: var(--lueur-p);
}
.recherche button {
  font: inherit; font-weight: 600; cursor: pointer;
  padding: 12px 26px; border: 0; border-radius: var(--rond);
  background: var(--degrade); color: var(--sur-primaire);
  transition: filter var(--vite), box-shadow var(--vite);
}
.recherche button:hover { filter: brightness(1.07); box-shadow: var(--lueur-p); }

.resultat { color: var(--discret); font-size: .9rem; margin: 0 0 var(--e2); }

.pages {
  display: flex; align-items: center; justify-content: center; gap: var(--e2);
  margin-top: var(--e4);
}
.pages a {
  padding: 10px 18px; border-radius: var(--rond);
  border: 1px solid var(--trait); color: var(--encre);
  transition: border-color var(--vite), background var(--vite);
}
.pages a:hover { border-color: var(--primaire-lisible); background: var(--voile); }
.pages .actuelle {
  color: var(--discret); font-size: .9rem; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les états vides
   ═══════════════════════════════════════════════════════════════════════════ */

.vide {
  border: 1px dashed var(--trait-fort); border-radius: var(--r3);
  background: var(--surface); padding: var(--e5) var(--e3);
  text-align: center; color: var(--discret);
}
.vide strong { display: block; color: var(--encre-fort); font-size: 1.05rem; }
.vide code {
  background: var(--fond-profond); border: 1px solid var(--trait);
  border-radius: 6px; padding: 2px 7px; font-size: .88em; color: var(--primaire-lisible);
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le pied
   ═══════════════════════════════════════════════════════════════════════════ */

.pied {
  border-top: 1px solid var(--trait);
  background: var(--fond-profond);
  padding: var(--e5) var(--e3);
  margin-top: var(--e6);
}
.pied-corps {
  max-width: 1280px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: var(--e5); justify-content: space-between;
}
.pied-marque { max-width: 34ch; }
.pied-slogan {
  margin-top: var(--e1); font-size: 1.1rem; font-weight: 600;
  background: var(--degrade-doux);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.pied-liens { display: flex; flex-direction: column; gap: var(--e1); }
.pied-liens a { color: var(--encre); font-size: .9rem; }
.pied-liens a:hover { color: var(--primaire-lisible); }
.pied-titre {
  font-size: .8125rem; font-weight: 600; letter-spacing: .18em;
  text-transform: uppercase; color: var(--discret); margin-bottom: 6px;
}
.pied-bas {
  max-width: 1280px; margin: var(--e5) auto 0; padding-top: var(--e3);
  border-top: 1px solid var(--trait);
  color: var(--discret); font-size: .8125rem;
  display: flex; flex-wrap: wrap; gap: var(--e2); justify-content: space-between;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le lecteur
   ═══════════════════════════════════════════════════════════════════════════ */

.lecteur {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; align-items: center; gap: var(--e3);
  padding: 12px var(--e3);
  background: rgba(6, 9, 17, .88);
  backdrop-filter: blur(20px) saturate(150%);
  -webkit-backdrop-filter: blur(20px) saturate(150%);
  border-top: 1px solid var(--trait);
}
/* Le filet lumineux du haut : il relie visuellement le lecteur à la carte
   « à l'antenne », et signale que la barre est vivante. */
.lecteur::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 1px;
  background: var(--degrade-audio); opacity: .8;
}

.lecteur-bouton {
  position: relative; flex: none;
  width: 54px; height: 54px; border-radius: 50%;
  border: 0; cursor: pointer; padding: 0;
  display: grid; place-items: center;
  background: var(--degrade); color: var(--sur-primaire);
  box-shadow: 0 4px 20px rgba(var(--primaire-canaux), .35);
  transition: transform var(--vite), box-shadow var(--vite);
}
.lecteur-bouton:hover { transform: scale(1.05); box-shadow: var(--lueur-forte); }
.lecteur-bouton:active { transform: scale(.98); }

/* Les deux formes sont dessinées en CSS : une icône de lecture et une de pause
   ne valent pas une bibliothèque entière. */
.ico-play {
  width: 0; height: 0; margin-left: 4px;
  border-left: 16px solid currentColor;
  border-top: 10px solid transparent;
  border-bottom: 10px solid transparent;
}
.lecteur-bouton.joue .ico-play {
  width: 16px; height: 18px; margin-left: 0; border: 0;
  background: currentColor;
  -webkit-mask: linear-gradient(#000 0 0) left / 5px 100% no-repeat,
                linear-gradient(#000 0 0) right / 5px 100% no-repeat;
          mask: linear-gradient(#000 0 0) left / 5px 100% no-repeat,
                linear-gradient(#000 0 0) right / 5px 100% no-repeat;
}

.lecteur-texte { flex: 1; min-width: 0; }
.lecteur-etat {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .8125rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--direct);
}
.lecteur-etat::before {
  content: ''; width: 6px; height: 6px; border-radius: 50%;
  background: var(--direct); animation: pouls 2s ease-in-out infinite;
}
.lecteur-titre {
  font-weight: 600; color: var(--encre-fort); font-size: .98rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.lecteur-artiste {
  color: var(--discret); font-size: .85rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.lecteur-volume {
  flex: none; width: 130px; height: 4px; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  background: var(--trait-fort); border-radius: var(--rond);
}
.lecteur-volume::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--primaire); border: 0; cursor: pointer;
  box-shadow: 0 0 10px rgba(var(--primaire-canaux), .6);
}
.lecteur-volume::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--primaire); border: 0; cursor: pointer;
}

/* « J'aime ce titre » : une cible de 44 px, un cœur qui se remplit. */
.lecteur-jaime {
  flex: none; width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  border: 1px solid var(--trait-fort); background: transparent; color: var(--encre);
  transition: color var(--vite), border-color var(--vite), transform var(--vite);
}
.lecteur-jaime svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.lecteur-jaime:hover { border-color: var(--secondaire-lisible); color: var(--secondaire-lisible); }
.lecteur-jaime.aime { color: var(--secondaire-lisible); border-color: var(--secondaire-lisible); }
.lecteur-jaime.aime svg { fill: currentColor; }
.lecteur-jaime.aime:active { transform: scale(.94); }
.lecteur-jaime[hidden] { display: none; }

/* Le choix du débit : discret, mais atteignable au pouce et au clavier. */
.lecteur-qualite {
  flex: none; font: inherit; font-size: .8125rem; font-weight: 600;
  font-family: var(--police-chiffres);
  min-height: 44px; padding: 0 10px; border-radius: var(--r1); cursor: pointer;
  color: var(--encre); background: var(--surface); border: 1px solid var(--trait-fort);
}
.lecteur-qualite { max-width: 200px; }
.lecteur-qualite[hidden] { display: none; }

/* ═══════════════════════════════════════════════════════════════════════════
   Ce qui s'adapte
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .entete { flex-wrap: wrap; gap: var(--e2); padding: var(--e2); }
  .nav { order: 3; width: 100%; overflow-x: auto; flex-wrap: nowrap; padding-bottom: 2px; }
  .nav::-webkit-scrollbar { display: none; }
  .direct { grid-template-columns: 1fr; gap: var(--e3); text-align: center; }
  .direct-pochette { width: 100%; max-width: 260px; height: auto; aspect-ratio: 1; margin: 0 auto; }
  .spectre { justify-content: center; }
}

@media (max-width: 640px) {
  .page { padding: var(--e2) var(--e2) var(--e5); }
  body.avec-lecteur { padding-bottom: 92px; }
  .titres { grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); }
  .hero { padding: var(--e3); border-radius: var(--r3); }
  .hero .ecouter, .bouton-2 { width: 100%; justify-content: center; }
  /* Le volume disparaît avant tout le reste : sur un téléphone, c'est le
     bouton physique qui règle le son. */
  .lecteur-volume { display: none; }
  .lecteur { gap: var(--e1); padding: 10px var(--e2); }
  .lecteur-bouton { width: 46px; height: 46px; }
  .lecteur-qualite { max-width: 84px; }
  .pied-corps { gap: var(--e3); }
}

/* Une page de radio est consultée en conduisant, en cuisinant, entre deux
   choses. Si le système dit « moins de mouvement », il n'y en a plus. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .spectre span { height: 55%; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les onglets — jours de la semaine, catégories
   ═══════════════════════════════════════════════════════════════════════════ */

.onglets {
  display: flex; gap: var(--e1); flex-wrap: wrap;
  margin-bottom: var(--e4);
  /* Sur téléphone, sept jours ne tiennent pas : ils défilent, ils ne se
     replient pas sur trois lignes. */
  overflow-x: auto; -ms-overflow-style: none; scrollbar-width: none;
}
.onglets::-webkit-scrollbar { display: none; }
.onglets a {
  flex: none;
  padding: 9px 18px; border-radius: var(--rond);
  border: 1px solid var(--trait);
  color: var(--encre); font-size: .88rem; font-weight: 500;
  white-space: nowrap;
  transition: border-color var(--vite), background var(--vite), color var(--vite);
}
.onglets a:hover { border-color: var(--trait-fort); background: var(--voile); }
.onglets a.actif {
  background: var(--degrade); border-color: transparent;
  color: var(--sur-primaire); font-weight: 600;
  box-shadow: var(--lueur-p);
}

/* ═══════════════════════════════════════════════════════════════════════════
   La grille des émissions
   ═══════════════════════════════════════════════════════════════════════════ */

.grille { display: flex; flex-direction: column; gap: var(--e2); }

.creneau {
  position: relative;
  display: grid; grid-template-columns: 96px 88px 1fr auto;
  align-items: center; gap: var(--e3);
  padding: var(--e2);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
  transition: border-color var(--vite), transform var(--vite);
}
.creneau:hover { border-color: var(--trait-fort); transform: translateX(2px); }
/* Le créneau en cours est le seul de la page à porter la lumière : c'est
   l'information qu'on vient chercher. */
.creneau.en-cours {
  border-color: transparent;
  background: linear-gradient(135deg, var(--surface-haute), var(--surface));
  box-shadow: var(--lueur-p);
}
.creneau.en-cours::before {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px;
  border-radius: var(--rond); background: var(--degrade);
}

.creneau-heure {
  font-size: .95rem; font-weight: 600; color: var(--encre-fort);
  font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.creneau-image {
  width: 88px; height: 88px; border-radius: var(--r2); object-fit: cover;
  background: var(--surface-haute);
}
.creneau-image.sans {
  display: grid; place-items: center; border: 1px solid var(--trait);
  font-size: 2rem; font-weight: 700; color: var(--discret);
}
.creneau-corps { min-width: 0; }
.creneau-corps h3 { display: flex; align-items: center; gap: var(--e1); flex-wrap: wrap; }
.creneau-accroche { color: var(--discret); font-size: .88rem; margin: 4px 0 0; }

.creneau-voix {
  display: flex; align-items: center; gap: 10px;
  color: var(--discret); font-size: .8125rem; white-space: nowrap;
}
.creneau-voix strong { color: var(--encre-fort); font-size: .9rem; }
.creneau-voix img, .creneau-voix .pastille {
  width: 42px; height: 42px; border-radius: 50%; object-fit: cover;
  border: 1px solid var(--trait-fort);
}
.creneau-voix .pastille {
  display: grid; place-items: center;
  background: var(--surface-haute); color: var(--encre-fort); font-weight: 600;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les étiquettes
   ═══════════════════════════════════════════════════════════════════════════ */

.etiquette {
  display: inline-block;
  font-size: .8125rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  padding: 4px 10px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); color: var(--discret);
}
.etiquette.directe { background: var(--direct); border-color: transparent; color: #fff; }

.tags { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--e1); }
.tag {
  font-size: .8125rem; font-weight: 500;
  padding: 5px 12px; border-radius: var(--rond);
  border: 1px solid var(--trait); color: var(--discret);
  transition: border-color var(--vite), color var(--vite);
}
a.tag:hover { border-color: var(--primaire-lisible); color: var(--primaire-lisible); }

/* ═══════════════════════════════════════════════════════════════════════════
   Les cartes de contenu
   ═══════════════════════════════════════════════════════════════════════════ */

.cartes {
  display: grid; gap: var(--e3);
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}
.carte {
  position: relative;
  display: block; min-width: 0;
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); overflow: hidden;
  color: inherit;
  transition: transform var(--doux), border-color var(--vite), box-shadow var(--doux);
}
.carte:hover {
  transform: translateY(-4px); border-color: var(--trait-fort);
  box-shadow: var(--ombre), var(--lueur-p);
}
.carte-lien { display: block; position: relative; color: inherit; }
.carte-image {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  background: var(--surface-haute);
}
.carte-image.sans {
  display: grid; place-items: center;
  font-size: 2.5rem; font-weight: 700; color: var(--discret);
}
.carte-image.ronde {
  aspect-ratio: 1; border-radius: 50%;
  width: 120px; margin: var(--e3) auto 0;
}
.carte-etiquette {
  position: absolute; top: 12px; left: 12px;
  font-size: .8125rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  padding: 5px 11px; border-radius: var(--rond);
  background: var(--degrade); color: var(--sur-primaire);
}
.carte-corps { padding: var(--e2); }
.carte-corps h3 { line-height: 1.35; }
.carte-corps h3 a { color: var(--encre-fort); }
.carte-corps h3 a:hover { color: var(--primaire-lisible); }
.carte-corps p { color: var(--discret); font-size: .87rem; margin: 6px 0 0; }
.carte-meta { font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; }
.carte-source { color: var(--primaire-lisible) !important; font-weight: 500; }

/* Les fiches d'animateurs se lisent d'un coup d'oeil : le nom sous le visage,
   centré, sans le poids d'une carte éditoriale. */
.cartes.voix { grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); }
.cartes.voix .carte-corps { text-align: center; }

/* ═══════════════════════════════════════════════════════════════════════════
   Les fiches et les articles
   ═══════════════════════════════════════════════════════════════════════════ */

.fiche {
  display: grid; grid-template-columns: minmax(0, 320px) 1fr; gap: var(--e5);
  align-items: center;
  margin-bottom: var(--e4);
}
.fiche-image {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: var(--r3); box-shadow: var(--ombre-haute);
}
.fiche-image.ronde { aspect-ratio: 1; border-radius: 50%; max-width: 260px; }
.fiche-corps { min-width: 0; }
.fiche-accroche { color: var(--encre); font-size: 1.05rem; margin: var(--e2) 0; }

.horaires { display: flex; flex-wrap: wrap; gap: var(--e1); margin-top: var(--e3); }
.horaire {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 14px; border-radius: var(--r1);
  border: 1px solid var(--trait); background: var(--surface);
  font-size: .85rem;
}
.horaire-jour { color: var(--discret); }
.horaire-heure { color: var(--encre-fort); font-weight: 600; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; }

/* Le texte long : 65 caractères par ligne, c'est ce qui se lit sans effort. */
.texte { max-width: 68ch; }
.texte p { margin: 0 0 var(--e2); }
.texte h2 { margin: var(--e4) 0 var(--e1); }
.texte ul { margin: 0 0 var(--e2); padding-left: var(--e3); }
/* Mentions légales et confidentialité : un renseignement que la radio doit
   encore donner se voit — il ne se devine pas (audit E-22). */
.a-renseigner {
  background: rgba(var(--accent-canaux), .14); color: var(--accent-lisible);
  border-radius: 4px; padding: 0 4px; font-weight: 600;
}

.article { max-width: 74ch; }
.article .chapo {
  font-size: 1.12rem; color: var(--encre-fort); font-weight: 500;
  margin: var(--e2) 0 var(--e3);
}
.article-image {
  width: 100%; border-radius: var(--r3); margin: var(--e3) 0 var(--e4);
  box-shadow: var(--ombre);
}

.une {
  display: grid; grid-template-columns: minmax(0, 1.2fr) 1fr; gap: var(--e4);
  align-items: center;
  padding: var(--e3); margin-bottom: var(--e4);
  border: 1px solid var(--trait); border-radius: var(--r4);
  background: linear-gradient(135deg, var(--surface-haute), var(--surface));
}
.une-visuel img, .une-visuel .carte-image {
  width: 100%; aspect-ratio: 16 / 10; object-fit: cover;
  border-radius: var(--r2);
}
.une-meta {
  display: flex; align-items: center; gap: var(--e2);
  color: var(--discret); font-size: .82rem;
}
.une-corps h2 { margin: 12px 0 !important; }
.une-corps h2::after { display: none; }
.une-corps h2 a { color: var(--encre-fort); }
.une-corps h2 a:hover { color: var(--primaire-lisible); }
.une-corps p { color: var(--discret); }

/* ═══════════════════════════════════════════════════════════════════════════
   Le direct en grand, et le lecteur de podcast
   ═══════════════════════════════════════════════════════════════════════════ */

.direct.grand { padding: var(--e4); }
.direct.grand .direct-pochette { width: 240px; height: 240px; }
.spectre.grand { height: 48px; }

.lecteur-fiche { margin-top: var(--e3); }
.lecteur-fiche audio {
  width: 100%; max-width: 520px;
  /* Le lecteur natif s'affiche clair par défaut : sur ce fond, il jure. */
  color-scheme: dark;
}
/* Un podcast vidéo (programme de la Visual Radio) : 16/9, toute la largeur. */
.fiche.fiche-video { grid-template-columns: 1fr; }
.lecteur-fiche video.podcast-video {
  display: block; width: 100%; max-width: 960px; aspect-ratio: 16 / 9;
  background: #000; border-radius: var(--e1); color-scheme: dark;
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le contact
   ═══════════════════════════════════════════════════════════════════════════ */

.contacts {
  display: grid; gap: var(--e2);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.contact {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); color: var(--encre-fort);
  transition: border-color var(--vite), transform var(--vite), box-shadow var(--vite);
}
.contact:hover {
  border-color: transparent; transform: translateY(-2px);
  box-shadow: var(--ombre), var(--lueur-p); color: var(--encre-fort);
}
.contact-quoi {
  font-size: .8125rem; font-weight: 600; letter-spacing: .14em;
  text-transform: uppercase; color: var(--discret);
}
.contact strong { font-size: 1.05rem; }

/* ═══════════════════════════════════════════════════════════════════════════
   Ce qui s'adapte — les nouveaux blocs
   ═══════════════════════════════════════════════════════════════════════════ */

@media (max-width: 900px) {
  .creneau { grid-template-columns: 72px 1fr; grid-template-areas: 'heure corps' 'voix voix'; }
  .creneau-heure { grid-area: heure; }
  .creneau-image { display: none; }
  .creneau-corps { grid-area: corps; }
  .creneau-voix { grid-area: voix; }
  .fiche, .une { grid-template-columns: 1fr; gap: var(--e3); }
  .fiche-image.ronde { max-width: 180px; }
  .direct.grand .direct-pochette { width: 100%; max-width: 260px; height: auto; }
}

@media (max-width: 640px) {
  .cartes { grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); }
  .cartes.voix { grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .carte-image.ronde { width: 92px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   L'accueil, sur le schéma de la maquette
   ═══════════════════════════════════════════════════════════════════════════

   Un hero, TROIS colonnes, puis DEUX. Ce n'est pas une disposition parmi
   d'autres : les trois colonnes répondent aux trois questions qu'un auditeur se
   pose en arrivant — qu'est-ce qui passe, qu'est-ce que je viens de manquer,
   qu'est-ce que vous passez en ce moment. Les empiler oblige à faire défiler
   pour obtenir ce qui devrait tenir dans un écran.                            */


/* Avec une vraie image, le hero se partage : le texte à gauche, la photo à
   droite, comme sur la maquette. */


/* ── Les grilles de blocs ────────────────────────────────────────────────── */

.trois, .deux {
  display: grid; gap: var(--e3);
  margin-top: var(--e4);
  align-items: start;
}
.trois { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.deux  { grid-template-columns: repeat(2, minmax(0, 1fr)); }

.bloc {
  min-width: 0;
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
  padding: var(--e2);
}
.bloc-tete {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--e2); margin-bottom: var(--e2);
}
/* Dans un bloc, le titre est une étiquette de colonne : ni le trait qui
   traverse la page, ni la marge d'une section de premier niveau. */
.bloc-tete h2 {
  margin: 0; font-size: .82rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; color: var(--encre-fort);
}
.bloc-tete h2::after { display: none; }

/* ── L'humeur de l'antenne ──────────────────────────────────────────────
   Trois familles d'ambiance, trois teintes vérifiées sur --surface pour les
   daltoniens (core/ambiances.json) ; l'ambiance exacte est toujours écrite. */
.ambiance-pastille {
  display: inline-flex; align-items: center; gap: var(--e1);
  margin-top: var(--e1); padding: 4px 12px 4px 10px;
  border: 1px solid var(--trait); border-radius: var(--rond);
  background: var(--voile); color: var(--encre-fort); font-size: .85rem;
}
.ambiance-pastille[hidden] { display: none; }
.ambiance-point {
  display: inline-block; flex: none;
  width: 10px; height: 10px; border-radius: 50%;
}
.ambiance-mot {
  color: var(--discret); font-size: .8125rem; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
}
.humeur { margin-top: var(--e3); }
.humeur-resume { font-size: .85rem; color: var(--encre-fort); }
/* Les barres couvrent toute la largeur : l'axe va du premier titre à
   « maintenant », il ne doit pas s'arrêter au milieu. */
.humeur-barres {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 4px;
  height: 120px; padding-top: var(--e1);
  border-bottom: 1px solid var(--trait-fort);
}
.humeur-barre {
  flex: 1 1 0; max-width: 56px; min-height: 4px; height: var(--h);
  border-radius: 4px 4px 0 0; background: var(--c);
  opacity: .72; transition: opacity var(--vite);
}
.humeur-barre:hover, .humeur-barre.courante { opacity: 1; }
.humeur-barre.courante { outline: 2px solid var(--encre-fort); outline-offset: 2px; }
.humeur-barre.sans-energie { background: transparent; border: 1px dashed var(--c); border-bottom: 0; }
.humeur-axe {
  display: flex; justify-content: space-between;
  margin-top: 6px; font-size: .8125rem; color: var(--discret);
  font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
}
.humeur-legende {
  display: flex; flex-wrap: wrap; gap: 6px var(--e2);
  margin: 12px 0 0; padding: 0; list-style: none;
  font-size: .8125rem; color: var(--encre);
}
.humeur-legende li { display: inline-flex; align-items: center; gap: 6px; }
.humeur-legende .humeur-note { color: var(--discret); }
@media (prefers-reduced-motion: reduce) {
  .humeur-barre { transition: none; }
}
.voir-tout {
  font-size: .8125rem; font-weight: 500; white-space: nowrap;
  color: var(--primaire-lisible);
}
.bloc-vide { color: var(--discret); font-size: .88rem; margin: 0; padding: var(--e2) 0; }

/* Une liste posée DANS un bloc n'a pas besoin de son propre cadre. */
.liste.nue { border: 0; background: transparent; border-radius: 0; }
.liste.nue .ligne { padding: 8px 0; }
.liste.nue .ligne:hover { background: transparent; }
.liste.nue .ligne:last-child { border-bottom: 0; }
.ligne-heure.devant {
  width: 42px; color: var(--primaire-lisible); font-weight: 600;
}
/* Heure, vignette, puis le texte qui prend la place restante. Sans cette
   regle, le texte tombait dans la colonne « auto » de fin et se collait a
   droite — trois elements pour une grille qui en attendait quatre. */
.liste.nue.sans-rang .ligne { grid-template-columns: auto auto minmax(0, 1fr); }

/* ── Le direct, en colonne ───────────────────────────────────────────────── */

.direct-bloc.en-direct {
  border-color: transparent;
  background: linear-gradient(150deg, var(--surface-haute), var(--surface));
  box-shadow: var(--lueur-p);
}
.direct-corps { display: flex; gap: var(--e2); align-items: center; }
.direct-bloc .direct-pochette {
  flex: none; width: 108px; height: 108px; border-radius: var(--r2);
}
.direct-bloc .titre-sans-pochette.direct-pochette { font-size: 2.4rem; }
.direct-bloc .direct-titre { font-size: 1.15rem; line-height: 1.25; }
.direct-bloc .direct-artiste { font-size: .95rem; }
.direct-bloc .spectre { height: 24px; margin-top: 10px; }
.direct-bloc .direct-album { font-size: .8125rem; }

/* Des cartes serrées : dans une colonne, deux par ligne suffisent. */
/* Quatre par rangee dans une colonne de moitie de page : c'est la maquette,
   et c'est ce qui fait tenir « Nos emissions » sur un seul rang. */
.cartes.serrees { grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 10px; }
.cartes.serrees .carte-corps { padding: 10px 12px; }
.cartes.serrees .carte-corps h3 { font-size: .88rem; }
.cartes.serrees .carte-corps p { font-size: .8125rem; }

/* ── La bande des applications et des réseaux ────────────────────────────── */

.bande {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: var(--e3);
  margin-top: var(--e5); padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r4);
  background:
    radial-gradient(600px 260px at 15% 50%, rgba(var(--primaire-canaux), .12), transparent 65%),
    radial-gradient(600px 260px at 85% 50%, rgba(var(--secondaire-canaux), .10), transparent 65%),
    var(--surface);
}
.bande-mot { min-width: 0; }
.bande-mot strong {
  display: block; font-size: 1.1rem; font-weight: 700; color: var(--encre-fort);
  letter-spacing: .04em; text-transform: uppercase;
}
.bande-mot span {
  background: var(--degrade); -webkit-background-clip: text; background-clip: text;
  color: transparent; font-weight: 600;
}
.bande-liens { display: flex; align-items: center; gap: var(--e1); flex-wrap: wrap; }
.magasin {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; border-radius: var(--r2);
  border: 1px solid var(--trait-fort); color: var(--encre-fort);
  font-size: .84rem; font-weight: 500;
  transition: border-color var(--vite), background var(--vite);
}
.magasin:hover { border-color: var(--primaire-lisible); background: var(--voile); }

.reseaux { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.reseau {
  display: grid; place-items: center;
  width: 40px; height: 40px; border-radius: 50%;
  border: 1px solid var(--trait-fort); color: var(--encre);
  font-size: .8125rem; font-weight: 700;
  transition: border-color var(--vite), color var(--vite), transform var(--vite);
}
.reseau:hover {
  border-color: transparent; color: var(--sur-primaire);
  background: var(--degrade); transform: translateY(-2px);
}

/* ── La recherche de l'en-tête ───────────────────────────────────────────── */

.chercher {
  display: flex; align-items: center; gap: 6px;
  padding: 7px 14px; border-radius: var(--rond);
  border: 1px solid var(--trait); background: transparent;
}
.chercher input {
  /* 130 px coupaient l'invite au milieu d'« artiste » : elle se lit en entier. */
  font: inherit; font-size: .85rem; width: 172px;
  background: transparent; border: 0; color: var(--encre-fort);
}
.chercher input::placeholder { color: var(--discret); }
.chercher input:focus { outline: none; }
.chercher:focus-within { border-color: var(--primaire-lisible); box-shadow: var(--lueur-p); }
.chercher button {
  background: transparent; border: 0; cursor: pointer; padding: 0;
  color: var(--discret); font-size: 1rem; line-height: 1;
}
.chercher button:hover { color: var(--primaire-lisible); }

/* ── Le logo, quand la radio en a déposé un ──────────────────────────────── */

.marque-logo { height: 34px; width: auto; }
.pied .marque-logo { height: 44px; margin-bottom: var(--e1); }

/* ── Le menu « Radio » qui se déroule ────────────────────────────────────── */

.nav-groupe { position: relative; }
.nav-bouton {
  position: relative;
  display: inline-flex; align-items: center; gap: 5px;
  font: inherit; font-size: .9rem; font-weight: 500;
  color: var(--encre); background: none; border: 0; cursor: pointer;
  padding: 6px 12px; border-radius: var(--r1);
  transition: color var(--vite), background var(--vite);
}
.nav-bouton:hover, .nav-groupe.ouvert .nav-bouton {
  background: var(--voile); color: var(--encre-fort);
}
.nav-bouton:focus-visible { outline: 2px solid var(--primaire-lisible); outline-offset: 2px; }
/* Une page du groupe est ouverte : le groupe porte le soulignement, comme un
   onglet actif — sinon on ne sait plus où l'on est une fois le menu refermé. */
.nav-bouton.actif { color: var(--encre-fort); }
.nav-bouton.actif::after {
  content: ''; position: absolute; left: 12px; right: 12px; bottom: -1px;
  height: 2px; border-radius: var(--rond); background: var(--degrade);
  box-shadow: var(--lueur-p);
}
.nav-fleche { font-size: .8125rem; transition: transform var(--vite); }
.nav-groupe.ouvert .nav-fleche { transform: rotate(180deg); }

.sous-menu {
  position: absolute; top: calc(100% + 8px); left: 0; z-index: 60;
  display: none; flex-direction: column; gap: 2px;
  min-width: 250px; padding: 8px;
  border: 1px solid var(--trait-fort); border-radius: var(--r2);
  background: var(--surface); box-shadow: var(--ombre-haute);
}
/* Un pont invisible au-dessus du menu : sans lui, le survol se perd dans les
   huit pixels entre le bouton et la liste, et le menu se referme sous la
   souris. */
.sous-menu::before {
  content: ''; position: absolute; left: 0; right: 0; top: -10px; height: 10px;
}
@media (hover: hover) {
  .nav-groupe:hover .sous-menu { display: flex; }
}
.nav-groupe.ouvert .sous-menu { display: flex; }
.nav .sous-menu a {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; white-space: nowrap;
}
.nav .sous-menu a svg { flex: none; color: var(--discret); }
.nav .sous-menu a[aria-current='page'] { background: var(--voile); }
.nav .sous-menu a[aria-current='page'] svg { color: var(--primaire-lisible); }
/* Dans la liste, pas de soulignement : le fond suffit, et un trait sous
   chaque ligne ouverte ferait une grille. */
.nav .sous-menu a[aria-current='page']::after { display: none; }

/* ── Le même groupe, dans la colonne de gauche ───────────────────────────── */

.lateral-groupe summary {
  list-style: none;
  display: flex; align-items: center; gap: 11px;
  padding: 9px 13px; border-radius: var(--r1);
  color: var(--encre); font-size: .87rem; font-weight: 500; cursor: pointer;
  transition: background var(--vite), color var(--vite);
}
.lateral-groupe summary::-webkit-details-marker { display: none; }
.lateral-groupe summary:hover { background: var(--voile); color: var(--encre-fort); }
.lateral-groupe summary svg { flex: none; }
.lateral-fleche { margin-left: auto; font-size: .8125rem; transition: transform var(--vite); }
.lateral-groupe[open] .lateral-fleche { transform: rotate(180deg); }
.lateral-menu .lateral-groupe a.enfant { padding-left: 26px; font-size: .84rem; }

/* ── L'équipe : un extrait de la bio sur chaque carte ────────────────────── */

.carte-bio {
  margin: 6px 0 0; font-size: .84rem; line-height: 1.5; color: var(--discret);
}

/* ── Ce qui s'adapte ─────────────────────────────────────────────────────── */

@media (max-width: 1080px) {
  .trois { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Le direct passe en pleine largeur : c'est l'information principale. */
  .trois .direct-bloc { grid-column: 1 / -1; }
  .chercher { display: none; }
}

@media (max-width: 780px) {
  .trois, .deux { grid-template-columns: 1fr; }

  .bande { flex-direction: column; align-items: flex-start; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le bandeau des pages intérieures
   ═══════════════════════════════════════════════════════════════════════════ */

.bandeau { margin-bottom: var(--e4); }
.bandeau.avec-image {
  position: relative; overflow: hidden;
  padding: clamp(var(--e4), 5vw, var(--e6)) clamp(var(--e3), 4vw, var(--e5));
  border: 1px solid var(--trait); border-radius: var(--r4);
  background: var(--banniere) center / cover no-repeat, var(--surface-haute);
}
/* PAS DE VOILE SUR L'IMAGE
   Les bannières sont préparées avec la place du titre : un dégradé par-dessus
   ne faisait que ternir toute la photo. Une ombre légère sous le texte suffit
   à le détacher, sans toucher à l'image. */
.bandeau.avec-image h1, .bandeau.avec-image .sous { text-shadow: 0 1px 12px rgba(0, 0, 0, .55); }
.bandeau.avec-image > * { position: relative; z-index: 1; }
.bandeau.avec-image .sous { margin-bottom: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   Les rubriques du jour — horoscope, éphéméride, anniversaires, question
   ═══════════════════════════════════════════════════════════════════════════

   Quatre pages qui changent tous les matins. Elles partagent une même idée :
   le contenu est court, il doit se lire d'un coup d'œil, et rien ne doit
   ressembler à un tableau de bord. */

.jour-quoi {
  display: block;
  font-size: .8125rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--discret);
  margin-bottom: 6px;
}
.jour-titre {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 1.15rem; margin: var(--e5) 0 var(--e2);
}

/* ── L'horoscope : douze cartes, une par signe ───────────────────────────── */

.signes {
  display: grid; gap: var(--e2);
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
}
.signe {
  display: flex; flex-direction: column; gap: var(--e2);
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
}
.signe-tete { display: flex; align-items: center; gap: 14px; }
/* Le glyphe est un caractère, pas une image : il prend le dégradé de la
   charte comme le ferait n'importe quel texte. */
.signe-glyphe {
  flex: none; width: 48px; height: 48px;
  display: grid; place-items: center;
  font-size: 1.7rem; line-height: 1;
  border-radius: 50%;
  border: 1px solid var(--trait-fort);
  background: var(--degrade);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.signe-tete h2 { font-size: 1.02rem; margin: 0; }
.signe-periode { margin: 2px 0 0; font-size: .8125rem; color: var(--discret); }
.signe-texte { margin: 0; color: var(--encre); font-size: .94rem; }

/* ── L'éphéméride ────────────────────────────────────────────────────────── */

/* Ce que la V3 mettait en or — la fête, la date d'un événement, l'âge d'une
   personnalité — prend ici le dégradé de la charte. Même geste, même place :
   l'œil de l'équipe retrouve ce qu'il cherchait, le public voit la charte. */
.jour-dore {
  background: var(--degrade);
  -webkit-background-clip: text; background-clip: text; color: transparent;
  font-weight: 700;
}
.jour-une {
  display: grid; gap: var(--e2);
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.jour-bloc {
  display: flex; flex-direction: column; gap: var(--e1);
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
}
.jour-bloc .jour-quoi { margin-bottom: 0; }
.jour-fete-phrase {
  margin: 0 0 var(--e1);
  font-size: 1.35rem; line-height: 1.3; color: var(--encre-fort); text-wrap: balance;
}
.jour-rien { margin: 0 0 var(--e1); color: var(--discret); }
.jour-journees { margin: 0; padding-left: 1.1rem; display: grid; gap: 4px; color: var(--encre); }
.jour-journees li::marker { color: var(--primaire-lisible); }
a.jour-question { color: inherit; text-decoration: none; transition: border-color var(--vite); }
a.jour-question:hover { border-color: var(--trait-fort); }
.jour-question-texte {
  margin: 0; font-size: 1.12rem; font-weight: 600; line-height: 1.4;
  color: var(--encre-fort); text-wrap: balance;
}
.jour-lien { margin-top: auto; font-size: .84rem; font-weight: 600; color: var(--primaire-lisible); }
.jour-compte {
  min-width: 26px; padding: 2px 8px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); background: var(--voile);
  font-size: .8125rem; font-weight: 600; color: var(--discret); text-align: center;
  font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
}

/* La pastille : « il y a 52 ans », « 67 ans », « À l'antenne aujourd'hui ».
   Ce qu'un animateur lit tel quel, donc ce qui doit sauter aux yeux. */
.jour-badge {
  display: inline-flex; align-items: center; align-self: flex-start;
  padding: 3px 10px; border-radius: var(--rond);
  background: rgba(var(--accent-canaux), .14); color: var(--accent-lisible);
  font-size: .8125rem; font-weight: 600; white-space: nowrap;
  font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
}
.jour-badge.plein { background: var(--degrade); color: var(--sur-primaire); }
.jour-badge.antenne { background: rgba(var(--secondaire-canaux), .16); color: var(--secondaire-lisible); }

/* La frise : la date à gauche, le fait à droite, un filet entre les deux.
   Les chiffres sont tabulaires — sans cela les années dansent d'une ligne à
   l'autre et la colonne cesse d'être une colonne. */
/* Le pied de page du plan d'intégration n'a pas de marge — l'accueil est
   réglé au pixel près. Chaque page finit donc par la sienne : sans elle, le
   dernier bloc touche le pied. */
.frise { list-style: none; margin: 0 0 var(--e5); padding: 0; }
.frise-ligne {
  display: grid; grid-template-columns: 210px minmax(0, 1fr);
  gap: var(--e3); align-items: baseline;
  padding: 14px 0;
  border-top: 1px solid var(--trait);
}
.frise-ligne:first-child { border-top: 0; }
.frise-date { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.frise-date strong { font-size: 1rem; line-height: 1.3; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; }
.frise-texte { margin: 0; color: var(--encre); }

/* En bref : une puce par personne, les fiches retenues pour l'antenne en
   couleur — la mise en avant de la V3. */
.jour-bref { margin: var(--e5) 0; }
.jour-bref .jour-titre { margin-top: 0; }
/* Le titre garde son filet jusqu'au lien : même ligne, même hauteur. */
.jour-bref-tete {
  display: flex; align-items: center; gap: var(--e2);
  margin-bottom: var(--e2);
}
.jour-bref-tete .jour-titre { flex: 1; margin: 0; }
.jour-puces { display: flex; flex-wrap: wrap; gap: 8px; }
.jour-puce {
  padding: 6px 14px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); background: var(--surface);
  font-size: .84rem; color: var(--encre); text-decoration: none;
}
a.jour-puce { transition: border-color var(--vite); }
a.jour-puce:hover { border-color: var(--primaire-lisible); }
.jour-puce.retenu {
  border-color: transparent; background: var(--degrade);
  color: var(--sur-primaire); font-weight: 600;
}

/* ── Les anniversaires ───────────────────────────────────────────────────── */

/* Des fiches sur trois colonnes, un portrait rond : la page de la V3, dans la
   charte du site. */
.annivs {
  display: grid; gap: var(--e2);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  margin-bottom: var(--e5);
}
.anniv {
  display: flex; gap: var(--e2); align-items: flex-start;
  padding: var(--e3);
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
}
/* Retenue pour l'antenne : le liseré prend le dégradé. Un fond en dégradé
   noierait le texte ; deux fonds superposés — la surface à l'intérieur, le
   dégradé sous la bordure — gardent la fiche lisible. */
.anniv.retenu {
  border-color: transparent;
  background: linear-gradient(var(--surface), var(--surface)) padding-box,
              var(--degrade) border-box;
  box-shadow: var(--lueur-p);
}
.anniv-portrait {
  flex: none; width: 84px; height: 84px; border-radius: 50%;
  object-fit: cover; display: block;
  border: 2px solid var(--trait-fort);
}
.anniv-portrait.sans {
  display: grid; place-items: center; border: 0;
  font-size: 1.6rem; font-weight: 700;
  background: var(--degrade); color: var(--sur-primaire);
}
.anniv-corps { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.anniv-tete { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.anniv-tete h2 { margin: 0; font-size: 1.05rem; line-height: 1.3; color: var(--encre-fort); }
.anniv-meta { margin: 0; font-size: .84rem; color: var(--discret); }
.anniv-note { margin: 4px 0 0; font-size: .88rem; color: var(--encre); }

/* ── La question du jour ─────────────────────────────────────────────────── */

.question-carte {
  display: grid; gap: 0;
  grid-template-columns: minmax(0, 1fr);
  border: 1px solid var(--trait); border-radius: var(--r4);
  background: var(--surface); overflow: hidden;
  max-width: 760px;
}
.question-carte:has(.question-image) { grid-template-columns: 300px minmax(0, 1fr); }
.question-image { width: 100%; height: 100%; object-fit: cover; display: block; }
.question-corps { padding: var(--e4); }
.question-texte {
  margin: 0 0 var(--e3);
  font-size: 1.4rem; font-weight: 600; line-height: 1.35;
  color: var(--encre-fort); text-wrap: balance;
}
.question-pied {
  margin: 0; font-size: .84rem; color: var(--discret);
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
}
/* Le bouton d'écoute au fil du texte : il commande la même chose que la
   barre du bas, il ne doit pas peser comme un bouton de formulaire. */
.lien-ecouter {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: var(--primaire-lisible); font-weight: 600;
}
.lien-ecouter:hover { text-decoration: underline; }

@media (max-width: 720px) {
  .question-carte:has(.question-image) { grid-template-columns: minmax(0, 1fr); }
  .question-image { max-height: 220px; }
  .frise-ligne { grid-template-columns: 1fr; gap: 4px; }
  .frise-date { flex-direction: row; align-items: center; flex-wrap: wrap; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA GRILLE DU PLAN D'INTÉGRATION — repère 1440 × 1080
   ═══════════════════════════════════════════════════════════════════════════

   Toutes les mesures viennent du document de spécifications :

     marge extérieure   24 px
     colonne de gauche  24 → 272          (248 de large)
     contenu principal  272 → 1200        (928 de large)
     rail de droite     1212 → 1416       (204, dans une piste de 216)
     navbar             y 44,  h 52
     hero               y 96,  h 374
     cartes du milieu   y 487, h 198
     dernières actus    y 711, h 200      (ajoutées le 2026-09-11)
     cartes du bas      y 937, h 140      (711 au plan d'origine)
     bande du pied      y 1099, h 86      (873)
     pied               y 1185, h 97      (959)

   À 1440 px, la page est donc au pixel près. En dessous, les colonnes se
   replient : un site ne peut pas exiger un écran précis, et la moitié des
   auditeurs d'une radio arrivent d'un téléphone.                             */

.cadre {
  max-width: 1440px;
  margin: 0 auto;
  padding: 24px;
}

/* La rangée de titre : 24 → 44, soit 20 px de haut. */
.titre-site {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e2); height: 20px;
}
.marque-titre {
  font-size: 1.05rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; line-height: 1;
  background: var(--degrade);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* La navbar : y 44, h 52. */
.navbar {
  display: flex; align-items: center; gap: var(--e2);
  height: 52px;
  border-bottom: 1px solid var(--trait);
}
.on-air {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  padding: 6px 13px; border-radius: var(--rond);
  background: rgba(239, 68, 68, .14); border: 1px solid var(--direct);
  color: var(--direct);
  font-size: .8125rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase;
}
.on-air i {
  width: 6px; height: 6px; border-radius: 50%; background: var(--direct);
  animation: pouls 2s ease-in-out infinite;
}
.navbar .nav { flex: 1; }
.navbar .ecouter { flex: none; }

/* Le corps : trois pistes de largeur fixe, comme au plan. */
.corps {
  display: grid;
  grid-template-columns: 248px minmax(0, 928px);
  align-items: start;
}
.corps > .page { padding: 0; max-width: 100%; min-width: 0; }
.cadre.avec-rail .corps { grid-template-columns: 248px minmax(0, 928px) 216px; }
.cadre.avec-rail .rail { padding-left: 12px; }   /* 1212, pas 1200 */

/* ── La colonne de gauche ────────────────────────────────────────────────── */

.lateral {
  padding: var(--e3) var(--e2) 0 0;
  display: flex; flex-direction: column; gap: var(--e2);
}
.lateral-surtitre {
  font-size: .8125rem; font-weight: 600; letter-spacing: .2em;
  text-transform: uppercase; color: var(--discret); line-height: 1.7;
}
.lateral-marque img { max-width: 180px; height: auto; }
.lateral-marque .marque-nom { font-size: 1.35rem; }
.lateral-slogan {
  font-size: .88rem; font-weight: 600;
  background: var(--degrade-doux);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.lateral-menu { display: flex; flex-direction: column; gap: 2px; margin-top: var(--e2); }
.lateral-menu a {
  display: flex; align-items: center; gap: 11px;
  padding: 9px 13px; border-radius: var(--r1);
  color: var(--encre); font-size: .87rem; font-weight: 500;
  transition: background var(--vite), color var(--vite);
}
.lateral-menu a:hover { background: var(--voile); color: var(--encre-fort); }
/* La rubrique ouverte porte le dégradé : c'est le seul aplat coloré de la
   colonne, donc on la trouve sans lire. */
.lateral-menu a.actif {
  background: var(--degrade); color: var(--sur-primaire); font-weight: 600;
  box-shadow: var(--lueur-p);
}
.lateral-menu svg { flex: none; }

/* ── Le hero : y 96, h 374 ───────────────────────────────────────────────── */

.hero {
  position: relative; overflow: hidden;
  height: 374px;
  padding: 40px;
  margin: 0 0 17px;                    /* 470 → 487 */
  border: 1px solid var(--trait); border-radius: var(--r4);
  background:
    radial-gradient(620px 340px at 12% 88%, rgba(var(--primaire-canaux), .16), transparent 62%),
    linear-gradient(150deg, var(--surface-haute), var(--fond-profond));
}

/* LE VISUEL EST LE FOND DU BLOC ENTIER
   Il remplit les 928 × 374 du plan, et le slogan s'écrit dessus. Pas de voile
   par-dessus : les visuels sont préparés avec la place du texte, et un
   dégradé ternissait toute l'image. Une ombre légère détache le texte. */
.hero.avec-visuel {
  background: var(--hero) center / cover no-repeat, var(--fond-profond);
}
.hero.avec-visuel .hero-texte h1, .hero.avec-visuel .hero-phrase { text-shadow: 0 1px 14px rgba(0, 0, 0, .6); }

/* Le texte occupe la moitié gauche — celle que les visuels lui laissent — et
   se centre dans la hauteur : sans le sur-titre et sans la rangée de mots-clés
   qui l'encadraient, un bloc calé en haut laissait un vide sous les boutons. */
.hero-texte {
  position: relative; z-index: 1;
  max-width: 47%;
  display: flex; flex-direction: column; justify-content: center;
  height: 100%;
}
.hero h1 { font-size: 2.6rem; }
.hero-phrase { margin: 14px 0 18px; font-size: .98rem; }

/* L'émission en cours, posée sur le voile du hero. Une pastille, pas une
   carte : elle vit entre le slogan et le bouton, et tout ce qui l'alourdirait
   éloignerait l'un de l'autre. */
.hero-emission {
  display: inline-flex; align-items: center; gap: 12px;
  align-self: flex-start; max-width: 100%;
  margin: 0 0 18px; padding: 8px 16px 8px 8px;
  border: 1px solid var(--trait-fort); border-radius: var(--rond);
  background: rgba(6, 9, 17, .62);
  text-decoration: none; min-width: 0;
  transition: border-color var(--vite), background var(--vite);
}
.hero-emission:hover {
  border-color: var(--primaire-lisible);
  background: rgba(6, 9, 17, .82);
}
.hero-emission-image {
  width: 46px; height: 46px; flex: none;
  border-radius: 50%; object-fit: cover;
  background: var(--surface-haute);
}
.hero-emission-image.sans {
  display: grid; place-items: center;
  font-size: 1.2rem; font-weight: 700; color: var(--encre-fort);
  background: var(--degrade-doux);
}
.hero-emission-mots { display: flex; flex-direction: column; min-width: 0; }
.hero-emission-quoi {
  font-size: .8125rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--direct);
}
.hero-emission-mots strong {
  font-size: .95rem; color: var(--encre-fort); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.hero-emission-quand {
  font-size: .8125rem; color: var(--discret);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ── Les deux rangées de cartes ──────────────────────────────────────────── */

.trois {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  height: 198px;                       /* y 487 → 685 */
  margin: 0 0 26px;                    /* 685 → 711 */
}
/* PAS 50/50 : le plan place les quatre emissions de x 290 a 822 et les trois
   podcasts de 854 a 1162. Les blocs valent donc 566 et 354, pas la moitie
   chacun — c'est ce qui donne aux emissions des vignettes de 126 px et aux
   podcasts des vignettes de 96, comme au tableau des assets. */
.deux {
  grid-template-columns: minmax(0, 566fr) minmax(0, 354fr);
  gap: 8px;
  height: 140px;                       /* y 937 → 1077 */
  margin: 0 0 22px;                    /* 1077 → 1099 */
}
/* LES DERNIÈRES ACTUS, ajoutées au plan le 2026-09-11 à la demande de la
   radio : une rangée entre le direct et les émissions, cinq vignettes. Trois
   étages — la rubrique, la photo, le titre sur deux lignes — d'où 200 px et non
   140 : le titre posé sur la photo en masquait trop (retour de la radio,
   2026-09-12), et à 180 il se faisait couper. Tout ce qui suit descend de
   200 + 26. Moins de cinq actus : elles se partagent la largeur plutôt que de
   laisser des cases vides. */
.rangee-actus {
  height: 200px;                       /* y 711 → 911 */
  margin: 0 0 26px;                    /* 911 → 937 */
}
.rangee-actus .cartes.serrees { grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr)); gap: 9px; }
.trois > .bloc, .deux > .bloc, .rangee-actus > .bloc {
  height: 100%; overflow: hidden;
  display: flex; flex-direction: column;
  padding: 12px 14px;
}
.trois .liste, .deux .cartes, .rangee-actus .cartes { overflow: hidden; }
.trois .bloc-tete, .deux .bloc-tete, .rangee-actus .bloc-tete { margin-bottom: 8px; }
.trois .bloc-tete h2, .deux .bloc-tete h2, .rangee-actus .bloc-tete h2 { font-size: .8125rem; }
.trois .ligne { padding: 5px 0; }
.trois .ligne-pochette { width: 30px; height: 30px; }
.trois .ligne-titre { font-size: .8125rem; }
.trois .ligne-artiste { font-size: .8125rem; }
.trois .rang { width: 18px; font-size: .85rem; }
.trois .ligne-heure.devant { width: 32px; font-size: .8125rem; }
.trois .ligne-passages { font-size: .8125rem; }

.direct-bloc .direct-pochette { width: 76px; height: 76px; }
.direct-bloc .titre-sans-pochette.direct-pochette { font-size: 1.8rem; }
.direct-bloc .direct-titre { font-size: .98rem; }
.direct-bloc .direct-artiste { font-size: .84rem; }
.direct-bloc .spectre { height: 18px; margin-top: 7px; }
.direct-bloc .direct-album { font-size: .8125rem; }

/* Les cartes des rangées basses : quatre émissions, trois podcasts, tenues
   dans 140 px de haut. Les visuels font 126 × 118 et 96 × 118 au plan. */
.deux .cartes.serrees { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 9px; }
.deux .bloc:last-child .cartes.serrees { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Le texte se pose SUR l'image, pas en dessous : le plan donne 118 px de
   visuel dans une rangee de 140, il n'y a pas la place pour deux blocs. C'est
   aussi ce que montre la maquette — un voile sombre en bas de la vignette, et
   le titre dessus. */
.deux .carte { position: relative; display: block; }
.deux .carte-image { width: 100%; height: 118px; aspect-ratio: auto; }
.deux .carte-corps {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px 8px 7px;
  background: linear-gradient(180deg, transparent, rgba(6, 9, 17, .93) 58%);
}
.deux .carte-corps h3 {
  font-size: .8125rem; line-height: 1.2; letter-spacing: -.01em;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical;
}
.deux .carte-corps p {
  font-size: .8125rem; margin: 1px 0 0; color: var(--primaire-lisible);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.deux .carte-corps p + p { color: var(--discret); }
/* Sur une vignette de 96 px, le nom de l'emission mange la duree. La fiche du
   podcast le porte deja. */
.deux .carte-source { display: none; }
/* LES VIGNETTES DES ACTUS : la rubrique, la photo, le titre — chacun son
   étage. Les émissions posent leur titre sur l'image parce qu'elles n'ont que
   140 px ; une actu, elle, se reconnaît à sa photo, et un titre par-dessus en
   masquait trop. Le titre est une phrase : deux lignes, pas une.

   RIEN N'EST CALCULÉ EN PIXELS ICI : le titre prend ses trois lignes, la PHOTO
   prend ce qui reste. Compter les marges à la main marchait jusqu'au premier
   titre un peu plus long, dont la dernière ligne passait sous le bas de la
   carte — que `overflow: hidden` taille net.

   La rubrique est posée en bas à droite de la photo, et non sur une ligne à
   elle : elle ne coûte alors aucune hauteur, et le titre gagne la place de
   dire de quoi l'actu parle — c'est lui qui donne envie de cliquer. */
.rangee-actus .carte { display: flex; flex-direction: column; padding: 6px; }
.rangee-actus .carte-visuel {
  position: relative; display: block;
  flex: 1 1 auto; min-height: 0;
}
.rangee-actus .carte-etiquette {
  top: auto; left: auto; right: 6px; bottom: 6px;
  padding: 2px 7px; font-size: .8125rem; letter-spacing: .08em;
}
.rangee-actus .carte-image {
  width: 100%; height: 100%; aspect-ratio: auto;
  border-radius: 6px; object-fit: cover;
}
.rangee-actus .carte-image.sans { background: var(--degrade-doux); }
.rangee-actus .carte-corps { flex: none; padding: 5px 2px 0; }
.rangee-actus .carte-corps h3 {
  /* Trois lignes réservées, même pour un titre court : sans cela, sa photo
     serait plus haute que celle d'à côté et les vignettes ne s'aligneraient
     plus. Plus petit que les cartes des émissions, pour en dire plus. */
  margin: 0; min-height: 3.75em;
  font-size: .8125rem; line-height: 1.25; letter-spacing: -.01em;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}

/* ── Le rail de droite ───────────────────────────────────────────────────── */

/* Les y du plan : image 1 de 128 a 380, image 2 de 399 a 717, image 3 de 742
   a 1026. Le rail commence a 96 — les 32 px suivants portent le surtitre. */
.rail { display: flex; flex-direction: column; gap: 19px; }
.rail-carte { position: relative; }
.rail-surtitre {
  height: 32px;                        /* 96 → 128 */
  font-size: .8125rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--encre-fort); line-height: 1.35;
}
/* Le slogan se pose SUR l'image, comme sur la maquette : le rail n'a pas
   32 px a lui donner en plus. */
.rail-slogan {
  position: absolute; left: 10px; right: 10px; top: 40px; z-index: 1;
  font-size: .8125rem; font-weight: 600; line-height: 1.3;
  color: var(--encre-fort); text-shadow: 0 2px 12px rgba(0, 0, 0, .9);
}
.rail-image {
  width: 100%; object-fit: cover; display: block;
  border: 1px solid var(--trait); border-radius: var(--r2);
}
/* Les hauteurs du plan : 252, 318, 284. */
.rail-image.experience { height: 252px; }
.rail-image.casque { height: 318px; }
.rail-image.micro { height: 284px; }

/* La légende se pose SUR l'image, comme le slogan de la première carte. En
   dessous, elle ajoutait 88 px à une colonne dont le plan fixe la fin à 1026 :
   le rail dépassait le pied de page de la colonne principale. */
.rail-legende {
  position: absolute; left: 10px; right: 10px; bottom: 8px; z-index: 1;
  font-size: .8125rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--encre-fort); line-height: 1.5;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .95);
}
/* Pas de voile sur les bandeaux du rail non plus : leurs images sont préparées
   avec la place de la légende, et l'ombre du texte suffit. */

/* ── Les deux rangées du pied ────────────────────────────────────────────── */

.bande {
  height: 86px; margin: 0;             /* y 1099 → 1185 */
  padding: 0 var(--e3);
  border-radius: var(--r3);
}
.bande-slogan {
  font-size: .9rem; font-weight: 600; white-space: nowrap;
  background: var(--degrade-doux);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.reseaux-mot {
  font-size: .8125rem; font-weight: 700; letter-spacing: .18em;
  text-transform: uppercase; color: var(--discret); margin-right: 4px;
}
.reseau { width: 34px; height: 34px; }

.pied {
  display: flex; align-items: center; gap: var(--e3); flex-wrap: wrap;
  height: 97px; margin: 0; padding: 0 var(--e3);   /* y 1185 → 1282 */
  border-top: 1px solid var(--trait); background: transparent;
}
.pied .pied-marque { flex: none; }
.pied .pied-liens {
  flex: 1; flex-direction: row; flex-wrap: wrap; gap: var(--e2);
}
.pied-mention { font-size: .8125rem; color: var(--discret); white-space: nowrap; }

/* ── Ce qui se replie ────────────────────────────────────────────────────── */

@media (max-width: 1380px) {
  /* Le rail part le premier : ce sont trois images, pas du contenu. */
  .cadre.avec-rail .corps { grid-template-columns: 248px minmax(0, 1fr); }
  .rail { display: none; }
  .corps { grid-template-columns: 248px minmax(0, 1fr); }
  .hero, .trois, .deux, .rangee-actus { height: auto; }
  .deux .carte-image { aspect-ratio: 16 / 10; }
  /* La rangée n'a plus de hauteur fixe : sans proportion donnée ici, le cadre
     de la photo n'aurait aucune hauteur à remplir et la photo disparaîtrait. */
  .rangee-actus .carte-visuel { aspect-ratio: 16 / 10; }
}

@media (max-width: 1080px) {
  .trois { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trois .direct-bloc { grid-column: 1 / -1; }
  .deux { grid-template-columns: 1fr; }
  .deux .bloc:last-child .cartes.serrees { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .hero-texte { max-width: 100%; }
  .navbar .nav { display: none; }        /* la colonne de gauche la porte déjà */
}

@media (max-width: 820px) {
  /* La colonne de gauche devient une rangée : sur un téléphone, une colonne
     de 248 px ne laisse rien au contenu. */
  /* minmax(0, …) et non 1fr : une colonne « 1fr » ne descend pas sous la
     largeur de son contenu le plus large — la rangée d'icônes du menu élargissait
     la page au-delà de l'écran (défilement horizontal à 390 px, vu le 29/09). */
  .corps, .cadre.avec-rail .corps { grid-template-columns: minmax(0, 1fr); }
  .lateral { padding: 0 0 var(--e3); min-width: 0; }
  .lateral-menu { flex-direction: row; overflow-x: auto; gap: 4px; max-width: 100%; scrollbar-width: none; }
  .lateral-menu a { white-space: nowrap; }
  .lateral-menu span { display: none; }
  .lateral-menu a.actif span { display: inline; }
  /* Un groupe ouvert (Radio, Participer) garde ses entrées DANS la rangée,
     à la suite de son icône, au lieu de les empiler en colonne. */
  .lateral-menu .lateral-groupe { flex: none; }
  .lateral-menu .lateral-groupe[open] { display: flex; align-items: center; gap: 4px; }
  .lateral-menu .lateral-groupe[open]::details-content { display: contents; }
  .lateral-menu .lateral-groupe summary { white-space: nowrap; }
  .lateral-menu .lateral-groupe a.enfant { padding-left: 13px; }
  .lateral-fleche { display: none; }
  .cadre { padding: 16px; }
  .trois { grid-template-columns: 1fr; }
  .deux .cartes.serrees,
  .deux .bloc:last-child .cartes.serrees { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Cinq actus sur deux colonnes en laisseraient une seule : elles défilent
     au pouce, la suivante dépasse pour dire qu'il y en a d'autres. */
  .rangee-actus .cartes.serrees {
    grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: 44%;
    overflow-x: auto; scroll-snap-type: x mandatory;
  }
  .rangee-actus .carte { scroll-snap-align: start; }
  .bande, .pied { height: auto; padding: var(--e3) var(--e2); }
  .titre-site { height: auto; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Le sondage musical (sondage.php) — des cibles de 44 px : on vote au pouce
   ═══════════════════════════════════════════════════════════════════════════ */

.sondage-extraits {
  list-style: none; margin: 0 0 var(--e3); padding: 0;
  display: grid; gap: var(--e2);
}
.sondage-extrait {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--e2) var(--e3);
  min-width: 0;
  align-items: center;
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); padding: var(--e2) var(--e3);
}
.sondage-ecouter {
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid var(--trait-fort); background: var(--surface-haute);
  color: var(--encre-fort); font-size: 1.05rem; cursor: pointer;
}
.sondage-ecouter:hover, .sondage-ecouter.joue { border-color: var(--accent); color: var(--accent); }
.sondage-ecouter:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.sondage-quoi { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.sondage-quoi strong { color: var(--encre-fort); }
.sondage-quoi span { color: var(--discret); }
.sondage-num {
  font-size: .8125rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--discret);
}
/* Un fieldset refuse par défaut de rétrécir sous son contenu : sur un téléphone,
   il élargissait toute la colonne et la page débordait à droite. */
.sondage-notes {
  grid-column: 1 / -1; border: 0; margin: 0; padding: 0; min-width: 0;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px;
}
.sondage-note { position: relative; min-width: 0; }
.sondage-note input { position: absolute; opacity: 0; pointer-events: none; }
.sondage-note span {
  display: flex; align-items: center; justify-content: center;
  min-height: 44px; padding: 6px; text-align: center;
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--fond-profond); color: var(--encre-fort); cursor: pointer;
}
.sondage-note input:checked + span {
  border-color: var(--accent); background: var(--surface-haute);
  color: var(--accent); font-weight: 700;
}
.sondage-note input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.sondage-sature { grid-column: 1 / -1; font-size: .92rem; color: var(--discret); }
.sondage-cache, .sondage-piege {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
.sondage-rgpd { color: var(--discret); font-size: .9rem; }
.sondage-envoyer {
  min-height: 48px; padding: 0 var(--e4); border: 0; border-radius: 999px;
  background: var(--accent); color: var(--fond-profond);
  font-weight: 700; font-size: 1rem; cursor: pointer;
}
.sondage-envoyer:focus-visible { outline: 2px solid var(--encre-fort); outline-offset: 3px; }
.sondage-merci, .sondage-refus {
  border: 1px solid var(--trait-fort); border-radius: var(--r3);
  background: var(--surface); padding: var(--e2) var(--e3); margin-bottom: var(--e3);
}
.sondage-merci { border-color: var(--accent); }
@media (max-width: 560px) {
  .sondage-notes { grid-template-columns: repeat(2, 1fr); }
}

/* ── Le rail pendant un sondage musical : la première carte invite à voter ──
   Le texte se pose SUR le visuel, en bas, comme la légende de la troisième
   carte : les hauteurs du plan ne bougent pas. */
.rail-sondage { display: block; color: inherit; text-decoration: none; }
.rail-sondage:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: var(--r2); }
.rail-sondage-titre {
  display: block; margin-bottom: 2px;
  font-size: 1.05rem; font-weight: 800; letter-spacing: .02em; color: var(--accent);
}
.rail-sondage-appel {
  position: absolute; left: 10px; right: 10px; bottom: 10px; z-index: 1;
  display: flex; flex-direction: column; align-items: flex-start; gap: 8px;
  font-size: .8125rem; font-weight: 700; line-height: 1.3;
  color: var(--encre-fort); text-shadow: 0 2px 12px rgba(0, 0, 0, .95);
}
.rail-sondage-bouton {
  padding: 6px 14px; border-radius: 999px;
  background: var(--accent); color: var(--fond-profond); text-shadow: none;
  font-size: .8125rem; letter-spacing: .03em;
  transition: transform var(--vite);
}
.rail-sondage:hover .rail-sondage-bouton { transform: translateX(3px); }

/* La source d'un article venu de la veille musicale. */
.article-source { margin-top: var(--e3); color: var(--discret); font-size: .9rem; }
.article-source a { color: var(--accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   Le direct en vidéo
   ═══════════════════════════════════════════════════════════════════════════
   Le panneau est ancré en bas à droite, au-dessus de la barre du lecteur : on
   regarde en continuant à parcourir le site, ce qui est tout l'intérêt de
   l'avoir sorti du cadre. Sur un téléphone il prend la largeur — une vignette
   de 420 px sur un écran de 390 ne montre rien. */

.lecteur-video {
  flex: none; display: inline-flex; align-items: center; gap: var(--e1);
  padding: 9px 16px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); background: transparent;
  color: var(--encre); font: inherit; font-size: .82rem; cursor: pointer;
  transition: border-color var(--vite), color var(--vite), background var(--vite);
}
.lecteur-video:hover { border-color: var(--primaire); color: var(--encre-fort); }
.lecteur-video[aria-pressed="true"] {
  border-color: var(--primaire); background: var(--primaire);
  color: var(--fond-profond);
}

/* Une caméra, dessinée — un corps et son objectif. Comme les deux formes du
   bouton de lecture, elle ne vaut pas une bibliothèque d'icônes. */
.ico-video {
  position: relative; flex: none;
  width: 15px; height: 11px; border-radius: 2px; background: currentColor;
}
.ico-video::after {
  content: ''; position: absolute; top: 1px; left: 100%;
  border-left: 6px solid currentColor;
  border-top: 4.5px solid transparent;
  border-bottom: 4.5px solid transparent;
}

.video-direct {
  position: fixed; right: var(--e3); bottom: 120px; z-index: 60;
  width: min(420px, calc(100vw - 2 * var(--e3)));
  background: var(--fond-profond);
  border: 1px solid var(--trait-fort); border-radius: var(--r2);
  box-shadow: var(--ombre-haute);
  overflow: hidden;
}
/* Sans barre de lecteur (radio sans flux audio), le panneau descend. */
body:not(.avec-lecteur) .video-direct { bottom: var(--e3); }

.video-barre {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--e2); padding: 8px 8px 8px 14px;
  border-bottom: 1px solid var(--trait);
}
.video-etat {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .8125rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--direct);
}
.video-etat i {
  width: 7px; height: 7px; border-radius: 50%;
  background: currentColor; flex: none;
}
.video-fermer {
  flex: none; width: 30px; height: 30px; border-radius: var(--r1);
  border: 0; background: transparent; color: var(--discret);
  font-size: .8125rem; line-height: 1; cursor: pointer;
  transition: background var(--vite), color var(--vite);
}
.video-fermer:hover { background: var(--voile); color: var(--encre-fort); }

/* 16/9 tenu par le rapport d'aspect : la hauteur suit la largeur, et le script
   n'a aucun calcul à refaire au redimensionnement. */
.video-cadre { position: relative; aspect-ratio: 16 / 9; background: #000; }
.video-cadre iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

@media (max-width: 640px) {
  .video-direct {
    right: 0; left: 0; bottom: 92px; width: auto;
    border-radius: 0; border-left: 0; border-right: 0;
  }
  /* Le libellé s'efface avant le reste : sur un téléphone, la barre porte
     déjà le titre en cours et la place manque. */
  .lecteur-video .regarder-texte { display: none; }
  .lecteur-video { padding: 9px 12px; }
}

/* « Regarder » dans l'en-tête : le pendant d'« Écouter en direct », en second
   rôle. Même forme, mais contour plutôt que dégradé — il y a un seul geste
   principal sur cette barre, et c'est d'écouter. */
.regarder-entete {
  display: inline-flex; align-items: center; gap: var(--e1);
  padding: 10px 18px; border-radius: var(--rond);
  border: 1px solid var(--trait-fort); background: transparent;
  color: var(--encre); font: inherit; font-weight: 600; font-size: .9rem;
  cursor: pointer; white-space: nowrap;
  transition: border-color var(--vite), color var(--vite), background var(--vite);
}
.regarder-entete:hover { border-color: var(--primaire); color: var(--encre-fort); }
.regarder-entete[aria-pressed="true"] {
  border-color: var(--primaire); background: var(--primaire);
  color: var(--fond-profond);
}

/* Le chemin de secours quand la plateforme refuse le cadre embarqué. */
.video-ailleurs {
  margin-left: auto; margin-right: var(--e1);
  font-size: .8125rem; letter-spacing: .04em; text-transform: uppercase;
  color: var(--discret); text-decoration: none; white-space: nowrap;
}
.video-ailleurs:hover { color: var(--encre-fort); text-decoration: underline; }

@media (max-width: 900px) {
  /* Sous cette largeur la navbar est déjà serrée : le libellé s'efface, pas
     le bouton. */
  .regarder-entete .regarder-texte { display: none; }
  .regarder-entete { padding: 10px 14px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   L'espace auditeurs — dédicaces, jeux, mes données, notifications, état
   (29/09/2026). Les composants sont les communs (formulaire, champ, message,
   bouton) ; ceci n'ajoute que la mise en page propre aux pages publiques.
   ═══════════════════════════════════════════════════════════════════════════ */

.formulaire-public { max-width: 760px; margin-bottom: var(--e4); }
.formulaire.sans-cadre { border: 0; padding: 0; background: none; }
.formulaire-public .bouton, .panneau .bouton { min-height: 44px; }
.formulaire-public .sous, .panneau .sous { margin: 0; max-width: none; }

.groupe-cases { border: 0; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--e1); }
.groupe-cases legend {
  padding: 0; margin-bottom: var(--e1);
  font-size: .8125rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--discret);
}
.case-ligne {
  display: flex; align-items: flex-start; gap: 10px; cursor: pointer;
  font-size: .95rem; color: var(--encre); line-height: 1.5;
}
.case-ligne input { flex: none; width: 20px; height: 20px; margin-top: 2px; accent-color: var(--primaire); }
.case-ligne small { display: block; color: var(--discret); font-size: .8125rem; }
/* Dans un champ, une case se lit comme une phrase, pas comme une étiquette. */
.champ .case-ligne, .champ.case-ligne {
  text-transform: none; letter-spacing: 0; font-size: .95rem; font-weight: 400; color: var(--encre);
}

.bouton-2.petit { padding: 8px 16px; font-size: .875rem; }
.bloc-tete { display: flex; align-items: center; justify-content: space-between; gap: var(--e2); flex-wrap: wrap; }
.envoi { display: inline; margin: 0; }

.rss-abonner { margin: 0 0 var(--e3); font-size: .95rem; }
.rss-abonner small { color: var(--discret); margin-left: var(--e1); font-size: .8125rem; }

/* L'état du service : une ligne par service, une pastille de couleur ET un mot. */
.etat-services { display: grid; gap: var(--e2); margin-bottom: var(--e4); }
.etat-service {
  display: flex; align-items: center; gap: var(--e2); flex-wrap: wrap;
  padding: var(--e2) var(--e3); border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface);
}
.etat-service > div { flex: 1; min-width: 200px; display: flex; flex-direction: column; }
.etat-service strong { color: var(--encre-fort); }
.etat-service span { color: var(--encre); font-size: .9rem; }
.etat-service small { color: var(--discret); font-size: .8125rem; font-family: var(--police-chiffres); }
.etat-pastille { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--discret); }
.etat-ok .etat-pastille { background: var(--ok-encre); }
.etat-doute .etat-pastille { background: var(--veille-encre); }
.etat-panne .etat-pastille { background: var(--erreur-encre); }
.etat-incidents .ligne { grid-template-columns: auto 1fr; }

.notifications .actions { margin: var(--e2) 0; }
.notifications-etat { margin: 0 0 var(--e2); color: var(--encre-fort); font-weight: 500; }

@media (max-width: 640px) {
  .formulaire-public { padding: var(--e2); }
  .formulaire-public .bouton { width: 100%; justify-content: center; }
}

/* Le lien de l'artiste en cours, et sa carte « À propos de l'artiste » (direct.php). */
.direct-artiste a {
  background: var(--degrade); -webkit-background-clip: text; background-clip: text;
  color: transparent; text-decoration: underline; text-decoration-color: var(--trait-fort);
  text-underline-offset: 4px;
}
/* Une carte par artiste à l'affiche : seule, elle prend la largeur ; deux
   (« Giorgio Moroder, Philip Oakey ») se mettent côte à côte dès qu'il y a la
   place, l'une sous l'autre au téléphone. */
.direct-fiches {
  display: grid; gap: var(--e2); margin: var(--e3) 0;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 360px), 1fr));
}
.direct-fiches[hidden] { display: none; }
/* La carte « À propos de l'artiste » : une vraie carte, pas une ligne. Une
   bordure de couleur à gauche, la photo À CÔTÉ du nom (au téléphone aussi),
   la bio sur trois lignes coupées proprement, et « Lire la suite » en forme
   de bouton vers la fiche. Une grille : la carte ne grandit jamais au-delà
   de ce qu'elle montre (18/10 : elle débordait sur la rangée des actus). */
.carte-artiste {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas: "photo tete" "photo bio" "photo suite";
  column-gap: var(--e3); row-gap: 8px; align-items: center; align-content: start;
  min-width: 0; padding: var(--e3);
  border: 1px solid var(--trait-fort); border-left: 4px solid var(--primaire-lisible);
  border-radius: var(--r3); background: var(--surface-haute, var(--surface));
  box-shadow: 0 6px 24px rgba(var(--primaire-canaux), .12);
  color: inherit; transition: border-color var(--vite), transform var(--doux), box-shadow var(--doux);
}
.carte-artiste:hover { border-color: var(--primaire-lisible); transform: translateY(-2px); box-shadow: 0 10px 30px rgba(var(--primaire-canaux), .2); }
.carte-artiste-photo {
  grid-area: photo; align-self: start;
  width: 96px; height: 96px; border-radius: 50%; object-fit: cover;
  display: flex; align-items: center; justify-content: center; background: var(--surface-2, var(--trait));
  border: 2px solid var(--trait-fort); font-weight: 700; font-size: 2rem; color: var(--encre-fort);
}
.carte-artiste-tete { grid-area: tete; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.carte-artiste-etiquette { font-size: .8125rem; text-transform: uppercase; letter-spacing: .08em; color: var(--primaire-lisible); font-weight: 600; }
.carte-artiste-tete strong { color: var(--encre-fort); font-size: 1.35rem; line-height: 1.2; overflow-wrap: anywhere; }
.carte-artiste-pays { color: var(--discret); font-size: .9rem; }
.carte-artiste-bio {
  grid-area: bio; min-width: 0;
  color: var(--encre); font-size: .95rem; line-height: 1.5;
  display: -webkit-box; -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.carte-artiste-suite {
  grid-area: suite; justify-self: start; padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--primaire-lisible); color: var(--primaire-lisible); font-size: .9rem; font-weight: 600;
}
.carte-artiste:hover .carte-artiste-suite { background: var(--primaire-lisible); color: var(--fond); }
/* L'accueil : une rangée à elle, sous les trois colonnes, aux marges du plan
   (26 px avant les actus) ; plus serrée que sur la page Direct. */
.direct-fiches.rangee-artiste { margin: 0 0 26px; gap: 12px; }
.rangee-artiste .carte-artiste { padding: 12px 16px; column-gap: 16px; row-gap: 6px; }
.rangee-artiste .carte-artiste-photo { width: 72px; height: 72px; font-size: 1.6rem; }
.rangee-artiste .carte-artiste-tete { gap: 2px; }
.rangee-artiste .carte-artiste-tete strong { font-size: 1.1rem; }
.rangee-artiste .carte-artiste-bio { font-size: .875rem; }
.rangee-artiste .carte-artiste-suite { padding: 4px 12px; font-size: .8125rem; }
@media (max-width: 640px) {
  /* Le téléphone : la photo reste à côté du nom, la bio passe dessous sur toute la largeur. */
  .carte-artiste, .rangee-artiste .carte-artiste {
    grid-template-areas: "photo tete" "bio bio" "suite suite";
    padding: var(--e2); column-gap: var(--e2);
  }
  .carte-artiste-photo, .rangee-artiste .carte-artiste-photo { width: 64px; height: 64px; font-size: 1.5rem; }
  .carte-artiste-tete strong, .rangee-artiste .carte-artiste-tete strong { font-size: 1.15rem; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   Les jeux publiés par Voxeo (18/10/2026) — les composants communs (fiche,
   cartes, étiquette, message) ; ceci n'ajoute que la mise en page des jeux.
   ═══════════════════════════════════════════════════════════════════════════ */

.jeu-section { margin-top: var(--e4); }
.jeu-dates { font-family: var(--police-chiffres); font-variant-numeric: tabular-nums; color: var(--discret); }
.jeu-dotations {
  display: grid; gap: var(--e2); list-style: none; padding: 0; margin: var(--e2) 0 0;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); align-items: start;
}
.jeu-dotation {
  border: 1px solid var(--trait); border-radius: var(--r3);
  background: var(--surface); overflow: hidden;
}
.jeu-dotation .carte-image { aspect-ratio: 4 / 3; }
.jeu-dotation p { margin: 0; padding: var(--e2); color: var(--encre-fort); font-weight: 600; }
.jeu-quantite { font-family: var(--police-chiffres); color: var(--primaire-lisible); margin-right: 6px; }
.jeu-participer { padding-left: var(--e3); max-width: 74ch; }
.jeu-participer li { margin: var(--e1) 0; }
.jeu-mentions {
  margin-top: var(--e4); padding-top: var(--e2); border-top: 1px solid var(--trait);
  color: var(--discret); font-size: .875rem; max-width: 74ch;
}
.jeu-mentions p { margin: 0 0 var(--e1); }
.reglement-texte { white-space: pre-line; max-width: 74ch; line-height: 1.6; }
.reglement-empreinte {
  font-family: var(--police-chiffres); font-size: .8125rem; word-break: break-all; color: var(--discret);
}
/* La valeur d'une dotation : seulement quand le jeu l'affiche (case de Voxeo). */
.jeu-dotation .jeu-valeur {
  padding-top: 0; font-family: var(--police-chiffres); font-variant-numeric: tabular-nums;
  font-weight: 500; color: var(--primaire-lisible);
}
/* L'information sur les données, sous le formulaire de participation et sur la fiche du gagnant. */
.jeu-rgpd { font-size: .875rem; color: var(--discret); max-width: 74ch; }
@media (max-width: 820px) {
  .jeu-fiche { grid-template-columns: minmax(0, 1fr); gap: var(--e3); }
}
