/* ----------------------------------------------------------------
   pape-france.fr — PROGRAMME : ÉTATS DES ÉVÈNEMENTS — v2
   Direction « Le rail et l'étiquette ».
   Remplace programme-etats.css. À fondre dans pages-v3.css une fois validé.

   LE PRINCIPE
   Deux axes indépendants, deux canaux visuels séparés, sur deux
   côtés différents de la ligne :

     Axe 1  a une page      → le TITRE (soulignement + flèche)   centre
     Axe 2  accès au public → les BORDS (rail gauche + étiquette) marges

   Ainsi une ligne peut porter les deux signaux sans qu'ils se
   confondent, et le lecteur apprend deux codes au lieu d'un système.

   CE QUI CHANGE PAR RAPPORT À LA v1
   La v1 posait trois fonds de ligne. Sur 21 lignes dont 15 mènent à
   une page, le fond bleu devient le fond de la page : il cesse d'être
   un signal. Ici AUCUNE ligne n'a de fond au repos. Le fond ne sert
   plus qu'au survol, où il désigne une cible unique. La page reste
   une liste, pas un tableau de bord.

   ACCROCHES
   Axe 1 : rien à configurer. Le plugin émet <a href="#pf-sans-page">
   puis retire le href ; a[href]:not([href^="#"]) couvre les deux temps.
   Axe 2 : data-pf-acces sur .tl-item, GB Pro > Advanced >
   HTML Attributes → data-pf-acces : {{post_meta key:pf_acces_public}}
   Aucun sélecteur ne peut deviner un huis clos ; c'est le seul hook exact.
   Second attribut FACULTATIF sur le même élément, pour la gradation de
   couleur de l'étiquette d'accès (voir « LA GRADATION DE L'ACCÈS ») :
   data-pf-nature : {{post_meta key:pf_affichage_acces_nature}}
   Et un shortcode, [pf_publics], pour les publics un par un.

   « NE RIEN AFFICHER » VAUT "rien", JAMAIS "".
   GenerateBlocks ne rend pas un bloc dont une donnée dynamique est vide :
   un data-pf-acces résolu à vide efface la ligne entière du programme,
   contenu compris. Le CPT stocke donc le slug « rien », qui est ici un
   état à part entière et non un synonyme d'« ouvert » : ni rail, ni
   pastille, ni repli — seulement le texte nu s'il y en a un. C'est
   aussi le sort réservé à toute valeur imprévue, et à un .tl-item qui
   aurait perdu son attribut : se taire ne ment jamais.
   ---------------------------------------------------------------- */

/* ─── SOCLE ───────────────────────────────────────────────────────
   Deux pseudo-éléments, un par axe : ::before = wash de survol
   (axe 1), ::after = rail d'accès (axe 2). Une ligne peut donc
   porter les deux. Empilement explicite plutôt que z-index négatif,
   qui passerait derrière le fond d'une section ancêtre. */
.timeline .tl-item{position:relative}
.timeline .tl-item::before{content:"";position:absolute;inset:0 -16px;z-index:0;border-radius:10px;pointer-events:none;transition:background-color .18s ease}
.timeline .tl-item>*{position:relative;z-index:1}

/* ─── AXE 1 — LES LIGNES QUI MÈNENT QUELQUE PART ──────────────────
   Une ligne sans page n'est pas une ligne dégradée : « Arrivée à
   l'aéroport d'Orly » ouvre le voyage. On ne lui retire donc rien.
   On ajoute une promesse de destination à celles qui en ont une. */

/* Le soulignement porte l'essentiel : convention universelle, il
   survit au daltonisme, au niveau de gris et au papier. 3px pour
   qu'il tienne à un mètre. */
.tl-body h3 a[href]:not([href^="#"]){cursor:pointer;text-decoration:underline;text-decoration-color:var(--primary-soft);text-decoration-thickness:3px;text-underline-offset:6px;text-decoration-skip-ink:none}
.tl-body h3 a[href]:not([href^="#"]):hover{text-decoration-color:var(--primary-deep)}

/* La flèche est un glyphe, pas une pastille : quinze disques marine
   feraient un damier, et une pastille ne grandit pas avec le titre.
   Celle-ci suit la taille du h3, donc reste lisible de loin. */
/* display:inline et non inline-block : un inline-block est une boîte
   atomique, la coupure de ligne se fait AVANT elle et l'espace
   insécable qu'elle contient n'y peut rien. En inline, l'insécable
   colle vraiment la flèche au dernier mot du titre. Corollaire :
   translateX ne s'applique pas à une inline non remplacée — le
   mouvement de survol passe par padding-left, qui, lui, s'applique. */
.tl-body h3 a[href]:not([href^="#"])::after{content:"\00A0\2192";display:inline;color:var(--primary-soft);font-weight:400;text-decoration:none;padding-left:0;transition:padding-left .18s ease}
.tl-body h3 a[href]:not([href^="#"]):hover::after{color:var(--primary-deep)}

/* Le survol éclaire la ligne entière : c'est là, et seulement là,
   qu'un fond désigne quelque chose. */
.gb-loop-item:has(.tl-body h3 a[href]:not([href^="#"])) .tl-item:hover::before{background:var(--primary-wash)}
.gb-loop-item:has(.tl-body h3 a[href]:not([href^="#"])) .tl-item:hover h3 a::after{padding-left:5px}

/* Le survol exclut le clavier et le tactile : le signal de repos
   (soulignement + flèche) doit suffire, et le focus doit se voir. */
.tl-body h3 a[href]:not([href^="#"]):focus-visible{outline:2px solid var(--primary-soft);outline-offset:4px;border-radius:3px}

/* Ce qui reste du lien mort, avant comme après le passage du JS. */
.tl-body h3 a[href="#pf-sans-page"],
.tl-body h3 a.pf-sans-lien,
.tl-body h3 .pf-sans-lien{cursor:default;text-decoration:none;color:inherit}

/* ─── AXE 2 — OUVERTURE AU PUBLIC ─────────────────────────────────
   LE RAIL MARQUE CE QUI EST OUVERT, PAS CE QUI EST FERMÉ.
   Version précédente : rail sur les évènements restreints. Le rail
   est l'élément le plus voyant de la marge — le donner aux lignes
   fermées, c'est mettre en avant ce à quoi le lecteur ne peut pas
   aller. Or 90 % des visiteurs viennent chercher l'inverse : où
   puis-je me rendre. Le signal fort doit désigner l'opportunité.

   Corollaire logique : le rail devient marine — la couleur
   institutionnelle, positive, jamais une alerte. Et le sélecteur se
   simplifie, puisqu'il ne porte plus que sur une valeur exacte.
   Conséquence à assumer : une saisie manquante ne reçoit pas de rail,
   donc ressemble à un huis clos. C'est le bon sens de l'erreur — ne
   jamais promettre un accès non confirmé sur le programme officiel. */

/* Rail plein, 5px, à gauche du bloc. En balayant la colonne des
   horaires, les rendez-vous ouverts se comptent d'un coup d'œil. */
.timeline .tl-item[data-pf-acces="ouvert"]::after{content:"";position:absolute;left:-22px;top:16px;bottom:16px;z-index:1;width:5px;border-radius:5px;background:var(--primary)}

/* L'horaire cesse d'être une consigne : personne n'a à être là à
   cette heure. Le titre, lui, garde tout son poids — l'évènement
   n'est pas moins important, il est seulement fermé. Un seul
   traitement pour les quatre restrictions : l'œil ne trie que
   « ouvert / pas ouvert », le mot de l'étiquette fait la nuance.
   Ardoise et jamais rouge : le rendez-vous a lieu, il est souvent
   retransmis — ce n'est ni une alerte ni une annulation. */
/* LES QUATRE VALEURS FERMÉES SONT NOMMÉES, JAMAIS DÉDUITES PAR
   NÉGATION. Elles sont recopiées de PF_ACCES_PUBLIC (section 3 du
   plugin) : invitation, delegations, accredites, prive. La forme
   précédente — [data-pf-acces]:not("ouvert"):not(""):not("rien") —
   disait « tout le reste », donc rangeait du côté du huis clos une
   valeur inconnue autant qu'un attribut mal saisi. Nommer les quatre
   fait retomber tout imprévu sur le silence : muet plutôt que faux.
   Duplication assumée, le CSS ne sait pas lire une constante PHP —
   ajouter une valeur à PF_ACCES_PUBLIC impose de passer ici. */
.timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .tl-time,
.timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .tl-place,
.timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .tl-place svg{color:var(--ink-mute)}

/* ─── LES ÉTIQUETTES ──────────────────────────────────────────────
   Elles s'opposent par le POIDS (contour vs plein), pas par la
   teinte : l'opposition tient en niveaux de gris et sur papier.

     contour coloré  un public est attendu, et lequel   (pf_public)
     plein marine    on peut s'y rendre                 (pf_acces_public)
     plein ardoise   personne n'est attendu             (pf_acces_public)
     rien            pas encore renseigné

   Les deux pleins relèvent du même axe et ne cohabitent jamais sur une
   ligne ; le contour relève de l'autre axe et se pose à côté de l'un
   ou de l'autre. C'est ce qui autorise deux pleins sans confusion.

   Le troisième cas reste franchement vide. Le programme est
   prévisionnel : habiller une saisie manquante d'une mention
   affirmative publierait une information fausse sur le programme
   officiel du Saint-Siège. Une absence doit rester une absence. */

/* Trois valeurs par public : l'accent pur ne sert qu'au voile de
   fond, le texte et le contour sont des versions ASSOMBRIES À TEINTE
   CONSTANTE — un cyan foncé reste cyan, un ambre foncé reste ambre.
   (Un mélange vers le marine, lui, ramènerait les sept publics au
   même bleu.) À 11,5 px en capitales, une étiquette n'est pas du
   « grand texte » au sens WCAG : elle doit tenir le 4,5:1, ce que le
   cyan et le jaune de la charte ne font jamais à l'état pur. */
/* Les couleurs de public ne doivent JAMAIS atteindre la mention
   d'accès, qui porte pourtant la même classe : d'où le :not(). */
.timeline .ag-event__tag.invit,
.timeline .ag-event__tag.public,
.pf-hero__pf-eyebrow .ag-event__tag.public{background:color-mix(in oklab,var(--pf-public,var(--primary)) 12%,var(--paper));color:var(--pf-ink,var(--primary-deep));border:1.5px solid var(--pf-line,var(--primary));font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;padding:6px 15px;border-radius:999px;white-space:nowrap}
.timeline .pf-acces .ag-event__tag{--pf-public:initial;--pf-ink:initial;--pf-line:initial}

/* ─── LA TROISIÈME DIMENSION : LES PUBLICS ────────────────────────
   Les deux axes du brief sont sémantiques : les colorer mentirait
   (rouge = alerte, vert = feu vert, jaune = attention). pf_public,
   lui, est une liste fermée sans hiérarchie — exactement la situation
   des rubriques de la FAQ, où la couleur est un NOM et non un
   jugement. C'est donc là que la charte entre, et nulle part ailleurs.
   Le markup porte déjà la classe : aucun réglage à faire.

   Sept publics pour cinq couleurs de charte : les deux manquantes
   sont des harmonisations oklch du marine (violet) et du vert.
   Teintes réparties sur toute la roue pour rester séparables. */
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-grand-public{--pf-public:#0F2D85;--pf-ink:#0F2D85;--pf-line:#2F51C4}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-clercs-et-consacres{--pf-public:#6B47C4;--pf-ink:#4A2E8F;--pf-line:#6B47C4}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-jeunes{--pf-public:#1ACCFF;--pf-ink:#006F9E;--pf-line:#0098D4}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-personnes-malades{--pf-public:#00B5B0;--pf-ink:#00615E;--pf-line:#00918C}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-benevoles{--pf-public:#22B36A;--pf-ink:#17683C;--pf-line:#229B58}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-familles{--pf-public:#FFA107;--pf-ink:#8A5200;--pf-line:#C57800}
:is(.timeline, .pf-hero__pf-eyebrow) .pf_public-presse{--pf-public:#F71021;--pf-ink:#A50C17;--pf-line:#D9101E}

/* UNE ÉTIQUETTE PAR PUBLIC — [pf_publics], plugin section 12.
   Le Dynamic Tag de termes rend une chaîne unique, « Familles | Grand
   public | Jeunes | Personnes malades », que le CSS ne sait pas
   découper. Deux conséquences : une étiquette longue de quatre noms,
   et surtout UNE SEULE COULEUR — car les classes pf_public-* viennent
   de post_class() sur l'élément de boucle, qui les porte donc toutes
   les quatre, et c'est la dernière règle déclarée ci-dessus qui
   l'emporte. La couleur affichée était arbitraire par construction.
   Le shortcode émet un <li> par terme, chacun portant sa classe : la
   couleur redevient un nom. La déclaration sur l'élément lui-même
   l'emporte sur celle héritée de l'élément de boucle, sans !important.
   Le <ul> remplace le bloc de termes dans le gabarit — les garder tous
   les deux afficherait les publics en double.

   .pf-hero__pf-eyebrow REJOINT .timeline dans tous les sélecteurs
   ci-dessus : la vue single des évènements pose désormais [pf_publics]
   dans l'eyebrow du hero (au lieu du Dynamic Tag de termes brut), pour
   que l'étiquette d'un public y ait la même couleur que sur le
   programme. L'alignement diffère seul : fin de ligne dans le
   programme (colonne de droite), début de ligne dans l'eyebrow. */
:is(.timeline, .pf-hero__pf-eyebrow) .pf-publics{display:flex;flex-wrap:wrap;gap:6px;margin:0;padding:0;list-style:none}
.timeline .pf-publics{justify-content:flex-end}
.pf-hero__pf-eyebrow .pf-publics{justify-content:flex-start}
:is(.timeline, .pf-hero__pf-eyebrow) .pf-publics li{display:flex}

/* ─── LES JOURNÉES ────────────────────────────────────────────────
   Quatre journées, quatre couleurs : même logique catégorielle, à
   l'échelle de la section. Le filet donne à la page les repères de
   couleur qui lui manquaient, sans toucher aux lignes. */
/* Le titre de journée reste collé en haut pendant le défilement de
   sa section : sur quatre journées et vingt-et-une lignes, on perd
   vite de vue quel jour on lit. Il se décroche tout seul à la journée
   suivante, .ag-day faisant office de conteneur de collage.
   --pf-sticky-top : hauteur de l'en-tête fixe du site, s'il y en a un. */
:root {
/*  --pf-sticky-top: 138px;*/
  --pf-sticky-top: calc(99px + var(--pf-flag-h, 0px));
}
.ag-day { position: relative; }
.ag-day .tl-day {
   position: sticky;
   top: var(--pf-sticky-top, 0px);
   z-index: 5;
   display: flex;
   align-items: center;
   gap: 14px;
   margin-inline: -26px;
   padding: 16px 26px 13px;
   background: var(--paper);
   box-shadow: 0 1px 0 var(--rule);
}
.ag-day h2.tl-day {
   font-family: inherit !important;
}
.ag-day .tl-day::before {
   content: "";
   width: 46px;
   height: 4px;
   border-radius: 2px;
   background: var(--jour, var(--primary));
   flex: none;
}
#j25 { --jour: var(--green); }
#j26 { --jour: var(--yellow); }
#j27 { --jour: var(--cyan); }
#j28 { --jour: var(--red); }

/* L'étiquette d'accès. MÉTHODE RECOMMANDÉE : afficher dans le
   groupe de troisième colonne un texte {{post_meta key:pf_affichage_acces}}
   portant la classe .pf-acces — la chaîne est déjà composée côté PHP
   (« Sur invitation · retransmis ») et le CSS n'a rien à recopier.

   MARKUP RÉEL — le bloc GB émet DEUX niveaux, et la mention d'accès
   porte la même classe que l'étiquette de public :

     <p class="gb-text invit">    <span class="ag-event__tag invit"><span>Grand public</span></span></p>
     <p class="gb-text pf-acces"><span class="ag-event__tag invit">Gratuit · accès libre</span></p>

   Le seul discriminant est donc l'ENCADREMENT : la mention d'accès est
   le .ag-event__tag qui se trouve DANS .pf-acces, l'étiquette de
   public est celui qui n'y est pas. Sans cette distinction, les deux
   familles de règles s'appliquaient ensemble — pastille sur le <p>,
   contour coloré sur le <span> — d'où le double anneau.

   Conséquence : le <p> redevient un simple conteneur, et tout le
   traitement se pose sur le <span>. */
.timeline .pf-acces{background:none;border:0;padding:0;margin:0}

/* ATTENTION — la même méta sert aux trois cas : elle vaut aussi bien
   « Sur invitation · retransmis » que « Gratuit · accès libre ». Une
   pastille identique de part et d'autre annulerait la distinction.
   D'où trois traitements, sélectionnés sur data-pf-acces :

     ouvert        pastille pleine marine      la couleur du rail
     fermé (× 4)   pastille pleine ardoise     le seul gris de la ligne
     rien / vide   texte nu, aucune pastille   une absence reste une absence

   L'ÉTIQUETTE D'UN RENDEZ-VOUS OUVERT PORTE LA COULEUR DE SON RAIL.
   C'est la règle à retenir : marine ici, --primary-soft sur fond
   marine — les mêmes valeurs que le rail, aux mêmes endroits, ce qui
   dispense la légende d'une entrée de plus. Seule l'impression y
   déroge, et pour une raison précise, expliquée au bas du fichier.

   LE DÉFAUT EST LE TEXTE NU ; LES DEUX PASTILLES SONT DES EXCEPTIONS
   NOMMÉES. La version précédente faisait l'inverse : la pastille
   ardoise se posait par double négation, si bien que tout .tl-item
   privé de son attribut — attribut HTML non configuré sur le bloc GB,
   évènement encore porteur de la chaîne vide d'avant le slug « rien »
   — recevait la pastille de huis clos alors que le texte à l'intérieur
   annonçait « Gratuit · accès libre ». C'était la cause principale des
   étiquettes fausses ou dépareillées.

   Le défaut nu doit rester déclaré AVANT les deux pastilles : il est
   moins spécifique, il perdrait de toute façon, mais l'ordre du fichier
   doit se lire comme la règle — le cas général puis ses exceptions. */
.timeline .tl-item .pf-acces .ag-event__tag{display:inline;background:none;border:0;padding:0;font-size:12.5px;font-weight:500;letter-spacing:.02em;text-transform:none;color:var(--ink-soft);white-space:nowrap}

/* CAS OUVERT — pastille pleine marine, texte blanc.
   Version précédente : texte nu, au motif que le rail disait déjà
   « ouvert ». Deux raisons de revenir dessus. La première est que le
   rail vit dans la marge, hors du parcours de lecture, et qu'il est le
   premier à sauter dès qu'une feuille de style ne suit pas (fond non
   imprimé, colonne étroite) : le seul signal positif de la ligne ne
   peut pas être le plus fragile. La seconde est que la mention
   n'existe pas toujours —
   pf_libelle_acces() renvoie une chaîne vide pour un évènement ouvert
   sans gratuité ni inscription, GB supprime alors le bloc, et la ligne
   se retrouvait sans aucune marque d'ouverture. Le REPLI plus bas
   couvre désormais ce cas, mais il n'aurait aucun sens si le cas
   normal, lui, restait muet.
   Plein et non contour : l'étiquette de public est un contour coloré,
   souvent marine elle aussi (grand public) — deux contours empilés
   feraient doublon. Le plein les sépare par le poids, pas par la
   teinte, et laisse la couleur nommer le destinataire. */
.timeline .tl-item[data-pf-acces="ouvert"] .pf-acces .ag-event__tag{display:inline-block;font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;padding:6px 15px;border-radius:999px;white-space:nowrap;background:var(--primary);color:var(--paper);border:1.5px solid var(--primary)}

/* CAS FERMÉ — pastille pleine ardoise. Ardoise et non marine : c'est
   le seul gris de la ligne, donc il se voit sans crier, et il ne peut
   pas être pris pour la couleur d'un public. Un seul traitement pour
   les quatre restrictions, le mot fait la nuance. */
.timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .pf-acces .ag-event__tag{display:inline-block;font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;padding:6px 15px;border-radius:999px;white-space:nowrap;background:var(--ink-soft);color:var(--paper);border:1.5px solid var(--ink-soft)}

/* REPLI : quand .pf-acces manque, on génère le libellé depuis
   data-pf-acces. « Manque » couvre deux situations bien réelles, et
   pas seulement l'oubli de l'éditeur :

     1. le bloc de mention n'a pas été posé sur le gabarit ;
     2. il a été posé, mais pf_affichage_acces est vide — cas normal
        d'un évènement ouvert sans gratuité ni modalité d'inscription,
        et GB ne rend pas un bloc dont la donnée dynamique est vide.

   Le cas 2 est celui qui laissait des lignes ouvertes sans la moindre
   étiquette. « Ouvert au public » ne promet rien de plus que ce que
   l'éditeur a saisi : c'est le libellé même de la valeur choisie.

   Libellés recopiés de PF_ACCES_PUBLIC (pf-cpt-evenement.php,
   section 3) — duplication assumée, le CSS ne sait pas lire une méta.
   Le « retransmis » se perd ici : raison de plus de préférer .pf-acces.
   « rien » n'a volontairement pas de repli : c'est le seul état dont
   le vide est le rendu juste. */
.timeline .tl-item[data-pf-acces]:not(:has(.pf-acces))>.wp-block-group::after{font-size:11.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;padding:6px 15px;border-radius:999px;white-space:nowrap;background:var(--ink-soft);color:var(--paper);border:1.5px solid var(--ink-soft)}
.timeline .tl-item[data-pf-acces="ouvert"]:not(:has(.pf-acces))>.wp-block-group::after{content:"Ouvert au public";background:var(--primary);border-color:var(--primary)}
.timeline .tl-item[data-pf-acces="invitation"]:not(:has(.pf-acces))>.wp-block-group::after{content:"Sur invitation"}
.timeline .tl-item[data-pf-acces="delegations"]:not(:has(.pf-acces))>.wp-block-group::after{content:"Délégations"}
.timeline .tl-item[data-pf-acces="accredites"]:not(:has(.pf-acces))>.wp-block-group::after{content:"Accrédités"}
.timeline .tl-item[data-pf-acces="prive"]:not(:has(.pf-acces))>.wp-block-group::after{content:"Sans public"}

/* ─── LA GRADATION DE L'ACCÈS ─────────────────────────────────────
   « Accès libre », « Inscription recommandée », « Inscription
   obligatoire » et « Réservé aux délégations » demandent au lecteur
   des choses de nature différente : rien, un conseil, une démarche,
   un renoncement. Les servir dans quatre pastilles identiques oblige
   à lire les quatre pour trier ; une couleur par degré permet de
   balayer la journée et de ne lire que ce qui concerne.

   UNE ÉCHELLE, PAS UNE PALETTE. C'est la nuance qui rend cette
   couleur licite là où la section « LES PUBLICS » l'interdisait :
   pf_acces_public est un axe ORDONNÉ, on peut donc y monter une
   gradation, alors que colorer « ouvert » contre « fermé » en vert
   contre rouge aurait posé un jugement sur deux valeurs de même rang.
   La couleur ne dit jamais rien que le mot ne dise déjà : elle
   accélère un tri, elle ne porte aucune information à elle seule —
   d'où le maintien du mot en toutes lettres dans chaque pastille.

   Le brique de « obligatoire » n'est pas une alerte : c'est le dernier
   cran avant le huis clos. Aucune confusion possible avec une
   annulation, qui relève de pf_statut et ne s'affiche pas ici.

   ACCROCHE : data-pf-nature sur .tl-item, GB Pro > Advanced >
   HTML Attributes → data-pf-nature : {{post_meta key:pf_affichage_acces_nature}}
   Méta dérivée, calculée par pf_nature_acces() (plugin, section 6) :
   c'est là que se décide quelle modalité d'inscription vaut une
   obligation, et non dans ces sélecteurs, qui n'auraient plus qu'à
   recopier la règle et à la laisser diverger.

   L'attribut est FACULTATIF : sans lui, tout reste dans le rendu
   marine / ardoise des deux règles ci-dessus. D'où la place de ce
   bloc — déclaré après la pastille ET après le repli, il les
   surcharge tous deux à égalité de spécificité, par l'ordre seul.
   N'y mettre QUE des couleurs : la géométrie appartient aux règles
   précédentes, qui restent le rendu par défaut. */
.timeline .tl-item[data-pf-nature="libre"] .pf-acces .ag-event__tag,
.timeline .tl-item[data-pf-nature="libre"]:not(:has(.pf-acces))>.wp-block-group::after{background:#17683C;color:var(--paper);border-color:#17683C}
.timeline .tl-item[data-pf-nature="ouvert"] .pf-acces .ag-event__tag,
.timeline .tl-item[data-pf-nature="ouvert"]:not(:has(.pf-acces))>.wp-block-group::after{background:var(--primary);color:var(--paper);border-color:var(--primary)}
.timeline .tl-item[data-pf-nature="recommandee"] .pf-acces .ag-event__tag,
.timeline .tl-item[data-pf-nature="recommandee"]:not(:has(.pf-acces))>.wp-block-group::after{background:#8A5200;color:var(--paper);border-color:#8A5200}
.timeline .tl-item[data-pf-nature="requise"] .pf-acces .ag-event__tag,
.timeline .tl-item[data-pf-nature="requise"]:not(:has(.pf-acces))>.wp-block-group::after{background:#A50C17;color:var(--paper);border-color:#A50C17}
.timeline .tl-item[data-pf-nature="ferme"] .pf-acces .ag-event__tag,
.timeline .tl-item[data-pf-nature="ferme"]:not(:has(.pf-acces))>.wp-block-group::after{background:var(--ink-soft);color:var(--paper);border-color:var(--ink-soft)}

/* La troisième colonne ne doit jamais s'effondrer : sa largeur fixe
   la position des étiquettes d'une ligne à l'autre. L'étiquette de
   public passe en premier — c'est elle qui porte la couleur et le
   nom du destinataire ; la mention d'accès la complète. */
/* Gouttière unique : le 6px réservé à « ouvert » compensait un texte
   nu, plus léger qu'une pastille. L'ouvert ayant sa pastille, les deux
   étiquettes ont partout le même poids, donc le même écart. */
.timeline .tl-item>.wp-block-group{display:flex;flex-direction:column;align-items:flex-end;gap:8px}

/* ─── LÉGENDE ─────────────────────────────────────────────────────
   Une distinction que le lecteur ne sait pas décoder n'est que de la
   décoration. <ul class="pf-prog-legende"> au-dessus de la première
   journée ; cinq <li> : est-page, est-ouvert, est-public, est-ferme,
   est-vide.
   Le <li class="est-vide"> n'est pas décoratif : il est la seule
   façon de dire que le vide est un vide, et non un oubli de design.
   Pas de sixième entrée pour la pastille d'ouverture : elle porte la
   couleur du rail, que .est-ouvert montre déjà. C'est le bénéfice de
   la règle « même couleur que le rail » — la légende ne grandit pas.
   Pas d'entrée non plus pour les cinq degrés de la gradation : chaque
   pastille contient son mot en toutes lettres, elle est sa propre
   légende. Une couleur ne demande à être expliquée que lorsqu'elle
   porte SEULE une information — c'est le cas du rail et du contour de
   public, pas celui d'un aplat qui dit « Inscription obligatoire ». */
.pf-prog-legende{display:flex;flex-wrap:wrap;gap:12px 30px;margin:0 0 6px;padding:16px 0;list-style:none;font-size:13.5px;color:var(--ink-soft);border-top:1px solid var(--rule);border-bottom:1px solid var(--rule)}
.pf-prog-legende li{display:flex;align-items:center;gap:10px}
.pf-prog-legende .est-page::before{content:"Titre \2192";text-decoration:underline;text-decoration-color:var(--primary-soft);text-decoration-thickness:3px;text-underline-offset:4px;color:var(--ink);font-weight:500}
.pf-prog-legende .est-ouvert::before{content:"";width:5px;height:16px;border-radius:5px;background:var(--primary);flex:none}
.pf-prog-legende .est-public::before{content:"";width:26px;height:14px;border-radius:999px;background:color-mix(in oklab,var(--cyan) 12%,var(--paper));border:1.5px solid #0098D4}
.pf-prog-legende .est-ferme::before{content:"";width:26px;height:14px;border-radius:999px;background:var(--ink-soft)}
.pf-prog-legende .est-vide{color:var(--ink-mute);font-style:italic}

/* ─── VERSION SOMBRE ──────────────────────────────────────────────
   Les valeurs d'origine sont des marines : sur fond marine elles
   disparaissent. Rail et étiquette pleine s'inversent — clair sur
   sombre — et le wash de survol devient un voile cyan. */
.pf-dark .gb-loop-item:has(.tl-body h3 a[href]:not([href^="#"])) .tl-item:hover::before{background:rgba(26,204,255,.10)}
.pf-dark .timeline .tl-item[data-pf-acces="ouvert"]::after{background:var(--primary-soft)}
.pf-dark .pf-prog-legende .est-ouvert::before{background:var(--primary-soft)}
.pf-dark .timeline .tl-item .pf-acces .ag-event__tag{color:var(--ink-soft)}
/* Les deux pastilles s'inversent — fond clair, texte marine profond —
   et celle de l'ouvert reprend la couleur que le rail vient de prendre
   ligne au-dessus : la règle « même couleur que le rail » tient dans
   les deux thèmes. */
.pf-dark .timeline .tl-item[data-pf-acces="ouvert"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-acces="ouvert"]:not(:has(.pf-acces))>.wp-block-group::after{background:var(--primary-soft);color:#0B142F;border-color:var(--primary-soft)}
.pf-dark .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]):not(:has(.pf-acces))>.wp-block-group::after{background:var(--ink-soft);color:#0B142F;border-color:var(--ink-soft)}
/* La gradation transposée : mêmes cinq degrés, mêmes teintes, mais en
   valeurs claires — un aplat sombre sur fond marine ne se voit pas.
   Ce sont les transpositions déjà retenues pour les publics (bénévoles,
   familles, presse) : une couleur qui a deux versions dans le fichier
   n'en aura pas une troisième. Texte marine profond sur les cinq. */
.pf-dark .timeline .tl-item[data-pf-nature="libre"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-nature="libre"]:not(:has(.pf-acces))>.wp-block-group::after{background:#5FD98A;color:#0B142F;border-color:#5FD98A}
.pf-dark .timeline .tl-item[data-pf-nature="ouvert"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-nature="ouvert"]:not(:has(.pf-acces))>.wp-block-group::after{background:var(--primary-soft);color:#0B142F;border-color:var(--primary-soft)}
.pf-dark .timeline .tl-item[data-pf-nature="recommandee"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-nature="recommandee"]:not(:has(.pf-acces))>.wp-block-group::after{background:#FFC04D;color:#0B142F;border-color:#FFC04D}
.pf-dark .timeline .tl-item[data-pf-nature="requise"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-nature="requise"]:not(:has(.pf-acces))>.wp-block-group::after{background:#FF6B75;color:#0B142F;border-color:#FF6B75}
.pf-dark .timeline .tl-item[data-pf-nature="ferme"] .pf-acces .ag-event__tag,
.pf-dark .timeline .tl-item[data-pf-nature="ferme"]:not(:has(.pf-acces))>.wp-block-group::after{background:var(--ink-soft);color:#0B142F;border-color:var(--ink-soft)}
/* Sur marine, un accent assombri disparaît : chaque public reçoit
   donc sa transposition claire, et l'étiquette n'est plus qu'un
   contour. Sept valeurs distinctes — les rabattre sur le cyan
   rendrait la légende « la couleur dit lequel » fausse. */
.pf-dark .timeline .ag-event__tag.invit,
.pf-dark .timeline .ag-event__tag.public,
.pf-dark .pf-hero__pf-eyebrow .ag-event__tag.public{background:transparent;color:var(--pf-lite,var(--primary-soft));border-color:var(--pf-lite,var(--primary-soft))}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-grand-public{--pf-lite:#9FB4F5}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-clercs-et-consacres{--pf-lite:#B79CFF}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-jeunes{--pf-lite:#1ACCFF}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-personnes-malades{--pf-lite:#4FD8D3}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-benevoles{--pf-lite:#5FD98A}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-familles{--pf-lite:#FFC04D}
.pf-dark :is(.timeline, .pf-hero__pf-eyebrow) .pf_public-presse{--pf-lite:#FF6B75}
.pf-dark .tl-body h3 a[href]:not([href^="#"]):hover{text-decoration-color:#fff}
.pf-dark .tl-body h3 a[href]:not([href^="#"]):hover::after{color:#fff}

/* ─── MOBILE ──────────────────────────────────────────────────────
   Sous 900px la grille passe en une colonne et le survol n'existe
   plus : c'est précisément pourquoi l'axe 1 se lit au repos
   (soulignement + flèche) et pas seulement au survol. L'étiquette
   tombe sous le texte, le rail se rapproche du bord. */
@media (max-width:900px){
  :root {
/*    --pf-sticky-top: 160px;*/
    --pf-sticky-top: 115px;
    --pf-sticky-top: calc(92px + var(--pf-flag-h, 0px));
  }
  .timeline .tl-item::before{inset:0 -12px}
  .timeline .tl-item[data-pf-acces="ouvert"]::after{left:-14px;top:12px;bottom:12px;width:4px}
  .timeline .tl-item>.wp-block-group{align-items:flex-start;margin-top:14px}
  .timeline .tl-item>.wp-block-group::after{align-self:flex-start}
  .timeline .pf-publics{justify-content:flex-start}
  .ag-day .tl-day{margin-inline:-18px;padding:13px 18px 11px}
  .pf-prog-legende{gap:10px 22px;font-size:13px}
}

@media (prefers-reduced-motion:reduce){
  .timeline .tl-item::before,
  .tl-body h3 a::after{transition:none}
  .gb-loop-item .tl-item:hover h3 a::after{padding-left:0}
}

/* ─── IMPRESSION ──────────────────────────────────────────────────
   Le programme se lit sur papier le jour J, quand le réseau sature.
   La flèche n'a plus de sens sur une feuille ; le soulignement, si —
   il dit « une fiche existe en ligne », et la légende s'imprime pour
   l'expliquer. Rail et étiquettes passent au noir : les deux états
   doivent survivre à une imprimante monochrome. */
@media print{
  /* Les navigateurs n'impriment PAS les fonds par défaut. Sans cette
     ligne, le rail disparaît et la pastille pleine imprime du blanc
     sur blanc — soit une étiquette illisible là où elle porte le
     seul mot qui compte. Restreint aux quatre éléments qui codent
     une information par leur fond, jamais posé sur la page entière. */
  .timeline .tl-item[data-pf-acces="ouvert"]::after,
  .timeline .tl-item .pf-acces .ag-event__tag,
  .timeline .tl-item>.wp-block-group::after,
  .pf-prog-legende li::before{print-color-adjust:exact;-webkit-print-color-adjust:exact}
  .pf-prog-legende{display:flex!important;color:#000;border-color:#000}
  .tl-body h3 a::after{content:none}
  .tl-body h3 a[href]:not([href^="#"]){text-decoration-color:#000;text-decoration-thickness:2px}
  .timeline .tl-item::before{background:none}
  .pf-prog-legende .est-ouvert::before{background:#000}
  .timeline .tl-item[data-pf-acces="ouvert"]::after{background:#000}
  .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .tl-time,
  .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .tl-place{color:#000}
  .timeline .tl-item .pf-acces .ag-event__tag{color:#000}
  /* Trois remplissages, trois niveaux de gris : l'ouvert en gris clair
     sur texte noir, le huis clos en aplat noir, le public en contour.
     Une imprimante monochrome doit encore pouvoir les séparer — c'est
     la seule raison pour laquelle l'ouvert n'est pas noir lui aussi. */
  .timeline .tl-item[data-pf-acces="ouvert"] .pf-acces .ag-event__tag,
  .timeline .tl-item[data-pf-acces="ouvert"]>.wp-block-group::after{background:#e6e6e6;color:#000;border-color:#000}
  .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"]) .pf-acces .ag-event__tag,
  .timeline .tl-item:is([data-pf-acces="invitation"],[data-pf-acces="delegations"],[data-pf-acces="accredites"],[data-pf-acces="prive"])>.wp-block-group::after{background:#000;color:#fff;border-color:#000}
  /* La gradation ne s'imprime pas : cinq aplats colorés donnent cinq
     gris voisins sur une laser, donc rien. On revient aux deux seuls
     états que le papier sait tenir — peut-on s'y rendre, oui ou non —
     et le mot, lui, s'imprime en entier. Déclaré ici, en fin de
     feuille, pour surcharger les couleurs à égalité de spécificité. */
  .timeline .tl-item:is([data-pf-nature="libre"],[data-pf-nature="ouvert"],[data-pf-nature="recommandee"],[data-pf-nature="requise"]) .pf-acces .ag-event__tag,
  .timeline .tl-item:is([data-pf-nature="libre"],[data-pf-nature="ouvert"],[data-pf-nature="recommandee"],[data-pf-nature="requise"])>.wp-block-group::after{background:#e6e6e6;color:#000;border-color:#000}
  .timeline .tl-item[data-pf-nature="ferme"] .pf-acces .ag-event__tag,
  .timeline .tl-item[data-pf-nature="ferme"]>.wp-block-group::after{background:#000;color:#fff;border-color:#000}
  .timeline .ag-event__tag.invit,
  .timeline .ag-event__tag.public{background:none;color:#000;border:1.5px solid #000}
  .timeline .tl-item{break-inside:avoid}
  .ag-day .tl-day{position:static;box-shadow:none;background:none;margin-inline:0;padding-inline:0}
}
