/* =====================================================================================
 *  HABILLAGE DU MATCH 2D — feuille dediee
 *  -------------------------------------------------------------------------------------
 *  Cette feuille existe pour une raison de METHODE : le style du match vit ici et nulle
 *  part ailleurs, pour qu'il puisse etre retravaille sans toucher a public/index.html,
 *  ou vivent toutes les autres pages du jeu. Elle est chargee APRES le style en ligne,
 *  donc elle gagne a specificite egale.
 * ================================================================================== */

/* =====================================================================================
 *  LE JETON — DISQUE PLAT, ANNEAU BLANC, NUMERO AU CENTRE
 *  -------------------------------------------------------------------------------------
 *  LE CONSTAT, capture a l'appui. Le pion cumulait six couches : un degrade lineaire
 *  entre deux couleurs de club, un reflet interne en haut, une occlusion en bas, deux
 *  appuis sombres devant, un liseré fonce, et par-dessus le tout un ANNEAU EXTERIEUR
 *  pose a inset -12 %. Mesure a l'ecran : pour un `--pj` de 19 px, le jeton occupait
 *  27,6 px, soit 3,4 % de la surface de jeu (813 px de large sur cet ecran).
 *  Trois consequences, toutes visibles :
 *    · le jeton depassait de 36 % la taille voulue — les vingt-deux se touchaient
 *      des qu'une melee se formait ;
 *    · le rapport ballon/jeton s'en trouvait fausse : `--balle` est regle a 26 % de
 *      `--pj`, mais le jeton REEL faisait 145 % de `--pj` ;
 *    · le degrade + les deux ombres internes ecrasaient la couleur du club vers le
 *      sombre : a cette taille, deux maillots de teintes voisines devenaient la meme
 *      tache brune.
 *
 *  LA REGLE RETENUE (le match view demande en reference) : un disque PARFAITEMENT ROND
 *  ET PLAT, d'une seule couleur, cercle d'un anneau blanc net, le numero au centre, et
 *  une ombre portee DOUCE dessous. Pas de perspective, pas de corps en trois quarts.
 *
 *  ⚠️ `box-sizing:border-box` N'EST PAS UN DETAIL. Il fait de `--pj` le diametre TOTAL
 *  du jeton, anneau compris. Sans lui, l'anneau s'ajouterait au diametre et on
 *  retomberait exactement sur le defaut qu'on corrige. Les huit paliers d'ecran de
 *  index.html ne bougent pas d'un pixel : c'est la definition de `--pj` qui devient
 *  enfin celle qu'ils supposaient. Le ballon retrouve du meme coup ses 26 %.
 *  Resultat mesure : 19 px de jeton pour 813 px de surface de jeu, soit 2,34 % —
 *  la cible etait 2,5 %, et le jeton perd 31 % de son encombrement precedent.
 * ================================================================================== */

/* LE DISQUE EST CENTRE SUR LA POSITION DU JOUEUR.
   Il etait dessine au-dessus d'elle (top: -0,875 x --pj), reste d'une epoque ou le
   pion representait un corps DEBOUT dont les pieds tenaient le point d'ancrage. Vu de
   dessus, ca n'a plus de sens : un joueur est a l'endroit ou il est, et l'ombre du
   ballon comme celle des poteaux tombent, elles, sur le sol. Le decalage faisait que
   le porteur semblait toujours avoir le ballon dans les talons. */
.pitch2d .pj-corps{
  box-sizing:border-box;
  left:calc(var(--pj) / -2); top:calc(var(--pj) / -2);
  width:var(--pj); height:var(--pj);
  border-radius:50%;
  /* LE REMPLISSAGE : LA PREMIERE COULEUR DU CLUB, ET ELLE SEULE.
     Le degrade ne melange PAS les deux couleurs — c'est exactement ce que faisait
     l'ancien pion, et c'est ce qui tirait tout vers le brun. Il ne fait varier que
     la CLARTE de la couleur principale : 23-rendu.js calcule les deux bouts en
     tirant vers le blanc (haut) et en multipliant (bas), une operation qui ne
     deplace pas la teinte d'un degre. Amplitude courte, environ six centiemes de
     clarte de chaque cote : de quoi poser une lumiere venue du haut, pas de quoi
     refaire un pion en relief.
     ⚠️ LE MILIEU DU DISQUE VAUT EXACTEMENT --jeton (arret a 52 %), parce que c'est
     la qu'est ecrit le numero : c'est cette valeur-la que _encreLisible a jugee. */
  background:linear-gradient(180deg,
             var(--jeton-haut, var(--jeton, #4aa8ff)) 0%,
             var(--jeton, #4aa8ff) 52%,
             var(--jeton-bas, var(--jeton, #4aa8ff)) 100%);
  /* L'ANNEAU : LA SECONDE COULEUR DU CLUB. Il etait blanc pour tout le monde ;
     porte par le liseré du club, il rend chaque equipe reconnaissable sans toucher
     au remplissage — Paris bleu nuit cercle de rouge, Lens jaune cercle de grenat,
     Barcelone grenat cercle de bleu. Le blanc reste la valeur de repli, et reste la
     vraie couleur des 189 clubs dont la seconde couleur EST le blanc.
     Net, 2 a 3 px selon l'ecran — jamais moins de 2, sinon il
     disparait sur la pelouse des que le jeton bouge.
     Mesure a l'ecran : Chrome ARRONDIT une largeur de bordure au pixel entier. La
     formule donne 2,47 px pour un jeton de 19 et 3,5 px pour un jeton de 27 ; on
     obtient donc 2 px sur un ecran courant et 3 px sur un grand. C'est exactement
     la fourchette voulue, mais il ne sert a rien de chercher le demi-pixel ici. */
  border-style:solid; border-color:var(--anneau, #ffffff);
  border-width:max(2px, calc(var(--pj) * 0.13));
  /* L'OMBRE PORTEE. Diffuse et posee SOUS le disque : c'est elle, et elle seule, qui
     donne le poids. L'ancienne ellipse dessinee (.pj-ombre) est retiree plus bas —
     une tache noire de forme fixe se detachait du pion des que la meteo la decalait. */
  /* Le filet d'1 px en tete de liste n'est pas decoratif : il est ce qui DETACHE le
     jeton du gazon. Mesure a l'ecran sur Monaco - Rodez : des jetons blancs poses sur
     la bande de tonte claire n'avaient rien pour les decouper. Il ne peut plus etre
     sombre pour tout le monde maintenant que l'anneau porte la couleur du club :
     187 des 379 clubs ont une seconde couleur FONCEE, et un cheveu sombre autour
     d'un anneau sombre ne detache rien. 23-rendu.js (_filetContour) lui donne donc
     la polarite inverse de l'anneau. Meme epaisseur qu'avant : le jeton ne grossit
     pas d'un pixel. */
  box-shadow:0 0 0 1px var(--filet, #0000002e),
             0 calc(var(--pj) * 0.10) calc(var(--pj) * 0.22) #00000073;
  transition:none}

/* CE QU'ON SUPPRIME, ET POURQUOI.
   · .pj-ombre     : ellipse dessinee, remplacee par l'ombre portee ci-dessus ;
   · .pj-corps::before : les deux appuis « pieds » — ils donnaient l'orientation, mais
     ils cassent le disque parfait demande, et a 19 px ils ne mesuraient que 1,7 px ;
   · .pj-corps::after  : l'anneau exterieur, celui qui gonflait le jeton de 36 %. */
.pitch2d .pj-ombre{display:none}
.pitch2d .pj-corps::before{display:none}
.pitch2d .pj-corps::after{display:none}

/* LE NUMERO. Il occupe tout le disque et se centre dessus, comme le corps.
   Sa COULEUR n'est plus fixe : 23-rendu.js la deduit de la clarte du maillot (voir
   _encreLisible). Un maillot blanc porte donc un chiffre bleu nuit, un maillot bleu
   un chiffre blanc — c'est ce contraste qui rend le numero lisible, pas un contour.
   L'ancien contour sombre sur les quatre cotes est retire : il empatait le chiffre
   et le rendait gras au point d'etre illisible en dessous de 9 px. */
.pitch2d .pj-num{
  left:calc(var(--pj) / -2); top:calc(var(--pj) / -2);
  width:var(--pj); height:var(--pj); line-height:var(--pj);
  font-family:system-ui,'Segoe UI',Arial,sans-serif;
  font-size:var(--pj-num); font-weight:800; letter-spacing:-0.01em;
  text-shadow:none}

/* LE GARDIEN A LA MEME TAILLE QUE LES AUTRES. Il etait dessine a 94 % — un ecart
   qu'on ne percoit pas, mais qui suffisait a decaler son anneau. Ce qui le distingue,
   c'est sa COULEUR (vert, des deux cotes, voir 23-rendu.js), pas son diametre. */
.pitch2d .pj.gk .pj-corps{
  left:calc(var(--pj) / -2); top:calc(var(--pj) / -2);
  width:var(--pj); height:var(--pj); border-color:#ffffff}

/* L'ARBITRE : DISQUE NOIR, LETTRE BLANCHE.
   Il portait le jaune, ce qui est juste sur un vrai terrain mais faux ici : le jaune
   est aussi une couleur de club, et un rond jaune de plus au milieu de vingt-deux
   ronds colores se compte comme un joueur. Le noir marque d'un « R » ne se confond
   avec rien — c'est le seul jeton du terrain qui ne porte pas de chiffre. */
.pitch2d .pj.arb .pj-corps{
  left:calc(var(--pj) / -2); top:calc(var(--pj) / -2);
  width:var(--pj); height:var(--pj);
  background:#14171d; border-color:#ffffff;
  box-shadow:0 0 0 1px #0000002e,
             0 calc(var(--pj) * 0.10) calc(var(--pj) * 0.22) #00000073}
.pitch2d .pj.arb .pj-num{color:#ffffff;font-weight:800}
/* Les assistants restent sur la ligne de touche et ne portent pas de lettre : deux
   « R » de plus donneraient trois arbitres a chercher. Ils sont plus petits et plus
   gris — presents, mais jamais confondus avec l'homme au sifflet. */
.pitch2d .pj.arb.assist .pj-corps{
  width:calc(var(--pj) * 0.78); height:calc(var(--pj) * 0.78);
  left:calc(var(--pj) * -0.39); top:calc(var(--pj) * -0.39);
  background:#2b303a; border-color:#ffffffcc}

/* ⚠️ LE DRAPEAU SUIVAIT UN JETON QUI N'EXISTE PLUS. Il etait pose a top:-26px, mesure
   sur le pion dessine AU-DESSUS de son ancrage. Le jeton est maintenant centre : le
   drapeau flottait a une demi-hauteur de disque au-dessus de l'assistant. Il repart du
   bord haut du disque, exprime en --pj comme tout ce qui est dessine sur la pelouse. */
.pitch2d .m2d-drapeau{left:calc(var(--pj) * -0.05);top:calc(var(--pj) * -0.5 - 13px)}

/* LE SPRINT. index.html remplacait toute l'ombre du jeton par un halo blanc lateral :
   pose sur un disque deja cercle de blanc, ce halo bavait sur l'anneau et le joueur
   semblait flou. On garde l'ombre portee et on ajoute une trainee sombre du cote
   oppose a la course — discrete, elle ne se lit qu'en mouvement. */
.pitch2d .pj.sprint .pj-corps{
  box-shadow:0 0 0 1px var(--filet, #0000002e),
             0 calc(var(--pj) * 0.10) calc(var(--pj) * 0.22) #00000073,
             calc(var(--pj) * -0.26) 0 calc(var(--pj) * 0.30) #00000059}

/* =====================================================================================
 *  LE NOM DU PORTEUR
 *  -------------------------------------------------------------------------------------
 *  Le terrain n'affichait AUCUN nom : vingt-deux chiffres, et rien qui dise qui tient
 *  le ballon. Le fil de commentaire le nommait, mais deux ou trois secondes plus tard —
 *  quand le geste etait deja fait. Un seul nom a la fois, celui du porteur, sous son
 *  jeton : c'est ce qui permet de suivre une action sans quitter le terrain des yeux.
 *
 *  Le nom est un ENFANT du jeton, donc la transform du jeton l'emmene : rien a
 *  repositionner par image. 23-rendu.js ne fait que poser la classe `porte` quand le
 *  ballon change de mains — deux ecritures de classe, jamais par image.
 *  L'ombre portee du texte n'est pas decorative : un texte blanc sur une bande de tonte
 *  claire disparait purement et simplement.
 * ================================================================================== */
.pitch2d .pj-nom{
  position:absolute;
  left:calc(var(--pj) * -3.5); top:calc(var(--pj) * 0.60);
  width:calc(var(--pj) * 7); text-align:center;
  font-family:system-ui,'Segoe UI',Arial,sans-serif;
  font-size:max(7.5px, calc(var(--pj) * 0.52)); font-weight:700; letter-spacing:.02em;
  color:#ffffff; white-space:nowrap; pointer-events:none;
  text-shadow:0 1px 2px #000000d9, 0 0 4px #000000a6;
  opacity:0; transition:opacity .12s linear}
.pitch2d .pj.porte .pj-nom{opacity:1}

/* =====================================================================================
 *  LE FILE DU BALLON — HUIT POINTS QUI S'EFFACENT
 *  -------------------------------------------------------------------------------------
 *  La mecanique est dans 23-rendu.js (filerBallon) ; ici il n'y a que le TON.
 *  Deux regles de dessin, et une seule raison derriere les deux : ce file doit se lire
 *  SANS se voir.
 *
 *  1. IL EST BLANC, ET RIEN D'AUTRE. Le ballon est blanc, la trainee d'un objet blanc
 *     est blanche. Une couleur — la moindre teinte chaude, le moindre halo — ferait de
 *     la vitesse une DECORATION, alors qu'on veut seulement prolonger le ballon. Le
 *     rendu vient d'etre refait dans l'esprit du match view de reference : jetons plats,
 *     traces a 68 % d'opacite, aucun effet lumineux nulle part. Une comete y serait le
 *     seul objet brillant de l'image, donc le premier que l'oeil irait chercher.
 *
 *  2. LE PLUS PROCHE PLAFONNE A 42 % D'OPACITE, ET LES SUIVANTS FONDENT VITE. L'ancienne
 *     trainee etait un disque de 6 px a #ffffff99 (60 %) FLOUTE de 2 px — plus large que
 *     le ballon lui-meme (5,1 a 6,1 px selon l'ecran) et presque aussi dense. Elle
 *     concurrencait le ballon au lieu de le prolonger. Ici le premier fantome fait 95 %
 *     du diametre du ballon et le dernier 45 % : le file s'affine ET palit, ce qui donne
 *     le sens de la marche sans qu'aucune fleche ne soit dessinee.
 *     ⚠️ LA DECROISSANCE DE TAILLE EST VOLONTAIREMENT MOLLE. Elle descendait a 29 %, et
 *     sur la frappe la plus rapide — celle ou les fantomes sont le plus espaces, 2,7 px
 *     a la vitesse maximale du moteur — la queue se resolvait en CHAPELET : douze petits
 *     points detaches au lieu d'un file. Le dernier fantome doit rester au moins aussi
 *     large que l'ecart entre deux, sinon des trous apparaissent exactement dans le cas
 *     qu'on cherchait a rendre lisible. C'est l'OPACITE qui porte l'effacement.
 *     Et ces valeurs sont un PLAFOND : elles sont multipliees par l'opacite de
 *     l'enveloppe, que 23-rendu.js pilote a la vitesse. Une passe courte n'en montre
 *     qu'un sixieme.
 *
 *  Le flou est obtenu par un degrade radial qui s'eteint sur le bord, PAS par `filter:
 *  blur()` : un filtre est une passe de rendu supplementaire par element, soit huit par
 *  image ici, pour un resultat que le degrade donne gratuitement.
 *  Les tailles sont exprimees en `--balle` : le file suit le ballon quand le proprietaire
 *  en rechange le diametre, et il suit les huit paliers d'ecran de index.html.
 * ================================================================================== */
.pitch2d .m2d-file{
  position:absolute;left:0;top:0;width:0;height:0;
  z-index:8;pointer-events:none;opacity:0}
/* ⚠️ LE COEUR DU DEGRADE A ETE ELARGI APRES MESURE A L'ECRAN. Il s'eteignait des
   38 % du rayon : la surface reellement blanche ne faisait alors qu'un septieme du
   disque, et a la taille reelle du ballon — cinq a six pixels — le file disparaissait
   purement et simplement. Vu a la loupe il etait parfait ; vu a 100 %, il n'existait
   pas. Le blanc tient maintenant jusqu'a la moitie du rayon avant de s'eteindre :
   la MEME opacite couvre deux fois plus de pixels, ce qui rend le file lisible sans
   qu'aucun de ses points ne soit plus brillant qu'avant. */
.pitch2d .m2d-file i{
  position:absolute;display:block;border-radius:50%;
  background:radial-gradient(circle,#ffffff 0 50%,#ffffff00 100%);
  will-change:transform;transition:none}
/* Le rang 1 est le plus proche du ballon, le rang 12 le plus ancien (144 ms derriere).
   ⚠️ LE NOMBRE DE RANGS EST FIXE PAR 23-rendu.js (FILE_N) : douze elements sont crees,
   donc douze regles. Un rang de plus dans le moteur sans sa regle ici retomberait sur
   la regle generique — un point a taille nulle, invisible : le file paraitrait
   simplement plus court, sans aucune erreur pour le signaler. */
.pitch2d .m2d-file i:nth-child(1){width:calc(var(--balle) * .95);height:calc(var(--balle) * .95);left:calc(var(--balle) * -.475);top:calc(var(--balle) * -.475);opacity:.42}
.pitch2d .m2d-file i:nth-child(2){width:calc(var(--balle) * .9);height:calc(var(--balle) * .9);left:calc(var(--balle) * -.450);top:calc(var(--balle) * -.450);opacity:.37}
.pitch2d .m2d-file i:nth-child(3){width:calc(var(--balle) * .85);height:calc(var(--balle) * .85);left:calc(var(--balle) * -.425);top:calc(var(--balle) * -.425);opacity:.33}
.pitch2d .m2d-file i:nth-child(4){width:calc(var(--balle) * .8);height:calc(var(--balle) * .8);left:calc(var(--balle) * -.400);top:calc(var(--balle) * -.400);opacity:.29}
.pitch2d .m2d-file i:nth-child(5){width:calc(var(--balle) * .75);height:calc(var(--balle) * .75);left:calc(var(--balle) * -.375);top:calc(var(--balle) * -.375);opacity:.25}
.pitch2d .m2d-file i:nth-child(6){width:calc(var(--balle) * .7);height:calc(var(--balle) * .7);left:calc(var(--balle) * -.350);top:calc(var(--balle) * -.350);opacity:.21}
.pitch2d .m2d-file i:nth-child(7){width:calc(var(--balle) * .65);height:calc(var(--balle) * .65);left:calc(var(--balle) * -.325);top:calc(var(--balle) * -.325);opacity:.175}
.pitch2d .m2d-file i:nth-child(8){width:calc(var(--balle) * .61);height:calc(var(--balle) * .61);left:calc(var(--balle) * -.305);top:calc(var(--balle) * -.305);opacity:.14}
.pitch2d .m2d-file i:nth-child(9){width:calc(var(--balle) * .57);height:calc(var(--balle) * .57);left:calc(var(--balle) * -.285);top:calc(var(--balle) * -.285);opacity:.11}
.pitch2d .m2d-file i:nth-child(10){width:calc(var(--balle) * .53);height:calc(var(--balle) * .53);left:calc(var(--balle) * -.265);top:calc(var(--balle) * -.265);opacity:.085}
.pitch2d .m2d-file i:nth-child(11){width:calc(var(--balle) * .49);height:calc(var(--balle) * .49);left:calc(var(--balle) * -.245);top:calc(var(--balle) * -.245);opacity:.06}
.pitch2d .m2d-file i:nth-child(12){width:calc(var(--balle) * .45);height:calc(var(--balle) * .45);left:calc(var(--balle) * -.225);top:calc(var(--balle) * -.225);opacity:.04}

/* =====================================================================================
 *  LES TRACES — FINS ET LEGEREMENT TRANSPARENTS
 *  -------------------------------------------------------------------------------------
 *  Ils etaient a 2,4 unites SVG d'epaisseur pour une opacite de 0,88 : sur un repere de
 *  1000 x 500, cela fait un trait de 24 cm peint en blanc franc. Une ligne de terrain
 *  est un ruban de chaux de douze centimetres, deja terni par une mi-temps de jeu — et
 *  a l'ecran, un trait epais et opaque attire l'oeil autant que les joueurs.
 *  L'epaisseur est posee ici plutot que dans 10-terrain.js, qui n'est pas de mon
 *  perimetre ; le CSS l'emporte de toute facon sur l'attribut de presentation SVG.
 * ================================================================================== */
.pitch2d .m2d-traces .m2d-lignes{stroke-width:1.7;opacity:.68}

/* =====================================================================================
 *  LES FILETS SUIVENT LA PELOUSE — RECALAGE DU FORMAT PANORAMIQUE
 *  -------------------------------------------------------------------------------------
 *  Le cadre de match est passe au format televise (~1,90:1) et la surface de jeu avec
 *  lui : left 7 % / width 86 % / top 7,5 % / height 66 %  devient
 *          left 8 % / width 84 % / top 7,5 % / height 72 %   (voir index.html, :root).
 *  Or 11b-filets.js ECRIT L'ANCIENNE BOITE EN STYLE INLINE (creerFiletsDOM) : sans ce
 *  recalage, les filets restent a 66 % de hauteur pendant que les cages descendent a
 *  72 %, et le ballon entre dans un but dont le filet flotte plus haut.
 *  Ce fichier n'a qu'un moyen de battre un style inline : `!important`. Il n'est pas la
 *  par confort — 11b-filets.js n'est pas de mon perimetre.
 *
 *  Les chiffres : le filet deborde de FILET_VUE.MARGE = 8 unites de terrain de chaque
 *  cote, et une unite vaut desormais 84/100 = 0,84 % du cadre (contre 0,86 % avant).
 *      debord = 8 x 0,84 = 6,72 %   ->   left  = 8 - 6,72   = 1,28 %
 *                                       width = 84 + 13,44 = 97,44 %
 *  A refaire si --m2d-jeu-w ou --m2d-format changent.
 * ================================================================================== */
.pitch2d .m2d-filets{
  left:1.28%!important; width:97.44%!important;
  top:var(--m2d-jeu-y,7.5%)!important; height:var(--m2d-jeu-h,72%)!important}

/* =====================================================================================
 *  UNE MAILLE QU'ON PEUT VOIR BOUGER
 *  -------------------------------------------------------------------------------------
 *  ⚠️ LE FILET ETAIT TRACE EN DESSOUS DU PIXEL. 11b-filets.js pose ses fils a
 *  stroke-width 0,9 dans un repere de 1 160 unites etale sur 883 px : cela fait
 *  0,9 x 0,761 = 0,68 PIXEL de trait, a 42 % d'opacite. A titre de comparaison, une
 *  ligne de terrain fait 1,29 px a 68 %. Le filet etait donc deux fois plus fin et
 *  moitie moins present qu'un trace de pelouse — a l'ecran, une buee grise de
 *  37 x 60 px derriere la ligne de but. Un filet qu'on ne distingue pas ne peut pas
 *  avoir l'air de bouger, quelle que soit la physique derriere.
 *  On le remonte au niveau d'une ligne de terrain, pas au-dessus : 1,5 x 0,761 =
 *  1,14 px a 55 %. Le cadre arriere, lui, doit dire ou la cage s'arrete.
 *  (Le CSS l'emporte sur l'attribut de presentation SVG : rien a changer dans le JS.)
 * ================================================================================== */
.pitch2d .m2d-filets .m2d-maille{stroke-width:1.5;stroke-opacity:.55}
.pitch2d .m2d-filets .m2d-cadre-arriere{stroke-width:2.2;stroke-opacity:.9}

/* ==================================================================================
 *  LE VOILE QUI RACONTE — 19/08/2026
 *  ----------------------------------------------------------------------------------
 *  Demande du proprietaire : « quand y'a des actions en match, cache la 2D, mets-la en
 *  flou et commente l'action par-dessus, car la 2D n'est pas au point. »
 *  Le voile existait deja (`REAL.voileEntreButs`, eteint depuis) et floutait bien le
 *  terrain, mais il n'affichait qu'un libelle fixe, « Match en cours », avec un
 *  sablier : on regardait une ATTENTE pendant que le match se jouait derriere. Il
 *  porte desormais la derniere ligne du compte-rendu, avec sa minute.
 *
 *  Ces regles sont ici et non dans index.html a dessein : elles appartiennent au
 *  moteur 2D, comme le reste de ce fichier, et la feuille est chargee apres — ce qui
 *  leur permet de completer les regles de base sans avoir a les reecrire.
 * ================================================================================== */

/* Le libelle devient une PHRASE : il lui faut de la place et une largeur de lecture.
   A 22 px et `letter-spacing:1px`, une ligne de compte-rendu debordait du terrain. */
.m2d-voile b{font-size:17px;letter-spacing:.2px;line-height:1.35;max-width:min(86%,560px);
             text-align:center;text-wrap:balance}
/* Un but merite d'etre lu plus fort que « corner pour Monaco ». */
.m2d-voile-fort b{font-size:23px;color:var(--gold);letter-spacing:.6px}

/* La minute, au-dessus de la phrase. Elle ancre le commentaire dans le match :
   sans elle, on lit des actions sans savoir ou l'on en est. */
.m2d-voile-min{font-size:12px;font-weight:800;letter-spacing:2px;color:var(--gold);
               opacity:.85;min-height:14px;text-shadow:0 2px 10px #000}

/* ⚠️ PLUS DE SABLIER. Il disait « patiente » — ce qui etait vrai quand les 90 minutes
   defilaient en 5,6 s derriere le voile, et qui est faux maintenant que le match se
   raconte ligne a ligne. Un sablier qui tourne pendant qu'on lit donne l'impression
   que le jeu est bloque. */
.m2d-voile i{display:none}

/* L'apparition d'une ligne : elle monte et se pose. Assez courte pour ne pas trainer
   sur la suivante — le moteur rend une ligne toutes les 4 s environ. */
@keyframes m2dVoileNeuf{0%{opacity:0;transform:translateY(7px)}100%{opacity:1;transform:translateY(0)}}
.m2d-voile b.m2d-voile-neuf{animation:m2dVoileNeuf .34s cubic-bezier(.2,.9,.3,1)}

/* Le flou monte de 6 a 9 px : a 6 px on reconnaissait encore les joueurs, et l'oeil
   revenait sans cesse au terrain au lieu de lire. Le fond s'assombrit un peu pour que
   le texte tienne par-dessus n'importe quelle phase de jeu. */
.pitch2d.m2d-flou .m2d-traces,.pitch2d.m2d-flou .m2d-couche{filter:blur(9px) saturate(.75)}
.m2d-voile{background:radial-gradient(ellipse at center,rgba(6,10,26,.62),rgba(6,10,26,.86))}

/* ==================================================================================
 *  LA RETRANSMISSION — 14/09/2026
 *  ----------------------------------------------------------------------------------
 *  Demande du president : « faut que le jeu soit beau comme Football Manager ».
 *  Quatre pieces, chacune dans son fichier JS (27-camera, 28-ralenti, 29-habillage-tv),
 *  et tout leur style ici :
 *    · l'ENVELOPPE DE CAMERA, qui porte le zoom et le suivi ;
 *    · le SCORE INCRUSTE en haut a gauche, comme a la television ;
 *    · le BANDEAU DE BUT au bas de l'image, qui remplace la banniere plein cadre ;
 *    · le RALENTI : bandes noires, pastille rouge, et les flashs des photographes.
 *  Rien de tout cela n'est anime par image en JavaScript : des classes, des keyframes.
 * ================================================================================== */

/* L'enveloppe reprend exactement la boite du cadre : tout ce qui y etait positionne en
   pourcentage du cadre retombe au meme pixel. L'origine en haut a gauche est celle que
   27-camera.js suppose dans son calcul. */
.pitch2d .m2d-camera{position:absolute;inset:0;transform-origin:0 0}

/* ---- LE SCORE INCRUSTE ---------------------------------------------------------- */
.m2d-tv-score{position:absolute;left:1.4%;top:2%;z-index:14;display:flex;align-items:stretch;
  height:clamp(17px,5.2%,30px);pointer-events:none;border-radius:4px;overflow:hidden;
  font:800 clamp(9.5px,1.25vw,14px)/1 system-ui,'Segoe UI',Arial,sans-serif;color:#fff;
  background:#0b1224eb;border:1px solid #ffffff26;box-shadow:0 4px 14px #0009}
.m2d-tv-score i{display:block;width:5px}
.m2d-tv-score b{display:flex;align-items:center;padding:0 .55em;letter-spacing:.07em}
.m2d-tv-score .m2d-tv-sc{display:flex;align-items:center;padding:0 .65em;background:#f3f5fa;
  color:#0b1224;font-weight:900;font-variant-numeric:tabular-nums;letter-spacing:.02em}
.m2d-tv-score em{display:flex;align-items:center;padding:0 .6em;font-style:normal;
  background:#18264a;color:#f4c04a;font-variant-numeric:tabular-nums;min-width:2.4em;justify-content:center}
@media (max-width:520px){ .m2d-tv-score b{padding:0 .35em} .m2d-tv-score em{display:none} }

/* ---- LE BANDEAU DE BUT ---------------------------------------------------------- */
/* Il se DEROULE de gauche a droite (clip-path) au lieu d'apparaitre : c'est le geste
   d'une incrustation tele, et il ne coute qu'une propriete composee par le GPU. */
.m2d-tv-but{position:absolute;left:3.5%;bottom:11%;z-index:15;display:flex;align-items:stretch;
  min-height:clamp(34px,13%,68px);max-width:88%;pointer-events:none;
  font-family:system-ui,'Segoe UI',Arial,sans-serif;filter:drop-shadow(0 8px 18px #000000b0);
  clip-path:inset(0 100% 0 0)}
.m2d-tv-but.m2d-tv-but-in{animation:m2dTvButIn .6s cubic-bezier(.2,.9,.25,1) forwards}
.m2d-tv-but.m2d-tv-but-out{animation:m2dTvButOut .5s cubic-bezier(.6,0,.8,.4) forwards}
@keyframes m2dTvButIn{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
@keyframes m2dTvButOut{from{clip-path:inset(0 0 0 0)}to{clip-path:inset(0 0 0 100%)}}
.m2d-tv-but-mot{display:flex;align-items:center;padding:0 1em;
  background:linear-gradient(120deg,var(--tv-c1) 0 62%,var(--tv-c2) 62% 100%);color:var(--tv-encre,#fff)}
.m2d-tv-but-mot span{font-weight:900;font-style:italic;letter-spacing:.14em;
  font-size:clamp(15px,2.7vw,32px);text-shadow:0 1px 0 #0000004d;
  animation:m2dTvMot .9s .35s cubic-bezier(.2,1.6,.4,1) both}
@keyframes m2dTvMot{0%{transform:scale(.6);opacity:0}100%{transform:scale(1);opacity:1}}
.m2d-tv-but-info{display:flex;flex-direction:column;justify-content:center;padding:.35em 1.1em;
  background:#0b1224f5;color:#fff;border-top:3px solid var(--tv-c1)}
.m2d-tv-but-info b{font-size:clamp(12px,1.55vw,20px);line-height:1.1;font-weight:800;white-space:nowrap;letter-spacing:.01em}
.m2d-tv-but-info small{margin-top:2px;line-height:1.1;font-size:clamp(9px,.95vw,12px);font-weight:600;color:#9fb0d8;white-space:nowrap}
.m2d-tv-but-sc{display:flex;align-items:center;padding:0 .9em;background:#f3f5fa;color:#0b1224;
  font-weight:900;font-size:clamp(14px,2.3vw,27px);font-variant-numeric:tabular-nums}

/* ---- LE RALENTI ----------------------------------------------------------------- */
.m2d-tv-ralenti{position:absolute;inset:0;z-index:13;pointer-events:none;opacity:0;transition:opacity .3s ease}
.m2d-tv-ralenti::before,.m2d-tv-ralenti::after{content:"";position:absolute;left:0;right:0;height:7.5%;
  background:#000;transition:transform .5s cubic-bezier(.2,.9,.3,1)}
.m2d-tv-ralenti::before{top:0;transform:translateY(-101%)}
.m2d-tv-ralenti::after{bottom:0;transform:translateY(101%)}
.pitch2d.m2d-ralenti .m2d-tv-ralenti{opacity:1}
.pitch2d.m2d-ralenti .m2d-tv-ralenti::before,.pitch2d.m2d-ralenti .m2d-tv-ralenti::after{transform:none}
.m2d-tv-ralenti span{position:absolute;right:2.2%;top:10.5%;display:flex;align-items:center;gap:.45em;
  padding:.38em .7em;border-radius:4px;background:#0b1224e0;border:1px solid #ffffff2e;
  font:900 clamp(10px,1.3vw,14px)/1 system-ui,'Segoe UI',Arial,sans-serif;letter-spacing:.2em;color:#fff}
.m2d-tv-ralenti span::before{content:"";width:.62em;height:.62em;border-radius:50%;background:#ff3b4f;
  box-shadow:0 0 8px #ff3b4f;animation:m2dTvRec 1s steps(2,jump-none) infinite}
@keyframes m2dTvRec{50%{opacity:.25}}
.m2d-tv-ralenti small{position:absolute;right:2.2%;bottom:1.8%;font:600 clamp(8.5px,.95vw,11px)/1 system-ui,sans-serif;
  color:#ffffffa6;letter-spacing:.04em}
@media (hover:none){ .m2d-tv-ralenti small{display:none} }

/* ---- LES FLASHS DES PHOTOGRAPHES ------------------------------------------------ */
.m2d-flashs{position:absolute;inset:0;z-index:2;pointer-events:none}
.m2d-flashs i{position:absolute;width:4px;height:4px;margin:-2px 0 0 -2px;border-radius:50%;
  background:#fff;box-shadow:0 0 7px 3px #ffffffd9;opacity:0;animation:m2dFlash .24s ease-out both}
@keyframes m2dFlash{0%{opacity:1;transform:scale(1.4)}100%{opacity:0;transform:scale(.3)}}

/* ---- LE PORTEUR DU BALLON ------------------------------------------------------- */
/* Une nappe de lumiere sous celui qui a le ballon, comme le halo du match view de
   Football Manager : l'oeil trouve l'action avant de lire le moindre numero. Pseudo-
   element du jeton, donc il suit le joueur sans aucune ecriture par image. */
.pitch2d .pj.porte::before{content:"";position:absolute;pointer-events:none;border-radius:50%;
  left:calc(var(--pj) * -1); top:calc(var(--pj) * -1); width:calc(var(--pj) * 2); height:calc(var(--pj) * 2);
  background:radial-gradient(circle,#fff7d0a6 0 30%,#fff7d000 70%)}

/* ---- LES REGLAGES DU MATCH (barre au-dessus du terrain) ------------------------- */
.ml-reglages{display:inline-flex;flex-wrap:wrap;gap:6px;align-items:center;justify-content:flex-end}
.ml-reglages .btn.on{border-color:var(--gold);color:var(--gold)}

/* ---- LE SOUS-TITRE DU DIRECT (19/09/2026) --------------------------------------- */
/* La derniere ligne du compte-rendu, en bandeau bas, terrain net. Meme famille que le
   score incruste : fond nuit, minute en or. Apparait par opacite + translation (deux
   proprietes composees), jamais au-dessus du bandeau de but (z-index inferieur). */
.m2d-tv-st{position:absolute;left:50%;bottom:4.2%;z-index:14;display:flex;align-items:stretch;
  max-width:min(92%,720px);pointer-events:none;opacity:0;transform:translate(-50%,8px);
  transition:opacity .28s ease,transform .28s cubic-bezier(.2,.9,.3,1);
  font-family:system-ui,'Segoe UI',Arial,sans-serif;filter:drop-shadow(0 6px 14px #000000a0)}
.m2d-tv-st.m2d-tv-st-on{opacity:1;transform:translate(-50%,0)}
.m2d-tv-st em{display:flex;align-items:center;justify-content:center;min-width:2.6em;padding:0 .55em;
  font-style:normal;font-weight:800;font-size:clamp(10px,1.05vw,13px);background:#18264a;color:#f4c04a;
  font-variant-numeric:tabular-nums}
.m2d-tv-st span{display:block;padding:.5em .95em;background:#0b1224ee;color:#fff;
  font-size:clamp(11px,1.2vw,15px);font-weight:600;line-height:1.3;border-left:3px solid #f4c04a;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.m2d-tv-st.m2d-tv-st-fort span{color:#f4c04a}
.pitch2d.m2d-ralenti .m2d-tv-st{opacity:0}
@media (max-width:520px){ .m2d-tv-st{bottom:2.5%;max-width:96%} .m2d-tv-st span{padding:.4em .7em} }

/* LE SOUS-TITRE SUR PETIT ECRAN. Sur un terrain de 320 px, deux lignes de sous-titre couvraient un quart
   de la pelouse, joueurs compris. Une seule ligne, plus fine, coupee par des points de suspension : le
   texte complet est dans le fil du match, juste sous le terrain. */
@media(max-width:700px){.m2d-tv-st{max-width:94%;font-size:9.5px;bottom:2%}.m2d-tv-st span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding:.35em .6em}}
