:root {
  --fond: #0f1117;
  --surface: #161a23;
  --surface-2: #1e2330;
  --trait: #2a3040;
  --texte: #eef1f6;
  --texte-2: #b4bccb;
  --attenue: #8690a3;
  --d: #3d84f5;
  --r: #e5484d;
  --i: #c99a1e;
  --vide: #3a4152;
  --d-pale: rgba(61, 132, 245, 0.16);
  --r-pale: rgba(229, 72, 77, 0.16);
  --i-pale: rgba(201, 154, 30, 0.18);
  /* Teinte du parti sortant sur les grosses tuiles : assez franche pour se lire de l'autre
     bout de la pièce. Ce qui distingue une course déclarée, ce n'est donc pas la force de la
     teinte, mais son contour coloré et sa barre de verdict en pleine couleur. */
  --d-sortant: rgba(61, 132, 245, 0.13);
  --r-sortant: rgba(229, 72, 77, 0.13);
  --i-sortant: rgba(201, 154, 30, 0.14);
  /* Les sept nuances de la carte, du bleu sûr au rouge sûr : « sûr » est foncé, « penche »
     est délavé, et la course à pile ou face est mauve. Ce sont les seules couleurs à changer
     entre le fond noir et le fond blanc, d'où les variables. */
  --n-d3: #1a4ea8;
  --n-d2: #2f6fc9;
  --n-d1: #5a86b8;
  --n-mauve: #6f5bab;
  --n-r1: #b87470;
  --n-r2: #d03a3f;
  --n-r3: #a81e22;
  --carte-vide: #242a38;
  --carte-trait: #4a5366;
  /* Bordure de chaque état. Sur fond noir, elle se confond avec la page : les états se
     détachent par leur couleur, pas par un trait. */
  --carte-bord: #0f1117;
  --bascule: #f5d90a;
  /* Ce qui est en cours ou en panne : le jaune des bascules sur fond noir, un orangé franc
     sur le fond blanc de la soirée, où le jaune ne se lit pas. */
  --encours: #f5d90a;
  --halo-nom: rgba(0, 0, 0, 0.6);
  --rayon: 10px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 16px/1.4 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2 { margin: 0; font-weight: 700; }
a { color: var(--texte-2); }
button { font: inherit; color: inherit; cursor: pointer; }

.attenue { color: var(--attenue); font-weight: 400; }
.parti-d { color: #7fb0ff; font-weight: 700; }
.parti-r { color: #ff8a8d; font-weight: 700; }
.parti-i { color: #e6bd4f; font-weight: 700; }
.parti-fond-d { background: var(--d); color: #fff; }
.parti-fond-r { background: var(--r); color: #fff; }
.parti-fond-i { background: var(--i); color: #14110a; }

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

.entete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  padding-top: max(12px, env(safe-area-inset-top));
  flex-wrap: wrap;
}
.titre { display: flex; flex-direction: column; gap: 2px; }
h1 { font-size: 1.25rem; }
.sous-titre { font-size: 0.85rem; color: var(--attenue); font-weight: 400; margin-left: 6px; }
.meta { display: flex; align-items: center; gap: 8px; color: var(--texte-2); font-size: 0.9rem; font-variant-numeric: tabular-nums; }
.connexion { width: 10px; height: 10px; border-radius: 50%; background: var(--attenue); display: inline-block; }
.connexion.ok { background: #31c48d; box-shadow: 0 0 0 3px rgba(49, 196, 141, 0.2); }
.connexion.ko { background: #f0a020; animation: clignote 1s infinite; }
.compte-bascules .puce-flips { background: var(--surface-2); border: 1px solid var(--trait); border-radius: 99px; padding: 1px 8px; font-weight: 600; margin-right: 6px; white-space: nowrap; }

.bouton-alertes {
  background: var(--surface-2);
  border: 1px solid var(--trait);
  border-radius: 99px;
  padding: 8px 14px;
  font-weight: 600;
}
.bouton-alertes.actif { background: #213a2f; border-color: #31c48d; }

/* ---------- Contrôle des chambres (toujours visible) ---------- */

.controle {
  position: sticky;
  top: 0;
  z-index: 5;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  padding: 8px 16px 12px;
  background: linear-gradient(var(--fond) 85%, rgba(15, 17, 23, 0));
}
.chambre {
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 12px 14px;
}
.chambre.controle-d { border-color: var(--d); box-shadow: inset 0 0 0 1px var(--d); }
.chambre.controle-r { border-color: var(--r); box-shadow: inset 0 0 0 1px var(--r); }
.chambre-entete { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.chambre h2 { font-size: 1rem; }
.majorite-note { font-size: 0.8rem; color: var(--attenue); }
.chiffres { display: flex; align-items: baseline; gap: 14px; margin: 6px 0; font-variant-numeric: tabular-nums; }
.chiffre b { font-size: 2rem; line-height: 1; }
.chiffre.parti-r { margin-left: auto; }
.chiffre.attenue b { font-size: 1.2rem; }

.barre {
  position: relative;
  display: flex;
  gap: 2px;
  height: 18px;
  border-radius: 4px;
  overflow: hidden;
}
.seg { height: 100%; transition: width 0.6s ease; }
.seg[style*="width:0%"] { display: none; }
.seg-d { background: var(--d); }
.seg-r { background: var(--r); }
.seg-i { background: var(--i); }
.seg-vide { background: var(--vide); }
.seuil {
  position: absolute;
  top: -3px;
  bottom: -3px;
  left: 50%;
  width: 2px;
  margin-left: -1px;
  background: var(--texte);
  box-shadow: 0 0 0 2px var(--fond);
}
.statut { margin-top: 8px; font-size: 0.92rem; color: var(--texte-2); }
.statut-controle { display: inline-block; padding: 3px 10px; border-radius: 99px; font-weight: 700; }

/* « Avant l'élection » doit se lire d'un coup d'oeil à quatre mètres : la même mention en
   gris fin passait inaperçue et on croyait regarder les résultats de la soirée. Jaune
   franc, majuscules, posé en pastille là où le bandeau annonce autrement une majorité. */
.badge-avant,
.badge-direct {
  display: inline-block;
  padding: 3px 12px;
  border-radius: 99px;
  background: #f5d90a;
  color: #1a1600;
  font-weight: 800;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
/* La carte de la soirée porte la même pastille, mais au ton inverse de la page : jaune
   pour « ce n'est pas encore commencé », contraste franc pour « ça se joue maintenant ».
   Ni bleu ni rouge, qui appartiennent aux partis. */
.badge-direct { background: var(--texte); color: var(--fond); }

/* ---------- Bilan : avant, bascules, chemin vers la majorité ---------- */

.bilan { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--trait); display: flex; flex-direction: column; gap: 7px; font-size: 0.9rem; }
.bilan-ligne { display: grid; grid-template-columns: 74px 1fr auto; align-items: center; gap: 10px; }
/* La barre au milieu, les deux chiffres de chaque côté, chacun du côté de sa couleur. */
.ligne-avant { grid-template-columns: 74px auto 1fr auto; }
.ligne-avant .bilan-chiffres b { font-size: 1.05rem; }
.bilan-titre { font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.06em; color: var(--attenue); font-weight: 700; }
.barre-avant { display: flex; gap: 2px; height: 8px; border-radius: 3px; overflow: hidden; }
.bilan-chiffres { color: var(--texte-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.bascules { display: flex; gap: 6px 16px; flex-wrap: wrap; }
.bascule-parti { white-space: nowrap; }
.bascule-parti b { font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.bilan-chemin { display: flex; flex-direction: column; gap: 2px; }
.bilan-chemin p { margin: 0; color: var(--texte-2); }
.statut-projete { display: inline-block; padding: 0 8px; border-radius: 99px; font-weight: 700; background: var(--surface-2); }
.bilan-court { display: none; margin: 0; font-size: 0.78rem; color: var(--texte-2); }
/* La projection ne se répète qu'une fois : ici sur le grand écran, dans le chemin ailleurs. */
.bilan-projete { display: none; }

.jauge { position: relative; height: 20px; margin: 16px 0 18px; }
.jauge-zone { position: absolute; top: 0; bottom: 0; }
.jauge-zone.zone-d { left: 0; background: var(--d-pale); border-radius: 4px 0 0 4px; }
.jauge-zone.zone-r { background: var(--r-pale); border-radius: 0 4px 4px 0; }
.jauge-zone span { position: absolute; top: -15px; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; white-space: nowrap; }
.jauge-zone.zone-d span { left: 2px; color: #7fb0ff; }
.jauge-zone.zone-r span { right: 2px; color: #ff8a8d; }
.jauge-remplissage { position: absolute; top: 6px; height: 8px; border-radius: 2px; transition: all 0.6s ease; }
.jauge-zero { position: absolute; top: 2px; bottom: 2px; width: 1px; background: var(--attenue); }
.jauge-ligne { position: absolute; top: -4px; bottom: -4px; width: 2px; margin-left: -1px; background: var(--texte); }
.jauge-zero span, .jauge-ligne span { position: absolute; top: calc(100% + 3px); transform: translateX(-50%); font-size: 0.66rem; color: var(--attenue); white-space: nowrap; }
.jauge-ligne span { color: var(--texte); font-weight: 700; }
.jauge-repere { position: absolute; top: 2px; width: 16px; height: 16px; margin-left: -8px; border-radius: 50%; background: var(--texte-2); box-shadow: 0 0 0 2px var(--fond); transition: left 0.6s ease; }
.jauge-repere.repere-d { background: var(--d); box-shadow: 0 0 0 2px #fff; }
.jauge-repere.repere-r { background: var(--r); box-shadow: 0 0 0 2px #fff; }

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

.mise-en-page { display: block; padding: 0 16px 24px; }
.cote { display: block; }
.bloc-qr { display: none; }
main section, .bloc-journal { margin-top: 18px; }
.section-titre { font-size: 1rem; margin-bottom: 8px; }
.section-titre .attenue { font-size: 0.82rem; margin-left: 6px; }

.grille { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 10px; }
.grille-compacte { grid-template-columns: repeat(auto-fill, minmax(170px, 1fr)); }

/* ---------- Cartes de course ---------- */

.course {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  overflow: hidden;
}
.course.cote-pile-ou-face { border-color: #4a5266; background: var(--surface-2); }
/* Avant la déclaration, la tuile porte la couleur du parti qui tenait le siège : plus pâle
   que celle d'un gagnant, pour qu'on ne confonde jamais « c'était à eux » et « ils ont
   gagné ». Dès qu'un résultat tombe, la règle `.declaree` écrase celle-ci.
   On ne pose que la couche d'image : le fond de la tuile reste celui de sa règle (une course
   à pile ou face garde le sien), et la teinte se dépose par-dessus. */
.course-ecran.sortant-d { background-image: linear-gradient(var(--d-sortant), var(--d-sortant)); }
.course-ecran.sortant-r { background-image: linear-gradient(var(--r-sortant), var(--r-sortant)); }
.course-ecran.sortant-i { background-image: linear-gradient(var(--i-sortant), var(--i-sortant)); }
.course.declaree.bord-d { border-color: var(--d); background: linear-gradient(var(--d-pale), var(--d-pale)), var(--surface); }
.course.declaree.bord-r { border-color: var(--r); background: linear-gradient(var(--r-pale), var(--r-pale)), var(--surface); }
.course.declaree.bord-i { border-color: var(--i); background: linear-gradient(var(--i-pale), var(--i-pale)), var(--surface); }
.course.bascule { box-shadow: 0 0 0 2px var(--fond), 0 0 0 4px #f5d90a; }
.course-haut { display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.nom-etat { font-weight: 700; font-size: 1.05rem; }
.puce-cote {
  font-size: 0.72rem;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 99px;
  white-space: nowrap;
  border: 1px solid var(--trait);
  color: var(--texte-2);
}
.puce-cote.cote-pile-ou-face { background: #f5d90a; color: #1a1600; border-color: #f5d90a; }
.puce-cote.cote-penche-d, .puce-cote.cote-probable-d { border-color: var(--d); color: #7fb0ff; }
.puce-cote.cote-penche-r, .puce-cote.cote-probable-r { border-color: var(--r); color: #ff8a8d; }
.candidats { font-size: 0.9rem; color: var(--texte); }
.sortant-etoile { color: var(--attenue); font-size: 0.7rem; margin-left: 2px; vertical-align: super; }
.course-bas { display: flex; justify-content: space-between; gap: 6px; font-size: 0.8rem; color: var(--attenue); flex-wrap: wrap; }
/* Sur le fond blanc du grand écran, un texte jaune disparaît. Le texte prend donc la
   couleur du texte, bien noire, et c'est la pastille qui clignote qui porte la couleur. */
.depouillement { color: var(--texte); font-weight: 700; }
.depouillement::before { content: "● "; color: var(--encours); animation: clignote 1.6s infinite; }
/* Le mot FLIP clignote dans la tuile : une fois l'animation passée, c'est le seul
   endroit du tableau qui dit qu'un siège a changé de camp, et l'œil doit le retrouver. */
.mot-flip { animation: clignote 1.1s infinite; }
.verdict { margin: 4px -12px -10px; padding: 5px 12px; font-weight: 800; letter-spacing: 0.02em; display: flex; justify-content: space-between; align-items: center; gap: 6px; }
.etat-source { font-size: 0.8rem; color: var(--attenue); }
.etat-source.panne { color: var(--encours); font-weight: 700; }
.etat-source[hidden] { display: none; }
.grille-compacte .nom-etat { font-size: 0.95rem; }

/* ---------- Cartes du Sénat sur le grand écran ---------- */

.course-ecran { gap: 6px; padding: 11px 14px; }
.course-ecran .nom-etat { font-size: 1.5rem; letter-spacing: -0.01em; }
.course-ecran .course-bas { font-size: 0.85rem; }
.course-ecran .verdict { font-size: 1.05rem; margin-top: 2px; }
/* Les deux candidats l'un sous l'autre, jamais côte à côte : sur une demi-carte, « Darline
   Graham » se coupait en « Darlin / e Graha / m ». Sur une ligne pleine, le nom s'écrit. */
.duel { display: grid; grid-template-columns: 1fr; gap: 8px; }
.candidat {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  min-width: 0;
  padding-left: 8px;
  border-left: 3px solid var(--trait);
}
.candidat.bord-d { border-left-color: var(--d); }
.candidat.bord-r { border-left-color: var(--r); }
.candidat.bord-i { border-left-color: var(--i); }
.visage {
  width: 66px;
  height: 66px;
  flex: none;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  background: var(--surface-2);
}
.visage.sans-photo {
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
}
.candidat figcaption { display: flex; flex-direction: column; min-width: 0; }
/* break-word et non anywhere : un nom ne se coupe qu'en dernier recours, entre ses mots. */
.candidat-nom { font-weight: 700; font-size: 1.35rem; line-height: 1.15; overflow-wrap: break-word; hyphens: none; }
.candidat-parti { font-size: 0.8rem; }
.duel.seul .visage { width: 94px; height: 94px; }
.duel.seul .candidat-nom { font-size: 1.7rem; }

/* Les chiffres d'un candidat tiennent sur SA ligne, à droite de son nom : la tuile ne
   grandit pas d'un pixel pour les accueillir. */
.course-ecran .candidat { justify-content: space-between; }
.course-ecran .candidat figcaption { flex: 1; }
.candidat-votes { flex: none; display: flex; flex-direction: column; text-align: right; line-height: 1.1; }
.candidat-votes b { font-size: 1.3rem; font-variant-numeric: tabular-nums; }
.candidat-votes span { font-size: 0.82rem; color: var(--texte-2); font-variant-numeric: tabular-nums; }

/* La barre dit d'un coup d'oeil qui mène et de combien, sans lire un chiffre. Le gris à
   droite, c'est ce qui n'est pas encore compilé. */
.barre-votes { display: flex; height: 7px; margin-top: 2px; border-radius: 99px; overflow: hidden; background: var(--surface-2); }
.barre-votes span { display: block; }
.barre-votes .part-d { background: var(--d); }
.barre-votes .part-r { background: var(--r); }
.barre-votes .part-i { background: var(--i); }
/* Les deux bouts de la ligne restent sur la MÊME ligne : à trois tuiles de large, « 17 %
   du vote compilé » et la fraction ne tenaient pas ensemble et la ligne se coupait en
   deux, ce qui faisait grandir la tuile. D'où le texte court et ce corps plus petit. */
.course-ecran .course-bas.ligne-votes { font-size: 0.78rem; flex-wrap: nowrap; gap: 10px; }
.course-bas.ligne-votes span { white-space: nowrap; }
.compile { font-variant-numeric: tabular-nums; }

/* ---------- Autres courses ---------- */

.autres { display: flex; flex-wrap: wrap; gap: 6px; }
.petite-course {
  padding: 4px 9px;
  border-radius: 6px;
  font-weight: 700;
  font-size: 0.85rem;
  font-variant-numeric: tabular-nums;
  background: var(--surface);
  border: 1px solid var(--trait);
}
.petite-course.parti-fond-d { background: var(--d); border-color: var(--d); color: #fff; }
.petite-course.parti-fond-r { background: var(--r); border-color: var(--r); color: #fff; }
.petite-course.parti-fond-i { background: var(--i); border-color: var(--i); color: #14110a; }
.petite-course.attendu-d { border-left: 4px solid var(--d); }
.petite-course.attendu-r { border-left: 4px solid var(--r); }
.petite-course.bascule { outline: 2px solid #f5d90a; outline-offset: 1px; }
.petite-course.serree:not(.parti-fond-d):not(.parti-fond-r):not(.parti-fond-i) { box-shadow: inset 0 -3px 0 #f5d90a; }

/* ---------- Fil de la soirée ---------- */

.journal { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 0.9rem; }
.journal li { background: var(--surface); border: 1px solid var(--trait); border-radius: 8px; padding: 6px 10px; }
.journal time { color: var(--attenue); font-variant-numeric: tabular-nums; margin-right: 6px; }
.journal .evt-bascule { border-color: #f5d90a; }
.journal .evt-controle { border-color: var(--texte-2); }

/* ---------- Alertes ---------- */

.alerte {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 24px;
  animation: entree 0.35s ease-out;
}
.alerte[hidden] { display: none; }
.alerte-titre { font-size: clamp(2.5rem, 11vw, 7rem); font-weight: 900; letter-spacing: 0.03em; animation: pulsation 1s ease-in-out 3; }
.alerte-detail { font-size: clamp(1.2rem, 4vw, 2.4rem); font-weight: 600; max-width: 30ch; margin-top: 12px; }
.alerte-fermer { margin-top: 28px; opacity: 0.8; font-size: 0.95rem; }

/* Le cadre reste en place entre les bascules : les images de l'animation sont ainsi déjà chargées. */
.animation-plein-ecran {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  z-index: 55;
}
.animation-plein-ecran.inactif { visibility: hidden; pointer-events: none; }

.bandeau {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: max(12px, env(safe-area-inset-bottom));
  z-index: 40;
  background: var(--surface-2);
  border: 1px solid #f5d90a;
  border-radius: var(--rayon);
  padding: 10px 14px;
  box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
}
.bandeau[hidden] { display: none; }

.indice-son { display: none; }

.dialogue {
  background: var(--surface);
  color: var(--texte);
  border: 1px solid var(--trait);
  border-radius: 14px;
  padding: 18px;
  width: min(520px, calc(100vw - 24px));
  max-height: calc(100vh - 24px);
}
.dialogue::backdrop { background: rgba(0, 0, 0, 0.65); }
.dialogue h2 { font-size: 1.2rem; }
.dialogue fieldset { border: 1px solid var(--trait); border-radius: 8px; margin: 12px 0 0; padding: 8px 12px 10px; }
.dialogue legend { color: var(--texte-2); font-weight: 600; padding: 0 4px; }
.dialogue label { display: block; padding: 5px 0; }
.choix-etats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 0 8px; margin-top: 4px; }
.choix-etats[hidden] { display: none; }
.choix-etat.cle { font-weight: 700; }
.actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 14px; flex-wrap: wrap; }
.actions button, .danger {
  background: var(--surface-2);
  border: 1px solid var(--trait);
  border-radius: 8px;
  padding: 9px 14px;
  font-weight: 600;
}
.actions .principal { background: #31c48d; border-color: #31c48d; color: #06140e; }

/* ---------- Grand écran ---------- */

/* La télé se lit à trois ou quatre mètres, pas à cinquante centimètres : tout est
   environ 30 % plus gros que sur un téléphone, et on en montre moins à la fois. */
html.ecran { font-size: 21px; }

/* La hauteur du ruban du fil sert aussi à remonter ce qui se posait au bas de l'écran. */
body.ecran { overflow: hidden; height: 100vh; display: flex; flex-direction: column; --ruban-h: 58px; }
/* Trois lignes empilées en haut, c'est trois lignes de moins pour les courses : sur le grand
   écran, le titre, l'heure et l'état des sources tiennent sur une seule. */
body.ecran .entete { padding: 8px 28px 2px; }
body.ecran .titre { flex-direction: row; align-items: baseline; gap: 20px; flex-wrap: wrap; flex: 1 1 auto; }
body.ecran .meta { font-size: 1.05rem; }
body.ecran .etat-source { font-size: 1rem; }
body.ecran h1 { font-size: 1.8rem; }
/* Les deux panneaux du haut prenaient près du tiers de l'écran et disaient quatre fois la
   même chose. Le grand écran reçoit à la place le bandeau « Balance du pouvoir » : par
   chambre, les gros chiffres, la barre des sièges et ce qu'il manque pour la majorité, en
   trois lignes. Le bilan complet (avant, bascules état par état, chemin) reste sur les
   téléphones et la page de saisie, qu'on lit de près. */
body.ecran .controle { padding: 6px 28px 8px; gap: 20px; position: static; }
.balance-chambre {
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 7px 14px 9px;
}
.balance-chambre.controle-d { border-color: var(--d); box-shadow: inset 0 0 0 1px var(--d); }
.balance-chambre.controle-r { border-color: var(--r); box-shadow: inset 0 0 0 1px var(--r); }
/* Le nom de la chambre et les chiffres sur la même ligne : à quatre mètres, « Sénat » n'a
   pas besoin d'une ligne à lui. */
.balance-haut { display: flex; align-items: baseline; gap: 18px; }
.balance-haut h2 { font-size: 1.25rem; margin: 0; flex: none; }
.balance-chiffres { display: flex; align-items: baseline; gap: 14px; flex: 1; font-variant-numeric: tabular-nums; }
.balance-chiffres .chiffre b { font-size: 2.4rem; line-height: 1; }
.balance-chiffres .chiffre.attenue b { font-size: 1.3rem; }
.balance-chiffres .chiffre.parti-r { margin-left: auto; }
body.ecran .balance-chambre .barre { height: 18px; margin-top: 2px; }
.balance-statut { margin: 5px 0 0; font-size: 1.05rem; color: var(--texte-2); }
body.ecran .mise-en-page {
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 20px;
  padding: 0 28px 16px;
  flex: 1;
  min-height: 0;
}
body.ecran main { overflow-y: auto; scrollbar-width: none; }
body.ecran main::-webkit-scrollbar { display: none; }
body.ecran .autres .petite-course { font-size: 0.88rem; padding: 4px 9px; }
/* Trois cartes par rangée plutôt que quatre : plus larges pour les noms, plus hautes pour
   remplir le bas de l'écran, qui restait noir. */
body.ecran .grille { grid-template-columns: repeat(auto-fill, minmax(420px, 1fr)); gap: 14px; }
#tuiles-reste { margin-top: 10px; }
#tuiles-reste[hidden] { display: none; }
body.ecran main section:first-child { margin-top: 0; }

/* Le titre des grosses tuiles reste collé en haut pendant que la grille défile : sans lui,
   on voit passer des visages sans savoir s'il s'agit du Sénat ou de la Chambre. Fond opaque
   et marge négative, sinon les tuiles se devinent derrière la ligne de texte. Seul celui-là
   est figé : les sections du dessous défilent normalement. */
body.ecran #titre-tuiles {
  position: sticky;
  top: 0;
  z-index: 3;
  font-size: 1.5rem;
  background: var(--fond);
  padding: 6px 0 10px;
  margin: 0 0 4px;
}
body.ecran #titre-tuiles .attenue { font-size: 0.95rem; }
body.ecran .cote { display: flex; flex-direction: column; gap: 14px; min-height: 0; }
/* Le code QR et son mode d'emploi l'un sous l'autre : côte à côte dans une colonne de
   340 px, chaque consigne retombait sur trois lignes et le bloc prenait toute la hauteur. */
body.ecran .bloc-qr {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  padding: 14px 16px;
  text-align: center;
}
body.ecran .bloc-qr img { width: 164px; height: 164px; border-radius: 6px; flex: none; }
body.ecran .bloc-qr > div { width: 100%; }
body.ecran .bloc-qr p { margin: 0 0 4px; font-size: 0.85rem; }
body.ecran .qr-titre { font-weight: 700; font-size: 1rem !important; }
/* L'adresse est faite pour être recopiée à la main : elle ne se coupe qu'entre les points,
   jamais au milieu d'un mot. */
body.ecran .qr-url { font-weight: 700; color: var(--texte); overflow-wrap: anywhere; }
body.ecran .qr-liste { text-align: left; padding-left: 1.4em; font-size: 0.9rem; }
body.ecran .bloc-journal { margin-top: 0; overflow: hidden; min-height: 0; flex: 1; }
body.ecran .bouton-alertes { display: none; }
/* On le cherche une fois, au début de la soirée, souvent sur une télé à deux mètres : il se
   voit donc de loin, en pleine couleur, et il disparaît une fois le plein écran pris, pour ne
   plus laisser que le tableau. Échap ou F11 le ramène. */
.bouton-plein-ecran { display: none; }
body.ecran .bouton-plein-ecran {
  display: block;
  position: fixed;
  left: 20px;
  /* Au-dessus du ruban du fil : posés sur lui, le bouton et l'indice cachaient les nouvelles. */
  bottom: calc(var(--ruban-h) + 18px);
  z-index: 6;
  padding: 14px 24px;
  border: 2px solid var(--texte);
  border-radius: 99px;
  background: var(--texte);
  color: var(--fond);
  font-size: 1.15rem;
  font-weight: 700;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  cursor: pointer;
}
body.ecran .bouton-plein-ecran:hover { filter: brightness(0.92); }
/* Ni bleu ni rouge : un soir d'élection, une couleur de parti sur un bouton d'interface se
   lirait comme un parti pris. Le bouton reste donc en noir et blanc, et se retourne avec le
   fond clair comme le reste. */
body.ecran.plein-ecran .bouton-plein-ecran { display: none; }
body.ecran .indice-son {
  display: block;
  position: fixed;
  right: 20px;
  bottom: calc(var(--ruban-h) + 14px);
  margin: 0;
  background: var(--surface-2);
  border: 1px solid var(--trait);
  border-radius: 99px;
  padding: 6px 14px;
  font-size: 0.9rem;
  color: var(--texte-2);
}
body.ecran .indice-son[hidden] { display: none; }

/* ---------- Page de l'hôte ---------- */

.message { position: sticky; top: 0; z-index: 10; margin: 0 16px; padding: 10px 14px; border-radius: 8px; background: #213a2f; border: 1px solid #31c48d; }
.message.erreur { background: #3a1f22; border-color: var(--r); }
.admin .controle { position: static; }
.admin-contenu { padding: 0 16px 40px; max-width: 900px; }
.bloc-admin { margin-top: 20px; }
.liste-admin { display: flex; flex-direction: column; gap: 6px; }
.ligne-admin {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: 8px;
  padding: 8px 10px;
}
.ligne-admin.bascule { border-color: #f5d90a; }
.ligne-admin.conflit { border-color: #ff8a8d; background: #2a1719; }
.prov-auto { font-size: 0.8rem; color: #6ee7b7; }
.prov-hote { font-size: 0.8rem; color: #f5d90a; }
.prov-conflit { font-size: 0.85rem; color: #ff8a8d; font-weight: 700; }
.liste-sources { list-style: none; padding: 0; margin: 0 0 8px; display: flex; flex-direction: column; gap: 4px; }
.liste-sources .ok { color: #6ee7b7; }
.liste-sources .ko { color: #ff8a8d; font-weight: 600; }
#lire-sources, #totaux-auto { background: var(--surface-2); border: 1px solid var(--trait); border-radius: 8px; padding: 8px 12px; font-weight: 600; }
#totaux > p { flex-basis: 100%; margin: 0 0 4px; }
.ligne-info { display: flex; flex-direction: column; min-width: 0; }
.ligne-info .attenue { font-size: 0.8rem; }
.ligne-boutons { display: flex; gap: 6px; flex: none; }
.choix-parti {
  min-width: 44px;
  min-height: 44px;
  border-radius: 8px;
  border: 1px solid var(--trait);
  background: var(--surface-2);
}
.choix-parti.actif { border-color: transparent; color: #fff; }
.choix-parti.retirer { color: var(--attenue); }
.choix-parti:disabled { opacity: 0.35; cursor: default; }
.totaux { display: flex; gap: 10px; flex-wrap: wrap; }
.total { display: flex; align-items: center; gap: 6px; background: var(--surface); border: 1px solid var(--trait); border-radius: 8px; padding: 8px; }
.total span { width: 18px; text-align: center; }
.total input {
  width: 80px;
  font: inherit;
  font-size: 1.3rem;
  font-weight: 700;
  text-align: center;
  background: var(--fond);
  color: var(--texte);
  border: 1px solid var(--trait);
  border-radius: 6px;
  padding: 6px;
}
.total button { min-width: 44px; min-height: 44px; border-radius: 8px; border: 1px solid var(--trait); background: var(--surface-2); font-weight: 700; }
.parti-bord-d { border-left: 4px solid var(--d); }
.parti-bord-r { border-left: 4px solid var(--r); }
.parti-bord-i { border-left: 4px solid var(--i); }
.danger { border-color: var(--r); color: #ff8a8d; }

/* ---------- Téléphones ---------- */

@media (max-width: 700px) {
  .controle { grid-template-columns: 1fr; gap: 6px; padding: 6px 10px 10px; }
  .chambre { padding: 8px 10px; }
  .chiffres { margin: 2px 0 4px; }
  .chiffre b { font-size: 1.5rem; }
  .barre { height: 12px; }
  .statut { margin-top: 4px; font-size: 0.82rem; }
  .majorite-note { display: none; }
  .bilan { margin-top: 6px; padding-top: 6px; }
  .bilan > :not(.bilan-court) { display: none; }
  .bilan-court { display: block; }
  .controle.reduit .statut { display: none; }
  .controle.reduit .chambre { padding: 5px 10px; }
  .controle.reduit .chambre h2 { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--attenue); }
  .controle.reduit .chiffres { margin: 0 0 3px; }
  .controle.reduit .chiffre b { font-size: 1.15rem; }
  .controle.reduit .bilan { margin-top: 3px; padding-top: 0; border-top: 0; }
  .controle.reduit .bilan-court { font-size: 0.7rem; }
  .mise-en-page, .admin-contenu { padding: 0 10px 24px; }
  .grille { grid-template-columns: 1fr 1fr; gap: 8px; }
  .course { padding: 8px 10px; }
  .verdict { margin: 4px -10px -8px; padding: 4px 10px; font-size: 0.85rem; }
  .nom-etat { font-size: 0.98rem; }
  .course-bas { font-size: 0.74rem; }
  .ligne-admin { flex-direction: column; align-items: stretch; }
  .ligne-boutons { justify-content: space-between; }
  .ligne-boutons .choix-parti { flex: 1; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; }
}

@keyframes clignote { 50% { opacity: 0.3; } }
@keyframes entree { from { opacity: 0; transform: scale(1.04); } }
@keyframes pulsation { 50% { transform: scale(1.08); } }

/* Écran de télé moins haut : on resserre le haut pour laisser voir les courses. */
@media (max-height: 860px) {
  body.ecran .entete { padding-top: 6px; }
  body.ecran h1 { font-size: 1.4rem; }
  body.ecran .chiffre b { font-size: 2.1rem; }
  body.ecran .barre { height: 20px; }
  body.ecran .statut, body.ecran .bilan { font-size: 0.9rem; }
  body.ecran .bilan { gap: 4px; margin-top: 6px; padding-top: 6px; }
}
/* ---------- Compte à rebours des fermetures ---------- */

/* Une soirée électorale avance par vagues : la barre dit laquelle vient de tomber et dans
   combien de temps la prochaine, pour que les creux ne soient jamais vides. */
.rebours {
  margin: 0 16px;
  padding: 7px 12px;
  border: 1px solid var(--trait);
  border-left: 4px solid var(--attenue);
  border-radius: 8px;
  background: var(--surface);
  color: var(--texte-2);
  font-size: 0.9rem;
}
.rebours[hidden] { display: none; }
.rebours b { color: var(--texte); font-variant-numeric: tabular-nums; }
.rebours.imminent { border-left-color: #f5d90a; }
.rebours.imminent b { color: #f5d90a; }
.rebours.ferme { border-left-color: #31c48d; background: #16241d; }
.rebours.ferme b { color: #6ee7b7; }

/* ---------- Carte des États-Unis ---------- */

/* Les formes réelles des états, dans un seul SVG : chaque état est un tracé qu'on colore,
   et le dessin se redimensionne sans jamais se pixeliser, du téléphone à la télé. */
.carte { display: block; width: 100%; max-width: 1000px; margin: 0 auto; }
.carte .etat { stroke: var(--carte-bord); stroke-width: 1; vector-effect: non-scaling-stroke; }
.carte .hors-jeu { fill: var(--carte-vide); }
.carte .nuance-d3 { fill: var(--n-d3); }
.carte .nuance-d2 { fill: var(--n-d2); }
.carte .nuance-d1 { fill: var(--n-d1); }
.carte .nuance-mauve { fill: var(--n-mauve); }
.carte .nuance-r1 { fill: var(--n-r1); }
.carte .nuance-r2 { fill: var(--n-r2); }
.carte .nuance-r3 { fill: var(--n-r3); }
/* Un siège en jeu qui n'est pas tombé garde sa nuance de départ, mais en retrait : l'oeil
   doit aller d'abord aux états déclarés. C'est le remplissage seul qui s'efface, pas le
   tracé : sur fond blanc, une opacité sur tout l'état emportait aussi sa bordure, et le
   pourtour du pays s'effaçait avec elle. */
.carte .en-attente { fill-opacity: 0.45; }
/* Déclaré : la couleur pleine du parti, plus vive que toutes les nuances de cotes. */
.carte .rempli-d { fill: var(--d); }
.carte .rempli-r { fill: var(--r); }
.carte .rempli-i { fill: var(--i); }
/* Une bascule, c'est l'événement de la soirée, et un trait de 3 px autour d'un état déjà
   bleu ou rouge ne se voyait pas du fond de la pièce. L'état garde donc son contour, mais
   il est redessiné par-dessus la carte (voir .contour-bascule) : les voisins dessinés après
   lui en mangeaient la moitié. Le trait est blanc, cerné de sombre, et bat franchement; le
   nom de l'état prend la même pastille blanche. L'or disait une troisième couleur de parti
   sur une carte qui n'en a que deux. */
.carte .bascule { stroke: #ffffff; stroke-width: 3; }
.carte .contour-bascule {
  fill: none;
  stroke: #ffffff;
  stroke-width: 4;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  animation: battement 1.8s ease-in-out infinite;
}
/* Le trait sombre passe dessous et déborde : sans lui, le blanc se perdait sur un état pâle
   voisin et sur le fond clair de la page, au bord de l'océan. */
.carte .ombre-bascule {
  fill: none;
  stroke: rgba(0, 0, 0, 0.72);
  stroke-width: 9;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  animation: battement-ombre 1.8s ease-in-out infinite;
}
@keyframes battement {
  0%, 100% { stroke-width: 4; }
  50% { stroke-width: 7; }
}
@keyframes battement-ombre {
  0%, 100% { stroke-width: 9; }
  50% { stroke-width: 13; }
}
.carte .pastille-bascule { fill: #ffffff; stroke: rgba(0, 0, 0, 0.72); stroke-width: 2; vector-effect: non-scaling-stroke; }
.carte-separateurs { stroke: var(--carte-trait); stroke-width: 1.5; vector-effect: non-scaling-stroke; }
/* Le nom est écrit par-dessus la couleur : un contour de la teinte du fond le détache sans
   boîte ni ombre portée. */
.carte .nom-etat {
  fill: var(--texte);
  font-size: 15px;
  font-weight: 800;
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  stroke: var(--halo-nom);
  stroke-width: 3px;
  stroke-linejoin: round;
}
.carte .nom-deporte { text-anchor: start; }
.carte .nom-bascule { fill: #1a1600; stroke: none; }
.carte .filet-etiquette { stroke: var(--attenue); stroke-width: 1; vector-effect: non-scaling-stroke; }
.carte-legende {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  max-width: 1000px;
  margin: 8px auto 0;
  font-size: 0.78rem;
}
.legende-puce {
  padding: 1px 8px;
  border: 1px solid var(--trait);
  border-radius: 99px;
  font-size: 0.72rem;
  font-weight: 700;
  color: #fff;
}
.legende-puce.nuance-d3 { background: var(--n-d3); border-color: var(--n-d3); }
.legende-puce.nuance-d1 { background: var(--n-d1); border-color: var(--n-d1); }
.legende-puce.nuance-mauve { background: var(--n-mauve); border-color: var(--n-mauve); }
.legende-puce.nuance-r1 { background: var(--n-r1); border-color: var(--n-r1); }
.legende-puce.nuance-r3 { background: var(--n-r3); border-color: var(--n-r3); }
.legende-puce.rempli-d { background: var(--d); border-color: var(--d); }
.legende-puce.rempli-r { background: var(--r); border-color: var(--r); }
.legende-puce.en-attente { opacity: 0.45; }
/* La puce « flip » de la légende montre ce qu'on voit sur la carte : la couleur du parti
   qui vient de prendre le siège, cernée du même trait blanc. */
.legende-puce.bascule { border-color: #ffffff; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.72); outline: none; }
/* Même bordure que sur la carte : sans elle, la puce « pas en jeu » n'avait plus de
   contour sur le fond blanc. */
.legende-puce.hors-jeu { background: var(--carte-vide); border-color: var(--carte-bord); color: var(--texte-2); }

/* Les trois choses qu'on peut faire avec son téléphone, numérotées : sur une télé, une
   énumération se lit mieux qu'une phrase. */
.qr-liste { margin: 6px 0 4px; padding-left: 1.1em; display: flex; flex-direction: column; gap: 2px; font-size: 0.95rem; }
.qr-liste li { color: var(--texte-2); }

/* ---------- Pronostics des invités ---------- */

.boutons-entete { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.meneurs { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; font-size: 0.9rem; }
.meneurs li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--trait);
  border-radius: 8px;
  padding: 5px 10px;
}
.meneurs li.moi { border-color: #31c48d; background: #16241d; }
.rang { color: var(--attenue); font-weight: 700; font-variant-numeric: tabular-nums; min-width: 1.4em; }
.meneur-nom { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.meneur-chiffres { margin-left: auto; color: var(--attenue); font-size: 0.82rem; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Le nombre porte la couleur du camp qu'il fait gagner : il ne doit pas être repeint en
   gris par la règle générale du classement. */
.meneur-chiffres b { color: var(--texte-2); }
.meneur-chiffres b.parti-d, .meneur-chiffres b.parti-r { color: inherit; }
.meneur-ecart {
  flex: none;
  padding: 1px 7px;
  border-radius: 99px;
  background: var(--surface-2);
  color: var(--texte-2);
  font-size: 0.78rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}
.champ { display: flex; flex-direction: column; gap: 3px; margin-top: 12px; font-weight: 600; }
.champ input {
  font: inherit;
  font-weight: 700;
  padding: 10px;
  border-radius: 8px;
  border: 1px solid var(--trait);
  background: var(--surface-2);
  color: var(--texte);
}
.champ input:disabled { opacity: 0.6; }
.pronostic-message { margin: 12px 0 0; padding: 8px 10px; border-radius: 8px; background: #213a2f; border: 1px solid #31c48d; font-size: 0.88rem; }
.pronostic-message.erreur { background: #3a1f22; border-color: var(--r); }
.pronostic-message[hidden] { display: none; }
#pronostic-classement { margin-top: 12px; max-height: 40vh; overflow-y: auto; }

/* ---------- Carte, rebours et meneurs sur le grand écran ---------- */

body.ecran .rebours { margin: 0 28px 10px; padding: 9px 16px; font-size: 1.05rem; }
body.ecran #section-carte[hidden], body.ecran #section-tuiles[hidden] { display: none; }
body.ecran .carte-legende { max-width: none; font-size: 0.9rem; }

/* La carte prend tout l'écran pendant son tour : les panneaux du haut, le rebours et la
   colonne de droite s'effacent. Une carte des États-Unis coupée en deux ne vaut rien, et les
   chiffres des deux chambres reviennent trente secondes plus tard. */
/* La bande « Balance du pouvoir » reste pendant la carte : sans elle, on ne sait plus où en
   sont les deux chambres, et la carte ne parle que du Sénat. Le reste s'efface. */
body.ecran.carte-pleine .rebours,
body.ecran.carte-pleine .cote { display: none; }
body.ecran.carte-pleine .controle { padding-bottom: 4px; }
body.ecran.carte-pleine .mise-en-page { grid-template-columns: 1fr; padding: 0 20px 8px; }
body.ecran.carte-pleine main { overflow: hidden; }
body.ecran.carte-pleine #section-carte { display: flex; flex-direction: column; height: 100%; margin-top: 0; }
/* Le div qui reçoit la carte devient lui aussi une colonne : sans ça, le svg n'a aucune
   hauteur à remplir et déborde du bas de l'écran. */
body.ecran.carte-pleine #carte { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 4px; }
body.ecran.carte-pleine #section-carte .carte { flex: 1; min-height: 0; max-width: none; width: 100%; height: auto; }
body.ecran.carte-pleine .carte-legende { flex: none; }
body.ecran.carte-pleine .carte .nom-etat { font-size: 13px; stroke-width: 3.5px; }
body.ecran.carte-pleine #titre-carte { font-size: 1.5rem; margin-bottom: 2px; }
/* Sur le grand écran, la pastille suit la taille du titre qu'elle accompagne. */
body.ecran .badge-avant,
body.ecran .badge-direct { font-size: 1.15rem; padding: 4px 16px; }
body.ecran .bloc-pronostics { margin-top: 0; flex: none; }
body.ecran .bloc-pronostics .section-titre { font-size: 1rem; }
body.ecran .meneurs { font-size: 0.95rem; gap: 3px; }
body.ecran .meneurs li { padding: 3px 9px; }

@media (max-width: 700px) {
  .rebours { margin: 0 10px; font-size: 0.82rem; }
  /* Sur un téléphone tenu à trente centimètres, les noms des états doivent grossir :
     la carte, elle, est large de 360 px au lieu de 1000. */
  .carte .nom-etat { font-size: 22px; stroke-width: 4px; }
  .carte .filet-etiquette { stroke-width: 1.4; }
  .boutons-entete { flex-direction: column; align-items: stretch; }
}

/* ---------- Podium de fin de soirée ---------- */

/* Il couvre tout : c'est le moment des prix, et personne ne regarde plus les courses. */
.podium {
  position: fixed;
  inset: 0;
  /* Au-dessus du bandeau (40), sous les alertes (50) et les animations (55) : une bascule
     de dernière minute passe encore devant le podium. */
  z-index: 45;
  background: var(--fond);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 24px;
  overflow-y: auto;
  text-align: center;
}
.podium[hidden] { display: none; }
.podium-titre { margin: 0; font-size: 2rem; }
.podium-marches { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 12px; width: min(760px, 100%); }
.podium-marche {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 8px 16px;
  padding: 14px 20px;
  border: 1px solid var(--trait);
  border-radius: var(--rayon);
  background: var(--surface);
  text-align: left;
}
/* La première marche est plus haute que les autres, comme un vrai podium. */
.podium-marche.marche-1 { padding: 20px; border-color: var(--bascule); box-shadow: inset 0 0 0 1px var(--bascule); }
.podium-medaille { font-size: 2rem; grid-row: span 2; }
.podium-marche.marche-1 .podium-nom { font-size: 2.2rem; }
.podium-nom { font-size: 1.5rem; font-weight: 800; }
.podium-ecart { grid-row: span 2; color: var(--texte-2); white-space: nowrap; }
.podium-chiffres { grid-column: 2; color: var(--texte-2); font-variant-numeric: tabular-nums; }
.podium-reste {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px 10px;
  width: min(900px, 100%);
  color: var(--texte-2);
}
.podium-reste li { display: flex; align-items: baseline; gap: 6px; padding: 3px 10px; border: 1px solid var(--trait); border-radius: 99px; }
.podium-note { margin: 0; color: var(--texte-2); font-size: 1.05rem; }
body.ecran .podium-titre { font-size: 2.6rem; }
body.ecran .podium-marche.marche-1 .podium-nom { font-size: 3rem; }
body.ecran .podium-nom { font-size: 2rem; }

/* ---------- Fond blanc ---------- */

/* Le fond de la soirée, décidé par Éric : c'est ce qui rend le mieux sur sa télé. ?sombre
   ramène le fond noir. Rien d'autre ne change : mêmes blocs, mêmes chiffres, mêmes tailles.
   Les couleurs vives des partis restent les mêmes - c'est le code de couleur des soirées
   électorales - mais tout ce qui était pâle sur fond noir devient foncé sur fond blanc,
   sinon plus rien ne se lit. */
body.clair {
  --fond: #ffffff;
  /* Les panneaux se détachent par leur trait, pas par leur fond : sur du blanc, un gris à
     peine teinté cerné d'un trait pâle se perdait dans la page, vu de loin. Le trait est donc
     franc et le fond des blocs descend d'un cran. */
  --surface: #e9eef5;
  --surface-2: #dbe2ec;
  --trait: #9fabbd;
  --texte: #14171f;
  --encours: #b35c00;
  --texte-2: #444c5c;
  --attenue: #6b7483;
  --vide: #ced4de;
  --d-pale: rgba(29, 78, 168, 0.12);
  --r-pale: rgba(168, 30, 34, 0.12);
  --i-pale: rgba(138, 106, 10, 0.14);
  --d-sortant: rgba(29, 78, 168, 0.12);
  --r-sortant: rgba(168, 30, 34, 0.12);
  --i-sortant: rgba(138, 106, 10, 0.13);
  --n-d3: #123f8c;
  --n-d2: #2f6fc9;
  --n-d1: #86abd8;
  --n-mauve: #8b73c4;
  --n-r1: #e0a09d;
  --n-r2: #d8484d;
  --n-r3: #9c1b1f;
  /* Sur fond blanc, les états hors jeu portent seuls la silhouette du pays : trop pâles,
     le contour des États-Unis se fondait dans la page, vu de loin sur une télé. Le gris
     descend donc, et la bordure devient un vrai trait gris plutôt que du blanc. */
  --carte-vide: #d3d9e3;
  --carte-trait: #8a93a3;
  --carte-bord: #8a93a3;
  --bascule: #b8860b;
  --halo-nom: rgba(255, 255, 255, 0.75);
  background: var(--fond);
  color: var(--texte);
  color-scheme: light;
}
/* Un panneau posé sur du blanc : à quatre mètres, un trait de 1 px disparaît. Trait de
   2 px et ombre basse, pour que le bloc se décolle vraiment de la page. Les chambres déjà
   gagnées gardent leur anneau de couleur : l'ombre s'ajoute, elle ne le remplace pas. */
body.clair .balance-chambre,
body.clair .chambre {
  border-width: 2px;
  box-shadow: 0 3px 12px rgba(20, 23, 31, 0.13);
}
/* Le rebours garde sa barre de couleur à gauche : seule l'ombre s'ajoute. */
body.clair .rebours { box-shadow: 0 3px 12px rgba(20, 23, 31, 0.13); }
body.clair .balance-chambre.controle-d,
body.clair .chambre.controle-d { box-shadow: inset 0 0 0 2px var(--d), 0 3px 12px rgba(20, 23, 31, 0.13); }
body.clair .balance-chambre.controle-r,
body.clair .chambre.controle-r { box-shadow: inset 0 0 0 2px var(--r), 0 3px 12px rgba(20, 23, 31, 0.13); }

/* Une tuile déclarée se peignait d'un voile de parti à 12 %, posé sur le gris bleuté des
   blocs : sur fond blanc, le rouge en ressortait terne, à mi-chemin du gris. Une course
   tombée est l'événement de la soirée et doit se voir du fond de la pièce : teinte opaque
   et franche, assez soutenue pour qu'on la distingue d'une tuile en attente sans lire le
   bandeau. Le bleu monte d'autant, sinon le camp d'en face paraîtrait délavé. Le texte de
   la tuile reste noir : ces teintes gardent un contraste très large. */
body.clair .course.declaree.bord-d { background: #c3d9fb; }
body.clair .course.declaree.bord-r { background: #f7bcbe; }
body.clair .course.declaree.bord-i { background: #f6e3ac; }

/* Les mêmes rôles, en teintes qui tiennent sur du blanc. */
body.clair .parti-d { color: #11479b; }
body.clair .parti-r { color: #a81e22; }
body.clair .parti-i { color: #7a5c08; }
body.clair .controle { background: linear-gradient(var(--fond) 85%, rgba(255, 255, 255, 0)); }
body.clair .carte .nom-etat { fill: #ffffff; stroke: rgba(0, 0, 0, 0.45); }
body.clair .carte .nom-etat.nom-deporte { fill: var(--texte); stroke: var(--fond); }
body.clair .carte .nom-bascule { fill: #1a1600; stroke: none; }
body.clair .meneurs li.moi { background: #e3f6ec; border-color: #1b8a5a; }
body.clair .rebours.ferme { background: #e3f6ec; }
body.clair .rebours.ferme b { color: #15724a; }
body.clair .rebours.imminent b { color: #8a6407; }
body.clair .pronostic-message { background: #e3f6ec; border-color: #1b8a5a; color: #0f3d2a; }
body.clair .pronostic-message.erreur { background: #fdeaea; border-color: var(--r); color: #6d1114; }
body.clair .actions .principal { background: #1b8a5a; border-color: #1b8a5a; color: #ffffff; }

/* ---------- Ruban du fil de la soirée (grand écran) ---------- */

/* Le fil passe en ruban au bas de l'écran : le garder aussi dans la colonne le dirait deux
   fois, et la place rendue va aux pronostics, qu'on lit de loin. */
body.ecran .bloc-journal { display: none; }

/* Un ruban qui défile au bas de l'écran, comme sur les chaînes d'info : le fil des
   déclarations passe devant les yeux sans qu'on ait à le chercher. Il n'existe que sur le
   grand écran, où personne ne fait défiler; sur un téléphone, la colonne de droite reste
   l'endroit du fil. */
.ruban { display: none; }
body.ecran .ruban {
  display: flex;
  height: var(--ruban-h);
  align-items: center;
  gap: 0;
  flex: 0 0 auto;
  /* Un ruban de bourse est toujours sombre, quelle que soit la page au-dessus : c'est ce fond
     noir qui le fait lire comme un fil d'information et non comme un pied de page. Il garde
     donc ses couleurs à lui, y compris sur le fond blanc de la soirée. */
  border-top: 2px solid #2b3242;
  background: #0d1017;
  color: #eef1f6;
  overflow: hidden;
}
/* Sur ce fond, les bleus et les rouges foncés du mode clair deviennent illisibles : le ruban
   reprend les teintes vives, celles qui sont faites pour un fond sombre. */
body.ecran .ruban .parti-d { color: #7fb0ff; }
body.ecran .ruban .parti-r { color: #ff8a8d; }
body.ecran .ruban .parti-i { color: #ffd166; }
body.ecran .ruban .attenue,
body.ecran .ruban .ruban-item time { color: #8b94a6; }
body.ecran .ruban[hidden] { display: none; }

/* Le fil commence un peu après le bord : une marge lui redonne de l'air. */
.ruban-fenetre { flex: 1 1 auto; overflow: hidden; padding-left: 20px; }

/* La piste contient le fil écrit deux fois de suite : en la décalant de la moitié de sa
   largeur, la fin rejoint le début et le défilement ne montre jamais de trou. */
.ruban-piste {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  font-size: 1.25rem;
  padding: 10px 0;
  will-change: transform;
  animation: ruban-defile linear infinite;
}
@keyframes ruban-defile {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .ruban-piste { animation: none; }
}

/* Chaque nouvelle est séparée par une puce, et son heure se lit en retrait. */
.ruban-item { padding: 0 28px; }
.ruban-item::after { content: "·"; margin-left: 28px; opacity: 0.4; }
.ruban-item time { color: var(--attenue); margin-right: 10px; font-variant-numeric: tabular-nums; }
/* « Caroline du Nord » est un état au Sénat, « Caroline du Nord 11 » un district de la
   Chambre : au ruban, rien ne disait laquelle des deux venait de tomber. L'étiquette le dit
   maintenant, en petites capitales, devant le lieu. */
.fil-chambre {
  font-size: 0.74em;
  font-weight: 800;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--texte-2);
  border: 1px solid var(--trait);
  border-radius: 99px;
  padding: 0 7px;
  margin-right: 8px;
  white-space: nowrap;
}
body.ecran .ruban .fil-chambre { color: #aeb7c6; border-color: #39414f; }

/* Une bascule est la nouvelle de la soirée : elle se détache du reste du ruban. */
.ruban-item.evt-bascule { font-weight: 800; }

/* ---------- Compte à rebours d'avant la soirée ---------- */

/* Sur la ligne du titre, poussé à droite où la place est libre. Jaune comme les autres
   mentions d'avant la soirée : ni bleu ni rouge, qui appartiennent aux partis. Il s'efface
   quand la soirée approche, et le ruban du bas prend le relais. */
.avant-rebours {
  align-self: flex-start;
  margin-top: 4px;
  padding: 3px 12px;
  border-radius: 99px;
  background: #f5d90a;
  color: #1a1600;
  font-weight: 800;
  font-size: 0.95rem;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.avant-rebours[hidden] { display: none; }
/* Sur le grand écran la ligne du titre est horizontale : le rebours file tout à droite. */
body.ecran .avant-rebours { margin: 0 0 0 auto; align-self: baseline; font-size: 1.25rem; padding: 5px 18px; }
