/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — LA VUE PUBLIQUE ET L'ESPACE JOUEUR

   Cette feuille REDESSINE les classes existantes du site public sans en
   renommer une seule : app.js, fil.js et guide.js les visent par leur nom,
   et des attributs data-* s'y accrochent. Elle vit dans la couche « tire »,
   declaree en dernier, et prolonge assets/css/tire.css qui porte deja le kit
   et le chrome (en-tete, pied, barre d'onglets, portail de connexion).

   ⚠️ Une couche ne gagne que sur les proprietes qu'elle ECRIT. Chaque regle
   d'ici neutralise donc explicitement la mise en page ancienne de app.css,
   sable.css et des feuilles de page, media queries comprises.

   Assemblee par scratchpad/assembler_public.py depuis les blocs de chaque
   famille.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ─────────────────────────────────────────────────────────────────
   LE SOCLE COMMUN : BOUTONS, CHAMPS, CARTES, MESSAGES, TABLEAUX
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   LE SOCLE COMMUN — les composants que toutes les pages publiques partagent.

   C'est la famille qui change la peau du site entier d'un coup : le bouton,
   la carte, le champ, le message, le tableau, la pastille. Le dessin cible
   est celui des composants .tp-* de assets/css/tire.css, mesure pour mesure —
   une .carte devient une .tp-carte, un .bouton une pilule de 52 px, un .champ
   un champ rayon 12 a focus or.

   ON NE RENOMME RIEN. app.js, fil.js, guide.js et des attributs data-* visent
   ces classes par leur nom : on leur donne un DESSIN, jamais un autre nom.

   ─────────────────────────────────────────────────────────────────────────
   LA REGLE QUI GOUVERNE TOUT CE FICHIER

   Une couche ne gagne que sur les proprietes qu'elle ECRIT — mais sur
   celles-la, elle gagne TOTALEMENT : entre deux declarations normales, la
   couche passe AVANT la specificite. Une regle d'ici en .bouton (0,1,0)
   l'emporte donc sur un .cl-invite .bouton (0,2,0) des feuilles de page.

   Cela coupe dans les deux sens, et c'est ce qui dicte le decoupage :
     · ce qu'il faut redessiner, on l'ecrit ET on neutralise explicitement ce
       que l'ancienne regle posait — position, display, fond, ombre, bordure,
       rayon, rembourrage, police — media queries anciennes comprises ;
     · ce qui est deja juste, on n'y touche PAS. Reecrire la largeur de
       .jeton ferait perdre les trois tailles que les vues posent en ligne et
       le .cl-lien-joueur .jeton { display: none } du telephone. Le silence
       est ici une decision, pas un oubli — les blocs « laisse tel quel » le
       disent nommement.

   Trois pieges payes cash sur ce projet, et tenus ici :
     · aucun !important — pour les declarations !important la cascade INVERSE
       l'ordre des couches, celui-ci serait donc le plus faible de tous ;
     · light-dark() n'accepte qu'une <color> : jamais une ombre, jamais une
       url. Les ombres passent par --tp-ombre ;
     · les jetons de app.css (--gouttiere, --largeur, --arrondi, --r1..r8)
       sont declares HORS couche : une declaration sans couche bat toutes les
       couches, on ne peut donc pas les redefinir d'ici. On ne l'essaie pas —
       ce serait un silence de plus. On consomme les --tp-* a la place.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ──────────────────────────────────────────────────────── LE RYTHME ──
   sable.css avait pousse la section a clamp(4rem, 8vw, 7.5rem) : sur un
   telephone, deux blocs voisins ne tenaient plus jamais dans le meme ecran et
   la page devenait un couloir. On revient au pas de la maquette. */

.section { padding-block: clamp(2rem, 5vw, 3.25rem); }
.section-mince { padding-block: clamp(1.5rem, 4vw, 2.25rem); }

/* LAISSE TEL QUEL, et volontairement : .enveloppe, .etroit, .pile, .pile-2,
   .rang, .grille et ses declinaisons. Leur geometrie est deja la bonne, et
   les redeclarer ici ferait perdre d'un coup les surcharges contextuelles des
   feuilles de page — .feuille > .enveloppe { padding-inline: 0 } en tete.
   Une seule mesure bouge, parce qu'elle tient le rythme des deux rangees : */
.rang { gap: .75rem; }
.rang-serre { gap: .5rem; }

/* ───────────────────────────────────────────────────────── LES TITRES ──
   Le surtitre donne le ton « fiche de resultats » de toute la maquette :
   Inter 700, onze pixels, capitales espacees. */

.surtitre {
  /* On garde le flex : deux en-tetes publiques centrent leur surtitre par un
     justify-content, qui ne veut plus rien dire sur un bloc. */
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin: 0 0 .5rem;

  /* Sept vues ecrivent encore color:var(--jaune) EN LIGNE sur ce surtitre.
     Aucune regle ne peut surcharger un style en ligne sans !important — mais
     l'element, lui, lit le jeton chez lui. On redefinit donc --jaune ICI, et
     seulement ici : l'or de marque (1,9:1 sur blanc, illisible) devient l'or
     lisible sans toucher une seule vue, et sans changer l'or des boutons.
     C'est le procede que app.css emploie deja pour .scene .surtitre. */
  --jaune: var(--tp-or-lisible);
  --jaune-profond: var(--tp-or-lisible);
}

/* Le tiret d'or en ::before appartenait a l'ancienne charte ; il a deja ete
   eteint dans le panneau du comite, on fait pareil ici. On coupe par le
   « content » et non par le display : app.css, eclat.css et sable.css lui
   posent chacun une largeur, une hauteur et un fond, et trois regles
   survivantes valent mieux mortes a la racine — sans content, le pseudo
   n'est jamais engendre. */
.surtitre::before { content: none; }

.surtitre a { color: var(--tp-or-lisible); font-weight: 700; }

/* Le titre nu : trois vues publiques s'en servent dans une carte ou une
   ligne. On ne lui donne PAS de couleur — .journee.finale .titre doit rester
   encre sombre sur son aplat d'or, et cette couleur-la vit dans la feuille de
   page, qu'une couleur ecrite ici ecraserait. */
.titre {
  font-weight: 700;
  line-height: 1.25;
  margin: 0;
}

.intitule {
  display: block;
  margin: 0 0 .375rem;
  font-weight: 700;
  font-size: 13px;
  color: var(--tp-encre-2);
}

.aide {
  margin: .375rem 0 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tp-encre-3);
}

/* ────────────────────────────────────────────────────────── LA CARTE ──
   La brique de tout le site. Blanche sur le creme, rayon 16, un trait fin et
   une ombre basse : elle se detache du papier sans flotter.

   A neutraliser, dans l'ordre ou les feuilles se sont empilees :
     app.css    fond, bordure, rayon 16, rembourrage ;
     eclat.css  rayon, couleur de bordure, ombre a reflet interieur ;
     sable.css  border: 0, rayon 24, rembourrage en clamp, double ombre.
   D'ou les six proprietes reecrites a chaque fois, meme quand la valeur
   ressemble a l'ancienne : ce qu'on n'ecrit pas reste a la feuille d'avant. */

.carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1rem 1.125rem;
}

.carte-nette { border-radius: var(--tp-r-tuile); }

/* Le bleu nuit reste un APLAT : eclat.css en avait fait un degrade a trois
   arrets double d'un halo dore en ::after. Le degrade decoratif n'est pas de
   cette direction, et le halo se voyait par-dessus le texte. */
.carte-bleue {
  background: #101838;
  border-color: rgb(255 255 255 / .1);
  color: #FFFFFF;
  box-shadow: var(--tp-ombre-haut);
}

.carte-bleue::after { content: none; }

.carte-bleue :is(h1, h2, h3) { color: #FFFFFF; }
.carte-bleue .surtitre { color: var(--tp-or); }
.carte-bleue :is(p, .sous, .muet) { color: #B9C4E0; }

/* L'or plein est un FOND, jamais une lettre : l'encre qui se pose dessus est
   celle du jeton, pas du blanc. */
.carte-jaune {
  background: var(--tp-or);
  border-color: var(--tp-or-profond);
  color: var(--tp-sur-or);
  box-shadow: var(--tp-ombre);
}

.carte-jaune :is(h1, h2, h3, .titre, strong) { color: var(--tp-sur-or); }
.carte-jaune .surtitre { color: var(--tp-or-profond); }

/* La carte cerclee marque « la mienne », « celle du jour ». Un lisere a
   gauche, pas un cerclage complet : l'or en cadre ferme la carte, l'or en
   filet la designe. sable.css la cerclait d'un inset 2px sur tout le tour. */
.carte-cerclee {
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

/* La carte d'attente : « ce n'est pas encore publie ». Meme filet d'or, mais
   a gauche d'un texte, donc on garde la bordure epaisse d'origine. */
.carte-attente {
  display: grid;
  gap: .375rem;
  border-left: 3px solid var(--tp-or);
  text-align: left;
}

.carte-attente-titre {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.125rem;
  color: var(--tp-encre);
}

.carte-attente-dit {
  margin: 0;
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--tp-encre-3);
}

/* La carte cliquable repond au survol : UN pixel vers le haut, l'ombre qui
   s'ouvre. eclat.css et sable.css en levaient quatre et changeaient la
   bordure en or — a quatre pixels, une grille de cartes tressaute au passage
   de la souris. */
a.carte,
.carte-lien {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              border-color var(--tp-elan);
}

a.carte:hover,
.carte-lien:hover {
  transform: translateY(-1px);
  box-shadow: var(--tp-ombre-haut);
  border-color: var(--tp-trait-fort);
  color: inherit;
}

/* Le verre : plus aucune vue publique ne l'emploie, mais la classe vit encore
   dans app.css. On la ramene a la carte plutot que de laisser un panneau
   translucide d'une direction abandonnee reapparaitre un jour. */
.verre {
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  background: var(--tp-carte);
  box-shadow: var(--tp-ombre);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.verre::before { content: none; }

/* ─────────────────────────────────────────────────────── LES BOUTONS ──
   Pilules de 52 px (44 en petit), Inter 700 15. Un seul or par ecran : l'or
   designe LE geste, pas les gestes.

   Le bouton etait l'element le plus charge du site : eclat.css le posait en
   position relative avec un reflet en ::after qui le traversait au survol,
   sable.css le repeignait en degre dore a ombre longue. On defait les deux —
   position, isolation, overflow, bordure, rayon, rembourrage, fond, ombre,
   graisse, et le reflet par son content. */

.bouton {
  position: static;
  isolation: auto;
  overflow: visible;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 52px;
  padding: 0 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  letter-spacing: 0;
  text-decoration: none;
  cursor: pointer;
  filter: none;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              background var(--tp-elan), border-color var(--tp-elan);
}

.bouton::after { content: none; }

.bouton:hover {
  background: var(--tp-or-vif);
  color: var(--tp-sur-or);
  box-shadow: 0 4px 16px rgb(245 180 28 / .45);
  transform: none;
  filter: none;
}

.bouton:active { transform: translateY(1px); }

.bouton-petit { min-height: 44px; padding: 0 1.125rem; font-size: 14px; }
.bouton-large { width: 100%; }

/* Le marine : le second geste, celui qui n'a pas droit a l'or. */
.bouton-bleu {
  background: light-dark(#1D1838, #FFFFFF);
  color: light-dark(#FFFFFF, #101838);
  border-color: transparent;
  box-shadow: none;
}

.bouton-bleu:hover {
  background: light-dark(#2B2450, #E9EDF8);
  color: light-dark(#FFFFFF, #101838);
}

/* Le bouton vide devient le fantome du kit : un trait, pas une carte.
   sable.css lui donnait un fond blanc et une ombre — sur une page de cartes
   blanches, il devenait une carte de plus au lieu d'un geste discret. Et
   eclat.css lui posait un backdrop-filter, qui coute une couche de
   composition pour un bouton qu'on ne voit pas a travers. */
.bouton-vide {
  background: transparent;
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

.bouton-vide:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
}

/* Vert et rouge se disent par le duo texte + fond du kit, jamais par un aplat
   sature : a cette taille, du blanc sur du rouge plein crie plus fort que
   l'or, et l'or doit rester le seul accent de l'ecran. */
.bouton-vert {
  background: var(--tp-vert-fond);
  color: var(--tp-vert);
  border-color: transparent;
  box-shadow: none;
}

.bouton-vert:hover {
  background: color-mix(in oklab, var(--tp-vert-fond) 75%, var(--tp-vert) 12%);
  color: var(--tp-vert);
}

.bouton-danger {
  background: var(--tp-rouge-fond);
  color: var(--tp-rouge);
  border-color: transparent;
  box-shadow: none;
}

.bouton-danger:hover {
  background: color-mix(in oklab, var(--tp-rouge-fond) 75%, var(--tp-rouge) 12%);
  color: var(--tp-rouge);
}

.bouton[disabled],
.bouton[aria-disabled="true"] {
  opacity: .5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

/* ──────────────────────────────────────────────────────── LES CHAMPS ──
   Rayon 12, fond carte, bordure marquee, et un focus qui se VOIT : l'anneau
   or double d'un halo. Un champ dont on ne sait pas qu'il a le curseur est un
   formulaire qu'on remplit deux fois.

   ⚠️ LE DEFAUT LE PLUS VISIBLE DU SITE. Dans les vues publiques, .champ est
   TOUJOURS le conteneur — <div class="champ"><label>…<input>. sable.css le
   peignait pourtant comme le champ lui-meme : fond blanc, rayon 14, ombre
   interieure, rembourrage. Le libelle et le texte d'aide se retrouvaient
   enfermes dans une boite blanche, avec le vrai champ dans une seconde boite
   a l'interieur. On rend donc au conteneur sa transparence, propriete par
   propriete, avant de dessiner la commande. */

.champ {
  display: flex;
  flex-direction: column;
  gap: .375rem;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

.champ > label {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tp-encre-2);
}

.champ :is(input, select, textarea) {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-size: 15px;
  color: var(--tp-encre);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

.champ textarea { min-height: 96px; line-height: 1.55; resize: vertical; }

.champ ::placeholder { color: var(--tp-encre-4); }

.champ :is(input, select, textarea):focus,
.champ :is(input, select, textarea):focus-visible {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* :user-invalid plutot que :invalid — on ne souligne pas en rouge un champ
   que la personne n'a pas encore touche. */
.champ :is(input, select, textarea):user-invalid {
  border-color: var(--tp-rouge);
  box-shadow: 0 0 0 3px rgb(201 52 43 / .18);
}

/* La case et le bouton radio ne sont pas des champs de saisie : ils ne
   prennent ni la largeur, ni la hauteur, ni le cadre. Sans ce retour en
   arriere, la regle ci-dessus en faisait des rectangles de 48 px. */
.champ :is([type="checkbox"], [type="radio"]) {
  width: 22px;
  min-width: 22px;
  height: 22px;
  min-height: 22px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  accent-color: var(--tp-or-lisible);
  flex: 0 0 auto;
}

/* La ligne « case + libelle » : 44 px de cible tactile, on la coche avec des
   gants un dimanche de novembre. */
.champ-inline {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: .625rem;
  min-height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
}

.champ-inline label {
  font-weight: 600;
  font-size: 15px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tp-encre);
  cursor: pointer;
}

/* ─────────────────────────────────────────────────────── LES MESSAGES ──
   Le duo icone + phrase sur fond teinte. Jamais la couleur seule.
   app.css les barrait d'un filet de 4 px a gauche, eclat.css et sable.css les
   faisaient monter a l'ouverture de la page : un message qui bouge pendant
   qu'on le lit se relit deux fois. */

.message {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  padding: .875rem 1rem;
  border: 0;
  border-radius: var(--tp-r-champ);
  background: var(--tp-creux);
  color: var(--tp-encre);
  box-shadow: none;
  font-size: 14px;
  animation: none;
}

.message svg { flex: 0 0 auto; margin-top: .0625rem; }

.message-succes { background: var(--tp-vert-fond);  color: var(--tp-vert); }
.message-erreur { background: var(--tp-rouge-fond); color: var(--tp-rouge); }
.message-info   { background: var(--tp-ambre-fond); color: var(--tp-ambre); }

/* ───────────────────────────────────────────────────────── LES TABLES ──
   Le classement, les journees, les feuilles de jeu. En-tete en petites
   capitales grises, lignes de 52 px, zebrage tres leger, et des chiffres
   TABULAIRES : sans eux les colonnes de points dansent d'une ligne a l'autre.

   On NE rend PAS l'en-tete collant, contrairement a .tp-table : sur le site,
   toutes les tables ne vivent pas dans une boite a defilement, et un th en
   position sticky irait se coller sous l'en-tete du site au milieu de la
   page. */

.tableau {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--tp-texte);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.tableau th {
  padding: .75rem;
  background: transparent;
  text-align: left;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  border-bottom: 1px solid var(--tp-trait);
  white-space: nowrap;
}

.tableau td {
  padding: .75rem;
  height: 52px;
  border-bottom: 1px solid var(--tp-trait);
  color: var(--tp-encre);
}

.tableau tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--tp-creux) 40%, transparent);
}

.tableau tbody tr:last-child td { border-bottom: 0; }

/* Le survol passe par-dessus le zebrage : sinon une ligne sur deux ne repond
   pas a la souris. */
.tableau tbody tr:hover td {
  background: color-mix(in oklab, var(--tp-creux) 55%, transparent);
}

.tableau :is(th, td).nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* La boite a defilement EST la carte de la table : c'est elle qui porte le
   fond, le trait et l'ombre, la table n'en a aucun. Le rembourrage que
   sable.css et eclat.css lui donnaient decalait la premiere colonne du bord
   et cassait l'alignement avec les cartes voisines. */
.defile {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: 0;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
}

/* Sur telephone, un tableau ne se fait pas defiler : il se simplifie. La
   compaction vivait dans une media query de app.css, que les valeurs
   ci-dessus emporteraient a toutes les largeurs — on la rejoue donc ici, au
   meme point de rupture, sinon les colonnes reviennent a 12 px de
   rembourrage sur un ecran de 390. */
@media (max-width: 720px) {
  .tableau { font-size: 13px; }
  .tableau :is(th, td) { padding-inline: .5rem; }
  .tableau td { height: 48px; }
  .tableau th { font-size: 10px; letter-spacing: .06em; }
}

/* ────────────────────────────────────────────────────── LES PASTILLES ──
   Vingt-quatre pixels, Inter 700 11 capitales, le duo texte + fond de chaque
   teinte de sens : l'etat reste lisible a cette taille.

   ⚠️ Aucun repere en ::before. Un point de couleur aide quand il INFORME ;
   sur « Inscrit », « Neutre », « Publie », il ajoute une tache a lire sans
   rien dire de plus. Le mot porte deja l'etat, c'est tout l'interet du duo.

   Note de cascade : tire.css donne a .pastille le dessin du COMPTEUR rouge de
   l'en-tete. Cette feuille etant chargee apres, la pastille redevient ici
   l'etiquette d'etat des 105 vues qui l'emploient — et le compteur est rendu
   a l'en-tete, juste en dessous, par un selecteur plus specifique : il tient
   donc quel que soit l'ordre des deux fichiers. */

.pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  min-width: 0;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  box-shadow: none;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
}

.pastille-bleue {
  background: light-dark(#1D1838, #FFFFFF);
  border: 0;
  color: light-dark(#FFFFFF, #101838);
}

.pastille-verte  { background: var(--tp-vert-fond);  color: var(--tp-vert); }
.pastille-rouge  { background: var(--tp-rouge-fond); color: var(--tp-rouge); }
.pastille-ambre  { background: var(--tp-ambre-fond); color: var(--tp-ambre); }
.pastille-neutre { background: var(--tp-creux);      color: var(--tp-encre-3); }

.pastille-vide {
  background: transparent;
  border: 1px solid var(--tp-trait-fort);
  color: var(--tp-encre-2);
}

/* Le compteur de l'en-tete : la, le chiffre doit se lire a 18 px, donc du
   rouge plein et du blanc dessus — jamais un pale sur pale. C'est le seul
   endroit ou .pastille n'est pas une etiquette d'etat. */
.nav .pastille {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  padding: 0 .3125rem;
  background: var(--tp-rouge);
  color: #FFFFFF;
  letter-spacing: 0;
  text-transform: none;
}

/* ────────────────────────────────────────── LES CHIFFRES ET LEURS MOTS ──
   Le chiffre en Playfair, son intitule en petites capitales grises. C'est le
   couple de la tuile du kit, et il revient partout : bilan, fiche joueur,
   vitrine. app.css les composait en Big Shoulders 900 — la condensee qui
   criait, precisement ce qu'on enleve. */

.chiffre {
  font-family: var(--tp-titre);
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
  text-shadow: none;
}

.chiffre-xl { font-size: clamp(1.875rem, 1.4rem + 2.2vw, 2.75rem); }
.chiffre-l  { font-size: 1.625rem; }
.chiffre-m  { font-size: 1.25rem; }

/* L'etiquette est un intitule nu, jamais une pilule : les pages la posent
   sous un chiffre et lui donnent elles-memes son display, qu'on se garde
   donc d'ecrire. */
.etiquette {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* ───────────────────────────────────────────────────────── LE JETON ──
   L'avatar du site : les initiales d'un joueur, le numero d'une equipe.

   On n'ecrit ICI que la matiere — fond, encre, cercle de detourage. Ni
   largeur, ni hauteur, ni taille de texte, ni display : trois vues posent ces
   trois mesures en ligne pour des jetons de 22, 28 et 44 px, et le classement
   masque le sien sous 460 px. Tout cela vit dans des regles moins fortes que
   cette couche et serait perdu a la premiere propriete de trop.

   eclat.css en faisait une bille en degrade cerclee de deux anneaux dores,
   sable.css une pastille a double ombre portee : on remet a plat. */

.jeton {
  background: var(--tp-creux);
  border: 2px solid var(--tp-carte);
  color: var(--tp-encre-2);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
}

.jeton-or {
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: none;
}

/* ─────────────────────────────────────────────── LA NUEE DE JOUEURS ──
   Chaque nom est une puce du kit, et une cible tactile confortable. */

.nom-joueur {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  padding: .25rem .875rem .25rem .3125rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  background: var(--tp-carte);
  box-shadow: none;
  color: var(--tp-encre-2);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  transition: border-color var(--tp-elan), background var(--tp-elan);
}

.nom-joueur:hover {
  border-color: var(--tp-trait-fort);
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  color: var(--tp-encre);
}

/* ────────────────────────────────────────────────────────── LE VIDE ──
   Un ecran vide dit ce qui manque ET donne le geste pour le remplir. Une page
   blanche avec « aucun resultat » laisse la personne sur place.

   On garde le cercle trace au pied dans le gravier — c'est une signature, et
   elle dit « rien a classer » avant la phrase. On le repose seulement sur les
   jetons du kit. */

.etat-vide {
  display: grid;
  justify-items: center;
  gap: .75rem;
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--tp-encre-3);
}

.etat-vide::before {
  border-color: var(--tp-trait-fort);
  width: 76px;
  height: 76px;
}

.etat-vide :is(h2, h3, .titre) {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.15;
  color: var(--tp-encre);
  margin: 0;
}

.etat-vide p {
  margin: 0;
  max-width: 42ch;
  font-size: 14px;
  color: var(--tp-encre-3);
}

/* ─────────────────────────────────────────────────────── LES UTILITAIRES ──
   Ils ne changent qu'une propriete chacun : on se contente de les rebrancher
   sur les jetons du kit. */

.muet  { color: var(--tp-encre-3); }
.petit { font-size: 13px; }
.minus { font-size: 12px; }

/* L'or ne s'ECRIT jamais en petit sur du clair : .jaune portait --jaune-profond,
   soit 1,9:1 sur une carte blanche. Il passe par l'or lisible. */
.jaune { color: var(--tp-or-lisible); }
.bleu  { color: var(--tp-encre); }
.vert  { color: var(--tp-vert); }
.rouge { color: var(--tp-rouge); }

.nombres { font-variant-numeric: tabular-nums; }

/* LAISSE TEL QUEL : .gras, .tres-gras, .centre, .droite, .plein, .rien,
   .coupe, .invisible et les marges .mt-* / .mb-*. Ce sont des mesures, pas un
   dessin — les reecrire n'aurait rien change qu'un risque. */

/* ─────────────────────────────────────────────────── LE FOCUS CLAVIER ──
   Une seule regle pour tout le socle : l'anneau or et son halo. On garde
   :focus-visible — l'anneau apparait au clavier, pas sous la souris. Les
   champs gardent le leur, deja dessine plus haut sur la bordure.

   La regle reste NOMMEE plutot que globale : un :focus-visible nu d'ici
   repeindrait aussi le panneau du comite, qui a le sien. */

.bouton:focus-visible,
a.carte:focus-visible,
.carte-lien:focus-visible,
.nom-joueur:focus-visible,
.pastille:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* ────────────────────────────────────────────── LE MOUVEMENT, EN MOINS ──
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. Les entrees en cascade de eclat.css et
   sable.css sont deja eteintes plus haut, a la source. */

@media (prefers-reduced-motion: reduce) {
  .bouton,
  a.carte,
  .carte-lien,
  .nom-joueur,
  .champ :is(input, select, textarea) {
    transition: none;
  }

  a.carte:hover,
  .carte-lien:hover,
  .bouton:active { transform: none; }
}

} /* fin de la couche */


/* ─────────────────────────────────────────────────────────────────
   L'ACCUEIL, LA VITRINE DU CIRCUIT
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — L'ACCUEIL, au dessin du kit.

   La vitrine du circuit, redessinee sur les jetons de assets/css/tire.css :
   papier creme, encre bleu nuit, UN SEUL accent or. Les classes ne changent
   pas d'un caractere — app.js vise [data-dispo] et bascule lui-meme
   « bouton / bouton-vide / bouton-bleu » sur les trois reponses, eclat.js pose
   [data-reveler] sur chaque .carte, .journee et .ligne-classement de la page.
   On leur donne un DESSIN, pas un autre nom.

   CE QUI DISPARAIT, ET POURQUOI
     · « Le circuit connecte. » en Big Shoulders condense capitales : c'etait la
       signature de l'ancienne charte. Playfair, casse normale, deux tiers de la
       taille. Le titre ne crie plus, il se lit.
     · Les six degrades de la vitrine (badges, boutons, jetons, marches du
       podium) : un aplat et un liseré disent la meme chose sans le vernis.
     · Les quatre couches de ciel derriere la carte de la journee. Sur le
       panneau bleu nuit elles se voyaient ; sur une carte blanche, une pluie en
       repeating-linear-gradient derriere un texte de 15 px devient du bruit.
       La phrase (« Ca risque de dracher sur Latour ») et la ligne de chiffres
       portaient DEJA l'information a elles seules : rien ne se perd.
     · L'entree en cascade des bandeaux et le devoilement au defilement. Le kit
       tranche la question dans son propre commentaire — « une page qui se monte
       sous les yeux fait perdre plus de temps qu'elle n'en donne ».

   ⚠️ CE QUI NE SE GAGNE PAS PAR LA CASCADE
   sable.css se termine par un bloc HORS COUCHE (apres son « } @layer sable »),
   et une declaration hors couche l'emporte sur TOUTE couche, la derniere
   comprise : ni « tire », ni aucune specificite, ne passe devant. Sur .acc-scene
   et .acc-etat ce bloc fixe la couleur du h1, du sous-titre et du surtitre — et
   sur .acc-etat il le fait en !important, terrain ou l'ordre des couches
   s'INVERSE et ou « tire » est la plus faible.
   D'ou le procede tenu plus bas : on ne se bat pas contre ces declarations, on
   REDEFINIT SUR NOS PROPRES ELEMENTS les jetons qu'elles lisent (--encre,
   --encre-2, --or-800, --s-rayon-l…). « color: var(--encre) !important » reste
   en place et resout notre encre. Un jeton pose sur .acc-scene ne concourt pas
   avec celui de :root — ce sont deux elements differents, la cascade ne les
   compare jamais. Zero !important, et le bloc hors couche travaille pour nous.

   Cette feuille est dans la couche « tire », declaree EN DERNIER : elle passe
   devant socle, composants, pages (p-accueil.css), utilitaires, eclat et les
   regles EN COUCHE de sable sans un seul !important.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ════════════════════════════════════════════════ 1. LE CADRE DE LA PAGE ══
   L'ordre reste celui du document : Moment::blocs() le produit, la vue le pose.
   La grille ne decide que de la LARGEUR d'un bloc, jamais de sa place dans la
   lecture — donc aucun « order » ici. */

.horloge {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 1.25rem;
  padding-block: 0 1.5rem;
}

.horloge > * { min-width: 0; }

/* minmax(0, 1fr) et non 1fr : sans le zero, un nom d'equipe long pousse la
   colonne au-dela de la page et le text-overflow cesse d'operer. */
@media (min-width: 62rem) {
  .horloge { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.5rem; }
  .horloge > .acc-bloc-large { grid-column: 1 / -1; }
}

/* Les jours ou l'on joue, l'ecran ne se partage pas. Le selecteur d'attribut
   porte sa propre specificite : il gagne sur la media query quel que soit
   l'ordre d'ecriture, puisqu'une media query n'en ajoute aucune. */
.horloge[data-moment="tirage"],
.horloge[data-moment="direct"] { grid-template-columns: minmax(0, 1fr); }

/* Les deux sections de la page respiraient sur trois a cinq rem : c'etait le
   rythme des pages produit, pas celui d'une fiche de resultats. :has() vise la
   section de l'accueil sans toucher aux dix autres pages qui portent
   « section-mince ». */
.section-mince:has(> .enveloppe > .horloge) {
  padding-block: clamp(1rem, 2.5vw, 1.75rem) clamp(1.5rem, 4vw, 2.5rem);
}

.section-mince:has(> .enveloppe > .vit-rangee) {
  padding-block: 0 clamp(1.5rem, 4vw, 2.5rem);
}

/* Le site s'installe en PWA : en paysage sur iPhone, l'encoche mange la
   gouttiere. env() garde son repli a 0 pour que la declaration reste valide
   partout. */
:is(.acc-scene, .acc-etat, .vit-hero) > .enveloppe,
.section-mince:has(> .enveloppe > .horloge) > .enveloppe,
.section-mince:has(> .enveloppe > .vit-rangee) > .enveloppe {
  padding-inline: max(var(--gouttiere, 1rem), env(safe-area-inset-left, 0px));
}

/* ═══════════════════════════════════════════════════════ 2. LA VITRINE ══
   Le visiteur non connecte n'a rien a comprendre : une phrase, l'application,
   la preuve. C'est la seule page du site ou le titre a le droit d'etre grand. */

.vit-hero {
  padding-block: clamp(2.25rem, 5vw, 3.75rem) 0;
  text-align: center;
}

.vit-hero > .enveloppe {
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Le surtitre du kit : Inter 700, onze pixels, capitales espacees. Le filet
   d'or de l'ancien composant tombe — .tp-surtitre n'en a pas, et deux
   grammaires d'en-tete sur une meme page se voient. */
.vit-hero .surtitre,
.vit-titre .surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--tp-encre-3);
  margin: 0 0 .625rem;
}

.vit-hero .surtitre::before,
.vit-titre .surtitre::before { content: none; }

/* LE CLAIM. Playfair 700 en casse normale, a peu pres la moitie des 9,5 rem
   d'avant : a cette taille le condense capitales etait une affiche de meeting.
   text-wrap: balance evite le mot solitaire sur la derniere ligne. */
.vit-claim {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(2rem, 1.35rem + 3.1vw, 3.75rem);
  line-height: 1.08;
  letter-spacing: -.015em;
  text-transform: none;
  color: var(--tp-encre);
  max-width: 16ch;
  margin: .25rem 0 0;
  text-wrap: balance;
}

/* « connecte. » : l'or qui PORTE du texte passe toujours par --tp-or-lisible.
   L'or plein fait 1,9:1 sur blanc — il est un fond, jamais une lettre. */
.vit-claim em {
  font-style: normal;
  color: var(--tp-or-lisible);
}

.vit-lead {
  margin: clamp(1rem, 2.5vw, 1.5rem) auto 0;
  max-width: 54ch;
  font-family: var(--tp-texte);
  font-size: clamp(1rem, .95rem + .35vw, 1.125rem);
  font-weight: 400;
  line-height: 1.6;
  color: var(--tp-encre-2);
  text-wrap: pretty;
}

.vit-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .625rem;
  margin-top: clamp(1.25rem, 3vw, 1.75rem);
}

/* — LES MAGASINS —
   La pilule marine du kit. L'ancien badge etait un aplat #0F1733 en dur : la
   nuit, une pastille sombre sur un fond sombre. light-dark() ne recoit ici
   qu'une <color>, seul usage que la fonction accepte. */
.vit-badges {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .5rem;
  margin-top: 1rem;
}

.vit-badge {
  display: inline-flex;
  align-items: center;
  gap: .625rem;
  min-height: 44px;
  padding: .5rem .9375rem .5rem .625rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: light-dark(#1D1838, #FFFFFF);
  color: light-dark(#FFFFFF, #101838);
  box-shadow: none;
  text-decoration: none;
  line-height: 1.1;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

.vit-badge:hover {
  background: light-dark(#2B2450, #E9EDF8);
  color: light-dark(#FFFFFF, #101838);
  transform: none;
  box-shadow: none;
}

.vit-badge svg { width: 22px; height: 22px; flex: 0 0 auto; }

.vit-badge small {
  display: block;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .04em;
  opacity: .78;
}

.vit-badge b {
  display: block;
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0;
}

/* Android n'est pas encore la : la pilule devient fantome, pas une pilule
   grise — une pilule pleine promet un lien qui n'existe pas. */
.vit-badge.bientot,
.vit-badge.bientot:hover {
  background: transparent;
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre-2);
  box-shadow: none;
  cursor: default;
}

/* — LES TROIS TELEPHONES —
   Le bandeau photo qui montait derriere eux (::before, image + masque) tombe :
   sur le papier creme, une photo de coucher de soleil en fond de scene remet
   le vernis qu'on vient d'enlever. Les telephones se suffisent. */
.vit-scene {
  position: relative;
  isolation: auto;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: clamp(.5rem, 2vw, 1.25rem);
  width: 100%;
  margin-top: clamp(1.75rem, 4vw, 3rem);
  padding: 0;
}

.vit-scene::before { content: none; }

.telephone {
  flex: 0 0 auto;
  width: clamp(120px, 22vw, 230px);
  aspect-ratio: 9 / 18.6;
  padding: clamp(5px, .8vw, 8px);
  border-radius: clamp(20px, 3vw, 34px);
  background: #101838;
  box-shadow: var(--tp-ombre-haut), inset 0 0 0 1px rgb(255 255 255 / .12);
  overflow: hidden;
  animation: none;
}

.telephone img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
  border-radius: calc(clamp(20px, 3vw, 34px) - clamp(5px, .8vw, 8px));
}

.vit-scene .telephone.grand { width: clamp(150px, 27vw, 278px); z-index: 1; }
.vit-scene .telephone.gauche { transform: translateY(6%) rotate(-3deg); }
.vit-scene .telephone.droite { transform: translateY(6%) rotate(3deg); }

/* — LES COMPTEURS —
   Le dessin de .tp-tuile : chiffre Playfair, intitule en petites capitales.
   Les chiffres sont TABULAIRES — quatre tuiles cote a cote dont les chiffres
   dansent, ca se voit. */
.vit-chiffres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: .75rem;
  width: 100%;
  margin-top: clamp(1.75rem, 4vw, 2.5rem);
}

.vit-chiffres .carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: .9375rem .75rem;
  text-align: center;
}

.vit-chiffres .chiffre {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.4rem + 1.4vw, 2.25rem);
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
  margin: 0;
}

.vit-chiffres small {
  display: block;
  margin-top: .25rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* — LES RANGEES — */

.vit-rangee {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  padding-block: clamp(2rem, 5vw, 3.5rem);
}

.vit-rangee.inverse > .vit-texte { order: 2; }

.vit-texte h2 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  max-width: 18ch;
  margin: 0;
  text-wrap: balance;
}

.vit-texte p {
  margin-top: .75rem;
  max-width: 46ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--tp-encre-2);
}

.vit-texte ul {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: grid;
  gap: .5rem;
  max-width: 46ch;
}

.vit-texte li {
  position: relative;
  padding-left: 1.5rem;
  font-size: 14.5px;
  font-weight: 500;
  color: var(--tp-encre);
}

/* Une puce n'est pas une information : l'or plein y est a sa place, il ne
   porte aucune lettre. */
.vit-texte li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .5em;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--tp-or);
}

.vit-visuel {
  position: relative;
  aspect-ratio: 5 / 4;
  border-radius: var(--tp-r-carte);
  margin-bottom: 1.5rem;
}

.vit-visuel > picture {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: var(--tp-r-carte);
  overflow: hidden;
  background: var(--tp-creux);
  box-shadow: var(--tp-ombre-haut);
}

.vit-visuel > picture > img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Le telephone pose sur la photo ne flotte plus en boucle : une animation
   infinie dans le coin de l'oeil se paye pendant toute la lecture. */
.vit-visuel .telephone {
  position: absolute;
  right: 8%;
  bottom: -6%;
  width: clamp(110px, 34%, 215px);
  transform: rotate(-4deg);
  animation: none;
}

/* — LE TRIO — */

.vit-trio {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: .75rem;
  margin-top: clamp(1.25rem, 3vw, 2rem);
}

.vit-trio .carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.25rem 1.125rem;
}

.vit-trio .icone { color: var(--tp-or-lisible); }

.vit-trio h3 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.2;
  color: var(--tp-encre);
  margin: .75rem 0 .375rem;
}

.vit-trio p { font-size: 14px; line-height: 1.55; color: var(--tp-encre-2); margin: 0; }

/* — LE TITRE DE SECTION — */

.vit-titre {
  text-align: center;
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
}

.vit-titre h2 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  margin: 0;
  text-wrap: balance;
}

.vit-titre p {
  margin: .5rem auto 0;
  max-width: 52ch;
  font-size: 15px;
  color: var(--tp-encre-2);
}

/* — L'APPEL, EN BLEU NUIT —
   Le pied d'appel a l'action reprend le dessin du pied de page : bleu nuit
   texture, intitules or, liens blanc casse. La photo de boulodrome et son
   voile tombent — le papier de nuit tient la surface tout seul.
   Le surtitre porte un style= en ligne « color: var(--or-300) » qu'aucune
   feuille ne peut reprendre : on redefinit donc --or-300 ICI, et le style en
   ligne resout notre or. */
.vit-nuit {
  --or-300: var(--tp-or);
  position: relative;
  isolation: auto;
  overflow: hidden;
  border: 1px solid rgb(255 255 255 / .1);
  border-radius: var(--tp-r-carte);
  background-color: #101838;
  background-image: url("../img/charte/papier_nuit.png");
  background-size: 512px;
  box-shadow: var(--tp-ombre-haut);
  color: #E9EDF8;
  padding: clamp(1.5rem, 4vw, 2.25rem);
}

.vit-nuit::before,
.vit-nuit::after { content: none; }

.vit-nuit h2 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.375rem, 1.1rem + 1.3vw, 2rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: #FFFFFF;
  margin: .25rem 0 0;
  text-wrap: balance;
}

.vit-nuit p { font-size: 15px; line-height: 1.6; color: #B9C4E0; }

.vit-nuit .vit-badges { justify-content: flex-start; margin-top: 1.25rem; }
.vit-nuit .vit-badge { background: #FFFFFF; color: #101838; border-color: transparent; }
.vit-nuit .vit-badge:hover { background: #E9EDF8; color: #101838; }

.vit-nuit .vit-badge.bientot,
.vit-nuit .vit-badge.bientot:hover {
  background: transparent;
  border-color: rgb(255 255 255 / .3);
  color: #B9C4E0;
}

.vit-qr {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 1.5rem;
}

.vit-qr img {
  width: 92px;
  height: 92px;
  padding: 6px;
  border-radius: var(--tp-r-champ);
  background: #FFFFFF;
}

.vit-qr small { max-width: 28ch; font-size: 13px; color: #B9C4E0; }

/* ══════════════════════════════════════════════════ 3. LES DEUX BANDEAUX ══
   La page s'ouvre sur une SCENE photo hors saison, sur un ETAT du circuit des
   qu'il se passe quelque chose. Les deux sont tenus par le bloc hors couche de
   sable (§ en-tete) : on lui donne nos jetons plutot que de lui disputer ses
   declarations. */

/* — LA SCENE —
   Hors couche, sable fixe deja : display flex colonne, photo en carte sous le
   texte (position, inset, largeur, hauteur, marge, rayon, ordre), ::before et
   ::after a « content: none », enveloppe en bloc sans hauteur minimale. C'est
   une mise en page saine : on la garde et on l'habille.
   Les trois jetons ci-dessous sont lus par ses declarations verrouillees —
   c'est par eux, et seulement par eux, que l'encre devient la notre. */
.acc-scene {
  --encre:     var(--tp-encre);
  --encre-2:   var(--tp-encre-2);
  --or-800:    var(--tp-or-lisible);
  --s-rayon-l: var(--tp-r-carte);
  padding-block: clamp(1.5rem, 4vw, 2.5rem) 0;
  background: transparent;
}

.acc-scene > picture { box-shadow: var(--tp-ombre); }

.acc-scene > .enveloppe { padding-top: 0; }

/* Playfair, casse normale. La couleur vient du hors-couche via --encre : on ne
   la redeclare pas, elle serait perdante. */
.acc-scene h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.75rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  text-wrap: balance;
  margin: 0 0 .5rem;
}

.acc-scene-surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
  margin: 0 0 .5rem;
}

.acc-scene-surtitre::before { content: none; }

.acc-scene-sous {
  max-width: 46ch;
  font-family: var(--tp-texte);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  margin: 0;
}

/* — L'ETAT DU CIRCUIT —
   La boule en filigrane, la photo de coucher et le voile en trois degrades
   s'en vont : l'etat est une LIGNE de la page, pas une affiche.
   Les jetons remappes ici sont ceux que lit le bloc !important hors couche de
   sable (h1, sous-titre, surtitre, pastilles, boutons, champs). Une fois
   remappes, ses declarations peignent nos couleurs et il n'y a plus rien a
   leur disputer. */
.acc-etat {
  --encre:      var(--tp-encre);
  --encre-2:    var(--tp-encre-2);
  --encre-3:    var(--tp-encre-3);
  --carte:      var(--tp-carte);
  --trait-2:    var(--tp-trait-fort);
  --or-500:     var(--tp-or);
  --or-400:     var(--tp-or-vif);
  --or-800:     var(--tp-encre-3);
  --marine-900: var(--tp-sur-or);
  --vert:       var(--tp-vert);
  --rouge:      var(--tp-rouge);
  --blanc:      var(--tp-carte);
  --s-ombre-1:  var(--tp-ombre);
  --s-ombre-2:  var(--tp-ombre-haut);
  position: relative;
  isolation: auto;
  background: transparent;
  padding-block: clamp(1.5rem, 4vw, 2.5rem) clamp(1rem, 2.5vw, 1.5rem);
}

.acc-etat-or,
.acc-etat-marine { background: transparent; }

.acc-etat::before,
.acc-etat::after { content: none; }

/* Le nom du terrain arrive DEJA en capitales depuis la vue (Moment + mb_strtoupper) :
   aucune feuille ne peut le remettre en casse normale. On l'assume donc en
   plaque gravee — Playfair, un rien d'interlettrage, et une taille de titre de
   page au lieu des 7,4 rem d'affiche. */
.acc-etat h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.75rem);
  line-height: 1.15;
  letter-spacing: .01em;
  text-shadow: none;
  text-wrap: balance;
  margin: 0 0 .375rem;
}

.acc-etat-surtitre {
  display: inline-flex;
  align-items: center;
  gap: 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
  margin: 0 0 .5rem;
}

.acc-etat-surtitre::before { content: none; }

/* « En direct », « Aujourd'hui » : quelque chose se passe A CETTE MINUTE. Un
   etat se dit par un duo texte + fond — le mot le dit, l'etiquette ambre le
   confirme. Jamais la couleur seule. */
.acc-etat-or { --or-800: var(--tp-or-lisible); }

.acc-etat-or .acc-etat-surtitre {
  height: 24px;
  padding: 0 .5625rem;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  letter-spacing: .06em;
}

.acc-etat-sous {
  max-width: 60ch;
  font-family: var(--tp-texte);
  font-size: 14px;
  font-weight: 600;
  margin: .375rem 0 0;
}

/* La phrase du jour garde son italique, sa taille et sa marge : le bloc hors
   couche les ecrit, et une couche ne peut pas les reprendre. Sa famille et sa
   couleur, elles, nous reviennent — la couleur par le remap ci-dessus. */
.acc-phrase-jour { font-family: var(--tp-texte); }

/* ═══════════════════════════════════════════════════ 4. LES TITRES DE BLOC ══
   Six fois sur la page. Le composant du socle les met en flex avec un filet
   d'or de 24 px ; .tp-surtitre n'en a pas. On aligne sur le kit. */

.acc-bloc .surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.3;
  color: var(--tp-encre-3);
  margin: 0 0 .5rem;
}

.acc-bloc .surtitre::before { content: none; }

/* « Tout voir » : le seul or ecrit de la rangee, donc --tp-or-lisible. */
.acc-bloc > .rang > a,
.acc-series .rang > a {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 13px;
  color: var(--tp-or-lisible);
  text-decoration: none;
  white-space: nowrap;
}

.acc-bloc > .rang > a:hover,
.acc-series .rang > a:hover { text-decoration: underline; }

.acc-bloc > .rang.entre { align-items: baseline; margin-bottom: .5rem; }

.acc-bloc .actions {
  display: flex;
  flex-wrap: wrap;
  gap: .625rem;
  margin-top: 1rem;
}

/* ═════════════════════════════════════════════════════════ 5. LA JOURNEE ══
   Le panneau bleu nuit devient une carte blanche au lisere d'or : c'est la
   journee qui vient, la seule de la page a le porter. */

.acc-journee {
  position: relative;
  isolation: auto;
  overflow: visible;
  background: var(--tp-carte);
  color: var(--tp-encre);
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
  padding: 1.125rem 1.25rem;
}

/* Les quatre ciels (drache, cagnard, vent, frais) : voir l'en-tete. La phrase
   et les chiffres portaient deja l'information. */
.acc-journee[data-ciel]::before { content: none; }

.acc-journee > .rang.entre { align-items: center; }

/* Le nom du terrain, capitales de la vue, la encore. */
.acc-journee .lieu {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.15rem + 1.4vw, 2rem);
  line-height: 1.15;
  letter-spacing: .01em;
  color: var(--tp-encre);
  margin: .625rem 0 0;
}

.acc-journee .detail {
  color: var(--tp-encre-2);
  font-size: 14px;
  font-weight: 500;
  margin: .375rem 0 0;
}

.acc-journee .detail svg { color: var(--tp-encre-4); flex: 0 0 auto; }

.acc-delai {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 .5625rem;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.acc-ciel {
  margin: 1rem 0 0;
  padding-left: .8125rem;
  border-left: 3px solid var(--tp-or);
  color: var(--tp-encre);
  font-size: 15px;
  font-weight: 600;
  line-height: 1.45;
  max-width: 44ch;
}

.acc-ciel-chiffres {
  margin: .25rem 0 0 .8125rem;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
}

/* Une journee annulee : ambre, jamais rouge. Personne n'a rien casse, il
   drache. La pastille rouge de la vue dit l'etat, cette phrase dit la suite. */
.acc-annulee {
  margin: 1rem 0 0;
  padding: .75rem .9375rem;
  border-left: 4px solid var(--tp-ambre);
  border-radius: 0 var(--tp-r-champ) var(--tp-r-champ) 0;
  background: var(--tp-ambre-fond);
  color: var(--tp-ambre);
  font-size: 14px;
  font-weight: 600;
}

/* Qui vient : la file de jetons puis le compte. Cible tactile pleine largeur,
   et un filet qui marque la fin de la carte. */
.acc-presents {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: .75rem;
  min-height: 44px;
  margin-top: 1rem;
  padding-top: .875rem;
  border-top: 1px solid var(--tp-trait);
  color: var(--tp-encre-3);
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  transition: color var(--tp-elan);
}

.acc-presents:hover { color: var(--tp-or-lisible); }
.acc-presents:hover .acc-presents-mot { text-decoration: underline; }
.acc-presents-mot { min-width: 0; }

/* ══════════════════════════════════════════════════════════ 6. ET MOI ? ══
   Le seul endroit de l'accueil qui parle du lecteur — ou, s'il n'est pas
   entre, la porte du circuit. */

.acc-porte,
.acc-moi,
.acc-podium-carte,
.acc-fil-carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.125rem 1.25rem;
}

/* La porte se distingue par le lisere d'or du kit, pas par un cadre dore
   complet : un rectangle or autour d'un bloc de texte fatigue la lecture. */
.acc-porte.carte-cerclee {
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

.acc-porte-titre {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.25rem, 1.05rem + .9vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  margin: 0;
}

.acc-porte-texte,
.acc-moi-vide {
  margin: .5rem 0 0;
  max-width: 52ch;
  font-size: 15px;
  line-height: 1.6;
  color: var(--tp-encre-2);
}

.acc-moi-chiffres {
  display: flex;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
}

.acc-moi-rang,
.acc-moi-mesure { margin: 0; flex: 0 0 auto; }

/* Un filet, pas trois cases : trois encadres donneraient trois chiffres a
   egalite, et le rang doit dominer SON bloc. */
.acc-moi-mesure {
  padding-left: 1.5rem;
  border-left: 1px solid var(--tp-trait);
}

.acc-rang {
  display: block;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 2.25rem;
  line-height: .95;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

.acc-rang sup { font-size: .36em; vertical-align: super; letter-spacing: 0; }

/* Les points et les journees restent une DONNEE : Inter tabulaire, pas une
   seconde affiche a cote du rang. */
.acc-nombre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

.acc-moi-chiffres .etiquette {
  display: block;
  margin-top: .25rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* La phrase du deuxieme couteau : elle vaut le podium pour les 90 % qui ne le
   verront jamais, donc elle est ECRITE. Le texte reste en encre pleine sur
   l'ambre — c'est le fond qui porte l'or, pas la lettre. */
.acc-moi-mot {
  margin: 1rem 0 0;
  padding: .75rem .9375rem;
  border-left: 4px solid var(--tp-or);
  border-radius: 0 var(--tp-r-champ) var(--tp-r-champ) 0;
  background: var(--tp-ambre-fond);
  color: var(--tp-encre);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.45;
  max-width: 54ch;
}

.acc-moi-suite {
  margin: 1rem 0 0;
  font-size: 14px;
  color: var(--tp-encre-2);
}

.acc-moi-suite strong { color: var(--tp-encre); font-weight: 700; }

/* ═══════════════════════════════════════════════════════════ 7. LE PODIUM ══
   Trois marches en liste, pas en escalier : l'escalier appartient a
   /classement, ou il est l'objet de la page. Ici le podium est un bloc parmi
   six et doit tenir dans une demi-colonne. */

.acc-podium-lieu {
  margin: 0 0 .875rem;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.25rem, 1.05rem + .9vw, 1.75rem);
  line-height: 1.15;
  letter-spacing: .01em;
  color: var(--tp-encre);
}

.acc-podium-lieu .muet {
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 12.5px;
  letter-spacing: 0;
  color: var(--tp-encre-3);
  white-space: nowrap;
}

.acc-podium {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .375rem;
}

.acc-marche {
  display: grid;
  grid-template-columns: auto 1.75rem minmax(0, 1fr) auto;
  align-items: center;
  gap: .75rem;
  padding: .625rem .75rem;
  border-radius: var(--tp-r-tuile);
  background: var(--tp-creux);
  color: var(--tp-encre);
  box-shadow: none;
}

/* La premiere marche change de FOND et porte le lisere : sans cela, deux
   marches sur trois resteraient a departager par une nuance de gris. */
.acc-marche-1 {
  background: var(--tp-ambre-fond);
  color: var(--tp-encre);
  box-shadow: inset 4px 0 0 var(--tp-or);
}

.acc-marche-1 .acc-place { color: var(--tp-or-lisible); }
.acc-marche-1 .acc-bilan,
.acc-marche-1 .muet { color: var(--tp-encre-2); }

/* Les metaux du kit : or, argent, bronze. De vraies teintes, pas trois gris —
   et le rang reste ecrit a cote, la couleur ne porte jamais seule. */
.acc-boule {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--tp-argent);
  box-shadow: inset 0 0 0 1px rgb(0 0 0 / .12);
}

.acc-podium > .acc-marche:nth-child(3) .acc-boule { background: var(--tp-bronze); }

.acc-marche-1 .acc-boule { width: 26px; height: 26px; background: var(--tp-or); }

.acc-place {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.375rem;
  line-height: 1;
  text-align: center;
  color: var(--tp-encre-2);
  font-variant-numeric: tabular-nums;
}

.acc-equipe {
  font-weight: 700;
  font-size: 14px;
  line-height: 1.25;
  overflow-wrap: anywhere;
}

.acc-bilan {
  text-align: right;
  font-weight: 700;
  font-size: 13px;
  color: var(--tp-encre-2);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* La phrase que le circuit attend depuis le matin. */
.acc-tournee {
  margin: 1rem 0 0;
  padding: .625rem .875rem;
  border-radius: var(--tp-r-champ);
  background: var(--tp-ambre-fond);
  color: var(--tp-encre);
  font-size: 14.5px;
  line-height: 1.45;
}

.acc-tournee strong { color: var(--tp-or-lisible); font-weight: 700; }

/* ═════════════════════════════════════════════════════════════ 8. ENSUITE ══
   Les journees a venir, au dessin de .tp-ligne : le bloc date de 48 px, le
   titre net, la meta grise, le chevron qui dit « ca s'ouvre ». */

.acc-bloc .grille-3 {
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: .75rem;
}

.horloge .journee {
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: .875rem;
  min-height: 60px;
  padding: .75rem 1rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: inherit;
  text-decoration: none;
}

.horloge .journee .date { text-align: center; line-height: 1; }

.horloge .journee .date .j {
  display: block;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1;
  color: var(--tp-encre);
}

.horloge .journee .date .s {
  display: block;
  margin-top: .1875rem;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

.horloge .journee .titre {
  display: block;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--tp-encre);
}

.horloge .journee .info { display: block; font-size: 13px; color: var(--tp-encre-3); }

.horloge .journee svg { color: var(--tp-encre-4); }

/* La finale garde l'or, mais en FOND teinte : un aplat or plein mangeait le
   titre qu'il portait. */
.horloge .journee.finale {
  background: var(--tp-ambre-fond);
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
}

.horloge .journee.finale .date .j,
.horloge .journee.finale .titre { color: var(--tp-encre); }

.horloge .journee.finale .date .s,
.horloge .journee.finale .info { color: var(--tp-or-lisible); }

/* ════════════════════════════════════════════════ 9. LE FIL ET LES ANNONCES ══
   Les deux seuls demi-blocs. Leurs cartes doivent descendre au meme fond,
   sinon la rangee montre une marche : le bloc s'etire, la carte remplit, le
   bouton se pose en bas. */

.acc-fil { display: flex; flex-direction: column; }

.acc-fil-carte {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  flex: 1 1 auto;
}

.acc-fil-mot {
  margin: 0;
  max-width: 42ch;
  font-size: 15px;
  line-height: 1.55;
  color: var(--tp-encre);
}

.acc-fil-carte .actions { margin-top: auto; }

.acc-annonces .pile-2 { gap: .625rem; }

/* Le type d'annonce se lit sur le bord ET dans la pastille : la couleur ne
   porte jamais l'information seule. */
.acc-annonces .annonce {
  display: block;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-left: 3px solid var(--tp-encre-4);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: .875rem 1rem;
  color: inherit;
  text-decoration: none;
}

.acc-annonces .annonce.urgent      { border-left-color: var(--tp-rouge); }
.acc-annonces .annonce.resultat    { border-left-color: var(--tp-vert); }
.acc-annonces .annonce.convocation { border-left-color: var(--tp-or); }

.acc-annonces .annonce .titre {
  margin: .375rem 0 0;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--tp-encre);
}

.acc-annonces .annonce .minus { font-size: 12px; color: var(--tp-encre-3); }
.acc-annonces .annonce .petit { font-size: 13px; color: var(--tp-encre-3); }

/* ══════════════════════════════════════════════════════════ 10. LE CLASSEMENT ══ */

.acc-series {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: 1.25rem;
}

.acc-series > div { min-width: 0; }

.acc-series .rang.entre { align-items: baseline; margin-bottom: .5rem; }

.acc-series .etiquette {
  margin: 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

.horloge .ligne-classement {
  display: grid;
  grid-template-columns: 2.5rem auto minmax(0, 1fr) auto;
  align-items: center;
  gap: .75rem;
  min-height: 60px;
  padding: .625rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: inherit;
  text-decoration: none;
}

.horloge .ligne-classement .rang {
  position: relative;
  display: block;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1;
  letter-spacing: 0;
  text-align: center;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

/* Le podium se marque par un FILET, pas par une teinte : le chiffre garde tout
   son contraste, et l'information ne repose pas sur la seule couleur. */
.horloge .ligne-classement.podium .rang { color: var(--tp-encre); }

.horloge .ligne-classement.podium .rang::before {
  content: "";
  position: absolute;
  left: -.4375rem;
  top: 50%;
  translate: 0 -50%;
  transform: none;
  width: 3px;
  height: 1.5em;
  border-radius: 2px;
  background: var(--tp-or);
  box-shadow: none;
}

/* La ligne « vous » : doree, comme au classement. Un panneau bleu nuit au
   milieu d'une pile de cartes blanches se lisait comme une erreur. */
.horloge .ligne-classement.moi {
  background: var(--tp-ambre-fond);
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
  color: var(--tp-encre);
}

.horloge .ligne-classement.moi .rang { color: var(--tp-encre); }
.horloge .ligne-classement.moi .sous { color: var(--tp-encre-2); }

.horloge .ligne-classement .nom {
  display: block;
  font-weight: 700;
  font-size: 14.5px;
  line-height: 1.2;
  color: var(--tp-encre);
}

.horloge .ligne-classement .sous {
  display: block;
  font-size: 12.5px;
  color: var(--tp-encre-3);
}

.horloge .ligne-classement .score { text-align: right; }

.horloge .ligne-classement .score .pts {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.1;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════ 11. BOUTONS, JETONS, PASTILLES DE LA PAGE ══
   Le socle, sable et eclat empilent sur le bouton un degrade vertical, un
   reflet qui le traverse (::after) et deux ombres internes. Le kit n'a qu'une
   pilule. On reprend donc AUSSI position, isolation, overflow et le pseudo :
   redeclarer le seul fond laissait le reflet glisser sur un aplat.
   La portee est limitee a l'accueil — .carte et .bouton appartiennent a tout
   le site, et cette feuille ne parle que d'une page. */

:is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton {
  position: static;
  isolation: auto;
  overflow: visible;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 52px;
  padding: 0 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  letter-spacing: 0;
  text-decoration: none;
  cursor: pointer;
  filter: none;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              background var(--tp-elan), border-color var(--tp-elan);
}

:is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton::after { content: none; }

:is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton:hover {
  background: var(--tp-or-vif);
  color: var(--tp-sur-or);
  box-shadow: 0 4px 16px rgb(245 180 28 / .45);
  transform: none;
  filter: none;
}

:is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton:active { transform: translateY(1px); }

/* app.js bascule ces deux classes sur les trois reponses de disponibilite :
   « Je viens » prend l'or, les deux autres le ton neutre. Un seul or par
   ecran — c'est le geste attendu, pas les gestes. */
:is(.horloge, .vit-hero, .vit-rangee, .vit-trio) .bouton-vide {
  background: transparent;
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

:is(.horloge, .vit-hero, .vit-rangee, .vit-trio) .bouton-vide:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
}

:is(.horloge, .vit-hero, .vit-rangee, .vit-trio) .bouton-bleu {
  background: var(--tp-creux);
  color: var(--tp-encre);
  box-shadow: none;
}

:is(.horloge, .vit-hero, .vit-rangee, .vit-trio) .bouton-bleu:hover {
  background: color-mix(in oklab, var(--tp-creux) 70%, var(--tp-encre) 8%);
  color: var(--tp-encre);
}

/* Le bouton tenu se dit par le fond ET par aria-pressed : le lecteur d'ecran
   l'entend, l'oeil le voit. */
:is(.horloge) .bouton[aria-pressed="true"] {
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
}

/* Sur le bleu nuit de l'appel, le bouton fantome devient du verre clair. */
.vit-nuit .bouton-vide,
.vit-nuit .bouton-vide:hover {
  background: rgb(255 255 255 / .1);
  border-color: rgb(255 255 255 / .22);
  color: #FFFFFF;
  box-shadow: none;
}

/* — LES JETONS —
   Le degrade marine et le double anneau or tombent : a 34 px, deux initiales
   sur un aplat se lisent, sur un degrade cercle d'or elles se devinent. */
.horloge .jeton {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 50%;
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0;
}

.horloge .jeton-or { background: var(--tp-or); color: var(--tp-sur-or); }

/* Le liseré de la file reprend la couleur de la CARTE, pas du panneau : les
   jetons se chevauchent desormais sur du blanc. */
.horloge .file-jetons .jeton { border: 2px solid var(--tp-carte); }
.horloge .file-jetons .jeton + .jeton { margin-left: -10px; }

/* Le « +33 » ferme la file : creux, pour qu'on lise les visages d'abord. */
.acc-jeton-plus {
  background: var(--tp-creux);
  color: var(--tp-encre-3);
  box-shadow: none;
  font-size: 11px;
}

/* — LES PASTILLES —
   Vingt-quatre pixels, Inter 700 onze capitales : le duo texte + fond de
   chaque teinte de sens, lisible a cette taille. */
.horloge .pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.horloge .pastille-rouge  { background: var(--tp-rouge-fond); color: var(--tp-rouge); }
.horloge .pastille-verte  { background: var(--tp-vert-fond);  color: var(--tp-vert); }
.horloge .pastille-neutre { background: var(--tp-creux);      color: var(--tp-encre-3); }
.horloge .pastille-bleue  { background: var(--tp-creux);      color: var(--tp-encre-2); border: 0; }

/* — LE SURVOL DES CARTES —
   Un pixel vers le haut et l'ombre qui s'ouvre, comme .tp-carte. Les quatre
   pixels de l'ancien survol faisaient sauter la ligne sous le doigt. */
@media (hover: hover) {
  .horloge :is(.carte-lien, .ligne-classement, .journee):hover {
    transform: translateY(-1px);
    border-color: var(--tp-trait-fort);
    box-shadow: var(--tp-ombre-haut);
  }

  .horloge .ligne-classement.moi:hover,
  .horloge .journee.finale:hover {
    border-color: color-mix(in oklab, var(--tp-or) 60%, var(--tp-trait));
  }
}

/* ══════════════════════════════════════════════════════ 12. LE FOCUS CLAVIER ══
   L'anneau or et son halo, comme partout dans le kit. :focus-visible : au
   clavier, pas sous la souris. */

.horloge :is(.bouton, .carte-lien, .ligne-classement, .journee, .acc-presents):focus-visible,
:is(.vit-hero, .vit-nuit, .vit-rangee, .vit-trio) :is(.bouton, .vit-badge, .carte-lien):focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* ═══════════════════════════════════════════ 13. LE MOUVEMENT, EN MOINS ══
   Le kit le dit dans son propre commentaire : aucune animation d'entree en
   cascade. Les bandeaux montaient ligne par ligne (sable ET eclat), les
   telephones montaient puis flottaient en boucle, et eclat.js posait
   [data-reveler] sur chaque carte pour la faire apparaitre au defilement.
   On rend la page immediate. Le filet de securite de eclat.js (tout s'affiche
   apres 1,2 s) devient sans objet : plus rien n'est cache au depart. */

:is(.acc-scene, .acc-etat, .vit-hero) > .enveloppe > *,
.acc-scene > picture > img,
.vit-scene .telephone,
.vit-visuel .telephone { animation: none; }

.js :is(.horloge, .vit-chiffres, .vit-trio, .vit-rangee) [data-reveler] {
  opacity: 1;
  transform: none;
  transition: none;
}

/* Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. */
@media (prefers-reduced-motion: reduce) {
  .horloge :is(.carte-lien, .ligne-classement, .journee, .bouton, .acc-presents),
  :is(.vit-hero, .vit-nuit, .vit-rangee, .vit-trio) :is(.bouton, .vit-badge),
  .telephone {
    transition: none;
    animation: none;
  }

  .horloge :is(.carte-lien, .ligne-classement, .journee):hover,
  :is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton:hover,
  :is(.horloge, .vit-hero, .vit-nuit, .vit-rangee, .vit-trio) .bouton:active,
  .vit-badge:hover { transform: none; }
}

/* ═══════════════════════════════════════════════════ 14. LES PETITS ECRANS ══
   La page tient a 390 px sans debordement horizontal. Les points de rupture
   des anciennes feuilles (640 px, 760 px) sont REPRIS ici : laisses en place,
   ils auraient continue de masquer les deux telephones lateraux et de replier
   les rangees a une largeur qui n'est plus la notre. */

@media (max-width: 47.5rem) {
  .vit-rangee {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
    padding-block: clamp(1.5rem, 4vw, 2.25rem);
  }

  .vit-rangee.inverse > .vit-texte { order: 0; }
  .vit-texte h2 { max-width: 22ch; }
  .vit-visuel .telephone { right: 5%; bottom: -8%; }
}

@media (max-width: 40rem) {
  .vit-scene .telephone.gauche,
  .vit-scene .telephone.droite { display: none; }

  .vit-scene .telephone.grand { width: min(62vw, 240px); }

  .vit-qr { flex-wrap: wrap; }
}

@media (max-width: 26rem) {
  /* Le filet vertical entre les mesures n'a plus de place : elles s'empilent,
     et le filet deviendrait une barre orpheline en tete de ligne. */
  .acc-moi-mesure { padding-left: 0; border-left: 0; }

  .acc-moi-chiffres { gap: .875rem 1.25rem; }

  .horloge .ligne-classement {
    grid-template-columns: 2.125rem auto minmax(0, 1fr) auto;
    gap: .5rem;
    padding: .625rem .75rem;
  }

  .horloge .ligne-classement .rang { font-size: 1.25rem; }

  .acc-marche { gap: .5rem; padding: .625rem; }

  .acc-journee,
  .acc-porte,
  .acc-moi,
  .acc-podium-carte,
  .acc-fil-carte { padding: 1rem; }

  .vit-chiffres { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   L'AGENDA DE LA SAISON
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — L'AGENDA. Le calendrier de la saison, au dessin du kit.

   La page garde ses classes (.pa-*, .banniere, .pastille, .bouton) : app.js ne
   les vise pas, mais la vue les ecrit et PHP pose data-passe et aria-current
   dessus. On leur donne un DESSIN, jamais un autre nom.

   LE DESSIN VISE — la LISTE DATEE du kit : un mois = UNE carte blanche, des
   lignes de 60 px separees par un trait EN RETRAIT de 72 px, le bloc jour en
   Playfair 20 surmontant trois capitales de 10. Les deux rails de filtres
   deviennent des .tp-puce ; le bandeau quitte l'aplat marine pour le papier.

   CE QUI RESISTE, ET QU'ON A DONC CONTOURNE AU LIEU DE FORCER
     · sable.css se termine HORS COUCHE, avec des !important. Pour les
       declarations !important la cascade INVERSE l'ordre des couches : « tire »
       etant declaree en dernier, elle est la plus faible. Dans le bandeau sont
       donc geles, quoi qu'on ecrive ici :
         .surtitre        color: var(--or-800)   (#876104 dans les TROIS etats)
         .sous, p, li     color: var(--encre-2)
         h1, strong, b    color: var(--encre)
         .bouton*         color/background/box-shadow/border-color
       Les deux dernieres lignes BASCULENT avec le theme : le bandeau doit donc
       rester une surface qui bascule elle aussi (le papier), sinon on ecrit de
       l'encre de jour sur une nuit. C'est la raison de fond du bandeau papier.
     · html body :is(.banniere-bleue, .acc-etat) { overflow: clip } est hors
       couche AUSSI (sans !important, mais le hors-couche passe devant toute
       couche) : rien ne doit deborder du bandeau. Aucun de nos blocs ne le fait.
     · p-agenda.css se termine hors couche lui aussi : .pa-rail-saisons .pa-puce
       garde font-size, padding, min-height et opacity. On rend donc la cible
       tactile par « height », que cette regle-la n'ecrit pas.

   Couche « tire », declaree en dernier (socle, composants, pages, utilitaires,
   eclat, sable, panneau, poste, tire) : elle passe devant app.css, sable.css et
   p-agenda.css sans un seul !important — mais UNIQUEMENT sur les proprietes
   qu'elle ecrit. D'ou les neutralisations explicites, ligne a ligne.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ═══════════════════════════════════════════════════════ 1. LE BANDEAU ══
   L'ancien bandeau etait un aplat marine (app.css), puis une scene a boule
   en filigrane (sable.css). Le nouveau est du PAPIER : on laisse passer le
   fond texture du site et on ne pose plus qu'une typographie dessus.
   Le :has() vise le seul bandeau de l'agenda : les autres pages ont leur
   propre feuille, et deux familles qui ecrivent « .banniere » se marcheraient
   dessus a la premiere concatenation. */

.banniere:has(.pa-chiffres) {
  position: relative;
  isolation: isolate;
  background: transparent;
  color: var(--tp-encre);
  padding-block: 1.75rem 1.25rem;
  /* sable.css et app.css posaient trois hauteurs differentes, dont une sous
     640 px : on les remplace toutes par une seule, ici. */
}

/* La boule en filigrane de sable.css : un decor de l'ancienne direction. Le
   papier porte deja son grain, deux textures se disputent. */
.banniere:has(.pa-chiffres)::before,
.banniere:has(.pa-chiffres)::after { content: none; }

/* L'entree en cascade de sable.css (s-monte, 80/160/240 ms) : une page qui se
   monte sous les yeux fait perdre plus de temps qu'elle n'en donne. Le kit ne
   fait entrer aucun ecran. */
.banniere:has(.pa-chiffres) > .enveloppe > * { animation: none; }

/* Le surtitre « Saison 2026 ». Sa couleur est gelee a #876104 par le bloc hors
   couche de sable : 4,96:1 sur le papier de jour, mais 3,29:1 sur la nuit. On
   ne peut pas changer l'encre — on change donc le FOND, avec une plaque d'or
   pale identique dans les trois etats (4,6:1 partout). Le blanc est ecrit en
   dur volontairement : cette plaque ne doit PAS basculer, sinon l'encre gelee
   se retrouve a nouveau sur du sombre. */
.pa-surtitre {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 .5625rem;
  border-radius: var(--tp-r-pilule);
  background: color-mix(in oklab, var(--tp-or-vif) 24%, #FFFFFF);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin: 0 0 .625rem;
}

/* Le filet d'or de .surtitre::before (app.css et sable.css) : dans une pilule
   il devient une barre coincee contre la premiere lettre. */
.pa-surtitre::before { content: none; }

/* Le titre. Big Shoulders montait a 7,4 rem en capitales condensees : c'est
   precisement le cri qu'on enleve. Playfair, casse normale, 24 → 34. */
.banniere:has(.pa-chiffres) h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  text-wrap: balance;
  margin: 0;
}

/* La phrase d'accroche. Sa couleur est gelee a --encre-2, qui bascule
   correctement : on ne reprend que la mesure. */
.banniere:has(.pa-chiffres) .sous {
  max-width: 56ch;
  margin-top: .5rem;
  font-size: 14.5px;
  font-weight: 400;
  line-height: 1.55;
  text-wrap: pretty;
}

/* Le calendrier du frigo. Fond, encre, ombre et couleur de bord sont geles par
   le bloc hors couche : il restera une pilule couleur carte a encre normale.
   On tient donc ce qui reste — la forme, la hauteur de doigt, la graisse. */
.banniere:has(.pa-chiffres) .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 1.125rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  text-decoration: none;
  transform: none;
}

/* app.css lui mettait un degrade jaune et sable.css un reflet : les deux sont
   ecrases par le bloc hors couche, mais le pseudo-element, lui, passerait. */
.banniere:has(.pa-chiffres) .bouton::after { content: none; }

/* Les trois chiffres de la saison : dates, a venir, jouees. Le kit en fait des
   TUILES (.tp-tuile) — chiffre Playfair 26, intitule 11 capitales. Le nombre
   est un <b> : sa couleur est gelee a --encre, qui bascule bien. */
.pa-chiffres {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .5rem;
  max-width: 24rem;
  margin: 1rem 0 0;
  padding: 0;
  list-style: none;
  font-variant-numeric: tabular-nums;
}

.pa-chiffres > li {
  display: block;
  min-width: 0;
  padding: .75rem .5rem;
  text-align: center;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
}

.pa-chiffres b {
  display: block;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.1;
  letter-spacing: 0;
}

/* Le <span> n'est vise par aucun !important : c'est le seul endroit du bandeau
   ou l'on choisit encore l'encre. On prend celle du kit. */
.pa-chiffres span {
  display: block;
  margin-top: .125rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* Le corps de la page. sable.css ouvrait la section sur 3 a 5 rem de vide :
   c'etait le rythme d'un bandeau d'affiche haut de sept lignes. Le bandeau de
   papier tient en trois, et la premiere rangee de puces doit rester au-dessus
   du pli sur un telephone. Le :has() tient la regle sur la seule page de
   l'agenda : .section-mince sert partout ailleurs sur le site. */

.section-mince:has(.pa-mois-rail),
.section-mince:has(.pa-vide) {
  padding-block: .25rem 2.5rem;
}

/* ══════════════════════════════════════════════════════ 2. LES TROIS RAILS ══
   Type de date, saison, mois : trois rangees de .tp-puce. Elles defilent au
   doigt en debordant jusqu'aux marges de l'enveloppe — une rangee qui passe a
   la ligne fait sauter le titre de la page a chaque filtre pose.
   Le debord passe par max(gouttiere, encoche) : en paysage sur iPhone, la
   premiere puce se retrouvait sous l'encoche. */

.pa-rail-filtres,
.pa-mois-rail {
  display: flex;
  flex-wrap: nowrap;
  gap: .5rem;
  margin: 0;
  margin-inline: calc(var(--gouttiere, 1rem) * -1);
  padding-block: .1875rem;
  padding-left: max(var(--gouttiere, 1rem), env(safe-area-inset-left, 0px));
  padding-right: max(var(--gouttiere, 1rem), env(safe-area-inset-right, 0px));
  list-style: none;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}

.pa-rail-filtres::-webkit-scrollbar,
.pa-mois-rail::-webkit-scrollbar { display: none; }

.pa-rail-filtres > li,
.pa-mois-rail > li {
  flex: 0 0 auto;
  scroll-snap-align: start;
  list-style: none;
}

.pa-puce {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  padding: 0 .9375rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  background: var(--tp-carte);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--tp-elan), color var(--tp-elan), border-color var(--tp-elan);
}

.pa-puce:hover {
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
}

/* La puce tenue prend l'or PLEIN : l'or est un fond, jamais une petite lettre
   sur du clair. La vue ecrit aria-current="true" ; on garde aussi .est-actif,
   la convention du kit. */
.pa-puce[aria-current],
.pa-puce.est-actif {
  background: var(--tp-or);
  border-color: var(--tp-or);
  color: var(--tp-sur-or);
  font-weight: 700;
}

.pa-puce[aria-current]:hover,
.pa-puce.est-actif:hover {
  background: var(--tp-or-vif);
  border-color: var(--tp-or-vif);
  color: var(--tp-sur-or);
}

/* Le compte de dates du mois. Tabulaire : sans cela « 11 » et « 4 » ne font
   pas la meme largeur et le rail tremble quand on le fait defiler. */
.pa-compte {
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  font-size: 12px;
  color: var(--tp-encre-3);
}

.pa-puce[aria-current] .pa-compte,
.pa-puce.est-actif .pa-compte { color: var(--tp-sur-or); }

/* Un mois deja joue reste lisible : il perd son trait, pas son encre. */
.pa-mois-rail .pa-puce[data-passe] {
  background: transparent;
  border-color: transparent;
  color: var(--tp-encre-3);
}

.pa-mois-rail .pa-puce[data-passe]:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  color: var(--tp-encre);
}

/* Le rail des saisons. font-size, padding, min-height et opacity lui sont
   imposes HORS COUCHE par la fin de p-agenda.css : impossible de les reprendre
   sans !important. On passe donc par « height », que cette regle n'ecrit pas,
   pour rendre les 44 px de doigt. */
.pa-rail-saisons .pa-puce {
  height: 44px;
  font-variant-numeric: tabular-nums;
}

/* ════════════════════════════════════════════════ 3. LES TITRES DE SECTION ══
   « A venir » et « Deja jouees ». Playfair casse normale, et la ligne de
   comptage a cote, pas dessous : elle qualifie le titre, elle ne le suit pas. */

.pa-tete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: .25rem 1rem;
  margin: 0 0 .75rem;
}

.pa-tete h2 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.25rem, 1rem + 1.1vw, 1.875rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--tp-encre);
  margin: 0;
}

.pa-tete p {
  margin: 0;
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* ════════════════════════════════════════════ 4. L'EN-TETE DE MOIS COLLANT ══
   Il colle sous l'en-tete du site : on sait toujours dans quel mois on lit,
   meme au milieu de quarante-six dates. 64 px, c'est la hauteur de .entete
   depuis la refonte (tire.css, .entete .enveloppe { min-height: 64px }) ;
   l'ancienne valeur, 62, laissait passer deux pixels de ligne au-dessus.

   Le fond reprend le papier — couleur ET texture — parce qu'un aplat uni
   glissant au-dessus d'un fond grene dessine une fenetre pendant tout le
   defilement. Le debord lateral de 12 px vient couvrir l'ombre de la carte
   des journees, qui sinon depassait de part et d'autre du bandeau. */

.pa-mois {
  position: sticky;
  top: 64px;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: .75rem;
  margin: 1.75rem -.75rem .5rem;
  padding: .625rem .75rem;
  background-color: var(--tp-sol);
  background-image: var(--tp-papier);
  background-repeat: repeat;
  background-size: 512px;
  border-bottom: 1px solid var(--tp-trait);
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--tp-encre);
  scroll-margin-top: calc(64px + 1rem);
}

/* Le filet d'or devant le mois : il devient le liseré du kit, plus fin et plus
   court — la barre de 6 px pesait autant que le mot. */
.pa-mois::before {
  content: "";
  flex: 0 0 auto;
  width: 3px;
  height: 1.1em;
  border-radius: 2px;
  background: var(--tp-or);
}

.pa-mois[data-passe] { color: var(--tp-encre-2); }
.pa-mois[data-passe]::before { background: var(--tp-trait-fort); }

.pa-mois-compte {
  margin-left: auto;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
}

/* ═══════════════════════════════════════════════════ 5. LA LISTE DATEE ══
   Un mois = UNE carte, et les journees sont ses lignes. C'est le passage des
   quarante-six vignettes bordees a gauche vers la liste d'application : le
   rythme vient du trait en retrait, plus de la repetition des bordures. */

.pa-jours {
  display: block;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  overflow: hidden;
  padding: 0;
  gap: 0;
}

/* La ligne. Trois pistes : la date (48 px), le corps, le comptoir. La date ne
   bouge jamais d'une ligne a l'autre : c'est elle qui rend la page lisible en
   diagonale. Le corps commence a 72 px = 16 (retrait) + 48 (date) + 8 (jeu). */
.pa-jour {
  position: relative;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr) auto;
  align-items: center;
  gap: .375rem .5rem;
  min-height: 60px;
  padding: .75rem 1rem;
  background: var(--pa-fond, transparent);
  border: 0;
  border-radius: 0;
  box-shadow: none;
  color: var(--tp-encre);
  text-decoration: none;
  scroll-margin-top: calc(64px + 3.5rem);
  transition: background var(--tp-elan);
  --pa-fond: transparent;
}

.pa-jour > * { min-width: 0; }

/* Le trait separateur, en retrait de 72 px : il part sous le texte, pas sous
   la date. Un border-top le tracerait d'un bord a l'autre et redonnerait le
   tableau qu'on quitte. La premiere ligne n'en porte pas : la carte a deja
   son bord. */
.pa-jour::before {
  content: "";
  position: absolute;
  top: 0;
  inset-inline: 72px 0;
  height: 1px;
  background: var(--tp-trait);
}

.pa-jours > .pa-jour:first-child::before { content: none; }

.pa-jour:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, var(--pa-fond, transparent));
}

/* — le rail : la date, et rien d'autre — */

.pa-date {
  text-align: center;
  line-height: 1;
}

.pa-date .pa-j {
  display: block;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  color: var(--tp-encre);
}

.pa-date .pa-s {
  display: block;
  margin-top: .1875rem;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* La boule d'acier marquait la prochaine journee. L'acier appartenait a
   l'ancienne direction ; le liseré d'or et la date doree disent la meme chose
   dans le vocabulaire du kit, et sans un objet de plus dans la colonne. */
.pa-boule,
.pa-jour--prochaine .pa-boule { display: none; }

/* — le corps — */

.pa-corps {
  display: flex;
  flex-direction: column;
  gap: .1875rem;
}

.pa-titre {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  color: var(--tp-encre);
  text-wrap: pretty;
}

.pa-info {
  display: flex;
  flex-wrap: wrap;
  gap: 0 .375rem;
  font-size: 13px;
  color: var(--tp-encre-3);
}

.pa-info .pa-sep { color: var(--tp-encre-4); }

/* Le badge de fete NOMME la fete. Une couleur qui ne dit pas son nom ne dit
   rien a un joueur qui ouvre la page une fois par mois — c'est pour cela que
   le duo encre + fond porte ici tout le sens, et la teinte rien du tout. */
.pa-fete {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  height: 24px;
  margin-top: .1875rem;
  padding: 0 .5625rem;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* La pastille de l'ancienne etiquette : le mot se suffit. */
.pa-fete::before { content: none; }

/* — le comptoir : l'etat, la drache, la distance — */

.pa-comptoir {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: .3125rem;
  text-align: right;
}

.pa-etats {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: .3125rem;
}

/* Les etats. Etiquettes du kit : 24 px, Inter 700 11 capitales, un duo encre +
   fond par teinte de sens. Portees SOUS .pa-etats seulement : .pastille sert
   aussi de compteur dans l'en-tete du site, que tire.css habille deja. */
.pa-etats .pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  font-family: var(--tp-texte);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  line-height: 1;
  white-space: nowrap;
  box-shadow: none;
}

.pa-etats .pastille-vide,
.pa-etats .pastille-neutre { background: var(--tp-creux); color: var(--tp-encre-3); }
.pa-etats .pastille-verte  { background: var(--tp-vert-fond);  color: var(--tp-vert); }
.pa-etats .pastille-ambre  { background: var(--tp-ambre-fond); color: var(--tp-ambre); }
.pa-etats .pastille-rouge  { background: var(--tp-rouge-fond); color: var(--tp-rouge); }

.pa-delai {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
}

.pa-meteo,
.pa-loin {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
}

.pa-meteo .pa-signe { flex: 0 0 auto; }

/* La drache et le cagnard sont des etats : chacun prend son duo. Le cagnard
   passe par l'or LISIBLE — l'or de marque sur du blanc fait 1,9:1. */
.pa-meteo--drache,
.pa-meteo--cagnard {
  height: 24px;
  padding: 0 .5rem;
  border-radius: var(--tp-r-pilule);
}

.pa-meteo--drache  { background: var(--tp-creux); color: var(--tp-encre-2); }
.pa-meteo--cagnard { background: var(--tp-ambre-fond); color: var(--tp-or-lisible); }

/* La phrase de comptoir, sous la seule prochaine journee. C'est un MOT, pas du
   corps de texte : le kit le dit a la main (Caveat Brush), comme la citation
   et le mot du comite. Aligne sur le titre, pas sur la date. */
.pa-drache-mot {
  grid-column: 2 / -1;
  margin: .125rem 0 0;
  padding-top: .5rem;
  border-top: 1px dashed var(--tp-trait);
  font-family: var(--tp-main);
  font-weight: 400;
  font-size: 1.1875rem;
  line-height: 1.3;
  color: var(--tp-encre-2);
  text-wrap: pretty;
}

/* ═════════════════════════════════════════ 6. LES FAMILLES DE JOURNEE ══
   L'ordre de ces regles est le leur : une journee peut etre a la fois fete et
   prochaine, et c'est la derniere ecrite qui garde le liseré. La prochaine
   passe donc en dernier — c'est le repere qu'on cherche en ouvrant la page. */

/* Kermesse, lundi de Paques, lundi de Pentecote, anniversaire de club : un
   voile d'ambre et une etiquette doree. Le badge NOMME la fete juste a cote. */
.pa-jour--fete {
  --pa-fond: color-mix(in oklab, var(--tp-ambre-fond) 55%, transparent);
}

.pa-jour--fete .pa-fete {
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
}

/* La semi-nocturne de 19 h. L'ancienne feuille lui donnait un aplat marine :
   sur le theme buvette, cet aplat tombait a deux points de la carte de nuit et
   la journee du soir disparaissait. L'etiquette marine, elle, tient dans les
   trois etats parce qu'elle inverse encre et fond. */
.pa-jour--nocturne {
  --pa-fond: color-mix(in oklab, var(--tp-creux) 40%, transparent);
  box-shadow: inset 3px 0 0 var(--tp-encre-2);
}

.pa-jour--nocturne .pa-fete {
  background: var(--tp-encre);
  color: var(--tp-sol);
}

/* La finale : le sommet de la saison, une fois l'an. L'or PLEIN sur son
   etiquette et son liseré — pas sur toute la ligne, sinon la carte entiere
   crie et l'accent unique ne designe plus rien. */
.pa-jour--finale {
  --pa-fond: color-mix(in oklab, var(--tp-ambre-fond) 80%, transparent);
  box-shadow: inset 3px 0 0 var(--tp-or);
}

.pa-jour--finale .pa-fete {
  background: var(--tp-or);
  color: var(--tp-sur-or);
}

.pa-jour--finale .pa-date .pa-j { color: var(--tp-or-lisible); }

/* Ce qui est joue s'efface sans devenir illisible : l'encre 3 tient 4,8:1 sur
   la carte. Aucun fond gris — trente lignes grisees, c'est une page morte. */
.pa-jour--passee {
  --pa-fond: transparent;
}

.pa-jour--passee .pa-date .pa-j { color: var(--tp-encre-3); }
.pa-jour--passee .pa-titre { font-weight: 600; color: var(--tp-encre-2); }

/* La prochaine journee du circuit : le seul or de la page avec la puce tenue.
   Liseré interne a gauche, date doree, delai dore — trois marques du meme
   accent, aucune nouvelle couleur. */
.pa-jour--prochaine {
  --pa-fond: color-mix(in oklab, var(--tp-ambre-fond) 70%, transparent);
  box-shadow: inset 3px 0 0 var(--tp-or);
}

.pa-jour--prochaine .pa-date .pa-j { color: var(--tp-or-lisible); }
.pa-jour--prochaine .pa-delai { color: var(--tp-or-lisible); }

/* ═══════════════════════════════════════════════════════ 7. L'ETAT VIDE ══
   Un ecran vide dit ce qui manque ET donne le geste pour le remplir. Le cercle
   trace au pied dans le gravier reste : c'est le seul dessin de la page, et il
   ne porte aucune information. */

.pa-vide {
  display: grid;
  justify-items: center;
  text-align: center;
  gap: .625rem;
  padding: 2.5rem 1.25rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: var(--tp-encre-3);
}

.pa-vide .pa-cercle {
  width: 56px;
  height: 56px;
  border: 3px solid var(--tp-trait-fort);
  border-bottom-color: transparent;
  border-radius: 50%;
  rotate: -24deg;
}

.pa-vide h3 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--tp-encre);
  margin: 0;
}

.pa-vide p {
  max-width: 44ch;
  margin: 0 0 .375rem;
  font-size: 14px;
  color: var(--tp-encre-3);
  text-wrap: pretty;
}

/* La sortie de l'impasse. C'est le seul geste de l'ecran : il prend l'or. Hors
   bandeau, aucun !important ne le tient — on reprend donc tout, y compris le
   degrade de app.css et le reflet de sable.css. */
.pa-vide .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 52px;
  padding: 0 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  transition: background var(--tp-elan), box-shadow var(--tp-elan), transform var(--tp-elan);
}

.pa-vide .bouton::after { content: none; }

.pa-vide .bouton:hover {
  background: var(--tp-or-vif);
  color: var(--tp-sur-or);
  box-shadow: 0 4px 16px rgb(245 180 28 / .45);
  transform: none;
  filter: none;
}

.pa-vide .bouton:active { transform: translateY(1px); }

/* La note de distance — « comptees depuis le boulodrome de… » — posee juste
   sous le rail des mois. On la prend par sa position et non par .minus.muet :
   ces deux utilitaires servent sur tout le site, et les habiller ici les
   habillerait partout. */
.pa-mois-rail + .minus {
  font-size: 12.5px;
  color: var(--tp-encre-3);
}

/* ══════════════════════════════════════════════════ 8. LE FOCUS CLAVIER ══
   L'anneau or et son halo, comme partout dans le kit. Le socle posait un
   anneau marine de 3 px : invisible sur la carte de nuit. */

.pa-jour:focus-visible,
.pa-puce:focus-visible,
.pa-vide .bouton:focus-visible,
.banniere:has(.pa-chiffres) .bouton:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* Le liseré des journees marquees doit survivre au focus, sinon la prochaine
   journee perd son repere au moment precis ou on la tient. */
.pa-jour--prochaine:focus-visible,
.pa-jour--finale:focus-visible {
  box-shadow: inset 3px 0 0 var(--tp-or), 0 0 0 5px rgb(245 180 28 / .25);
}

.pa-jour--nocturne:focus-visible {
  box-shadow: inset 3px 0 0 var(--tp-encre-2), 0 0 0 5px rgb(245 180 28 / .25);
}

/* ═══════════════════════════════════════════════════════ 9. LES LARGEURS ══
   Sous 46 rem le comptoir tombe SOUS le corps, jamais sous la date : la date
   garde sa colonne, et l'oeil garde son point d'entree. La feuille d'origine
   faisait deja ce choix ; on le reprend avec nos mesures, faute de quoi ses
   propres declarations de 46 rem reviendraient sur celles qu'on n'ecrit pas. */

@media (max-width: 46rem) {
  .pa-jour {
    grid-template-columns: 48px minmax(0, 1fr);
    padding: .75rem 1rem;
    gap: .375rem .5rem;
  }

  .pa-comptoir {
    grid-column: 2;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    gap: .3125rem .5rem;
  }

  .pa-etats { justify-content: flex-start; }

  .pa-date .pa-j { font-size: 20px; }
  .pa-titre { font-size: 15px; }
  .pa-mois { font-size: 1.1875rem; }

  /* Le mot de comptoir repasse a gauche : a 390 px, une colonne de 302 px
     n'a plus de quoi porter un retrait. */
  .pa-drache-mot { grid-column: 1 / -1; }
}

/* Au-dela, la carte du mois garde une mesure de lecture : une ligne datee
   etiree sur 1 180 px separe la date de son etat par vingt centimetres.
   NOTE — le calendrier mensuel en grille du cahier ne peut PAS se faire ici :
   la vue n'ecrit que les jours occupes, sans les cases vides ni le rang du
   premier jour. Il demande une colonne de plus cote PHP, pas une regle CSS. */
@media (min-width: 62rem) {
  .pa-jours { max-width: 58rem; }
  .pa-mois { max-width: 58rem; }
  .pa-jour { padding: .875rem 1.25rem; min-height: 64px; }
  .pa-jour::before { inset-inline: 72px 0; }
}

/* ═══════════════════════════════════════════ 10. LE MOUVEMENT, EN MOINS ══
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. Le defilement par a-coups du rail compris. */

@media (prefers-reduced-motion: reduce) {
  .pa-jour,
  .pa-puce,
  .pa-vide .bouton,
  .banniere:has(.pa-chiffres) .bouton { transition: none; }

  .pa-vide .bouton:active { transform: none; }

  .pa-rail-filtres,
  .pa-mois-rail { scroll-snap-type: none; }
}

/* ═══════════════════════════════════════════════════════════ 11. LE PAPIER ══
   Le calendrier finit punaise au mur de la buvette. L'en-tete de mois cesse de
   coller — sinon il s'imprime une fois par page — et la carte perd son ombre.
   Les aplats de fete sont deja neutralises par le bloc d'impression de
   p-agenda.css, dont les !important sont dans une couche ANTERIEURE a la
   notre : sur ce terrain-la, c'est lui qui gagne, et c'est tres bien ainsi. */

@media print {
  .pa-mois {
    position: static;
    background-color: transparent;
    background-image: none;
    border-bottom-color: #999;
    margin-inline: 0;
    padding-inline: 0;
  }

  .pa-jours {
    border-color: #999;
    box-shadow: none;
  }

  .pa-jour::before { background: #999; }

  /* La main ne s'imprime pas bien en petit corps : le mot reprend l'Inter. */
  .pa-drache-mot {
    font-family: var(--tp-texte);
    font-size: 12px;
  }

  .pa-chiffres > li { box-shadow: none; border-color: #999; }
}

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   LE CLASSEMENT ET SON PODIUM
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — LE CLASSEMENT, au dessin du kit.

   Le corps de la page de classement (hommes et dames) repris sur les jetons et
   les composants de assets/css/tire.css : les puces de serie et d'annee, le
   podium en trois cartes 2 · 1 · 3, la table a en-tete collant et zebrage
   leger, la ligne « Vous » doree, et la barre qui rappelle le rang du lecteur.

   ON NE RENOMME RIEN. .cl-*, .c-*, #cl-table, #cl-ruban, #moi et les data-*
   sont vises par le script de la vue (le trouble du socle, le filtre client,
   le guetteur du ruban) : cette feuille leur donne un DESSIN, pas un autre nom.

   Elle est dans la couche « tire », declaree EN DERNIER (socle, composants,
   pages, utilitaires, eclat, sable, panneau, poste, tire) : elle passe devant
   app.css, eclat.css, sable.css et p-classement.css sans un seul !important —
   et le !important serait de toute facon inoperant ici, la cascade INVERSANT
   l'ordre des couches pour ces declarations.

   DEUX CHOSES QU'ELLE NE PEUT PAS REPRENDRE, et qu'elle assume plutot que de
   les combattre :
     · sable.css pose, HORS CALQUE et en !important, la couleur des p, li,
       .sous, h1, strong, b et .surtitre de toute .banniere. Une declaration
       hors calque l'emporte sur n'importe quelle couche : la banniere garde
       donc ses encres (--encre, --encre-2, --or-800), qui sont lisibles sur le
       papier. Tout le reste de son dessin — graisse, corps, casse, fonte,
       fond, trait, rythme — est repris ici.
     · p-classement.css declare :root { --cl-entete } HORS CALQUE lui aussi.
       Le redeclarer ici serait perdu en silence : on pose des noms NEUFS.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ──────────────────────────────────────────────────── LES JETONS LOCAUX ──
   Trois mesures qui reviennent dans quatre regles. Noms neufs, pour la raison
   dite plus haut : --cl-entete et --cl-ruban existent deja hors calque. */

:root {
  --cl-tp-entete:  64px;   /* .entete de tire.css : enveloppe de 64 de haut */
  --cl-tp-tete:    52px;   /* la ligne d'en-tete collante de la table */
  --cl-tp-onglets: 58px;   /* la barre d'onglets du telephone */
}

/* ═════════════════════════════════════════════════════════ LA BANNIERE ══
   Plus de photo de coucher de soleil, plus de boule en filigrane, plus de
   cascade d'entree : le titre s'ecrit sur le papier, comme sur la maquette.
   Les trois decors venaient de eclat.css et de sable.css — on les coupe par
   leur contenu, la seule facon de retirer un pseudo-element sans le masquer.

   Note : une regle HORS CALQUE de sable.css garde overflow: clip sur cette
   banniere. Sans decor qui depasse, ca ne coute rien — on n'ecrit donc pas
   une declaration qui perdrait. */

.cl-banniere {
  background: transparent;
  background-image: none;
  padding-block: 2rem 1.25rem;
  margin: 0;
  border: 0;
}

.cl-banniere::before,
.cl-banniere::after { content: none; }

.cl-banniere > .enveloppe > * { animation: none; }

/* Playfair en CASSE NORMALE : c'est precisement la condensee en capitales
   (Big Shoulders, 3,6 rem, interligne .88) que la nouvelle direction retire. */
.cl-banniere h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 2.4vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  margin: 0;
}

/* Le surtitre du kit : Inter 700, onze pixels, capitales espacees — et SANS
   le filet dore de 22 px que app.css et sable.css lui accrochent devant. */
.cl-banniere .surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin: 0 0 .5rem;
  opacity: 1;
}

.cl-banniere .surtitre::before { content: none; }

.cl-banniere .sous {
  margin: .5rem 0 0;
  font-family: var(--tp-texte);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.55;
  max-width: 62ch;
}

/* ──────────────────────────────────────────────────────────── LE RELEVE ──
   L'affiche punaisee au mur de la buvette : elle ne se lit pas au milieu d'un
   paragraphe, elle se lit comme un cachet. D'ou la carte a liseré or — le
   meme geste que .tp-carte--or — au lieu du bandeau blanc translucide qui
   supposait un fond de nuit. */

.cl-banniere .cl-releve {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  max-width: 62ch;
  margin: 1rem 0 0;
  padding: .75rem .875rem;
  background: color-mix(in oklab, var(--tp-carte) 72%, transparent);
  border: 1px solid var(--tp-trait);
  border-left: 3px solid var(--tp-or);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
}

.cl-banniere .cl-releve strong { font-weight: 700; }

/* L'icone echappe au !important de sable, qui ne vise que le <p> : la couleur
   se transmet par heritage, pas par importance. On peut donc la dorer. */
.cl-banniere .cl-releve .icone {
  flex: 0 0 auto;
  margin-top: .125rem;
  color: var(--tp-or-lisible);
}

/* L'embargo dit d'un coup d'œil que ce qu'on lit n'est pas encore public : il
   prend l'ambre, et le duo fond + texte plutot que la couleur seule. */
.cl-banniere .cl-embargo {
  background: var(--tp-ambre-fond);
  border-color: var(--tp-ambre-fond);
  border-left: 3px solid var(--tp-ambre);
  padding-left: .875rem;
}

.cl-banniere .cl-embargo .icone { color: var(--tp-ambre); }

/* ════════════════════════════════════════════ LES PUCES DE SERIE ET D'AN ══
   Series et saisons partagent le dessin de .tp-puce : pilule creme, or quand
   elle est tenue. Les deux rangees changent de RÔLE, pas de dessin — on change
   de serie tous les dimanches, de saison une fois l'an — d'ou la seule
   difference, l'espace qui les separe.

   Elles passent de 36 a 44 px de haut : c'est la cible tactile, et ces deux
   liens sont les plus touches de la page. */

.cl-banniere .cl-series,
.cl-banniere .cl-saisons {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 1rem 0 0;
  padding: 0;
}

.cl-banniere .cl-saisons { margin-top: .5rem; }

.cl-banniere :is(.cl-series, .cl-saisons) a {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 1rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 14px;
  letter-spacing: 0;
  text-transform: none;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--tp-elan), color var(--tp-elan), border-color var(--tp-elan);
}

.cl-banniere :is(.cl-series, .cl-saisons) a:hover {
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
}

.cl-banniere :is(.cl-series, .cl-saisons) a[aria-current="true"] {
  background: var(--tp-or);
  border-color: var(--tp-or);
  color: var(--tp-sur-or);
  font-weight: 700;
}

/* ══════════════════════════════════════════════════════════ LE PODIUM ══
   Trois cartes 2 · 1 · 3, la premiere plus haute et doree, comme .tp-podium.
   Le placement par grid-column garde l'ordre du document 1-2-3 : le clavier et
   le lecteur d'ecran entendent bien premier, deuxieme, troisieme.

   Il vaut a TOUTES les largeurs, et non plus a partir de 42 rem seulement :
   un podium empile en une colonne n'est plus un podium, c'est une liste. */

.cl-podium-bloc { margin: 0 0 1.5rem; }

/* Ce h2 porte .surtitre : il echappe au clamp de sable, mais pas a la fonte
   d'affiche que app.css pose sur tous les h1 et h2. On le ramene au surtitre
   du kit, corps compris. */
.cl-podium-bloc > h2.surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  line-height: 1.4;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin: 0 0 .75rem;
}

.cl-podium-bloc > h2.surtitre::before { content: none; }

.cl-podium {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: end;
  gap: .625rem;
  margin: 0;
}

.cl-marche {
  position: relative;
  display: grid;
  grid-template-rows: auto;
  justify-items: center;
  align-content: start;
  text-align: center;
  padding: 1.375rem .5rem 0;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: inherit;
  text-decoration: none;
  overflow: hidden;
  /* L'ancienne marche se cerclait d'un outline tire vers l'interieur : il
     ferait un second trait par-dessus la bordure de la carte. */
  outline: 0;
  outline-offset: 0;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan), border-color var(--tp-elan);
}

.cl-marche:hover {
  transform: translateY(-1px);
  box-shadow: var(--tp-ombre-haut);
  border-color: var(--tp-trait-fort);
  color: inherit;
}

.cl-marche--1 {
  grid-column: 2;
  padding-top: 1.75rem;
  border-color: color-mix(in oklab, var(--tp-or) 50%, var(--tp-trait));
  box-shadow: var(--tp-ombre-haut);
}

.cl-marche--2 { grid-column: 1; }
.cl-marche--3 { grid-column: 3; }

/* La boule d'acier devient le disque du kit : creux, cercle de la carte, mat.
   Le seul objet brillant du site est parti avec l'ancienne direction — trois
   spheres chromees sur du papier creme, c'etait la vitrine, pas la fiche. */
.cl-marche .boule-acier {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background:
    /* L'eclat speculaire : dur, petit, decale — c'est lui qui dit « metal ». */
    radial-gradient(circle at 34% 26%,
      #FFFFFF 0 4%,
      color-mix(in oklab, var(--tp-argent) 55%, #FFFFFF) 9%,
      transparent 30%),
    /* Le reflet du comptoir : l'or vient du bas-droite, jamais du haut. */
    radial-gradient(circle at 68% 78%,
      color-mix(in oklab, var(--tp-or) 62%, transparent) 0 14%,
      transparent 46%),
    /* Le corps : froid, marine dans l'ombre. */
    linear-gradient(158deg,
      color-mix(in oklab, var(--tp-argent) 80%, #FFFFFF) 0%,
      var(--tp-argent) 34%,
      color-mix(in oklab, var(--tp-argent) 52%, #1D1838) 70%,
      color-mix(in oklab, var(--tp-argent) 24%, #1D1838) 100%);
  border: 2px solid var(--tp-carte);
  box-shadow: 0 2px 4px rgb(29 24 56 / .28), inset 0 0 0 1px rgb(255 255 255 / .16);
}

.cl-marche--1 .boule-acier { width: 56px; height: 56px; }

/* La pastille de rang, posee a cheval sur le bas du disque. Marge negative
   plutot que position absolue : la carte est en overflow: hidden pour que le
   pied dore suive son rayon, et une pastille sortie du cadre y serait coupee. */
.cl-marche .cl-rang-podium {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin: -14px 0 0;
  border-radius: 50%;
  border: 2px solid var(--tp-carte);
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 13px;
  line-height: 1;
  letter-spacing: 0;
  /* Les trois metaux sont les memes de jour comme de nuit : l'encre qui s'y
     pose l'est donc aussi. C'est le role exact de --tp-sur-or, et il tient sur
     le bronze la ou un blanc tomberait a 2,4:1. */
  color: var(--tp-sur-or);
  background: var(--tp-argent);
}

.cl-marche--1 .cl-rang-podium { background: var(--tp-or); }
.cl-marche--2 .cl-rang-podium { background: var(--tp-argent); }
.cl-marche--3 .cl-rang-podium { background: var(--tp-bronze); }

.cl-marche .cl-rang-podium sup {
  font-size: .5em;
  vertical-align: super;
  letter-spacing: 0;
}

.cl-marche .cl-nom {
  margin: .5rem 0 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  line-height: 1.25;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
}

.cl-marche--1 .cl-nom { font-size: 15px; }

.cl-marche .cl-detail {
  margin: .1875rem 0 0;
  font-size: 12px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--tp-encre-3);
}

.cl-marche .cl-pts-podium {
  margin: .5rem 0 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 22px;
  line-height: 1.1;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

.cl-marche--1 .cl-pts-podium { font-size: 26px; }

/* « points » passe sous le chiffre : a cote, il poussait le nombre hors de
   l'axe de la carte des que le total depassait trois chiffres. */
.cl-marche .cl-pts-podium span {
  display: block;
  margin: .0625rem 0 0;
  font-family: var(--tp-texte);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* LE SOCLE — un pied dore, plus une estrade de 74 px. La hauteur de la marche
   se dit maintenant par la carte elle-meme (la premiere est plus haute et
   doree) : le pied ne fait que la signer. */
.cl-socle {
  width: 100%;
  height: 10px;
  margin: 1rem 0 0;
  background: var(--tp-or);
  border-top: 0;
}

.cl-marche--1 .cl-socle { height: 14px; }
.cl-marche--2 .cl-socle { height: 10px; }
.cl-marche--3 .cl-socle { height: 8px; }

/* Le trouble reste — c'est le script qui le declenche, une fois, du troisieme
   au premier — mais il rentre dans le mouvement du site : l'or profond chauffe
   vers l'or vif en 180 ms au lieu de virer a l'ivoire en 600. Sans JavaScript
   le pied reste dore : un etat final valable, pas un etat mort. */
.cl-socle.se-trouble {
  background: color-mix(in oklab, var(--tp-or-profond), var(--tp-or-vif) var(--trouble));
  transition: --trouble var(--tp-elan);
}

/* L'etat d'arrivee est redit ICI plutot que laisse a l'ancienne feuille : sans
   lui, un pied dore n'aurait plus de destination le jour ou p-classement.css
   s'en irait. La propriete --trouble, elle, reste enregistree par @property
   dans cette meme feuille, hors calque — c'est cet enregistrement qui rend la
   couleur animable, et il ne peut pas etre repris ici sans sortir de la
   couche. */
.cl-socle.se-trouble.est-trouble { --trouble: 100%; }

/* Le telephone : le podium reste a trois colonnes, on resserre ce qu'il y a
   dedans. C'est la seule facon de tenir trois cartes dans 390 px. */
@media (max-width: 26rem) {
  .cl-podium { gap: .375rem; }
  .cl-marche { padding: 1.125rem .3125rem 0; }
  .cl-marche--1 { padding-top: 1.375rem; }
  .cl-marche .boule-acier { width: 40px; height: 40px; }
  .cl-marche--1 .boule-acier { width: 46px; height: 46px; }
  .cl-marche .cl-nom,
  .cl-marche--1 .cl-nom { font-size: 13px; }
  .cl-marche .cl-detail { font-size: 11px; }
  .cl-marche .cl-pts-podium { font-size: 19px; }
  .cl-marche--1 .cl-pts-podium { font-size: 22px; }
}

/* ═══════════════════════════════════════════════════════════════ MOI ══
   Ma place, en haut, avec la regle du plafond dessinee dessus. La carte prend
   le liseré or de .tp-carte--or : un trait a gauche pose en ombre interieure,
   pas une bordure de 5 px qui decale tout le contenu. */

.cl-moi-carte {
  background: var(--tp-carte);
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  border-left-width: 1px;
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
  padding: 1.125rem 1.25rem;
  margin: 0 0 1.25rem;
}

.cl-moi-tete {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  flex-wrap: wrap;
}

.cl-moi-tete .cl-moi-titre { flex: 1 1 14rem; min-width: 0; }

/* .etiquette sert ici d'intitule de bloc : on lui donne le surtitre du kit. */
.cl-moi-carte .etiquette,
.cl-verre-texte .etiquette {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin: 0 0 .375rem;
}

/* Le rang garde le premier rôle, mais en Playfair et a 2,25 rem : a cette
   taille l'or LISIBLE porte du texte sans difficulte — c'est en petit qu'il
   est interdit. */
.cl-moi-rang {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .5rem;
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.25rem);
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--tp-or-lisible);
  font-variant-numeric: tabular-nums;
}

.cl-moi-rang sup { font-size: .45em; vertical-align: super; letter-spacing: 0; }

.cl-moi-rang .cl-moi-nom {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  letter-spacing: 0;
  color: var(--tp-encre-2);
  overflow-wrap: anywhere;
}

.cl-moi-chiffres {
  margin: .5rem 0 0;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.5;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
  max-width: none;
}

.cl-moi-chiffres strong { color: var(--tp-encre); font-weight: 700; }

/* ──────────────────────────────────────────────────── LE VERRE DE SAISON ──
   Le dessin SVG ne porte aucune couleur : il prend les jetons par ses classes,
   donc Cagnard, Buvette et l'impression suivent sans une ligne de script.
   La hachure reste : la surface doree ne dit jamais seule ce qu'elle compte. */

.cl-verre-bloc {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  margin: 1rem 0 0;
  padding: 1rem 0 0;
  border-top: 1px solid var(--tp-trait);
}

.cl-verre { flex: 0 0 auto; width: 76px; height: 138px; }

.cl-verre-corps   { fill: none; stroke: var(--tp-trait-fort); stroke-width: 2; }
.cl-verre-or      { fill: var(--tp-or); }
.cl-verre-cercle  { fill: none; stroke: var(--tp-or-profond); stroke-width: 1.5; }
.cl-verre-eau     { fill: url("#cl-verre-hachure"); }
.cl-verre-hachure { stroke: var(--tp-encre-3); stroke-width: 2.4; }
.cl-verre-barre   { stroke: var(--tp-encre-4); stroke-width: 2; stroke-dasharray: 5 4; }
.cl-verre-grad    { stroke: var(--tp-trait-fort); stroke-width: 1.5; }

.cl-verre-texte { flex: 1 1 auto; min-width: 0; }

.cl-verre-ligne {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin: 0 0 .375rem;
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--tp-encre-2);
  max-width: none;
}

.cl-verre-ligne b {
  color: var(--tp-encre);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Les deux puces de la legende reprennent EXACTEMENT les deux remplissages du
   verre : l'or plein pour les journees retenues, le creux cercle pour celles
   de presence. Une legende qui ne ressemble pas au dessin ne sert a rien. */
.cl-verre-puce {
  flex: 0 0 auto;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  background: var(--tp-or);
  border: 1px solid var(--tp-or-profond);
  transform: translateY(1px);
}

.cl-verre-puce--eau {
  background: var(--tp-creux);
  border-color: var(--tp-encre-4);
}

.cl-verre-phrase {
  margin: .625rem 0 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--tp-encre);
  max-width: 62ch;
}

.cl-verre-source {
  margin: .5rem 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--tp-encre-3);
  max-width: 62ch;
}

@media (max-width: 26rem) {
  .cl-verre-bloc { gap: .75rem; }
  .cl-verre { width: 60px; height: 110px; }
}

/* ══════════════════════════════════════════════════════════ LE RUBAN ══
   Ma ligne me suit des que la carte sort du champ. Il passe EN BAS, au-dessus
   de la barre d'onglets : en haut, il se serait pose exactement sur l'en-tete
   collant de la table et aurait masque la ligne que le lecteur cherche. En bas
   il est aussi sous le pouce, la ou on le touche.

   On ne touche pas a son « display » : le script ne fait que poser et retirer
   l'attribut hidden, et une couche qui redeclarerait display ici le rendrait
   visible en permanence. */

.cl-ruban {
  position: fixed;
  inset: auto 0 calc(var(--cl-tp-onglets) + env(safe-area-inset-bottom, 0px)) 0;
  z-index: 35;
  background: color-mix(in oklab, var(--tp-carte) 96%, transparent);
  -webkit-backdrop-filter: saturate(1.6) blur(12px);
  backdrop-filter: saturate(1.6) blur(12px);
  color: var(--tp-encre);
  border-top: 1px solid var(--tp-trait);
  border-bottom: 0;
  box-shadow: var(--tp-ombre-haut);
}

/* Passe 900 px la barre d'onglets disparait : le ruban se pose sur le bord. */
@media (min-width: 901px) {
  .cl-ruban { bottom: env(safe-area-inset-bottom, 0px); }
}

.cl-ruban-corps {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-height: 56px;
  padding-block: .375rem;
}

.cl-ruban .cl-ruban-rang {
  flex: 0 0 auto;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.1;
  color: var(--tp-or-lisible);
  font-variant-numeric: tabular-nums;
}

.cl-ruban .cl-ruban-rang sup { font-size: .5em; vertical-align: super; }

.cl-ruban .cl-ruban-nom {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 700;
  font-size: 14px;
  line-height: 1.3;
  color: var(--tp-encre);
}

.cl-ruban .cl-ruban-pts {
  margin-left: auto;
  flex: 0 0 auto;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 17px;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

.cl-ruban .cl-ruban-pts span {
  font-family: var(--tp-texte);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin-left: .25rem;
}

.cl-ruban a {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  min-height: 44px;
  padding: 0 .875rem;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre);
  font-weight: 700;
  font-size: 13px;
  text-decoration: none;
  transition: background var(--tp-elan);
}

.cl-ruban a:hover {
  background: color-mix(in oklab, var(--tp-creux) 70%, var(--tp-encre) 8%);
  color: var(--tp-encre);
}

/* Le meme point de rupture que l'ancienne feuille, a dessein : deux seuils
   differents laisseraient une bande de largeurs au comportement flottant. */
@media (max-width: 30rem) {
  .cl-ruban .cl-ruban-nom { display: none; }
}

/* ────────────────────────────────────────────────────────── L'INVITATION ──
   Ce que voit un visiteur non connecte, ou un joueur absent de la serie. Une
   carte au trait interrompu : elle dit « il manque quelque chose ici » sans
   prendre le poids d'une carte pleine. */

.cl-invite {
  display: flex;
  align-items: center;
  gap: .875rem;
  flex-wrap: wrap;
  padding: 1rem 1.125rem;
  background: var(--tp-carte);
  border: 1px dashed var(--tp-trait-fort);
  border-radius: var(--tp-r-carte);
  box-shadow: none;
  margin: 0 0 1.25rem;
}

.cl-invite p {
  flex: 1 1 18rem;
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tp-encre-2);
  max-width: none;
}

/* ══════════════════════════════════════════════════════════ LA RECHERCHE ══
   Le champ du kit : rayon 12, loupe posee dedans, et un focus qui se VOIT.
   Le bouton d'effacement passe a 44 px — on efface une recherche avec des
   gants, le dimanche, en plein vent. */

.cl-chercher { margin: 0 0 1rem; }

.cl-chercher-champ {
  position: relative;
  display: flex;
  align-items: center;
}

.cl-chercher-champ .icone {
  position: absolute;
  left: .8125rem;
  top: 50%;
  translate: 0 -50%;
  color: var(--tp-encre-4);
  pointer-events: none;
}

.cl-chercher input[type="search"] {
  width: 100%;
  min-height: 48px;
  padding: .75rem 3.25rem .75rem 2.5rem;
  background: var(--tp-carte);
  color: var(--tp-encre);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 15px;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

.cl-chercher input[type="search"]::placeholder { color: var(--tp-encre-4); }

.cl-chercher input[type="search"]:focus,
.cl-chercher input[type="search"]:focus-visible {
  outline: none;
  outline-offset: 0;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

.cl-effacer {
  position: absolute;
  right: .25rem;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--tp-encre-3);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--tp-elan), color var(--tp-elan);
}

.cl-effacer:hover { background: var(--tp-creux); color: var(--tp-encre); }

.cl-compte {
  margin: .5rem 0 0 .125rem;
  font-size: 12.5px;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
  min-height: 1.2em;
  max-width: none;
}

/* ══════════════════════════════════════════════════════════ LA TABLE ══
   Le dessin de .tp-table pose dans la boite de .defile : carte blanche,
   rayon 16, en-tete en petites capitales grises, lignes de 52 px, zebrage tres
   leger et chiffres TABULAIRES — sans eux les colonnes de points dansent d'une
   ligne a l'autre.

   .defile passe de « overflow-x: auto » a « overflow: clip » : un conteneur de
   defilement retient les elements collants a l'interieur de sa propre boite,
   et l'en-tete du tableau ne suivrait plus la page. Clip coupe au rayon sans
   creer ce conteneur. Le tableau ne peut de toute facon pas deborder : sa mise
   en page est FIXE, donc les colonnes se partagent la largeur disponible au
   lieu de la reclamer. */

.cl-banniere + .section-mince { padding-block: .5rem 2rem; }

.cl-banniere + .section-mince .defile {
  overflow: clip;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 0;
}

.tableau.cl-tableau {
  /* Conserve de l'ancienne feuille, et pour la meme raison : en mise en page
     automatique le navigateur mesure 341 lignes avant de peindre la premiere. */
  table-layout: fixed;
  width: 100%;
  margin: 0;
  border-collapse: collapse;
  font-family: var(--tp-texte);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.cl-tableau th {
  position: sticky;
  top: var(--cl-tp-entete);
  z-index: 1;
  background: var(--tp-carte);
  padding: .75rem .625rem;
  text-align: left;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  border-bottom: 1px solid var(--tp-trait);
  white-space: nowrap;
}

.cl-tableau td {
  height: 52px;
  padding: .625rem;
  border-bottom: 1px solid var(--tp-trait);
  color: var(--tp-encre);
  vertical-align: middle;
}

.cl-tableau tbody tr:nth-child(even) > td {
  background: color-mix(in oklab, var(--tp-creux) 40%, transparent);
}

.cl-tableau tbody tr:last-child > td { border-bottom: 0; }

.cl-tableau tbody tr:hover > td {
  background: color-mix(in oklab, var(--tp-creux) 60%, transparent);
}

.cl-tableau .nombre { text-align: right; }

.cl-tableau th.c-rg   { width: 3.25rem; }
.cl-tableau th.c-club { width: 5.5rem; }
.cl-tableau th.c-pts  { width: 4.75rem; }
.cl-tableau th.c-v    { width: 5.25rem; }
.cl-tableau th.c-j    { width: 6rem; }
.cl-tableau th.c-cout { width: 5.5rem; }

/* LE RANG. Il reste la colonne de tete, mais il cesse de crier : Playfair 17
   au lieu d'une condensee de 2,1 rem. La colonne « Rg » porte deja le sens ;
   c'est la LIGNE qu'on cherche, pas le chiffre. */
.cl-tableau td.c-rg {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 17px;
  line-height: 1.1;
  letter-spacing: 0;
  text-align: left;
  white-space: nowrap;
  color: var(--tp-encre-2);
}

.cl-tableau tr.cl-podium-ligne td.c-rg { color: var(--tp-or-lisible); }

/* Le filet dore sous le rang faisait doublon avec le podium dessine juste
   au-dessus, et decalait la ligne de base des trois premieres lignes. */
.cl-tableau tr.cl-podium-ligne td.c-rg::after { content: none; }

.cl-tableau td.c-rg .cl-hors {
  font-family: var(--tp-texte);
  font-size: 14px;
  color: var(--tp-encre-4);
}

.cl-lien-joueur {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  min-width: 0;
  color: inherit;
  text-decoration: none;
}

.cl-nom-joueur {
  display: block;
  font-weight: 700;
  font-size: 14px;
  line-height: 1.25;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
  transition: color var(--tp-elan);
}

.cl-lien-joueur:hover .cl-nom-joueur { color: var(--tp-or-lisible); }

.cl-sous-joueur {
  display: block;
  margin-top: .0625rem;
  font-size: 12px;
  line-height: 1.35;
  color: var(--tp-encre-3);
}

.cl-sous-joueur .cl-qualifie { color: var(--tp-or-lisible); font-weight: 700; }

.cl-lien-joueur .jeton {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  font-size: 11px;
  box-shadow: none;
}

/* LES POINTS, et le relief du classement en fond. Le degrade reste une
   background-IMAGE : le zebrage et la couleur de survol passent dessous, et il
   n'ajoute pas un nœud de plus au DOM sur 341 lignes. La part vient de
   l'attribut style de la vue (--cl-part) : on la garde telle quelle. */
.cl-tableau td.c-pts {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
  background-image: linear-gradient(to left,
    color-mix(in oklab, var(--tp-or) 20%, transparent) var(--cl-part, 0%),
    transparent 0);
}

.cl-tableau td.c-v { font-weight: 600; color: var(--tp-encre-2); }
.cl-tableau td.c-j { color: var(--tp-encre-3); }

/* Ce que le plafond a retire : une soustraction, donc une donnee de second
   plan. En or profond elle se lisait comme un gain. */
.cl-tableau td.c-cout {
  font-weight: 600;
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* MA LIGNE, doree — et elle le reste par-dessus le zebrage ET le survol, d'ou
   les deux selecteurs. Le fond ne suffit pas en plein soleil sur du gravier :
   le filet d'or a gauche, lui, se voit. */
.cl-tableau tbody tr.cl-moi-ligne > td,
.cl-tableau tbody tr.cl-moi-ligne:hover > td {
  background: var(--tp-ambre-fond);
  font-weight: 700;
}

.cl-tableau tbody tr.cl-moi-ligne > td:first-child {
  box-shadow: inset 3px 0 0 var(--tp-or);
}

.cl-tableau tbody tr.cl-moi-ligne td.c-rg { color: var(--tp-or-lisible); }
.cl-tableau tbody tr.cl-moi-ligne .cl-nom-joueur { color: var(--tp-encre); }

/* L'ancre « Voir ma ligne » : sans cette marge, l'en-tete collant du tableau
   deposerait la ligne juste derriere lui. Le ruban ne compte plus — il est
   passe en bas de l'ecran. */
.cl-tableau tr[id="moi"] {
  scroll-margin-top: calc(var(--cl-tp-entete) + var(--cl-tp-tete) + 1rem);
}

/* Le filtre ne trouve rien : on le dit au milieu du tableau, on ne laisse pas
   une carte vide. */
.cl-tableau .cl-vide td {
  height: auto;
  padding: 2rem 1.25rem;
  text-align: center;
  font-size: 14px;
  color: var(--tp-encre-3);
}

/* Le telephone. La colonne « Plafond » (.col-confort) est deja retiree a
   720 px par app.css : on garde ce seuil pour ne pas creer un second palier. */
@media (max-width: 720px) {
  .cl-tableau { font-size: 13.5px; }
  .cl-tableau th { padding: .625rem .375rem; font-size: 10px; letter-spacing: .06em; }
  .cl-tableau td { padding: .5rem .375rem; }
  .cl-tableau th.c-rg  { width: 2.75rem; }
  .cl-tableau th.c-pts { width: 4rem; }
  .cl-tableau th.c-v   { width: 4.5rem; }
  .cl-tableau td.c-rg  { font-size: 16px; }
  .cl-tableau td.c-pts { font-size: 14px; }
  .cl-lien-joueur .jeton { display: none; }
}

/* ══════════════════════════════════════════════════════════ LA LEGENDE ══
   Le duo icone + phrase sur fond ambre du kit. app.css lui posait un filet de
   4 px a gauche et sable.css une ombre et une animation d'entree : les trois
   partent, le message se lit comme un encart, pas comme une alerte. */

.message.cl-legende {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  margin: 1.5rem 0 0;
  padding: .875rem 1rem;
  background: var(--tp-ambre-fond);
  color: var(--tp-encre);
  border: 0;
  border-radius: var(--tp-r-champ);
  box-shadow: none;
  animation: none;
  font-size: 13.5px;
}

.message.cl-legende .icone {
  flex: 0 0 auto;
  margin-top: .125rem;
  color: var(--tp-or-lisible);
}

.cl-legende strong {
  display: block;
  margin-bottom: .5rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  color: var(--tp-encre);
}

.cl-legende dl { display: grid; gap: .25rem; margin: 0; }

.cl-legende dt {
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--tp-or-lisible);
}

.cl-legende dd {
  margin: 0 0 .5rem;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tp-encre-2);
  max-width: 68ch;
}

.cl-legende dd:last-child { margin-bottom: 0; }

/* ══════════════════════════════════════════════ LES CARTES D'ATTENTE ══
   Les deux ecrans sans classement (« pas encore publie », « rien a classer »)
   n'ont pas de classe a eux : on les tient par la place qu'ils occupent, juste
   sous la banniere du classement. Rien n'est renomme, rien n'est ajoute a la
   vue, et aucune autre page n'est touchee. */

.cl-banniere + .section-mince > .enveloppe > .carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.25rem 1.375rem;
}

.cl-banniere + .section-mince > .enveloppe > .carte h2 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  margin: 0;
}

.cl-banniere + .section-mince > .enveloppe > .carte .muet {
  font-size: 14px;
  line-height: 1.55;
  color: var(--tp-encre-3);
  max-width: 62ch;
}

/* ══════════════════════════════════════════════════════════ LES GESTES ══
   Les trois boutons de la page (« Voir ma ligne », « Voir le calendrier »,
   « Activer mon acces ») prennent la pilule du kit. Ils sont tous HORS
   banniere : les regles hors calque de sable.css, qui reprennent en !important
   les boutons poses sur un bandeau, ne les atteignent pas.
   L'or reste pour UN seul geste par ecran — ici, l'activation du compte. */

.cl-moi-carte .bouton,
.cl-invite .bouton,
.cl-banniere + .section-mince > .enveloppe > .carte .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 1.125rem;
  background: var(--tp-creux);
  color: var(--tp-encre);
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  text-decoration: none;
  box-shadow: none;
  filter: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

.cl-moi-carte .bouton:hover,
.cl-invite .bouton:hover,
.cl-banniere + .section-mince > .enveloppe > .carte .bouton:hover {
  background: color-mix(in oklab, var(--tp-creux) 70%, var(--tp-encre) 8%);
  color: var(--tp-encre);
  filter: none;
}

/* Le bouton plein — celui qui n'est pas « vide » — est le geste de l'ecran. */
.cl-invite .bouton:not(.bouton-vide) {
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
}

.cl-invite .bouton:not(.bouton-vide):hover {
  background: var(--tp-or-vif);
  color: var(--tp-sur-or);
  box-shadow: 0 4px 16px rgb(245 180 28 / .45);
}

.cl-moi-carte .bouton:active,
.cl-invite .bouton:active,
.cl-banniere + .section-mince > .enveloppe > .carte .bouton:active {
  transform: translateY(1px);
}

/* ══════════════════════════════════════════════════════ LES GARDES ══
   Cinq elements de cette page sont poses ou retires par le script au moyen de
   l'attribut hidden. Comme on redeclare « display » sur certains d'entre eux
   (le bouton d'effacement passe en grille, la ligne vide du tableau), il faut
   redire ici que hidden l'emporte : sinon la couche « tire », qui est la
   derniere, revelerait en permanence ce que le script croit avoir cache. */

.cl-ruban[hidden],
.cl-chercher[hidden],
.cl-effacer[hidden],
.cl-tableau tbody tr[hidden],
.cl-tableau tr.cl-vide[hidden] { display: none; }

/* ═══════════════════════════════════════════════════ LE FOCUS CLAVIER ══
   L'anneau or et son halo, comme partout dans le kit. :focus-visible, donc au
   clavier seulement — pas sous la souris. */

.cl-marche:focus-visible,
.cl-lien-joueur:focus-visible,
.cl-banniere :is(.cl-series, .cl-saisons) a:focus-visible,
.cl-ruban a:focus-visible,
.cl-effacer:focus-visible,
.cl-moi-carte .bouton:focus-visible,
.cl-invite .bouton:focus-visible,
.cl-banniere + .section-mince > .enveloppe > .carte .bouton:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* ═══════════════════════════════════════════ LE MOUVEMENT, EN MOINS ══
   Qui demande moins d'animation la coupe entierement. Le trouble du socle
   compris : sans transition, la propriete enregistree saute a sa valeur finale
   des que le script pose la classe — le pied dore arrive, il ne voyage pas. */

@media (prefers-reduced-motion: reduce) {
  .cl-marche,
  .cl-nom-joueur,
  .cl-banniere :is(.cl-series, .cl-saisons) a,
  .cl-chercher input[type="search"],
  .cl-effacer,
  .cl-ruban a,
  .cl-moi-carte .bouton,
  .cl-invite .bouton,
  .cl-banniere + .section-mince > .enveloppe > .carte .bouton,
  .cl-socle.se-trouble {
    transition: none;
  }

  .cl-marche:hover { transform: none; }

  .cl-moi-carte .bouton:active,
  .cl-invite .bouton:active,
  .cl-banniere + .section-mince > .enveloppe > .carte .bouton:active {
    transform: none;
  }
}

/* ══════════════════════════════════════════════════════ L'IMPRESSION ══
   Le comite punaise le classement au mur de la buvette. Les couleurs sont
   ecrites en dur ICI, et seulement ici : les jetons suivent le theme de
   l'ECRAN, et un lecteur en Buvette imprimerait sinon du blanc sur du bleu
   nuit. L'en-tete perd son adherence — un titre colle n'a pas de sens sur du
   papier, et il se repeterait au milieu d'une page. */

@media print {
  .cl-banniere + .section-mince .defile {
    background: #FFFFFF;
    border-color: #999999;
    box-shadow: none;
  }

  .cl-tableau th {
    position: static;
    background: #FFFFFF;
    color: #000000;
    border-bottom-color: #999999;
  }

  .cl-tableau td { border-bottom-color: #DDDDDD; color: #000000; }
  .cl-tableau tbody tr:nth-child(even) > td { background: transparent; }
  .cl-tableau td.c-pts { background-image: none; }
  .cl-tableau tbody tr.cl-moi-ligne > td { background: #F2F2F2; }
  .cl-tableau tbody tr.cl-moi-ligne > td:first-child { box-shadow: inset 3px 0 0 #000000; }
  .cl-tableau td.c-cout,
  .cl-sous-joueur,
  .cl-marche .cl-detail { color: #444444; }

  .cl-marche {
    background: #FFFFFF;
    color: #000000;
    border-color: #999999;
    box-shadow: none;
  }

  .cl-marche .cl-nom,
  .cl-marche .cl-pts-podium,
  .cl-nom-joueur,
  .cl-tableau td.c-rg { color: #000000; }

  .cl-moi-carte {
    break-inside: avoid;
    border-color: #999999;
    box-shadow: none;
  }

  .cl-tableau tr { break-inside: avoid; }

  .message.cl-legende {
    background: transparent;
    border: 1px solid #999999;
    color: #000000;
  }
}

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   LA PAGE JOURNEE, LE PLUS GROS GABARIT DU SITE
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — LA PAGE JOURNEE (app/Views/pages/competition.php)

   Le plus gros gabarit du site : l'en-tete de la journee, la reponse « Je
   viens », la recherche d'equipier, le covoiturage, la photo de tablee, le
   SOS, le livre d'or, le retour au comite, mes parties, le classement du
   jour, le tirage par tour, qui vient et les equipes inscrites.

   Cette feuille PROLONGE assets/css/tire.css : memes jetons, memes mesures,
   meme ton. Elle ne renomme rien — app.js accroche [data-dispo],
   [data-recherche-joueur] et bascule lui-meme .bouton/.bouton-vide/
   .bouton-bleu ; le script d'onglets de la vue fabrique des [role="tab"] qui
   portent .pastille ; eclat.js pose [data-reveler]. On leur donne un DESSIN.

   CE QU'ELLE HABILLE, ET CE QU'ELLE LAISSE
     · a elle seule : .jr-* (trente classes qui n'avaient AUCUNE regle nulle
       part — la section equipier et le covoiturage sortaient nus), .nuee,
       .etat-vide, .carte-attente, les commandes sans classe (#sos-message,
       #livre-texte, #retour-commentaire) et tous les blocs a #id ;
     · partage du site : .banniere, .surtitre, .etiquette, .pastille, .jeton,
       .chiffre, .rencontre. On les dessine aux mesures du kit, jamais a des
       mesures a soi : deux familles qui suivent tire.css tombent d'accord ;
     · laisse au socle : .carte (fond), .bouton, .champ, .message et le corps
       de .tableau. On n'y touche que dans nos propres conteneurs.

   LE GARDE-FOU DE SELECTEUR : :where(#contenu:not(.poste-plan)). Le kit du
   comite (tire-poste.css) vit dans la meme couche et le panneau rend AUSSI
   dans <main id="contenu" class="poste-plan"> — sans ce :not, une etiquette
   de statut du site irait redessiner celles de la table de marque. :where()
   ne coute AUCUNE specificite : la regle reste a un seul point de classe, et
   le socle garde la main s'il ecrit plus precis.

   ⚠️ Les couleurs a l'interieur de .banniere sont VERROUILLEES par un bloc
   !important HORS COUCHE de sable.css (lignes 728-743). Rien ici ne peut les
   reprendre, et surtout pas un !important : pour ces declarations la cascade
   INVERSE l'ordre des couches, « tire » etant la derniere serait la plus
   faible. On dessine donc l'en-tete AUTOUR de son encre : la graisse, la
   famille, le corps, l'espace — jamais la teinte. Le detail des declarations
   qui resistent est dans le rapport.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ───────────────────────────────────────────────────── LE RYTHME DE LA PAGE ──
   Douze sections a la suite. app.css leur donnait 2 rem HAUT ET BAS, soit
   quatre centimetres de creme entre deux titres : la page se lisait comme une
   pile de feuillets separes. On resserre a 1,25 rem — le surtitre et sa barre
   d'or suffisent a dire qu'une section commence. */

:where(#contenu:not(.poste-plan)) .section-mince { padding-block: 1.25rem; }

/* Les ancres de la page. Huit sections portent un #id et le site s'y rend par
   lien (#equipier depuis une notification, #mes-parties apres un « bien joue »,
   #retour depuis le courriel du soir). L'en-tete est COLLANTE sur 64 px : sans
   decalage, le navigateur amene le titre de la section pile dessous et le
   lecteur arrive sur un bloc decapite. Aucune feuille publique ne posait ce
   decalage — il n'existait que pour le panneau du comite et l'agenda. */
#equipier,
#voiture,
#tablee,
#sos,
#livre-or,
#retour,
#mes-parties,
#projection { scroll-margin-top: calc(64px + 1rem); }

/* La zone sure du telephone. tire.css rend deja la hauteur volee par la barre
   d'onglets ; il reste les cotes, qui mangent le texte en paysage sur un
   iPhone a encoche une fois le site installe en PWA. max() : la gouttiere
   normale gagne partout ailleurs, la regle ne coute rien. */
:where(#contenu:not(.poste-plan)) .banniere > .enveloppe,
:where(#contenu:not(.poste-plan)) .section-mince > .enveloppe {
  padding-inline: max(var(--gouttiere, 1rem), env(safe-area-inset-left), env(safe-area-inset-right));
}

/* Le surtitre de section. app.css le posait en 11,2 px graisse 800 espace
   .2em avec un filet or de 24 x 3 ; sable l'a passe en or plein. Douze
   surtitres dores sur une page, c'est douze accents : l'or ne designe plus
   rien. L'encre reprend le mot, le filet garde l'or — un seul trait. */
:where(#contenu:not(.poste-plan)) .surtitre {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin: 0 0 .625rem;
}

:where(#contenu:not(.poste-plan)) .surtitre::before {
  content: "";
  flex: 0 0 auto;
  width: 22px;
  height: 2px;
  border-radius: 2px;
  background: var(--tp-or);
}

/* L'intitule de champ et de bloc, celui que la vue ecrit en <p>, en <label>
   et en <legend>. Le <p> emportait 1 rem de marge basse du socle : le titre
   flottait au-dessus de son propre formulaire. */
:where(#contenu:not(.poste-plan)) .etiquette {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  margin: 0 0 .5rem;
}

/* Les utilitaires de texte, en :where() a zero point de specificite : ils
   passent devant app.css par le seul ordre des couches, et toute regle
   nommee de cette feuille (.jr-mot, .jr-comite…) passe devant eux sans
   qu'on ait a la surcharger d'ancetres. */
:where(#contenu:not(.poste-plan)) :where(.muet)  { color: var(--tp-encre-3); }
:where(#contenu:not(.poste-plan)) :where(.petit) { font-size: 13px; }
:where(#contenu:not(.poste-plan)) :where(.minus) { font-size: 12.5px; }
:where(#contenu:not(.poste-plan)) :where(.gras)  { font-weight: 700; }
:where(#contenu:not(.poste-plan)) :where(.jaune) { color: var(--tp-or-lisible); }
:where(#contenu:not(.poste-plan)) :where(.vert)  { color: var(--tp-vert); }
:where(#contenu:not(.poste-plan)) :where(.rouge) { color: var(--tp-rouge); }

/* ⚠️ .mt-1 et .mt-3 n'existent DANS AUCUNE feuille du projet : app.css ne
   declare que 2, 4, 5 et 6. Dix vues les ecrivent quand meme, dont celle-ci
   huit fois — la phrase du resume du soir, la rangee des quatre chiffres, la
   signature du livre d'or et le mot du SOS collaient donc au bloc du dessus.
   On les pose ici, sur l'echelle de app.css (.25 rem et .75 rem), pour que
   la page tienne son rythme sans qu'on touche au balisage. */
:where(#contenu:not(.poste-plan)) :where(.mt-1) { margin-top: .25rem; }
:where(#contenu:not(.poste-plan)) :where(.mt-3) { margin-top: .75rem; }

/* Le nom de code d'une table du schema, dans la note reservee au comite. */
:where(#contenu:not(.poste-plan)) code {
  padding: .0625rem .375rem;
  border-radius: var(--tp-r-tuile);
  background: var(--tp-creux);
  font-size: .9em;
  color: var(--tp-encre-2);
}

/* ────────────────────────────────────────────────────────────── LE HEROS ──
   L'en-tete de la journee : le type de journee et la date, le nom, puis
   l'heure, la formule, les points, les terrains, l'adresse et le club qui
   recoit. Pas de photo : la seule de la page est la tablee, plus bas.

   Ce qu'on DEFAIT, propriete par propriete : l'aplat jaune plein cadre de
   app.css, ses 2 rem de padding (et le 1,5 rem de sa media query a 640) ;
   puis, cote sable, cinq rem de padding haut, le h1 a 7,4 rem d'affiche, la
   boule en filigrane de la variante bleue et la cascade d'entree des trois
   lignes. Redeclarer le seul fond aurait laisse le reste en place. */

:where(#contenu:not(.poste-plan)) .banniere,
:where(#contenu:not(.poste-plan)) .banniere-bleue {
  position: relative;
  overflow: visible;
  background: transparent;
  padding-block: 1.75rem 1.25rem;
  border-bottom: 1px solid var(--tp-trait);
}

/* La boule photographique posee derriere le titre d'une journee terminee.
   Elle date de la charte d'avant ; sur le papier creme elle fait une tache. */
:where(#contenu:not(.poste-plan)) .banniere-bleue::before { content: none; }

/* Aucune animation d'entree : trois lignes qui montent l'une apres l'autre
   font perdre plus de temps qu'elles n'en donnent, et c'est la premiere
   chose que lit quelqu'un qui cherche l'heure du dimanche. */
:where(#contenu:not(.poste-plan)) .banniere > .enveloppe > *,
:where(#contenu:not(.poste-plan)) .banniere-bleue > .enveloppe > * { animation: none; }

/* Playfair en CASSE NORMALE. Le socle imposait Big Shoulders 800, un
   interlignage de .88 et un creusement de -.022em — c'est exactement la
   criee de l'ancienne charte qu'on enleve. */
:where(#contenu:not(.poste-plan)) .banniere h1,
:where(#contenu:not(.poste-plan)) .banniere-bleue h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.625rem, 1.15rem + 2vw, 2.375rem);
  line-height: 1.12;
  letter-spacing: -.01em;
  text-transform: none;
  text-wrap: balance;
  margin: 0 0 .375rem;
}

:where(#contenu:not(.poste-plan)) .banniere .sous,
:where(#contenu:not(.poste-plan)) .banniere-bleue .sous {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.65;
  max-width: 64ch;
  margin: 0;
}

/* Le lien vers le club qui recoit porte un style= « color:inherit » : sa
   teinte ne nous appartient pas, son soulignage si — c'est lui qui dit que
   la ligne est cliquable. */
:where(#contenu:not(.poste-plan)) .banniere .sous a,
:where(#contenu:not(.poste-plan)) .banniere-bleue .sous a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* ─────────────────────────────────────────────── L'ETIQUETTE DE STATUT ──
   Vingt-huit pastilles sur cette page : presents, peut-etre, absents,
   forfait, exempte, tour a jouer, invitation envoyee, place retenue…

   ⚠️ tire.css dessine .pastille pour le COMPTEUR de l'en-tete : un disque
   rouge de 18 px a chiffre blanc. Toutes les etiquettes de statut du site
   tombaient dedans — « Vous montez » s'affichait en rouge. On redonne ici le
   dessin d'etiquette du kit (24 px, Inter 700 11, duo texte + fond), et le
   garde-fou de selecteur laisse le compteur tranquille : il vit dans .nav et
   dans la barre d'onglets, hors de <main>. */

:where(#contenu:not(.poste-plan)) .pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  min-width: 0;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: none;
}

/* Le duo texte + fond de chaque teinte de sens : l'etat tient a 11 px, et il
   tient aussi pour qui ne separe pas le vert du rouge — le mot est ecrit. */
:where(#contenu:not(.poste-plan)) .pastille-verte  { background: var(--tp-vert-fond);  color: var(--tp-vert); }
:where(#contenu:not(.poste-plan)) .pastille-rouge  { background: var(--tp-rouge-fond); color: var(--tp-rouge); }
:where(#contenu:not(.poste-plan)) .pastille-ambre  { background: var(--tp-ambre-fond); color: var(--tp-ambre); }
:where(#contenu:not(.poste-plan)) .pastille-neutre { background: var(--tp-creux);      color: var(--tp-encre-3); }

/* La marine : les jetons plutot qu'un gris de plus. Elle est faite de deux
   jetons qui se croisent — l'encre pleine, le papier par-dessus — donc elle
   se retourne toute seule la nuit. */
:where(#contenu:not(.poste-plan)) .pastille-bleue {
  background: var(--tp-encre);
  color: var(--tp-sol);
}

/* Le contour seul : « vous », sur sa propre ligne. Un trait, pas un fond. */
:where(#contenu:not(.poste-plan)) .pastille-vide {
  background: transparent;
  color: var(--tp-encre-3);
  box-shadow: inset 0 0 0 1px var(--tp-trait-fort);
}

/* Les onglets Hommes / Dames du classement du jour. Le script de la vue les
   fabrique avec .pastille et un style= qui pose « font: inherit », donc le
   corps et la graisse nous echappent : inutile de les ecrire. Restent la
   casse, la teinte et la forme — et une etiquette de 11 px en capitales
   espacees ferait crier un onglet de 15 px. */
:where(#contenu:not(.poste-plan)) [role="tab"] {
  height: auto;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  letter-spacing: 0;
  text-transform: none;
  transition: background var(--tp-elan), color var(--tp-elan);
}

:where(#contenu:not(.poste-plan)) [role="tab"][aria-selected="true"] {
  background: var(--tp-or);
  color: var(--tp-sur-or);
  font-weight: 700;
  box-shadow: none;
}

/* Le panneau recoit tabindex=0 pour le clavier : il doit donc se voir quand
   il prend le focus, sans halo qui deborde de la carte. */
:where(#contenu:not(.poste-plan)) [data-serie-jour]:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 4px;
  border-radius: var(--tp-r-carte);
}

/* ──────────────────────────────────────────────── LE JETON ET LES NOMS ──
   Le jeton porte des initiales ou un numero d'equipe. sable en faisait un
   disque marine cercle de blanc avec une ombre portee : trente disques
   marine sur la page, c'est trente points d'appel pour une information de
   service. Le creux du kit, comme .tp-avatar.

   Les trois tailles posees en style= dans la vue (22, 28 px) resistent et
   c'est tant mieux : elles distinguent la nuee des noms de la liste des
   equipes. On ne met donc PAS de bordure — un anneau de 2 px sur un disque
   de 22 px n'est plus un disque. */

:where(#contenu:not(.poste-plan)) .jeton {
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0;
  line-height: 1;
  box-shadow: none;
  overflow: hidden;
}

/* La nuee : chaque present est une cible tactile de 44 px, pas un mot dans
   un paragraphe. On y entre par le nom, on en sort par la fiche. */
:where(#contenu:not(.poste-plan)) .nuee {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem;
}

:where(#contenu:not(.poste-plan)) .nom-joueur {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  padding: .25rem .875rem .25rem .3125rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  box-shadow: none;
  color: var(--tp-encre);
  font-weight: 600;
  font-size: 13.5px;
  text-decoration: none;
  white-space: nowrap;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

:where(#contenu:not(.poste-plan)) .nom-joueur:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
}

/* ───────────────────────────────────────────────────────── LES CHIFFRES ──
   Les scores, les victoires, la place du jour. Big Shoulders 900 a
   interlignage .9 appartenait a l'ancienne charte ; Playfair 700 tabulaire
   le remplace — tabulaire parce que ces chiffres s'empilent en colonne et
   que sans ca les unites dansent d'une ligne a l'autre. */

:where(#contenu:not(.poste-plan)) .chiffre {
  font-family: var(--tp-titre);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
  color: var(--tp-encre);
}

:where(#contenu:not(.poste-plan)) .chiffre-l { font-size: 1.75rem; }
:where(#contenu:not(.poste-plan)) .chiffre-m { font-size: 1.1875rem; }
:where(#contenu:not(.poste-plan)) .chiffre sup { font-size: .5em; font-weight: 700; }

/* ─────────────────────────────────────────────── LA REPONSE « JE VIENS » ──
   Trois boutons, un seul tenu. app.js bascule lui-meme les classes apres
   l'envoi sans recharger : le dessin doit donc tenir sur .bouton /
   .bouton-vide / .bouton-bleu, jamais sur un etat a nous.

   A 390 px, trois pilules cote a cote debordent. On les laisse partager la
   ligne : deux en haut, une en bas, chacune pleine largeur de sa part. */

[data-dispo] { gap: .5rem; }
[data-dispo] .bouton { flex: 1 1 9rem; }

/* La reponse du serveur, ecrite par app.js dans un <p> qu'il cree lui-meme.
   Sa teinte lui appartient (il pose style.color) ; le reste est a nous. */
[data-dispo-groupe] [data-retour] {
  margin: .625rem 0 0;
  font-weight: 600;
  font-size: 13px;
}

/* ───────────────────────────────────────────────── LES COMMANDES NUES ──
   Trois champs de la page vivent HORS d'un .champ : le mot du SOS, le livre
   d'or et le commentaire du retour au comite. Aucune feuille ne les voyait
   — ils sortaient en champ de navigateur brut, bord gris et coins carres, au
   milieu de cartes a rayon 16. Ils prennent ici le dessin de .tp-champ. */

#sos-message,
#retour-commentaire,
#livre-texte {
  display: block;
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 15px;
  line-height: 1.5;
  color: var(--tp-encre);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

#livre-texte { resize: vertical; }

#sos-message::placeholder,
#retour-commentaire::placeholder,
#livre-texte::placeholder { color: var(--tp-encre-4); }

/* Un champ dont on ne sait pas qu'il a le curseur est un formulaire qu'on
   remplit deux fois : l'anneau or et son halo, comme partout dans le kit. */
#sos-message:focus,
#retour-commentaire:focus,
#livre-texte:focus {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* ─────────────────────────────────────────────── TROUVER UN EQUIPIER ──
   Le geste du samedi soir. Trente classes .jr-* sans UNE SEULE regle dans
   tout le projet : la section sortait en paragraphes empiles. Tout ce qui
   suit est donc un dessin neuf — rien a defaire, tout a poser. */

.jr-equipier,
.jr-voiture {
  display: grid;
  gap: .75rem;
}

/* La note grise : « votre equipe est inscrite », « connectez-vous ». Une
   carte basse, qui dit sans appeler. */
.jr-note {
  margin: 0;
  padding: .8125rem 1rem;
  font-size: 13.5px;
  line-height: 1.5;
}

.jr-note a {
  color: var(--tp-or-lisible);
  font-weight: 700;
  text-underline-offset: 2px;
}

/* Le formulaire « il vous manque un equipier ? ». */
.jr-opt > p { margin: 0; }
.jr-opt > p + p { margin-top: .375rem; }
.jr-opt .champ { margin-top: .875rem; }
.jr-opt .bouton { margin-top: .875rem; }

/* « (facultatif) » : le mot doit se lire comme une aparte dans l'intitule,
   donc sans la casse ni l'espacement des capitales de .etiquette. */
.jr-facultatif {
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tp-encre-3);
}

/* Les invitations recues : c'est LE geste de la section, et il se repond en
   deux boutons. Le liseré d'or a gauche, jamais un aplat — l'or en aplat
   mangerait le texte. */
.jr-invitations,
.jr-demandes {
  display: grid;
  gap: .625rem;
}

.jr-invitation,
.jr-demande {
  padding: .9375rem 1rem;
}

.jr-invitation p,
.jr-demande p { margin: 0; }

.jr-invitation p + p,
.jr-demande p + p { margin-top: .375rem; }

/* La liste des joueurs qui cherchent. Une colonne a 390 px, deux des que la
   place existe : min(100%, 300px) empeche la grille de forcer une colonne
   plus large que l'ecran — c'est ce qui fait deborder une page. */
.jr-liste {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: .625rem;
}

.jr-fiche {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-height: 72px;
  padding: .75rem .875rem;
}

/* L'avatar de la fiche. Il tient sa taille de .jeton, mais on l'ecrit ici
   noir sur blanc : le jour ou le socle donnera a .jeton un selecteur plus
   precis que le notre, la fiche garderait sinon un disque de 34 px du fond
   d'une feuille d'avant. */
.jr-jeton {
  width: 44px;
  height: 44px;
  font-size: 14px;
}

.jr-fiche-texte {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: break-word;
}

.jr-fiche-texte > p { margin: 0; }
.jr-fiche-texte > p + p { margin-top: .125rem; }

.jr-nom {
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
}

.jr-nom a {
  color: var(--tp-encre);
  text-decoration: none;
}

.jr-nom a:hover {
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* La ligne « c'est moi » : le liseré d'or du kit, celui de la ligne « Vous »
   du classement. Un trait a gauche et une bordure doree, pas un fond. */
.jr-fiche-moi {
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

/* « vous » : la plus petite etiquette de la page, posee au bout du nom. */
.jr-mini {
  height: 20px;
  padding: 0 .4375rem;
  font-size: 10px;
  letter-spacing: .05em;
  vertical-align: 1px;
}

/* « vient peut-etre » : le mot porte le sens, l'ambre ne fait que l'appuyer. */
.jr-peutetre {
  color: var(--tp-ambre);
  font-weight: 600;
}

/* Le mot que la personne a ecrit — a la main, comme une note au crayon sur
   la feuille de match. C'est la seule chose de cette fiche qu'un humain a
   redigee : elle ne doit pas ressembler a une donnee de plus. */
.jr-mot {
  font-family: var(--tp-main);
  font-size: 1.0625rem;
  line-height: 1.3;
  color: var(--tp-encre-2);
}

.jr-fiche-action { flex: 0 0 auto; }

/* Le compte pour la table de marque : une note de service, mise a part. */
.jr-comite {
  margin: .75rem 0 0;
  padding: .625rem .875rem;
  border-radius: var(--tp-r-champ);
  background: var(--tp-creux);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tp-encre-2);
}

/* L'ecran vide dit ce qui manque ET donne le geste. Le cercle ouvert de
   app.css est garde — c'est la signature du site — mais reduit et pose sur
   un trait du kit : a 92 px il pesait plus que la phrase. */
:where(#contenu:not(.poste-plan)) .etat-vide {
  display: grid;
  justify-items: center;
  gap: .625rem;
  padding: 2.25rem 1.25rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  text-align: center;
  color: var(--tp-encre-3);
}

:where(#contenu:not(.poste-plan)) .etat-vide::before {
  width: 72px;
  height: 72px;
  border: 2px solid var(--tp-trait-fort);
}

:where(#contenu:not(.poste-plan)) .etat-vide .titre {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.25;
  color: var(--tp-encre);
}

:where(#contenu:not(.poste-plan)) .etat-vide p {
  margin: 0;
  max-width: 42ch;
  font-size: 13.5px;
}

/* Le dicton de l'ecran vide : de la main, lui aussi. */
.jr-vide p:last-child {
  font-family: var(--tp-main);
  font-size: 1.0625rem;
  color: var(--tp-encre-3);
}

/* ─────────────────────────────────────────────────────── LE COVOITURAGE ──
   Cent kilometres d'Arlon a Bastogne, et beaucoup de licencies qui ne
   conduisent plus. Le formulaire d'annonce, puis les voitures. */

.jr-annonce-form > p { margin: 0; }
.jr-annonce-form > p + p { margin-top: .375rem; }

/* Le choix du sens. Un <fieldset> garde son bord et ses marges d'agent
   utilisateur : sans ce nettoyage, deux traits gris entourent la question.
   On le laisse en bloc et ce sont les etiquettes qui se rangent : une
   <legend> dans un conteneur flex ne se place pas pareil d'un moteur a
   l'autre, et ce formulaire se remplit surtout au telephone. */
.jr-sens {
  min-inline-size: 0;
  margin: .875rem 0 0;
  padding: 0;
  border: 0;
}

.jr-sens > legend {
  float: none;
  padding: 0;
  margin-bottom: .5rem;
}

/* Chaque choix est une pilule de 44 px : on la touche au pouce, pas au
   millimetre du petit rond. */
.jr-radio {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  margin: 0 .5rem .5rem 0;
  padding: 0 .9375rem 0 .75rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  font-weight: 600;
  font-size: 14px;
  color: var(--tp-encre);
  cursor: pointer;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

.jr-radio input {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--tp-or);
}

/* Le choix tenu : un fond ambre ET le rond coche. La couleur ne porte
   jamais l'etat toute seule. */
.jr-radio:has(input:checked) {
  background: var(--tp-ambre-fond);
  border-color: color-mix(in oklab, var(--tp-or) 55%, var(--tp-trait));
}

.jr-radio:has(input:focus-visible) {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
}

/* Commune, heure, places : trois champs qui tiennent sur une ligne des que
   la place existe, et l'un sous l'autre a 390 px. */
.jr-champs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 180px), 1fr));
  gap: .75rem;
  margin-top: .875rem;
}

.jr-annonce-form .aide {
  display: block;
  margin-top: .25rem;
  font-size: 12.5px;
  color: var(--tp-encre-3);
}

.jr-annonce-form .champ { margin-top: .875rem; }
.jr-annonce-form .jr-champs .champ { margin-top: 0; }
.jr-annonce-form .bouton { margin-top: 1rem; }

/* Mon annonce publiee : la carte cerclee d'or du site. sable en faisait un
   double liseré interieur de 2 px ; le kit dit un trait dore et le liseré a
   gauche — le meme signe que « c'est moi » dans les listes. */
:where(#contenu:not(.poste-plan)) .carte-cerclee,
.jr-mienne {
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

.jr-mienne p { margin: 0; }
.jr-mienne p + p { margin-top: .375rem; }
.jr-mienne form { margin-top: .875rem; }

/* Le titre d'une des deux listes de voitures. */
.jr-titre-liste { margin: .75rem 0 .5rem; }

/* Le nombre de places libres, dans le jeton : c'est la seule donnee qu'on
   lit en diagonale dans cette liste, donc c'est elle qui prend l'or. L'or
   est un FOND, le chiffre est ecrit dessus en encre. */
.jr-places {
  background: var(--tp-or);
  color: var(--tp-sur-or);
  font-family: var(--tp-titre);
  font-size: 18px;
}

.jr-places-mot {
  font-weight: 600;
  color: var(--tp-encre-2);
}

/* Voiture complete : la fiche s'eteint, mais reste lisible — on doit encore
   pouvoir lire qui part d'ou, ne serait-ce que pour demander la prochaine
   fois. Pas d'opacite globale : elle emporterait aussi le nom. */
.jr-fiche-complete {
  background: color-mix(in oklab, var(--tp-creux) 40%, var(--tp-carte));
  box-shadow: none;
}

.jr-fiche-complete .jr-places {
  background: var(--tp-creux);
  color: var(--tp-encre-3);
}

/* ───────────────────────────────────────────────────── LA PHOTO DE TABLEE ──
   La seule photo de la page. Le style= de la vue tient deja le cadrage
   (padding 0, debordement coupe, hauteur plafonnee, object-fit) : il ne
   reste qu'a poser la carte autour et la legende dessous. */

#tablee figure {
  margin: 0;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
}

#tablee figcaption {
  border-top: 1px solid var(--tp-trait);
  font-size: 12.5px;
  color: var(--tp-encre-3);
}

/* ──────────────────────────────────────────────────────── SOS REMPLACANT ──
   « Mon equipier ne peut plus venir. » Le repli se lit comme un bouton
   fantome, pas comme un lien perdu sous une liste : le marqueur natif du
   <summary> est remplace par un chevron qui tourne a l'ouverture. */

#sos > .enveloppe > .carte { padding: .9375rem 1rem; }
#sos .carte p { margin: 0; }
#sos .carte p + p { margin-top: .375rem; }

#sos details { margin-top: .875rem; }

#sos summary {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 1.125rem;
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-pilule);
  background: transparent;
  color: var(--tp-encre);
  font-size: 14px;
  font-weight: 700;
  list-style: none;
  transition: background var(--tp-elan);
}

#sos summary::-webkit-details-marker { display: none; }

#sos summary::after {
  content: "";
  width: 8px;
  height: 8px;
  border-right: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  rotate: 45deg;
  translate: 0 -2px;
  transition: rotate var(--tp-elan);
}

#sos details[open] summary::after { rotate: 225deg; translate: 0 2px; }

#sos summary:hover { background: color-mix(in oklab, var(--tp-creux) 45%, transparent); }

#sos form.carte { margin-top: .625rem; }
#sos form.carte .bouton { margin-top: .75rem; }

/* ──────────────────────────────────────────────────────── LE LIVRE D'OR ──
   Ce que les gens ecrivent le soir, pour le club qui a recu. C'est le seul
   endroit du site ou la main prend tout le bloc : papier texture, ecriture
   a la main, signature en petit dessous. Une carte blanche a corps de texte
   ferait une zone de commentaires ; ici on veut une page de livre. */

#livre-or .carte.mb-2 {
  background-color: color-mix(in oklab, var(--tp-or) 6%, var(--tp-carte));
  background-image: var(--tp-papier);
  background-size: 512px;
  padding: 1.125rem 1.25rem;
}

#livre-or .carte.mb-2 > p:first-child {
  margin: 0;
  font-family: var(--tp-main);
  font-size: 1.3125rem;
  color: var(--tp-encre-2);
}

#livre-or .carte.mb-2 > p + p {
  margin: .625rem 0 0;
  color: var(--tp-encre-3);
}

#livre-or .carte.mb-2 a { color: var(--tp-encre-2); }

#livre-or form.carte .bouton { margin-top: .75rem; }

/* ───────────────────────────────────────────────── LE RETOUR AU COMITE ──
   Anonyme, trois crans. Les etoiles sont du texte : le choix se dit donc
   par la pilule tenue, pas par la teinte des etoiles. */

#retour label.rang {
  flex-wrap: nowrap;
  min-height: 44px;
  padding: 0 .9375rem 0 .75rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  font-weight: 600;
  font-size: 14px;
  color: var(--tp-encre);
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

#retour label.rang input {
  width: 18px;
  height: 18px;
  margin: 0;
  accent-color: var(--tp-or);
}

#retour label.rang:has(input:checked) {
  background: var(--tp-ambre-fond);
  border-color: color-mix(in oklab, var(--tp-or) 55%, var(--tp-trait));
}

#retour label.rang:has(input:focus-visible) {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
}

#retour .bouton { margin-top: .75rem; }

/* ─────────────────────────────────────────────────────────── MES PARTIES ──
   Le resume du soir, la projection en direct, puis une carte par tour. */

/* La carte d'attention de la page — resume du soir, invitation, SOS ouvert,
   partie a jouer. sable en faisait un APLAT d'or a encre #0F1733 : la nuit,
   l'encre blanche du theme tombait a 1,9:1 dessus, et six aplats d'or sur
   une page annulent la regle du seul accent. On garde le sens (« regardez
   ici ») avec le fond ambre du kit et l'encre courante, qui se retourne avec
   le theme.  ⚠️ Le socle peut revendiquer .carte-jaune : meme dessin des
   deux cotes, c'est voulu. */
:where(#contenu:not(.poste-plan)) .carte-jaune {
  background: var(--tp-ambre-fond);
  border: 1px solid color-mix(in oklab, var(--tp-or) 40%, var(--tp-trait));
  box-shadow: var(--tp-ombre);
  color: var(--tp-encre);
}

/* Sur ce fond ambre, l'encre pale du gris de service perd le contraste :
   on remonte d'un cran. */
:where(#contenu:not(.poste-plan)) .carte-jaune :where(.muet, .minus, .petit) { color: var(--tp-encre-2); }

#mes-parties .carte { padding: .9375rem 1rem; }
#mes-parties .carte p { margin: 0; }
#mes-parties .carte p + p { margin-top: .375rem; }

/* Les quatre chiffres de la soiree : victoires, place, points, rang. Le
   chiffre au-dessus, son intitule en capitales dessous — la tuile du kit,
   sans les bords : la carte les tient deja. */
#mes-parties .carte-jaune > .rang > span {
  display: grid;
  gap: .0625rem;
}

#mes-parties .carte-jaune > .rang > span > .minus {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-2);
}

/* Le score d'une partie jouee : le seul grand chiffre de la carte. */
#mes-parties .chiffre-l { font-size: 1.875rem; }
#mes-parties .chiffre-l .muet { color: var(--tp-encre-4); }

/* Les adversaires, chacun vers sa fiche. */
#mes-parties .carte a {
  color: var(--tp-encre);
  text-decoration-color: color-mix(in oklab, var(--tp-encre) 30%, transparent);
  text-underline-offset: 2px;
}

/* Mes points en direct : un encadre de lecture, pas une carte de plus. */
#projection .surtitre { margin: 0; }
#projection strong { font-weight: 700; color: var(--tp-encre); }

/* ──────────────────────────────────────────────── LE CLASSEMENT DU JOUR ──
   L'attente d'abord (le comite relit avant de publier), puis les onglets et
   la table. */

/* La carte d'attente portait un filet jaune de 4 px a gauche, en bordure :
   le rayon ne pouvait plus l'arrondir, et le trait cassait sur l'angle. Le
   meme signe passe par une ombre interieure — le liseré du kit. Le raccourci
   « border » remet d'abord les quatre cotes a un trait fin : sans lui, le
   4 px de gauche survivrait. */
:where(#contenu:not(.poste-plan)) .carte-attente {
  display: grid;
  gap: .5rem;
  padding: 1.125rem 1.25rem;
  background: var(--tp-carte);
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
  text-align: left;
}

:where(#contenu:not(.poste-plan)) .carte-attente-titre {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.1875rem;
  line-height: 1.25;
  color: var(--tp-encre);
}

:where(#contenu:not(.poste-plan)) .carte-attente-dit {
  margin: 0;
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.6;
  color: var(--tp-encre-2);
}

/* Les titres de serie et de tour. Le socle les mettait en Archivo 700 a
   22,4 px ; leur teinte est posee en style= dans la vue et ne nous
   appartient pas — la famille, le corps et l'espace, si. Les marges
   reprennent celles que .mt-5 / .mb-2 posaient, au rythme d'ici. */
:where(#contenu:not(.poste-plan)) [data-serie-jour] > h3,
:where(#contenu:not(.poste-plan)) .section-mince > .enveloppe > h3 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -.005em;
  margin: 1.25rem 0 .625rem;
}

/* La table du jour. Le corps de .tableau appartient au socle ; ici on ne
   pose que ce qui est propre au classement d'une journee : la colonne des
   places, l'alignement des nombres et la tenue a 390 px. */
[data-serie-jour] .tableau { font-variant-numeric: tabular-nums; }

[data-serie-jour] .tableau .chiffre {
  font-size: 1.125rem;
  line-height: 1;
}

[data-serie-jour] .tableau .nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* La marque de l'equipe invaincue jusqu'au dernier tour : un signe, pas une
   couleur seule — le titre de l'attribut le dit, et l'or reste lisible. */
[data-serie-jour] .tableau .jaune {
  font-weight: 700;
  color: var(--tp-or-lisible);
}

/* Les noms d'equipe sont la seule colonne qui peut passer a la ligne : sans
   ca, la table pousse la page a deborder sur le cote au telephone. */
[data-serie-jour] .tableau td.gras {
  font-weight: 700;
  line-height: 1.3;
  overflow-wrap: break-word;
}

[data-serie-jour] .tableau td.gras a { color: var(--tp-encre); }

@media (max-width: 640px) {
  [data-serie-jour] .tableau { font-size: 13px; }
  [data-serie-jour] .tableau th,
  [data-serie-jour] .tableau td { padding: .625rem .5rem; }
}

/* ───────────────────────────────────────────────────── LE TIRAGE PAR TOUR ──
   Terrain, equipe A, score, equipe B. C'est le tableau d'affichage du club,
   pose sur la page : le terrain dans sa tuile, le score en Playfair.

   ⚠️ L'ancienne regle de app.css a une media query a 640 px qui rebat toute
   la grille (deux colonnes, zones nommees). Elle continue de s'appliquer :
   on la reecrit donc entierement, sinon les colonnes d'ici et les zones de
   la-bas se contredisent au telephone. */

:where(#contenu:not(.poste-plan)) .rencontre {
  display: grid;
  grid-template-columns: 44px 1fr auto 1fr;
  grid-template-areas: none;
  align-items: center;
  gap: .75rem;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
}

/* Le numero de terrain : une tuile creuse, pas un chiffre en l'air. C'est
   par lui qu'on retrouve sa partie quand on arrive en retard. */
:where(#contenu:not(.poste-plan)) .rencontre .jeu {
  display: grid;
  place-items: center;
  min-height: 36px;
  border-radius: var(--tp-r-tuile);
  background: var(--tp-creux);
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 16px;
  line-height: 1;
  color: var(--tp-encre-2);
  font-variant-numeric: tabular-nums;
}

:where(#contenu:not(.poste-plan)) .rencontre .equipe {
  min-width: 0;
  font-weight: 600;
  font-size: 13.5px;
  line-height: 1.3;
  overflow-wrap: break-word;
}

:where(#contenu:not(.poste-plan)) .rencontre .equipe a { color: var(--tp-encre); }

/* Le numero d'equipe passe sous le nom : sur la meme ligne il se lisait
   comme une partie du nom. */
:where(#contenu:not(.poste-plan)) .rencontre .num {
  display: block;
  margin-top: .125rem;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  color: var(--tp-encre-3);
}

:where(#contenu:not(.poste-plan)) .rencontre .score {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 22px;
  line-height: 1;
  color: var(--tp-encre);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

:where(#contenu:not(.poste-plan)) .rencontre .score .muet,
:where(#contenu:not(.poste-plan)) .rencontre .score .perdant { color: var(--tp-encre-4); }

/* Pas encore jouee : le trait pointille et le papier a nu. Une partie a
   venir n'est pas une donnee, c'est une place vide sur le tableau. */
:where(#contenu:not(.poste-plan)) .rencontre.a-jouer {
  background: transparent;
  border: 1px dashed var(--tp-trait-fort);
  box-shadow: none;
}

/* Exempte : trois colonnes seulement, et le fond ambre qui dit l'exception
   — a cote de l'etiquette « Exempte », jamais a sa place. */
:where(#contenu:not(.poste-plan)) .rencontre.exempte {
  grid-template-columns: 44px 1fr auto;
  background: var(--tp-ambre-fond);
  border-color: color-mix(in oklab, var(--tp-or) 30%, var(--tp-trait));
}

@media (max-width: 640px) {
  :where(#contenu:not(.poste-plan)) .rencontre {
    grid-template-columns: 44px 1fr;
    grid-template-areas:
      "jeu   a"
      "score b";
    row-gap: .5rem;
  }

  :where(#contenu:not(.poste-plan)) .rencontre .jeu { grid-area: jeu; }
  :where(#contenu:not(.poste-plan)) .rencontre .score { grid-area: score; text-align: center; font-size: 19px; }
  :where(#contenu:not(.poste-plan)) .rencontre .equipe:first-of-type { grid-area: a; }
  :where(#contenu:not(.poste-plan)) .rencontre .equipe:last-of-type { grid-area: b; }

  /* L'exempte n'a pas de second nom : sa deuxieme ligne n'existe pas, et
     l'etiquette prend la place du score. */
  :where(#contenu:not(.poste-plan)) .rencontre.exempte {
    grid-template-columns: 44px 1fr auto;
    grid-template-areas: none;
  }
}

/* ────────────────────────────────────────────── QUI VIENT ET LES EQUIPES ──
   Deux colonnes cote a cote, une seule au telephone (.grille-2 s'en charge
   deja). A gauche les presences, a droite les equipes inscrites. */

/* Le compte entre parentheses du surtitre « Equipes inscrites » : son style=
   lui enleve deja la casse et l'espacement ; il ne lui manquait qu'une
   teinte de service. */
:where(#contenu:not(.poste-plan)) .surtitre .muet { color: var(--tp-encre-4); }

/* Une equipe inscrite : le numero dans son jeton, la composition a cote, le
   forfait au bout. Le padding serre vient d'un style= de la vue. */
:where(#contenu:not(.poste-plan)) .pile-2 > .carte.rang {
  flex-wrap: nowrap;
  gap: .625rem;
  min-height: 52px;
}

:where(#contenu:not(.poste-plan)) .pile-2 > .carte.rang a {
  color: var(--tp-encre);
  text-decoration-color: color-mix(in oklab, var(--tp-encre) 30%, transparent);
  text-underline-offset: 2px;
}

/* Le champ de recherche d'un partenaire, et les propositions que app.js pose
   dessous sous forme de boutons : une rangee qui passe a la ligne plutot
   qu'une liste qui deborde. */
[data-recherche-joueur] [data-suggestions] {
  flex-wrap: wrap;
  margin-top: .375rem;
}

[data-recherche-joueur] [data-suggestions]:empty { margin-top: 0; }

/* ──────────────────────────────────────────────────── LE FOCUS CLAVIER ──
   Une seule regle pour tout ce que cette page rend atteignable au clavier :
   l'anneau or et son halo, comme dans le kit. */

.jr-radio:focus-visible,
.jr-fiche a:focus-visible,
.jr-nom a:focus-visible,
:where(#contenu:not(.poste-plan)) .nom-joueur:focus-visible,
:where(#contenu:not(.poste-plan)) [role="tab"]:focus-visible,
#sos summary:focus-visible,
#retour label.rang:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* ────────────────────────────────────────────── LE MOUVEMENT, EN MOINS ──
   Qui demande moins d'animation la coupe entierement. Le chevron du SOS
   arrete de tourner, les pilules de cesser de glisser : l'etat reste dit par
   le fond et par le texte, jamais par le seul mouvement. */

@media (prefers-reduced-motion: reduce) {
  :where(#contenu:not(.poste-plan)) .nom-joueur,
  :where(#contenu:not(.poste-plan)) [role="tab"],
  .jr-radio,
  #retour label.rang,
  #sos summary,
  #sos summary::after,
  #sos-message,
  #retour-commentaire,
  #livre-texte {
    transition: none;
  }
}

} /* fin de la couche */


/* ─────────────────────────────────────────────────────────────────
   LA FICHE JOUEUR ET L'ESPACE « MOI »
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — LA FICHE JOUEUR ET L'ESPACE « MOI ».

   Le modele : assets/css/tire.css. Memes mesures, memes jetons, meme ton.
   Ici on ne renomme RIEN : .fj-*, .sb-*, .stats, .carte, .tableau, .jeton sont
   vises par les vues, par eclat.js (qui pose data-reveler sur .carte et .defile,
   et fait compter les .chiffre) et par l'impression. On leur donne un DESSIN.

   CE QUE CETTE FEUILLE REMPLACE : assets/css/p-joueur.css, direction « email &
   acier » — Big Shoulders en capitales, boule d'acier a reflets, carton terre.
   Elle vit dans @layer pages ; nous sommes dans « tire », declaree en dernier :
   nous passons devant sans un seul !important.

   ─────────────────────────────────────────────────────────────────────────
   LES QUATRE MURS DE CETTE PAGE — releves dans les feuilles, pas supposes.

   1. sable.css se termine HORS COUCHE. Une declaration hors couche bat TOUTE
      declaration en couche, !important ou pas. Deux consequences definitives :
        · « html body :is(.banniere-bleue, .acc-etat) { overflow: clip } » nous
          est INTOUCHABLE. Un avatar qui deborde de la banniere serait coupe.
          D'ou le dessin ci-dessous : la bande photo est un ::before POSE DANS
          la banniere, et l'avatar chevauche son bord bas — il deborde de la
          BANDE, jamais de la banniere.
        · les couleurs de texte de la banniere sont verrouillees en !important
          (p et li → --encre-2 · h1, .chiffre, strong, b → --encre ·
          .surtitre → --or-800 · .pastille et .bouton → or plein). On ne les
          reprend pas : on leur donne le FOND qu'elles reclament. Le sol de
          l'en-tete suit donc le theme, comme --encre.
      .jeton, lui, n'est verrouille nulle part : l'avatar est a nous.

   2. --or-800 (#876104) est CONSTANT dans les deux themes. Sur le papier il
      fait 5,1:1, sur le bleu nuit 2,3:1 — illisible. La licence et le club
      passent donc sur une plaque d'or pale constante : c'est la seule facon
      de rendre cette ligne lisible la nuit sans un !important.

   3. polices.css ne sert Playfair QU'EN 700, et Inter en 400/600/700. Les
      font-weight 800 et 900 de l'ancienne feuille etaient synthetises par le
      navigateur — un faux gras, plus epais et plus sale que le vrai. Tout
      revient a 700 ici, et c'est un gain de dessin, pas un renoncement.

   4. Les vues portent 20 styles en ligne sur /profil et 8 sur la fiche. Un
      style en ligne bat toute declaration non-!important : ils sont listes a
      la fin du fichier, et le dessin FAIT AVEC plutot que contre.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ═══════════════════════════════════════════════════ LE CADRE DES DEUX PAGES ══
   Les deux pages n'ont pas de classe a elles : la fiche se reconnait a sa
   banniere, « Moi » au formulaire du poste, qui n'existe que la. :where() tient
   la portee a specificite ZERO — c'est la couche qui nous fait gagner, pas une
   surenchere de selecteurs, et nos propres classes gardent la main. */

:where(body:has(.fj-banniere), body:has(form[action="/profil/poste"])) .section-mince {
  padding-block: 1.75rem;
}

/* La gouttiere du telephone pose : sur un iPhone en paysage, l'encoche mange
   le bord gauche de la page. Le max() ne retire jamais de marge, il en ajoute
   quand l'appareil en demande. */
:where(body:has(.fj-banniere), body:has(form[action="/profil/poste"])) .enveloppe {
  padding-inline: max(var(--gouttiere, 1rem), env(safe-area-inset-left, 0px))
                  max(var(--gouttiere, 1rem), env(safe-area-inset-right, 0px));
}

/* ═══════════════════════════════════════════════════════ L'EN-TETE DE FICHE ══
   Une bande photo bornee a 220 px, l'avatar de 88 pose a cheval sur son bord
   bas, le nom en Playfair dessous. La bande est un ::before : la banniere est
   en overflow:clip hors couche (mur n° 1), rien ne peut en sortir. */

.banniere.fj-banniere,
:where(body:has(form[action="/profil/poste"])) .banniere.banniere-bleue {
  --fj-bande: clamp(132px, 32vw, 220px);
  --fj-avatar: 88px;

  position: relative;
  isolation: isolate;
  background-color: var(--tp-sol);
  background-image: var(--tp-papier);
  background-repeat: repeat;
  background-size: 512px;
  color: var(--tp-encre);
  /* La moitie haute de l'avatar mord dans la bande : le corps commence donc
     un demi-avatar avant la fin de celle-ci. Un seul calcul tient le dessin. */
  padding-block: calc(var(--fj-bande) - var(--fj-avatar) / 2) 1.75rem;
  margin-bottom: 0;
}

/* LA BANDE. L'ancienne regle posait ici la boule en filigrane : un cercle de
   46vw cale a droite, masque en radial, anime. On la DEFAIT propriete par
   propriete — inset, dimensions, masque, rayon, animation — sinon la boule
   reparait sous la photo, decalee, et personne ne comprend d'ou elle sort. */
.banniere.fj-banniere::before,
:where(body:has(form[action="/profil/poste"])) .banniere.banniere-bleue::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  right: auto;
  top: 0;
  width: 100%;
  height: var(--fj-bande);
  aspect-ratio: auto;
  z-index: -1;
  pointer-events: none;
  background-image: image-set(
    url("/assets/img/photos/boulodrome-soir-1074.avif") type("image/avif"),
    url("/assets/img/photos/boulodrome-soir-1074.webp") type("image/webp"),
    url("/assets/img/photos/boulodrome-soir-1074.jpg") type("image/jpeg"));
  background-size: cover;
  background-position: center 42%;
  background-repeat: no-repeat;
  border-radius: 0;
  opacity: 1;
  -webkit-mask-image: none;
  mask-image: none;
  animation: none;
}

/* LE VOILE. Une photo de terrain prise au telephone un dimanche est claire au
   centre et sombre aux angles : sans ce degrade, le bord bas de la bande passe
   du noir au creme sans transition et l'avatar semble colle sur un timbre.
   sable.css avait mis ce ::after a « content: none » : on le redonne. */
.banniere.fj-banniere::after,
:where(body:has(form[action="/profil/poste"])) .banniere.banniere-bleue::after {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--fj-bande);
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to bottom,
      rgb(16 24 56 / .28) 0%,
      rgb(16 24 56 / .34) 58%,
      rgb(16 24 56 / .62) 100%),
    radial-gradient(64% 86% at 88% 8%, rgb(245 180 28 / .26), transparent 64%);
}

/* Le corps : l'identite a gauche, le rang cale EN BAS a droite. Le fond de la
   ligne est le papier, pas la photo — c'est ce qui rend l'encre verrouillee de
   la banniere (mur n° 1) lisible dans les trois etats d'affichage. */
.fj-banniere .fj-banniere-corps {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
}

/* L'identite passe en COLONNE : l'avatar chevauche la bande, le nom se pose
   dessous, sur le papier. En ligne, le nom serait reste dans la photo. */
.fj-banniere .fj-identite {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .75rem;
  flex: 1 1 18rem;
  min-width: 0;
  /* Le corps est cale en bas pour que la plaque du rang s'assoie sur la ligne
     de base. L'identite, elle, doit rester accrochee au HAUT : c'est de son
     bord superieur qu'on a deduit le demi-avatar de chevauchement. Sans ce
     align-self, une plaque de rang plus haute que la colonne du nom repousse
     l'avatar vers le bas et le decolle de la bande — le dessin ne tient alors
     que tant que le rang tient sur deux lignes. */
  align-self: flex-start;
}

.fj-banniere .fj-identite-texte { min-width: 0; width: 100%; }

/* L'en-tete de « Moi » n'a pas de corps a lui : c'est l'enveloppe elle-meme,
   en .rang. Meme mecanique que la fiche — le contenu se cale en bas, donc SOUS
   la bande, et seul l'avatar remonte la chevaucher. Le « gap » de cette ligne
   est pose en style en ligne par la vue : il reste a 1 rem, et le dessin fait
   avec. */
:where(body:has(form[action="/profil/poste"])) .banniere-bleue > .enveloppe.rang {
  align-items: flex-end;
  row-gap: .75rem;
}

/* L'AVATAR — 88, liseré 4 px de la couleur du papier : c'est lui qui detache
   le disque de la photo, comme .tp-avatar--grand detache l'avatar du podium.
   align-self tient le chevauchement quoi qu'il arrive au reste de la ligne. */
.fj-banniere .jeton.jeton-l,
:where(body:has(form[action="/profil/poste"])) .banniere-bleue .jeton.jeton-l {
  width: var(--fj-avatar);
  height: var(--fj-avatar);
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  overflow: hidden;
  background: var(--tp-or);
  color: var(--tp-sur-or);
  border: 4px solid var(--tp-sol);
  box-shadow: var(--tp-ombre);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 28px;
  letter-spacing: 0;
  align-self: flex-start;
}

/* LE NOM. Playfair 700 en CASSE NORMALE — la vue envoie deja le nom en
   capitales, on ne lui en ajoute pas. Les tailles sont celles de .tp-titre-1. */
.fj-banniere .fj-identite h1,
:where(body:has(form[action="/profil/poste"])) .banniere-bleue h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-shadow: none;
  text-wrap: balance;
  overflow-wrap: anywhere;
  padding-top: 0;
  margin: 0;
}

/* LA LICENCE ET LE CLUB. Le mur n° 2 : cette ligne est verrouillee en bronze
   constant. Sur le bleu nuit de La Buvette, le bronze tombe a 2,3:1. On ne
   peut pas changer son encre — on lui donne sa PLAQUE : un or pale constant,
   sur lequel le bronze fait 4,9:1 dans les trois etats. Le filet d'or de
   .surtitre::before est retire : dans une plaque, il n'est plus qu'un bruit. */
.fj-banniere .surtitre,
:where(body:has(form[action="/profil/poste"])) .banniere-bleue .surtitre {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  max-width: 100%;
  padding: .25rem .625rem;
  border-radius: var(--tp-r-pilule);
  background: color-mix(in oklab, var(--tp-or) 26%, #FFFFFF);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.45;
  text-wrap: pretty;
  overflow-wrap: anywhere;
}

.fj-banniere .surtitre::before,
:where(body:has(form[action="/profil/poste"])) .banniere-bleue .surtitre::before {
  content: none;
}

.fj-banniere .fj-surtitre-nuit { margin-bottom: .5rem; }

/* Le geste de l'en-tete (« Mon compte », « Ma fiche publique »). L'or plein et
   l'encre sont verrouilles par sable : on ne reprend que la forme — la pilule
   de 44 px du kit, et rien d'autre. */
.fj-banniere .bouton,
:where(body:has(form[action="/profil/poste"])) .banniere-bleue .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 1.125rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  text-decoration: none;
}

.fj-banniere .fj-actions { margin: 0; }

/* ───────────────────────────────────────────────────────────────── LE RANG ──
   Il n'est plus le chiffre geant de l'ancienne fiche : la question « combien
   de points » se lit maintenant dans les tuiles, et un nombre de 5 rem en
   Playfair 700 sur du papier crie autant que l'ancienne condensee. Il devient
   une plaque doree posee au bas de l'en-tete — lue d'un coup, pas hurlee. */

.fj-banniere .fj-rang {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: .25rem;
  flex: 0 1 auto;
  min-width: 0;
  max-width: min(100%, 22rem);
  padding: .75rem 1rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  background: var(--tp-carte);
  box-shadow: var(--tp-ombre);
  text-align: left;
}

/* Le podium garde son repere non colore — un liseré d'or a gauche, comme la
   ligne « Vous » du classement (.tp-carte--or). La couleur ne porte jamais le
   sens toute seule. L'ancien filet etait a DROITE, puis a gauche sous 640 px :
   les deux sont defaits ici. */
.fj-banniere .fj-rang--podium {
  padding-right: 1rem;
  border-right: 1px solid var(--tp-trait);
  border-left: 1px solid var(--tp-trait);
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

/* Le chiffre. Son encre est verrouillee a --encre-2 par sable (c'est un <p>) :
   inutile d'ecrire une couleur ici, elle serait ignoree en silence. On tient
   ce qui nous reste — la famille, la graisse, la taille, les chiffres
   tabulaires — et c'est amplement de quoi le faire dominer sa plaque. */
.fj-banniere .fj-rang-chiffre {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(2rem, 1.4rem + 2.4vw, 2.75rem);
  line-height: 1.05;
  letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}

.fj-banniere .fj-rang-exposant {
  font-size: .42em;
  vertical-align: super;
  letter-spacing: 0;
  font-weight: 700;
}

/* Pas de rang : le tiret cadratin tient la place, en plus pale. Une case vide
   laisserait croire a un chargement qui n'arrive jamais. */
.fj-banniere .fj-rang-chiffre--absent { opacity: .55; }

.fj-banniere .fj-rang-quoi {
  margin: 0;
  max-width: 30ch;
  font-family: var(--tp-texte);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.4;
  text-wrap: pretty;
}

/* LA BOULE. Elle etait une recette d'acier a trois degrades — la seule chose
   qui avait le droit de briller. La nouvelle direction n'a qu'un accent, l'or,
   et rien n'y brille : la boule devient un disque plein, comme la pastille de
   rang du podium (.tp-rang--1). On defait donc le degrade ET son ombre. */
.fj-boule {
  display: inline-block;
  flex: none;
  width: var(--fj-boule, 30px);
  height: var(--fj-boule, 30px);
  border-radius: 50%;
  background: var(--tp-or);
  box-shadow: none;
}

.fj-boule--22 { --fj-boule: 22px; }
.fj-boule--30 { --fj-boule: 30px; }

/* Sous 560 px, le rang passe pleine largeur : a 390 px, une plaque calee a
   droite et un nom a gauche se partagent 358 px et se coupent tous les deux. */
@media (max-width: 560px) {
  .fj-banniere .fj-banniere-corps { align-items: stretch; }
  .fj-banniere .fj-rang { max-width: none; width: 100%; }
}

/* ══════════════════════════════════════════════════════ LES TUILES CHIFFREES ══
   .stats etait une grille d'un pixel de trait, cases collees, coins coupes.
   Elle devient la rangee de tuiles du kit (.tp-chiffres / .tp-tuile) : des
   cartes separees, chiffre Playfair 26, intitule Inter 700 11 capitales. */

.fj-chiffres {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
  gap: .75rem;
  background: transparent;
  border: 0;
  border-radius: 0;
  overflow: visible;
}

.fj-chiffres > div {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: .875rem .75rem;
  text-align: center;
}

.fj-chiffres .chiffre {
  display: block;
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 26px;
  line-height: 1.1;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

.fj-chiffres .etiquette {
  display: block;
  margin-top: .25rem;
  font-family: var(--tp-texte);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  text-wrap: balance;
}

/* Le denominateur d'une place — « 6/48 ». Il descend d'un cran : c'est le
   numerateur qu'on lit, le denominateur ne fait que le rendre honnete. */
.fj-sur {
  font-family: var(--tp-texte);
  font-size: .5em;
  font-weight: 700;
  color: var(--tp-encre-3);
}

/* La seule case doree de la rangee, et seulement quand une place est connue.
   --tp-or-lisible, jamais --tp-or : ce chiffre est une LETTRE sur du clair. */
.fj-chiffres .fj-chiffre-or { color: var(--tp-or-lisible); }

.fj-assiduite {
  display: flex;
  align-items: center;
  gap: .5rem .625rem;
  flex-wrap: wrap;
  margin: 1rem 0 0;
  color: var(--tp-encre-2);
  font-size: 14px;
  line-height: 1.5;
}

/* L'etiquette du kit : 24 px, Inter 700 11 capitales, le duo texte + fond. */
.fj-assiduite .pastille.fj-pastille-fidele {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: none;
}

/* ══════════════════════════════════════════════════════ LES TITRES DE SECTION ══
   Le surtitre du kit au-dessus, le titre Playfair en casse normale dessous.
   Hors banniere, le surtitre n'est plus verrouille : il reprend l'or lisible
   et se passe donc de plaque. */

:where(body:has(.fj-banniere)) .section-mince .surtitre {
  display: block;
  gap: 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-or-lisible);
  margin: 0 0 .5rem;
}

:where(body:has(.fj-banniere)) .section-mince .surtitre::before { content: none; }

.fj-titre {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.25rem, 1rem + 1.1vw, 1.875rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  text-wrap: balance;
  margin: 0 0 1rem;
}

.fj-note {
  margin: 0;
  max-width: 62ch;
  color: var(--tp-encre-3);
  font-size: 12.5px;
  line-height: 1.55;
  text-wrap: pretty;
}

.fj-note a { color: var(--tp-or-lisible); font-weight: 600; }

/* L'ecran vide dit ce qui manque, et il le dit sur une carte du kit. */
/* Le selecteur porte .section-mince pour rester PLUS SPECIFIQUE que la regle
   generique des cartes, plus bas. A specificite egale, c'est l'ordre des
   lignes qui trancherait — et l'ordre des lignes est precisement ce qui bouge
   tout seul le jour ou quelqu'un deplace un bloc. */
.section-mince .carte.fj-vide {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.25rem 1.375rem;
  color: var(--tp-encre-2);
  font-size: 14px;
  line-height: 1.55;
  max-width: 62ch;
}

/* ═══════════════════════════════════════════════════════ LE VERRE DE SAISON ══
   Le dessin de la regle du plafond. Il reste un CONTOUR : l'or est la matiere,
   la hachure est l'eau, le pointille est la barre des douze. Aucune couleur
   n'est ecrite dans la vue — tout passe par ces classes, donc par les jetons,
   donc par les trois etats d'affichage.

   ⚠️ La ou la vue pose deja fill="url(#…)" pour une trame, cette feuille NE
   DECLARE PAS `fill` : une declaration CSS l'emporterait sur l'attribut de
   presentation et effacerait le motif. */

.fj-verre-bloc {
  display: grid;
  gap: 1.5rem 2rem;
  grid-template-columns: minmax(0, 1fr);
  align-items: start;
}

@media (min-width: 46rem) {
  .fj-verre-bloc { grid-template-columns: auto minmax(0, 1fr); }
}

.fj-verre { margin: 0; flex: none; }

.fj-verre-trace {
  width: 100%;
  max-width: 210px;
  height: auto;
  /* Le SVG n'a pas de dimension intrinseque : sans ce rapport, height:auto
     l'ecrase a zero des que la grille lui laisse le choix. */
  aspect-ratio: 210 / 300;
}

.fj-verre-paroi {
  fill: none;
  stroke: var(--tp-trait-fort);
  stroke-width: 2;
}

/* L'arete haute : le liseré de lumiere qui donne son epaisseur au verre. Il
   doit rester plus clair que la carte dans les deux themes — l'or vif est le
   seul jeton constant qui tienne ce role des deux cotes. */
.fj-verre-arete {
  stroke: var(--tp-or-vif);
  stroke-width: 3;
  stroke-linecap: round;
}

/* LA DOSE D'OR, toujours cerclee : l'or plein est un fond, et un fond se
   borne. Le cerclage lui donne son bord dans les deux themes. */
.fj-or {
  fill: var(--tp-or);
  stroke: var(--tp-or-profond);
  stroke-width: 1.5;
}

/* L'EAU — les journees ecartees, ramenees a 1 point de presence. Son
   remplissage est la trame posee en attribut : pas de `fill` ici. */
.fj-eau { stroke: none; }

.fj-eau-bord {
  fill: none;
  stroke: var(--tp-encre-3);
  stroke-width: 1.5;
}

/* Le trait de la trame, partage par les trois motifs de la page. */
.fj-hachure {
  stroke: var(--tp-encre-3);
  stroke-width: 2.2;
}

/* Chaque trait est la limite d'une journee retenue : on les voit sans qu'ils
   decoupent l'or en tranches. */
.fj-dose {
  stroke: var(--tp-or-profond);
  stroke-width: 1;
  stroke-opacity: .45;
}

/* LA COUPURE — la barre des douze. Pointille ambre : c'est un SEUIL, pas une
   mesure, et la grammaire du repere de moyenne est la meme. */
.fj-coupure {
  stroke: var(--tp-ambre);
  stroke-width: 2;
  stroke-dasharray: 5 4;
}

.fj-coupure-mot {
  fill: var(--tp-ambre);
  font-family: var(--tp-texte);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
}

/* Le rail des graduations. Le verre est gradue AVANT d'avoir un contenu :
   celui qui depasse le plafond y voit la coupure, celui qui ne l'atteint pas
   y voit une graduation a atteindre. Un seul dessin, deux lectures. */
.fj-cran {
  stroke: var(--tp-trait-fort);
  stroke-width: 2;
  stroke-linecap: round;
}

.fj-cran--pleine {
  stroke: var(--tp-or-profond);
  stroke-width: 3;
}

.fj-verre-brut {
  fill: var(--tp-encre-3);
  font-family: var(--tp-texte);
  font-size: 12px;
  font-weight: 700;
}

.fj-verre-total {
  fill: var(--tp-encre);
  font-family: var(--tp-titre);
  font-size: 30px;
  font-weight: 700;
}

.fj-verre-legende {
  margin-top: .625rem;
  max-width: 210px;
  color: var(--tp-encre-3);
  font-size: 12.5px;
  line-height: 1.45;
}

/* — LA LECTURE — le graphe n'est jamais seul : il est toujours double d'une
     liste chiffree. Un dessin qu'on ne peut pas lire au point pres n'est
     qu'une ambiance. */

.fj-verre-lecture { min-width: 0; }

.fj-doses {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.fj-doses li {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  color: var(--tp-encre-2);
  font-size: 14px;
  line-height: 1.5;
}

.fj-doses strong { color: var(--tp-encre); font-weight: 700; }

/* Les puces de legende : carrees et cerclees, jamais des ronds pleins — une
   puce doit dire la MATIERE du trace qu'elle annonce. */
.fj-puce {
  flex: none;
  width: 12px;
  height: 12px;
  border-radius: 3px;
  transform: translateY(1px);
}

.fj-puce--or {
  background: var(--tp-or);
  border: 1.5px solid var(--tp-or-profond);
}

.fj-puce--eau {
  background: color-mix(in oklab, var(--tp-encre-3) 45%, transparent);
  border: 1.5px solid var(--tp-encre-3);
}

.fj-puce--total {
  background: var(--tp-encre-2);
  border: 1.5px solid var(--tp-encre-2);
}

.fj-puce--repere {
  background: transparent;
  border: 0;
  border-top: 3px dashed var(--tp-ambre);
  height: 0;
  border-radius: 0;
  transform: translateY(-3px);
}

.fj-verre-phrase {
  margin: 0 0 .75rem;
  max-width: 58ch;
  color: var(--tp-encre);
  font-size: 15px;
  line-height: 1.55;
  text-wrap: pretty;
}

/* ═════════════════════════════════════════════════════════ LA LIGNE DE VIE ══
   Des BARRES, jamais une courbe : une journee du circuit est un evenement
   isole, et entre deux dimanches le total ne bouge pas. */

.fj-trace-bloc { margin: 0; }

.fj-trace {
  width: 100%;
  height: auto;
  aspect-ratio: 660 / 200;
  overflow: visible;   /* le pic est chiffre AU-DESSUS de sa barre */
}

.fj-barre { fill: var(--tp-or); }

/* La journee ecartee : hachuree, pas grisee. Sa trame est posee en attribut —
   d'ou l'absence de `fill` ici. Le contour, lui, est a nous : il la borne. */
.fj-barre--eau {
  stroke: var(--tp-encre-3);
  stroke-width: 1;
}

.fj-sol {
  stroke: var(--tp-encre-3);
  stroke-width: 1.5;
}

.fj-grille {
  stroke: var(--tp-trait);
  stroke-width: 1;
}

.fj-mois {
  fill: var(--tp-encre-3);
  font-family: var(--tp-texte);
  font-size: 12px;
  font-weight: 600;
}

.fj-repere {
  stroke: var(--tp-ambre);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
}

.fj-repere-mot {
  fill: var(--tp-ambre);
  font-family: var(--tp-texte);
  font-size: 11px;
  font-weight: 700;
}

.fj-valeur {
  fill: var(--tp-encre);
  font-family: var(--tp-titre);
  font-size: 17px;
  font-weight: 700;
}

.fj-valeur--creux { fill: var(--tp-encre-3); }

.fj-trace-legende {
  display: flex;
  flex-wrap: wrap;
  gap: .4rem 1rem;
  margin-top: .75rem;
  color: var(--tp-encre-3);
  font-size: 12.5px;
}

.fj-trace-legende > span {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}

/* ══════════════════════════════════════════════════ LE DETAIL DES JOURNEES ══ */

.fj-deux {
  display: grid;
  gap: 2rem;
  grid-template-columns: minmax(0, 1fr);
}

@media (min-width: 62rem) {
  .fj-deux { grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr); }
}

.fj-deux > div { min-width: 0; }

/* LA BOITE DU TABLEAU. sable.css fait de .defile une carte a rembourrage :
   on la reprend au dessin de .tp-table-boite — le trait, le rayon 16, et le
   rembourrage a zero pour que le zebrage aille bien jusqu'au bord. */
:where(body:has(.fj-banniere)) .defile {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 0;
  overflow-x: auto;
}

:where(body:has(.fj-banniere)) .tableau {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

:where(body:has(.fj-banniere)) .tableau th {
  background: var(--tp-carte);
  padding: .75rem;
  text-align: left;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  border-bottom: 1px solid var(--tp-trait);
  white-space: nowrap;
}

:where(body:has(.fj-banniere)) .tableau th abbr {
  text-decoration: none;
  border-bottom: 1px dotted var(--tp-encre-4);
  cursor: help;
}

:where(body:has(.fj-banniere)) .tableau td {
  padding: .75rem;
  height: 52px;
  border-bottom: 1px solid var(--tp-trait);
  color: var(--tp-encre);
}

:where(body:has(.fj-banniere)) .tableau tbody tr:nth-child(even) > td {
  background: color-mix(in oklab, var(--tp-creux) 40%, transparent);
}

:where(body:has(.fj-banniere)) .tableau tbody tr:last-child > td { border-bottom: 0; }

:where(body:has(.fj-banniere)) .tableau tbody tr:hover > td {
  background: color-mix(in oklab, var(--tp-creux) 55%, transparent);
}

:where(body:has(.fj-banniere)) .tableau .nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

.fj-tableau { width: 100%; }

.fj-ligne > td { vertical-align: middle; }
.fj-ligne:first-child > td { padding-top: .75rem; }

.fj-lien-journee {
  display: inline-block;
  color: inherit;
  text-decoration: none;
  min-width: 0;
}

.fj-lien-journee .gras { font-weight: 700; }

.fj-lien-journee:hover { color: var(--tp-or-lisible); text-decoration: underline; }

/* LA LIGNE ECARTEE. Meme trame que l'eau du verre et que la barre hachuree :
   un seul motif dit « ecartee » d'un bout a l'autre de la fiche. La ligne
   reste PLEINEMENT lisible — elle est ecartee du calcul, pas de la lecture. */
.fj-ligne--ecartee > td {
  background-image: repeating-linear-gradient(45deg,
    transparent 0 5px,
    color-mix(in oklab, var(--tp-encre-3) 16%, transparent) 5px 7px);
}

:where(body:has(.fj-banniere)) .tableau tbody tr.fj-ligne--ecartee:hover > td {
  background-color: color-mix(in oklab, var(--tp-creux) 55%, transparent);
}

/* L'etiquette « ecartee » : le duo texte + fond du kit, en 24 px. */
.pastille.fj-ecartee {
  display: inline-flex;
  align-items: center;
  height: 24px;
  margin-left: .375rem;
  padding: 0 .5rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre-3);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 10.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
  vertical-align: middle;
  white-space: nowrap;
}

/* Le bafa : un signe et une teinte de sens, jamais la teinte seule — la vue
   ecrit deja « +3 » ou « −2 », le signe porte l'information. */
.fj-bafa-plus  { color: var(--tp-vert);  font-weight: 700; }
.fj-bafa-moins { color: var(--tp-rouge); font-weight: 700; }

:where(body:has(.fj-banniere)) .tableau .muet { color: var(--tp-encre-4); }
:where(body:has(.fj-banniere)) .tableau .jaune { color: var(--tp-or-lisible); font-weight: 700; }

/* ═══════════════════════════════════════════════════════════ LES PARTENAIRES ══
   La barre de frequence reste un background-image et non un noeud de plus :
   la couleur de survol passe dessous, et une fiche a trente partenaires ne
   gagne pas trente <span>. La part arrive en style en ligne (« --part: 62% »)
   et reste declaree a zero ici : une carte servie sans elle montre une barre
   vide, jamais une barre pleine ni une declaration invalide. */

.fj-partenaires {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

/* .fj-partenaires en tete : la regle generique des cartes, plus bas, a la meme
   specificite et repose un « background » COURT — qui remet background-image a
   none et effacerait la barre de frequence. Un cran de specificite ici, et la
   barre ne depend plus de l'ordre des blocs dans le fichier. */
.fj-partenaires .carte.fj-partenaire {
  --part: 0%;
  display: flex;
  align-items: center;
  gap: .625rem;
  min-height: 60px;          /* on ouvre une fiche avec le pouce, dehors */
  padding: .625rem .875rem;
  background-color: var(--tp-carte);
  background-image: linear-gradient(to right,
    color-mix(in oklab, var(--tp-or) 18%, transparent) var(--part), transparent 0);
  background-repeat: no-repeat;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

.fj-partenaires .carte.fj-partenaire:hover {
  border-color: var(--tp-trait-fort);
  box-shadow: var(--tp-ombre-haut);
}

.fj-partenaire-nom { min-width: 0; flex: 1 1 auto; }
.fj-partenaire-nom > span { display: block; }

.fj-partenaire-nom .gras {
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
}

.fj-partenaire-nom .minus {
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* Le compteur de journees gagnees ensemble : l'etiquette doree du kit. */
.fj-partenaire .pastille {
  flex: none;
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: none;
}

/* L'avatar de la ligne : 44, le format du kit (.tp-avatar). */
.fj-partenaire .jeton.fj-jeton-petit {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  border: 2px solid var(--tp-carte);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
}

/* ═════════════════════════════════════════════ LE PROFIL DE JEU, LES TENDANCES ══
   Deux sections servies par des .carte generiques. On leur donne la carte du
   kit, et aux six chiffres la tuile — sans jamais toucher a .carte hors de
   ces deux pages : le reste du site appartient a d'autres feuilles. */

:where(body:has(.fj-banniere)) .section-mince .carte,
:where(body:has(form[action="/profil/poste"])) .section-mince .carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1rem 1.125rem;
}

/* LA CARTE DE MEMBRE FLASHEE. Elle ne parait que lorsqu'un membre du comite
   vient de lire le QR d'une licence : c'est un GESTE en attente, pas une carte
   de plus. L'ancienne feuille en faisait un aplat d'or — sur lequel le
   surtitre bronze tombe a 2,6:1, et le bouton d'or se perd dans son propre
   fond. Le kit dit l'attente autrement : le lisere d'or de .tp-carte--or.
   L'or redevient ce qu'il doit etre, un trait ou un fond, jamais une petite
   lettre sur du clair. */
:where(body:has(.fj-banniere)) .section-mince .carte.carte-jaune {
  background: var(--tp-carte);
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
  color: var(--tp-encre);
}

:where(body:has(.fj-banniere)) .grille .carte .chiffre {
  display: block;
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  line-height: 1.1;
  color: var(--tp-encre);
  font-variant-numeric: tabular-nums;
}

:where(body:has(.fj-banniere)) .grille .carte .chiffre-l { font-size: 26px; }

:where(body:has(.fj-banniere)) .grille .carte .chiffre .muet {
  color: var(--tp-encre-3);
  font-family: var(--tp-texte);
  font-weight: 600;
}

:where(body:has(.fj-banniere)) .grille .carte .minus {
  display: block;
  margin: .25rem 0 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--tp-encre-3);
  text-wrap: pretty;
}

/* Les lignes « Tour 3 — 62 % » : une ligne de liste du kit, en plus serre.
   Le rembourrage vertical leur donne les 44 px de cible tactile du lien. */
:where(body:has(.fj-banniere)) .carte .rang.entre {
  min-height: 44px;
  gap: .75rem;
  padding-block: .375rem;
  border-top: 1px solid var(--tp-trait);
  font-size: 14px;
  color: var(--tp-encre-2);
}

:where(body:has(.fj-banniere)) .carte .surtitre + .rang.entre { border-top: 0; }

:where(body:has(.fj-banniere)) .carte .rang.entre strong {
  color: var(--tp-encre);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

:where(body:has(.fj-banniere)) .carte .rang.entre a {
  color: var(--tp-encre);
  font-weight: 600;
  text-decoration: none;
}

:where(body:has(.fj-banniere)) .carte .rang.entre a:hover {
  color: var(--tp-or-lisible);
  text-decoration: underline;
}

/* ═══════════════════════════════════════════════════════════════ LE SOUS-BOCK ══
   La carte qu'on montre a un copain, et la SEULE chose qui sort de
   l'imprimante. Elle ne bascule PAS de theme : un sous-bock est en carton dans
   les deux lieux — c'est une matiere, comme la feuille blanche du portail
   (tire.css, § LE PORTAIL), pas une encre. D'ou une creme construite a partir
   de l'or, constant dans les trois etats, et une encre bleu nuit qui tient
   dessus des deux cotes. */

.fj-carte-cadre {
  display: flex;
  justify-content: center;
  padding-block: 1rem;
}

.fj-sous-bock {
  --fj-bock: 88mm;                  /* le cote du carton : un vrai sous-bock */
  --fj-carton: color-mix(in oklab, var(--tp-or) 9%, #FFFFFF);
  --fj-carton-trait: color-mix(in oklab, var(--tp-or-profond) 35%, #FFFFFF);
  --fj-carton-encre: #101838;
  --fj-carton-encre-2: color-mix(in oklab, #101838 62%, #FFFFFF);

  position: relative;
  isolation: isolate;
  /* Le nom se cale sur la LARGEUR DU CARTON, pas sur celle de la fenetre : la
     carte doit tenir aussi bien dans la page que dans un cadre imprime de
     88 mm. D'ou la requete de conteneur, et les cqi du nom. */
  container-type: inline-size;
  width: min(100%, var(--fj-bock));
  aspect-ratio: 1;
  display: flex;
  flex-direction: column;
  padding: 1rem 1rem .75rem;
  border-radius: var(--tp-r-carte);
  background-color: var(--fj-carton);
  background-image: var(--tp-papier);
  background-repeat: repeat;
  background-size: 512px;
  color: var(--fj-carton-encre);
  box-shadow: var(--tp-ombre-haut);
  overflow: hidden;
}

/* L'ancienne feuille posait ici un grain en « multiply » par-dessus le carton.
   Le papier du kit fait deja ce travail, en tuile de 512 : on retire le
   calque plutot que d'empiler deux textures qui se combattent. */
.fj-sous-bock::after { content: none; }

/* Le cran : l'anneau interieur en pointille du carton decoupe. */
.fj-sous-bock::before {
  content: "";
  position: absolute;
  inset: 6px;
  border: 1.5px dashed var(--fj-carton-trait);
  border-radius: calc(var(--tp-r-carte) - 4px);
  pointer-events: none;
}

.fj-sb-tete {
  display: flex;
  align-items: center;
  gap: .5rem;
}

.fj-sb-marque {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.05rem;
  line-height: 1.05;
  letter-spacing: 0;
  color: var(--fj-carton-encre);
}

.fj-sb-marque small {
  display: block;
  font-family: var(--tp-texte);
  font-size: .46rem;
  font-weight: 700;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fj-carton-encre-2);
}

/* LA BANDE. Elle porte aussi la classe .bande, que tire.css dessine en filet
   d'or de 3 px pour tout le site. Le selecteur est ici volontairement plus
   specifique : a specificite egale, c'est l'ordre de chargement des deux
   fichiers qui trancherait — autant ne pas en dependre. */
.fj-sous-bock .fj-sb-bande {
  display: block;
  height: 4px;
  margin: .5rem 0 .625rem;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--tp-or-profond), var(--tp-or), var(--tp-or-vif));
}

.fj-sb-nom {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.3rem, 5.4cqi, 1.8rem);
  line-height: 1.05;
  letter-spacing: -.01em;
  color: var(--fj-carton-encre);
  overflow-wrap: anywhere;
}

.fj-sb-club {
  margin: .25rem 0 0;
  font-family: var(--tp-texte);
  font-size: .68rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--fj-carton-encre-2);
}

.fj-sb-chiffres {
  display: flex;
  gap: 1rem;
  margin-top: auto;
  padding-top: .75rem;
}

.fj-sb-nombre {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.5rem;
  line-height: 1.05;
  color: var(--fj-carton-encre);
  font-variant-numeric: tabular-nums;
}

.fj-sb-mot {
  margin: .125rem 0 0;
  font-family: var(--tp-texte);
  font-size: .54rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fj-carton-encre-2);
}

.fj-sb-trace {
  width: 100%;
  height: auto;
  aspect-ratio: 300 / 58;
  margin-top: .5rem;
}

.fj-sb-pied {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: .75rem;
  margin-top: .625rem;
}

.fj-sb-adresse {
  margin: 0;
  font-family: var(--tp-texte);
  font-size: .58rem;
  font-weight: 700;
  line-height: 1.3;
  color: var(--fj-carton-encre);
  overflow-wrap: anywhere;
}

.fj-sb-adresse span {
  display: block;
  font-weight: 600;
  color: var(--fj-carton-encre-2);
}

.fj-sb-tampon {
  flex: none;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1.5px solid var(--fj-carton-trait);
}

/* Quand la page dediee demande un QR, le tampon cesse d'etre un cachet rond :
   un carre blanc pose dans un cercle laisse quatre coins qui debordent. Le
   code lui-meme (.sb-qr, .sb-tampon-qr) appartient a p-impression.css, servie
   par /joueur/{id}/carte seule — on ne fait ici que lui rendre son cadre. */
.fj-sb-tampon.sb-tampon-qr { border-radius: 6px; }

/* Sur le carton, la trame et le sol ne peuvent pas dependre des jetons qui
   basculent : le carton, lui, ne bascule pas. L'or est constant, on s'en sert. */
.fj-sous-bock .fj-barre   { fill: var(--tp-or-profond); }
.fj-sous-bock .fj-hachure { stroke: var(--fj-carton-encre-2); }
.fj-sous-bock .fj-barre--eau { stroke: var(--fj-carton-encre-2); }
.fj-sous-bock .fj-sol     { stroke: var(--fj-carton-trait); }
.fj-sous-bock .fj-boule   { background: var(--tp-or-profond); }

/* ══════════════════════════════════════════════════════════════ MON ESPACE ══
   /profil. Les quatre liens, le panneau d'organisation et les formulaires
   deviennent des LIGNES DE MENU au dessin de .tp-ligne-menu : un libelle de
   15, un sous-titre de 12, une cible de 56 px. On ne renomme rien — .bouton,
   .carte, .champ gardent leurs noms, ils changent de dessin. */

/* Les quatre raccourcis (« Ma Legende », « Mon album »…). La rangee passe a la
   ligne plutot que de deborder, comme .tp-gestes. */
:where(body:has(form[action="/profil/poste"])) .section-mince .rang {
  gap: .625rem;
}

:where(body:has(.fj-banniere)) .section-mince .bouton,
:where(body:has(form[action="/profil/poste"])) .section-mince .bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 1.125rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

:where(body:has(.fj-banniere)) .section-mince .bouton:hover,
:where(body:has(form[action="/profil/poste"])) .section-mince .bouton:hover {
  background: var(--tp-or-vif);
}

/* Le bouton second : le fantome du kit. Un seul or par ecran — ici, celui qui
   enregistre. La declaration de fond est reprise en entier parce que sable
   pose un fond plein et une ombre sur .bouton-vide. */
:where(body:has(form[action="/profil/poste"])) .section-mince .bouton-vide {
  background: transparent;
  border: 1px solid var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}

:where(body:has(form[action="/profil/poste"])) .section-mince .bouton-vide:hover {
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border-color: var(--tp-trait-fort);
}

/* LE PANNEAU D'ORGANISATION. Ses deux libelles portent une couleur en ligne
   (or, puis un bleu pale) : ils exigent un fond sombre, dans les trois etats.
   C'est exactement .tp-carte--nuit, et la raison est la meme que pour le
   carton — cet objet est une matiere, pas une encre. On defait le degrade et
   le halo d'angle que sable et app lui donnaient. */
:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue {
  display: flex;
  align-items: center;
  gap: .75rem;
  min-height: 56px;
  padding: .875rem 1rem;
  background: #101838;
  background-image: none;
  border: 1px solid rgb(255 255 255 / .1);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  color: #FFFFFF;
  text-decoration: none;
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue::after { content: none; }

:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue:hover {
  border-color: color-mix(in oklab, var(--tp-or) 45%, transparent);
  box-shadow: var(--tp-ombre-haut);
}

/* Le chevron de la ligne de menu : il dit « ca s'ouvre », et il glisse d'un
   pixel au survol — le geste de .tp-chevron, sur l'icone que pose la vue. */
:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue svg {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--tp-or);
  transition: transform var(--tp-elan);
}

:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue:hover svg {
  transform: translateX(2px);
}

/* LES FORMULAIRES. Chaque <form class="carte"> devient une carte du kit ; ses
   titres passent en Playfair casse normale. La couleur des h3 arrive en style
   en ligne (var(--bleu)) : on ne la reprend pas, elle est lisible sur la carte
   dans les deux themes — on ne touche qu'a la famille et a la taille. */
:where(body:has(form[action="/profil/poste"])) .section-mince h3 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
}

:where(body:has(form[action="/profil/poste"])) .carte.pile { gap: 1rem; }

:where(body:has(form[action="/profil/poste"])) .champ { gap: .375rem; }

:where(body:has(form[action="/profil/poste"])) .champ > label {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--tp-encre-2);
}

/* Le champ du kit : rayon 12, fond carte, bord marque, et un focus qui se
   VOIT. sable dessine le champ a l'ombre interieure : on repose une vraie
   bordure, sinon les deux se superposent en un double filet. */
:where(body:has(form[action="/profil/poste"])) .champ input,
:where(body:has(form[action="/profil/poste"])) .champ select,
:where(body:has(form[action="/profil/poste"])) .champ textarea,
:where(body:has(form[action="/profil/poste"])) select {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-size: 15px;
  color: var(--tp-encre);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

:where(body:has(form[action="/profil/poste"])) select { width: auto; }

:where(body:has(form[action="/profil/poste"])) .champ input:focus,
:where(body:has(form[action="/profil/poste"])) .champ select:focus,
:where(body:has(form[action="/profil/poste"])) .champ textarea:focus,
:where(body:has(form[action="/profil/poste"])) select:focus {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* :user-invalid plutot que :invalid — on ne souligne pas en rouge un champ
   que la personne n'a pas encore touche. */
:where(body:has(form[action="/profil/poste"])) .champ input:user-invalid {
  border-color: var(--tp-rouge);
  box-shadow: 0 0 0 3px rgb(201 52 43 / .18);
}

:where(body:has(form[action="/profil/poste"])) .champ .aide {
  font-size: 12.5px;
  color: var(--tp-encre-3);
}

/* Les six familles de notification : une case a cocher est une cible, pas une
   decoration. 22 px de case, la ligne entiere cliquable par son <label>. */
:where(body:has(form[action="/profil/poste"])) .champ-inline {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  min-height: 44px;
  padding-block: .25rem;
}

:where(body:has(form[action="/profil/poste"])) .champ-inline input[type="checkbox"] {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  margin-top: .125rem;
  accent-color: var(--tp-or-profond);
  cursor: pointer;
}

:where(body:has(form[action="/profil/poste"])) .champ-inline label {
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 15px;
  line-height: 1.4;
  color: var(--tp-encre);
  cursor: pointer;
  text-transform: none;
  letter-spacing: 0;
}

:where(body:has(form[action="/profil/poste"])) .champ-inline label .muet {
  font-weight: 400;
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--tp-encre-3);
}

/* Le portrait et sa notice. */
:where(body:has(form[action="/profil/poste"])) .petit.muet {
  font-size: 13px;
  line-height: 1.55;
  color: var(--tp-encre-3);
  text-wrap: pretty;
}

:where(body:has(form[action="/profil/poste"])) .minus.muet {
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tp-encre-3);
}

/* L'absence declaree : le duo texte + fond de l'ambre, en 24 px. */
:where(body:has(form[action="/profil/poste"])) .pastille {
  display: inline-flex;
  align-items: center;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
  box-shadow: none;
}

:where(body:has(form[action="/profil/poste"])) .pastille.pastille-ambre {
  background: var(--tp-ambre-fond);
  color: var(--tp-ambre);
}

/* Les deux messages de retour, au dessin du kit. */
:where(body:has(form[action="/profil/poste"])) .message {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  padding: .875rem 1rem;
  border: 0;
  border-left: 0;
  border-radius: var(--tp-r-champ);
  background: var(--tp-creux);
  color: var(--tp-encre);
  font-size: 14px;
  box-shadow: none;
}

:where(body:has(form[action="/profil/poste"])) .message-succes {
  background: var(--tp-vert-fond);
  color: var(--tp-vert);
}

:where(body:has(form[action="/profil/poste"])) .message-erreur {
  background: var(--tp-rouge-fond);
  color: var(--tp-rouge);
}

/* ═══════════════════════════════════════════════════════════ LE FOCUS CLAVIER ══
   La regle unique du kit : l'anneau or et son halo. :focus-visible seulement —
   l'anneau apparait au clavier, pas sous la souris. */

.fj-banniere .bouton:focus-visible,
.fj-lien-journee:focus-visible,
.fj-partenaires .carte.fj-partenaire:focus-visible,
:where(body:has(.fj-banniere)) .section-mince .bouton:focus-visible,
:where(body:has(form[action="/profil/poste"])) .section-mince .bouton:focus-visible,
:where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* ══════════════════════════════════════════════════ LE MOUVEMENT, EN MOINS ══
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. eclat.js pose data-reveler sur les cartes,
   mais il se coupe lui-meme dans ce cas — on n'a donc qu'a tenir nos gestes. */

/* Les selecteurs sont ecrits ICI a la meme specificite qu'en plein ecran. Une
   coupure de mouvement moins specifique que la regle qu'elle coupe ne coupe
   rien du tout — et cela ne se voit sur aucune capture : il faut avoir regle
   son systeme sur « moins d'animation » pour s'en apercevoir. */
@media (prefers-reduced-motion: reduce) {
  .fj-partenaires .carte.fj-partenaire,
  :where(body:has(.fj-banniere)) .section-mince .bouton,
  :where(body:has(form[action="/profil/poste"])) .section-mince .bouton,
  :where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue,
  :where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue svg,
  :where(body:has(form[action="/profil/poste"])) .champ input,
  :where(body:has(form[action="/profil/poste"])) .champ select {
    transition: none;
  }

  .fj-partenaires .carte.fj-partenaire:hover,
  :where(body:has(form[action="/profil/poste"])) .section-mince .carte.carte-bleue:hover svg {
    transform: none;
  }
}

/* ════════════════════════════════════════════════════════════════ LE PAPIER ══
   « Imprimez cette page : seule la carte sort, au format sous-bock. »
   L'effacement de .fj-ecran et la mise a zero de .fj-papier sont tenus par
   p-joueur.css en !important, dans une couche ANTERIEURE : pour les
   declarations !important la cascade inverse l'ordre des couches, ces deux
   regles-la nous passent donc devant et c'est tres bien ainsi. On ne redit
   rien ici : on rend seulement le carton imprimable — encre noire sur blanc,
   et surtout pas une texture de papier a 512 px envoyee au toner. */

@media print {
  /* Le filet de securite, et rien de plus. Tant que p-joueur.css est chargee,
     ses deux regles !important gagnent et celles-ci ne servent a rien ; le
     jour ou elle sera retiree, la promesse « seule la carte sort » tiendra
     encore. Deux declarations pour ne pas imprimer une page web entiere a la
     place d'un sous-bock : c'est un prix honnete. */
  .fj-ecran { display: none; }
  .fj-papier { padding: 0; }

  .fj-carte-cadre {
    padding: 0;
    justify-content: flex-start;
  }

  .fj-sous-bock {
    width: var(--fj-bock);
    background-color: #FFFFFF;
    background-image: none;
    color: #000000;
    box-shadow: none;
    border: 1px solid #999999;
    break-inside: avoid;
  }

  .fj-sous-bock::before { border-color: #999999; }

  .fj-sb-marque,
  .fj-sb-nom,
  .fj-sb-nombre,
  .fj-sb-adresse { color: #000000; }

  .fj-sb-marque small,
  .fj-sb-club,
  .fj-sb-mot,
  .fj-sb-adresse span { color: #444444; }

  .fj-sb-tampon { border-color: #999999; }

  .fj-sous-bock .fj-sb-bande { background: #000000; }
  .fj-sous-bock .fj-boule { background: #000000; }
  .fj-sous-bock .fj-barre { fill: #000000; }
  .fj-sous-bock .fj-sol   { stroke: #666666; }
  .fj-sous-bock .fj-hachure { stroke: #666666; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   LES STYLES EN LIGNE QUE CETTE FEUILLE NE PEUT PAS REPRENDRE

   Un style en ligne bat toute declaration non-!important. Les voici, avec ce
   que le dessin en a fait — aucun n'est resté un probleme, mais aucun ne
   disparaitra sans une main dans la vue.

   profil.php
     · .enveloppe.rang « gap:var(--r4) »      → l'ecart de l'en-tete reste 1 rem.
     · .surtitre « color:#B9C0DE »            → deja neutralise par le
       !important de sable (--or-800) ; c'est la plaque d'or pale qui le rend
       lisible dans les trois etats.
     · .carte-bleue « color:var(--jaune) » et « color:#B9C0DE » → les deux
       exigent un fond sombre : d'ou le panneau d'organisation en bleu nuit.
     · h3 × 5 « color:var(--bleu) »           → lisible sur la carte dans les
       deux themes ; on n'a repris que la famille et la taille.
     · .bouton-vide « border-color/color:var(--rouge) » (supprimer mon compte)
       → garde son rouge : c'est le geste qui coute, il doit le dire.
     · img du portrait « width/height/border-radius/object-fit/border » → le
       portrait reste un disque de 64 ; sa bordure suit --trait-2, pas nos
       jetons. C'est la seule piece de ces deux pages qui ne soit pas au kit.
     · les « display:block », « margin:0 », « gap », « flex-wrap » restants
       sont de la mise en page, et le dessin fait avec.

   joueur.php
     · .fj-rang-quoi « margin-top:.4rem;line-height:1.5 » → conserve.
     · strong « color:var(--jaune) »          → deja neutralise par le
       !important de sable (--encre) dans la banniere.
     · .fj-partenaire « --part:62% »          → c'est une DONNEE, pas un style :
       elle nourrit la barre de frequence, et cette feuille la declare a 0 %
       en repli.
     · .chiffre > .muet « font-size:1rem »    → conserve, la tuile s'y accorde.
     · strong « color:var(--jaune-profond) » dans les finales → bronze sur
       carte, 5,1:1, conserve.
   ═══════════════════════════════════════════════════════════════════════════ */

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   LE FIL DU CIRCUIT ET LES ANNONCES
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — famille « LE FIL ET LES ANNONCES »

   .fil-banniere · .fil-colonne · .fil-retour · .fil-fleche-retour ·
   .fil-composer · .fil-composer-pied · .fil-fichiers · .fil-aide ·
   .fil-comite · .fil-bloques · .fil-attente · .fil-flux · .fil-pub ·
   .fil-tete · .fil-portrait · .fil-portrait-circuit · .fil-portrait-vide ·
   .fil-qui · .fil-nom · .fil-quand · .fil-vous · .fil-marques ·
   .fil-et-or · .fil-et-bleu · .fil-et-vert · .fil-texte · .fil-lien-journee ·
   .fil-photos · .fil-scene · .fil-reactions · .fil-reaction ·
   .fil-reaction-carreau · .fil-reaction-mienne · .fil-reaction-mot ·
   .fil-reaction-nb · .fil-carreau · .fil-carreau-jeu · .fil-carreau-boule ·
   .fil-pied · .fil-pied-outils · .fil-action · .fil-action-premiere ·
   .fil-action-danger · .fil-signalement · .fil-commentaires ·
   .fil-sous-titre · .fil-repondre · .fil-liste-commentaires ·
   .fil-commentaire · .fil-commentaire-reponse · .fil-com-tete ·
   .fil-com-nom · .fil-com-texte · .fil-com-outils · .fil-vide ·
   .fil-vide-cercle · .fil-vide-titre · .fil-plus · .fil-bout · .fil-nouveau
   Et les annonces : .annonce et ses onze types, dans .carte.

   Trois vues : fil.php (la page ET le fragment de « Voir la suite »),
   annonces.php, annonce.php. Le fragment ne repasse pas par la page : une
   publication chargee en cours de lecture doit donc se dessiner entierement
   avec les regles de la carte, sans rien attendre d'un parent.

   ON NE RENOMME RIEN. fil.js pose .fil-reaction-mienne, .fil-nouveau et
   [data-fil-retour], lit .fil-pub, [data-fil-flux], [data-fil-plus],
   [data-fil-reactions], [data-fil-repondre], [data-fil-formulaire],
   [data-parent] et [data-nb] : ces classes recoivent un DESSIN, pas un autre
   nom.

   ⚠️ TROIS PIEGES PROPRES A CETTE FAMILLE

   1. .pastille NE VEUT PAS DIRE LA MEME CHOSE ICI QU'AILLEURS. Le kit
      (tire.css) en fait un COMPTEUR : un disque rouge de 18 px, en
      inline-grid, pour le nombre de nouveautes de la barre d'onglets. Mes
      deux vues s'en servent pour tout autre chose — l'etiquette « Podium »,
      « Urgent », « Epinglee », « En attente du comite ». Le dessin du
      compteur est donc defait propriete par propriete (display, min-width,
      height, padding, fond, encre, corps, interligne) et remplace par celui
      de .tp-etiquette. Chaque regle est qualifiee par son contexte
      (.fil-marques .pastille, .annonce .pastille) : le compteur de la barre
      d'onglets n'est jamais touche.

   2. LES TYPES D'ANNONCE SONT DES CLASSES NUES. Une annonce porte
      « info », « urgent », « resultat », « convocation », « meteo » ou
      « buvette » ; une notification porte « annonce », « appel »,
      « invitation », « covoiturage » ou « urgence » — sans prefixe, ecrites
      telles quelles dans le class=. Elles ne sont JAMAIS ecrites seules ici :
      toujours composees avec .annonce, sinon cette feuille irait teinter
      n'importe quel element du site qui porterait le mot « info ».

   3. LE MOT DE LA FIN SE CACHE PAR DISPLAY. fil.css eteint .fil-bout tant
      qu'il reste du fil a charger. Ecrire un « display » sur .fil-bout ou
      sur .fil-plus depuis cette couche-ci rallumerait le mot de la fin au
      milieu du fil : les deux regles sont donc reprises ici telles quelles,
      et aucune autre ne touche a leur affichage.

   CE QUI EST EXPLICITEMENT DEFAIT, ET POURQUOI
   Une couche ne gagne QUE sur les proprietes qu'elle ECRIT :
     · fil.css (couche pages) — la carte de publication etait une carte au
       rayon 16 mais a l'ombre plate ; le portrait du circuit et la boule du
       carreau etaient peints avec la recette --acier de app.css ; les
       reactions avaient un cadre de 1,5 px et un fond transparent ; le
       commentaire vivait sur --sol ; le vide ouvrait a 3 rem. Sa requete de
       conteneur a 26 rem et son bloc d'impression comptent aussi : les deux
       sont repris ici, sinon la mosaique de photos et la feuille imprimee
       restent a l'ancienne feuille.
     · app.css (couche composants) — .annonce posait un liseré de 4 px en
       bordure gauche ; .pastille etait une gelule de .68 rem en capitales ;
       .surtitre portait un tiret d'or de 24 px en pseudo-element.
     · sable.css (couche sable) — la banniere ouvrait a 5 rem avec un h1 de
       7,4 rem et une boule en filigrane derriere le titre, et chaque enfant
       de son enveloppe montait en fondu decale. Le kit a tranche : aucune
       animation d'entree en cascade.

   CE QUI RESTE HORS D'ATTEINTE, ET ASSUME
     · La couleur du surtitre des trois bannieres est forcee par sable.css
       avec une declaration prioritaire. Pour ces declarations-la, la cascade
       INVERSE l'ordre des couches : « tire », declaree en dernier, y est la
       plus faible. L'or sombre qu'elle impose se lit sur le creme, on ne se
       bat donc pas — seuls le corps, l'espacement et le tiret sont repris.
     · La banniere de annonces.php et de annonce.php ne porte aucune classe
       de page, et le gabarit ne pose ni classe sur body ni identifiant de
       page : il n'existe aucun selecteur qui la vise sans viser en meme
       temps l'accueil et les journees. Elle est donc laissee au socle.

   Direction : papier creme, encre bleu nuit, UN SEUL accent or. Cartes
   blanches rayon 16, pilules, titres Playfair en casse normale, intitules
   Inter 700 onze pixels capitales espacees.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ──────────────────────────────────────────── LA BANNIERE ET LA COLONNE ──
   Le fil se lit, il ne s'annonce pas : la banniere doit rendre la place au
   premier message. Celle de sable ouvrait a cinq rem avec un titre de 7,4 —
   on entrait dans la page par un mur. */

.fil-banniere {
  position: relative;
  isolation: isolate;
  overflow: visible;
  background: transparent;
  color: var(--tp-encre);
  padding-block: clamp(1.5rem, 1rem + 2.4vw, 2.5rem) clamp(1rem, .75rem + 1.2vw, 1.5rem);
}

/* La boule en filigrane derriere le titre : elle appartient a la vitrine,
   pas a un flux qu'on parcourt au pouce. */
.fil-banniere::before,
.fil-banniere::after { content: none; }

/* Le fondu decale des enfants de la banniere. Une page qui se monte sous les
   yeux fait perdre plus de temps qu'elle n'en donne, et ici le titre precede
   un flux qui, lui, arrive deja par paquets. */
.fil-banniere > .enveloppe > * {
  animation: none;
  opacity: 1;
  transform: none;
}

.fil-banniere h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.75rem, 1.2rem + 2.2vw, 2.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  text-shadow: none;
  text-wrap: balance;
  margin: 0;
}

/* Le tiret d'or de app.css disparait : le kit dit le surtitre par la casse et
   l'espacement, jamais par un ornement. */
.fil-banniere .surtitre {
  display: block;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  margin: 0 0 .5rem;
}

.fil-banniere .surtitre::before { content: none; }

.fil-banniere .sous {
  max-width: 58ch;
  margin: .5rem 0 0;
  font-size: 15px;
  line-height: 1.55;
  color: var(--tp-encre-2);
}

.fil-colonne { position: relative; }

/* Le retour depuis une publication seule. Fleche retournee : le signe du
   socle ne pointe qu'a droite. */
.fil-retour { margin: 0 0 1.25rem; }

.fil-retour a {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  color: var(--tp-encre-2);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
}

.fil-retour a:hover { color: var(--tp-encre); text-decoration: underline; }

.fil-fleche-retour { transform: scaleX(-1); }

/* ─────────────────────────────────────────────────────────── LE COMPOSER ──
   La premiere carte de la page, et la seule qui demande quelque chose. La
   question est en Playfair : c'est le ton de la maison, pas un intitule de
   formulaire. */

.fil-composer {
  display: flex;
  flex-direction: column;
  gap: .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.125rem 1.25rem;
  margin: 0 0 1.5rem;
}

.fil-composer > label {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
}

/* Les deux zones de saisie du fil. Le socle ne peut pas les atteindre : elles
   n'ont pas de classe, et une regle sur « textarea » nu perdrait contre les
   selecteurs de fil.css. C'est donc ici que le champ du kit est pose. */
.fil-composer textarea,
.fil-repondre textarea {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 15px;
  line-height: 1.55;
  color: var(--tp-encre);
  resize: vertical;
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

.fil-composer textarea::placeholder,
.fil-repondre textarea::placeholder { color: var(--tp-encre-4); }

/* Un champ dont on ne sait pas qu'il a le curseur est un formulaire qu'on
   remplit deux fois : l'anneau or et son halo, comme partout. */
.fil-composer textarea:focus-visible,
.fil-composer textarea:focus,
.fil-repondre textarea:focus-visible,
.fil-repondre textarea:focus {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

.fil-composer-pied {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
}

/* Le champ de fichier natif reste dans le flux, transparent par-dessus son
   bouton : il demeure atteignable au clavier et annonce par les lecteurs
   d'ecran. C'est le bouton visible qui prend l'anneau. */
.fil-fichiers {
  position: relative;
  display: inline-flex;
}

.fil-fichiers input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.fil-fichiers:focus-within .bouton {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

.fil-aide {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--tp-encre-3);
}

/* ─────────────────────────────────────── LE CHEMIN DU COMITE ET LES SOURDS ──
   Rien de la moderation ne se joue dans le fil : une ligne, jamais un
   panneau. Le trait tirete dit « c'est un passage », pas une carte de plus. */

.fil-comite {
  display: flex;
  margin: 0 0 1.5rem;
  padding: .5rem .875rem;
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border: 1px dashed var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
}

.fil-comite a {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  color: var(--tp-or-lisible);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
}

.fil-comite a:hover { text-decoration: underline; }

/* La liste de ceux qu'on ne lit plus, repliee : on ne met pas sous les yeux,
   a chaque ouverture, la liste de ce qui s'est mal passe. */
.fil-bloques { margin: 0 0 1.5rem; }

.fil-bloques > summary {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-weight: 700;
  font-size: 14px;
  color: var(--tp-encre-2);
  cursor: pointer;
}

.fil-bloques > summary:hover { color: var(--tp-encre); }

.fil-bloques ul {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .5rem;
  margin: .5rem 0 0;
  padding: 0;
}

.fil-bloques li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .75rem;
  flex-wrap: wrap;
  min-height: 56px;
  padding: .5rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-champ);
  font-size: 14px;
}

.fil-bloques form,
.fil-pied form,
.fil-com-outils form { margin: 0; }

/* ───────────────────────────────────────────── LA CARTE DE PUBLICATION ──
   La brique du fil, au dessin de .tp-carte. Le conteneur nomme sert la
   mosaique de photos : le fil vit aussi bien dans une colonne etroite que
   sur un ecran large, la requete porte donc sur la CARTE et jamais sur la
   fenetre. */

.fil-flux {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.fil-pub {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1.125rem 1.25rem;
  container-type: inline-size;
}

/* La publication qu'on vient d'ouvrir par son ancre se signale par le liseré
   or du kit — un trait a gauche, pas un fond : l'or en aplat mangerait le
   texte. */
.fil-pub:target {
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

/* fil.js pose tabindex="-1" sur la premiere publication ajoutee et lui donne
   le focus : sans anneau, personne ne voit ou la lecture reprend. */
.fil-pub:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
}

/* ────────────────────────────────────────────────────────────── LA TETE ──
   Portrait, nom, heure, et les marques a droite. Elle passe a la ligne sous
   le pouce : la rangee des marques n'est ecrite par la vue que si elle a
   quelque chose a dire, on peut donc la laisser prendre sa place. */

.fil-tete {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
}

.fil-portrait {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: 0 0 44px;
  border-radius: 50%;
  border: 2px solid var(--tp-carte);
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  font-weight: 700;
  font-size: 15px;
  object-fit: cover;
  overflow: hidden;
}

/* LE CIRCUIT PARLE, ET C'EST LA BOULE D'ACIER QUI LE DIT.
   L'acier n'est pas une onzieme couleur : c'est une FINITION, et elle ne
   bascule pas avec le theme — une boule reste une boule au soleil comme a la
   buvette. Elle se construit donc sur --tp-argent, le metal du kit, eclaire
   par --tp-or : l'eclat speculaire dur en haut a gauche, le reflet du
   comptoir par le bas a droite, le corps froid. Le liseré interieur d'un
   pixel n'est pas un reflet de plus : sans lui, le bas de la sphere se
   confond avec la carte de nuit et la boule se lit en croissant.
   La meme recette sert au carreau : elle est ecrite en pourcentages, elle
   vaut donc a dix pixels comme a quarante-quatre. */
.fil-portrait-circuit,
.fil-carreau-boule {
  background:
    radial-gradient(circle at 34% 26%,
      #FFFFFF 0 4%,
      color-mix(in oklab, var(--tp-argent) 55%, #FFFFFF) 9%,
      transparent 30%),
    radial-gradient(circle at 68% 78%,
      color-mix(in oklab, var(--tp-or) 62%, transparent) 0 14%,
      transparent 46%),
    linear-gradient(158deg,
      color-mix(in oklab, var(--tp-argent) 80%, #FFFFFF) 0%,
      var(--tp-argent) 34%,
      color-mix(in oklab, var(--tp-argent) 52%, #1D1838) 70%,
      color-mix(in oklab, var(--tp-argent) 24%, #1D1838) 100%);
}

.fil-portrait-circuit {
  border-color: transparent;
  box-shadow: var(--tp-ombre), inset 0 0 0 1px rgb(255 255 255 / .14);
}

/* Pas de photo, ou un compte parti : les initiales, ou le signe du joueur. Le
   creux et son liseré disent « il n'y a pas de portrait ici » sans faire
   croire a une image qui n'a pas fini de charger. */
.fil-portrait-vide {
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  box-shadow: inset 0 0 0 1px var(--tp-trait-fort);
}

.fil-portrait-vide svg { color: var(--tp-encre-3); }

.fil-qui {
  flex: 1 1 auto;
  min-width: 0;
}

.fil-nom {
  margin: 0;
  font-weight: 700;
  font-size: 15px;
  line-height: 1.25;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
}

.fil-nom a {
  color: var(--tp-encre);
  text-decoration: none;
}

.fil-nom a:hover { text-decoration: underline; }

.fil-nom .muet { color: var(--tp-encre-3); }

.fil-quand {
  margin: .125rem 0 0;
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* « vous » — la marque discrete qui evite de relire son propre nom pour
   savoir que c'est de soi qu'on parle. L'or ne s'ECRIT jamais en petit sur du
   clair : le mot passe par --tp-or-lisible sur le fond ambre. */
.fil-vous {
  display: inline-flex;
  align-items: center;
  height: 18px;
  margin-left: .375rem;
  padding: 0 .4375rem;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  vertical-align: .1em;
}

.fil-marques {
  display: flex;
  align-items: center;
  gap: .375rem;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* ─────────────────────────────────────────────────────── LES ETIQUETTES ──
   Ici .pastille n'est pas le compteur du kit mais l'etiquette de
   .tp-etiquette : vingt-quatre pixels, Inter 700 onze capitales. Tout le
   dessin du compteur est defait — sans quoi « En attente du comite » et
   « Podium » se liraient en disques rouges de dix-huit pixels. */

.fil-marques .pastille,
.annonce .pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  min-width: 0;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  line-height: 1;
  letter-spacing: .06em;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Le ton par defaut de chaque contexte, avant les variantes. Dans le fil,
   l'etiquette du circuit est neutre tant qu'elle ne dit pas une couleur ;
   dans une annonce, la pastille nue est « Epinglee » ou « Nouveau », deux
   mots qui valent d'etre vus. */
.fil-marques .pastille {
  background: var(--tp-creux);
  color: var(--tp-encre-2);
}

.annonce .pastille {
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
}

/* Le duo texte + fond de chaque teinte de sens : jamais la couleur seule, et
   l'etat tient encore a onze pixels.
   L'etiquette bleue du circuit est l'encre en aplat et la carte en encre —
   c'est la marine de .tp-etiquette--marine, dite avec les jetons du kit,
   donc juste dans les trois etats d'affichage. */
.fil-marques .fil-et-or,
.pastille.fil-et-or       { background: var(--tp-ambre-fond); color: var(--tp-or-lisible); }
.fil-marques .fil-et-bleu,
.pastille.fil-et-bleu     { background: var(--tp-encre);      color: var(--tp-carte); }
.fil-marques .fil-et-vert,
.pastille.fil-et-vert     { background: var(--tp-vert-fond);  color: var(--tp-vert); }

/* Retenue par le filtre : ambre, jamais rouge. Son auteur n'a rien casse, il
   attend une relecture. */
.fil-marques .pastille-ambre { background: var(--tp-ambre-fond); color: var(--tp-ambre); }

/* ───────────────────────────────────────────────────── LE MOT EN ATTENTE ──
   La phrase qui dit « vous etes seul a voir ceci ». Meme duo que l'etiquette,
   au dessin de .tp-message. */

.fil-attente {
  display: flex;
  align-items: flex-start;
  gap: .625rem;
  margin: .875rem 0 0;
  padding: .875rem 1rem;
  border-radius: var(--tp-r-champ);
  background: var(--tp-ambre-fond);
  color: var(--tp-ambre);
  font-size: 14px;
  line-height: 1.5;
}

.fil-attente svg {
  flex: 0 0 auto;
  margin-top: .0625rem;
}

/* ──────────────────────────────────────────── LE TEXTE ET LA JOURNEE ──
   Le corps du message. « anywhere » parce qu'un lien colle sans espace
   deborderait la carte sur un telephone de 390. */

.fil-texte {
  margin: .875rem 0 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
  text-wrap: pretty;
}

.fil-lien-journee { margin: .625rem 0 0; }

.fil-lien-journee a {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  color: var(--tp-or-lisible);
  font-weight: 700;
  font-size: 14px;
  text-decoration: none;
}

.fil-lien-journee a:hover { text-decoration: underline; }

/* ────────────────────────────────────────────────────────── LES PHOTOS ──
   LA SCENE : aucune photo brute. Le corpus du circuit est, et restera, des
   photos de telephone prises un dimanche — mal cadrees, a contre-jour, avec
   une poubelle dans le fond. Le halo dore les rattache a la marque, le
   vignettage referme le cadre sur le sujet.

   Les deux voiles sont ecrits en bleu nuit fixe, et non avec un jeton
   d'encre : une photo n'est pas une surface du site, elle ne bascule pas
   avec le theme — c'est exactement le parti de .tp-heros. Un vignettage qui
   passerait au blanc la nuit delaverait le sujet au lieu de le cerner.

   C'est un <figure> : la marge de 40 px de l'agent utilisateur est annulee,
   sinon la mosaique se disloque. */

.fil-photos {
  display: grid;
  grid-template-columns: 1fr;
  gap: .5rem;
  margin-top: .875rem;
}

.fil-scene {
  position: relative;
  isolation: isolate;
  margin: 0;
  overflow: hidden;
  border-radius: var(--tp-r-champ);
  background: var(--tp-creux);
}

.fil-scene::before,
.fil-scene::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.fil-scene::before {
  background:
    radial-gradient(circle at 78% 8%,
      color-mix(in oklab, var(--tp-or) 18%, transparent) 0%, transparent 62%),
    radial-gradient(ellipse 100% 98% at 50% 45%,
      transparent 38%, rgb(16 24 56 / .34) 100%);
}

/* Le depot bas : la photo se pose sur la carte au lieu d'y etre collee. Il
   s'arrete tres bas — sur une photo de fil, qui ne porte aucun texte, un
   voile plus haut effacerait le tiers du sujet, c'est-a-dire les joueurs. */
.fil-scene::after {
  background: linear-gradient(180deg, transparent 62%, rgb(16 24 56 / .24) 100%);
}

.fil-photos img {
  display: block;
  width: 100%;
  height: auto;
}

/* Une photo seule garde son cadrage et se borne en hauteur : un portrait pris
   au telephone occuperait sinon deux ecrans a lui tout seul. Les largeur et
   hauteur portees par la balise reservent la place avant le chargement, donc
   rien ne saute sous le doigt. */
.fil-photos[data-nb="1"] img {
  max-height: 70svh;
  object-fit: contain;
  object-position: center;
}

/* A plusieurs, elles forment une mosaique reguliere : la coupe carree vaut
   mieux que des hauteurs qui ne tombent jamais juste. */
.fil-photos:not([data-nb="1"]) img {
  aspect-ratio: 1 / 1;
  object-fit: cover;
}

@container (min-width: 26rem) {
  .fil-photos:not([data-nb="1"]) { grid-template-columns: 1fr 1fr; }
  .fil-photos[data-nb="3"] .fil-scene:first-child { grid-column: 1 / -1; }
  .fil-photos[data-nb="3"] .fil-scene:first-child img { aspect-ratio: 16 / 9; }
}

/* ─────────────────────────────────────────────────────── LES REACTIONS ──
   Des pilules, comme les filtres du site : creuses au repos, or quand elles
   sont tenues. L'or designe LE geste, pas les gestes — une seule pilule est
   doree a la fois puisqu'une seule reaction est la votre. */

.fil-reactions {
  display: flex;
  flex-wrap: wrap;
  gap: .375rem;
  margin-top: .875rem;
  padding-top: .875rem;
  border-top: 1px solid var(--tp-trait);
}

.fil-reaction {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  padding: 0 .875rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  background: var(--tp-carte);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: background var(--tp-elan), color var(--tp-elan), border-color var(--tp-elan);
}

.fil-reaction:hover { border-color: var(--tp-trait-fort); }

.fil-reaction[disabled] {
  opacity: .5;
  cursor: default;
}

.fil-reaction-mot { white-space: nowrap; }

/* La sienne : la pilule d'or pleine et l'encre dessus. L'etat ne repose pas
   sur la seule couleur — aria-pressed le dit aussi, et fil.js le maintient. */
.fil-reaction-mienne {
  background: var(--tp-or);
  border-color: var(--tp-or);
  color: var(--tp-sur-or);
  font-weight: 700;
}

.fil-reaction-mienne:hover { background: var(--tp-or-vif); border-color: var(--tp-or-vif); }

.fil-reaction-nb {
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  opacity: .85;
}

/* Un compteur a zero ne s'ecrit pas : la vue laisse le vide, on retire la
   boite pour que l'ecart de la pilule reste juste. */
.fil-reaction-nb:empty { display: none; }

/* ════════════════════════════════════════════════ LE CARREAU QUI CLAQUE ══
   Le carreau porte le nom de l'exploit absolu du jeu : la boule qui prend la
   place de l'autre, net, sans la pousser. C'est la reaction vedette du fil,
   et le seul endroit du site ou le ressort a le droit d'exister.

   POURQUOI UNE TRANSITION ET NON UNE ANIMATION : une @keyframes se rejoue a
   chaque affichage de la page. Un joueur qui a mis un carreau il y a huit
   jours reverrait donc le geste a chaque ouverture du fil — une consecration
   qui se rejoue n'en est plus une, et elle ment sur la fraicheur de
   l'information. Une transition ne se declenche jamais au rendu initial :
   elle attend un changement.

   D'ou l'etat de repos, qui est aussi une donnee : la boule est POSEE dans le
   cercle quand la reaction est la votre, et elle attend au depart du trait
   quand elle ne l'est pas. Au clic, fil.js bascule la classe et la boule
   part ; le ressort la fait deborder d'un cheveu a l'impact, puis se reposer.

   Les coordonnees ne se devinent pas : le signe fait 22 px pour une grille de
   24, soit 0,9167. Le centre du cercle vise (16,4 ; 15,4) tombe a
   (15,03 ; 14,12) px, et le depart du pointille (5,2 ; 7,2) a (4,77 ; 6,60).
   La duree et la courbe sont ecrites ici plutot qu'empruntees a fil.css :
   cette feuille doit tenir seule le jour ou l'autre disparaitra. */

.fil-reaction-carreau {
  padding-left: .625rem;
  border-color: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
}

.fil-carreau {
  position: relative;
  flex: none;
  width: 22px;
  height: 22px;
}

.fil-carreau-jeu {
  display: block;
  color: var(--tp-encre-3);
  transition: color var(--tp-elan);
}

.fil-carreau-boule {
  position: absolute;
  left: 10px;
  top: 9.1px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  box-shadow: 0 1px 2px rgb(29 24 56 / .34);
  transform: translate(0, 0) scale(1);
  transition: transform 220ms cubic-bezier(.34, 1.56, .64, 1);
}

/* Au repos, la boule attend au depart du trait, un peu plus petite : elle
   n'est pas encore arrivee. */
.fil-reaction-carreau:not(.fil-reaction-mienne) .fil-carreau-boule {
  transform: translate(-10.27px, -7.52px) scale(.82);
}

/* Le carreau est fait : le trace se dore, et la pilule est deja d'or. */
.fil-reaction-carreau.fil-reaction-mienne .fil-carreau-jeu { color: var(--tp-sur-or); }

/* ──────────────────────────────────────────────────────────── LE PIED ──
   Commenter est l'action ; bloquer, retirer et signaler sont des recours.
   Les seconds partent a droite, et l'ecart entre les deux groupes dit la
   difference de nature mieux qu'une couleur ne le ferait. */

.fil-pied {
  display: flex;
  align-items: center;
  gap: .5rem 1rem;
  flex-wrap: wrap;
  margin-top: .5rem;
}

.fil-pied-outils {
  display: flex;
  align-items: center;
  gap: .5rem 1rem;
  flex-wrap: wrap;
  margin-left: auto;
}

.fil-action {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  min-height: 44px;
  padding: .25rem 0;
  background: none;
  border: 0;
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 14px;
  color: var(--tp-encre-3);
  text-decoration: none;
  cursor: pointer;
  transition: color var(--tp-elan);
}

.fil-action:hover { color: var(--tp-encre); text-decoration: underline; }

/* Le seul or de la carte : commenter, c'est ce qu'on attend du lecteur. */
.fil-action-premiere {
  font-weight: 700;
  color: var(--tp-or-lisible);
}

.fil-action-premiere:hover { color: var(--tp-or-lisible); }

.fil-action-danger { color: var(--tp-rouge); }
.fil-action-danger:hover { color: var(--tp-rouge); }

.fil-signalement > summary {
  list-style: none;
  color: var(--tp-encre-3);
}

.fil-signalement > summary::-webkit-details-marker { display: none; }

.fil-signalement form {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  margin-top: .5rem;
}

/* Le motif du signalement : meme champ que le reste du kit. Comme les zones
   de saisie, il n'a pas de classe et reste hors de portee du socle. */
.fil-signalement select {
  min-height: 44px;
  padding: .5rem .75rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 14px;
  color: var(--tp-encre);
}

.fil-signalement select:focus-visible {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* Le retour d'erreur pose par fil.js. Sa couleur et sa marge sont ecrites en
   ligne par le script : elles ne peuvent pas etre reprises d'ici, et on ne
   leur oppose donc aucun fond teinte qui rendrait le rouge d'origine
   illisible. Seuls le corps et le liseré sont repris. */
[data-fil-retour] {
  padding-left: .625rem;
  border-left: 3px solid var(--tp-rouge);
  font-size: 13px;
  font-weight: 600;
}

/* ─────────────────────────────────────────────────────── LES COMMENTAIRES ── */

.fil-commentaires {
  margin-top: 1.25rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--tp-trait);
}

.fil-sous-titre {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.125rem, 1rem + .6vw, 1.5rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  margin: 0 0 .875rem;
}

.fil-repondre {
  display: flex;
  align-items: flex-end;
  gap: .5rem;
  flex-wrap: wrap;
  margin-bottom: 1.25rem;
}

.fil-repondre textarea {
  flex: 1 1 16rem;
  width: auto;
}

.fil-liste-commentaires {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin: 0;
  padding: 0;
}

.fil-commentaire {
  padding: .75rem .875rem;
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
  border-radius: var(--tp-r-champ);
}

/* Une seule profondeur de reponse : le retrait dit le lien, et il s'arrete
   la. Le retrait se resserre sur telephone — a 390 px, une reponse decalee
   d'une fois et demie le corps ne laisse plus de place au texte. */
.fil-commentaire-reponse {
  margin-left: clamp(.75rem, 4vw, 1.5rem);
  border-left: 3px solid var(--tp-trait-fort);
}

.fil-com-tete {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  flex-wrap: wrap;
  margin: 0 0 .25rem;
}

.fil-com-nom {
  font-weight: 700;
  font-size: 14px;
  color: var(--tp-encre);
  text-decoration: none;
}

.fil-com-nom:hover { text-decoration: underline; }

.fil-com-texte {
  margin: 0;
  font-size: 14px;
  line-height: 1.55;
  color: var(--tp-encre);
  overflow-wrap: anywhere;
}

.fil-com-outils {
  display: flex;
  align-items: center;
  gap: .5rem 1rem;
  flex-wrap: wrap;
  margin: .25rem 0 0;
}

/* ──────────────────────────────────────────────────────────── LE VIDE ──
   Un ecran vide dit ce qui manque ET donne le geste pour le remplir. Le signe
   est LE CERCLE TRACE au pied dans le gravier, sans boule dedans : « rien a
   lire ici pour l'instant » devient une image avant d'etre une phrase. L'arc
   fait 300° et s'ouvre en bas, un peu de travers — un cercle parfait serait
   un chargeur, pas un trace. Le masque conique decoupe l'ouverture ; sur un
   navigateur qui l'ignore il reste un cercle complet, personne n'y perd. */

.fil-vide {
  display: grid;
  justify-items: center;
  gap: .75rem;
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--tp-encre-3);
}

.fil-vide-cercle {
  width: 92px;
  height: 92px;
  border: 3px solid var(--tp-trait-fort);
  border-radius: 50%;
  transform: rotate(-8deg);
  -webkit-mask-image: conic-gradient(from 210deg, #000 0 300deg, transparent 300deg);
          mask-image: conic-gradient(from 210deg, #000 0 300deg, transparent 300deg);
}

.fil-vide p {
  margin: 0;
  max-width: 44ch;
  font-size: 14px;
}

.fil-vide-titre {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1.15;
  letter-spacing: -.01em;
  color: var(--tp-encre);
}

/* ─────────────────────────────────────── LA SUITE ET LE MOT DE LA FIN ──
   Le libellé de « Voir la suite » est repris tel quel par fil.js pendant le
   chargement, puis repose : il reste du TEXTE, et le bouton garde sa hauteur
   quand le mot « Chargement… » y passe. */

.fil-plus { margin-top: 1.5rem; }

.fil-bout {
  margin: 2rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--tp-trait);
  text-align: center;
  font-size: 13px;
  line-height: 1.5;
  color: var(--tp-encre-3);
}

.fil-bout a {
  font-weight: 700;
  color: var(--tp-or-lisible);
  text-decoration: none;
}

.fil-bout a:hover { text-decoration: underline; }

/* Les deux seules regles de cette feuille qui touchent a l'affichage de ces
   deux blocs, reprises de fil.css pour qu'elles vivent dans la meme couche
   que le reste : le mot de la fin est faux tant qu'il reste du fil, et
   fil.js retire le lien mais laisse son paragraphe en place. */
.fil-colonne:has([data-fil-plus]) .fil-bout { display: none; }
.fil-plus:not(:has(a)) { display: none; }

/* Le lot ajoute par « Voir la suite » arrive en fondu court, pour qu'on voie
   ou l'on est reste. Il n'anime QUE le lot ajoute, jamais la page. */
.fil-nouveau { animation: fil-arrivee 260ms cubic-bezier(.2, .7, .3, 1) both; }

@keyframes fil-arrivee {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* ═══════════════════════════════════════════════════════════ LES ANNONCES ══
   Une annonce est une carte du kit plus un liseré de type. Le liseré est un
   pseudo-element et non une bordure : la carte est cliquable, son ombre
   change au survol, et un liseré porte par l'ombre disparaitrait au passage
   du doigt. La bordure de 4 px de app.css est ramenee au trait du kit. */

.carte.annonce {
  position: relative;
  overflow: hidden;
  border-left: 1px solid var(--tp-trait);
}

.carte.annonce::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 3px;
  background: var(--tp-encre);
  pointer-events: none;
}

/* Les six types d'annonce et les cinq categories de notification portent des
   classes NUES : elles ne sont jamais ecrites seules, toujours composees avec
   .annonce. « info » et « annonce » gardent le liseré d'encre par defaut. */
.carte.annonce.urgent::before,
.carte.annonce.urgence::before     { background: var(--tp-rouge); }
.carte.annonce.resultat::before,
.carte.annonce.invitation::before  { background: var(--tp-vert); }
.carte.annonce.convocation::before,
.carte.annonce.appel::before       { background: var(--tp-or); }
.carte.annonce.meteo::before,
.carte.annonce.covoiturage::before { background: var(--tp-ambre); }
.carte.annonce.buvette::before     { background: var(--tp-bronze); }

/* La rangee de tete : les etiquettes a gauche, la date a droite. Les dates
   s'alignent d'une carte a l'autre, elles passent donc en chiffres
   tabulaires — sans quoi la colonne danse. */
.annonce .rang {
  gap: .5rem .75rem;
  min-width: 0;
}

.annonce .minus {
  color: var(--tp-encre-3);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Le titre de l'annonce sur sa page de liste : Playfair, en casse normale. Le
   .titre des versions compactes (accueil, notifications) reste en Inter — a
   cette taille et dans une demi-colonne, l'empattement se perd. */
.annonce h3 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.125rem;
  line-height: 1.25;
  letter-spacing: -.01em;
  color: var(--tp-encre);
  text-wrap: balance;
  margin: .5rem 0 0;
}

.annonce .titre {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  color: var(--tp-encre);
  margin: .5rem 0 0;
}

.annonce .muet { color: var(--tp-encre-3); }

/* Les trois tons d'etiquette des annonces, apres le ton par defaut pose plus
   haut : le type urgent, le type resultat, et le neutre de tous les autres. */
.annonce .pastille-rouge  { background: var(--tp-rouge-fond); color: var(--tp-rouge); }
.annonce .pastille-verte  { background: var(--tp-vert-fond);  color: var(--tp-vert); }
.annonce .pastille-neutre { background: var(--tp-creux);      color: var(--tp-encre-3); }

/* La page d'une annonce dit la journee concernee dans un .message-info. Rien
   n'est ecrit ici pour lui : le socle porte deja les trois tons de message,
   celui-la compris, au meme duo ambre. Une seconde ecriture ne ferait que
   creer un endroit de plus ou les deux pourraient diverger. */

/* ──────────────────────────────────────────────────── LE FOCUS CLAVIER ──
   Une seule regle pour toute la famille : l'anneau or et son halo, comme
   dans le kit. On garde :focus-visible — l'anneau apparait au clavier, pas
   sous la souris. */

.fil-reaction:focus-visible,
.fil-action:focus-visible,
.fil-signalement > summary:focus-visible,
.fil-bloques > summary:focus-visible,
.fil-comite a:focus-visible,
.fil-retour a:focus-visible,
.fil-nom a:focus-visible,
.fil-com-nom:focus-visible,
.fil-lien-journee a:focus-visible,
.fil-bout a:focus-visible,
.carte.annonce:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  border-radius: var(--tp-r-tuile);
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* Les deux pilules gardent leur rondeur sous l'anneau. */
.fil-reaction:focus-visible { border-radius: var(--tp-r-pilule); }
.carte.annonce:focus-visible { border-radius: var(--tp-r-carte); }

/* ───────────────────────────────────────────────────────── LE TELEPHONE ──
   390 px, le plus etroit des iPhone en service. Trois blocs debordent a cette
   largeur si on les laisse en rangee : les marques de la tete, les recours du
   pied, et la ligne d'un joueur bloque. */

@media (max-width: 30rem) {
  .fil-pub,
  .fil-composer { padding: 1rem; }

  /* Les marques passent sous le nom et reviennent a gauche : serrees a droite
     d'une tete de 390, elles se coupaient mot par mot. */
  .fil-marques {
    flex-basis: 100%;
    justify-content: flex-start;
    margin-top: .125rem;
  }

  /* Les recours reprennent le fil de la ligne : pousses a droite sous le
     pouce, « Signaler » sortait de la carte. */
  .fil-pied-outils { margin-left: 0; }

  .fil-bloques li {
    align-items: flex-start;
    flex-direction: column;
    gap: .5rem;
  }

  .fil-vide { padding: 2rem .75rem; }
  .fil-vide-cercle { width: 76px; height: 76px; }
}

/* ────────────────────────────────────────────── LE MOUVEMENT, EN MOINS ──
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. La boule du carreau, elle, prend sa place
   sans le geste — jamais une boule bloquee en vol. */

@media (prefers-reduced-motion: reduce) {
  .fil-reaction,
  .fil-action,
  .fil-carreau-jeu,
  .fil-carreau-boule,
  .fil-composer textarea,
  .fil-repondre textarea {
    transition: none;
  }

  .fil-nouveau { animation: none; }
}

/* ────────────────────────────────────────────────────────── L'IMPRESSION ──
   Le fil s'imprime pour etre affiche a la buvette. fil.css masque deja le
   composer, les reactions, le pied et les recours ; ce qui suit ne reprend
   que les proprietes que CETTE feuille vient d'ecrire et qui, sans cela,
   passeraient devant lui : l'ombre de la carte et la finition d'acier. Une
   boule en degrade coute une cartouche et sort grise. */

@media print {
  .fil-pub {
    box-shadow: none;
    border-color: #999999;
    break-inside: avoid;
  }

  .fil-portrait-circuit,
  .fil-carreau-boule {
    background: none;
    box-shadow: inset 0 0 0 1px #999999;
  }

  .carte.annonce::before { background: #999999; }
}

} /* fin de la couche */


/* ─────────────────────────────────────────────────────────────────
   LES CLUBS, CHAMPIONNATS ET SPONSORS PUBLICS
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   TIRE OU POINTE — LES CLUBS, LES CHAMPIONNATS D'HIVER, LES SPONSORS

   Quatre vues du site public, et le cadre de la cinquieme :
     pages/club.php        la fiche d'un club — palmares, terrain, trombinoscope
     pages/clubs.php       l'annuaire — classement par club, cartes, federation
     pages/championnat.php un championnat d'hiver — journees + classement
     pages/championnats.php la liste des championnats
     pages/sponsors.php    le cadre de la page (la famille .spo-* est deja faite)

   ON NE RENOMME RIEN. Ces vues ecrivent .carte, .bouton, .pastille, .tableau,
   .jeton, .surtitre, .banniere, .bandeau-photo. On leur donne un DESSIN, pas
   un autre nom : papier creme, encre bleu nuit, un seul accent or, cartes
   blanches rayon 16, boutons pilule, Playfair en CASSE NORMALE, intitules
   Inter 700 onze pixels espaces de .14em.

   TROIS CHOSES QUE CETTE FEUILLE NE PEUT PAS FAIRE, ET COMMENT ELLE COMPOSE

   1 · LA QUEUE HORS COUCHE DE SABLE. Les lignes 694-753 de sable.css sont
       ecrites APRES la fermeture de @layer sable. Une declaration hors couche
       bat TOUTES les couches, « tire » comprise, et aucun !important n'y
       changerait rien (pour les !important la cascade INVERSE l'ordre des
       couches : « tire », declaree en dernier, y serait la plus faible). Elle
       tient la scene photo (.bandeau-photo devient : le titre sur le papier,
       puis la photo en grande carte dessous) et repeint en !important le
       titre, le sous-titre, le surtitre et les pastilles des bannieres.
       On ne la combat pas : on ECRIT DANS SON SENS, et on retourne sa propre
       arme — elle peint avec var(--or-800), var(--encre), var(--encre-2),
       var(--s-rayon-l). Ces JETONS, on les redefinit sur l'element lui-meme,
       dans cette couche. La declaration hors couche gagne toujours, mais elle
       resout desormais une valeur de la maison. C'est le geste que app.css
       documente deja pour --jaune (ligne 1226).

   2 · LES STYLES EN LIGNE. Dix-neuf sur club.php, sept sur clubs.php, seize
       sur les deux championnats. Un style= bat toute regle sans !important :
       les largeurs, les rayons, les ecarts et les deux polices de caracteres
       qu'ils posent sont acquis. On dessine AUTOUR, et jamais contre.

   3 · LE <style> DE championnat.php. Il est hors couche et en !important : la
       grille a deux colonnes retombe a une seule sous 1000 px. C'est le bon
       comportement, on n'y touche pas.

   CE QU'ON NEUTRALISE, PROPRIETE PAR PROPRIETE. Une couche ne gagne QUE sur
   les proprietes qu'elle ECRIT. Chaque regle d'ici reecrit donc explicitement
   ce que l'ancienne posait — display, position, grid-template-*, largeur,
   fond, bordure, rayon, ombre, rembourrage, marge, font-* — et eteint ses
   pseudo-elements par « content: none » plutot que par « display: none ».
   Les media queries anciennes comptent aussi : notre couche passe devant
   elles quelle que soit leur largeur, donc chaque valeur qu'elles posaient
   est reprise ici.

   ⚠️ light-dark() n'accepte QU'UNE <color>. Pour une ombre : var(--tp-ombre).
   ⚠️ Aucun !important. La couche « tire » est declaree en dernier, elle passe
      deja devant socle, composants, pages, utilitaires, eclat, sable.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ═══════════════════════════════════════════════ 1. LES EN-TETES DE PAGE ══
   Deux dessins pour la meme chose : .banniere.banniere-bleue sur la fiche de
   club, .bandeau-photo sur les trois autres. Dans les deux cas l'aplat jaune
   de la premiere charte et le marine de la seconde disparaissent : le titre
   se pose sur le papier creme, comme un en-tete de feuille de resultats. */

.banniere,
.banniere-bleue,
.bandeau-photo {
  /* L'aplat (--jaune sur .banniere, --panneau sur .banniere-bleue, le bleu
     nuit sur la scene) s'en va. La forme du raccourci remet aussi l'image de
     fond a zero, ce qu'aucune couleur seule n'aurait fait. */
  background: transparent;
  color: var(--tp-encre);
  border: 0;

  /* clamp(3rem, 6vw, 5rem) de haut plus clamp(1.5rem, 3vw, 2.5rem) de bas :
     quatre-vingts pixels de blanc avant le premier mot sur un telephone. Le
     dessin de l'application ouvre sur le contenu. */
  padding-block: 1.75rem 1.25rem;

  /* Les jetons que la queue hors couche consomme en !important. On ne peut
     pas lui reprendre la propriete, on lui donne la bonne valeur. */
  --encre:   var(--tp-encre);
  --encre-2: var(--tp-encre-2);
  --or-800:  var(--tp-or-lisible);
}

/* La photo de la scene descend sous le titre (regle hors couche) : le
   rembourrage du bas ne sert plus a rien et l'eloignait d'autant. */
.bandeau-photo {
  padding-block: 1.75rem 0;
  /* Le rayon de la grande photo passe par ce jeton, hors couche : 32 px
     devenaient une carte etrangere a la maison. Seize, comme tout le reste. */
  --s-rayon-l: var(--tp-r-carte);
}

/* La boule en filigrane, a droite, a 14 % — une photo de 560 px derriere le
   titre, et qui DERIVE a chaque chargement. Elle appartenait a la direction
   « sable » ; ici elle brouille le papier et retarde le premier mot.
   « content: none » et non « display: none » : le pseudo-element n'existe
   plus du tout, donc ni son image ni son animation ne sont demandees. */
.banniere::before,
.banniere::after,
.banniere-bleue::before,
.banniere-bleue::after,
.bandeau-photo::before,
.bandeau-photo::after { content: none; }

/* L'entree en cascade : chaque ligne de l'en-tete montait de 22 px, decalee
   de 80 ms. Une page qui se monte sous les yeux fait perdre plus de temps
   qu'elle n'en donne — et ici elle retardait le titre de la page. */
.banniere > .enveloppe > *,
.banniere-bleue > .enveloppe > *,
.bandeau-photo > .enveloppe > *,
.bandeau-photo > picture > img { animation: none; }

/* La regle hors couche remet le rembourrage BAS de l'enveloppe a zero mais
   laisse passer celui du haut (clamp(2rem, 7vw, 4.5rem)) : on l'eteint. */
.bandeau-photo > .enveloppe { padding-block: 0; }

/* La photo elle-meme : l'ombre de la maison a la place d'une ombre de 100 px
   de flou, et un trait, sans lequel une photo claire flotte sur le creme. */
.bandeau-photo > picture,
.bandeau-photo > img {
  border: 1px solid var(--tp-trait);
  box-shadow: var(--tp-ombre);
  background: var(--tp-creux);
}

/* Le titre de page. Big Shoulders montait a 7,4 rem en capitales condensees :
   c'est exactement ce qu'on enleve. Playfair, casse normale, a la mesure du
   kit (.tp-titre-1, 24 → 34 px). */
.banniere h1,
.banniere-bleue h1,
.bandeau-photo h1,
.section > .enveloppe > h1,
.section-mince > .enveloppe > h1 {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  text-wrap: balance;
  margin: 0;
}

/* La ligne de chiffres sous le titre : le corps de texte du site, pas une
   seconde affiche. Le clamp de sable montait a 1,25 rem en 500. */
.banniere .sous,
.banniere-bleue .sous,
.bandeau-photo .sous {
  margin: .5rem 0 0;
  max-width: 60ch;
  font-family: var(--tp-texte);
  font-weight: 400;
  font-size: 15px;
  line-height: 1.55;
  text-wrap: pretty;
}

/* Le geste du comite, pose dans l'en-tete du championnat. Il n'est PAS sous
   le coup des !important de sable (qui ne visent que .banniere et .acc-etat) :
   il garde donc l'or plein du kit, et il est le seul or de l'ecran. */
.bandeau-photo .rang { margin-top: 1rem; }

/* ═════════════════════════════════════════════ 2. LE RYTHME DE LA PAGE ══ */

/* L'enveloppe tient la gouttiere ET l'encoche : le site s'installe en PWA sur
   iPhone, et en paysage la zone sure mord de 44 px sur le bord gauche. Les
   deux cotes sont ecrits separement — un seul « padding-inline » aurait donne
   l'encoche gauche au bord droit. */
.enveloppe {
  max-width: 1160px;
  margin-inline: auto;
  padding-inline-start: max(var(--gouttiere, 1rem), env(safe-area-inset-left, 0px));
  padding-inline-end:   max(var(--gouttiere, 1rem), env(safe-area-inset-right, 0px));
}

/* clamp(4rem, 8vw, 7.5rem) entre deux sections, c'etait la respiration d'une
   page produit. Ici on empile des listes de clubs : on se lit a la suite. */
.section       { padding-block: 2rem; }
.section-mince { padding-block: 1.5rem; }

/* L'intitule de la maison : Inter 700, onze pixels, capitales espacees de
   .14em. Le tiret dore de 24 px qui le precedait est un motif de l'ancienne
   charte — et sur une page qui en compte six, six tirets font une grille. */
.surtitre {
  display: block;
  gap: 0;
  margin: 0 0 .5rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

.surtitre::before { content: none; }

/* Le titre de section. h2 montait a 3,4 rem en Big Shoulders 800 : sur la
   page des sponsors, chaque nom de club devenait une affiche. */
.section > .enveloppe > h2,
.section-mince > .enveloppe > h2 {
  margin: 0 0 .25rem;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.25rem, 1rem + 1.1vw, 1.875rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-wrap: balance;
  color: var(--tp-encre);
}

/* La ville, en petit, a cote du nom du club sur la page des sponsors. */
.section > .enveloppe > h2 > small,
.section-mince > .enveloppe > h2 > small {
  display: block;
  margin-top: .25rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* Le chapeau de la page des sponsors. Aucune feuille ne le dessinait : il
   tombait en corps de texte, a la meme taille que le reste. */
.chapo {
  margin: .75rem 0 0;
  font-size: 17px;
  line-height: 1.6;
  color: var(--tp-encre-2);
  text-wrap: pretty;
}

/* ═════════════════════════════════════════ 3. LES GRILLES ET LES PILES ══
   Le « min(100%, …) » garantit qu'une carte seule ne depasse jamais sa
   colonne : c'est lui qui tient les 390 px sans debordement horizontal, et
   c'est deja le geste de .spo-grille. */

.grille   { gap: 1rem; }
.grille > * { min-width: 0; }

.grille-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.grille-3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 16rem), 1fr)); }

/* Le trombinoscope : 9,5 rem tient DEUX portraits de front sur un telephone
   de 390 px, la ou 170 px n'en tenait qu'un et demi — donc un seul. */
.grille-4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 9.5rem), 1fr)); }

/* .g3 n'est definie QUE dans presentation.css, qui n'est pas chargee sur le
   site : la liste des championnats d'hiver tombait donc en UNE colonne pleine
   largeur, quelle que soit la fenetre. C'est un manque, pas un choix. */
.grille.g3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 17rem), 1fr)); }

.pile-2 { gap: .5rem; }
.pile-2 > * { min-width: 0; }

/* Les rangees de gestes passent a la ligne plutot que de deborder, et
   l'ecart vertical se resserre quand elles le font. */
.rang       { gap: .5rem .75rem; }
.rang-serre { gap: .5rem; }

/* Une icone dans une rangee ne se laisse jamais comprimer, et se cale sur la
   premiere ligne du texte qu'elle accompagne. */
.rang .icone,
.rang-serre .icone { flex: 0 0 auto; margin-top: .125rem; }

/* ═══════════════════════════════════════════════════════ 4. LA CARTE ══
   La brique de ces quatre pages. Blanche sur le creme, rayon 16, un trait fin
   et une ombre basse : elle se detache du papier sans flotter. L'ancienne
   n'avait aucune bordure (sable) et un rayon de 24 : sur un creme texture,
   une carte sans trait bave sur le papier. */

.carte {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 1rem 1.125rem;
  color: var(--tp-encre);
}

/* .carte-nette valait « un peu moins rond » quand la carte faisait 24. Les
   deux rayons se rejoignent : il n'y a qu'un rayon de carte dans la maison. */
.carte-nette { border-radius: var(--tp-r-carte); }

.carte-attente { border-left: 0; box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or); }

/* La carte cliquable. « display: block » est indispensable a un <a> — mais
   PAS a la ligne de journee du championnat, qui porte aussi .rang et doit
   rester une rangee : la couche « tire » passant devant « composants », un
   display:block seul l'aurait mise a plat. */
a.carte {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              border-color var(--tp-elan);
}

a.carte.rang { display: flex; align-items: center; }

/* Un pixel vers le haut, pas quatre : sur une grille de vingt clubs, le
   survol de sable faisait bouger la page entiere. Et la bordure ne s'efface
   plus au survol — elle se renforce, sinon la carte se decolle du papier. */
@media (hover: hover) {
  a.carte:hover {
    color: inherit;
    transform: translateY(-1px);
    border-color: var(--tp-trait-fort);
    box-shadow: var(--tp-ombre-haut);
  }
}

/* L'etat vide du championnat : « le calendrier n'est pas encore pose ». Une
   phrase seule dans une carte pleine largeur se lit comme une panne ; centree
   et aeree, elle se lit comme une attente. */
p.carte.muet {
  padding: 1.75rem 1.125rem;
  text-align: center;
  font-size: 14px;
  color: var(--tp-encre-3);
  text-wrap: pretty;
}

/* ═══════════════════════════════════════════════════════ 5. LES BOUTONS ══
   Pilules de 52 px (44 en petit), Inter 700 quinze. L'or plein est un FOND :
   il designe LE geste. L'ancien bouton portait un degrade vertical, un reflet
   d'arete blanc et une bordure de 2 px — trois matieres pour un bouton. */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  min-height: 52px;
  padding: 0 1.375rem;
  border: 1px solid transparent;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-or);
  color: var(--tp-sur-or);
  box-shadow: 0 2px 10px rgb(245 180 28 / .35);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              background var(--tp-elan), border-color var(--tp-elan);
}

.bouton::after { content: none; }

/* 44 px, et pas 34 : c'est la cible tactile. Toutes les paires de series
   (Hommes / Dames) et tous les gestes de la fiche de club sont en « petit ». */
.bouton-petit { min-height: 44px; padding: 0 1.125rem; font-size: 14px; }
.bouton-large { width: 100%; }

/* Le second ton : le contour, pas l'or. C'est lui qui porte la serie NON
   tenue d'une paire de filtres — l'or ne dit qu'une chose a la fois. */
.bouton-vide {
  background: transparent;
  border-color: var(--tp-trait-fort);
  color: var(--tp-encre);
  box-shadow: none;
}

@media (hover: hover) {
  .bouton:hover {
    filter: none;
    transform: none;
    background: var(--tp-or-vif);
    color: var(--tp-sur-or);
    box-shadow: 0 4px 16px rgb(245 180 28 / .45);
  }

  .bouton-vide:hover {
    background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
    border-color: var(--tp-trait-fort);
    color: var(--tp-encre);
    box-shadow: none;
  }
}

/* sable ecrivait « translateY(0) scale(.98) » : le bouton RETRECISSAIT sous
   le doigt au lieu de s'enfoncer. */
.bouton:active { transform: translateY(1px); }

.bouton[disabled],
.bouton[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }

/* ═════════════════════════════════════════════════════ 6. LES ETIQUETTES ══
   ⚠️ tire.css a DEJA pris « .pastille » pour le compteur rouge de l'en-tete
   et de la barre d'onglets. On ne le lui reprend pas : ces regles ne visent
   que les pastilles DU CONTENU, sous <main>. Sans ce « main », le nombre
   d'annonces non lues serait devenu une etiquette ambre dans la navigation.
   Les variantes portent le meme prefixe, sinon la regle generale — plus
   specifique — les effacerait toutes. */

main .pastille {
  display: inline-flex;
  align-items: center;
  gap: .3125rem;
  height: 24px;
  padding: 0 .5625rem;
  border: 0;
  border-radius: var(--tp-r-pilule);
  background: var(--tp-ambre-fond);
  color: var(--tp-or-lisible);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .06em;
  line-height: 1;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Le code du club, et son rang au classement par club : le marine plein, la
   seule etiquette qui pese autant qu'un logo. */
main .pastille-bleue {
  background: light-dark(#1D1838, #FFFFFF);
  color: light-dark(#FFFFFF, #101838);
}

/* Toujours le duo texte + fond, jamais la couleur seule : a onze pixels, une
   etiquette qui ne serait que coloree ne dirait plus rien. */
main .pastille-verte { background: var(--tp-vert-fond);  color: var(--tp-vert); }
main .pastille-ambre { background: var(--tp-ambre-fond); color: var(--tp-ambre); }
main .pastille-rouge { background: var(--tp-rouge-fond); color: var(--tp-rouge); }

/* « A venir » n'est pas un etat en creux : c'est un etat neutre. Le contour
   de 1,5 px disparait au profit du creux plein, qui se lit a cette taille. */
main .pastille-vide,
main .pastille-neutre {
  background: var(--tp-creux);
  color: var(--tp-encre-2);
  border: 0;
}

/* ═══════════════════════════════ 7. LES JOURNEES D'UN CHAMPIONNAT ══
   La liste datee du kit, transposee : le bloc date a gauche, le titre et sa
   meta au milieu, l'etat a droite. Les mesures du <span class="jeton"> sont
   posees en ligne (44 px, .62rem) : acquises, on dessine autour. */

.pile-2 > a.carte.rang {
  min-height: 60px;
  padding: .75rem 1rem;
  align-items: center;
}

/* Le jeton etait un disque marine a lettres or — le dessin d'un avatar de
   joueur, applique a une date. Il devient la tuile datee de l'application :
   le quantieme en Playfair, le mois en capitales espacees. */
.pile-2 > a.carte.rang > .jeton {
  display: grid;
  place-items: center;
  align-content: center;
  border: 0;
  border-radius: var(--tp-r-tuile);
  background: var(--tp-creux);
  color: var(--tp-encre-3);
  box-shadow: none;
  font-family: var(--tp-texte);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.pile-2 > a.carte.rang > .jeton b {
  font-family: var(--tp-titre);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--tp-encre);
}

/* Le nom de la journee est le titre de la ligne : quinze pixels, encre
   pleine. .minus le ramenait a 12,5 px, soit moins que sa propre meta. */
.pile-2 > a.carte.rang .gras.minus {
  font-size: 15px;
  line-height: 1.25;
  color: var(--tp-encre);
}

.pile-2 > a.carte.rang .petit.muet {
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* ═══════════════════════════════════════════════════════ 8. LE TABLEAU ══
   Le classement par club, et le classement general d'un championnat. L'ancien
   en-tete etait souligne de 2 px de bleu plein : un trait de plus que le
   tableau n'en demande. En-tete en petites capitales grises, lignes de 52 px,
   zebrage tres leger, chiffres TABULAIRES — sans eux les colonnes de points
   dansent d'une ligne a l'autre. */

.defile {
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  padding: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

.tableau {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--tp-texte);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

/* L'en-tete reste visible quand on fait defiler une province de trente
   clubs : sans lui, on ne sait plus quelle colonne on lit. */
.tableau th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--tp-carte);
  padding: .75rem;
  border-bottom: 1px solid var(--tp-trait);
  text-align: left;
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
  white-space: nowrap;
}

.tableau td {
  height: 52px;
  padding: .75rem;
  border-bottom: 1px solid var(--tp-trait);
  color: var(--tp-encre);
}

.tableau tbody tr:nth-child(even) td {
  background: color-mix(in oklab, var(--tp-creux) 40%, transparent);
}

.tableau tbody tr:last-child td { border-bottom: 0; }

/* Le survol se peignait en voile dore sur la RANGEE : il passait donc sous le
   zebrage, qui est pose sur les cellules. On eteint la rangee et on peint les
   cellules — l'un ou l'autre, jamais les deux. */
.tableau tbody tr:hover { background: transparent; }

@media (hover: hover) {
  .tableau tbody tr:hover td {
    background: color-mix(in oklab, var(--tp-creux) 60%, transparent);
  }
}

.tableau .nombre {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}

/* Le rang du club. Big Shoulders 900 a line-height .9 : deux chiffres qui se
   touchaient. Playfair 700, vingt pixels — la mesure du bloc date du kit.
   La couleur est posee EN LIGNE par la vue (--jaune-profond pour le podium,
   --encre-2 sinon) : on ne peut pas la reprendre, on redefinit les deux
   jetons ici meme, et l'or devient l'or qui a le droit de s'ecrire. */
.tableau .chiffre {
  --jaune-profond: var(--tp-or-lisible);
  --encre-2: var(--tp-encre-2);
  font-family: var(--tp-titre);
  font-weight: 700;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.tableau .chiffre-m { font-size: 20px; }

/* ═══════════════════════════════════════ 9. LES LIENS DU CORPS DE PAGE ══
   Un lien ne se distingue jamais par la seule couleur : il porte un filet
   dore sous le texte, visible en permanence. L'ancien --lien peignait le
   texte en marine de jour et en or de nuit — deux couleurs, aucun filet. */

.section .carte a:not(.bouton):not(.pastille),
.section-mince .carte a:not(.bouton):not(.pastille),
.section-mince > .enveloppe > ul.pile-2 a,
.tableau a {
  color: var(--tp-encre);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in oklab, var(--tp-or) 55%, transparent);
  text-underline-offset: 3px;
}

.section .carte a:not(.bouton):not(.pastille):hover,
.section-mince .carte a:not(.bouton):not(.pastille):hover,
.section-mince > .enveloppe > ul.pile-2 a:hover,
.tableau a:hover {
  color: var(--tp-encre);
  text-decoration-color: var(--tp-or);
}

/* ═════════════════════════════════════════════ 10. LE PALMARES DU CLUB ══
   Deux cartes, Hommes et Dames, chacune avec son rang et ses trois meilleurs.
   Le titre est peint EN LIGNE en var(--bleu-texte) : on redefinit le jeton
   sur l'element, et le lien qu'il contient herite (il porte color:inherit). */

.grille-2 > .carte h3,
.grille-3 > .carte h3 {
  --bleu-texte: var(--tp-encre);
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 1.25rem;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-wrap: balance;
}

.grille-2 > .carte > ol {
  margin: .75rem 0 0;
  font-size: 14px;
}

.grille-2 > .carte > ol > li { margin-bottom: .25rem; }

/* Le numero d'ordre est une donnee de second rang : il compte, il ne crie
   pas. Chiffres tabulaires, parce qu'ils s'empilent. */
.grille-2 > .carte > ol > li::marker {
  color: var(--tp-encre-4);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* ══════════════════════════════════════ 11. LES LISTES DE LA FICHE CLUB ══
   « Journees gagnees par le club » et « Jubiles » : deux <ul class="pile-2">
   poses a nu sur le papier, une ligne par element. Ils deviennent la liste du
   kit — une carte sans rembourrage, des lignes separees d'un trait. */

.section-mince > .enveloppe > ul.pile-2 {
  gap: 0;
  margin: 0;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
}

.section-mince > .enveloppe > ul.pile-2 > li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: .25rem .5rem;
  min-height: 52px;
  padding: .75rem 1rem;
  border-top: 1px solid var(--tp-trait);
}

.section-mince > .enveloppe > ul.pile-2 > li:first-child { border-top: 0; }

/* ═══════════════════════════════════════════════ 12. LE TERRAIN DU CLUB ══
   La carte du lieu : la photo, l'adresse, l'acces, le ou les responsables, et
   les trois gestes — « Y aller » en or, le telephone et le site en contour.
   Un seul or : on ne va au terrain qu'une fois. */

#terrain > .enveloppe > .carte { padding: 1rem 1.125rem 1.125rem; }

/* La photo porte deja son rayon de 12 px en ligne. Il lui manquait un trait :
   une photo de terrain en plein soleil se fond dans la carte blanche. */
#terrain > .enveloppe > .carte > img {
  display: block;
  border: 1px solid var(--tp-trait);
  background: var(--tp-creux);
}

/* L'adresse est ce qu'on vient chercher : elle se lit avant tout le reste. */
#terrain .carte .gras {
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 16px;
  line-height: 1.35;
  color: var(--tp-encre);
}

/* La ligne d'equipement (terrains, couvert, buvette, horaires) est une meta,
   pas une phrase : elle se range au bas de la carte, detachee d'un filet. */
#terrain .carte > div > p.minus.muet:last-of-type {
  margin-top: .75rem;
  padding-top: .75rem;
  border-top: 1px solid var(--tp-trait);
}

/* La rangee du responsable : le nom, puis les deux moyens de le joindre. Elle
   passe a la ligne sur un telephone sans que les pilules se chevauchent. */
#terrain .carte p.rang { row-gap: .5rem; }

/* ═════════════════════════════════════════════ 13. LE TROMBINOSCOPE ══
   Une grille de portraits ronds. La vue centre par « text-align: center » —
   mais le socle met « display: block » sur toute image : un bloc ne se centre
   pas au texte, et les 96 px etaient donc colles a gauche de leur carte.
   Deux marges automatiques suffisent. */

#trombinoscope .grille-4 > a.carte {
  padding: 1rem .75rem 1.125rem;
}

#trombinoscope .grille-4 > a.carte img {
  margin-inline: auto;
  /* L'anneau du kit : deux pixels de carte, un trait autour. Pose en ombre
     plutot qu'en bordure — une bordure aurait rogne 4 px sur une image dont
     la taille est fixee en ligne. */
  box-shadow: 0 0 0 2px var(--tp-carte), 0 0 0 3px var(--tp-trait);
}

#trombinoscope .grille-4 > a.carte .gras {
  margin-top: .75rem;
  font-size: 14px;
  line-height: 1.25;
  color: var(--tp-encre);
  overflow-wrap: break-word;
}

#trombinoscope .grille-4 > a.carte .minus {
  font-size: 12px;
  color: var(--tp-encre-3);
  font-variant-numeric: tabular-nums;
}

/* La liste des licencies sans portrait : des noms separes par des points
   medians. Ils doivent rester des cibles, et ne jamais couper la page. */
#trombinoscope > .enveloppe > p:last-child {
  overflow-wrap: break-word;
  color: var(--tp-encre-3);
}

#trombinoscope > .enveloppe > p:last-child a {
  color: var(--tp-encre-2);
  font-weight: 600;
  text-decoration: underline;
  text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in oklab, var(--tp-or) 45%, transparent);
  text-underline-offset: 3px;
}

#trombinoscope > .enveloppe > p:last-child a:hover {
  color: var(--tp-encre);
  text-decoration-color: var(--tp-or);
}

/* ═══════════════════════════════════════════════════════ 14. LES TIROIRS ══
   Les provinces de la federation, et la fiche pratique du comite. Le <summary>
   n'etait qu'un mot souligne par le navigateur : ni cible, ni repere d'etat.
   Il devient une ligne du kit — 52 px, un chevron qui tourne a l'ouverture.
   ⚠️ Rien de tout ceci ne vaut pour « summary » en general : le selecteur de
   province, dans l'en-tete, a son propre dessin dans sable.css. */

#terrain > .enveloppe > details,
#federation > .enveloppe > details { margin-bottom: .5rem; }

#terrain > .enveloppe > details > summary,
#federation > .enveloppe > details > summary {
  display: flex;
  align-items: center;
  gap: .5rem;
  min-height: 52px;
  padding: .625rem 1rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-carte);
  box-shadow: var(--tp-ombre);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  color: var(--tp-encre);
  cursor: pointer;
  list-style: none;
  transition: background var(--tp-elan), border-color var(--tp-elan);
}

#terrain > .enveloppe > details > summary::-webkit-details-marker,
#federation > .enveloppe > details > summary::-webkit-details-marker { display: none; }

/* Le chevron est trace au trait, pas ecrit : un caractere « › » change de
   dessin d'une police a l'autre, et disparait si la police tarde. */
#terrain > .enveloppe > details > summary::after,
#federation > .enveloppe > details > summary::after {
  content: "";
  flex: 0 0 auto;
  margin-left: auto;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--tp-encre-4);
  border-bottom: 2px solid var(--tp-encre-4);
  rotate: -45deg;
  translate: 0 -1px;
  transition: rotate var(--tp-elan);
}

#terrain > .enveloppe > details[open] > summary::after,
#federation > .enveloppe > details[open] > summary::after {
  rotate: 45deg;
  translate: 0 -3px;
}

@media (hover: hover) {
  #terrain > .enveloppe > details > summary:hover,
  #federation > .enveloppe > details > summary:hover {
    background: color-mix(in oklab, var(--tp-creux) 45%, var(--tp-carte));
    border-color: var(--tp-trait-fort);
  }
}

/* Le compte de clubs, a droite du nom de province : une meta, pas un titre. */
#federation > .enveloppe > details > summary .minus.muet {
  font-weight: 600;
  font-size: 13px;
  color: var(--tp-encre-3);
}

/* ══════════════════════════════════ 15. LA FICHE PRATIQUE DU COMITE ══
   Le formulaire de club.php. Ses champs n'ont AUCUNE classe : app.css ne
   dessine que « .champ input », donc ils tombaient en champs bruts du
   navigateur, au milieu d'une page entierement redessinee. */

#terrain > .enveloppe > details > form.carte { padding: 1.125rem; }

#terrain form :is(label, p).etiquette {
  display: block;
  margin: 0 0 .375rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  line-height: 1.35;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

#terrain form :is(input[type="text"], input[type="url"], textarea) {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 15px;
  line-height: 1.5;
  color: var(--tp-encre);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

#terrain form textarea { min-height: 96px; resize: vertical; }

#terrain form :is(input, textarea)::placeholder { color: var(--tp-encre-4); }

/* Un champ dont on ne sait pas qu'il a le curseur est un formulaire qu'on
   remplit deux fois : l'anneau or double d'un halo. */
#terrain form :is(input[type="text"], input[type="url"], textarea):focus {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* :user-invalid plutot que :invalid — on ne souligne pas en rouge une adresse
   de site que la personne n'a pas encore touchee. */
#terrain form :is(input[type="text"], input[type="url"]):user-invalid {
  border-color: var(--tp-rouge);
  box-shadow: 0 0 0 3px rgb(201 52 43 / .18);
}

/* Le bouton de choix de fichier est le seul element du site que le navigateur
   dessine encore lui-meme : il prend la pilule secondaire du kit. */
#terrain form input[type="file"] {
  width: 100%;
  padding: .5rem 0;
  font-size: 14px;
  color: var(--tp-encre-2);
}

#terrain form input[type="file"]::file-selector-button {
  min-height: 44px;
  margin-right: .75rem;
  padding: 0 1.125rem;
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-pilule);
  background: var(--tp-creux);
  color: var(--tp-encre);
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
}

#terrain form input[type="radio"] {
  width: 22px;
  height: 22px;
  accent-color: var(--tp-or);
  flex: 0 0 auto;
}

/* Les photos de journee proposees en vignette. Le choix se voyait au seul
   petit rond du bouton radio, a cote d'une image de 96 px : on ne voyait pas
   laquelle etait retenue. La vignette entiere devient la cible, et le choix
   se dit par le liseré d'or de la maison. */
#terrain form .rang > label {
  display: inline-flex;
  align-items: center;
  gap: .375rem;
  padding: .25rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-tuile);
  background: var(--tp-carte);
  font-size: 14px;
  color: var(--tp-encre-2);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

#terrain form .rang > label:has(input:checked) {
  border-color: var(--tp-or);
  box-shadow: 0 0 0 2px color-mix(in oklab, var(--tp-or) 45%, transparent);
  color: var(--tp-encre);
}

/* ═══════════════════════════════════════════ 16. LE CADRE DES SPONSORS ══
   La famille .spo-* a son dessin dans tire-poste.css : on ne le refait pas.
   Ne restent ici que les blocs de la page qui l'entourent — le chapeau (§ 2),
   les deux cartes de texte, et l'ecart entre l'intitule d'un club et sa
   grille. La grille, elle, pose deja sa propre marge haute. */

.section-mince > .enveloppe > .carte > p > strong {
  font-weight: 700;
  color: var(--tp-encre);
}

.section-mince > .enveloppe > h2 + p.muet { margin-top: .25rem; }

/* ═══════════════════════════════════════════════════ 17. LES UTILITAIRES ══
   ⚠️ .mt-1, .mt-3, .mb-1 et .mb-5 ne sont definies NULLE PART dans app.css,
   qui ne descend qu'a .mt-2 / .mt-4 / .mt-5 / .mt-6 / .mb-2 / .mb-4. Les
   quatre sont pourtant ecrites treize fois dans ces vues — et ne faisaient
   rien du tout. On les pose au meme pas que les autres (--r1, --r3, --r5). */

.mt-1 { margin-top: .25rem; }
.mt-3 { margin-top: .75rem; }
.mb-1 { margin-bottom: .25rem; }
.mb-5 { margin-bottom: 1.5rem; }

/* La meta passe de --encre-2 a --encre-3 : c'est l'encre des lignes de
   detail dans tout le kit (.tp-ligne-meta). Elle tient 4,8:1 sur le papier
   et 7,5:1 sur le bleu nuit — au-dessus du seuil, dans les deux thèmes. */
.muet  { color: var(--tp-encre-3); }
.petit { font-size: 13.5px; }
.minus { font-size: 13px; }
.gras  { font-weight: 700; }

/* ═══════════════════════════════════════════════════ 18. LE FOCUS CLAVIER ══
   Le socle pose un anneau de 3 px double d'un halo de 6 px sur TOUT element,
   avec un rayon de 3 px qui coupe les angles d'une pilule. Ici, l'anneau de
   la maison : deux pixels d'or, decales de deux. */

:is(.bouton, a.carte, main .pastille):focus-visible,
#terrain > .enveloppe > details > summary:focus-visible,
#federation > .enveloppe > details > summary:focus-visible,
#terrain form :is(input, textarea, button):focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  border-radius: var(--tp-r-pilule);
  box-shadow: 0 0 0 5px rgb(245 180 28 / .25);
}

/* Une carte et un tiroir ne sont pas des pilules : ils gardent leur rayon. */
a.carte:focus-visible,
#terrain > .enveloppe > details > summary:focus-visible,
#federation > .enveloppe > details > summary:focus-visible {
  border-radius: var(--tp-r-carte);
}

#terrain form :is(input, textarea):focus-visible { border-radius: var(--tp-r-champ); }

/* Les liens du corps de page : le meme anneau, sans le halo — un lien au fil
   du texte n'a pas a repousser ses voisins. */
.section a:focus-visible,
.section-mince a:focus-visible,
.banniere a:focus-visible,
.banniere-bleue a:focus-visible,
.bandeau-photo a:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  border-radius: 4px;
  box-shadow: none;
}

/* ══════════════════════════════════════════ 19. LE MOUVEMENT, EN MOINS ══
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. Les entrees en cascade de sable sont deja
   eteintes plus haut, pour tout le monde. */

@media (prefers-reduced-motion: reduce) {
  .carte,
  a.carte,
  .bouton,
  .bouton-vide,
  #terrain > .enveloppe > details > summary,
  #terrain > .enveloppe > details > summary::after,
  #federation > .enveloppe > details > summary,
  #federation > .enveloppe > details > summary::after,
  #terrain form :is(input, textarea),
  #terrain form .rang > label {
    transition: none;
  }

  a.carte:hover,
  .bouton:hover,
  .bouton:active { transform: none; }
}

/* ═════════════════════════════════════════════════ 20. LE TELEPHONE ══
   390 px de large, encoche comprise. Rien ne deborde de cote : les tableaux
   defilent DANS leur carte, les grilles retombent a une colonne par le
   « min(100%, …) », et les noms sans espace se coupent. */

@media (max-width: 480px) {
  .banniere,
  .banniere-bleue { padding-block: 1.25rem 1rem; }

  .bandeau-photo  { padding-block: 1.25rem 0; }

  .section        { padding-block: 1.5rem; }
  .section-mince  { padding-block: 1.25rem; }

  .carte { padding: .875rem 1rem; }

  /* Serrer les cellules rend une colonne de plus lisible sans defilement. */
  .tableau th,
  .tableau td { padding: .625rem .5rem; }
  .tableau    { font-size: 13px; }
  .tableau td { height: 48px; }

  /* Les trois gestes du terrain se partagent la largeur au lieu de laisser un
     orphelin sur la troisieme ligne. */
  #terrain .carte p.rang > .bouton { flex: 1 1 8rem; }

  /* Un nom de club sans espace (« BOULODROME-DE-SAINTE-ODE ») prenait la
     largeur de son plus long mot et faisait glisser la page de cote. */
  .grille-3 > .carte h3,
  .grille-2 > .carte h3,
  .section-mince > .enveloppe > ul.pile-2 > li { overflow-wrap: break-word; }
}

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   LES SPONSORS, COTE PUBLIC
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   LE POSTE — famille « LES SPONSORS »

   .spo-grille · .spo-grille--grand · .spo-carte · .spo-logo · .spo-logo--mot ·
   .spo-corps · .spo-nom · .spo-ville · .spo-texte · .spo-tel · .spo-bandeau ·
   .spo-bandeau-titre · .spo-rangee · .spo-vignette · .spo-vignette-mot
   (et les deux <img> : .spo-logo img, .spo-vignette img)

   Ceux qui font tourner le circuit. Cette famille sert DEUX contextes et il
   fallait tenir les deux du premier coup : la page « Nos sponsors » et la
   fiche de club du site PUBLIC, sur le papier crème ; et le bandeau repris au
   bas d'une fiche de journée, dans le panneau. Aucune règle d'ici ne suppose
   le fond sur lequel elle tombe — tout passe par les jetons, donc le cagnard,
   la buvette et le réglage du téléphone suivent sans une ligne de plus.

   LA RÈGLE QUI COMMANDE TOUT LE RESTE, héritée de l'ancienne feuille et
   conservée telle quelle : UN LOGO NE SE DÉFORME JAMAIS. Le commerçant qui
   voit son logo étiré sur le site du circuit ne se souvient que de ça — et
   c'est justement la personne qu'on remercie. D'où « object-fit: contain »
   partout, la plaque claire derrière, et de l'air autour. Deuxième règle
   héritée : un logo manquant ne laisse pas un trou, le nom s'écrit en grand à
   sa place ; un cadre gris avec une croix dedans est pire que rien.

   UN SEUL OR, et il ne s'écrit pas : le liseré des sponsors DU CIRCUIT, au
   dessin exact de .tp-carte--or. La hiérarchie est déjà portée par la taille
   des cartes et par l'intitulé de la section ; le liseré ne fait que la redire
   dans le signe de la maison. Rien d'autre n'est doré, hors l'anneau de focus.

   ON NE RENOMME RIEN : les vues (pages/sponsors.php, pages/club.php,
   pages/competition.php, partials/sponsors_bandeau.php) écrivent ces classes
   telles quelles. Elles reçoivent un DESSIN, pas un autre nom.

   CE QUI EST NEUTRALISÉ, ET POURQUOI
   Une couche ne gagne QUE sur les propriétés qu'elle ÉCRIT. p-sponsors.css
   (@layer pages) dessine encore toute la famille : grille à écart élastique,
   carte sans ombre franche (--ombre-1) qui monte de 2 px et se dore la bordure
   au survol ET au focus, anneau de focus de 3 px sur un jeton --focus étranger
   à cette direction, noms de sponsor en 800 CAPITALES sur --marine-800 en dur,
   ville à .78rem/.09em, téléphone peint en --lien, barre de défilement visible
   sous le bandeau. Chaque règle ci-dessous réécrit donc explicitement display,
   grid-template-*, flex-*, largeur, fond, bordure, rayon, ombre, transform,
   rembourrage, marge et font-* de l'ancienne.

   ⚠️ SA QUEUE EST HORS COUCHE. Les deux dernières media queries de
   p-sponsors.css (mouvement réduit, impression) sont écrites APRÈS la
   fermeture de @layer pages : une déclaration hors couche bat toutes les
   couches, « tire » comprise, et aucun !important n'y changerait rien. Elles
   coupent déjà la transition de la carte et masquent le bandeau au papier :
   on écrit donc DANS LEUR SENS, et seulement là où elles se taisent.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ──────────────────────────────────────────────────────────── LA GRILLE ──
   L'écart est FIXE, comme partout dans la maison : l'ancien clamp (.9 → 1.6rem)
   faisait changer le pas du rythme avec la largeur de la fenêtre, donc d'un
   poste à l'autre. Le « min(100%, …) » garantit qu'une carte seule ne dépasse
   jamais sa colonne : c'est lui qui tient les 390 px sans débordement. */

.spo-grille {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 15rem), 1fr));
  align-items: stretch;
  gap: 1rem;
  margin-top: 1rem;
}

/* Sans ça, un nom de commerçant sans espace (« GARAGE-DUPONT-BASTOGNE ») prend
   la largeur de son plus long mot et fait défiler la page de côté. */
.spo-grille > * { min-width: 0; }

/* Les sponsors du circuit soutiennent toute la saison, pas une journée : ils
   ont droit à plus de place. La hiérarchie se lit à la taille — un libellé
   « sponsor principal » ne se lit pas. */
.spo-grille--grand {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 19rem), 1fr));
}

/* ───────────────────────────────────────────────────────────── LA CARTE ──
   La carte du kit, au mot près : blanche sur le crème, rayon 16, un trait fin
   ET une ombre basse. L'ancienne portait --ombre-1 sans vrai trait ; sur un
   crème texturé, une carte sans trait bave sur le papier.

   Les trois variables locales ne sont PAS des jetons : c'est de la plomberie.
   Elles évitent d'écrire quatre exceptions pour la carte du circuit — sans
   elles, le survol et le focus, qui doivent de toute façon réécrire bordure et
   ombre pour défaire l'ancienne feuille, effaceraient son liseré d'or. */

.spo-carte {
  --spo-bord: var(--tp-trait);
  --spo-bord-vif: var(--tp-trait-fort);
  --spo-filet: 0 0 transparent;

  display: grid;
  grid-template-rows: auto 1fr;
  gap: .75rem;
  min-width: 0;
  padding: 1rem 1.125rem;
  border: 1px solid var(--spo-bord);
  border-radius: var(--tp-r-carte);
  background: var(--tp-carte);
  color: var(--tp-encre);
  box-shadow: var(--tp-ombre), var(--spo-filet);
  text-decoration: none;
  transition: transform var(--tp-elan), box-shadow var(--tp-elan),
              border-color var(--tp-elan);
}

/* Le liseré d'or du circuit : un trait à gauche, jamais un aplat — l'or en
   fond mangerait le nom et le texte. Même geste que la ligne « Vous » du
   classement : le lecteur le reconnaît d'un écran à l'autre. */
.spo-grille--grand > .spo-carte {
  --spo-bord: color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  --spo-bord-vif: color-mix(in oklab, var(--tp-or) 60%, var(--tp-trait));
  --spo-filet: inset 3px 0 0 var(--tp-or);
}

/* Un pixel vers le haut, pas deux : sur une grille de douze commerçants, le
   survol faisait bouger la page entière. Un pixel suffit à dire « ça clique ».
   Seul le <a> répond — une carte sans lien reste immobile. */
@media (hover: hover) {
  a.spo-carte:hover {
    color: var(--tp-encre);
    transform: translateY(-1px);
    border-color: var(--spo-bord-vif);
    box-shadow: var(--tp-ombre-haut), var(--spo-filet);
  }
}

/* L'ancienne feuille soulevait AUSSI la carte au clavier et lui dorait la
   bordure : la ligne qu'on suit sautait à chaque tabulation. L'anneau de la
   maison suffit, et transform est explicitement remis à plat. */
a.spo-carte:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  transform: none;
  border-color: var(--spo-bord-vif);
  box-shadow: var(--tp-ombre), var(--spo-filet);
}

/* ────────────────────────────────────────────────────────────── LE LOGO ──
   La plaque reste BLANCHE dans les deux thèmes, et c'est délibéré : la plupart
   des logos de commerçants sont dessinés pour du papier blanc, et beaucoup
   disparaissent purement et simplement sur du bleu nuit. Un fond neutre les
   rend tous lisibles sans avoir à demander une version claire à chacun.
   Le trait, lui, est nouveau : de jour, la carte est blanche elle aussi, et
   sans lui la plaque n'existait pas. */

.spo-logo {
  display: grid;
  place-items: center;
  aspect-ratio: 16 / 9;
  max-width: 100%;
  padding: .75rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-champ);
  background: #FFFFFF;
  overflow: hidden;
}

.spo-logo img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  /* JAMAIS « cover » : il recadre, et un logo recadré perd son nom. */
  object-fit: contain;
}

/* Sans logo, le nom prend la place — en Playfair et en CASSE NORMALE.
   L'ancienne l'écrivait en 800 capitales intégrales, héritage de Big
   Shoulders : en Playfair, « BOULANGERIE DE LA GRAND-PLACE » se déchiffre au
   lieu de se lire.

   La couleur passe par --tp-sur-or, seule encre de la palette qui reste sombre
   dans les deux thèmes — c'est exactement ce qu'il faut sur une plaque
   toujours claire. var(--tp-encre) aurait écrit blanc sur blanc la nuit. */
.spo-logo--mot {
  padding: 1rem .75rem;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.125rem, 1rem + 1vw, 1.625rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-align: center;
  text-wrap: balance;
  overflow-wrap: break-word;
  color: var(--tp-sur-or);
}

/* ────────────────────────────────────────────────────────────── LE TEXTE ──
   Quatre lignes au plus, du plus fort au plus discret. L'écart vient du « gap »
   seul : les marges de l'ancienne s'ajoutaient à lui et creusaient un blanc
   qu'on croyait vide. Elles sont donc toutes remises à zéro. */

.spo-corps {
  display: grid;
  align-content: start;
  gap: .25rem;
  min-width: 0;
}

.spo-nom {
  margin: 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.3;
  color: var(--tp-encre);
  overflow-wrap: break-word;
}

/* La ville est l'intitulé de la maison : Inter 700, onze pixels, capitales
   espacées de .14em. L'ancienne écrivait .78rem à .09em — presque le même
   dessin, juste à côté du pas commun, et c'est ce « juste à côté » qui faisait
   que la page ne ressemblait pas au reste. */
.spo-ville {
  margin: 0;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--tp-encre-3);
}

.spo-texte {
  margin: 0;
  font-size: 14px;
  line-height: 1.5;
  color: var(--tp-encre-2);
  text-wrap: pretty;
}

/* Le numéro est ÉCRIT, pas appelable : le gabarit pose un <span>. Peint en
   --lien, il promettait un appui qui ne déclenche rien. Chiffres tabulaires
   parce que les numéros s'empilent d'une carte à l'autre dans la colonne. */
.spo-tel {
  margin: 0;
  font-weight: 700;
  font-size: 13.5px;
  font-variant-numeric: tabular-nums;
  color: var(--tp-encre-2);
}

/* ═══════════════════════════════════ LE BANDEAU DES AUTRES PAGES ══
   Une ligne de logos au bas d'une fiche de journée ou de club. Elle ne doit
   jamais concurrencer ce qu'on est venu lire : petite, discrète, et elle
   défile horizontalement DANS son bloc plutôt que de pousser la page vers le
   bas. Le débordement reste à l'intérieur — une page qui glisse de gauche à
   droite sur un téléphone est le défaut le plus visible qui soit, et c'est
   celui qu'on remarque avant le logo. */

.spo-bandeau {
  margin-top: 1.75rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--tp-trait);
}

.spo-bandeau-titre {
  margin: 0 0 .625rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.35;
  color: var(--tp-encre-3);
}

/* La barre de défilement fine était visible sous la rangée : un trait gris de
   plus sous des logos qu'on veut nets. Elle disparaît, comme sous les puces du
   kit, et le rembourrage vertical remplace celui que l'ancienne lui réservait
   — quatre pixels, la place exacte de l'anneau de focus d'une vignette, qui
   sans eux serait rogné par le bord du bloc qui défile. */
.spo-rangee {
  display: flex;
  flex-wrap: nowrap;
  gap: .625rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
  padding-block: 4px;
}

.spo-rangee::-webkit-scrollbar { display: none; }

/* 120 px de large sur 16/9 : 68 px de haut, la cible se touche au pouce. */
.spo-vignette {
  flex: 0 0 auto;
  scroll-snap-align: start;
  display: grid;
  place-items: center;
  width: 7.5rem;
  max-width: 100%;
  aspect-ratio: 16 / 9;
  padding: .5rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-tuile);
  background: #FFFFFF;
  box-shadow: none;
  overflow: hidden;
  text-decoration: none;
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

.spo-vignette img {
  display: block;
  width: auto;
  height: auto;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

/* Même plaque claire, donc même encre sombre dans les deux thèmes. */
.spo-vignette-mot {
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 13px;
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-align: center;
  text-wrap: balance;
  overflow-wrap: break-word;
  color: var(--tp-sur-or);
}

/* Une vignette sans lien est un <span> : l'ancienne feuille dorait sa bordure
   au survol comme celle des autres, et promettait un clic qui n'existe pas.
   On éteint d'abord pour tout le monde, on rallume ensuite pour le seul <a>. */
.spo-vignette:hover {
  border-color: var(--tp-trait);
  box-shadow: none;
}

@media (hover: hover) {
  a.spo-vignette:hover {
    border-color: var(--tp-trait-fort);
    box-shadow: var(--tp-ombre);
  }
}

/* L'anneau de la maison : deux pixels d'or, décalés de deux. L'ancien montait
   à trois sur un jeton --focus qui n'appartient plus à cette direction. */
.spo-vignette:focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
  border-color: var(--tp-trait-fort);
}

/* ══════════════════════════════════════════════ LE MOUVEMENT, EN MOINS ══
   La queue hors couche de p-sponsors.css coupe déjà la transition de la carte
   et son survol ; elle ignore en revanche la vignette du bandeau, qui bougeait
   donc encore. Qui demande moins de mouvement n'en a aucun. */

@media (prefers-reduced-motion: reduce) {
  .spo-carte,
  .spo-vignette { transition: none; }

  a.spo-carte:hover,
  a.spo-carte:focus-visible { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════ PAPIER ══
   Une page de sponsors s'imprime pour l'afficher au mur du club. La queue hors
   couche masque déjà le bandeau et aplatit la carte, et elle gagne sur cette
   couche quoi qu'on écrive : on ne la combat pas. Reste ce dont elle ne parle
   pas — les fonds et les encres. Ils sont écrits en clair, aux valeurs du
   jour : le papier n'a pas de thème, et une page imprimée depuis la buvette
   sortait en encre blanche sur blanc. */

@media print {
  .spo-carte {
    background: #FFFFFF;
    color: #1D1838;
  }

  .spo-nom,
  .spo-logo--mot,
  .spo-vignette-mot { color: #1D1838; }

  .spo-ville,
  .spo-texte,
  .spo-tel { color: #3F475B; }

  /* La plaque garde un trait gris : sans lui, un logo clair s'imprime dans un
     rectangle qui n'existe pas. */
  .spo-logo,
  .spo-vignette {
    background: #FFFFFF;
    border-color: #CCCCCC;
    box-shadow: none;
  }
}

} /* @layer tire */


/* ─────────────────────────────────────────────────────────────────
   LES PAGES DE TEXTE ET LES MENTIONS LEGALES
   ───────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════════
   LA VUE PUBLIQUE — famille « PAGES DE TEXTE ET MENTIONS LEGALES »

   /conditions · /confidentialite · /suppression-compte · /compte/supprimer ·
   /regles · /carreau · /fanny · /legende

   Huit pages qui n'ont qu'un seul geste a offrir : se lire. C'est la que se
   joue la confiance, et c'est la que le RGPD s'ecrit — une page de droits
   qu'on n'arrive pas a lire est une page de droits qu'on n'exerce pas.

   Meme direction que le reste : papier creme, encre bleu nuit, UN SEUL accent
   or. Colonne bornee a ~70 signes, titres Playfair en casse NORMALE, corps
   Inter 15/1.6, listes aerees, intitules Inter 700 11px capitales espacees.

   ON NE RENOMME RIEN : ces classes sont celles du site depuis le premier jour,
   et app.js accroche [data-confirmer] sur le formulaire de suppression. Elles
   recoivent un DESSIN, pas un autre nom.

   ─────────────────────────────────────────────────────────── LA PORTEE ──
   Cette feuille est assemblee EN DERNIER. Elle doit donc ne rien imposer aux
   familles posees avant elle, et aucune de ces huit vues ne porte de classe
   ni d'attribut qui dise « je suis une page de texte ». La portee est donc
   prise sur la STRUCTURE, et verifiee vue par vue :

     · LA COLONNE DE PROSE — .enveloppe.etroit:has(.carte :is(ul, ol).pile-2)
       .etroit sert a neuf vues ; les cinq autres (annonce, annonces, fil,
       notifications, profil) ne portent AUCUNE liste ul/ol en .pile-2 dans
       une carte — celle de notifications est un <div>, que :is(ul, ol)
       ecarte. Le test isole donc exactement les quatre pages legales, et
       laisse a fil.php sa colonne large et a profil.php ses formulaires.

     · LE BANDEAU — le meme test, porte sur la section qui suit. Sans lui,
       annonce.php serait pris : c'est la seule autre vue dont le bandeau
       enveloppe directement une colonne etroite, et elle appartient a la
       famille « fil », assemblee AVANT celle-ci.

     · LES PIECES UNIQUES — .grille-3 > .carte > .chiffre-xl ne decrit que les
       chapitres de la legende, .carte > .surtitre + ol que le mur des Fanny.
       Verifie sur l'ensemble des 83 vues : aucune autre n'y repond.

     · LE TIROIR, LUI, EST PARTAGE — details:has(> form.carte) decrit TROIS
       vues : carreau, club et competition. Elles portent le meme defaut, au
       meme endroit : un <summary> qu'aucune feuille n'a jamais dessine, des
       intitules .etiquette sans marge basse, et des champs poses nus, hors de
       tout .champ. Les dessiner ici repare le meme manque aux trois plutot
       que d'en laisser deux a moitie faites — mais club et competition
       appartiennent a d'autres familles : ce bloc gagnerait a etre remonte
       dans « socle », qui tient deja les champs.

   ──────────────────────────────── CE QUI APPARTIENT A UNE AUTRE FEUILLE ──
     · .carte, .bouton, .champ, .message, .tableau, .pastille : famille
       « socle », qui redessine les composants partages par TOUTES les pages.
       Mes pages les portent en nombre ; les redessiner ici en ferait deux
       versions pour une seule piece, et la mienne — assemblee en dernier —
       gagnerait par accident plutot que par decision.
     · Le bandeau des quatre pages LARGES (/regles, /carreau, /fanny,
       /legende) : voir « CE QUI RESTE HORS DE PORTEE », plus bas.

   ────────────────────────────────────── CE QUI EST NEUTRALISE, ET POURQUOI ──
   Une couche ne gagne QUE sur les proprietes qu'elle ECRIT — media queries
   comprises, qu'une couche posterieure bat sans avoir a les repeter. Quatre
   feuilles dessinent encore ces pages :
     · app.css (@layer composants/pages/utilitaires) — .etroit a 780px, le
       bandeau en aplat jaune, le tiret d'or devant chaque surtitre, le numero
       d'article en Inter 11 capitales, et un repli du bandeau sous 640px.
     · sable.css (@layer sable) — .enveloppe a 1160px, un titre de bandeau a
       clamp(3.2rem, 9vw, 7.4rem), la photo de boule en ::before a .14, une
       cascade d'entree sur chaque enfant du bandeau, et un bloc de
       declarations FORCEES sur le texte du bandeau (voir juste dessous).
     · eclat.css (@layer eclat) — la meme cascade d'entree, en 90/180/270ms,
       et une lueur d'or sur .carte-cerclee.
   Chaque regle ci-dessous reecrit donc explicitement fond, bordure, rayon,
   ombre, rembourrage, marge, caracteres et mouvement de l'ancienne.

   ──────────────────── LE SEUL LEVIER SUR CE QU'ON NE PEUT PAS BATTRE ──
   Ces huit vues portent 47 attributs style= en ligne, et sable.css verrouille
   le texte des bandeaux par des declarations forcees. Ni l'un ni l'autre ne
   se bat par une declaration normale : pour les declarations forcees la
   cascade INVERSE l'ordre des couches, et « tire » etant declaree en dernier
   elle y est la plus faible. Mais les deux lisent des PROPRIETES
   PERSONNALISEES — color: var(--bleu) en ligne, color: var(--encre-2) forcee
   — et une propriete personnalisee posee normalement par une couche
   posterieure, elle, l'emporte. Redefinir le jeton est donc le seul geste qui
   porte, et il a l'avantage de ne rien deplacer : on change la valeur, pas la
   mise en page.

   ──────────────────────── CE QUI RESTE HORS DE PORTEE, ET DOIT ETRE ARBITRE ──
     · /presentation ne peut pas etre atteinte d'ici : son gabarit est
       autonome (son propre <head>), il ne charge que polices.css et
       presentation.css, et presentation.css n'est enveloppee dans AUCUN
       @layer — donc elle passe devant toutes les couches, tire comprise.
     · Le bandeau des quatre pages larges : .banniere y est le meme element
       que sur 37 autres vues, sans rien qui distingue une page de texte d'une
       autre. Le borner ici reviendrait a l'imposer a tout le site.

   La couche « tire » est declaree EN DERNIER dans app.css (socle, composants,
   pages, utilitaires, eclat, sable, panneau, poste, tire) : elle passe devant
   toutes les autres sans qu'une seule declaration ait a etre forcee.
   ═══════════════════════════════════════════════════════════════════════════ */

@layer tire {

/* ───────────────────────────────────────────────── LA COLONNE DE LECTURE ──
   .etroit ne bornait plus rien. app.css lui donne 780px dans la couche
   « composants », sable.css donne 1160px a .enveloppe dans la couche
   « sable » : meme specificite d'une seule classe, couche posterieure, c'est
   le 1160 qui l'emportait. Les quatre pages etroites etaient larges depuis le
   jour ou sable est arrivee. Deux classes (0,2,0) tranchent la question.

   40rem, et pas davantage : rembourrage de la carte deduit, la ligne tombe
   entre 65 et 70 signes. Au-dela l'oeil perd le debut de la ligne suivante, et
   c'est precisement ici qu'on ne peut pas se permettre de faire relire un
   paragraphe deux fois. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) {
  max-width: 40rem;
}

/* Le bandeau prend la MEME mesure, sinon le titre et le texte qu'il annonce ne
   partagent plus de bord gauche : l'enveloppe du bandeau restait a 1160px
   (sable.css) pendant que la colonne descendait a 40rem, et comme les deux
   sont centrees par margin-inline:auto, l'ecart est nul sous 640px et s'ouvre
   d'autant plus que l'ecran est large — au point que « Conditions
   d'utilisation » commencait quatre centimetres a gauche de son premier
   paragraphe. */
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) > .enveloppe.etroit {
  max-width: 40rem;
}

/* Le site s'installe en PWA sur iPhone : en paysage, l'encoche mange la
   gouttiere du cote du capteur. max() retient la plus grande des trois
   mesures — il ne retire donc jamais rien a une vue qui n'est pas la mienne —
   et garantit au passage le retrait minimal de 16px a 390px. */
.banniere > .enveloppe.etroit,
.section-mince > .enveloppe.etroit {
  padding-inline: max(var(--gouttiere, 1rem),
                      env(safe-area-inset-left, 0px),
                      env(safe-area-inset-right, 0px));
}

/* ──────────────────────────────────── LES JETONS HERITES, REMIS SUR TIRE ──
   Le seul geste qui atteint les 47 style= en ligne et les declarations
   forcees de sable.css. Chaque ancien jeton retrouve ici son equivalent de
   ROLE dans le kit — on ne reaffecte pas un jeton, on le traduit :

     --bleu          l'encre d'accent des titres d'article   → l'encre
     --jaune         l'aplat d'or (le filet de 4px a gauche) → l'or plein
     --jaune-profond l'or QUI S'ECRIT                        → l'or lisible
     --rouge/--vert  les deux sens                           → les deux sens
     --lien          le lien dans le corps du texte          → l'or lisible
     --or-800        l'or du surtitre, verrouille par sable  → l'or lisible

   --jaune-profond et --lien tombent sur --tp-or-lisible et jamais sur
   --tp-or : l'or de la marque sur du blanc donne 1,9:1. L'or plein reste un
   FOND, ce qui est exactement l'usage qu'en fait --jaune ici (un filet, pas
   une lettre). */

.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) {
  --bleu:          var(--tp-encre);
  --jaune:         var(--tp-or);
  --jaune-profond: var(--tp-or-lisible);
  --or-800:        var(--tp-or-lisible);
  --encre:         var(--tp-encre);
  --encre-2:       var(--tp-encre-2);
}

.section-mince > .enveloppe.etroit:has(.carte :is(ul, ol).pile-2) {
  --bleu:          var(--tp-encre);
  --jaune:         var(--tp-or);
  --jaune-profond: var(--tp-or-lisible);
  --rouge:         var(--tp-rouge);
  --vert:          var(--tp-vert);
  --encre:         var(--tp-encre);
  --lien:          var(--tp-or-lisible);
  --lien-survol:   var(--tp-encre);
  /* --encre-2 porte ici .muet et .minus.muet, donc le ton EFFACE, alors que
     dans le bandeau il porte le chapo, qui est du vrai texte. Les deux rangs
     du kit sont distincts : on ne les confond pas. */
  --encre-2:       var(--tp-encre-3);
}

/* ───────────────────────────────────────────────────── LE BANDEAU DE TETE ──
   Un titre, un surtitre, une phrase. sable.css en faisait une affiche :
   clamp(3rem, 6vw, 5rem) de rembourrage haut pour trois lignes de texte, sur
   une page ou le contenu commence justement en dessous. */

.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) {
  position: relative;
  overflow: visible;
  background: none;
  border: 0;
  box-shadow: none;
  padding-block: 2rem 1.25rem;
}

/* La boule en filigrane a 14% et la cascade d'entree : deux decors qui ont
   leur place sur l'accueil et aucune ici. Une page qui se monte sous les yeux
   fait perdre plus de temps qu'elle n'en donne, et une photo derriere un
   texte de droits ajoute du bruit la ou il faut du calme. eclat.css et
   sable.css posent la MEME cascade a deux durees differentes : la seule facon
   de les eteindre toutes les deux est de reecrire animation sur l'enfant. */
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2)::before,
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2)::after {
  content: none;
}

.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) > .enveloppe > * {
  animation: none;
}

/* Playfair en CASSE NORMALE, a l'echelle du titre 1 du kit. sable.css montait
   jusqu'a 7,4rem de Big Shoulders condense : « Conditions d'utilisation » y
   tenait trois lignes de haut et se lisait comme une affiche de concours. */
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) h1 {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.125rem);
  line-height: 1.15;
  letter-spacing: -.01em;
  text-transform: none;
  text-shadow: none;
  text-wrap: balance;
}

/* L'intitule du kit se tient par son interlettrage, pas par un tiret. app.css
   puis sable.css dessinaient un trait d'or de 24 puis 22px devant chaque
   surtitre : c'etait la ponctuation de l'ancienne charte. Sa couleur vient du
   jeton --or-800 remis plus haut — sable la verrouille par une declaration
   forcee que rien d'autre ne peut atteindre. */
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) .surtitre {
  display: block;
  margin: 0 0 .5rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) .surtitre::before {
  content: none;
}

/* Le chapo : du texte courant, pas un sous-titre d'affiche. Sa couleur est
   elle aussi verrouillee par sable, et passe donc par --encre-2. */
.banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) .sous {
  margin: .5rem 0 0;
  font-family: var(--tp-texte);
  font-size: 15px;
  font-weight: 400;
  line-height: 1.6;
  max-width: 62ch;
}

/* ────────────────────────────────────────────────────── L'ARTICLE, LE TITRE ──
   Le titre de chaque article des conditions, de la confidentialite et des
   deux pages de suppression. Sa TAILLE est ecrite en ligne (1,5rem ou
   1,35rem) et ne peut donc pas etre reprise — mais les deux tombent dans la
   fourchette du titre 3 du kit (18 → 24px), il n'y a rien a y corriger. Sa
   COULEUR passe par --bleu, --rouge ou --jaune-profond, remis plus haut. Ce
   qui restait a faire, c'est la fonte : app.css les servait en Big Shoulders
   800, capitales comprises. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte > h2 {
  margin: 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -.01em;
  text-transform: none;
  text-wrap: balance;
}

/* ─────────────────────────────────────────────────── LE CORPS DE L'ARTICLE ──
   Inter 15/1.6, l'encre d'un cran en retrait du titre. La mesure est rappelee
   sur le paragraphe lui-meme : un <p> qui sort de la carte — le pied de page
   de l'editeur, par exemple — doit se borner tout seul. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte p {
  font-family: var(--tp-texte);
  font-size: 15px;
  line-height: 1.6;
  max-width: 68ch;
  color: var(--tp-encre-2);
}

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte p.petit { font-size: 13.5px; }
.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte p.minus { font-size: 12.5px; }

/* La page confidentialite ouvre chaque point par un <strong> qui NOMME le
   point (« Ce que vous saisissez — … »). Il doit se lire comme un intitule,
   donc prendre toute l'encre pendant que la phrase reste un cran derriere. */
.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte :is(p, li) strong {
  font-weight: 700;
  color: var(--tp-encre);
}

/* ──────────────────────────────────────────────────────── LES LISTES AEREES ──
   Le retrait et la marge des listes sont ecrits en ligne (margin:0 et
   padding-left:1,1 ou 1,2rem) : ils ne se reprennent pas, et ils n'ont pas a
   l'etre — 1,1rem est un retrait pendu correct a cette taille. Ce qui
   manquait, c'est l'air entre deux points : .pile-2 les serre a --r2, soit
   8px, et six affirmations juridiques collees les unes aux autres se lisent
   comme un seul paragraphe au lieu de six points distincts. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte :is(ul, ol).pile-2 {
  gap: .75rem;
  max-width: 68ch;
}

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte :is(ul, ol) > li {
  line-height: 1.6;
}

/* La puce et le numero prennent l'or : c'est le seul endroit de ces pages ou
   l'accent a quelque chose a faire, et il y INFORME — il compte. L'or lisible,
   jamais l'or plein : une puce est une lettre, pas un aplat. */
.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte :is(ul, ol) > li::marker {
  color: var(--tp-or-lisible);
  font-weight: 700;
}

/* Le mur des Fanny aligne deux listes numerotees — ceux qui l'ont donnee, ceux
   qui l'ont prise — sous un surtitre, hors de toute colonne etroite. Le motif
   « .surtitre suivi d'un <ol> dans une carte » ne se retrouve nulle part
   ailleurs sur le site : ni accueil.php ni admin/poules.php, les deux autres
   vues a poser un <ol> dans une carte, n'y repondent. */
.carte > .surtitre + ol > li::marker {
  color: var(--tp-or-lisible);
  font-weight: 700;
}

/* ───────────────────────────────────────────────────────── LA CARTE CERCLEE ──
   Trois feuilles lui dessinaient trois anneaux : app.css une bordure d'or de
   2px, sable.css un anneau INTERIEUR double d'une ombre portee, eclat.css une
   lueur d'or. Le kit dit qu'une carte doree est une carte avec un FILET d'or
   a gauche, jamais un contour : un contour entre en concurrence avec l'arete
   de la carte elle-meme, et l'or en aplat mangerait le texte. On reecrit donc
   les deux proprietes que les trois anciennes se partageaient, bordure ET
   ombre. Accueil et competition portent aussi .carte-cerclee, hors colonne
   etroite : elles gardent la leur. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) > .carte-cerclee {
  border: 1px solid color-mix(in oklab, var(--tp-or) 45%, var(--tp-trait));
  box-shadow: var(--tp-ombre), inset 3px 0 0 var(--tp-or);
}

/* ────────────────────────────────────────────────────── LE NUMERO D'ARTICLE ──
   Les conditions ouvrent chacun de leurs six articles par « 01 », « 02 »…
   dans un .etiquette — c'est-a-dire dans l'habillage d'un INTITULE : Inter 11
   capitales espacees. Un numero d'article n'est pas un intitule, c'est un
   repere ; il se pose en Playfair, a la taille ou on le voit du coin de
   l'oeil.

   ⚠️ Regle tenue SOUS la colonne de prose, et pas sur p.etiquette seul : les
   dix-sept autres <p class="etiquette"> du site sont de vrais intitules
   (« points retenus », « journees », « Pour WhatsApp, SMS, Messenger »), et
   les passer en Playfair dore les casserait tous. Aucune des cinq autres vues
   en colonne etroite ne porte .etiquette : la regle ne vise que conditions.

   Chiffres tabulaires : sans eux, 01 et 06 ne tombent pas sur le meme axe
   d'une carte a l'autre et la colonne des numeros ondule. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte > p.etiquette {
  margin: 0 0 .25rem;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: 20px;
  line-height: 1;
  letter-spacing: 0;
  text-transform: none;
  font-variant-numeric: tabular-nums;
  color: var(--tp-or-lisible);
}

/* ──────────────────────────────────────────── LE TIROIR « PROPOSER UN CARREAU » ──
   Aucune feuille n'a jamais dessine ce <summary> : il sortait en 12,5px avec
   le triangle du navigateur, haut de vingt pixels, sous une carte dessinee.
   C'etait le seul geste de la page, et le seul element du site sous la cible
   tactile de 44px. Il prend le dessin de la puce du kit.

   Vise par :has(> form.carte), la signature du tiroir : un summary suivi d'un
   formulaire en carte, en enfant direct. Trois vues y repondent — carreau,
   club et competition — et pas une de plus : les tiroirs du site qui n'ouvrent
   pas sur un formulaire en carte gardent le leur. */

details:has(> form.carte) > summary {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  min-height: 44px;
  padding: 0 .9375rem;
  border: 1px solid var(--tp-trait);
  border-radius: var(--tp-r-pilule);
  background: var(--tp-carte);
  color: var(--tp-encre-2);
  font-family: var(--tp-texte);
  font-weight: 600;
  font-size: 14px;
  list-style: none;
  cursor: pointer;
  transition: border-color var(--tp-elan), background var(--tp-elan);
}

/* Les deux ecritures du marqueur : WebKit garde la sienne malgre list-style. */
details:has(> form.carte) > summary::-webkit-details-marker { display: none; }
details:has(> form.carte) > summary::marker { content: ""; }

details:has(> form.carte) > summary:hover {
  border-color: var(--tp-trait-fort);
  background: color-mix(in oklab, var(--tp-creux) 45%, transparent);
}

details:has(> form.carte)[open] > summary {
  border-color: var(--tp-trait-fort);
  margin-bottom: .25rem;
}

/* L'intitule des champs du tiroir. Il etait en ligne et sans marge basse :
   l'intitule touchait son champ et on ne voyait plus lequel allait avec
   lequel. suivre.php porte le meme defaut hors d'un tiroir ; il reste a sa
   famille, faute d'un motif qui l'y rattache. */
details > form.carte label.etiquette {
  display: block;
  margin: 0 0 .375rem;
  font-family: var(--tp-texte);
  font-weight: 700;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--tp-encre-3);
}

/* Les champs sont poses NUS, hors de tout .champ : aucune feuille ne les
   habillait et ils rendaient en champs bruts du navigateur — vingt et un
   pixels de haut, au milieu d'une carte dessinee. Ils prennent le dessin du
   champ du kit, anneau de focus compris : un champ dont on ne sait pas qu'il a
   le curseur est un formulaire qu'on remplit deux fois.

   Les quatre types sont nommes un par un, et c'est deliberé : la fiche
   pratique du club pose dans le MEME formulaire une case a cocher, un bouton
   radio et un choix de fichier. Un selecteur sur « input » les prendrait tous
   et leur collerait une boite de 48px. N'habiller que text et number aurait
   laisse ce formulaire-la a moitie fait — trois champs dessines, deux bruts,
   ce qui se voit plus que si l'on n'y avait pas touche. */
details > form.carte input[type="number"],
details > form.carte input[type="text"],
details > form.carte input[type="url"],
details > form.carte textarea {
  width: 100%;
  min-height: 48px;
  padding: .75rem .875rem;
  background: var(--tp-carte);
  border: 1px solid var(--tp-trait-fort);
  border-radius: var(--tp-r-champ);
  font-family: var(--tp-texte);
  font-size: 15px;
  color: var(--tp-encre);
  transition: border-color var(--tp-elan), box-shadow var(--tp-elan);
}

details > form.carte :is(input, textarea)::placeholder { color: var(--tp-encre-4); }

details > form.carte input[type="number"]:focus,
details > form.carte input[type="text"]:focus,
details > form.carte input[type="url"]:focus,
details > form.carte textarea:focus {
  outline: none;
  border-color: var(--tp-or);
  box-shadow: 0 0 0 3px rgb(245 180 28 / .28);
}

/* ────────────────────────────────────────────────────── LE CHIFFRE DE LEGENDE ──
   Les chapitres de « Ma Legende » posent un grand chiffre par carte. app.css
   le servait en Big Shoulders 900 ; il passe en Playfair, et en chiffres
   tabulaires — trois cartes cote a cote dont les chiffres ne tombent pas sur
   le meme axe se lisent comme trois cartes mal posees.

   Tenu sous .grille-3 > .carte : le resume du soir pose son chiffre dans un
   <div> nu et le poste dans une .adm-carte, ni l'un ni l'autre n'est pris. */

.grille-3 > .carte > .chiffre.chiffre-xl {
  margin: .25rem 0 0;
  font-family: var(--tp-titre);
  font-weight: 700;
  font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem);
  line-height: 1.05;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
}

/* Le jeton, lui, est pose sur TOUS les chiffres-xl et sur la place de podium
   des tableaux : c'est le seul moyen d'atteindre les style= en ligne qui
   ecrivent color:var(--jaune-profond), et une propriete personnalisee se lit
   sur l'element ou sur un de ses ancetres. On ne pose qu'un jeton — aucune
   mise en page n'est touchee, et l'or redevient lisible partout ou il
   s'ecrit. */
.chiffre.chiffre-xl,
.tableau td.nombre strong {
  --jaune-profond: var(--tp-or-lisible);
}

/* ────────────────────────────────────────────────── L'ENCART D'AVERTISSEMENT ──
   Le rappel de bas de page des regles : « ce resume ne remplace pas le
   reglement officiel ». tire.css dessine .message et ses tons succes et
   erreur, mais le ton INFO n'y a jamais ete repris : sa regle .message
   l'emportant sur le .message-info de app.css — meme specificite, couche
   posterieure — le message retombait sur le fond neutre du kit et perdait le
   duo texte + fond, seul moyen de tenir un etat lisible a 14px.

   ⚠️ Cette regle repare une omission du KIT, pas une page : les dix vues qui
   portent .message-info en profitent. Sa vraie place est dans tire.css, aux
   cotes de .tp-message--info dont elle reprend exactement les deux valeurs ;
   elle est ici faute d'y etre. A remonter d'un cran a l'occasion. */

.message.message-info {
  border: 0;
  border-radius: var(--tp-r-champ);
  background: var(--tp-ambre-fond);
  color: var(--tp-ambre);
  box-shadow: none;
  animation: none;
}

/* ─────────────────────────────────────────────────────────── LE FOCUS CLAVIER ──
   La meme regle que le kit, etendue aux trois pieces que cette feuille est
   seule a dessiner. L'anneau or et son halo, au clavier seulement. */

.enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte a:focus-visible,
details:has(> form.carte) > summary:focus-visible,
details > form.carte :is(input, textarea):focus-visible {
  outline: 2px solid var(--tp-or);
  outline-offset: 2px;
}

/* ───────────────────────────────────────────────── LE MOUVEMENT, EN MOINS ──
   Qui demande moins d'animation la coupe entierement : pas de « version
   allegee » qui bouge quand meme. On reprend ici les transitions posees plus
   haut ET les animations d'entree de eclat.css et sable.css. */

@media (prefers-reduced-motion: reduce) {
  .banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) > .enveloppe > *,
  .message.message-info {
    animation: none;
  }

  details:has(> form.carte) > summary,
  details > form.carte input[type="number"],
  details > form.carte input[type="text"],
  details > form.carte input[type="url"],
  details > form.carte textarea {
    transition: none;
  }
}

/* ──────────────────────────────────────────────────────────── LE TELEPHONE ──
   390px de large, encoche comprise. app.css repliait le bandeau sur --r5 sous
   640px : la mesure appartenait a l'affiche, pas a la page de texte. Sous
   26rem on resserre le bandeau et on rend au texte un peu de l'air des
   listes — a cette largeur, six points aeres a 12px poussent la fin de
   l'article trois ecrans plus bas. */

@media (max-width: 26rem) {
  .banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) {
    padding-block: 1.5rem 1rem;
  }

  .banniere:has(> .enveloppe.etroit):has(+ .section-mince .carte :is(ul, ol).pile-2) .sous {
    font-size: 14.5px;
  }

  .enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte :is(ul, ol).pile-2 {
    gap: .625rem;
  }

  .enveloppe.etroit:has(.carte :is(ul, ol).pile-2) .carte > p.etiquette {
    font-size: 18px;
  }
}

} /* @layer tire */

