/* Import Font Google Moderne */
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap');

/* Police du menu (Sora), hébergée localement — pas d'appel à Google Fonts */
@font-face {
  font-family: 'Sora';
  src: url('../fonts/sora-latin-500-normal.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Sora';
  src: url('../fonts/sora-latin-700-normal.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

html {
  box-sizing: border-box;
}
*, *::before, *::after {
  box-sizing: inherit;
}
html, body {
  margin: 0;
  padding: 0;
}

/* ============================================
   ÉTATS DE FOCUS CLAVIER (accessibilité)
   ============================================ */
/* Contour cohérent avec la charte (accent rose) sur tout élément
   interactif navigué au clavier — n'apparaît jamais au clic souris
   grâce à :focus-visible. Les éléments qui ont déjà leur propre style
   de focus plus spécifique (champs de formulaire des déclarations,
   Contact Form 7, recherche d'étalons...) restent inchangés : leurs
   règles ".xxx:focus" ont une spécificité supérieure et l'emportent. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid var(--wp--preset--color--accent, #F60B51);
  outline-offset: 3px;
}
/* Le halo doux (variante utilisée sur fond sombre : bandeau CTA, menu
   mobile) reste identique en teinte pour ne pas casser le contraste sur
   fond bleu nuit — accent rose déjà bien visible sur #1E293B/#0F172A. */


/* Fond doux lumineux avec gradients diffus */
body {
  font-family: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  background:
    radial-gradient(circle at 10% 10%, rgba(246, 11, 81, 0.07), transparent 35%),
    radial-gradient(circle at 90% 25%, rgba(71, 85, 105, 0.08), transparent 40%),
    radial-gradient(circle at 50% 80%, rgba(246, 11, 81, 0.04), transparent 50%),
    var(--wp--preset--color--bg);
  background-attachment: fixed;
  color: var(--wp--preset--color--text);
  -webkit-font-smoothing: antialiased;
}

/* Alignement à gauche pour le texte de contenu (standard web, meilleur pour la lisibilité
   et l'accessibilité) : neutralise tout texte justifié, sans toucher aux éléments
   volontairement centrés (titres, boutons, bandeaux CTA, footer). */
.content-card p,
.content-card li,
.wp-block-post-content p,
.wp-block-post-content li {
  text-align: left;
}
[style*="text-align:justify"],
[style*="text-align: justify"],
.has-text-align-justify {
  text-align: left !important;
}

/* Header flottant en verre (piste B) : la barre se détache du bord de
   l'écran (marge + coins arrondis en pilule) au lieu d'un bandeau plein
   écran. Le sticky doit rester posé sur le wrapper <header> généré par
   WordPress (zone "header" du theme.json) et pas sur .site-header : ce
   dernier est imbriqué à l'intérieur d'un <header> dont la hauteur ne
   dépasse pas celle du header lui-même, donc un sticky posé directement
   sur .site-header n'a aucune marge de manœuvre pour "voyager" et se
   décroche dès les premiers pixels de scroll (vérifié : ça casse le
   collage en haut). .site-header reste donc un simple bloc — c'est lui
   qui porte l'apparence "pilule" (marge, coins arrondis, verre). */
.wp-site-blocks > header {
  position: sticky !important;
  top: 0 !important;
  z-index: 1000 !important;
  /* Le décalage "flottant" (14px) est un padding sur le wrapper sticky,
     pas une margin sur .site-header : une margin ici collapserait avec
     le bord du wrapper (pas de bordure/padding pour l'en empêcher) et
     ferait remonter tout le bloc sticky de 14px au lieu de creuser un
     espace à l'intérieur — décalant sa vraie position d'ancrage. Le
     padding, lui, ne collapse jamais et reste compté dans la hauteur
     réservée en flux normal, donc pas de chevauchement avec le hero. */
  padding-top: 14px;
}
/* Même décalage "flottant" (14px), mais pour les gabarits PHP classiques
   (déclaration, adhésion, repas, liste des actualités — voir get_header()
   dans ces fichiers) : ceux-ci n'ont PAS le <header class="wp-block-template-part">
   généré par WordPress ci-dessus (.site-header y est un enfant direct de
   <body>), donc la règle .wp-site-blocks > header ne les concerne jamais et
   .site-header s'y retrouvait collé tout en haut de la page, sans le
   moindre espace au-dessus (signalé sur /inscription-repas en 2.20.3).
   header.php enveloppe désormais son menu dans .ucfas-header-offset pour ces
   gabarits, exactement pour porter ce padding-top — comme .wp-site-blocks >
   header ci-dessus, un padding est utilisé (pas une margin) : une margin
   directement sur .site-header, premier élément visible de <body>, collapse
   avec le haut du document et n'a aucun effet (vérifié en direct — piège
   déjà documenté plus haut pour le hero, retombé dans le même trou ici). */
.ucfas-header-offset {
  padding-top: 14px;
}
.site-header {
  /* position:relative confine le verre (::before, ci-dessous) à la
     pilule — mais SANS backdrop-filter/filter/transform directement ici :
     l'une de ces propriétés sur .site-header transformerait ce bloc en
     "containing block" pour ses descendants en position:fixed, ce qui
     casserait le panneau plein écran du menu mobile (.site-nav en
     position:fixed quand la case à cocher est cochée) — vérifié : le menu
     se retrouvait coincé dans les ~80px de la pilule au lieu de couvrir
     l'écran. Le flou vit donc sur un pseudo-élément séparé. */
  position: relative;
  /* z-index (2.20.2) : sur les gabarits PHP classiques (déclaration,
     adhésion, repas, liste des actualités — voir get_header()), .site-header
     n'est PAS niché dans le <header class="wp-block-template-part"> qui
     porte le z-index:1000 plus bas (cette balise n'existe que sur les
     gabarits 100% FSE) : sans son propre z-index, .site-header (auto ≈ 0)
     se ferait recouvrir par .page-title-band (z-index:1, voir plus bas)
     une fois ce dernier remonté sous le menu flottant. Le redéclarer ici
     n'a aucun effet indésirable sur les gabarits FSE (déjà au-dessus). */
  z-index: 1000;
  padding: 10px 28px;
  /* 2.7.93 : sur les très grands écrans (4K, ultra-wide), le header
     s'étirait bord à bord — le logo (taille fixe) se retrouvait tout
     petit dans un immense vide, avec le menu poussé loin à droite.
     On plafonne la largeur totale de la pilule (logo + menu) et on la
     centre ; "min(1560px, calc(100% - 32px))" garantit aussi une marge
     visible de chaque côté sur les écrans plus étroits que 1560px, pour
     que la pilule reste détachée du bord (et pas seulement plafonnée).
     Vérifié en direct sur dev.ucfas.fr (écran 4096px) avant publication. */
  width: min(1560px, calc(100% - 32px));
  margin: 0 auto;
  border-radius: 999px;
  /* Bordure + ombre renforcées (2.20.2) : sur les pages sans photo derrière
     le menu (toutes sauf l'accueil, voir le correctif .page-title-band plus
     haut dans ce fichier), une bordure blanche à 55% et une ombre à 15% sont
     quasi invisibles sur un fond déjà clair — la pilule se voyait alors
     comme un bandeau plat. Une bordure sombre très légère (au lieu de
     blanche) et une ombre à deux niveaux (contact fin + ombre portée) restent
     lisibles quel que soit le fond, y compris sur la photo d'accueil où
     l'effet reste discret. */
  border: 1px solid rgba(15, 23, 42, 0.08);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.05), 0 12px 28px rgba(15, 23, 42, 0.16);
  transition: all 0.3s ease;
}
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(255, 255, 255, 0.75);
  backdrop-filter: blur(22px) saturate(130%);
  -webkit-backdrop-filter: blur(22px) saturate(130%);
  z-index: -1;
  /* 2.20.71 : signalé par Alex sur "Inscription exposition" (capture à
     l'appui) — le fond derrière le menu flottant apparaissait en deux
     teintes (clair d'un côté, rosé de l'autre). Première tentative : forcer
     une couche de composition stable (translateZ + will-change) en misant
     sur un artefact de rendu GPU par tuiles — gardé ci-dessous par prudence
     (inoffensif) mais insuffisant : le problème est réapparu à l'identique
     après coup.
     2.20.73 : vraie cause identifiée en reproduisant le rendu en local à la
     largeur exacte de la capture d'Alex — ce n'est pas un artefact, c'est le
     fond ambiant diffus du thème (dégradés radiaux sur <body>, volontaires,
     voir plus haut) qui transparaît à travers le verre du menu : à
     55% d'opacité blanche, le blur + saturate(200%) laisse largement passer
     et amplifie ces dégradés (le rose à 10%/10% et le gris à 90%/25%), ce
     qui donne un menu visiblement teinté différemment à gauche et à droite
     selon la largeur d'écran (leur position dépend du viewport). Passer
     l'opacité du verre à 75% et ramener la saturation à 130% atténue ce
     dégradé résiduel jusqu'à le rendre imperceptible sur les pages au fond
     uni, tout en gardant l'effet "verre" flouté nettement visible sur la
     photo du hero en page d'accueil (vérifié en local sur les deux cas). */
  transform: translateZ(0);
  will-change: backdrop-filter;
}

.site-header .wp-block-site-title a {
  text-transform: uppercase;
  font-weight: 800;
  letter-spacing: 0.5px;
  color: var(--wp--preset--color--text) !important;
  text-shadow: 0 1px 10px rgba(255, 255, 255, 0.85);
}

.site-nav a {
  text-shadow: 0 1px 10px rgba(255, 255, 255, 0.75);
}

.site-brand {
  gap: 12px !important;
  align-items: center;
  flex-shrink: 1;
  /* Plancher (2.7.91) : le logo doit pouvoir se réduire pour laisser
     la place au menu, mais pas au point de devenir minuscule ou
     illisible sur les résolutions "moyennes" (tablette / petit
     laptop) où le menu desktop est encore affiché en entier. */
  min-width: 130px;
}
.site-brand img {
  max-height: 65px !important;
  width: 290px !important;
  max-width: 100% !important;
  min-width: 130px !important;
  height: auto !important;
  display: block;
  object-fit: contain;
  transition: max-height 0.3s ease, width 0.3s ease;
}

/* Petit clin d'œil canin : le logo remue au survol (et au focus clavier),
   même esprit que la patte animée de la page 404. */
.site-brand:hover img,
.site-brand:focus-within img {
  animation: ucfas-logo-wag 0.6s ease-in-out;
  transform-origin: 50% 85%;
}
@keyframes ucfas-logo-wag {
  0%, 100% {
    transform: rotate(0deg);
  }
  25% {
    transform: rotate(-6deg);
  }
  50% {
    transform: rotate(5deg);
  }
  75% {
    transform: rotate(-3deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .site-brand:hover img,
  .site-brand:focus-within img {
    animation: none;
  }
}

/* Suppression des marges parasites */
main.hero-section {
  margin-top: 0 !important;
}
.wp-site-blocks > * {
  margin-top: 0 !important;
}
/* Le hero (page d'accueil) remonte sous le header flottant, sinon il n'y a
   rien à flouter derrière le verre du menu tout en haut de la page — il
   paraît alors juste posé sur un fond uni (signalé après la mise en place
   du menu flottant, cf. version 2.17.0). -100px couvre la hauteur réelle
   du header (~95 à 99px selon les gabarits testés) avec une petite marge
   de sécurité ; le header garde un z-index supérieur (1000 contre 1 ici)
   donc il reste bien au-dessus du hero. Cette règle vient après le reset
   général ci-dessus pour le surcharger, et ne cible que le hero de la
   page d'accueil (seul gabarit où .hero-section est utilisé juste après
   le header — vérifié dans les templates). */
.wp-site-blocks > .hero-section {
  margin-top: -100px !important;
  position: relative;
  z-index: 1;
}

/* Même correctif que le hero ci-dessus, mais pour TOUTES les autres pages
   (signalé en 2.20.2 : "le menu apparaît sur une bande blanche, sauf sur
   la page d'accueil"). Le hero avait déjà été traité en 2.17.0, mais
   seulement lui : sur les gabarits page/single/résultats (templates/*.html)
   et sur les gabarits PHP classiques (déclaration, adhésion, repas, liste
   des actualités — get_header(), pas de <header> englobant), le bandeau
   titre .page-title-band suivait le menu flottant sans jamais passer
   dessous — le verre du menu n'avait donc rien à flouter derrière lui
   que le fond quasi blanc de la page, et se voyait comme un bandeau plat
   au lieu de la pilule flottante avec ombre. Deux sélecteurs sont
   nécessaires car .page-title-band ne suit pas le même élément selon le
   gabarit : le <header> englobant en FSE, .site-header directement en PHP
   classique (pas de <header> englobant sur ces gabarits-là). Le
   padding-top est augmenté d'autant que la marge est remontée, pour que le
   titre reste lisible sous le menu au lieu d'être caché derrière lui.
   2.20.74 : correctif du sélecteur PHP classique — signalé par Alex sur
   "Inscription exposition" (capture à l'appui, avec annotations montrant
   deux zones de couleur différente juste sous le menu) : en creusant les
   pixels de sa capture, la bande de titre change bien de teinte pile à la
   jonction avec le menu (mesuré : un saut nettement visible, la bordure de
   1px de .section-tint — voir plus bas dans ce fichier — se voit à cet
   endroit précis). Cause : ".site-header + .page-title-band" ne matche en
   réalité JAMAIS sur les gabarits PHP classiques (déclaration, adhésion,
   repas, demande d'affixe, inscription expo) — header.php enveloppe .site-
   header dans .ucfas-header-offset (voir plus haut dans ce fichier), donc
   .page-title-band est le frère suivant de .ucfas-header-offset, pas de
   .site-header. Le correctif "-100px" ne s'appliquait donc JAMAIS sur ces
   5 pages : leur bandeau de titre restait à sa position normale, sans
   remonter sous le menu flottant, exposant en plein jour son propre fond
   et sa bordure (.section-tint) juste sous le verre du menu — d'où le
   changement de couleur net et localisé à cette seule famille de pages
   (les gabarits FSE utilisent le bon sélecteur "header.wp-block-template-
   part" depuis le début, et ne sont pas concernés). Reproduit et vérifié
   en local (avant/après, sélecteur corrigé) : la jonction est bien
   invisible une fois .ucfas-header-offset ajouté comme sélecteur. */
header.wp-block-template-part + .page-title-band,
.site-header + .page-title-band,
.ucfas-header-offset + .page-title-band {
  margin-top: -100px !important;
  padding-top: calc(3rem + 100px) !important;
  position: relative;
  z-index: 1;
}
@media (max-width: 700px) {
  header.wp-block-template-part + .page-title-band,
  .site-header + .page-title-band,
  .ucfas-header-offset + .page-title-band {
    padding-top: calc(2.25rem + 100px) !important;
  }
}

/* ============================================
   SITKY FOOTER : quand une page a peu de contenu
   (ex: "Les commissions"), le footer reste collé
   en bas de l'écran au lieu de laisser un vide.
   ============================================ */
.wp-site-blocks {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  min-height: 100dvh;
}
/* Compense la barre d'admin WordPress (visible seulement en étant connecté) */
html.admin-bar .wp-site-blocks {
  min-height: calc(100vh - 32px);
  min-height: calc(100svh - 32px);
  min-height: calc(100dvh - 32px);
}
@media (max-width: 782px) {
  html.admin-bar .wp-site-blocks {
    min-height: calc(100vh - 46px);
    min-height: calc(100svh - 46px);
    min-height: calc(100dvh - 46px);
  }
}
/* Le contenu s'étire pour combler l'espace vide ; le footer garde sa taille normale et reste collé en bas */
.wp-site-blocks > .page-content,
.wp-site-blocks > main:not(.page-content),
.wp-site-blocks > .hero-section {
  flex: 1 0 auto;
}
.page-content {
  padding-top: 2.5rem;
  padding-bottom: 3rem;
}
@media (max-width: 700px) {
  .page-content {
    padding-top: 1.75rem;
    padding-bottom: 2rem;
  }
}
.wp-site-blocks > footer,
.wp-site-blocks > .site-footer {
  flex-shrink: 0;
}

/* Même principe de footer collant (2.20.5), mais pour les gabarits PHP
   classiques (déclaration, adhésion, repas, liste des actualités —
   get_header()/get_footer()) : ceux-ci n'ont pas de .wp-site-blocks (voir
   plus haut, section header flottant), donc rien ne les faisait bénéficier
   du même traitement — le footer ne restait "collé en bas" que par
   coïncidence, quand le contenu était assez long pour atteindre le bas de
   l'écran de lui-même (signalé : ça se voyait surtout sur les pages
   courtes, ex. le message "réservations fermées"). Voir la classe
   "ucfas-classic-template" posée sur <body> par header.php. */
body.ucfas-classic-template {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100svh;
  min-height: 100dvh;
}
html.admin-bar body.ucfas-classic-template {
  min-height: calc(100vh - 32px);
  min-height: calc(100svh - 32px);
  min-height: calc(100dvh - 32px);
}
@media (max-width: 782px) {
  html.admin-bar body.ucfas-classic-template {
    min-height: calc(100vh - 46px);
    min-height: calc(100svh - 46px);
    min-height: calc(100dvh - 46px);
  }
}
body.ucfas-classic-template > .page-content,
body.ucfas-classic-template > main:not(.page-content) {
  flex: 1 0 auto;
}
body.ucfas-classic-template > .ucfas-header-offset,
body.ucfas-classic-template > .page-title-band,
body.ucfas-classic-template > footer,
body.ucfas-classic-template > .site-footer {
  flex-shrink: 0;
}

/* ============================================
   BANDEAU TITRE (pages & articles)
   ============================================ */
.page-title-band {
  padding: 3rem 2rem 2.5rem;
  text-align: center;
}
.page-title-band h1 {
  font-size: clamp(1.8rem, 4vw, 2.6rem);
  margin: 0.3rem 0 0;
}
.single-post-date {
  display: block;
  margin-top: 0.6rem;
  color: var(--wp--preset--color--muted, #475569);
  font-size: 0.9rem;
}
@media (max-width: 700px) {
  .page-title-band {
    padding: 2.25rem 1.5rem 1.75rem;
  }
}

/* ============================================
   CARTE DE CONTENU (pages & articles)
   ============================================ */
.content-card {
  padding: 2.5rem 2.75rem !important;
  max-width: 800px;
  margin: 0 auto;
}
/* 2.7.99 : même piège que .ucfas-level-card — quand plusieurs
   ".content-card" sont empilées sur une même page (ex. "Le Standard
   de l'UCFAS et son évolution"), elles n'ont aucune marge verticale
   propre et se touchent bord à bord. Ne s'applique qu'entre cartes
   empilées : les pages avec une seule carte (la grande majorité) ne
   sont pas concernées. */
.content-card + .content-card {
  margin-top: 2rem;
}
/* 2.15.5 : le gabarit "Page" (templates/page.html) enveloppe TOUJOURS le
   contenu dans une .content-card ("verre clair", 65% opaque, cf.
   .is-glass dans theme.json). Sur les pages qui contiennent elles-mêmes
   plusieurs sections .content-card / .ucfas-level-card (ex : pages
   "Dépistages", "Nanisme Hypophysaire ou NAH"), ces sections imbriquées
   héritaient du même fond translucide à 65% que leur conteneur : deux
   calques quasi identiques superposés, donc peu de contraste, cartes peu
   visibles/peu distinctes. On réutilise le jeton de couleur existant
   "glass-strong" (85% opaque, déjà défini dans theme.json) pour les
   cartes imbriquées uniquement, avec bordure et ombre plus marquées —
   sans toucher aux pages à une seule carte (non concernées par ce
   sélecteur). */
.content-card .content-card,
.content-card .ucfas-level-card {
  background: var(--wp--preset--color--glass-strong, rgba(255, 255, 255, 0.85)) !important;
  border: 1px solid rgba(30, 41, 59, 0.14) !important;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.10), inset 0 1px 0 rgba(255, 255, 255, 0.75) !important;
}
/* Correctif : double cadre imbriqué, généralisé à TOUTES les pages
   concernées (2.20.6). Signalé sur /ucfas/statuts, /ucfas/adhesions,
   /ucfas/le-reglement, /ucfas/les-commissions, /confirmation,
   /titre-initial — et en réalité présent, en amont, sur ~30 pages du site.
   Cause : le gabarit "Page" (templates/page.html) enveloppe TOUJOURS le
   contenu dans un groupe ".is-glass.content-card". Une trentaine de pages
   (Statuts, Adhésions, Le règlement, Les commissions, Confirmation, Titre
   initial, Dysplasies, Dépistages, Obéissance, etc.) ont un contenu qui
   commence lui-même par un groupe ".is-glass.content-card" identique (issu
   des patterns du thème, dossier patterns/) — d'où deux cadres vitrés
   RIGOUREUSEMENT identiques superposés (contrairement au cas ci-dessus,
   où la carte imbriquée est un type de carte différent — ucfas-level-card
   — et reste voulue/distincte). Corrigé en neutralisant entièrement le
   cadre interne (fond, flou, bordure, ombre, arrondi, marge/padding)
   quand un ".is-glass.content-card" se retrouve imbriqué dans un autre
   ".is-glass.content-card" : il ne reste plus qu'un seul cadre visible
   (l'extérieur), le contenu de la page venant simplement s'y loger. Cette
   règle, plus spécifique que celle ci-dessus (4 classes contre 2), la
   prend le pas uniquement pour ce cas précis — les autres cartes
   imbriquées (ucfas-level-card, card-item, ucfas-decl-card...) ne sont pas
   concernées et gardent leur distinction visuelle. Un correctif ciblé
   avait déjà retiré "is-glass" du gabarit spécifique à 3 pages de
   formulaire en 2.20.5 (Inscription repas, Adhésion, Déclaration de
   portée) ; cette règle-ci couvre, elle, toutes les pages de contenu
   "classiques" construites à partir des patterns du thème. Les fichiers
   patterns/*.php ont aussi été nettoyés (is-glass retiré de leur groupe
   racine) pour que les prochaines insertions ne recréent pas le problème,
   mais c'est bien cette règle CSS qui corrige les pages déjà publiées. */
.content-card.is-glass .content-card.is-glass {
  background: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
  max-width: none !important;
  margin: 0 !important;
}
/* Correctif : double cadre, cas de la fiche ".ucfas-level-card" UNIQUE
   (2.20.8). Signalé sur /confirmation-renforcee, où le contenu de la page
   ne comporte qu'UNE seule fiche ".ucfas-level-card" (le paragraphe
   "Exigences") au milieu de sections ".content-card" ordinaires — la règle
   2.20.6 ci-dessus ne couvrait que le cas ".content-card" imbriqué dans
   ".content-card" et laissait volontairement les ".ucfas-level-card" de
   côté, car sur des pages comme Obéissance ou Protocole de seconde
   lecture plusieurs fiches ".ucfas-level-card" se suivent (Niveau 1, 2,
   3... ou les deux protocoles) et DOIVENT rester visuellement distinctes
   les unes des autres. Mais une page qui n'a qu'UNE SEULE fiche
   ".ucfas-level-card" (Adhésions, Confirmation renforcée, Dépistages MD/
   MDR1, Dysplasies hanches/coudes, Identifications ADN, Nanisme
   hypophysaire, Titre initial, VTL — une dizaine de pages en tout) n'a
   personne d'autre à se distinguer : cette fiche isolée se retrouve donc,
   comme les ".content-card" ci-dessus, avec un second cadre superposé au
   cadre de la page. Plutôt que de figer la liste des pages concernées
   (qui pourrait s'allonger), la règle ci-dessous détecte directement en
   CSS le cas "aucune fiche sœur du même type" via :has() : elle ne
   neutralise une ".ucfas-level-card" que si elle est la SEULE parmi les
   enfants directs de son conteneur — les pages à fiches multiples
   (Obéissance, Protocole de seconde lecture, Recherche utilitaire,
   Activités d'attelage, Les couleurs) ne sont pas concernées et gardent
   leurs fiches distinctes, exactement comme avant. Le badge (ex.
   "EXIGENCES") reste affiché tel quel : seul le cadre autour du texte est
   retiré. */
.wp-block-group:has( > .is-glass.ucfas-level-card ):not(:has( > .is-glass.ucfas-level-card ~ .is-glass.ucfas-level-card )) > .is-glass.ucfas-level-card {
  background: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  border: none !important;
  box-shadow: none !important;
  border-radius: 0 !important;
  padding: 0 !important;
}
.content-card p,
.content-card li {
  color: var(--wp--preset--color--muted, #475569);
}
.content-card h2,
.content-card h3 {
  color: var(--wp--preset--color--text, #1E293B);
}

/* Centre les images du contenu qui n'ont pas d'alignement explicite (gauche/droite/large/pleine largeur) */
.content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide) {
  text-align: center;
  margin-left: auto;
  margin-right: auto;
}
.content-card .wp-block-image:not(.alignleft):not(.alignright) img {
  margin-left: auto;
  margin-right: auto;
  display: block;
}
.content-card img {
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(30, 41, 59, 0.08);
}
/* Sur grand écran, les images qui n'ont pas de légende propre flottent en
   alternance à côté du texte plutôt que de couper la lecture par un bloc
   pleine largeur — un peu d'air texte/photo au lieu d'un empilement.
   Les images légendées (suivies d'un paragraphe italique) restent centrées :
   elles sont pensées pour être regardées seules. */
@media (min-width: 900px) {
  /* 2.20.39 : ":has(+ p > em:only-child)" repérait le paragraphe suivant
     comme une légende dès qu'il commençait par un <em>, même quand du texte
     normal suivait ("*Vue de face* — merci à J. Dupont") — même limite que
     le bug du gras documenté plus bas (:only-child ignore le texte brut).
     Remplacé par la classe .ucfas-caption-italic, posée par
     assets/js/standalone-bold-fix.js seulement sur les vraies légendes
     (paragraphe qui ne contient RIEN d'autre que l'italique). */
  .content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)) {
    max-width: 320px;
    text-align: left;
  }
  .content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)) img {
    margin: 0;
  }
  .content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)):nth-of-type(odd) {
    float: right;
    margin: 0.3rem 0 1.25rem 2.25rem;
  }
  .content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)):nth-of-type(even) {
    float: left;
    margin: 0.3rem 2.25rem 1.25rem 0;
  }
  /* 2.20.49 : le flottement alterné ci-dessus suppose UNE photo à côté de
     SON texte. Quand deux de ces photos (contenu ancien migré, aucun texte
     entre les deux) se suivent directement, l'une flotte à droite et
     l'autre à gauche : il ne reste qu'un étroit couloir entre les deux, où
     le paragraphe suivant se retrouve coincé — une phrase courte s'y
     affichait coupée en deux (« Merci à nos » écrasé entre les photos,
     puis le reste de la phrase repassant à la ligne en dessous une fois le
     couloir épuisé). Signalé par Alex sur une page de résultats migrée
     (régionale d'élevage, mars 2018), capture à l'appui. Dès que deux
     photos non légendées se suivent sans texte entre elles, on force le
     paragraphe qui vient juste après à repasser sous les deux plutôt que
     de tenter de se glisser dans cet espace résiduel — vérifié par
     reconstitution du motif exact (deux photos 320px + courte phrase)
     avant/après ce correctif. */
  .content-card .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)) + .wp-block-image:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide):not(.aligncenter):not(:has(+ p.ucfas-caption-italic)) + p {
    clear: both;
  }
  .content-card h2,
  .content-card h3 {
    clear: both;
  }
}
/* 2.7.97 : image mise en avant des articles individuels réduite —
   auparavant pleine largeur de la carte (jusqu'à ~700px de haut sur les
   grands écrans), désormais une vignette centrée et sobre au-dessus du
   texte de l'article, avec un léger effet au survol (soulèvement +
   zoom doux sur l'image), assorti au style des cartes actualités. */
.single-featured-image {
  margin: 0 auto 1.75rem;
  max-width: 480px;
  overflow: hidden;
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s ease;
}
.single-featured-image:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 38px rgba(15, 23, 42, 0.16);
}
.single-featured-image img {
  width: 100%;
  height: 260px;
  object-fit: cover;
  display: block;
  transition: transform 0.5s ease;
}
.single-featured-image:hover img {
  transform: scale(1.06);
}
@media (max-width: 560px) {
  .single-featured-image {
    max-width: 100%;
  }
  .single-featured-image img {
    height: 220px;
  }
}

/* Images insérées au milieu d'un paragraphe de texte, sans classe
   d'alignement (contenu ancien migré depuis l'ancien thème) : par défaut
   elles s'affichaient à la taille brute de la miniature, en plein milieu
   d'une phrase. On les fait flotter proprement à droite, comme une
   illustration, plutôt que de laisser le texte se couper autour. */
.content-card p img:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide) {
  float: right;
  max-width: 240px;
  width: 100%;
  height: auto;
  margin: 4px 0 14px 22px;
}
@media (max-width: 700px) {
  .content-card p img:not(.alignleft):not(.alignright):not(.alignfull):not(.alignwide) {
    float: none;
    display: block;
    max-width: 100%;
    margin: 14px auto;
  }
}

/* Sécurité mobile : sous 900px, aucune image de contenu ne doit
   flotter — le float « alterné » plus haut est pensé uniquement pour
   le grand écran (texte à côté de la photo). Sur un écran étroit, ce
   même flottement produit une colonne de texte illisible coincée à
   côté de l'image (cf. retours utilisateur). On neutralise donc tout
   flottement avec !important pour éviter toute fuite de la règle
   desktop, quelle qu'en soit la cause. */
@media (max-width: 899px) {
  .content-card .wp-block-image {
    float: none !important;
    text-align: center !important;
    max-width: 100% !important;
    margin-left: auto !important;
    margin-right: auto !important;
  }
  .content-card .wp-block-image img {
    float: none !important;
    margin-left: auto !important;
    margin-right: auto !important;
    display: block !important;
    max-width: 100% !important;
    height: auto !important;
  }
}

/* Galeries et colonnes de blocs dans le contenu : centrées, qui
   s'enroulent proprement et se réempilent sur mobile plutôt que de
   déborder ou de rester collées à un bord. */
.content-card .wp-block-gallery,
.content-card .wp-block-columns {
  display: flex !important;
  flex-wrap: wrap !important;
  justify-content: center !important;
  align-items: flex-start;
  gap: 12px;
  margin: 1.5rem auto;
}
.content-card .wp-block-gallery figure,
.content-card .wp-block-gallery .wp-block-image {
  margin: 0;
  flex: 0 1 auto;
}
.content-card .wp-block-gallery img,
.content-card .wp-block-columns img {
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(30, 41, 59, 0.08);
  max-width: 100%;
  height: auto;
}
@media (max-width: 600px) {
  .content-card .wp-block-columns {
    flex-direction: column;
    align-items: center;
  }
  .content-card .wp-block-column {
    width: 100% !important;
    flex-basis: 100% !important;
  }
}

/* Rythme vertical un peu plus aéré pour les longues pages de contenu */
.content-card p {
  line-height: 1.75;
  margin-bottom: 1.1rem;
}

/* Citations et listes en retrait (ex. "Les questions à se poser avant...") :
   habillées en encart verre avec liseré d'accent, plutôt que la citation
   par défaut du navigateur. */
.content-card blockquote {
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-left: 4px solid var(--wp--preset--color--accent, #F60B51);
  border-radius: 14px;
  padding: 1.25rem 1.75rem;
  margin: 1.75rem 0;
}
.content-card blockquote p {
  margin: 0.4rem 0;
  line-height: 1.6;
}
.content-card blockquote p:first-child {
  margin-top: 0;
}
.content-card blockquote p:last-child {
  margin-bottom: 0;
}

/* Correctif radical pour les images centrées explicitement (aligncenter) :
   WordPress ajoute parfois display:table/inline-block sur une figure
   "is-resized", ce qui peut casser le centrage par margin:auto selon le
   contexte. On force ici tous les axes possibles avec !important pour
   ne plus dépendre de la cause exacte, et on empêche la légende
   d'hériter d'une largeur réduite (rétrécie au texte le plus long,
   provoquant un retour à la ligne mot par mot). */
.content-card .wp-block-image.aligncenter {
  display: block !important;
  float: none !important;
  clear: both !important;
  width: 100% !important;
  max-width: 100% !important;
  margin-left: auto !important;
  margin-right: auto !important;
  text-align: center !important;
}
.content-card .wp-block-image.aligncenter img {
  display: block !important;
  float: none !important;
  margin-left: auto !important;
  margin-right: auto !important;
}
.content-card .wp-block-image.aligncenter figcaption {
  display: block !important;
  width: 100% !important;
  max-width: 100% !important;
  text-align: center !important;
  margin-left: auto !important;
  margin-right: auto !important;
}

/* Légende sous une image : un paragraphe entièrement en italique juste après
   un bloc image est traité comme une légende discrète plutôt qu'une citation.

   2.20.39 : s'appuyait auparavant directement sur ".wp-block-image + p >
   em:only-child", avec la même limite que le bug du gras documenté plus bas
   (:only-child ignore le texte brut qui suit l'<em> — un paragraphe comme
   "*Vue de face* — merci à J. Dupont pour la photo" était donc à tort pris
   pour une légende autonome). Détection désormais faite en JS, comme pour
   le gras (voir assets/js/standalone-bold-fix.js) : la classe
   .ucfas-caption-italic n'est posée que sur les vrais paragraphes qui ne
   contiennent RIEN d'autre que l'italique, juste après une image. */
.content-card p.ucfas-caption-italic > em {
  display: block;
  text-align: center;
  font-size: 0.82rem;
  font-style: italic;
  color: var(--wp--preset--color--muted, #64748B);
  margin-top: -0.6rem;
  margin-bottom: 1.75rem;
}

/* Paragraphe entièrement en italique ailleurs dans le texte : mis en avant
   comme une phrase clé plutôt que noyé dans le reste du contenu.

   2.20.39 : même correctif que ci-dessus — ".ucfas-standalone-italic" posée
   en JS remplace le sélecteur brut "p > em:only-child", qui traitait à tort
   comme phrase-clé autonome tout paragraphe où l'italique était juste
   suivi d'un mot ou d'une ponctuation sans lien (même bug que celui déjà
   corrigé pour le gras en 2.18.0, voir plus bas dans ce fichier). */
.content-card p.ucfas-standalone-italic > em {
  display: block;
  font-size: 1.08rem;
  font-style: italic;
  color: var(--wp--preset--color--text, #1E293B);
  text-align: center;
  padding: 0.5rem 1.5rem;
  margin: 1.75rem 0;
}
@media (max-width: 700px) {
  .content-card {
    padding: 1.75rem 1.5rem !important;
  }
}

/* Paragraphe entièrement en gras : utilisé un peu partout comme mini-titre
   (question de FAQ, mention "NB.", avertissement) mais avec le gras par
   défaut du navigateur, peu visible. On le fait ressortir avec la couleur
   d'accent et un liseré, sans savoir s'il s'agit d'une question ou d'une
   alerte — les deux usages s'accommodent bien de cette mise en avant.
   Exception : un paragraphe qui ne contient qu'un lien vers un PDF est
   traité à part, en vrai bouton de téléchargement (règle suivante).

   2.18.0 : cette règle s'appuyait auparavant directement sur
   `strong:only-child`, qui ne compte que les enfants-ÉLÉMENT du paragraphe.
   Un <strong> suivi de texte brut ("**Nom** reste de la phrase") est donc vu
   par CSS comme "seul enfant" au même titre qu'un vrai mini-titre autonome
   — CSS n'a aucun moyen d'inspecter le contenu des nœuds texte dans un
   sélecteur pour faire la différence (cf. les correctifs ponctuels 2.7.95
   et 2.9.1 ci-dessous, qui contournaient le problème au cas par cas plutôt
   que de le résoudre). La détection fiable ("y a-t-il vraiment autre chose
   que ce <strong> dans le paragraphe ?") est maintenant faite une fois en
   JS au chargement de la page (assets/js/standalone-bold-fix.js), qui
   ajoute la classe .ucfas-standalone-bold uniquement sur les vrais
   paragraphes autonomes. La mise en avant ci-dessous ne s'active donc plus
   que sur cette classe, pas sur le sélecteur brut — ce qui corrige d'un
   coup tous les cas de ce type sur les ~150 pages existantes, sans avoir à
   les chercher un par un ni à ajouter une classe manuelle sur chacune. */
.content-card p.ucfas-standalone-bold > strong {
  display: block;
  font-size: 1.02rem;
  color: var(--wp--preset--color--accent, #F60B51);
  margin: 1.75rem 0 0.6rem;
  padding-left: 14px;
  border-left: 3px solid rgba(246, 11, 81, 0.4);
}

/* 2.7.95 : effet de bord non voulu de la règle ci-dessus sur les listes
   numérotées "Comment procéder" (.ucfas-exercise). "N." est en <strong>
   suivi de texte brut (pas d'élément) — :only-child ne comptant que les
   enfants-ÉLÉMENT, ce texte brut est invisible pour le sélecteur, donc
   "N." était pris à tort pour un paragraphe entièrement en gras... sauf
   quand l'étape contenait un lien (mailto, PDF...), qui lui compte comme
   enfant-élément et désactivait l'effet. Résultat : un numéro sur deux
   affiché différemment selon la présence d'un lien dans le texte de
   l'étape. On force un affichage toujours inline et sobre pour ces
   numéros, quel que soit le contenu de l'étape. */
.ucfas-level-card .ucfas-exercise > strong:only-child {
  display: inline !important;
  font-size: inherit !important;
  color: var(--wp--preset--color--text, #1E293B) !important;
  margin: 0 !important;
  padding-left: 0 !important;
  border-left: none !important;
}

/* 2.9.1 : même piège que ci-dessus (:only-child qui ignore le texte brut),
   rencontré cette fois sur des paragraphes "gagnant" du type "**SHINE**
   de la Légende du Loup Noir à M et Mme WENTZEL" — un nom en gras suivi
   du reste de la phrase en texte normal, pas un vrai encadré. À l'époque,
   seul contournement possible : ajouter à la main la classe is-inline-bold
   (bloc Paragraphe > Avancé > Classe CSS additionnelle) sur chaque
   paragraphe concerné. Depuis 2.18.0 la détection est automatique (voir le
   correctif ci-dessus) et cette classe manuelle n'est normalement plus
   nécessaire sur les nouveaux contenus — elle reste supportée pour ne pas
   casser les pages qui l'utilisent déjà, et comme échappatoire manuelle si
   un cas imprévu passait malgré tout entre les mailles du script JS. */
.content-card p.is-inline-bold > strong {
  display: inline !important;
  font-size: inherit !important;
  color: inherit !important;
  margin: 0 !important;
  padding-left: 0 !important;
  border-left: none !important;
}

/* Lien vers un PDF, seul dans son paragraphe : mis en avant comme un vrai
   bouton de téléchargement plutôt que du texte en gras souligné.
   2.18.0 : même correctif que la règle "mini-titre" ci-dessus — activé via
   la classe .ucfas-pdf-button posée par le script JS (paragraphe vérifié
   comme ne contenant vraiment rien d'autre que le lien PDF), plus fiable
   que :only-child seul. */
.content-card p.ucfas-pdf-button {
  text-align: center;
  margin: 1.75rem 0;
}
.content-card p.ucfas-pdf-button > strong > a {
  display: inline-block;
  background: linear-gradient(135deg, #F60B51, #D00742);
  color: #ffffff !important;
  text-decoration: none !important;
  border-radius: 30px;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.82rem;
  letter-spacing: 0.5px;
  padding: 12px 28px;
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.content-card p.ucfas-pdf-button > strong > a:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(246, 11, 81, 0.3);
}

/* Séparateurs : discrets et élégants, utiles pour structurer les longues listes
   (ex. page Éleveurs affiliés) — mais masqués s'ils se retrouvent en toute fin
   de contenu (ex. juste avant le footer), où ils n'ont aucun rôle. */
.page-content hr,
.page-content .wp-block-separator,
.content-card hr,
.content-card .wp-block-separator {
  display: block;
  border: none;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(148, 163, 184, 0.45), transparent);
  margin: 2.25rem 0;
}
.content-card hr:last-child,
.content-card .wp-block-separator:last-child {
  display: none;
}

/* ============================================
   MENU BURGER 100% CSS
   ============================================ */
.ucfas-menu-toggle-checkbox {
  display: none;
}

#ucfas-mobile-nav {
  display: none;
}

.ucfas-menu-toggle-label {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 32px;
  height: 24px;
  cursor: pointer;
  z-index: 100000;
}
.ucfas-menu-toggle-label span {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--wp--preset--color--text);
  border-radius: 2px;
  transition: transform 0.25s ease, opacity 0.25s ease;
}

.site-nav {
  font-family: 'Sora', var(--wp--preset--font-family--system);
}
.site-nav a {
  text-transform: uppercase;
  font-weight: 600;
  font-size: 0.78rem;
  letter-spacing: 0.4px;
  padding: 8px 10px;
  border-radius: 8px;
  color: var(--wp--preset--color--muted) !important;
  transition: all 0.2s ease;
  white-space: nowrap;
}
.site-nav a:hover {
  color: var(--wp--preset--color--accent) !important;
  background: var(--wp--preset--color--accent-soft);
}

/* Empêche le menu desktop de passer à la ligne */
.site-header {
  flex-wrap: nowrap !important;
}
.site-nav .wp-block-navigation__container {
  flex-wrap: nowrap !important;
}
.site-nav,
.site-nav .wp-block-navigation__container,
.site-nav .wp-block-navigation-item {
  white-space: nowrap;
}
/* 2.7.92 : retour en arrière sur la tentative 2.7.91 de laisser le
   menu se réduire — un "overflow-x: auto" sur .site-nav bascule aussi
   overflow-y en "auto" (comportement standard CSS), ce qui rognait
   les sous-menus (positionnés en absolute, censés déborder du
   conteneur) et rendait le menu inutilisable. Le menu redevient
   protégé comme avant (jamais rétréci) ; seul le logo garde son
   plancher de taille (cf. .site-brand ci-dessus). */
.site-header .site-nav {
  flex-shrink: 0;
}
.site-nav .wp-block-navigation__submenu-container {
  background: rgba(255, 255, 255, 0.9) !important;
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 14px;
  box-shadow: 0 10px 35px rgba(0, 0, 0, 0.08);
  padding: 8px;
  z-index: 9999 !important;
  max-height: 80vh;
  max-width: 260px;
  overflow-y: auto;
}
.site-nav .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  white-space: normal;
}

/* Signal "inscriptions ouvertes" dans le menu Manifestations (voir
   functions.php, ucfas_glass_enqueue_nav_active_registrations(), et
   assets/js/nav-active-registrations.js qui pose ces éléments) — pastille
   sur le libellé du menu, entrée mise en avant en tête du sous-menu.
   Ajouté aussi bien pour le menu desktop (.site-nav) que pour le tiroir
   mobile (#ucfas-mobile-nav), qui partagent la même structure de classes. */
.site-nav .ucfas-nav-active-dot,
#ucfas-mobile-nav .ucfas-nav-active-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #F60B51;
  margin-left: 6px;
  vertical-align: super;
}
.site-nav .wp-block-navigation__submenu-container .ucfas-nav-active-item > .wp-block-navigation-item__content,
#ucfas-mobile-nav .ucfas-nav-active-item > .wp-block-navigation-item__content {
  background: rgba(246, 11, 81, 0.09) !important;
  color: #F60B51 !important;
  font-weight: 700 !important;
  border-radius: 8px;
}

/* À partir du 3ᵉ niveau imbriqué, on ouvre vers la gauche au lieu de continuer
   vers la droite, pour ne plus sortir de l'écran sur les menus très profonds
   (Manifestations > Expositions > Année > Exposition > Résultats). */
.site-nav .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
  left: auto !important;
  right: 100% !important;
}
.site-nav .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container .wp-block-navigation__submenu-container {
  left: auto !important;
  right: 100% !important;
}

@media (max-width: 1320px) {
  /* Le menu desktop (.site-nav) a "flex-shrink: 0" et "white-space: nowrap"
     sur tous ses éléments : il ne rétrécit et ne passe jamais à la ligne
     (cf. commentaire 2.7.92 plus haut). Son contenu actuel nécessite
     environ 1255px de large (logo + libellés). Le seuil de bascule vers
     le menu burger était fixé à 782px, un cran typique "mobile only" :
     entre 783px et ~1255px (tablettes en portrait, téléphones larges en
     paysage — donc bel et bien "sur mobile"), le menu desktop restait
     affiché mais débordait du viewport, provoquant un scroll horizontal
     intermittent. Seuil relevé à 1320px (marge de sécurité) pour couvrir
     ces largeurs et n'afficher le menu desktop que là où il tient vraiment. */
  html, body {
    overflow-x: hidden;
  }

  .ucfas-menu-toggle-label {
    display: flex;
  }
  .site-header .site-nav {
    display: none;
  }
  #ucfas-mobile-nav {
    display: none;
  }

  /* --- Repli : menu simple, liste complète. Actif par défaut. --- */
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav {
    display: block !important;
    position: fixed !important;
    top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
    background: rgba(255, 255, 255, 0.92) !important;
    backdrop-filter: blur(25px) saturate(180%) !important;
    -webkit-backdrop-filter: blur(25px) saturate(180%) !important;
    padding: 90px 28px 40px !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    z-index: 999999 !important;
  }  .ucfas-menu-toggle-checkbox:checked ~ .site-nav .wp-block-navigation__container {
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 8px !important;
    opacity: 1 !important;
    visibility: visible !important;
    width: 100%;
    white-space: normal !important;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav .wp-block-navigation-item {
    display: block !important;
    width: 100%;
    opacity: 1 !important;
    visibility: visible !important;
    white-space: normal !important;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav a,
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav .wp-block-navigation-item__content {
    font-size: 1.05rem;
    padding: 14px 12px;
    display: block !important;
    width: 100%;
    color: var(--wp--preset--color--text, #1E293B) !important;
    opacity: 1 !important;
    visibility: visible !important;
    /* Les libellés générés (ex. noms d'expositions/évènements) peuvent être
       très longs : sans ce reset, le "white-space: nowrap" du menu desktop
       (hérité via .site-nav) les empêche de passer à la ligne et fait
       déborder le panneau plein écran horizontalement — c'est la cause du
       scroll horizontal "aléatoire" sur mobile. */
    white-space: normal !important;
    word-break: break-word !important;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav .wp-block-navigation__submenu-container {
    position: static;
    background: transparent !important;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    box-shadow: none;
    padding-left: 16px;
  }

  /* --- Tiroirs : dès que la copie a réussi, elle prend le relais du repli --- */
  html.has-drilldown-nav .ucfas-menu-toggle-checkbox:checked ~ .site-nav {
    display: none !important;
  }
  html.has-drilldown-nav .ucfas-menu-toggle-checkbox:checked ~ #ucfas-mobile-nav {
    display: block !important;
    position: fixed !important;
    top: 0 !important; left: 0 !important; right: 0 !important; bottom: 0 !important;
    background: rgba(255, 255, 255, 0.92) !important;
    backdrop-filter: blur(25px) saturate(180%) !important;
    -webkit-backdrop-filter: blur(25px) saturate(180%) !important;
    padding: 90px 28px 40px !important;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    z-index: 999999 !important;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .site-nav::before,
  html.has-drilldown-nav .ucfas-menu-toggle-checkbox:checked ~ #ucfas-mobile-nav::before {
    content: "";
    position: fixed;
    bottom: 10px;
    right: 10px;
    width: 200px;
    height: 200px;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 52c-13 0-22 10-22 22 0 11 9 18 22 18s22-7 22-18c0-12-9-22-22-22z' fill='%23778ead' fill-opacity='0.08'/%3E%3Cellipse cx='21' cy='42' rx='9' ry='13' fill='%23778ead' fill-opacity='0.08' transform='rotate(-22 21 42)'/%3E%3Cellipse cx='38' cy='22' rx='10' ry='15' fill='%23778ead' fill-opacity='0.08' transform='rotate(-8 38 22)'/%3E%3Cellipse cx='60' cy='22' rx='10' ry='15' fill='%23778ead' fill-opacity='0.08' transform='rotate(8 60 22)'/%3E%3Cellipse cx='78' cy='42' rx='9' ry='13' fill='%23778ead' fill-opacity='0.08' transform='rotate(22 78 42)'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: bottom right;
    background-size: contain;
    pointer-events: none;
    z-index: 0;
  }
  #ucfas-mobile-nav > ul {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    width: 100%;
    position: static;
    background: transparent;
    border: none;
    box-shadow: none;
    padding: 0;
    list-style: none;
    margin: 0;
  }
  /* Les sous-niveaux pas encore ouverts (imbriqués plus profondément à
     l'intérieur du niveau actuellement affiché) restent masqués. */
  #ucfas-mobile-nav > ul ul {
    display: none !important;
  }
  #ucfas-mobile-nav .wp-block-navigation-item {
    display: block;
    width: 100%;
  }
  #ucfas-mobile-nav a,
  #ucfas-mobile-nav .wp-block-navigation-item__content {
    font-size: 1.05rem;
    padding: 14px 12px;
    display: block;
    width: 100%;
    color: #1E293B;
    text-decoration: none;
    text-transform: uppercase;
    letter-spacing: 0.4px;
  }
  #ucfas-mobile-nav li.has-child > a,
  #ucfas-mobile-nav li.has-child > .wp-block-navigation-item__content {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
  #ucfas-mobile-nav li.has-child > a::after,
  #ucfas-mobile-nav li.has-child > .wp-block-navigation-item__content::after {
    content: "\203A";
    color: #cbd5e1;
    font-size: 1.3rem;
    font-weight: 700;
    margin-left: 8px;
  }
  .drill-back-item {
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 10px 12px 14px;
    margin-bottom: 8px;
    border-bottom: 1px solid rgba(226, 232, 240, 0.8);
  }
  .drill-back {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #F60B51;
    font-weight: 800;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    cursor: pointer;
    padding: 6px 12px 6px 8px;
    border-radius: 20px;
    background: rgba(246, 11, 81, 0.08);
  }

  /* --- Animation du burger : commune aux deux versions --- */
  .ucfas-menu-toggle-checkbox:checked ~ .ucfas-menu-toggle-label span:nth-child(1) {
    transform: translateY(7px) rotate(45deg);
  }
  .ucfas-menu-toggle-checkbox:checked ~ .ucfas-menu-toggle-label span:nth-child(2) {
    opacity: 0;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .ucfas-menu-toggle-label span:nth-child(3) {
    transform: translateY(-7px) rotate(-45deg);
  }
  /* Bug signalé par Alex : une fois le menu ouvert, le bouton (déjà animé
     en croix ci-dessus) restait en position:static — sans position, son
     z-index:100000 (cf. règle de base) n'a aucun effet, et le panneau
     plein écran (z-index:999999, cf. règles .site-nav/#ucfas-mobile-nav
     "checked" plus haut) le recouvre entièrement. Résultat : la croix
     existe bien mais est invisible et inatteignable une fois le menu
     ouvert, seul un lien du menu permet d'en sortir. On la repasse en
     position:fixed avec un z-index supérieur à celui du panneau, pour
     qu'elle réapparaisse au même endroit (haut droite) par-dessus le menu
     ouvert et reste cliquable pour le refermer — même <label>, aucune
     nouvelle logique JS.
     2.20.160 : sur demande d'Alex, le fond rond translucide initialement
     ajouté pour la lisibilité est retiré, et la croix passe en couleur
     accent (rose) plutôt que la couleur texte du hamburger fermé, pour
     mieux ressortir sur le panneau flouté derrière elle. */
  .ucfas-menu-toggle-checkbox:checked ~ .ucfas-menu-toggle-label {
    position: fixed;
    top: 18px;
    right: 24px;
    width: 40px;
    height: 40px;
    z-index: 1000001;
  }
  .ucfas-menu-toggle-checkbox:checked ~ .ucfas-menu-toggle-label span {
    background: var(--wp--preset--color--accent, #F60B51);
  }
}

/* Hero Section */
.hero-section {
  position: relative;
  z-index: 1 !important;
  overflow: hidden;
  min-height: 70vh;
}
.hero-slideshow {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
}
.hero-slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  opacity: 0;
  will-change: opacity, transform;
  animation-name: ucfasHeroSlideFade;
  animation-duration: var(--hero-cycle, 60s);
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
}
.hero-slide:first-child {
  opacity: 1; /* filet de sécurité si les animations CSS ne s'exécutent pas */
}
.hero-dim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, rgba(15, 23, 42, 0.08), rgba(15, 23, 42, 0.3));
  pointer-events: none;
}
.hero-inner {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  width: 100%;
  min-height: 70vh;
  padding: 0 5% 40px;
  text-align: center;
}
.hero-bar {
  width: 100%;
  max-width: 1100px;
  margin: 0 auto;
  background: rgba(255, 255, 255, 0.28) !important;
  backdrop-filter: blur(16px) saturate(180%);
  -webkit-backdrop-filter: blur(16px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.4) !important;
  border-radius: 18px;
  padding: 14px 16px 14px 28px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.4);
  text-align: left;
}
.hero-bar h1 {
  font-size: clamp(0.95rem, 1.8vw, 1.3rem);
  margin: 0;
  font-weight: 700;
  color: var(--wp--preset--color--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  text-shadow: 0 1px 12px rgba(255, 255, 255, 0.5);
}
.hero-bar .wp-block-buttons {
  margin: 0;
  flex-shrink: 0;
}
/* Groupe de boutons centré avec espace entre eux (ex : page Embark) -
   classe de bloc additionnelle "buttons-centered" ajoutée volontairement
   au bloc concerné, pour ne pas changer tous les groupes de boutons
   du site (le thème n'active pas les styles de mise en page flex de
   Gutenberg, donc l'attribut "layout" seul du bloc buttons ne suffit
   pas : il faut ces règles explicites). */
.wp-block-buttons.buttons-centered {
  display: flex !important;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 16px;
}
@media (max-width: 700px) {
  .hero-bar {
    flex-direction: column;
    text-align: center;
    padding: 16px 18px;
    gap: 12px;
    border-radius: 16px;
  }
  .hero-bar h1 {
    white-space: normal;
    font-size: 1rem;
  }
  .hero-inner {
    padding-bottom: 24px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .hero-slide {
    animation: none !important;
    opacity: 0;
    transform: none !important;
  }
  .hero-slide:first-child {
    opacity: 1;
  }
}

/* Cartes Glassmorphism */
.glass-cards {
  position: relative;
  isolation: isolate;
}
.glass-cards::before {
  content: "";
  position: absolute;
  inset: -50px -20px;
  z-index: -1;
  background:
    radial-gradient(circle at 15% 20%, rgba(246, 11, 81, 0.16), transparent 42%),
    radial-gradient(circle at 85% 12%, rgba(71, 85, 105, 0.14), transparent 45%),
    radial-gradient(circle at 55% 95%, rgba(246, 11, 81, 0.10), transparent 50%);
  filter: blur(40px);
  pointer-events: none;
}
.glass-cards {
  perspective: 1200px;
}
.glass-cards .card-item {
  --mx: 50%;
  --my: 50%;
  --tilt-x: 0deg;
  --tilt-y: 0deg;
  --entrance-y: 0px;
  --hover-y: 0px;
  position: relative;
  overflow: hidden;
  border-radius: 22px !important;
  background: rgba(255, 255, 255, 0.55) !important;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  transform: translateY(calc(var(--entrance-y) + var(--hover-y))) rotateX(var(--tilt-x)) rotateY(var(--tilt-y));
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.4s ease, border-color 0.4s ease, opacity 0.6s ease;
  transform-style: preserve-3d;
}
/* État initial masqué : activé uniquement une fois le JS chargé (voir
   cards-interactive.js, qui ajoute .reveal-ready) — si le script ne
   s'exécute pas (JS désactivé, erreur réseau), les cartes restent visibles
   par défaut plutôt que de disparaître définitivement. Le transform est
   déclaré une seule fois ci-dessus via des variables CSS : chaque état
   (apparition, survol) se contente d'ajuster une variable, ce qui évite
   tout conflit de spécificité entre les règles .is-visible et :hover. */
.glass-cards.reveal-ready .card-item {
  opacity: 0;
  --entrance-y: 28px;
}
.glass-cards.reveal-ready .card-item.is-visible {
  opacity: 1;
  --entrance-y: 0px;
}
.glass-cards .card-item::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: radial-gradient(280px circle at var(--mx) var(--my), rgba(246, 11, 81, 0.20), transparent 70%);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}
.glass-cards .card-item:hover::before {
  opacity: 1;
}
.glass-cards .card-item::after {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 40%;
  height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.5), transparent);
  transform: skewX(-15deg);
  transition: left 0.7s ease;
  pointer-events: none;
}
.glass-cards .card-item:hover {
  --hover-y: -10px;
  box-shadow: 0 28px 52px rgba(246, 11, 81, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  border-color: rgba(246, 11, 81, 0.3) !important;
}
.glass-cards .card-item:hover::after {
  left: 130%;
}
.glass-cards .card-icon {
  width: 64px;
  height: 64px;
  border-radius: 20px;
  background: linear-gradient(135deg, rgba(246, 11, 81, 0.20), rgba(246, 11, 81, 0.05));
  box-shadow: 0 8px 20px rgba(246, 11, 81, 0.16), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  color: var(--wp--preset--color--accent);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 18px;
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.glass-cards .card-item:hover .card-icon {
  transform: scale(1.12) rotate(-6deg);
}
.glass-cards .card-icon svg {
  width: 30px;
  height: 30px;
}
.glass-cards .card-icon img {
  width: 34px;
  height: 34px;
  object-fit: contain;
}
@media (prefers-reduced-motion: no-preference) {
  .glass-cards .card-icon {
    animation: ucfas-icon-float 4.5s ease-in-out infinite;
  }
  .glass-cards .card-item:nth-child(2) .card-icon {
    animation-delay: 0.6s;
  }
  .glass-cards .card-item:nth-child(3) .card-icon {
    animation-delay: 1.2s;
  }
  .glass-cards .card-item:hover .card-icon {
    animation-play-state: paused;
  }
}
@keyframes ucfas-icon-float {
  0%, 100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-6px) rotate(-4deg);
  }
}

/* Variante "bannière" des cartes "Par où commencer ?" : photo pleine
   largeur en haut de la carte (au lieu du petit picto), avec un badge rond
   qui chevauche la photo et le texte pour garder un repère iconographique. */
.glass-cards .card-item-banner {
  padding: 0 !important;
  display: flex;
  flex-direction: column;
}
.glass-cards .card-banner {
  position: relative;
  height: 128px;
  background-size: cover;
  background-position: center;
  flex-shrink: 0;
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Léger zoom de la photo de bannière au survol, pour retrouver la même
   vivacité que le hero (le conteneur .card-item a déjà overflow:hidden). */
.glass-cards .card-item-banner:hover .card-banner {
  transform: scale(1.08);
}
.glass-cards .card-badge {
  position: absolute;
  bottom: -22px;
  left: 22px;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: linear-gradient(135deg, #F60B51, #D00742);
  border: 3px solid rgba(255, 255, 255, 0.92);
  box-shadow: 0 8px 18px rgba(246, 11, 81, 0.28);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  transition: transform 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
/* Même traitement que .card-icon:hover (scale + légère rotation), pour que
   les cartes à bannière photo aient un survol aussi vivant que les cartes
   à picto. */
.glass-cards .card-item-banner:hover .card-badge {
  transform: scale(1.12) rotate(-8deg);
}
.glass-cards .card-badge svg {
  width: 21px;
  height: 21px;
}
.glass-cards .card-body {
  padding: 2.6rem 1.6rem 1.9rem;
}

/* Variante pour les cartes affichant l'image d'origine d'un partenaire
   (bannière) plutôt qu'un picto : cadre pleine largeur, hauteur fixe,
   l'image s'inscrit dedans sans être déformée ni recadrée. Le fond
   blanc évite les GIF/logos à fond transparent qui se fondraient mal
   sur le verre translucide de la carte. */
.glass-cards .card-icon-img {
  width: 100%;
  height: 84px;
  border-radius: 14px;
  background: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  padding: 10px;
}
.glass-cards .card-icon-img img {
  width: auto !important;
  height: auto !important;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
  border-radius: 0;
  box-shadow: none;
}
.glass-cards .card-item:has(.card-icon-img) h3 {
  text-align: center;
}
.glass-cards .card-link {
  margin-top: 14px !important;
}

/* ============================================
   FICHES "ÉPREUVE" (pages sport : Obéissance, etc.)
   ============================================ */
.ucfas-level-card {
  padding: 2rem 2.25rem;
  /* 2.7.96 : margin-top était à 0, donc sans espace de bloc défini par
     ailleurs (pas de blockGap dans theme.json), cette carte touchait
     directement le bloc précédent (ex. le ".content-card" d'intro) —
     bord à bord, d'où l'effet "collé". Marge haute et basse égales,
     qui fusionnent proprement avec la carte suivante le cas échéant. */
  margin: 2rem 0;
}
.ucfas-level-badge {
  display: inline-block;
  background: var(--wp--preset--color--accent-soft, rgba(246,11,81,0.10));
  color: var(--wp--preset--color--accent, #F60B51);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 5px 14px;
  border-radius: 20px;
  margin-bottom: 12px;
}
.ucfas-level-card h3 {
  margin: 0 0 1.1rem;
  font-family: Georgia, serif;
  font-style: italic;
  color: var(--wp--preset--color--text, #1E293B);
}
.ucfas-level-card .ucfas-exercise {
  color: var(--wp--preset--color--muted, #64748B);
  line-height: 1.75;
  margin: 0 0 0.9rem;
}
.ucfas-level-card .ucfas-exercise strong {
  color: var(--wp--preset--color--text, #1E293B);
}
.ucfas-level-photos.ucfas-level-photos {
  display: flex !important;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  margin-top: 1.5rem;
  width: 100%;
}
.ucfas-level-photos.ucfas-level-photos img {
  display: inline-block !important;
  border-radius: 14px;
  box-shadow: 0 12px 28px rgba(30, 41, 59, 0.1);
  max-width: 100%;
  height: auto;
  flex: 1 1 260px;
  max-height: 260px;
  object-fit: cover;
  cursor: zoom-in; /* 2.20.170 : ces photos ouvrent désormais la visionneuse plein écran */
}
@media (max-width: 600px) {
  .ucfas-level-card { padding: 1.6rem 1.4rem; }
  /* La règle générale ci-dessous (repasser chaque photo en pleine largeur
     sur mobile, une par ligne) ne doit PAS s'appliquer à une rangée de 3
     photos (ex. "Noir et sable", page Couleurs) : on veut au contraire
     garder les 3 côte à côte, comme sur desktop — juste plus petites.
     Sans ce :not(), les 3 photos distinctes repassaient à l'unité en
     pleine largeur sur téléphone, contrairement à une carte comme "Sable
     faiblement charbonné" qui n'a qu'UNE SEULE image (un visuel composite
     montrant 3 vues) et n'était donc jamais concernée par ce problème. */
  .ucfas-level-photos.ucfas-level-photos:not(:has( > img:nth-child(3):last-child )) img {
    flex-basis: 100%;
  }
  /* !important nécessaire : la règle desktop équivalente (plus bas dans ce
     fichier, "2.20.149 : rangée de 3 photos...") a EXACTEMENT la même
     spécificité que celle-ci — à spécificité égale, c'est l'ordre dans le
     fichier qui tranche, et cette règle desktop étant définie APRÈS celle-ci,
     elle l'emportait silencieusement même à l'intérieur de ce @media,
     annulant le rétrécissement voulu ici pour mobile.
     min-width: 0 plutôt qu'une valeur en px (88px ne suffisait déjà plus sur
     un téléphone étroit — reproduit et signalé par Alex) : sans plancher,
     flex-basis (en %) répartit toujours les 3 photos sur une seule ligne,
     quelle que soit la largeur de l'écran, aussi étroit soit-il. */
  .ucfas-level-photos.ucfas-level-photos:has( > img:nth-child(3):last-child ) > img {
    flex: 1 1 calc(33.333% - 6px) !important;
    min-width: 0 !important;
    max-height: 100px !important;
  }
  .ucfas-level-photos.ucfas-level-photos:has( > img:nth-child(3):last-child ) {
    gap: 6px !important;
  }
}

/* Correctif (2.20.9) : photo isolée tronquée dans .ucfas-level-photos.
   La règle ci-dessus donne à chaque photo une bande large de 260px de haut avec
   object-fit: cover — pensé pour une RANGÉE de plusieurs photos (paires
   chiot/adulte de la page Couleurs, photos d'exercices d'Obéissance, etc.),
   où recadrer chaque image en bande large garde la rangée bien alignée.
   Problème : quand il n'y a qu'UNE SEULE photo dans le bloc (ex. le visuel du
   kit de prélèvement Antagène® sur Dépistage MD, Dépistage MDR1 et Nanisme
   hypophysaire, ou les radios/photos de Dysplasie des coudes, Dysplasie des
   hanches, Titre initial, VTL), ce même recadrage en bande large tronque une
   grande partie de la photo — le haut et le bas disparaissent, ce qui a été
   signalé sur les photos du kit Antagène (texte/emballages coupés).
   Correctif ciblé : quand une photo est seule dans son bloc (:only-child),
   elle n'est plus étirée en bande large ni recadrée — elle s'affiche à sa
   taille naturelle (dans la limite de 480px de haut et de la largeur
   disponible), entière, sans perte de contenu. Les rangées de plusieurs
   photos ne sont pas concernées par cette règle et gardent leur recadrage
   habituel. Vérifié en direct sur Dépistage MD (photo du kit Antagène
   affichée en entier) et sur Obéissance (rangées de 2 et 3 photos inchangées). */
.ucfas-level-photos.ucfas-level-photos:has( > img:only-child ) > img {
  flex: none !important;
  width: auto !important;
  height: auto !important;
  max-width: 100% !important;
  max-height: 480px !important;
  object-fit: contain !important;
}

/* 2.20.149 : rangée de 3 photos dans .ucfas-level-photos (ex. "Fauve
   charbonné", page Couleurs). La règle générale plus haut donne à chaque
   photo une largeur minimale de 260px (flex-basis), pensée pour des
   rangées de 2 photos ou des blocs plus larges (Obéissance). Mais sur la
   page Couleurs, la carte de contenu est plus étroite (~636px) : 3 photos
   à 260px minimum ne tiennent pas sur une seule ligne et repassaient à la
   ligne une par une au lieu de former une rangée alignée. Quand il y a
   exactement 3 photos dans le bloc, on réduit leur largeur minimale pour
   qu'elles se répartissent toujours sur une seule ligne, quelle que soit
   la largeur du conteneur. Vérifié en direct sur "Fauve charbonné". */
.ucfas-level-photos.ucfas-level-photos:has( > img:nth-child(3):last-child ) > img {
  flex: 1 1 calc(33.333% - 8px);
  min-width: 150px;
  max-height: 220px;
}

/* Encart d'avertissement (règlementation, licences, etc.) */
.ucfas-note {
  background: rgba(246, 11, 81, 0.05);
  border-left: 4px solid var(--wp--preset--color--accent, #F60B51);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
  margin: 1.75rem 0;
}
.ucfas-note p {
  margin: 0 0 0.5rem;
  color: var(--wp--preset--color--text, #1E293B) !important;
}
.ucfas-note p:last-child { margin-bottom: 0; }

/* ============================================
   CARTES GÉNOTYPE (ex : page "Alopécie des Robes
   Diluées") : grille de mini-cartes glass, une par
   génotype (code + description de robe + statut),
   en remplacement d'un tableau à 3 colonnes classique.
   ============================================ */
.genotype-cards {
  margin: 1.75rem 0;
  gap: 24px !important;
}
/* La règle générale ".content-card > *" (garde-fou anti-colonnes CSS plus
   bas dans ce fichier) pose "display: block !important" sur TOUS les
   enfants directs de ".content-card", y compris cette grille — ce qui
   annulait le "display: grid" posé par WordPress et rendait le "gap"
   ci-dessus sans aucun effet (les cartes s'empilaient donc bord à bord,
   sans espace). Sélecteur à spécificité plus élevée (2 classes) pour
   reprendre la main ici uniquement, sans toucher au garde-fou général. */
.content-card > .genotype-cards {
  display: grid !important;
}
/* Même souci que ci-dessus, cette fois pour un bloc "Boutons" (wp:buttons)
   placé directement dans une .content-card (ex : bouton de téléchargement
   PDF) : le garde-fou ".content-card > *" imposait "display: block", ce qui
   annulait le "display: flex" nécessaire à "justifyContent: center" et le
   bouton restait collé à gauche au lieu d'être centré. */
.content-card > .wp-block-buttons {
  display: flex !important;
}
.genotype-card {
  background: rgba(255, 255, 255, 0.78);
  border: 1px solid rgba(30, 41, 59, 0.14);
  border-radius: 16px;
  padding: 1.5rem 1.25rem;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.12), inset 0 1px 0 rgba(255, 255, 255, 0.7);
  transition: transform 0.3s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}
.genotype-card:hover {
  transform: translateY(-5px);
  border-color: var(--wp--preset--color--accent, #F60B51);
  box-shadow: 0 20px 42px rgba(246, 11, 81, 0.18), inset 0 1px 0 rgba(255, 255, 255, 0.7);
}
.genotype-card .genotype-code {
  font-weight: 800;
  font-size: 1.05rem;
  letter-spacing: 0.02em;
  color: var(--wp--preset--color--text, #1E293B) !important;
  margin: 0 0 10px !important;
}
.genotype-card .genotype-robe {
  margin: 0 0 12px !important;
}
.genotype-card .genotype-status {
  font-weight: 700;
  color: var(--wp--preset--color--accent, #F60B51) !important;
  margin: 0 !important;
}
/* 2.20.52 : cette grille est toujours à 2 colonnes dans le contexte d'une
   .content-card (largeur max 800px — pas assez pour 3 colonnes de 240px+
   avec cet espacement, voir le "minimumColumnWidth" posé sur le bloc dans
   l'éditeur). Avec un nombre impair de cartes (le cas courant : 3 génotypes
   DM/DM, DM/N, N/N), la dernière se retrouvait donc seule sur sa ligne,
   collée à gauche au lieu d'être centrée sous les deux du dessus — signalé
   par Alex, capture à l'appui, sur les pages "Dépistages MD" et "Nanisme
   Hypophysaire ou NAH". ":last-child:nth-of-type(odd)" repère précisément
   ce cas (dernier élément en position impaire = orphelin d'une grille à 2
   colonnes) sans dépendre du nombre total de cartes : la carte étend sa
   zone de grille sur toute la largeur de la ligne (grid-column: 1 / -1),
   "justify-self: center" centre sa propre boîte dans cette zone, et
   "calc(50% - 12px)" (12px = la moitié du gap de 24px ci-dessus)
   reconstitue exactement la largeur d'une carte normale plutôt que de
   l'étirer sur toute la ligne. Vérifié par reconstitution du motif exact
   (3 cartes) avant/après ce correctif. */
.genotype-cards .genotype-card:last-child:nth-of-type(odd) {
  grid-column: 1 / -1;
  justify-self: center;
  width: calc(50% - 12px);
}
@media (max-width: 480px) {
  .genotype-cards {
    grid-template-columns: 1fr !important;
  }
  /* La grille ne fait plus qu'une colonne : la carte orpheline doit
     redevenir une carte normale (pleine largeur, comme ses sœurs) plutôt
     que de garder la largeur "moitié de ligne" calculée pour 2 colonnes. */
  .genotype-cards .genotype-card:last-child:nth-of-type(odd) {
    width: auto;
  }
}

/* ============================================
   TABLEAUX (pages santé : génotypes, accouplements)
   ============================================ */
.content-card .wp-block-table {
  margin: 1.5rem 0;
  overflow-x: auto;
}
.content-card .wp-block-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
  background: rgba(255, 255, 255, 0.55);
  border-radius: 12px;
  overflow: hidden;
}
.content-card .wp-block-table th,
.content-card .wp-block-table td {
  padding: 10px 14px;
  text-align: left;
  border: 1px solid rgba(30, 41, 59, 0.1);
  color: var(--wp--preset--color--muted, #64748B);
}
.content-card .wp-block-table th {
  background: rgba(119, 142, 173, 0.15);
  color: var(--wp--preset--color--text, #1E293B);
  font-weight: 700;
}
.content-card .wp-block-table tr:first-child td { font-weight: 700; color: var(--wp--preset--color--text, #1E293B); }
@media (max-width: 700px) {
  .content-card .wp-block-table table { font-size: 0.78rem; }
  .content-card .wp-block-table th,
  .content-card .wp-block-table td { padding: 7px 9px; }
}

/* Cartes d'exercice (ex : page "Le TCN") : le tableau porte la classe de
   bloc additionnelle "exercise-table". Une carte par ligne (texte + score
   regroupés dans la même carte), empilées verticalement avec un espace
   entre elles - plutôt que la grille de mini-cartes utilisée pour les
   tableaux "santé" ci-dessus, et sans le style "trombinoscope" (tr en
   colonne centrée) prévu pour les tableaux photo + nom. */
.content-card .exercise-table.wp-block-table {
  margin: 1.5rem 0;
}
.content-card .exercise-table table,
.content-card .exercise-table thead,
.content-card .exercise-table tbody {
  display: block !important;
}
.content-card .exercise-table tr {
  display: flex !important;
  flex-direction: row !important;
  align-items: center !important;
  justify-content: space-between !important;
  text-align: left !important;
  gap: 16px;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid rgba(30, 41, 59, 0.12);
  border-left: 4px solid var(--wp--preset--color--accent, #F60B51);
  border-radius: 0 12px 12px 0;
  padding: 14px 18px;
  margin-bottom: 12px;
  box-shadow: none;
}
.content-card .exercise-table tr:last-child {
  margin-bottom: 0;
}
.content-card .exercise-table td {
  border: none !important;
  padding: 0 !important;
  background: none !important;
  margin: 0 !important;
  color: var(--wp--preset--color--muted, #64748B);
}
.content-card .exercise-table td:first-child {
  flex: 1;
}
.content-card .exercise-table td:last-child {
  flex: 0 0 auto;
  font-weight: 700;
  color: var(--wp--preset--color--accent, #F60B51);
  white-space: nowrap;
}
.content-card .exercise-table th {
  border: none !important;
  padding: 0 !important;
  background: none !important;
  margin: 0 !important;
  color: var(--wp--preset--color--text, #1E293B);
  font-weight: 700;
}
.content-card .exercise-table th:first-child {
  flex: 1;
}
.content-card .exercise-table th:last-child {
  flex: 0 0 auto;
  white-space: nowrap;
}
@media (max-width: 600px) {
  .content-card .exercise-table tr {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
}

/* Variante "liste" sans espace entre les lignes (ex : barème "Appréciation
   du commissaire" - Points / Mention). S'ajoute à exercise-table. */
.content-card .exercise-table.exercise-table-compact tr {
  margin-bottom: 0;
  border-radius: 0;
  border-top: none;
}
.content-card .exercise-table.exercise-table-compact tr:first-child {
  border-radius: 12px 12px 0 0;
  border-top: 1px solid rgba(30, 41, 59, 0.12);
}
.content-card .exercise-table.exercise-table-compact tr:last-child {
  border-radius: 0 0 12px 12px;
}

.glass-cards .card-link a {
  color: var(--wp--preset--color--accent);
  font-weight: 600;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: gap 0.25s ease;
}
.glass-cards .card-link a:hover {
  gap: 8px;
}

/* Boutons modernes */
.wp-block-button.is-style-glass-button > .wp-block-button__link,
a.wp-block-button__link.is-style-glass-button,
.is-style-glass-button .wp-block-button__link,
.is-style-glass-button .wp-element-button {
  background-color: #F60B51 !important;
  background: linear-gradient(135deg, #F60B51, #D00742) !important;
  color: #ffffff !important;
  border-radius: 30px !important;
  font-weight: 700;
  text-transform: uppercase;
  font-size: 0.85rem;
  letter-spacing: 0.8px;
  padding: 13px 32px !important;
  box-shadow: 0 8px 20px rgba(246, 11, 81, 0.28);
  border: none !important;
  transition: all 0.25s ease !important;
}

.wp-block-button.is-style-glass-button > .wp-block-button__link:hover,
a.wp-block-button__link.is-style-glass-button:hover,
.is-style-glass-button .wp-block-button__link:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 25px rgba(246, 11, 81, 0.4);
  filter: brightness(1.05);
}

/* Bouton secondaire Contour Verre */
.is-style-outline-glass .wp-block-button__link {
  background: rgba(255, 255, 255, 0.6) !important;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1.5px solid rgba(30, 41, 59, 0.2) !important;
  color: #1E293B !important;
  border-radius: 30px !important;
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.82rem;
  letter-spacing: 0.6px;
  padding: 12px 28px !important;
  transition: all 0.25s ease !important;
}
.is-style-outline-glass .wp-block-button__link:hover {
  border-color: #F60B51 !important;
  color: #F60B51 !important;
  background: rgba(255, 255, 255, 0.9) !important;
  transform: translateY(-2px);
}

/* Eyebrow Label */
.section-eyebrow {
  text-transform: uppercase;
  letter-spacing: 2.5px;
  font-size: 0.78rem;
  color: #F60B51;
  font-weight: 800;
  margin-bottom: 0.5rem;
}

/* Galerie */
.gallery-strip {
  margin-top: 2rem;
}
.gallery-thumb {
  overflow: hidden;
  padding: 8px !important;
  margin: 0 !important;
  border-radius: 18px !important;
  transition: all 0.3s ease;
}
.gallery-thumb img {
  border-radius: 12px;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  width: 100%;
  display: block;
  transition: transform 0.4s ease;
  background: linear-gradient(110deg, rgba(30, 41, 59, 0.05) 8%, rgba(30, 41, 59, 0.11) 18%, rgba(30, 41, 59, 0.05) 33%);
  background-size: 200% 100%;
  animation: ucfas-img-skeleton 1.6s linear infinite;
}
.gallery-thumb:hover img {
  transform: scale(1.06);
}
@keyframes ucfas-img-skeleton {
  0% {
    background-position: 200% 0;
  }
  100% {
    background-position: -200% 0;
  }
}
/* Une fois l'image chargée, image-skeleton.js ajoute .is-loaded pour
   arrêter l'animation et retirer le dégradé (l'image chargée le masque
   déjà visuellement, mais on évite de faire tourner l'animation pour
   rien en arrière-plan). Repli sans JS : le dégradé reste sous l'image
   une fois celle-ci chargée, invisible car entièrement recouvert. */
.gallery-thumb img.is-loaded,
.news-card-media img.is-loaded {
  animation: none;
  background: none;
}
@media (prefers-reduced-motion: reduce) {
  .gallery-thumb img,
  .news-card-media img {
    animation: none;
    background: rgba(30, 41, 59, 0.06);
  }
}

/* Mosaïque asymétrique (page d'accueil) : une grande photo focale + 3
   tuiles secondaires, la dernière servant d'appel vers la galerie
   complète. Remplace la grille 4 colonnes uniforme d'origine. */
.gallery-strip.gallery-mosaic {
  display: grid;
  grid-template-columns: 1.5fr 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 16px;
  height: 440px;
}
.gallery-strip.gallery-mosaic .gallery-thumb {
  position: relative;
  height: 100%;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.12);
}
.gallery-strip.gallery-mosaic .gallery-thumb img {
  height: 100%;
  aspect-ratio: auto;
}
.gallery-strip.gallery-mosaic .gallery-thumb:nth-child(1) {
  grid-column: 1;
  grid-row: 1 / 3;
}
.gallery-strip.gallery-mosaic .gallery-thumb:nth-child(2) {
  grid-column: 2;
  grid-row: 1;
}
.gallery-strip.gallery-mosaic .gallery-thumb:nth-child(3) {
  grid-column: 3;
  grid-row: 1;
}
.gallery-strip.gallery-mosaic .gallery-thumb:nth-child(4) {
  grid-column: 2 / 4;
  grid-row: 2;
}
.gallery-strip.gallery-mosaic .gallery-thumb {
  cursor: pointer;
}
.gallery-strip.gallery-mosaic .gallery-thumb::after {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 12px;
  background: linear-gradient(180deg, transparent 55%, rgba(15, 23, 42, 0.5));
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.gallery-strip.gallery-mosaic .gallery-thumb:hover::after {
  opacity: 1;
}
@media (max-width: 700px) {
  .gallery-strip.gallery-mosaic {
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 220px 150px 150px;
    height: auto;
    gap: 12px;
  }
  .gallery-strip.gallery-mosaic .gallery-thumb:nth-child(1) {
    grid-column: 1 / 3;
    grid-row: 1;
  }
  .gallery-strip.gallery-mosaic .gallery-thumb:nth-child(2) {
    grid-column: 1;
    grid-row: 2;
  }
  .gallery-strip.gallery-mosaic .gallery-thumb:nth-child(3) {
    grid-column: 2;
    grid-row: 2;
  }
  .gallery-strip.gallery-mosaic .gallery-thumb:nth-child(4) {
    grid-column: 1 / 3;
    grid-row: 3;
  }
}

/* CTA Band */
.cta-band {
  text-align: center;
  padding: 3.5rem 2.5rem !important;
  border-radius: 24px !important;
}
.cta-band h2 {
  margin-bottom: 0.8rem;
}
.cta-band p {
  max-width: 560px;
  margin-left: auto;
  margin-right: auto;
}

/* Footer */
.site-footer {
  background: rgba(255, 255, 255, 0.8);
  border-top: 1px solid rgba(226, 232, 240, 0.8);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  padding: 32px 20px 0;
}

.footer-columns {
  gap: 24px !important;
  padding-bottom: 24px;
  grid-template-columns: 1fr !important;
  justify-items: center;
  text-align: center;
}
.footer-col-brand {
  max-width: 380px;
}

.footer-logo-text {
  font-size: 1.3rem;
  font-weight: 800;
  letter-spacing: 0.5px;
  margin-bottom: 8px !important;
  color: #4176A6;
  -webkit-text-stroke: 1px #1a1a1a;
  paint-order: stroke fill;
  text-shadow: -1px -1px 0 #1a1a1a, 1px -1px 0 #1a1a1a, -1px 1px 0 #1a1a1a, 1px 1px 0 #1a1a1a;
}
.footer-logo-text .footer-logo-f {
  color: #ffffff;
}
.footer-logo-text .footer-logo-as {
  color: #892D2F;
}

.footer-social {
  gap: 8px !important;
  margin-top: 12px !important;
  justify-content: center;
}
.footer-social-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 9px;
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid rgba(226, 232, 240, 0.9);
  color: var(--wp--preset--color--muted, #475569);
  text-decoration: none;
  font-size: 0.85rem;
  font-weight: 700;
  transition: all 0.2s ease;
}
.footer-social-icon:hover {
  background: var(--wp--preset--color--accent, #F60B51);
  color: #fff;
  border-color: transparent;
  transform: translateY(-2px);
}

.footer-bottom {
  border-top: 1px solid rgba(226, 232, 240, 0.8);
  padding: 12px 0;
  flex-wrap: wrap;
  justify-content: center !important;
  text-align: center;
  gap: 8px 24px;
}
.footer-bottom p {
  color: var(--wp--preset--color--muted, #475569);
  opacity: 0.85;
  margin: 0 !important;
}
.footer-legal-links a {
  color: var(--wp--preset--color--muted, #475569);
  text-decoration: underline;
}
.footer-legal-links a:hover {
  color: var(--wp--preset--color--accent, #F60B51);
}

@media (max-width: 700px) {
  .footer-columns {
    grid-template-columns: 1fr !important;
    gap: 28px !important;
    text-align: center;
  }
  .footer-col {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .footer-social {
    justify-content: center;
  }
  .footer-bottom {
    flex-direction: column;
    align-items: center !important;
    text-align: center;
  }
}

@media (prefers-reduced-transparency: reduce) {
  .site-header::before {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: #ffffff !important;
  }
  .site-footer, .glass-cards .card-item, .hero-bar, .cta-band, .gallery-thumb,
  .photo-gallery-glass-ngg .ngg-gallery-thumbnail span,
  body:has(.ucfas-menu-toggle-checkbox:checked) .site-nav {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: #ffffff !important;
  }
  .gallery-filter-pill {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

@media (max-width: 700px) {
  .glass-cards {
    grid-template-columns: 1fr !important;
  }
  .site-header {
    padding: 12px 4%;
  }
}

/* ============================================
   RYTHME DES SECTIONS DE LA PAGE D'ACCUEIL
   ============================================ */
.section-plain {
  background: transparent;
}
.section-tint {
  background: linear-gradient(180deg, rgba(71, 85, 105, 0.05), rgba(246, 11, 81, 0.03));
  border-top: 1px solid rgba(226, 232, 240, 0.6);
  border-bottom: 1px solid rgba(226, 232, 240, 0.6);
}

/* CTA en fond sombre, fort contraste */
.section-dark {
  position: relative;
  background: linear-gradient(180deg, #1E293B, #0F172A);
}
/* Vague SVG qui adoucit la coupure entre la section claire qui précède
   (galerie) et ce bandeau sombre, dans le même esprit que le halo doux
   déjà utilisé derrière les cartes "Par où commencer ?" juste après le
   hero. Positionnée juste au-dessus du bloc, dans sa couleur de départ. */
.section-dark::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 46px;
  transform: translateY(-99%);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 40' preserveAspectRatio='none'><path d='M0,40 C100,0 300,0 400,40 L400,40 L0,40 Z' fill='%231E293B'/></svg>");
  background-size: 100% 100%;
  background-repeat: no-repeat;
  pointer-events: none;
}
@media (max-width: 700px) {
  .section-dark::before {
    height: 28px;
  }
}
.section-dark .cta-band {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}
.section-dark .cta-band h2 {
  color: #ffffff;
}
.section-dark .cta-band p {
  color: rgba(255, 255, 255, 0.75) !important;
}
.section-dark .is-style-glass-button .wp-block-button__link {
  background: #F60B51 !important;
  box-shadow: 0 8px 25px rgba(246, 11, 81, 0.35);
}
.section-dark .is-style-glass-button .wp-block-button__link:hover {
  background: #ffffff !important;
  color: #1E293B !important;
}

/* ============================================
   CARTES ACTUALITÉS RÉCENTES — mise en page magazine
   ============================================ */
.news-grid ul.wp-block-post-template {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 232px;
  align-items: stretch;
  gap: 24px;
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  position: relative;
  isolation: isolate;
}
/* 2.14.3 : la classe "is-layout-flow" que WordPress ajoute automatiquement
   au <ul> du bloc Query (mise en page par défaut, avant qu'on le transforme
   en grille CSS ci-dessus) continue d'appliquer sa règle native
   ".is-layout-flow > * + * { margin-block-start: ... }" à tous les <li> sauf
   le premier — un reliquat qui n'a plus de sens une fois en grille. Cette
   marge de 24px venait s'ajouter à l'intérieur de la hauteur de ligne
   (210px) sous align-items:stretch, ce qui rétrécissait les 2 cartes
   compactes à 186px et les décalait vers le bas de leur case : la grande
   carte vedette à gauche et les 2 cartes empilées à droite ne s'alignaient
   plus ni en haut ni en bas. On neutralise cette marge héritée ci-dessous. */
.news-grid ul.wp-block-post-template::before {
  content: "";
  position: absolute;
  inset: -40px -20px;
  z-index: -1;
  background:
    radial-gradient(circle at 12% 15%, rgba(246, 11, 81, 0.14), transparent 42%),
    radial-gradient(circle at 88% 20%, rgba(71, 85, 105, 0.13), transparent 45%),
    radial-gradient(circle at 50% 95%, rgba(246, 11, 81, 0.09), transparent 50%);
  filter: blur(40px);
  pointer-events: none;
}
.news-grid ul.wp-block-post-template > li {
  margin-top: 0 !important;
  min-height: 0;
  min-width: 0;
}
.news-grid ul.wp-block-post-template > li:first-child {
  grid-column: 1 / 3;
  grid-row: 1 / 3;
}
.news-card {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 0 !important;
  border-radius: 22px !important;
  background: rgba(255, 255, 255, 0.55) !important;
  box-shadow: 0 14px 34px rgba(15, 23, 42, 0.07), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  transition: transform 0.35s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.35s ease;
}
.news-card::after {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 40%;
  height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.5), transparent);
  transform: skewX(-15deg);
  transition: left 0.7s ease;
  pointer-events: none;
  z-index: 3;
}
.news-card:hover {
  transform: translateY(-6px);
  box-shadow: 0 22px 44px rgba(246, 11, 81, 0.13), inset 0 1px 0 rgba(255, 255, 255, 0.6);
}
.news-card:hover::after {
  left: 130%;
}
.news-card-media {
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
  height: 110px;
  background: linear-gradient(135deg, #64748B, #1E293B);
}
.news-card-media::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Cpath d='M50 52c-13 0-22 10-22 22 0 11 9 18 22 18s22-7 22-18c0-12-9-22-22-22z' fill='%23ffffff' fill-opacity='0.16'/%3E%3Cellipse cx='21' cy='42' rx='9' ry='13' fill='%23ffffff' fill-opacity='0.16' transform='rotate(-22 21 42)'/%3E%3Cellipse cx='38' cy='22' rx='10' ry='15' fill='%23ffffff' fill-opacity='0.16' transform='rotate(-8 38 22)'/%3E%3Cellipse cx='60' cy='22' rx='10' ry='15' fill='%23ffffff' fill-opacity='0.16' transform='rotate(8 60 22)'/%3E%3Cellipse cx='78' cy='42' rx='9' ry='13' fill='%23ffffff' fill-opacity='0.16' transform='rotate(22 78 42)'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 44% auto;
}
.news-card-media figure,
.news-card-media a {
  display: block;
  height: 100%;
  margin: 0;
  position: relative;
  z-index: 1;
}
.news-grid ul.wp-block-post-template > li:first-child .news-card-media {
  height: 250px;
}
.news-card-media::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(180deg, transparent 55%, rgba(15, 23, 42, 0.4));
  pointer-events: none;
}
.news-card-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  margin: 0 !important;
  border-radius: 0 !important;
  transition: transform 0.5s ease;
  position: relative;
  z-index: 1;
  background: linear-gradient(110deg, rgba(255, 255, 255, 0.10) 8%, rgba(255, 255, 255, 0.22) 18%, rgba(255, 255, 255, 0.10) 33%);
  background-size: 200% 100%;
  animation: ucfas-img-skeleton 1.6s linear infinite;
}
.news-card:hover .news-card-media img {
  transform: scale(1.08);
}
.news-card .news-card-date {
  position: absolute;
  left: 14px;
  bottom: 12px;
  z-index: 2;
  background: rgba(255, 255, 255, 0.9);
  color: var(--wp--preset--color--accent, #F60B51);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  font-weight: 700;
  font-size: 0.72rem;
  padding: 4px 11px;
  border-radius: 20px;
  margin: 0;
}
.news-card-body {
  padding: 16px 18px 20px;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.news-grid ul.wp-block-post-template > li:not(:first-child) .news-card-body {
  padding: 12px 16px 14px;
}
.news-card .wp-block-post-title {
  margin: 0 0 8px !important;
  font-size: 0.95rem !important;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
.news-grid ul.wp-block-post-template > li:first-child .wp-block-post-title {
  font-size: 1.3rem !important;
  -webkit-line-clamp: 3;
}
.news-grid ul.wp-block-post-template > li:not(:first-child) .wp-block-post-title {
  font-size: 0.8rem !important;
  margin-bottom: 4px !important;
  -webkit-line-clamp: 1;
}
/* 2.14.10 : le bloc titre applique la classe utilitaire ".has-medium-font-size"
   (attribut fontSize:"medium" dans le pattern), qui pose son font-size en
   !important — ça écrasait silencieusement le 0.8rem/1.3rem ci-dessus malgré
   une sélection plus précise, d'où le titre encore rendu à 20px et repassant
   sur plusieurs lignes visibles malgré le -webkit-line-clamp. D'où les
   !important ci-dessus pour reprendre la main.
   Second problème, plus sournois : le bloc Titre de WordPress rend son lien
   en "display: inline-block" par défaut. Le "-webkit-line-clamp" (technique
   de troncature multi-lignes) ne peut compter/couper des lignes de texte qu'à
   l'intérieur d'un flux "inline" ; un enfant inline-block est traité comme un
   bloc opaque et n'est jamais tronqué, donc le titre débordait sur autant de
   lignes que nécessaire (2 à 4 lignes visibles, sans "…") au lieu d'être
   limité à 1 ou 3 lignes avec ellipse. On repasse ce lien en "inline". */
.news-card .wp-block-post-title a {
  display: inline !important;
  color: var(--wp--preset--color--text, #1E293B);
  text-decoration: none;
}
.news-card .wp-block-post-title a:hover {
  color: var(--wp--preset--color--accent, #F60B51);
}
.news-card .wp-block-post-excerpt {
  color: var(--wp--preset--color--muted, #475569);
  font-size: 0.85rem;
  line-height: 1.5;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0 0 10px;
}
.news-card .wp-block-read-more.card-link {
  margin-top: auto;
  color: var(--wp--preset--color--accent);
  font-weight: 600;
  text-decoration: none;
  font-size: 0.85rem;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  transition: gap 0.25s ease;
}
.news-card .wp-block-read-more.card-link:hover {
  gap: 8px;
}
.news-grid ul.wp-block-post-template > li:not(:first-child) .wp-block-post-excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 0.78rem;
  line-height: 1.4;
  margin: 0 0 4px;
}
.news-grid ul.wp-block-post-template > li:not(:first-child) .wp-block-read-more {
  font-size: 0.78rem;
}

@media (max-width: 900px) {
  .news-grid ul.wp-block-post-template {
    grid-template-columns: repeat(2, 1fr);
    grid-auto-rows: auto;
  }
  .news-grid ul.wp-block-post-template > li:first-child {
    grid-column: 1 / -1;
    grid-row: auto;
  }
  .news-grid ul.wp-block-post-template > li:not(:first-child) {
    grid-column: auto;
    grid-row: auto;
  }
  .news-grid ul.wp-block-post-template > li:first-child .news-card-media {
    height: 220px;
  }
  .news-card-media {
    height: 130px;
  }
}
@media (max-width: 700px) {
  .news-grid ul.wp-block-post-template {
    grid-template-columns: 1fr;
  }
  .news-grid ul.wp-block-post-template > li:not(:first-child) .wp-block-post-excerpt,
  .news-grid ul.wp-block-post-template > li:not(:first-child) .wp-block-read-more {
    display: -webkit-box;
    display: flex;
  }
  .news-card-media {
    height: 150px;
  }
}

/* ============================================
   ARCHIVE ACTUALITÉS — grille chronologique (2.7.93)
   Page "Actualités" (template-blog.php) : toutes les actualités,
   plus récentes en premier, en grille régulière (pas de grande carte
   "vedette" comme sur l'accueil), avec pagination assortie au style
   verre du reste du site. Réutilise le composant .news-card tel quel.
   ============================================ */
.news-archive-wrap {
  max-width: 1200px;
  margin: 0 auto;
  padding: 0 5%;
}
.news-archive-grid {
  position: relative;
  isolation: isolate;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  margin: 0;
}
.news-archive-grid::before {
  content: "";
  position: absolute;
  inset: -40px -20px;
  z-index: -1;
  background:
    radial-gradient(circle at 12% 15%, rgba(246, 11, 81, 0.1), transparent 42%),
    radial-gradient(circle at 88% 30%, rgba(71, 85, 105, 0.1), transparent 45%),
    radial-gradient(circle at 50% 95%, rgba(246, 11, 81, 0.07), transparent 50%);
  filter: blur(40px);
  pointer-events: none;
}
.news-archive-grid .news-card {
  height: 100%;
}
.news-archive-grid .news-card-media {
  height: 190px;
}
.news-archive-grid .wp-block-post-title {
  font-size: 1.05rem;
}
.news-archive-empty {
  max-width: 600px;
}

@media (max-width: 900px) {
  .news-archive-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (max-width: 600px) {
  .news-archive-grid {
    grid-template-columns: 1fr;
  }
  .news-archive-grid .news-card-media {
    height: 170px;
  }
}

/* ============================================
   RECHERCHE D'ARTICLES — page Actualités (2.20.181)
   Barre de recherche au-dessus de la grille, reliée à la requête WP
   (WP_Query 's') plutôt qu'à un filtrage côté client, car les 9 cartes
   affichées par page ne représentent pas l'ensemble des actualités.
   Même habillage "verre" que .etalon-search (page Étalons disponibles).
   ============================================ */
.news-search {
  padding: 18px 22px;
  border-radius: 18px;
  margin: 0 0 24px;
}
.news-search-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.news-search-icon {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  fill: var(--wp--preset--color--muted, #64748B);
}
.news-search-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid rgba(30, 41, 59, 0.12);
  background: rgba(255, 255, 255, 0.8);
  border-radius: 10px;
  padding: 10px 14px;
  font-size: 0.9rem;
  color: var(--wp--preset--color--text, #1E293B);
  font-family: inherit;
  box-sizing: border-box;
}
.news-search-input:focus {
  outline: none;
  border-color: var(--wp--preset--color--accent, #F60B51);
  box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.12);
}
.news-search-submit {
  flex: 0 0 auto;
  border: none;
  background: linear-gradient(135deg, #F60B51, #D00742);
  color: #fff;
  font-weight: 700;
  font-size: 0.85rem;
  padding: 10px 20px;
  border-radius: 10px;
  cursor: pointer;
  box-shadow: 0 8px 18px rgba(246, 11, 81, 0.24);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.news-search-submit:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 22px rgba(246, 11, 81, 0.3);
}
.news-search-clear {
  flex: 0 0 auto;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--wp--preset--color--muted, #64748B);
  text-decoration: none;
  padding: 10px 6px;
  white-space: nowrap;
}
.news-search-clear:hover {
  color: var(--wp--preset--color--accent, #F60B51);
}
.news-search-summary {
  margin: -8px 0 20px !important;
  font-size: 0.85rem;
  color: var(--wp--preset--color--muted, #64748B) !important;
}
@media (max-width: 600px) {
  .news-search-row {
    flex-wrap: wrap;
  }
  .news-search-input {
    flex: 1 1 100%;
    order: -1;
  }
  .news-search-clear {
    padding: 6px 6px 0;
  }
}

/* État vide de la recherche d'articles (0 résultat) : même ton chaleureux
   que la recherche d'étalons (.etalon-empty) — pattes de chien, message
   rassurant, action directe pour repartir sans recherche. */
.news-search-empty {
  text-align: center;
}
.news-search-empty-paws {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 6px;
  margin-bottom: 12px;
}
.news-search-empty-paw {
  fill: rgba(246, 11, 81, 0.55);
}
.news-search-empty-paw-sm {
  width: 18px;
  height: 18px;
  fill: rgba(246, 11, 81, 0.3);
}
.news-search-empty-paw-sm:first-child {
  transform: rotate(-12deg);
}
.news-search-empty-paw-sm:last-child {
  transform: rotate(12deg);
}
.news-search-empty-paw-md {
  width: 24px;
  height: 24px;
}
.news-search-empty-title {
  font-weight: 700;
  font-size: 1rem;
  color: var(--wp--preset--color--text, #1E293B);
  margin: 0 0 6px !important;
}
.news-search-empty-text {
  font-size: 0.85rem;
  color: var(--wp--preset--color--muted, #64748B) !important;
  margin: 0 0 16px !important;
}
.news-search-empty-reset {
  display: inline-block;
  border: none;
  background: linear-gradient(135deg, #F60B51, #D00742);
  color: #fff;
  font-weight: 700;
  font-size: 0.82rem;
  padding: 10px 22px;
  border-radius: 20px;
  text-decoration: none;
  box-shadow: 0 8px 20px rgba(246, 11, 81, 0.24);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.news-search-empty-reset:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(246, 11, 81, 0.3);
}

/* Pagination "verre" (Précédent / numéros / Suivant) */
.news-archive-pagination {
  margin: 3rem 0 0.5rem;
  display: flex;
  justify-content: center;
}
.news-archive-pagination ul {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.news-archive-pagination .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 42px;
  height: 42px;
  padding: 0 14px;
  border-radius: 30px;
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border: 1.5px solid rgba(30, 41, 59, 0.15);
  color: #1E293B;
  font-weight: 600;
  font-size: 0.85rem;
  text-decoration: none;
  transition: all 0.25s ease;
}
.news-archive-pagination a.page-numbers:hover {
  border-color: #F60B51;
  color: #F60B51;
  background: rgba(255, 255, 255, 0.9);
  transform: translateY(-2px);
}
.news-archive-pagination .page-numbers.current {
  background: linear-gradient(135deg, #F60B51, #D00742);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 8px 20px rgba(246, 11, 81, 0.28);
}
.news-archive-pagination .page-numbers.dots {
  background: none;
  border: none;
  box-shadow: none;
}

/* ============================================
   TROMBINOSCOPE : transforme les tableaux "photo + nom" de la page
   "Composition du Bureau" (page-id-59) en grille de cartes modernes.
   2.20.172 : nouvelle mise en page sur demande d'Alex (l'ancienne —
   photo ronde + texte dessous — jugee "moche", notamment a cause des
   fiches sans intitule de poste qui laissaient un grand vide, et de la
   derniere rangee incomplete mal centree). Chaque carte est maintenant
   une photo plein format avec un degrade sombre en bas, sur laquelle le
   nom et un badge rose (intitule de poste) sont poses directement --
   toutes les cartes ont donc la meme taille quel que soit le texte, et
   flexbox (au lieu d'une grille stricte) centre proprement la derniere
   rangee meme incomplete.
   IMPORTANT -- scope : ce style est desormais limite a "body.page-id-59"
   (id de la page "Composition du Bureau"). Il ciblait auparavant TOUS les
   tableaux de TOUTES les pages via ".content-card table" -- en repérant
   d'autres tableaux du site (ex. page "Le TCN", grille de bareme
   criteres/points), on a réalisé que ce style les aurait rendus
   illisibles (positionnement en absolu pensé uniquement pour une photo +
   un nom, pas pour du texte ordinaire). D'où la restriction à cette seule
   page, plutôt qu'un ciblage générique par structure de tableau.
   ============================================ */
body.page-id-59 .content-card table {
  width: 100%;
  border: none !important;
  border-collapse: separate;
  margin: 1.5rem 0;
}
body.page-id-59 .content-card table,
body.page-id-59 .content-card tbody {
  display: block;
}
body.page-id-59 .content-card tbody {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 22px;
}
body.page-id-59 .content-card tr {
  position: relative;
  flex: 0 1 220px;
  aspect-ratio: 3 / 4.4;
  display: flex;
  align-items: stretch;
  justify-content: flex-end;
  overflow: hidden;
  background: #1E293B; /* visible un court instant pendant le chargement de la photo */
  border: none;
  border-radius: 20px;
  padding: 0;
  box-shadow: 0 10px 26px rgba(15, 23, 42, 0.18);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
body.page-id-59 .content-card tr:hover {
  transform: translateY(-6px);
  box-shadow: 0 18px 36px rgba(15, 23, 42, 0.26);
}
/* Masque les lignes vides utilisees comme espaceurs dans l'ancien contenu */
body.page-id-59 .content-card tr:not(:has(td:not(:empty))) {
  display: none;
}
/* Degrade sombre pour garder le nom/badge lisibles quelle que soit la
   photo -- insere au-dessus de la photo (z-index: 1) mais sous le texte
   (z-index: 2). */
body.page-id-59 .content-card tr::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, rgba(15, 23, 42, 0.9) 0%, rgba(15, 23, 42, 0.45) 38%, rgba(15, 23, 42, 0) 65%);
  pointer-events: none;
}
body.page-id-59 .content-card td {
  border: none !important;
  padding: 0 !important;
}
body.page-id-59 .content-card td:first-child {
  position: absolute;
  inset: 0;
  z-index: 0;
  margin: 0;
}
body.page-id-59 .content-card td:first-child img {
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  border-radius: 0 !important;
  border: none !important;
  box-shadow: none !important;
  object-fit: cover !important;
  transition: transform 0.5s ease;
}
/* 2.20.173 : bug signale par Alex - certaines photos (celles inserees via
   le bloc image de l'editeur) sont enveloppees dans <figure><a><img></a>
   </figure> plutot qu'un simple <img>. Sans regle dediee, ce <figure> ne
   remplissait pas toute la hauteur de la carte (comportement par defaut,
   base sur son contenu) : le "height: 100%" de l'image ci-dessus n'avait
   alors aucune reference de hauteur definie a suivre et retombait sur le
   format carre d'origine de la photo (140x140), laissant un grand vide
   sombre en dessous. On force donc ces eventuels conteneurs intermediaires
   a remplir 100% de la carte, comme s'ils n'existaient pas. */
body.page-id-59 .content-card td:first-child figure,
body.page-id-59 .content-card td:first-child a {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
}
body.page-id-59 .content-card tr:hover td:first-child img {
  transform: scale(1.08);
}
body.page-id-59 .content-card td:last-child {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 14px 16px 22px !important; /* 2.20.176 : !important requis, écrasé sinon par ".content-card td { padding: 0 !important; }" juste au-dessus */
  color: #fff;
  font-weight: 700;
  text-align: center; /* 2.20.174 : sur demande d'Alex, texte centré plutôt qu'aligné à gauche */
  font-size: 0.95rem;
  line-height: 1.25;
}
/* Intitule de poste (dans un <p>) affiche en badge rose ; ":not(:empty)"
   evite d'afficher un badge vide pour les membres sans intitule renseigne.
   "text-align: center" explicite necessaire : ".content-card p
   { text-align: left; }" (tout en haut de ce fichier) cible directement
   chaque <p> et l'emporte sur le centrage seulement herite du parent —
   meme bug deja rencontre et documente plus loin (cf. 2.20.96/97). */
body.page-id-59 .content-card td:last-child p:not(:empty) {
  display: inline-block;
  margin: 0 0 5px !important;
  padding: 3px 10px;
  background: var(--wp--preset--color--accent, #F60B51);
  color: #fff;
  border-radius: 999px;
  font-size: 0.65rem;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  text-transform: uppercase;
  letter-spacing: 0.03em;
}
@media (max-width: 700px) {
  body.page-id-59 .content-card tbody {
    gap: 14px;
  }
  body.page-id-59 .content-card tr {
    flex-basis: 150px;
  }
  body.page-id-59 .content-card td:last-child {
    padding: 10px 10px 12px;
    font-size: 0.85rem;
  }
}

/* ============================================
   PAGES DE TYPE ANNUAIRE (ex. Éleveurs affiliés)
   Bannières d'éleveurs/liens en encadré verre, noms mis en valeur,
   coordonnées plus lisibles.
   ============================================ */
.content-card p a img {
  border-radius: 14px;
  border: 1px solid rgba(226, 232, 240, 0.9);
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.06);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
  max-width: 100%;
  height: auto;
  margin: 0.75rem 0;
}
.content-card p a:has(img):hover img {
  transform: translateY(-3px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.1);
}
.content-card p strong {
  color: var(--wp--preset--color--text, #1E293B);
  font-size: 1.02rem;
}
.content-card p strong a,
.content-card h2 a {
  color: var(--wp--preset--color--accent, #F60B51);
  text-decoration: none;
  border-bottom: 1px solid rgba(246, 11, 81, 0.3);
}
.content-card p strong a:hover {
  border-bottom-color: var(--wp--preset--color--accent, #F60B51);
}
.content-card p {
  margin-bottom: 0.5rem;
}
.content-card .wp-block-post-content,
.content-card > * {
  display: block !important;
  column-count: 1 !important;
  columns: 1 !important;
  width: 100% !important;
}

/* ============================================
   GRILLE DE CARTES ÉLEVEURS (page Éleveurs affiliés)
   ============================================ */
.breeder-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
  margin: 2rem 0;
}
/* Variante plus dense pour les listes très longues (ex. étalons disponibles) :
   2 colonnes sur grand écran, avec des cartes un peu plus compactes.
   En dessous de 900px, on repasse entièrement au comportement standard
   (identique à la page Éleveurs) — d'où ces réglages réservés au desktop. */
@media (min-width: 901px) {
  .breeder-grid.breeder-grid--compact {
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
  }
  .breeder-grid--compact .breeder-card-body {
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
  }
  /* 2.20.163 : bug pré-existant (déjà présent avant cette session, jamais
     remarqué car cette media query ne se déclenche qu'à partir de 901px)
     repéré par Alex sur /etalons-disponibles-pour-saillies ET /dev-alex.
     "width: 50%" sur l'<img> ne donnait pas des photos bien réparties
     comme attendu : chaque photo est enveloppée dans un <a> (lightbox)
     qui est lui-même un enfant flex SANS largeur explicite. Un pourcentage
     sur l'<img> a besoin d'un conteneur de référence de largeur "définie"
     pour se calculer correctement ; comme la largeur du <a> dépendait
     elle-même du contenu (cercle vicieux), le navigateur retombait sur la
     taille naturelle de chaque photo (différente pour chacune), que le
     flex réduisait ensuite de façon disproportionnée pour tenir dans la
     carte — d'où des photos de tailles très inégales et mal alignées.
     Solution : donner au <a> une largeur flexible explicite (flex: 1 1 0,
     min-width: 0) pour qu'il partage l'espace de façon fiable, et faire
     remplir entièrement ce <a> par la photo (width/height: 100% +
     object-fit: cover) plutôt que de dépendre du rapport largeur/hauteur
     de chaque photo. Une seule photo occupe alors naturellement 100% de
     la largeur (plus besoin du correctif ":has(...)" fragile pour ce cas
     précis, réservé à la page Éleveurs non-compacte plus bas). */
  .breeder-grid--compact .breeder-card-photos {
    width: 100%;
  }
  .breeder-grid--compact .breeder-card-photos > a {
    flex: 1 1 0;
    min-width: 0;
  }
  .breeder-grid--compact .breeder-card-photos img {
    width: 100%;
    height: 160px;
    object-fit: cover;
    display: block;
  }
}
.breeder-card {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 18px;
  padding: 24px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
  position: relative;
  overflow: hidden;
}
.breeder-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 5px;
  background: linear-gradient(180deg, rgba(246, 11, 81, 0.35), rgba(119, 142, 173, 0.35));
}
.breeder-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.09);
}
.breeder-card-header {
  margin-bottom: 1rem;
}
.breeder-card-header .kennel-badge {
  display: inline-block;
  background: rgba(119, 142, 173, 0.15);
  color: var(--wp--preset--color--text, #1E293B) !important;
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none !important;
  padding: 5px 14px;
  border-radius: 8px;
  margin-bottom: 6px;
}
.breeder-card-header .kennel-badge:hover {
  background: rgba(246, 11, 81, 0.15);
  color: var(--wp--preset--color--accent, #F60B51) !important;
}
.breeder-card-header .owner-name {
  margin: 0 !important;
  font-size: 0.82rem;
  color: var(--wp--preset--color--muted, #64748b);
}
.breeder-card-header .dog-name-title {
  margin: 0 !important;
  font-family: 'Georgia', serif;
  font-style: italic;
  font-size: 0.85rem;
  font-weight: 700;
  color: var(--wp--preset--color--text, #1E293B);
  padding-bottom: 5px;
  border-bottom: 2px solid rgba(246, 11, 81, 0.25);
  white-space: nowrap;
}
.breeder-card-body {
  display: flex;
  flex-wrap: wrap;
  align-items: center; /* centrage vertical du texte face à la photo, en desktop */
  gap: 32px;
}
.breeder-card-body > p {
  margin: 0 !important;
  flex-shrink: 0;
}
.breeder-card-body img {
  width: 340px;
  height: 200px;
  object-fit: cover;
  border-radius: 12px;
  display: block;
}
/* Une ou plusieurs photos groupées côte à côte (portrait + profil pour les étalons) */
.breeder-card-photos {
  display: flex;
  gap: 10px;
  flex-shrink: 0;
}
.breeder-card-photos img {
  width: 160px;
  height: 200px;
  cursor: zoom-in;
  transition: transform 0.25s ease;
}
.breeder-card-photos img:hover {
  transform: scale(1.03);
}
/* ":only-child" doit couvrir deux structures possibles : une image seule
   directement enfant de .breeder-card-photos (page éleveurs/étalons
   existante, construite par ucfas_glass_breeder_cards()), ou une image
   seule enveloppée dans un lien vers la pleine taille (nouvelle page
   étalons pilotée par base de données, voir ucfas_etalons_render_grid()) —
   sans le ", a:only-child", CHAQUE lien-image se retrouvait "enfant
   unique" de son propre <a>, déclenchant cette règle à tort même avec 2
   photos, d'où le débordement constaté.
   2.20.162 : bug persistant signalé par Alex sur /dev-alex — même avec le
   ", a:only-child" ajouté ci-dessus, le sélecteur restait faux : sans le
   combinateur direct ">", "img:only-child" vérifie si l'image est seule
   enfant de SON PARENT IMMÉDIAT (le <a>), ce qui est TOUJOURS vrai ici
   puisque chaque photo est individuellement enveloppée dans son propre
   <a><img></a> — que la carte ait 1 ou 2 photos. La règle des 340px se
   déclenchait donc systématiquement pour les deux images. Le ">" force la
   vérification sur un enfant direct unique de .breeder-card-photos lui-même. */
.breeder-card-photos:has( > img:only-child, > a:only-child ) img {
  width: 340px;
}
/* Adresse / téléphone / e-mail : regroupés dans un seul bloc */
.breeder-card-info {
  flex: 1 1 220px;
  min-width: 0;
  flex-shrink: 1;
}
.breeder-card-info p {
  margin: 0 0 0.35rem !important;
  font-size: 0.92rem;
}
@media (max-width: 700px) {
  .breeder-card-body {
    flex-direction: column;
    align-items: center; /* centrage horizontal en mode mobile */
    text-align: center;
    gap: 16px;
  }
  .breeder-card-body img {
    width: 100%;
    height: 220px;
  }
  .breeder-card-photos {
    width: 100%;
  }
  /* 2.20.167 : même bug que la variante desktop plus haut (2.20.163),
     jamais corrigé ici — signalé par Alex sur mobile. "width: 50%" sur
     l'image ne peut pas se calculer correctement puisque son parent direct
     (le <a> de la lightbox) n'a pas de largeur propre : chaque photo
     retombait sur sa taille naturelle, écrasée ensuite de façon inégale
     pour tenir dans la carte. Même solution : le <a> reçoit une largeur
     flexible fiable, l'image remplit cet espace avec un recadrage propre
     plutôt que de dépendre de son format d'origine. */
  .breeder-card-photos > a {
    flex: 1 1 0;
    min-width: 0;
  }
  .breeder-card-photos img {
    width: 100%;
    height: 160px;
    object-fit: cover;
    display: block;
  }
  .breeder-card-info {
    text-align: center;
    flex: 0 0 auto; /* évite l'étirement vertical hérité du flex-basis desktop */
    width: 100%;
  }
}

/* Icônes devant chaque ligne de coordonnées */
.breeder-card-info p {
  display: flex;
  align-items: center;
  gap: 8px;
}
.line-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: rgba(246, 11, 81, 0.12);
  color: var(--wp--preset--color--accent, #F60B51);
  font-size: 0.75rem;
  flex-shrink: 0;
}
@media (max-width: 700px) {
  .breeder-card-info p {
    justify-content: center;
  }
}

/* Bouton "Contacter" (remplace l'adresse e-mail en texte brut) */
.breeder-card .contact-btn {
  display: inline-block;
  margin-top: 16px;
  background: var(--wp--preset--color--accent2, #778ead);
  color: #fff !important;
  text-decoration: none !important;
  font-size: 0.8rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 10px 22px;
  border-radius: 20px;
  transition: background 0.2s ease;
}
.breeder-card .contact-btn:hover {
  background: var(--wp--preset--color--accent, #F60B51);
}

/* Confirmation flottante affichée au clic sur "Contacter" (2.20.106) : le
   lien mailto: peut ne rien faire du tout si le visiteur n'a pas de client
   de messagerie configuré — ce message confirme que l'adresse a bien été
   copiée dans le presse-papier, avec l'adresse affichée en toutes lettres
   comme filet de secours si même la copie échoue.
   2.20.161 : sur demande d'Alex, repositionné au milieu de l'écran
   (au lieu d'en bas) et affiché plus longtemps (voir le setTimeout dans
   functions.php). */
.ucfas-contact-toast {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, calc(-50% + 12px));
  z-index: 9999;
  max-width: min(92vw, 420px);
  background: rgba(51, 51, 51, 0.94);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: center;
  padding: 12px 20px;
  border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.ucfas-contact-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, -50%);
}
@media (prefers-reduced-motion: reduce) {
  .ucfas-contact-toast {
    transition: opacity 0.25s ease;
    transform: translate(-50%, -50%);
  }
  .ucfas-contact-toast.is-visible {
    transform: translate(-50%, -50%);
  }
}

/* ============================================
   RÉSULTATS PAR CLASSE (cartes) — pattern
   « Résultats par classe (cartes) »
   ============================================ */
.class-results-grid {
  margin: 2rem 0;
  /* Filet de sécurité : le motif "Résultats par classe (cartes)" obtient
     déjà sa grille du support de mise en page de Gutenberg (style inline
     généré sur le bloc). Le shortcode [ucfas_resultats] (2.9.0) produit du
     HTML brut sans cet inline style : ces deux propriétés lui donnent la
     même grille par défaut. Sans effet sur le motif existant (l'inline
     style du bloc est prioritaire). */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 1.5rem;
}
/* Grille à une seule carte (ex. « Meilleur TCN ») : Gutenberg génère, par
   bloc, une classe unique (ex. .wp-container-core-group-is-layout-XXXX)
   avec sa propre règle grid-template-columns basée sur minimumColumnWidth,
   qui utilise 1fr pour la piste restante. Avec une seule carte présente,
   cette unique piste absorbe alors toute la largeur du conteneur au lieu
   de rester à la taille d'une carte normale. On plafonne la largeur d'une
   piste à celle d'une carte classique pour que le nombre de cartes
   n'affecte plus leur taille — !important nécessaire pour prendre le pas
   sur la règle générée, quel que soit l'ordre de chargement des feuilles
   de style.
   2.20.40 : élargie de 280-340px à 460-600px pour que chaque résultat
   (nom, affixe, propriétaire) ait la place de tenir sur une seule ligne —
   voir .class-result-card-body ol li plus bas. */
.class-results-grid {
  grid-template-columns: repeat(auto-fit, minmax(480px, 640px)) !important;
}
.class-result-card {
  background: rgba(255, 255, 255, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.05);
  transition: transform 0.25s ease, box-shadow 0.25s ease;
}
.class-result-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(0, 0, 0, 0.09);
}
.class-result-card.ucfas-card-clickable {
  cursor: zoom-in;
}
/* Visionneuse plein écran (assets/js/class-card-lightbox.js) */
.ucfas-lightbox-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.88);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4vh 4vw;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.2s ease;
  z-index: 9999;
}
.ucfas-lightbox-overlay.is-open {
  opacity: 1;
  visibility: visible;
}
.ucfas-lightbox-img {
  max-width: 92vw;
  max-height: 92vh;
  object-fit: contain;
  border-radius: 10px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
  cursor: default;
}
.ucfas-lightbox-close {
  position: fixed;
  top: 18px;
  right: 24px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.15);
  color: #fff;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s ease;
}
.ucfas-lightbox-close:hover {
  background: rgba(255, 255, 255, 0.28);
}
body.ucfas-lightbox-locked {
  overflow: hidden;
}
.class-result-card .class-photo {
  /* Neutralise la règle de flottement alterné pensée pour les photos
     isolées au milieu d'un texte migré (voir plus haut dans ce fichier) :
     elle ciblait .wp-block-image sans distinction et s'appliquait aussi
     ici, réduisant la photo à sa largeur intrinsèque au lieu de remplir
     la carte. */
  float: none !important;
  max-width: none !important;
  width: 100% !important;
  margin: 0 !important;
  text-align: left !important;
}
.class-result-card .class-photo img {
  /* 2.20.147 : affichage de la photo en entier (plus de recadrage en
     bandeau à 160px/object-fit:cover, qui coupait systématiquement le
     haut et le bas de la photo). La hauteur suit désormais librement le
     format de chaque photo — les cartes d'une même grille peuvent donc
     avoir des hauteurs différentes selon l'orientation de leur photo. */
  display: block;
  width: 100%;
  height: auto;
  object-fit: contain;
  margin: 0 !important;
  float: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
}
/* Quand la photo garde son lien vers la version grand format (loupe/lightbox),
   l'image est entourée d'un <a>. Ce lien est en display:inline-block par
   défaut et se réduit à la taille intrinsèque de l'image (« shrink-to-fit »),
   ce qui empêche le width:100% ci-dessus de s'appliquer correctement : la
   photo se retrouve étroite au lieu de remplir la carte. On force le lien à
   se comporter comme un bloc pleine largeur pour que la photo suive. */
.class-result-card .class-photo a {
  display: block;
  width: 100%;
}
.class-result-card-body {
  padding: 20px 22px 22px;
}
.class-result-card-body .section-eyebrow {
  margin: 0 0 4px !important;
}
.class-result-card-count {
  color: var(--wp--preset--color--muted, #64748B) !important;
  font-size: 0.85rem;
  margin: 0 0 14px !important;
}
.class-result-card-body ol {
  list-style: none;
  counter-reset: rank;
  margin: 0 !important;
  padding: 0 !important;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.class-result-card-body ol li {
  counter-increment: rank;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 0 !important;
  color: var(--wp--preset--color--text, #1E293B) !important;
  font-size: 0.92rem;
  line-height: 1.4;
}
/* 2.20.40 : nom / affixe / propriétaire vivent désormais dans trois
   <span> distincts (voir ucfas_glass_resultats_shortcode() dans
   inc/resultats-concours.php) plutôt qu'un seul bloc de texte, pour éviter
   qu'une mention un peu longue ("Coup de cœur — NIKITA AUNOR de la Horde
   du Loup Gascon (à Mme TAMENNE)") ne fasse enrouler toute la ligne sur
   3-4 lignes dans la carte. Ne s'applique qu'aux résultats générés par le
   shortcode [ucfas_resultats] ; le motif "Résultats par classe (cartes)"
   (contenu saisi à la main dans l'éditeur, un simple <li> de texte) n'est
   pas concerné.
   2.20.56 : chaque colonne tronquait son propre texte avec "…" (affixe et
   propriétaire surtout), le texte complet n'étant visible qu'au survol
   (attribut title) — invisible sur mobile/tactile et peu pratique même au
   clavier/souris (signalé par Alex, capture à l'appui : "de la Légende du
   Loup …" tronqué). On affiche désormais le texte complet en le laissant
   s'enrouler sur plusieurs lignes DANS sa colonne plutôt que de le couper :
   la carte grandit un peu en hauteur sur les lignes concernées, mais plus
   aucune information n'est cachée. min-width:0 reste nécessaire pour que
   les enfants flex acceptent de rétrécir sous leur largeur de contenu par
   défaut (sinon ils poussent la carte en largeur au lieu de s'enrouler). */
.class-result-card-body .entry-name,
.class-result-card-body .entry-affixe,
.class-result-card-body .entry-owner {
  overflow: visible;
  white-space: normal;
  text-overflow: clip;
  min-width: 0;
}
.class-result-card-body .entry-name {
  /* 2.20.57 : largeur au contenu (pas de flex-grow) au lieu d'une largeur
     fixe à 42% qui laissait un nom court ("OASIS") grandir pour occuper
     tout l'espace inutilisé de sa colonne — l'espace ainsi perdu poussait
     l'affixe dans une colonne trop étroite, qui s'enroulait sur deux
     lignes (signalé par Alex, capture à l'appui). max-width borne les noms
     très longs (avec mention "Coup de cœur — ...") pour qu'ils ne
     réduisent pas trop l'affixe et le propriétaire à leur tour. */
  flex: 0 1 auto;
  max-width: 55%;
}
.class-result-card-body .entry-mention {
  color: var(--wp--preset--color--muted, #64748B);
}
.class-result-card-body .entry-affixe {
  color: var(--wp--preset--color--muted, #475569);
  font-size: 0.85rem;
}
.class-result-card-body .entry-affixe,
.class-result-card-body .entry-owner {
  /* 2.20.58 : en 2.20.57, .entry-affixe avait flex-grow:1 pour récupérer
     l'espace libéré par .entry-name (voir ci-dessus), mais grandissait
     ainsi bien au-delà de son propre texte — cet excédent de largeur
     n'était pas utilisé par l'affixe (aligné à gauche dans sa colonne) et
     manquait ensuite au propriétaire, resté lui à une largeur fixe (28%)
     trop juste pour "M. et Mme BRISWALTER-WENTZEL" par exemple : il
     s'enroulait sur deux lignes alors qu'il restait justement de la place
     visible à sa gauche (signalé par Alex, capture à l'appui). Les deux
     colonnes prennent maintenant chacune la largeur de leur propre texte
     (comme .entry-name ci-dessus) au lieu de se disputer un espace que
     l'une gaspille sans besoin réel : chacune ne s'enroule sur deux lignes
     que si la carte est vraiment trop étroite pour tout faire tenir. */
  flex: 0 1 auto;
}
.class-result-card-body .entry-owner {
  color: var(--wp--preset--color--muted, #64748B);
  font-size: 0.85rem;
}
.class-result-card-body ol li::before {
  content: counter(rank);
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--wp--preset--color--accent2, #778EAD);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 1px;
}
.class-result-card-body ol li:nth-child(1)::before {
  background: #F5B301;
  color: #4A3400;
}
.class-result-card-body ol li:nth-child(2)::before {
  background: #94A3B8;
}
.class-result-card-body ol li:nth-child(3)::before {
  background: #B08D57;
}
@media (max-width: 700px) {
  .class-results-grid {
    grid-template-columns: 1fr !important;
  }

  /* 2.20.42 : sur mobile, un résultat par ligne d'information plutôt que
     les 3 colonnes côte à côte — une carte pleine largeur reste trop
     étroite pour ce découpage une fois affichée en une seule colonne (voir
     la règle ci-dessus). Ne touche pas au desktop/tablette (au-delà de
     700px), qui garde les colonnes sur une ligne mises en place en 2.20.40.
     "flex-basis: 100%" sur un enfant flex en wrap le force à occuper sa
     propre ligne (technique standard) : chaque span passe donc sous le
     précédent au lieu de rester aligné à côté. Depuis 2.20.56, le texte
     complet s'affiche déjà (sans troncature) à toutes les largeurs — cette
     règle ne change donc plus que la disposition (empilée) sur mobile, pas
     la visibilité du texte. */
  .class-result-card-body ol li {
    flex-wrap: wrap;
    row-gap: 2px;
  }
  .class-result-card-body .entry-name,
  .class-result-card-body .entry-affixe,
  .class-result-card-body .entry-owner {
    flex: 1 1 100%;
  }
}

/* ============================================
   BARRE DE RECHERCHE — page Étalons disponibles
   ============================================ */
.etalon-search {
  padding: 20px 24px;
  border-radius: 18px;
  margin: 0 0 24px;
}
.etalon-search-row {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
}
.etalon-search-row-name {
  margin-bottom: 12px;
}
.etalon-input {
  border: 1px solid rgba(30, 41, 59, 0.12);
  background: rgba(255, 255, 255, 0.8);
  border-radius: 10px;
  padding: 9px 12px;
  font-size: 0.85rem;
  color: var(--wp--preset--color--text, #1E293B);
  font-family: inherit;
}
.etalon-input-name {
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}
.etalon-input-num {
  width: 110px;
  flex: 0 0 auto;
}
.etalon-input:focus {
  outline: none;
  border-color: var(--wp--preset--color--accent, #F60B51);
  box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.12);
}
.etalon-reset {
  border: none;
  background: rgba(119, 142, 173, 0.15);
  color: var(--wp--preset--color--text, #1E293B);
  font-weight: 700;
  font-size: 0.8rem;
  padding: 9px 16px;
  border-radius: 10px;
  cursor: pointer;
  transition: background 0.2s ease;
  flex: 0 0 auto;
}
.etalon-reset:hover {
  background: rgba(246, 11, 81, 0.15);
  color: var(--wp--preset--color--accent, #F60B51);
}
.etalon-count {
  margin: 12px 0 0 !important;
  font-size: 0.8rem;
  color: var(--wp--preset--color--muted, #64748B) !important;
}

/* État vide de la recherche d'étalons (0 résultat) : même ton chaleureux
   que la page 404 (pattes de chien, message rassurant, action directe),
   affiché par ucfas_glass_stallion_search() à la place du compteur brut
   quand aucune carte ne correspond aux filtres. */
.etalon-empty {
  margin-top: 18px !important;
  padding: 34px 24px 28px;
  border-radius: 20px !important;
  text-align: center;
}
.etalon-empty-paws {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 6px;
  margin-bottom: 12px;
}
.etalon-empty-paw {
  fill: rgba(246, 11, 81, 0.55);
}
.etalon-empty-paw-sm {
  width: 18px;
  height: 18px;
  fill: rgba(246, 11, 81, 0.3);
}
.etalon-empty-paw-sm:first-child {
  transform: rotate(-12deg);
}
.etalon-empty-paw-sm:last-child {
  transform: rotate(12deg);
}
.etalon-empty-paw-md {
  width: 24px;
  height: 24px;
}
.etalon-empty-title {
  font-weight: 700;
  font-size: 1rem;
  color: var(--wp--preset--color--text, #1E293B);
  margin: 0 0 6px !important;
}
.etalon-empty-text {
  font-size: 0.85rem;
  color: var(--wp--preset--color--muted, #64748B) !important;
  margin: 0 0 16px !important;
}
.etalon-empty-reset {
  border: none;
  background: linear-gradient(135deg, #F60B51, #D00742);
  color: #fff;
  font-weight: 700;
  font-size: 0.82rem;
  padding: 10px 22px;
  border-radius: 20px;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(246, 11, 81, 0.24);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.etalon-empty-reset:hover {
  transform: translateY(-2px);
  box-shadow: 0 12px 26px rgba(246, 11, 81, 0.3);
}
@media (max-width: 700px) {
  .etalon-search { padding: 16px 18px; }
  .etalon-input-num { flex: 1 1 45%; }
}

/* ============================================
   GALERIE VERRE — branchée sur NextGEN Gallery
   (shortcode [ucfas_gallery id="X" tags="Tag 1,Tag 2"], voir functions.php)
   ============================================
   On restyle les classes générées par les templates NextGEN
   "basic thumbnails" : .ngg-galleryoverview, .ngg-gallery-thumbnail-box,
   .ngg-gallery-thumbnail, et le <span> de légende par image. Si NextGEN
   change ces classes dans une future mise à jour, seule cette section
   est à ajuster. */
.gallery-filter-bar {
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 8px;
  margin: 1.5rem 0 2rem;
}
.gallery-filter-pill {
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  color: var(--wp--preset--color--accent2, #475569);
  font-size: 0.78rem;
  font-weight: 700;
  padding: 7px 18px;
  border-radius: 999px;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease;
}
.gallery-filter-pill:hover {
  background: rgba(255, 255, 255, 0.8);
}
.gallery-filter-pill.is-active {
  background: var(--wp--preset--color--accent, #F60B51);
  border-color: var(--wp--preset--color--accent, #F60B51);
  color: #fff;
}
.gallery-filter-panel.is-hidden {
  display: none;
}
/* Sécurité : masque le lien "Montrer sous forme de diaporama" de NextGEN
   s'il apparaît malgré show_slideshow_link="0" (ex. version mise en cache). */
.photo-gallery-glass-ngg .ngg-slideshow-link,
.photo-gallery-glass-ngg a[href*="slideshow"] {
  display: none !important;
}
.photo-gallery-glass-ngg .ngg-galleryoverview {
  display: grid !important;
  grid-template-columns: repeat(4, 1fr) !important;
  gap: 12px !important;
  margin: 2.5rem 0 !important;
  width: 100% !important;
  counter-reset: ucfas-photo;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail-box {
  width: auto !important;
  float: none !important;
  margin: 0 !important;
  max-width: none !important;
  position: relative;
  counter-increment: ucfas-photo;
}
/* Badge numéroté en verre flouté, révélé au survol — visible même sans
   légende NextGEN, pour garder un vrai moment "verre" sur chaque photo. */
.photo-gallery-glass-ngg .ngg-gallery-thumbnail-box::after {
  content: counter(ucfas-photo);
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 3;
  background: rgba(255, 255, 255, 0.55);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.7);
  color: var(--wp--preset--color--text, #1E293B);
  font-size: 0.7rem;
  font-weight: 700;
  min-width: 24px;
  height: 24px;
  padding: 0 6px;
  border-radius: 999px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail-box:hover::after {
  opacity: 1;
  transform: translateY(0);
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail {
  position: relative;
  border: 1px solid rgba(255, 255, 255, 0.35) !important;
  background: transparent !important;
  border-radius: 22px;
  overflow: hidden;
  margin: 0 !important;
  aspect-ratio: 4 / 5;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail:hover {
  transform: translateY(-4px);
  box-shadow: -6px 6px 18px rgba(246, 11, 81, 0.22), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  border-left: 3px solid rgba(246, 11, 81, 0.6) !important;
  border-bottom: 3px solid rgba(246, 11, 81, 0.6) !important;
}
/* Reflet diagonal qui balaie la photo au survol (même effet que les
   cartes "À découvrir" de la page d'accueil, mais atténué ici). */
.photo-gallery-glass-ngg .ngg-gallery-thumbnail::before {
  content: "";
  position: absolute;
  top: 0;
  left: -60%;
  width: 30%;
  height: 100%;
  background: linear-gradient(115deg, transparent, rgba(255, 255, 255, 0.22), transparent);
  transform: skewX(-15deg);
  transition: left 0.9s ease;
  pointer-events: none;
  z-index: 2;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail:hover::before {
  left: 130%;
}
/* Voile en bas de chaque photo, pour donner de la profondeur sans
   dépendre d'une légende (celle-ci reste facultative, voir plus bas). */
.photo-gallery-glass-ngg .ngg-gallery-thumbnail::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.32), transparent 55%);
  pointer-events: none;
  z-index: 1;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail a {
  position: absolute;
  inset: 0;
  display: block;
  margin: 0 !important;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail:hover img {
  transform: scale(1.06);
}
/* Légende par image (titre / description saisis dans NextGEN), au-dessus du voile */
.photo-gallery-glass-ngg .ngg-gallery-thumbnail span {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  background: rgba(255, 255, 255, 0.75);
  backdrop-filter: blur(14px) saturate(180%);
  -webkit-backdrop-filter: blur(14px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 10px;
  padding: 8px 12px !important;
  font-size: 0.78rem;
  font-weight: 700;
  color: var(--wp--preset--color--text, #1E293B);
  text-align: left;
}
.photo-gallery-glass-ngg .ngg-gallery-thumbnail span:empty {
  display: none;
}
@media (prefers-reduced-transparency: reduce) {
  .photo-gallery-glass-ngg .ngg-gallery-thumbnail span,
  .photo-gallery-glass-ngg .ngg-gallery-thumbnail-box::after {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    background: #ffffff;
  }
}
@media (max-width: 700px) {
  .photo-gallery-glass-ngg .ngg-galleryoverview {
    grid-template-columns: repeat(2, 1fr) !important;
    gap: 14px !important;
  }
  .photo-gallery-glass-ngg .ngg-gallery-thumbnail {
    box-shadow: 0 8px 18px rgba(0, 0, 0, 0.06), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    border-color: rgba(246, 11, 81, 0.18) !important;
  }
  /* Pas de survol tactile sur mobile : le badge numéroté reste visible en
     permanence plutôt que de dépendre d'un :hover qui ne se déclenchera pas. */
  .photo-gallery-glass-ngg .ngg-gallery-thumbnail-box::after {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ============================================
   DÉCLARATION DE PORTÉE (formulaire en 3 étapes)
   ============================================ */
.ucfas-declaration-wrap { max-width: 680px; }
/* 2.20.95 : sur demande d'Alex, l'intitulé de la manifestation (repas ou
   exposition) au-dessus du sous-titre "Les champs obligatoires...", sur
   toutes les étapes des deux formulaires concernés — jusqu'ici rien
   n'indiquait, une fois sur le formulaire, POUR QUELLE manifestation on
   était en train de s'inscrire. Style repris du H1 des pages (Georgia
   italique) mais en rose d'accent et plus petit, pour rester bien visible
   sans concurrencer le vrai titre H1 de la page juste au-dessus.
   2.20.96 : signalé par Alex, capture à l'appui — s'affichait en gris/bleu
   muté au lieu du rose prévu. Cause : ce paragraphe est toujours à
   l'intérieur de ".content-card" (voir page-inscription-repas.php et
   page-inscription-expo.php), et ".content-card p { color: ... muted }"
   (plus haut dans ce fichier) a une spécificité CSS plus forte (une classe
   + un sélecteur de balise) qu'un simple ".ucfas-decl-event-banner" (une
   seule classe) — peu importe l'ordre des règles dans le fichier, la règle
   la plus spécifique gagne toujours. Corrigé en préfixant le sélecteur par
   ".content-card" pour égaliser puis dépasser cette spécificité. */
.content-card .ucfas-decl-event-banner { text-align: center; font-family: Georgia, serif; font-style: italic; font-weight: 700; font-size: clamp(1.15rem, 2.6vw, 1.5rem); color: #F60B51; margin: 0 0 8px; }
/* 2.20.97 : sur demande d'Alex, capture à l'appui — l'écran de confirmation
   des 5 formulaires (Inscription repas, Déclaration de portée, Adhésion,
   Demande d'affixe, Inscription expo) affichait son texte aligné à gauche
   au lieu d'être centré, malgré le `text-align:center` déjà posé en style
   inline sur le conteneur `.ucfas-decl-card` de cet écran. Même famille de
   bug que le 2.20.96 ci-dessus : `.content-card p { text-align: left; }`
   (tout en haut de ce fichier) cible directement chaque <p>, et une règle
   explicite sur l'élément l'emporte toujours sur une valeur seulement
   héritée du parent — peu importe que ce parent ait lui-même un
   `text-align:center`. Nouvelle classe dédiée `.ucfas-decl-confirm-card`
   (ajoutée à côté de `.ucfas-decl-card` sur ces 5 écrans uniquement, pas sur
   le reste des formulaires où le texte doit rester aligné à gauche), avec
   une spécificité suffisante (deux classes) pour battre `.content-card p`.
   2.20.98 : même correctif étendu, sur confirmation d'Alex, aux deux autres
   écrans de confirmation construits sur le même modèle mais hors du
   périmètre initial des "5 formulaires" — Contact (`inc/contact.php`) et
   Feuille de jugement (`inc/jugement-expo.php`). Même classe
   `.ucfas-decl-confirm-card`, aucun nouveau CSS nécessaire. */
.content-card .ucfas-decl-confirm-card,
.content-card .ucfas-decl-confirm-card p { text-align: center; }
.ucfas-decl-subtitle { color: var(--wp--preset--color--muted, #64748B); font-size: 14px; margin-top: -0.5rem; }
.ucfas-decl-steps { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; justify-content: center; align-items: center; gap: 6px; margin: 20px 0 28px; width: 100%; }
.ucfas-decl-dot { flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; }
.ucfas-decl-dot.is-active { background: #F60B51; color: #fff; }
.ucfas-decl-dot.is-done { background: rgba(34,197,94,0.15); color: #16a34a; }
.ucfas-decl-dot.is-upcoming { background: rgba(30, 41, 59, 0.1); color: #64748B; }
.ucfas-decl-steplabel { flex: 0 0 auto; font-size: 12px; white-space: nowrap; }
.ucfas-decl-steplabel.is-active { color: #1E293B; font-weight: 700; }
.ucfas-decl-steplabel.is-upcoming, .ucfas-decl-steplabel.is-done { color: #94A3B8; }
.ucfas-decl-stepline { flex: 1 1 16px; min-width: 12px; max-width: 40px; height: 2px; background: rgba(30, 41, 59, 0.15); margin: 0 4px; }
/* La portion de ligne qui suit une étape déjà validée se remplit en rose,
   pour une sensation de progression plus nette qu'un simple trait fixe. */
.ucfas-decl-dot.is-done + .ucfas-decl-steplabel + .ucfas-decl-stepline {
  background: #F60B51;
}
@media (max-width: 480px) {
	.ucfas-decl-steps { gap: 4px; }
	.ucfas-decl-steplabel { display: none; }
	.ucfas-decl-stepline { max-width: 24px; }
}

.ucfas-decl-card {
  background: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(20px) saturate(180%);
  -webkit-backdrop-filter: blur(20px) saturate(180%);
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 24px;
  padding: 32px;
  box-shadow: 0 20px 50px rgba(30, 41, 59, 0.08), inset 0 1px 0 rgba(255, 255, 255, 0.6);
  margin-bottom: 1.5rem;
}
.ucfas-decl-section { font-size: 11px; letter-spacing: 1px; text-transform: uppercase; color: #F60B51; font-weight: 700; margin: 24px 0 12px; }
.ucfas-decl-section:first-child { margin-top: 0; }
.ucfas-decl-row { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 14px; }
.ucfas-decl-row.single { grid-template-columns: 1fr; }
.ucfas-decl-field { display: flex; flex-direction: column; gap: 6px; }
/* Sans cette règle, [hidden] (même spécificité que .ucfas-decl-field) est
   silencieusement ignoré : masquer un champ via l'attribut hidden (ex.
   "Ou saisir librement" sur l'étape Nom du Juge, affiché seulement si
   "Saisie manuelle" est choisi) ne fonctionnait pas, le champ restant
   visible en display:flex. */
.ucfas-decl-field[hidden] { display: none; }
.ucfas-decl-field label { font-size: 12px; font-weight: 700; color: #475569; line-height: 1.35; transition: color 0.2s ease; }
/* Le libellé passe en rose accent dès que son propre champ est actif —
   petit lien visuel entre le label et le champ qu'il décrit, pour un
   formulaire qui se sent plus "guidé". */
.ucfas-decl-field:has(input:focus) label,
.ucfas-decl-field:has(select:focus) label,
.ucfas-decl-field:has(textarea:focus) label {
  color: #F60B51;
}
/* 2.20.60 : les deux champs d'une même .ucfas-decl-row (2 colonnes) peuvent
   avoir des libellés de longueurs très différentes (ex. "Nom complet (avec
   affixe) du père du chien 2" sur 2 lignes à côté de "N° de pedigree du
   père du chien 2" sur 1 seule) — chaque .ucfas-decl-field empile
   label+input en flex sans lien avec l'autre colonne, donc le champ au
   libellé plus court démarrait son input plus haut que celui d'à côté,
   désalignant les deux inputs de la ligne. On réserve la hauteur de 2
   lignes sur ces libellés (qu'ils tiennent sur 1 ou 2 lignes) pour que les
   inputs restent alignés quel que soit le nombre de lignes du texte.
   2.20.67 : limité aux lignes à 2 colonnes (:not(.single)) — appliqué à
   tort à TOUTES les lignes en 2.20.60, ça réservait aussi 2 lignes de
   hauteur sur les libellés à une seule colonne (ex. "Dans quelle classe
   souhaitez-vous l'inscrire ?"), qui n'ont aucun alignement à préserver :
   ça laissait un vide visible entre le libellé et ce qui suit juste en
   dessous (ex. la ligne d'âge du chien) — signalé par Alex. */
.ucfas-decl-row:not(.single) .ucfas-decl-field label { min-height: 2.7em; }
.ucfas-decl-field input[type="text"], .ucfas-decl-field input[type="email"], .ucfas-decl-field input[type="date"], .ucfas-decl-field select, .ucfas-decl-field textarea {
  width: 100%; background: rgba(255, 255, 255, 0.8); border: 1.5px solid rgba(30, 41, 59, 0.14);
  border-radius: 16px; padding: 11px 14px; font-size: 14px; font-family: inherit; color: #1E293B;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
/* Icône calendrier personnalisée sur les champs date, à la place de la
   flèche/icône brute du navigateur (Chrome/Edge/Safari — Firefox n'expose
   pas ce pseudo-élément mais hérite déjà du style de champ ci-dessus). */
.ucfas-decl-field input[type="date"] {
  color-scheme: light;
}
.ucfas-decl-field input[type="date"]::-webkit-calendar-picker-indicator {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='2'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
  background-size: 16px 16px;
  background-repeat: no-repeat;
  background-position: center;
  width: 20px;
  height: 20px;
  cursor: pointer;
  opacity: 1;
}
/* Chevron personnalisé sur les menus déroulants, à la place de la flèche
   native du navigateur — cohérent avec le reste des icônes de champ.
   ".ucfas-decl-review-field" (champs de relecture verrouillés) garde
   volontairement l'apparence native, cf. règle dédiée plus bas. */
.ucfas-decl-field select {
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 14px center;
  background-size: 14px 14px;
}
/* Petites icônes de repère dans les champs les plus reconnaissables
   (email, téléphone, adresse) — même principe visuel qu'un champ de
   recherche avec loupe, purement décoratif (pas de perte d'info si
   l'icône ne s'affiche pas, ex. lecteur d'écran). Fond en deux calques :
   l'icône + le même fond que le champ, pour ne pas dépendre de l'ordre
   des règles CSS. */
.ucfas-decl-field input[type="email"],
.ucfas-decl-field input[name="email"],
.ucfas-decl-field input[name="telephone"],
.ucfas-decl-field input[name="adresse"],
.ucfas-decl-field input[name="organisateur_adresse"],
.ucfas-decl-field input[name="salle_adresse"] {
  padding-left: 38px;
  background-repeat: no-repeat;
  background-position: 12px center;
  background-size: 16px 16px;
}
.ucfas-decl-field input[type="email"],
.ucfas-decl-field input[name="email"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16v16H4z' stroke='none'/%3E%3Cpath d='M3 6l9 7 9-7'/%3E%3Cpath d='M3 6v12h18V6'/%3E%3C/svg%3E");
}
.ucfas-decl-field input[name="telephone"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z'/%3E%3C/svg%3E");
}
.ucfas-decl-field input[name="adresse"],
.ucfas-decl-field input[name="organisateur_adresse"],
.ucfas-decl-field input[name="salle_adresse"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2394A3B8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-6.5-7-11a7 7 0 0 1 14 0c0 4.5-7 11-7 11z'/%3E%3Ccircle cx='12' cy='10' r='2.5'/%3E%3C/svg%3E");
}
.ucfas-decl-field input[type="email"]:focus,
.ucfas-decl-field input[name="email"]:focus,
.ucfas-decl-field input[name="telephone"]:focus,
.ucfas-decl-field input[name="adresse"]:focus,
.ucfas-decl-field input[name="organisateur_adresse"]:focus,
.ucfas-decl-field input[name="salle_adresse"]:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16v16H4z' stroke='none'/%3E%3Cpath d='M3 6l9 7 9-7'/%3E%3Cpath d='M3 6v12h18V6'/%3E%3C/svg%3E");
}
.ucfas-decl-field input[name="telephone"]:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z'/%3E%3C/svg%3E");
}
.ucfas-decl-field input[name="adresse"]:focus,
.ucfas-decl-field input[name="organisateur_adresse"]:focus,
.ucfas-decl-field input[name="salle_adresse"]:focus {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 21s-7-6.5-7-11a7 7 0 0 1 14 0c0 4.5-7 11-7 11z'/%3E%3Ccircle cx='12' cy='10' r='2.5'/%3E%3C/svg%3E");
}
/* 2.20.92 : le "resize" natif d'un <textarea> (ex. le champ "Votre message"
   du formulaire de contact) autorise par défaut un agrandissement en
   LARGEUR en plus de la hauteur — l'utilisateur peut alors le tirer plus
   large que le champ "Sujet" juste au-dessus, cassant l'alignement des deux
   champs. Restreint à la hauteur seule (comportement identique partout où
   ce composant est utilisé). */
.ucfas-decl-field textarea { resize: vertical; }
.ucfas-decl-field input:focus, .ucfas-decl-field select:focus, .ucfas-decl-field textarea:focus { outline: none; border-color: rgba(246, 11, 81, 0.55); box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.12); }
/* 2.20.68 : dans le menu "Dans quelle classe souhaitez-vous l'inscrire ?",
   les options grisées par le navigateur (classes hors d'âge, voir
   ucfas_expo_classe_eligible_for_age()) se distinguaient trop peu des
   options normales au premier coup d'œil (nuance de gris subtile,
   dépendante du rendu natif du système) — signalé par Alex. Les navigateurs
   n'appliquent qu'un jeu très limité de styles CSS aux <option>, d'où le
   texte en italique ici plutôt qu'une pastille/icône ; un repère textuel
   explicite (suffixe "— âge non compatible", ajouté côté PHP) complète ce
   style pour rester lisible même là où le CSS des options est ignoré
   (certains mobiles). */
.ucfas-expo-classe-select option:disabled,
.ucfas-expo-classe-select option.ucfas-expo-classe-ineligible {
  color: #b6c0cc;
  font-style: italic;
}
/* 2.20.64 : le remplissage automatique du navigateur (Chrome/Safari) impose
   un fond jaune pâle sur les champs qu'il a pré-remplis — signalé par Alex
   sur "numéro d'adhérent" (Inscription expo) resté jaune après avoir
   répondu "Oui" à la question précédente, mais le même mécanisme concerne
   tous les champs texte de ces formulaires. Ce fond est appliqué en interne
   par le navigateur (pas par ce thème) et ignore un simple "background" :
   on le neutralise avec l'astuce standard du box-shadow inset (une seule
   propriété que l'on peut surcharger), pour retrouver le même fond que les
   champs non pré-remplis — y compris quand le champ est aussi au focus
   (glow rose additionné plutôt que perdu). */
.ucfas-decl-field input:-webkit-autofill,
.ucfas-decl-field input:-webkit-autofill:hover {
  -webkit-box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.8) inset;
  box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.8) inset;
  -webkit-text-fill-color: #1E293B;
  caret-color: #1E293B;
  transition: background-color 600000s ease-in-out 0s, color 600000s ease-in-out 0s;
}
.ucfas-decl-field input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.8) inset, 0 0 0 3px rgba(246, 11, 81, 0.12);
  box-shadow: 0 0 0 1000px rgba(255, 255, 255, 0.8) inset, 0 0 0 3px rgba(246, 11, 81, 0.12);
  -webkit-text-fill-color: #1E293B;
  caret-color: #1E293B;
  transition: background-color 600000s ease-in-out 0s, color 600000s ease-in-out 0s;
}
/* Champ "grisé" (Race sur Feuille de jugement : toujours la même valeur,
   pas la peine que le juge puisse la modifier ring-side). Générique sur
   tout .ucfas-decl-field, réutilisable ailleurs si besoin. */
.ucfas-decl-field input[readonly] {
  background: rgba(30, 41, 59, 0.06);
  color: #64748B;
  cursor: not-allowed;
}
.ucfas-decl-field input[readonly]:focus {
  box-shadow: none;
  border-color: rgba(30, 41, 59, 0.14);
}

.ucfas-decl-review-row { display: flex; justify-content: space-between; align-items: center; gap: 16px; padding: 8px 0; border-bottom: 1px solid rgba(30,41,59,0.08); font-size: 14px; }
.ucfas-decl-review-row:last-child { border-bottom: none; }
.ucfas-decl-review-row span:first-child { color: #64748B; flex: 0 0 auto; }
.ucfas-decl-review-value { display: flex; align-items: center; gap: 6px; justify-content: flex-end; flex: 1 1 auto; min-width: 0; }
.ucfas-decl-review-field { border: none; background: transparent; font-weight: 700; color: #1E293B; text-align: right; font-size: 14px; font-family: inherit; padding: 4px 6px; border-radius: 8px; max-width: 100%; min-width: 0; }
.ucfas-decl-review-field.is-locked { pointer-events: none; }
.ucfas-decl-review-field:not(.is-locked) { background: rgba(246, 11, 81, 0.06); box-shadow: 0 0 0 2px rgba(246, 11, 81, 0.3); outline: none; }
select.ucfas-decl-review-field { appearance: auto; }
.ucfas-decl-edit-btn { flex: 0 0 auto; border: none; background: rgba(30, 41, 59, 0.08); color: #475569; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; font-size: 12px; padding: 0; transition: background 0.2s ease, color 0.2s ease; }
.ucfas-decl-edit-btn:hover { background: rgba(246, 11, 81, 0.15); color: #F60B51; }

.ucfas-decl-puppy-heading { display: flex; align-items: center; gap: 12px; margin: 28px 0 16px; padding-top: 22px; border-top: 1px solid rgba(30, 41, 59, 0.1); }
.ucfas-decl-puppy-heading:first-of-type { margin-top: 4px; padding-top: 0; border-top: none; }
.ucfas-decl-puppy-badge { flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 18px; font-weight: 700; line-height: 1; }
.ucfas-decl-puppy-badge.is-male { background: #DCE7F5; color: #4A6FA5; }
.ucfas-decl-puppy-badge.is-female { background: #FBDCE7; color: #F60B51; }
.ucfas-decl-puppy-heading h3 { margin: 0; font-family: Georgia, serif; font-style: italic; font-weight: 700; font-size: 18px; color: #1E293B; }

.ucfas-decl-submit-row { display: flex !important; flex-direction: row !important; flex-wrap: nowrap !important; justify-content: center; align-items: center; gap: 14px; margin-top: 8px; width: 100%; }
.ucfas-decl-submit-row form { flex: 0 1 auto; min-width: 0; }
.ucfas-decl-submit-row .ucfas-decl-btn { flex: 0 1 auto; min-width: 0; max-width: 100%; white-space: normal; text-align: center; }
.ucfas-decl-btn {
  border: none; border-radius: 30px; font-weight: 700; text-transform: uppercase; font-size: 13px;
  letter-spacing: 0.6px; padding: 14px 32px; cursor: pointer;
  transition: transform 0.2s ease, box-shadow 0.2s ease, filter 0.2s ease;
}
a.ucfas-decl-btn { display: inline-block; text-decoration: none; text-align: center; }
.ucfas-decl-btn:hover { transform: translateY(-2px); filter: brightness(1.05); }
.ucfas-decl-btn-primary { background: linear-gradient(135deg, #F60B51, #D00742); color: #fff; }
.ucfas-decl-btn-primary:hover { box-shadow: 0 12px 25px rgba(246, 11, 81, 0.35); }
.ucfas-decl-btn-secondary { background: #778ead; color: #fff; }
.ucfas-decl-btn-secondary:hover { box-shadow: 0 12px 25px rgba(119, 142, 173, 0.35); }

.ucfas-decl-icon-ok { width: 56px; height: 56px; border-radius: 50%; background: rgba(34,197,94,0.15); color: #16a34a; font-size: 28px; display: flex; align-items: center; justify-content: center; margin: 0 auto 18px; }
.ucfas-decl-warn { font-size: 13px; color: #b45309; background: rgba(251,191,36,0.15); border-radius: 12px; padding: 10px 14px; margin-top: 16px; }

.ucfas-decl-consent { margin-top: 20px; padding: 18px 22px; }
.ucfas-decl-consent-label,
.ucfas-decl-checkbox-label { display: flex; align-items: flex-start; gap: 12px; cursor: pointer; font-size: 13.5px; line-height: 1.5; color: #475569; }
/* Case à cocher "glass" (carré arrondi + coche), en remplacement de la
   case native du navigateur — ciblée largement via ".ucfas-decl-card
   input[type=checkbox]" pour couvrir aussi les cases de consentement qui
   n'ont pas de classe dédiée sur leur <label> (ex. "consentement" sur
   inscription-expo.php et l'adhésion), sans dépendre de la présence d'une
   classe particulière. */
.ucfas-decl-card input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border-radius: 6px;
  border: 1.5px solid rgba(30, 41, 59, 0.2);
  background: rgba(255, 255, 255, 0.8);
  cursor: pointer;
  position: relative;
  transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.ucfas-decl-card input[type="checkbox"]:hover {
  border-color: rgba(246, 11, 51, 0.5);
}
.ucfas-decl-card input[type="checkbox"]:checked {
  background: linear-gradient(135deg, #F60B51, #D00742);
  border-color: transparent;
  box-shadow: 0 4px 10px rgba(246, 11, 81, 0.28);
}
.ucfas-decl-card input[type="checkbox"]:checked::after {
  content: "";
  position: absolute;
  left: 6px;
  top: 2px;
  width: 5px;
  height: 10px;
  border: solid #fff;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.ucfas-decl-card input[type="checkbox"]:focus-visible {
  outline: 2px solid #F60B51;
  outline-offset: 2px;
}
.ucfas-decl-consent-label a { color: #F60B51; text-decoration: underline; }

/* 2.19.0 : lien "modifier" inline (formulaire Inscription repas) — un
   simple <a> stylé en accent, utilisé dans une phrase plutôt qu'un bouton
   pilule .ucfas-decl-btn, pour rester dans le fil du texte comme sur le
   modèle fourni ("En cas d'erreur de saisie, vous pouvez modifier."). */
.ucfas-decl-inline-link { color: #F60B51; font-weight: 700; text-decoration: underline; cursor: pointer; }
.ucfas-decl-inline-link:hover { color: #D00742; }

@media (max-width: 700px) {
  .ucfas-decl-card { padding: 22px; border-radius: 20px; }
  .ucfas-decl-row { grid-template-columns: 1fr; }
}
@media (max-width: 480px) {
  .ucfas-decl-submit-row { gap: 8px; }
  .ucfas-decl-submit-row .ucfas-decl-btn { padding: 12px 14px; font-size: 10.5px; letter-spacing: 0.2px; }
}

/* ============================================
   FEUILLE DE JUGEMENT — page publique (2.20.183/184)
   Pilules radio (Sexe/Classe) du formulaire unique, même famille visuelle
   que .ucfas-decl-* ci-dessus. Le menu déroulant "Chien inscrit" lui-même
   n'a besoin d'aucun style particulier — il réutilise .ucfas-decl-field
   select comme n'importe quel autre champ du formulaire.
   ============================================ */

/* Pilules radio (Sexe) — remplace le radio natif par un toggle "verre".
   border/padding/margin "neutres" posés dès la base (pas seulement sur
   l'état invalide ci-dessous) pour que l'apparition du liseré rouge au
   clignotement ne décale rien autour. */
.ucfas-jug-pill-group {
  display: flex;
  gap: 10px;
  align-items: center;
  height: 100%;
  border: 1.5px solid transparent;
  border-radius: 14px;
  padding: 4px;
  margin: -4px;
}
.ucfas-jug-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
  padding: 10px 18px;
  border-radius: 14px;
  border: 1.5px solid rgba(30, 41, 59, 0.14);
  background: rgba(255, 255, 255, 0.8);
  font-size: 13.5px;
  font-weight: 600;
  color: #475569;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.ucfas-jug-pill input { position: absolute; opacity: 0; pointer-events: none; }
.ucfas-jug-pill:has(input:checked) {
  background: linear-gradient(135deg, #F60B51, #D00742);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 6px 14px rgba(246, 11, 81, 0.28);
}
.ucfas-jug-pill:has(input:focus-visible) { outline: 2px solid #F60B51; outline-offset: 2px; }
/* Le clic sur une pilule donne le focus à son radio, ce qui déclenche la
   règle globale ".ucfas-decl-field:has(input:focus) label { color:
   #F60B51; }" (plus haut dans ce fichier) sur TOUS les libellés du champ,
   y compris les pilules elles-mêmes — sa spécificité (2 classes + 1 type)
   dépasse celle de ma règle "checked" ci-dessus (2 classes seules),
   d'où un texte rose sur fond rose (quasi illisible) sur la pilule
   sélectionnée dès qu'elle a le focus. Un sélecteur plus spécifique
   (3 classes) rétablit le blanc dans ce cas précis, sans toucher au
   comportement des autres champs/formulaires. */
.ucfas-decl-card .ucfas-jug-pill:has(input:checked) { color: #fff; }

/* Espacement libellé → champ incohérent, signalé par Alex : la règle
   globale ".ucfas-decl-row:not(.single) .ucfas-decl-field label {
   min-height: 2.7em;}" (plus haut) réserve 2 lignes de hauteur sous les
   libellés des champs en 2 colonnes (Date/Lieu, Race/Sexe, etc.), pour
   aligner des libellés de longueurs très différentes sur d'autres
   formulaires — mais sur cette page tous les libellés sont courts et
   tiennent sur une ligne, donc cette réserve ne fait qu'ajouter un espace
   inutile, absent sur les champs en 1 colonne (Nom du chien, Chien
   inscrit) juste à côté. On annule la réserve pour ce formulaire précis
   afin que l'espacement reste identique partout. */
#ucfas-jug-public-form .ucfas-decl-row .ucfas-decl-field label { min-height: auto; }

/* Grille "Classe" — 2 lignes x 4 colonnes sur desktop, empilée sur mobile. */
.ucfas-jug-classe-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  border: 1.5px solid transparent;
  border-radius: 14px;
  padding: 4px;
  margin: -4px;
}
.ucfas-jug-classe-grid .ucfas-jug-pill { justify-content: center; padding: 9px 8px; font-size: 12.5px; text-align: center; }
@media (max-width: 700px) {
  .ucfas-jug-classe-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Parcours en plusieurs étapes (Dentition, puis les ~26 sections à venir)
   — un écran par section, voir ucfas_jugement_render_step_public() dans
   inc/feuille-jugement.php. Options en liste verticale plutôt qu'en
   pilules horizontales (.ucfas-jug-pill) : les intitulés multilingues de
   la feuille papier (ex. "Complète en ciseau – Volles Scherengebiss –
   Full Scissor Bite") sont trop longs pour tenir sur une ligne courte. */
/* Chien "en cours" dans le menu déroulant "Chien inscrit" — orange + gras
   pour le repérer d'un coup d'œil (sur demande d'Alex). Passé d'un style
   en ligne à une règle CSS avec !important : certains navigateurs (Chrome
   sous Windows notamment) ignorent la couleur du texte posée en style
   direct sur une <option> lors du rendu de la liste déroulante ouverte,
   mais respectent plus fiablement une règle issue d'une feuille de style. */
#jug-chien-select option.ucfas-jug-option-en-cours {
  /* 2.20.310 : orange plus vif (#ea580c au lieu de #d97706, jugé trop terne
     par Alex) + fond orangé clair, pour que les chiens « en cours » ressortent
     nettement dans le menu déroulant — y compris lorsqu'une ligne est survolée
     (le fond gris de survol masquait l'ancien orange). */
  color: #ea580c !important;
  font-weight: 700 !important;
  background-color: #fff1e6 !important;
}
#jug-chien-select optgroup {
  /* 2.20.309 : en-têtes de classe (Baby, Puppy…) bien lisibles. */
  color: #1e293b;
  font-weight: 700;
}

/* 2.20.311 : menu « Chien inscrit » CUSTOM (non natif) — voir l'IIFE
   correspondante dans assets/js/jugement-public.js. Le rendu coloré des
   <option> natives n'est pas fiable partout (Firefox ignore la couleur des
   options quand le select est en appearance:none). Ce menu maison affiche
   les groupes de classe et les chiens « en cours » en orange de façon
   IDENTIQUE dans tous les navigateurs. Le <select> natif reste masqué
   (.ucfas-jug-cs-native) pour la soumission et comme repli sans JS. */
.ucfas-jug-cs { position: relative; }
.ucfas-jug-cs-native {
  position: absolute !important;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0; padding: 0; margin: -1px;
}
.ucfas-jug-cs-btn {
  width: 100%; text-align: left; cursor: pointer;
  background: rgba(255, 255, 255, 0.8);
  border: 1.5px solid rgba(30, 41, 59, 0.14);
  border-radius: 16px;
  padding: 11px 38px 11px 14px;
  font-size: 14px; font-family: inherit; color: #1E293B;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23F60B51' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 14px center; background-size: 14px 14px;
  transition: border-color 0.2s ease, box-shadow 0.2s ease;
}
.ucfas-jug-cs-btn:focus {
  outline: none;
  border-color: rgba(246, 11, 81, 0.55);
  box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.12);
}
.ucfas-jug-cs[data-open="true"] .ucfas-jug-cs-btn {
  border-color: rgba(246, 11, 81, 0.55);
  box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.12);
}
.ucfas-jug-cs-panel {
  position: absolute; z-index: 60; left: 0; right: 0; top: calc(100% + 6px);
  max-height: 320px; overflow-y: auto;
  background: #fff;
  border: 1.5px solid rgba(30, 41, 59, 0.14);
  border-radius: 14px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12);
  padding: 6px;
}
.ucfas-jug-cs-panel[hidden] { display: none; }
.ucfas-jug-cs-group {
  padding: 9px 12px 4px;
  font-size: 11.5px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em;
  color: #64748b;
}
.ucfas-jug-cs-opt {
  padding: 9px 12px; border-radius: 10px;
  font-size: 14px; color: #1E293B; cursor: pointer;
}
.ucfas-jug-cs-opt.is-group-child { padding-left: 22px; }
.ucfas-jug-cs-opt:hover,
.ucfas-jug-cs-opt.is-active { background: #f1f5f9; }
.ucfas-jug-cs-opt[aria-selected="true"] { background: rgba(246, 11, 81, 0.08); font-weight: 600; }
.ucfas-jug-cs-opt.is-en-cours { color: #ea580c; font-weight: 700; background: #fff1e6; }
.ucfas-jug-cs-opt.is-en-cours:hover,
.ucfas-jug-cs-opt.is-en-cours.is-active { background: #ffe2cc; }

.ucfas-jug-step-header {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}
.ucfas-jug-step-count {
  margin: 0 !important;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--wp--preset--color--accent, #F60B51);
  text-align: center;
}
/* Bouton + menu de navigation entre étapes ("maison", pas un <select>
   natif — voir le commentaire dans ucfas_jugement_render_step_public()) :
   permet de sauter directement à n'importe quelle section plutôt que de
   n'avancer que d'un cran à la fois via Suivant/Précédent, sur demande
   d'Alex. Les sections déjà répondues apparaissent en gris/italique. */
.ucfas-jug-step-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  padding: 0;
  border: none;
  background: rgba(30, 41, 59, 0.08);
  border-radius: 50%;
  color: #1E293B;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.ucfas-jug-step-nav-toggle:hover { background: rgba(30, 41, 59, 0.15); }
.ucfas-jug-step-nav-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.ucfas-jug-step-nav-toggle svg { transition: transform 0.2s ease; }
.ucfas-jug-step-nav-menu {
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  margin-top: 6px;
  width: 270px;
  max-height: 300px;
  overflow-y: auto;
  background: #fff;
  border: 1px solid rgba(30, 41, 59, 0.12);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(30, 41, 59, 0.16);
  padding: 6px;
  z-index: 30;
  text-align: left;
}
.ucfas-jug-step-nav-item {
  display: block;
  padding: 8px 10px;
  border-radius: 9px;
  font-size: 13px;
  font-weight: 600;
  color: #1E293B;
  text-decoration: none;
  transition: background 0.15s ease;
}
.ucfas-jug-step-nav-item:hover {
  background: rgba(246, 11, 81, 0.07);
}
.ucfas-jug-step-nav-item.is-done {
  color: #94A3B8;
  font-style: italic;
  font-weight: 400;
}
.ucfas-jug-step-nav-item.is-current {
  color: #F60B51;
  font-weight: 700;
  background: rgba(246, 11, 81, 0.06);
}
.ucfas-jug-step-nav-sublabel {
  font-weight: 400;
  font-size: 0.85em;
  opacity: 0.75;
}
/* Confirmation avant "← Précédent" (voir assets/js/jugement-public.js) —
   centrée à l'écran, dans le style du thème plutôt que la boîte native
   confirm() du navigateur (non stylable, pas cohérente visuellement). */
.ucfas-jug-confirm-overlay {
  position: fixed;
  inset: 0;
  background: rgba(30, 41, 59, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
  padding: 20px;
}
.ucfas-jug-confirm-modal {
  background: #fff;
  border-radius: 20px;
  padding: 30px 26px;
  max-width: 320px;
  width: 100%;
  text-align: center;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.3);
}
.ucfas-jug-confirm-modal p {
  margin: 0 0 22px;
  font-size: 15px;
  font-weight: 600;
  color: #1E293B;
  line-height: 1.4;
}
.ucfas-jug-confirm-actions {
  display: flex;
  gap: 12px;
  justify-content: center;
}
.ucfas-jug-confirm-actions .ucfas-decl-btn {
  flex: 1 1 auto;
}
.ucfas-decl-card .ucfas-jug-step-title {
  margin-top: 1em !important;
  text-align: center;
  text-transform: none;
  letter-spacing: normal;
  font-size: 1.15rem;
  font-weight: 700;
  color: #1E293B;
}
.ucfas-jug-step-sublabel {
  display: inline;
  font-size: 1em;
  font-weight: 700;
  font-style: normal;
  color: #1E293B;
}
.ucfas-decl-card .ucfas-jug-step-chien-nom {
  margin: 18px 0 0 !important;
  text-align: right;
  font-size: 0.85rem;
  font-weight: 700;
  font-style: italic;
  color: #A0AEC0;
}
.ucfas-jug-step-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 18px 0 24px;
  border: 1.5px solid transparent;
  border-radius: 14px;
  padding: 4px;
  margin-left: -4px;
  margin-right: -4px;
  /* Numérote chaque option (1, 2, 3...) affiché dans son rond — voir
     .ucfas-jug-step-option::before ci-dessous — pour permettre de choisir
     au clavier en tapant simplement le chiffre correspondant (voir
     assets/js/jugement-public.js), sur demande d'Alex pour aller plus
     vite ring-side sans avoir à cliquer précisément sur chaque ligne. */
  counter-reset: ucfas-jug-option;
}
.ucfas-jug-step-option {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1.5px solid rgba(30, 41, 59, 0.14);
  background: rgba(255, 255, 255, 0.8);
  font-size: 14px;
  font-weight: 600;
  color: #475569;
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
  counter-increment: ucfas-jug-option;
}
/* Radio natif masqué (toujours présent et cliquable pour le clavier/lecteur
   d'écran) — remplacé visuellement par un rond gris neutre affichant le
   NUMÉRO de l'option (1, 2, 3...), qui devient un rond vert ✓ plein sur la
   ligne sélectionnée une fois un choix fait. Version "neutre par défaut"
   (option 1 proposée à Alex) : pas de croix avant sélection — elle
   donnait l'impression trompeuse que "tout est faux" alors qu'aucun choix
   n'a encore été fait.
   Fonds de case : neutres tant qu'AUCUNE option du groupe n'est cochée
   (comme à l'origine) ; dès qu'un choix est fait, la ligne choisie passe
   en vert et les AUTRES lignes (pas cette ligne-ci) passent en rose
   discret — d'où le :not(:has(input:checked)) ci-dessous, qui cible
   spécifiquement "les autres". */
.ucfas-jug-step-option input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.ucfas-jug-step-option::before {
  content: counter( ucfas-jug-option );
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  background: transparent;
  border: 2px solid #CBD5E1;
  color: #94A3B8;
  box-sizing: border-box;
  transition: background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.ucfas-jug-step-options:has(input:checked) .ucfas-jug-step-option:not(:has(input:checked)) {
  border-color: rgba(246, 11, 81, 0.18);
  background: rgba(246, 11, 81, 0.045);
}
.ucfas-jug-step-option:has(input:checked) {
  border-color: rgba(34, 197, 94, 0.4);
  background: rgba(34, 197, 94, 0.07);
}
.ucfas-jug-step-option:has(input:checked)::before {
  content: '✓';
  background: rgba(34, 197, 94, 0.18);
  border-color: transparent;
  color: #16a34a;
}
.ucfas-jug-step-option:has(input:focus-visible) { outline: 2px solid #F60B51; outline-offset: 2px; }

/* Tous les champs de la Feuille de jugement sont obligatoires (sur demande
   d'Alex) : cette classe, posée dynamiquement (voir
   assets/js/jugement-public.js et ucfas_jugement_render_form_public()) sur
   un champ vide au moment de la validation, fait clignoter son liseré 3
   fois pour attirer l'œil, puis le laisse rouge fixe — un clignotement en
   continu serait plus fatigant à l'œil et poserait un problème
   d'accessibilité (photosensibilité) sans apporter d'information
   supplémentaire une fois l'attention du juge attirée. */
@keyframes ucfas-jug-blink {
  0%, 100% {
    border-color: rgba(30, 41, 59, 0.14);
    box-shadow: none;
  }
  50% {
    border-color: #F60B51;
    box-shadow: 0 0 0 3px rgba(246, 11, 81, 0.25);
  }
}
.ucfas-decl-field input.ucfas-jug-field-invalid,
.ucfas-decl-field select.ucfas-jug-field-invalid,
.ucfas-decl-field textarea.ucfas-jug-field-invalid,
.ucfas-jug-pill-group.ucfas-jug-field-invalid,
.ucfas-jug-step-options.ucfas-jug-field-invalid,
.ucfas-jug-classe-grid.ucfas-jug-field-invalid {
  animation: ucfas-jug-blink 0.5s ease-in-out 3;
  border-color: #F60B51 !important;
}

/* Carte des éleveurs affiliés (page "trouver-son-as/eleveurs") — Leaflet /
   OpenStreetMap, injectée par ucfas_glass_eleveurs_inject_map(). */
.ucfas-eleveurs-map-toggle {
  display: flex;
  justify-content: center;
  margin: 1.5rem 0;
}
.ucfas-eleveurs-map-toggle .wp-block-button {
  margin: 0;
}
.ucfas-eleveurs-map-toggle .wp-block-button__link {
  cursor: pointer;
}
.ucfas-eleveurs-map-wrap {
  margin: 0 0 2.25rem;
}
.ucfas-eleveurs-map-wrap[hidden] {
  display: none;
}
#ucfas-eleveurs-map {
  height: 480px;
  width: 100%;
  border-radius: 18px;
  border: 1px solid rgba(255, 255, 255, 0.8);
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.08);
  background: rgba(255, 255, 255, 0.5); /* pendant le chargement des tuiles */
}
.ucfas-eleveurs-map-caption {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  color: var(--wp--preset--color--muted, #64748B);
  text-align: center;
}
/* Bulle Leaflet réhabillée pour coller au style du site plutôt qu'au thème
   par défaut de la librairie. */
.ucfas-eleveurs-map-wrap .leaflet-popup-content-wrapper {
  border-radius: 12px;
  box-shadow: 0 10px 24px rgba(0, 0, 0, 0.12);
}
.ucfas-eleveurs-map-wrap .leaflet-popup-content {
  font-family: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  font-size: 0.85rem;
  color: var(--wp--preset--color--text, #1E293B);
  line-height: 1.5;
}
.ucfas-eleveurs-map-wrap .leaflet-tooltip {
  font-family: 'Plus Jakarta Sans', system-ui, -apple-system, sans-serif;
  font-size: 0.8rem;
  font-weight: 700;
  color: var(--wp--preset--color--text, #1E293B);
  border: 1px solid rgba(30, 41, 59, 0.12);
  border-radius: 8px;
  padding: 4px 10px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.1);
}
/* Filet de sécurité : la bulle d'info (nom de l'éleveur + adresse) qui
   s'ouvre au clic sur un point de la carte utilise l'animation de fondu
   native de Leaflet (opacity 0 -> 1 pilotée par la classe
   ".leaflet-fade-anim"). Ce fondu ne se termine pas de façon fiable dans
   tous les environnements/navigateurs, laissant la bulle bloquée
   invisible (opacity: 0) alors qu'elle est bien ouverte avec le bon
   contenu — elle "n'apparaît pas au clic". On force sa visibilité en
   direct, sans dépendre du fondu.  */
.ucfas-eleveurs-map-wrap .leaflet-popup {
  opacity: 1 !important;
}
@media (max-width: 600px) {
  #ucfas-eleveurs-map { height: 360px; border-radius: 14px; }
}

/* ============================================
   PAGE 404 (templates/404.html) — 2.20.55
   ============================================
   Gabarit "page introuvable" du thème (jusqu'ici, WordPress retombait sur
   templates/index.html : une simple boucle d'articles vide, sans aucun
   message, très peu accueillant). Reprend la structure standard des
   pages du site (.page-title-band + .content-card, cf. templates/page.html)
   pour rester cohérent avec le reste, avec juste une touche ludique
   assumée (clin d'œil canin) plutôt qu'un message d'erreur froid — Alex
   a explicitement demandé une page "sympa". */
.ucfas-404-eyebrow {
  color: var(--wp--preset--color--accent, #F60B51);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 0.85rem;
  margin: 0 0 0.5rem;
}
.ucfas-404-card {
  text-align: center;
}
/* Petite trace de pattes qui s'éloigne, comme si le chien de la page
   s'était sauvé en courant : 4 empreintes de taille croissante (celle du
   fond, la plus petite, suggère qu'elle s'enfuit au loin), légèrement
   décalées verticalement et alternées en rotation pour un tracé naturel
   plutôt qu'une ligne droite trop rigide. Purement décoratif
   (aria-hidden), sans contenu informatif. */
.ucfas-404-paws {
  display: flex;
  justify-content: center;
  align-items: flex-end;
  gap: 0.85rem;
  margin: 0 0 1.75rem;
}
.ucfas-404-paw {
  display: inline-flex;
  color: var(--wp--preset--color--accent, #F60B51);
}
.ucfas-404-paw-1 { opacity: 0.35; transform: translateY(-2px) rotate(-8deg); }
.ucfas-404-paw-2 { opacity: 0.55; transform: translateY(3px) rotate(6deg); }
.ucfas-404-paw-3 { opacity: 0.8; transform: translateY(-2px) rotate(-6deg); }
.ucfas-404-paw-4 { opacity: 1; transform: translateY(2px) rotate(4deg); animation: ucfas-404-wag 2.4s ease-in-out infinite; }
@keyframes ucfas-404-wag {
  0%, 100% { transform: translateY(2px) rotate(4deg); }
  50% { transform: translateY(2px) rotate(14deg); }
}
@media (prefers-reduced-motion: reduce) {
  .ucfas-404-paw-4 { animation: none; }
}
@media (max-width: 480px) {
  .ucfas-404-paws { gap: 0.6rem; }
}

/* 2.20.154 : filigrane "panneau de danger" sur la page d'erreur des liens
   externes fragiles (inc/external-link-guard.php), sur le même principe
   décoratif que les pattes de la page 404 ci-dessus : purement visuel
   (aria-hidden), grand triangle en couleur accent très diluée, affiché en
   arrière-plan dans le cadre de la carte, derrière le texte. Le point
   d'exclamation est "découpé" dans le triangle (fill-rule: evenodd) plutôt
   que dessiné par-dessus, pour un rendu net même à très faible opacité. */
.ucfas-link-error-card {
  position: relative;
  overflow: hidden;
}
.ucfas-link-error-watermark {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 160px !important;
  height: 160px !important;
  transform: translate(-50%, -50%);
  color: var(--wp--preset--color--accent, #F60B51);
  opacity: 0.07;
  pointer-events: none;
  z-index: 0;
}
@media (max-width: 480px) {
  .ucfas-link-error-watermark { width: 110px !important; height: 110px !important; }
}
.ucfas-link-error-watermark svg {
  display: block;
  width: 100%;
  height: 100%;
}
.ucfas-link-error-content {
  position: relative;
  z-index: 1;
}

/* ============================================
   VARIANTES DE MISE EN PAGE POUR PAGES DE CONTENU
   (patterns/section-image-droite.php et
   patterns/section-en-bref.php) — à insérer au cas par
   cas, en complément de la carte pleine largeur par défaut.
   ============================================ */
.content-split {
  padding: 2.5rem 2.75rem !important;
}
.content-split-columns {
  align-items: center !important;
  gap: 2.5rem !important;
}
.content-split-image-col {
  align-self: center;
}
.content-split-img {
  margin: 0 !important;
}
.content-split-img img {
  border-radius: 20px;
  box-shadow: 0 14px 32px rgba(15, 23, 42, 0.12);
  width: 100%;
  height: auto;
  object-fit: cover;
}

/* Encadré "En bref" : teinte accent douce, pour un résumé rapide en marge
   du texte principal. */
.ucfas-en-bref {
  background: rgba(246, 11, 81, 0.06);
  border: 1px solid rgba(246, 11, 81, 0.18);
  border-radius: 20px;
  padding: 1.4rem 1.5rem;
}
.ucfas-en-bref-title {
  font-size: 0.78rem !important;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--wp--preset--color--accent, #F60B51) !important;
  margin: 0 0 0.7rem !important;
}
.ucfas-en-bref-list {
  margin: 0 !important;
  padding-left: 1.1rem !important;
  font-size: 0.9rem;
}
.ucfas-en-bref-list li {
  margin-bottom: 0.5rem;
  color: var(--wp--preset--color--text, #1E293B);
}
.ucfas-en-bref-list li:last-child {
  margin-bottom: 0;
}

@media (max-width: 700px) {
  .content-split {
    padding: 1.75rem 1.5rem !important;
  }
  .content-split-columns {
    gap: 1.5rem !important;
  }
  .content-split-image-col {
    order: -1;
  }
}

/* ============================================
   PARCOURS TCN (Test de Capacités Naturelles)
   assets/js/tcn-form.js + inc/test-tcn.php
   ============================================ */
.ucfas-tcn-progress {
  height: 4px;
  background: rgba(30, 41, 59, 0.1);
  border-radius: 2px;
  overflow: hidden;
  margin-bottom: 0.75rem;
}
.ucfas-tcn-progress-fill {
  height: 100%;
  background: #F60B51;
  border-radius: 2px;
  transition: width 0.3s ease;
}
.ucfas-tcn-step-label {
  font-size: 12px;
  color: #94A3B8;
  margin: 0 0 1rem;
}
.ucfas-tcn-title {
  margin: 0 0 1rem;
}
/* Les exercices TCN réutilisent désormais le même mécanisme de sélection
   que la feuille de jugement (.ucfas-jug-step-options / .ucfas-jug-step-option
   dans glass.css, section "FEUILLE DE JUGEMENT") : rond numéroté par
   option, sélection au clavier en tapant son chiffre, ligne choisie en
   vert avec un ✓, les autres en rose discret dès qu'un choix est fait —
   voir assets/js/tcn-form.js. Seul l'espacement propre au TCN (les points
   de chaque option affichés à droite, absents de la feuille de jugement)
   est ajouté ici via .ucfas-tcn-step-option, en plus de la classe commune. */
.ucfas-tcn-step-option {
  justify-content: space-between;
}
.ucfas-tcn-step-option .ucfas-tcn-option-text {
  flex: 1;
}
.ucfas-tcn-option-text {
  font-size: 14px;
  color: #1E293B;
}
.ucfas-tcn-option-pts {
  font-size: 13px;
  font-weight: 700;
  color: #64748B;
  flex-shrink: 0;
}
.ucfas-tcn-recap-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.ucfas-tcn-recap-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(30, 41, 59, 0.08);
}
.ucfas-tcn-recap-title {
  font-size: 13px;
  color: #1E293B;
  flex: 1;
}
.ucfas-tcn-recap-select {
  max-width: 220px;
}
.ucfas-tcn-total-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 1.25rem;
  padding: 1rem 1.25rem;
  border-radius: 16px;
  background: rgba(30, 41, 59, 0.04);
}
.ucfas-tcn-total-label {
  font-size: 13px;
  color: #64748B;
  margin: 0;
}
.ucfas-tcn-total-value {
  font-size: 24px;
  font-weight: 700;
  color: #1E293B;
  margin: 0;
}
.ucfas-tcn-badge {
  padding: 6px 16px;
  border-radius: 20px;
  font-size: 13px;
  font-weight: 700;
  background: rgba(246, 11, 81, 0.12);
  color: #F60B51;
}
@media (max-width: 480px) {
  .ucfas-tcn-recap-row {
    flex-direction: column;
    align-items: flex-start;
  }
  .ucfas-tcn-recap-select {
    max-width: 100%;
    width: 100%;
  }
}
.ucfas-tcn-hint {
  font-size: 12px;
  color: #94A3B8;
  margin: 6px 0 0;
}
/* Message "aucune exposition en cours" (ucfas_tcn_closed_message) :
   centré, avec un triangle d'avertissement en filigrane très discret en
   fond de carte. Même bug de spécificité que .ucfas-tcn-progress-summary-text
   plus haut (".content-card p { text-align:left; }" est plus spécifique
   qu'un simple style inline) — on force donc via une règle dédiée. */
.ucfas-tcn-closed-card {
  max-width: 520px;
  margin: 0 auto;
  position: relative;
  overflow: hidden;
}
.ucfas-tcn-closed-card p {
  text-align: center !important;
  position: relative;
  z-index: 1;
}
.ucfas-tcn-closed-card::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 260px;
  height: 260px;
  transform: translate(-50%, -50%);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231E293B' stroke-width='1.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z'/%3E%3Cline x1='12' y1='9' x2='12' y2='13'/%3E%3Cline x1='12' y1='17' x2='12.01' y2='17'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: contain;
  opacity: 0.04;
  pointer-events: none;
  z-index: 0;
}
/* Toast affiché si on tente de valider le récapitulatif alors qu'un exercice
   n'a pas été répondu (possible depuis l'ajout du menu "Aller à un autre
   exercice", qui permet de sauter des exercices sans y répondre — voir
   assets/js/tcn-form.js) : même principe visuel que .ucfas-contact-toast
   dans functions.php (carte sombre centrée, apparition en fondu), mais
   dupliqué ici plutôt que réutilisé — celui de functions.php est défini
   dans une fonction JS interne à une IIFE différente, donc inaccessible
   depuis ce fichier. */
.ucfas-tcn-toast {
  position: fixed;
  left: 50%;
  top: 50%;
  transform: translate(-50%, calc(-50% + 12px));
  z-index: 9999;
  max-width: min(92vw, 420px);
  background: rgba(51, 51, 51, 0.94);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  color: #fff;
  font-size: 0.85rem;
  line-height: 1.4;
  text-align: center;
  padding: 12px 20px;
  border-radius: 14px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.22);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
.ucfas-tcn-toast.is-visible {
  opacity: 1;
  transform: translate(-50%, -50%);
}
@media (prefers-reduced-motion: reduce) {
  .ucfas-tcn-toast {
    transition: opacity 0.25s ease;
    transform: translate(-50%, -50%);
  }
  .ucfas-tcn-toast.is-visible {
    transform: translate(-50%, -50%);
  }
}
/* Patte de chien en filigrane sur les pages de formulaire — même tracé que
   les autres pattes du thème (404, état vide de la recherche d'étalons).
   2.20.187 : règle généralisée à TOUTE page utilisant .ucfas-declaration-wrap
   (elle était jusqu'ici scopée au seul gabarit page-test-tcn.php via la
   classe de template WordPress) — sur demande d'Alex, en prévision d'autres
   pages à venir qui voudront la même patte sans code CSS supplémentaire :
   il suffit de reprendre le même marquage `<span class="ucfas-tcn-watermark">`
   (voir page-test-tcn.php et page-jugement-feuille.php) dans le wrapper.
   Élément réel (pas un ::before) pour qu'un script comme
   assets/js/tcn-form.js puisse éventuellement la déplacer — voir
   moveWatermark() dans ce fichier pour le TCN, qui reste inchangé ; les
   autres pages n'ont besoin d'aucun JS, la patte reste alors fixe. */
.ucfas-declaration-wrap {
  position: relative;
  overflow: hidden;
}
.ucfas-tcn-watermark {
  position: absolute;
  bottom: -20px;
  right: -10px;
  width: 60px !important;
  height: 60px !important;
  opacity: 0.05;
  transform: rotate(-12deg);
  transition: top 0.6s ease, bottom 0.6s ease, left 0.6s ease, right 0.6s ease, transform 0.6s ease;
  pointer-events: none;
  z-index: 0;
}
.ucfas-tcn-watermark svg {
  width: 100%;
  height: 100%;
  fill: #1E293B;
}
.ucfas-declaration-wrap > *:not(.ucfas-tcn-watermark) {
  position: relative;
  z-index: 1;
}
/* Champ pré-rempli et verrouillé depuis une exposition (date/lieu du
   TCN repris de l'exposition sélectionnée, voir tcn-form.js). */
.ucfas-decl-field input.is-locked {
  background: rgba(30, 41, 59, 0.05);
  color: #64748B;
  cursor: not-allowed;
}
/* Écran de confirmation : "Télécharger le PDF" et "Envoyer par email"
   côte à côte, "Test TCN suivant" en dessous sur sa propre ligne. */
.ucfas-tcn-confirm-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  justify-content: center;
  margin-top: 18px;
}
.ucfas-tcn-confirm-actions form {
  display: contents;
}
/* Une fois l'email envoyé, remplace le bouton par un badge non cliquable
   (email_sent_at renseigné) — plus de possibilité de renvoyer depuis
   l'écran de confirmation. */
.ucfas-tcn-email-sent {
  background: rgba(34, 197, 94, 0.12) !important;
  color: #16a34a !important;
  border: none !important;
  cursor: default !important;
  pointer-events: none;
}
.ucfas-tcn-next-row {
  text-align: center !important;
  margin-top: 12px !important;
}
.ucfas-tcn-email-notice {
  text-align: center !important;
  font-size: 13px;
  color: #16a34a;
  margin: 4px 0 0 !important;
}
@media (max-width: 480px) {
  .ucfas-tcn-confirm-actions {
    flex-direction: column;
  }
  .ucfas-tcn-confirm-actions .ucfas-decl-btn,
  .ucfas-tcn-confirm-actions form {
    width: 100%;
  }
}
/* Résumé d'avancement sous le bouton de l'étape 1 (nombre de chiens déjà
   testés / prévus), voir ucfas_tcn_progress_stats(). */
.ucfas-tcn-progress-summary {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid rgba(30, 41, 59, 0.08);
}
.ucfas-tcn-progress-summary-text {
  font-size: 13px;
  color: #475569;
  text-align: center !important;
  margin: 0 0 8px;
}
.ucfas-tcn-progress-summary .ucfas-tcn-progress {
  margin-bottom: 0;
}
