/* ============================================================================
   COMPOSANTS
   Regle d'or : chaque composant expose ses propres variables locales, et un
   modificateur ne reassigne QUE ces variables — jamais une propriete CSS.
   Consequence : aucune specificite a arbitrer, aucune divergence entre pages.
   ========================================================================= */

@layer components {

/* ---- BOUTON ---------------------------------------------------------- */
.btn {
  --btn-bg: transparent;
  --btn-fg: var(--c-text);
  --btn-bd: var(--c-border-strong);
  /* Hauteur figee : la taille du libelle ne change plus le gabarit du bouton. */
  --btn-h: 2.75rem;
  --btn-pad-y: .25rem;
  --btn-pad-x: 1.5rem;
  --btn-fs: var(--fs-base);
  --btn-shadow: var(--sh-0);

  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: var(--btn-h);
  padding: var(--btn-pad-y) var(--btn-pad-x);
  border: var(--bw) solid var(--btn-bd);
  border-radius: var(--r-pill);
  background: var(--btn-bg);
  color: var(--btn-fg);
  box-shadow: var(--btn-shadow);
  font-family: var(--ff-body);
  font-weight: var(--fw-medium);
  font-size: var(--btn-fs);
  line-height: 1;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-decoration: none;
  text-align: center;
  cursor: pointer;
  transition: var(--t-all);
}
.btn:hover { transform: translateY(-2px); color: var(--btn-fg-hover, var(--btn-fg)); }
.btn:active { transform: translateY(0) scale(.98); transition-duration: var(--dur-instant); }
.btn[disabled], .btn.is-loading { opacity: var(--op-disabled); pointer-events: none; }
.btn.is-loading::after {
  content: '';
  width: 1em; height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: var(--r-circle);
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.btn--primary { --btn-bg: var(--c-red-500); --btn-fg: #fff; --btn-bd: var(--c-red-500); --btn-shadow: var(--sh-brand); }
.btn--primary:hover { --btn-bg: var(--c-red-700); --btn-bd: var(--c-red-700); }
.btn--outline { --btn-bd: currentColor; }
.btn--ghost { --btn-bd: transparent; --btn-fg: var(--c-link); }
.btn--danger { --btn-bg: var(--c-danger); --btn-fg: #fff; --btn-bd: var(--c-danger); }
.btn--sm { --btn-h: 36px; --btn-pad-x: 1rem; --btn-fs: var(--fs-xs); }
.btn--lg { --btn-h: 3.35rem; --btn-pad-x: 2.25rem; --btn-fs: var(--fs-md); }
.btn--block { display: flex; width: 100%; }
.btn__icon { width: 1.15em; height: 1.15em; fill: currentColor; flex: none; }

/* ---- CARTE ------------------------------------------------------------ */
.card {
  --card-bg: var(--c-surface);
  --card-bd: var(--c-border);
  --card-pad: var(--sp-6);
  --card-radius: var(--r-lg);
  --card-shadow: var(--sh-1);

  display: flex;
  flex-direction: column;
  background: var(--card-bg);
  border: var(--bw-hair) solid var(--card-bd);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  transition: var(--t-all);
}
.card--link:hover { --card-shadow: var(--sh-3); transform: translateY(-4px); }
.card__media { aspect-ratio: 16 / 10; overflow: hidden; background: var(--c-bg-alt); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--dur-slow) var(--ease-out); }
.card--link:hover .card__media img { transform: scale(1.04); }
.card__body { padding: var(--card-pad); display: flex; flex-direction: column; gap: var(--sp-3); flex: 1; }
.card__meta { font-size: var(--fs-xs); letter-spacing: var(--ls-wide); text-transform: uppercase; color: var(--c-text-muted); font-weight: var(--fw-semibold); }
.card__title { font-size: var(--fs-lg); }
.card__text { color: var(--c-text-muted); }

/* ---- BADGE ------------------------------------------------------------ */
.badge {
  --badge-bg: var(--c-bg-alt);
  --badge-fg: var(--c-text);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: .3em .8em;
  border-radius: var(--r-pill);
  background: var(--badge-bg);
  color: var(--badge-fg);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  white-space: nowrap;
}
.badge--gold { --badge-bg: var(--c-gold-500); --badge-fg: var(--c-ink-900); }
.badge--success { --badge-bg: var(--c-success-bg); --badge-fg: var(--c-success); }
.badge--warning { --badge-bg: var(--c-warning-bg); --badge-fg: var(--c-warning); }
.badge--danger { --badge-bg: var(--c-danger-bg); --badge-fg: var(--c-danger); }
.badge--outline { --badge-bg: transparent; box-shadow: inset 0 0 0 var(--bw-hair) var(--c-border-strong); }

/* Disciplines : icone + libelle, jamais la couleur seule. */
.badge--natation { --badge-bg: var(--c-gold-100); --badge-fg: var(--c-gold-700); }
.badge--velo { --badge-bg: var(--c-red-100); --badge-fg: var(--c-red-700); }
.badge--cap { --badge-bg: var(--c-ink-100); --badge-fg: var(--c-ink-900); }
.badge--renfo, .badge--multi, .badge--autre { --badge-bg: var(--c-info-bg); --badge-fg: var(--c-info); }

/* ---- CHIP / FILTRE ---------------------------------------------------- */
.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  min-height: var(--hit-target);
  padding: .45rem 1rem;
  border: var(--bw-hair) solid var(--c-border-strong);
  border-radius: var(--r-pill);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: var(--t-all);
}
.chip:hover { border-color: var(--c-ink-900); }
.chip.is-selected {
  background: var(--c-ink-900);
  color: var(--c-paper);
  border-color: var(--c-ink-900);
}
.chip-group { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* ---- COMMUTATEUR SEGMENTE ----------------------------------------------
   Le rail reprend EXACTEMENT la pilule des boutons : lisere d'accent, fond
   teinte par ce meme accent. La pastille active est le bouton rempli. */
.switch {
  --switch-pad: var(--sp-1);
  --switch-fond: color-mix(in srgb, var(--c-accent) 10%, var(--c-surface));
  --switch-on: #fff;
  --switch-btn-pad: .7rem 1.6rem;
  --switch-btn-fs: var(--fs-md);

  position: relative;
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1);
  max-width: 100%;
  padding: var(--switch-pad);
  border: var(--bw) solid var(--c-accent);
  border-radius: var(--r-pill);
  background: var(--switch-fond);
  isolation: isolate;
}
/* z-index negatif : la pastille passe sous les libelles mais reste sur le fond du rail. */
.switch__thumb {
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  width: var(--switch-w, 0);
  height: var(--switch-h, 0);
  translate: var(--switch-x, 0) var(--switch-y, 0);
  border-radius: var(--r-pill);
  background: var(--c-accent);
  box-shadow: var(--sh-brand);
}
/* La transition n'arrive qu'apres le premier calage : sinon la pastille glisserait depuis le coin au chargement. */
.switch.is-ready .switch__thumb {
  transition: translate var(--dur) var(--ease-out),
              width var(--dur) var(--ease-out),
              height var(--dur) var(--ease-out);
}
/* Meme typographie que .btn sous le theme sombre : casse saisie, pas d'interlettrage. */
.switch__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--switch-btn-pad);
  border: 0;
  border-radius: var(--r-pill);
  background: none;
  color: var(--c-text);
  font-family: var(--ff-body);
  font-size: var(--switch-btn-fs);
  font-weight: var(--fw-medium);
  line-height: 1.4;
  white-space: nowrap;
  cursor: pointer;
  transition: var(--t-color);
}
.switch__btn:hover { background: color-mix(in srgb, var(--c-accent) 16%, transparent); }
.switch__btn[aria-pressed="true"] { color: var(--switch-on); }
.switch__btn[aria-pressed="true"]:hover { background: none; }
/* Sans JavaScript la pastille n'est pas mesuree : l'option active se peint elle-meme. */
.switch:not(.is-ready) .switch__btn[aria-pressed="true"] { background: var(--c-accent); }
.switch__icon { width: 1.15em; height: 1.15em; fill: currentColor; flex: none; }
/* Variante compacte : 44 px de bouton + 2 px de rail + 2 px de liseré = la hauteur d'un .btn du theme sombre. */
.switch--sm { --switch-pad: 2px; --switch-btn-pad: 0 1.1rem; --switch-btn-fs: var(--fs-sm); }

/* ---- FORMULAIRES ------------------------------------------------------ */
.field { display: flex; flex-direction: column; gap: var(--sp-2); }
.field__label { font-size: var(--fs-sm); font-weight: var(--fw-semibold); }
.field__hint { font-size: var(--fs-xs); color: var(--c-text-muted); }
.field__error { font-size: var(--fs-xs); color: var(--c-danger); font-weight: var(--fw-semibold); }
.field__error:empty { display: none; }

.input, .select, .textarea {
  --input-bd: var(--c-border-strong);
  width: 100%;
  min-height: var(--hit-target);
  padding: .7rem .9rem;
  border: var(--bw-hair) solid var(--input-bd);
  border-radius: var(--r-sm);
  background: var(--c-surface);
  color: var(--c-text);
  font-size: var(--fs-base);
  transition: var(--t-color), box-shadow var(--dur-fast) var(--ease-out);
}
.input:hover, .select:hover, .textarea:hover { --input-bd: var(--c-ink-300); }
.input:focus, .select:focus, .textarea:focus { --input-bd: var(--c-ink-900); }
.textarea { min-height: 8rem; resize: vertical; line-height: var(--lh-normal); }
.select { appearance: none; padding-right: 2.4rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 1.1rem) 55%, calc(100% - .75rem) 55%;
  background-size: .35rem .35rem, .35rem .35rem;
  background-repeat: no-repeat;
}
.field.has-error .input, .field.has-error .select, .field.has-error .textarea { --input-bd: var(--c-danger); }

.checkbox { display: flex; align-items: center; gap: var(--sp-3); min-height: var(--hit-target); cursor: pointer; }
.checkbox input { width: 1.15rem; height: 1.15rem; accent-color: var(--c-red-500); flex: none; }

.form-grid { display: grid; gap: var(--sp-5); }
@media (min-width: 768px) { .form-grid--2 { grid-template-columns: repeat(2, 1fr); } }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; }

/* ---- ALERTE ----------------------------------------------------------- */
.alert {
  --alert-bg: var(--c-info-bg);
  --alert-fg: var(--c-info);
  display: flex;
  gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-left: var(--bw-thick) solid var(--alert-fg);
  border-radius: var(--r-sm);
  background: var(--alert-bg);
  color: var(--c-ink-900);
  font-size: var(--fs-sm);
}
.alert:empty { display: none; }
.alert--success { --alert-bg: var(--c-success-bg); --alert-fg: var(--c-success); }
.alert--warning { --alert-bg: var(--c-warning-bg); --alert-fg: var(--c-warning); }
.alert--danger { --alert-bg: var(--c-danger-bg); --alert-fg: var(--c-danger); }
.alert__icon { width: 1.3em; height: 1.3em; flex: none; fill: var(--alert-fg); margin-top: .1em; }

/* ---- AVATAR : initiales par defaut, photo si elle existe --------------- */
.avatar {
  --avatar-size: 2.25rem;
  display: inline-grid;
  place-items: center;
  width: var(--avatar-size);
  height: var(--avatar-size);
  border-radius: var(--r-circle);
  background: var(--g-brand);
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: calc(var(--avatar-size) * .38);
  letter-spacing: .02em;
  overflow: hidden;
  flex: none;
  user-select: none;
}
.avatar--lg { --avatar-size: 5.5rem; }
.avatar--xl { --avatar-size: 8rem; }
.avatar img { width: 100%; height: 100%; object-fit: cover; }

/* ---- RESEAUX SOCIAUX -------------------------------------------------- */
.social { display: flex; gap: var(--sp-3); align-items: center; list-style: none; padding: 0; }
.social__link {
  display: grid;
  place-items: center;
  width: var(--hit-target);
  height: var(--hit-target);
  border: var(--bw-hair) solid var(--c-border-strong);
  border-radius: var(--r-circle);
  color: var(--c-text);
  transition: var(--t-all);
}
.social__link:hover {
  background: var(--c-gold-500);
  border-color: var(--c-gold-500);
  color: var(--c-ink-900);
  transform: translateY(-3px);
}
.social__icon { width: 1.25rem; height: 1.25rem; fill: currentColor; }
.social--lg .social__link { width: 3rem; height: 3rem; }
.social--lg .social__icon { width: 1.4rem; height: 1.4rem; }

/* ---- TABLEAU ---------------------------------------------------------- */
.table__wrap { overflow-x: auto; border: var(--bw-hair) solid var(--c-border); border-radius: var(--r-md); }
.table { font-size: var(--fs-sm); }
.table th, .table td { padding: var(--sp-3) var(--sp-4); text-align: left; border-bottom: var(--bw-hair) solid var(--c-border); }
.table th { background: var(--c-bg-alt); font-weight: var(--fw-bold); font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: var(--ls-wide); white-space: nowrap; }
.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--c-bg-alt); }

/* ---- ETAT VIDE / SQUELETTE -------------------------------------------- */
.empty {
  padding: var(--sp-12) var(--sp-6);
  text-align: center;
  color: var(--c-text-muted);
  border: var(--bw) dashed var(--c-border-strong);
  border-radius: var(--r-lg);
}
.skeleton {
  background: linear-gradient(90deg, var(--c-bg-alt) 25%, var(--c-ink-100) 50%, var(--c-bg-alt) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s infinite;
  border-radius: var(--r-sm);
  min-height: 1em;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* ---- MODALE (sur <dialog> natif) ---------------------------------------
   Le composant expose ses variables locales : la variante large et la feuille
   mobile ne reassignent QUE ces variables, jamais une propriete.

   Deux pieges corriges ici :
   1. base/reset.css pose `* { margin: 0 }`, ce qui annule le `margin: auto`
      que le navigateur applique a une <dialog> modale — sans la declaration
      ci-dessous la boite se colle en haut a gauche du viewport.
   2. `display: flex` est porte par .modal[open] et NON par .modal : une regle
      d'auteur `display` non conditionnee battrait la regle du navigateur
      `dialog:not([open]) { display: none }` et la boite serait toujours
      visible, fermee comprise. */
.modal {
  --modal-w: 620px;
  --modal-max-w: 92vw;
  --modal-margin: auto;
  --modal-radius: var(--r-lg);
  --modal-bg: var(--c-surface);
  --modal-shadow: var(--sh-4);
  --modal-pad: var(--sp-6);
  --modal-pad-y: var(--sp-5);
  --modal-h-max: calc(100dvh - var(--sp-16));
  --modal-body-max: 65svh;
  --modal-map-h: 220px;
  --modal-action-flex: 0 1 auto;

  width: 100%;
  max-width: min(var(--modal-max-w), var(--modal-w));
  max-height: var(--modal-h-max);
  margin: var(--modal-margin);
  padding: 0;
  border: none;
  background: transparent;
  color: var(--c-text);
}
.modal[open] { display: flex; flex-direction: column; animation: modal-in var(--dur) var(--ease-out); }
.modal::backdrop { background: var(--scrim-modal); }
.modal[open]::backdrop { animation: modal-scrim var(--dur) var(--ease-out); }
@keyframes modal-in { from { opacity: 0; transform: translateY(14px) scale(.98); } }
@keyframes modal-scrim { from { opacity: 0; } }

/* Q5 — le formulaire de course et sa mini-carte. */
.modal--large { --modal-w: 920px; }
/* Q4 — la variante confirmation : peu de texte, pas de zone defilante utile. */
.modal--confirm { --modal-w: 440px; --modal-body-max: 60svh; }

.modal__dialog {
  display: flex;
  flex-direction: column;
  flex: 0 1 auto;
  min-height: 0;
  background: var(--modal-bg);
  border-radius: var(--modal-radius);
  box-shadow: var(--modal-shadow);
  overflow: hidden;
}
/* Le formulaire enjambe le corps ET la barre d'actions : le bouton de
   soumission reste dans le <form>, ce dont setLoading() a besoin. */
.modal__form { display: flex; flex-direction: column; flex: 0 1 auto; min-height: 0; }

.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-4);
  flex: none;
  padding: var(--modal-pad-y) var(--modal-pad);
  border-bottom: var(--bw-hair) solid var(--c-border);
}
.modal__title { font-size: var(--fs-lg); }
.modal__desc { margin-top: var(--sp-1); font-size: var(--fs-sm); color: var(--c-text-muted); }
.modal__close {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--hit-target);
  min-height: var(--hit-target);
  margin: calc(var(--sp-2) * -1) calc(var(--sp-3) * -1) 0 0;
  border-radius: var(--r-circle);
  color: var(--c-text-muted);
  transition: var(--t-color);
}
.modal__close:hover { background: var(--c-bg-alt); color: var(--c-text); }
.modal__close-icon { width: 1.1rem; height: 1.1rem; fill: currentColor; }

/* Q5 — zone fixe, entre l'en-tete et le corps : ce qui s'y trouve ne defile
   jamais. C'est la que vit la mini-carte du formulaire de course ; dans le
   corps, on ferait defiler la popup en croyant zoomer. */
.modal__fixed { flex: none; padding: var(--modal-pad) var(--modal-pad) 0; }
.modal__map {
  height: var(--modal-map-h);
  border: var(--bw-hair) solid var(--c-border);
  border-radius: var(--r-md);
  overflow: hidden;
}
/* Repli quand Leaflet n'a pas pu etre charge : le bloc garde sa place et dit
   quoi faire, plutot que de laisser un rectangle vide. */
.modal__map--vide { display: grid; place-items: center; background: var(--c-bg-alt); }

/* Formulaire de course (components/race-admin.js), ouvert depuis l'espace membres. */
.race-form__group { display: grid; gap: var(--sp-4); }
.race-form__title { font-size: var(--fs-base); font-weight: var(--fw-bold); }
.race-form__row { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: end; }
.race-form__row .field { min-width: 10rem; flex: 1 1 12rem; }

.modal__body {
  flex: 1 1 auto;
  min-height: 0;
  max-height: var(--modal-body-max);
  padding: var(--modal-pad);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.modal__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--sp-3);
  flex: none;
  padding: var(--modal-pad-y) var(--modal-pad);
  border-top: var(--bw-hair) solid var(--c-border);
  background: var(--c-bg-alt);
}
/* Le socle a11y donne deja min-height: var(--hit-target) a tout <button>. */
.modal__foot .btn { flex: var(--modal-action-flex); }
.modal__message { color: var(--c-text-muted); }
.modal__note { margin-top: var(--sp-4); font-size: var(--fs-sm); color: var(--c-text-muted); }
/* Une valeur a recopier a la main (mot de passe provisoire) : lisible de loin,
   selectionnable d'un clic, jamais tronquee. */
.modal__value {
  margin-top: var(--sp-4);
  padding: var(--sp-4) var(--sp-5);
  border: var(--bw) dashed var(--c-border-strong);
  border-radius: var(--r-md);
  background: var(--c-bg-alt);
  font-family: var(--ff-mono);
  font-size: var(--fs-lg);
  font-weight: var(--fw-bold);
  letter-spacing: .06em;
  text-align: center;
  overflow-wrap: anywhere;
  user-select: all;
}

/* Q3 — sous 768 px : feuille pleine largeur ancree en bas, 92dvh au maximum,
   barre d'actions collee en bas et toujours visible (le corps seul defile).
   Pas de second composant : le point de rupture ne fait que reassigner les
   variables locales. La valeur 768 est ecrite en litteral — les custom
   properties ne fonctionnent pas dans @media (miroir : js/config.js). */
@media (max-width: 767px) {
  .modal {
    --modal-w: 100vw;
    --modal-max-w: 100vw;
    --modal-margin: auto auto 0;
    --modal-radius: var(--r-lg) var(--r-lg) 0 0;
    --modal-h-max: 92dvh;
    --modal-body-max: none;
    --modal-map-h: 180px;
    --modal-pad: var(--sp-5);
    /* Doigt sur un telephone : les actions occupent toute la largeur. */
    --modal-action-flex: 1 1 10rem;
  }
}

/* ---- NOTIFICATIONS ----------------------------------------------------- */
.toast-stack { position: fixed; inset-block-end: var(--sp-6); inset-inline-end: var(--sp-6); z-index: var(--z-toast); display: flex; flex-direction: column; gap: var(--sp-3); pointer-events: none; }
.toast {
  --toast-bg: var(--c-ink-900);
  --toast-fg: var(--c-paper);
  padding: var(--sp-4) var(--sp-5);
  border-radius: var(--r-md);
  background: var(--toast-bg);
  color: var(--toast-fg);
  box-shadow: var(--sh-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  max-width: 22rem;
  pointer-events: auto;
  animation: toast-in var(--dur) var(--ease-spring);
}
.toast--success { --toast-bg: var(--c-success); }
.toast--danger { --toast-bg: var(--c-danger); }
@keyframes toast-in { from { opacity: 0; transform: translateY(12px); } }

/* ---- BANDEAU DEFILANT (partenaires) ------------------------------------ */
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee__track { display: flex; gap: var(--sp-12); width: max-content; align-items: center; animation: marquee var(--marquee-dur) linear infinite; }
.marquee:hover .marquee__track, .marquee:focus-within .marquee__track { animation-play-state: paused; }
@keyframes marquee { to { transform: translateX(-50%); } }
@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; overflow-x: auto; scroll-snap-type: x mandatory; }
}

/* ---- REVEAL AU SCROLL ---------------------------------------------------
   L'etat masque est conditionne a html.js : sans ce garde, une erreur
   JavaScript rendrait tout le site invisible. */
html.js [data-reveal-pending] {
  opacity: 0;
  transform: translate3d(var(--reveal-x, 0), var(--reveal-y, 28px), 0) scale(var(--reveal-s, 1));
  transition: opacity var(--dur-reveal) var(--ease-out) calc(var(--reveal-i, 0) * 90ms),
              transform var(--dur-reveal) var(--ease-out) calc(var(--reveal-i, 0) * 90ms);
  will-change: opacity, transform;
}
[data-reveal="left"]  { --reveal-x: -36px; --reveal-y: 0; }
[data-reveal="right"] { --reveal-x: 36px;  --reveal-y: 0; }
[data-reveal="zoom"]  { --reveal-y: 0; --reveal-s: .94; }
/* Sous 768 px le conteneur touche les bords : un bloc deja large comme lui,
   decale de 36 px, deborde de 20 px et rend la page defilable en largeur.
   On retombe donc sur le decalage vertical, qui ne coute aucune largeur. */
@media (max-width: 767px) {
  [data-reveal="left"], [data-reveal="right"] { --reveal-x: 0; --reveal-y: 28px; }
}
[data-reveal].is-revealed { opacity: 1; transform: none; will-change: auto; }

/* ---- UTILITAIRES (une quinzaine, pas un framework) --------------------- */
}

@layer utilities {
  .u-mt-4 { margin-top: var(--sp-4); }
  .u-mt-8 { margin-top: var(--sp-8); }
  .u-mt-12 { margin-top: var(--sp-12); }
  .u-mb-4 { margin-top: 0; margin-bottom: var(--sp-4); }
  .u-mb-6 { margin-top: 0; margin-bottom: var(--sp-6); }
  .u-muted { color: var(--c-text-muted); }
  .u-nowrap { white-space: nowrap; }
}

@layer components {
/* ============================================================================
   REFONTE — composants partages du nouveau design.
   Tous sont additifs : aucune page existante n'est modifiee tant qu'elle
   n'utilise pas ces classes.
   ========================================================================= */

/* ---- HALO FLOU ---------------------------------------------------------
   La signature visuelle du design de reference : un disque de couleur
   fortement floute, pose derriere le contenu. Le parent doit etre positionne. */
.glow {
  position: absolute;
  z-index: -2;
  width: var(--glow-size, 40rem);
  aspect-ratio: 1;
  border-radius: var(--r-circle);
  background: var(--glow-c, var(--c-accent));
  filter: blur(var(--glow-blur, 140px));
  opacity: var(--glow-op, .22);
  pointer-events: none;
  will-change: transform;
}
.glow--drift { animation: glow-drift var(--glow-dur, 16s) var(--ease-in-out) infinite alternate; }
@keyframes glow-drift {
  to { transform: translate3d(var(--glow-dx, 8%), var(--glow-dy, -6%), 0) scale(1.18); }
}
@media (prefers-reduced-motion: reduce) { .glow--drift { animation: none; } }

/* ---- BOUTON A BALAYAGE -------------------------------------------------
   Le disque d'accent part de la gauche et envahit le bouton au survol.
   Le pseudo-element est neutre tant que --btn-sweep n'est pas defini :
   les boutons existants ne bougent pas d'un pixel. */
.btn { position: relative; overflow: hidden; isolation: isolate; }
.btn::before {
  content: '';
  position: absolute;
  z-index: -1;
  top: 50%;
  /* Le disque est cale PAR SON BORD DROIT sur le bord gauche du bouton :
     aucune fraction ne depasse au repos, quelle que soit la largeur. */
  inset-inline-end: 100%;
  margin-inline-end: .5rem;
  width: 130%;
  aspect-ratio: 1;
  translate: 0 -50%;
  border-radius: var(--r-circle);
  background: var(--btn-sweep, transparent);
  transition: transform var(--dur-sweep) var(--ease-sweep);
}
/* 2.8 et non 3.4 : le besoin geometrique reel est de 2,63 pour le bouton le
   plus exigeant de la page (disque de rayon 130 % cale a gauche, il doit
   atteindre le coin oppose). Tout ce qui depasse se joue HORS du bouton :
   l'animation paraissait finie a mi-parcours alors qu'elle tournait encore. */
.btn:hover::before, .btn:focus-visible::before { transform: scale(2.8); }

/* Fleche de tete : a gauche du libelle, fixe, et nettement plus grande.
   `order` et non un deplacement dans le markup : la fleche est decorative
   (aria-hidden), l'ordre du DOM ne change donc rien a ce qui est annonce. */
.btn__lead {
  width: 1.4em; height: 1.4em;
  fill: currentColor;
  flex: none;
  order: -1;
}

/* ---- ETIQUETTE DE SECTION ----------------------------------------------
   L'etiquette qui coiffe un titre de section. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  padding: .5rem 1.15rem;
  border: var(--bw) solid color-mix(in srgb, var(--c-accent) 38%, transparent);
  border-radius: var(--r-pill);
  background: color-mix(in srgb, var(--c-accent) 12%, transparent);
  color: var(--c-accent);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-bold);
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  line-height: 1;
}
.pill--red { --c-accent: var(--c-red-500); }

/* ---- TEXTE QUI ROULE AU SURVOL ----------------------------------------
   Le libelle monte, son double arrive par le bas. Le double est porte par
   data-swap : aucun texte duplique dans le DOM, donc rien de lu deux fois. */
.swap { display: inline-block; overflow: hidden; vertical-align: bottom; }
.swap__in {
  display: block;
  position: relative;
  transition: transform var(--dur-swap) var(--ease-swap);
}
.swap__in::after {
  content: attr(data-swap);
  position: absolute;
  inset-block-start: 100%;
  inset-inline-start: 0;
  color: var(--swap-c, var(--c-accent));
  white-space: nowrap;
}
:where(a, button, .swap):hover > .swap > .swap__in,
:where(a, button):hover .swap__in,
:where(a, button):focus-visible .swap__in { transform: translateY(-100%); }

/* ---- ZOOM D'IMAGE AU SURVOL -------------------------------------------- */
.media-zoom { overflow: hidden; border-radius: var(--r-lg); }
.media-zoom img {
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform var(--dur-slow) var(--ease-out);
}
:hover > .media-zoom img, .media-zoom:hover img { transform: scale(1.12); }

/* ---- ADAPTATIONS DU THEME SOMBRE ---------------------------------------
   Les seuls composants qui codaient une couleur en dur plutot qu'un token. */
.theme-dark .card { --card-shadow: var(--sh-2); }
.theme-dark .card--link:hover { --card-bd: color-mix(in srgb, var(--c-accent) 45%, transparent); }
.theme-dark .alert { color: var(--c-text); }
.theme-dark .chip.is-selected {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-ink-900);
}
.theme-dark .chip:hover { border-color: var(--c-accent); }
/* Le fond exact des boutons du theme sombre : l'or ramene a 16 %, sur le noir de la page. */
.theme-dark .switch {
  --switch-fond: color-mix(in srgb, var(--c-accent) 16%, rgb(11 11 14 / .88));
  --switch-on: var(--c-ink-900);
}
.theme-dark .switch__thumb { box-shadow: var(--sh-gold); }
.theme-dark .skeleton {
  background: linear-gradient(90deg, var(--c-bg-alt) 25%, var(--c-surface-2) 50%, var(--c-bg-alt) 75%);
  background-size: 200% 100%;
}
.theme-dark .badge--natation { --badge-bg: rgb(245 168 0 / .16); --badge-fg: var(--c-gold-300); }
.theme-dark .badge--velo { --badge-bg: rgb(232 50 26 / .18); --badge-fg: var(--c-red-300); }
.theme-dark .badge--cap { --badge-bg: rgb(255 255 255 / .10); --badge-fg: var(--c-paper); }
.theme-dark .checkbox input { accent-color: var(--c-gold-500); }
.theme-dark .social__link:hover { color: var(--c-ink-900); }
.theme-dark .toast { --toast-bg: var(--c-surface-2); }
.theme-dark :focus-visible { outline-color: var(--c-gold-500); }

/* ---- REVEAL : une variante de plus, le voile qui se leve ---------------- */
[data-reveal="rise"] { --reveal-y: 52px; }
[data-reveal="fade"] { --reveal-y: 0; }
}

@layer components {
/* UN SEUL style de bouton sous le theme sombre : pilule sombre a liseré dore,
   dont le disque d'accent envahit le fond au survol pendant que le libelle
   passe au noir. Les modificateurs de couleur (--primary, --gold, --outline,
   --ghost) sont volontairement neutralises ici ; ils continuent de servir sur
   les pages restees en clair, donc aucun markup n'a besoin d'etre reecrit.
   La regle :hover est necessaire : `.btn--primary:hover` redefinit --btn-bg a
   specificite egale, et gagnerait au seul jeu de l'ordre des declarations. */
.theme-dark .btn {
  /* Le fond n'est PAS noir : c'est un brun tres sombre teinte par l'accent —
     l'or ramene a 10 % de luminosite — pose a 90 % d'opacite, exactement comme
     la reference. Sur un noir neutre le bouton parait creux ; teinte, il se
     rattache au liseré qui l'entoure. */
  --btn-fond: color-mix(in srgb, var(--c-accent) 16%, rgb(11 11 14 / .88));
  --btn-bg: var(--btn-fond);
  --btn-bd: var(--c-accent);
  --btn-fg: var(--c-text);
  --btn-fg-hover: var(--c-ink-900);
  --btn-sweep: var(--c-accent);
  --btn-shadow: var(--sh-0);
  /* UNE SEULE taille : hauteur, police et icone identiques partout, quel que
     soit le modificateur. Ces trois variables etant posees ici a specificite
     (0,2,0), elles l'emportent sur .btn--sm et .btn--lg sans les reecrire.
     La hauteur est figee a 3,25 rem : la pilule paraissait epaisse avec un
     grand remplissage, et on garde la cible tactile de 44 px de a11y.css. */
  --btn-h: 3.25rem;
  --btn-pad-x: 2.25rem;
  --btn-fs: var(--fs-md);
  /* Meme interligne que la hauteur d'icone (1,4 em) : sans cela un bouton sans
     icone serait 3 px plus bas que ses voisins, l'icone debordant du texte. */
  line-height: 1.4;
  /* Casse saisie et non capitales, comme les boutons du site de reference.
     L'interlettrage large de .btn est calibre pour des capitales : en casse
     mixte il delie les lettres, on le remet a zero. */
  text-transform: none;
  letter-spacing: 0;
  /* Le libelle doit virer au noir AU RYTHME du remplissage : a la duree de
     --t-color (140 ms) il basculait bien avant que le fond l'ait rejoint.
     La derniere occurrence d'une propriete dans une liste de transition gagne,
     donc ce `color` remplace celui de --t-all. */
  transition: var(--t-all), color var(--dur-sweep) var(--ease-sweep);
}
/* Pas de soulevement au survol : le remplissage suffit, et le decalage de 2 px
   se lisait comme un sursaut. L'enfoncement au clic (:active) reste, lui. */
.theme-dark .btn:hover { --btn-bg: var(--btn-fond); --btn-bd: var(--c-accent); transform: none; }

/* Seule exception : une action destructrice doit rester reconnaissable. */
.theme-dark .btn--danger,
.theme-dark .btn--danger:hover {
  --btn-bd: var(--c-danger);
  --btn-sweep: var(--c-danger);
  --btn-fg-hover: #fff;
}

/* Le libelle qui roule n'est arme que sous le theme sombre, et le focus
   clavier est traite EXACTEMENT comme le survol : sans cela, `:focus-visible`
   ferait rouler un libelle dont le double a ete neutralise, et le lien
   apparaitrait vide. */
.site-nav__link .swap__in { transition: none; }
.site-nav__link:hover .swap__in,
.site-nav__link:focus-visible .swap__in { transform: none; }

.theme-dark .site-nav__link .swap__in { transition: transform var(--dur-swap) var(--ease-swap); }
.theme-dark .site-nav__link:hover .swap__in,
.theme-dark .site-nav__link:focus-visible .swap__in { transform: translateY(-100%); }
}

@layer components {
/* Dans le tiroir mobile les liens sont empiles en gros : le double deborderait
   sur la ligne suivante, on neutralise l'effet sous 1024 px.
   `content: none` et pas seulement `overflow: hidden` : le tiroir a besoin de
   `overflow: visible` pour ne pas rogner les jambages de ses grandes capitales,
   et sans decoupe le double s'afficherait SOUS chaque libelle. */
@media (max-width: 1023.98px) {
  .site-nav__link .swap { overflow: visible; }
  .site-nav__link .swap__in::after { content: none; }
  .theme-dark .site-nav__link:hover .swap__in,
  .theme-dark .site-nav__link:focus-visible .swap__in { transform: none; }
}
}

@layer components {
/* ---- LIGNE DE MOTS-CLES ------------------------------------------------
   Enumeration courte separee par des doubles barres, reprise du design de
   reference. Les separateurs sont decoratifs : aria-hidden dans le markup,
   pour qu'un lecteur d'ecran enonce les termes sans epeler la ponctuation. */
.keywords {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  line-height: 1.4;
}
.keywords__sep { color: var(--c-accent); font-weight: var(--fw-black); }
}

@layer components {
/* ============================================================================
   REFONTE — BLOCS DE PAGE MUTUALISES
   Tout ce que l'accueil a invente et que les autres pages reutilisent tel quel.
   Ces blocs vivent ICI et non dans pages/home.css : components.css est charge
   par head.html, donc par TOUTES les pages, sans requete supplementaire.
   ========================================================================= */

/* ---- EN-TETE DE PAGE INTERIEURE ---------------------------------------- */
/* Meme grammaire que le hero d'accueil, en deux fois plus court. */
.page-hero {
  position: relative;
  display: grid;
  align-items: center;
  min-height: min(56svh, 460px);
  isolation: isolate;
  overflow: clip;
  padding-bottom: var(--sp-16);
}
/* L'image de fond est OPTIONNELLE : sans --page-hero-image, les halos suffisent a habiller le noir. */
.page-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -3;
  background: var(--c-bg) var(--page-hero-image, none) center 42% / cover no-repeat;
  opacity: var(--page-hero-op, .20);
  filter: grayscale(.4) contrast(1.1);
}
.page-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(85% 80% at 30% 50%, rgb(11 11 14 / .3) 0%, rgb(11 11 14 / .68) 60%, var(--c-bg) 100%),
    linear-gradient(180deg, rgb(11 11 14 / .85) 0%, rgb(11 11 14 / .45) 45%, var(--c-bg) 100%);
}
/* Durees premieres entre elles (23 s / 31 s) : les deux halos ne repassent jamais ensemble par leur point de depart. */
.page-hero .glow--a {
  top: -24rem; right: -10rem;
  --glow-size: 40rem; --glow-op: .24; --glow-blur: 150px;
  --glow-dx: -8%; --glow-dy: 10%; --glow-dur: 23s;
}
.page-hero .glow--b {
  bottom: -20rem; left: -12rem;
  --glow-c: var(--c-red-500); --glow-size: 30rem; --glow-op: .22;
  --glow-dx: 18%; --glow-dy: -12%; --glow-dur: 31s;
}

.page-hero__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(1.25rem, 1rem + 1vw, 2rem);
}
.page-hero--center .page-hero__content { align-items: center; text-align: center; max-width: 52rem; }
.page-hero--center .page-hero__lead { margin-inline: auto; }

/* Capitale initiale seulement : les h1-h3 du socle sont en capitales, on annule ici comme sur l'accueil. */
.page-hero__title {
  font-family: var(--ff-display);
  font-size: var(--fs-3xl);
  line-height: .95;
  letter-spacing: var(--ls-tightest);
  text-transform: none;
  color: var(--c-text);
}
.page-hero__lead { max-width: 46rem; font-size: var(--fs-md); color: var(--c-text-muted); }
.page-hero__actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-4); }

/* ---- DEGRADE DE MARQUE SUR UN GROUPE DE MOTS --------------------------- */
/* `nowrap` indispensable : background-clip s'applique fragment par fragment, un groupe coupe rejouerait le degrade sur chaque ligne. */
.grad-accent {
  white-space: nowrap;
  /* --g-brand et non un degrade en dur : le sous-site du trail le reassigne a
     ses propres couleurs, et les titres suivent sans une ligne de plus. */
  background: var(--g-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ---- ENTREE EN CASCADE D'UN EN-TETE ------------------------------------ */
/* Conditionnee a html.js comme le reveal au defilement : sans JavaScript, rien n'est masque. */
html.js .hero__content > *,
html.js .page-hero__content > * {
  animation: intro-rise var(--dur-reveal) var(--ease-out) backwards;
  animation-delay: calc(var(--i, 0) * 110ms + 120ms);
}
.hero__content > :nth-child(2), .page-hero__content > :nth-child(2) { --i: 1; }
.hero__content > :nth-child(3), .page-hero__content > :nth-child(3) { --i: 2; }
.hero__content > :nth-child(4), .page-hero__content > :nth-child(4) { --i: 3; }
.hero__content > :nth-child(5), .page-hero__content > :nth-child(5) { --i: 4; }
.hero__content > :nth-child(6), .page-hero__content > :nth-child(6) { --i: 5; }
@keyframes intro-rise { from { opacity: 0; transform: translate3d(0, 26px, 0); } }
@media (prefers-reduced-motion: reduce) {
  html.js .hero__content > *,
  html.js .page-hero__content > * { animation: none; }
}

/* ---- ETIQUETTE DE SECTION, GRAND FORMAT -------------------------------- */
/* Calque sur l'etiquette du site de reference : fond dore dense, casse saisie, remplissage genereux. */
.pill--lg {
  text-transform: none;
  letter-spacing: .01em;
  font-size: var(--fs-base);
  font-weight: var(--fw-medium);
  padding: .75rem 2rem;
  background: color-mix(in srgb, var(--c-accent) 26%, transparent);
  border-color: color-mix(in srgb, var(--c-accent) 40%, transparent);
}

/* ---- EN-TETE DE SECTION, VARIANTE CENTREE ------------------------------ */
.section__head--center { text-align: center; margin-inline: auto; max-width: 46rem; }
.section__head .pill { margin-bottom: var(--sp-5); }
.section__head--center .section__lead { margin-inline: auto; }

/* ---- BANDE DE CHIFFRES ------------------------------------------------- */
/* `isolation: isolate` est obligatoire partout ou vit un .glow : sinon son z-index negatif remonte jusqu'a la racine. */
.stats-band { position: relative; isolation: isolate; overflow: clip; }
/* Ellipse plutot que disque : un disque de 46 rem dans une bande de 250 px se fait trancher net en haut et en bas. */
.stats-band .glow {
  top: 50%; left: 50%; translate: -50% -50%;
  --glow-size: 62rem; --glow-op: .16; --glow-blur: 110px;
  height: 12rem; aspect-ratio: auto;
}
.stats { display: grid; gap: var(--sp-6); text-align: center; }
@media (min-width: 480px) { .stats { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat {
  padding: var(--sp-6) var(--sp-4);
  border: var(--bw-hair) solid var(--c-border);
  border-radius: var(--r-xl);
  background: color-mix(in srgb, var(--c-surface) 70%, transparent);
  backdrop-filter: blur(6px);
  transition: var(--t-all);
}
.stat:hover { border-color: color-mix(in srgb, var(--c-accent) 45%, transparent); transform: translateY(-4px); }
.stat__value {
  font-family: var(--ff-display);
  font-size: var(--fs-2xl);
  line-height: 1;
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.stat__label {
  margin-top: var(--sp-3);
  font-size: var(--fs-xs);
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--c-text-muted);
}

/* ---- INTRO COLLANTE + GRILLE D'ARGUMENTS ------------------------------- */
.why { display: grid; gap: var(--sp-12); align-items: start; }
@media (min-width: 1024px) { .why { grid-template-columns: 1fr 1.15fr; gap: var(--sp-16); } }
.why__intro { display: flex; flex-direction: column; align-items: flex-start; gap: var(--sp-5); }
@media (min-width: 1024px) { .why__intro { position: sticky; top: calc(var(--header-h-lg) + var(--sp-8)); } }
.why__grid { display: grid; gap: var(--sp-8); }
@media (min-width: 640px) { .why__grid { grid-template-columns: repeat(2, 1fr); } }

/* Le chevron du logo sert de puce, comme partout ailleurs sur le site. */
.why-item { position: relative; padding-left: var(--sp-6); }
.why-item::before {
  content: '';
  position: absolute;
  left: 0;
  top: .35em;
  width: 10px;
  height: 20px;
  border-radius: 2px;
  background: var(--c-accent);
  transform: skewX(var(--chevron-skew));
}
.why-item__title { font-family: var(--ff-body); font-size: var(--fs-md); font-weight: var(--fw-bold); color: var(--c-accent); }
.why-item__text { margin-top: var(--sp-2); color: var(--c-text-muted); font-size: var(--fs-sm); }

/* ---- BANDE MISE EN AVANT (pleine largeur du navigateur) ---------------- */
.feature {
  position: relative;
  border-block: var(--bw-hair) solid var(--c-border);
  background: var(--c-surface);
  overflow: hidden;
  isolation: isolate;
}
/* Porte aussi .container : le texte reste aligne sur le reste de la page. */
.feature__body {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-5);
  padding-block: var(--sp-12);
}
@media (min-width: 900px) { .feature__body { padding-block: var(--sp-16); } }
.feature .glow { bottom: -14rem; right: -6rem; --glow-c: var(--c-red-500); --glow-size: 34rem; --glow-op: .22; }
.feature__title { font-size: var(--fs-2xl); }
.feature__text { color: var(--c-text-muted); }
.feature__meta { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* ---- APPEL FINAL ------------------------------------------------------- */
.cta-final {
  position: relative;
  isolation: isolate;
  overflow: clip;
  padding: clamp(2.5rem, 6vw, 5.5rem) var(--sp-6);
  border: var(--bw-hair) solid var(--c-border);
  border-radius: var(--r-2xl);
  background: var(--c-bg-alt);
  text-align: center;
}
.cta-final .glow { top: 50%; left: 50%; translate: -50% -50%; --glow-size: 38rem; --glow-op: .20; }
.cta-final__title { font-size: var(--fs-3xl); }
.cta-final__text { margin: var(--sp-5) auto 0; max-width: 48ch; color: var(--c-text-muted); font-size: var(--fs-md); }
.cta-final__actions { display: flex; flex-wrap: wrap; gap: var(--sp-4); justify-content: center; margin-top: var(--sp-8); }

/* ---- CARTE DISCIPLINE -------------------------------------------------- */
.disc-grid { display: grid; gap: var(--sp-gap); }
@media (min-width: 768px) { .disc-grid { grid-template-columns: repeat(3, 1fr); } }
.disc-card {
  --disc-c: var(--c-accent);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sp-4);
  padding: var(--sp-5);
  border: var(--bw-hair) solid var(--c-border);
  border-radius: var(--r-2xl);
  background: var(--c-surface);
  overflow: hidden;
  transition: var(--t-all);
}
/* Lisere de discipline, revele au survol. */
.disc-card::before {
  content: '';
  position: absolute;
  inset: 0 0 auto 0;
  height: var(--bw-thick);
  background: var(--disc-c);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--dur-slow) var(--ease-out);
}
.disc-card:hover {
  transform: translateY(-6px);
  border-color: color-mix(in srgb, var(--disc-c) 45%, transparent);
  box-shadow: var(--sh-3);
}
.disc-card:hover::before { transform: scaleX(1); }
.disc-card--swim { --disc-c: var(--c-gold-500); }
.disc-card--bike { --disc-c: var(--c-red-500); }
.disc-card--run  { --disc-c: var(--c-paper); }
.disc-card__media { position: relative; width: 100%; aspect-ratio: 4 / 3; border-radius: var(--r-lg); background: var(--c-bg-alt); }
/* Pastille de discipline posee sur la photo. */
.disc-card__tag { position: absolute; left: var(--sp-3); bottom: var(--sp-3); z-index: 1; box-shadow: var(--sh-2); }
.disc-card__title { font-size: var(--fs-lg); }
.disc-card__text { color: var(--c-text-muted); font-size: var(--fs-sm); }
.disc-card__facts { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin-top: auto; }
.disc-card__cta { margin-top: auto; }

/* ---- LIEN CENTRE SOUS UNE GRILLE --------------------------------------- */
.section__more { display: flex; justify-content: center; margin-top: var(--sp-10); }

/* ---- PANNEAU DE CONTENU ------------------------------------------------ */
/* Le support des textes longs, tableaux et notes : meme rayon et meme liseré que les cartes. */
.panel {
  padding: var(--sp-6);
  border: var(--bw-hair) solid var(--c-border);
  border-radius: var(--r-2xl);
  background: var(--c-surface);
}
@media (min-width: 768px) { .panel { padding: var(--sp-10); } }
.panel--alt { background: var(--c-bg-alt); }
}

@layer components {
/* ============================================================================
   REFONTE — HARMONISATION DU THEME SOMBRE
   Tout le site porte desormais .theme-dark : les composants du socle doivent
   adopter le meme rayon, le meme liseré et le meme or que les blocs de la
   refonte, sinon deux grammaires visuelles cohabitent sur la meme page.
   ========================================================================= */

/* Meme rayon que les cartes de la refonte (.disc-card, .feature, .panel). */
.theme-dark .card { --card-radius: var(--r-2xl); }
.theme-dark .card--link:hover { transform: translateY(-6px); }

/* Le focus posait un liseré #0D0D0D : invisible sur un fond quasi noir. */
.theme-dark .input:hover,
.theme-dark .select:hover,
.theme-dark .textarea:hover { --input-bd: var(--c-border-strong); }
.theme-dark .input:focus,
.theme-dark .select:focus,
.theme-dark .textarea:focus { --input-bd: var(--c-accent); }
.theme-dark .input, .theme-dark .select, .theme-dark .textarea { border-radius: var(--r-md); background: var(--c-surface); }
.theme-dark .input::placeholder, .theme-dark .textarea::placeholder { color: var(--c-text-muted); }

.theme-dark .empty { border-radius: var(--r-2xl); border-color: var(--c-border-strong); }
.theme-dark .table__wrap { border-radius: var(--r-lg); }
.theme-dark .table th { background: var(--c-surface-2); }
.theme-dark .table tbody tr:hover { background: var(--c-surface-2); }
/* Boutons d'action dans une cellule : format compact, sinon ils doublent la hauteur de la ligne. */
.theme-dark .table .btn { --btn-h: 2.25rem; --btn-pad-x: .9rem; --btn-fs: var(--fs-sm); }

/* Le chevron decoratif du pied de page et des separateurs : le noir disparait sur fond noir. */
.theme-dark .chevrons .chevron:nth-child(3) { --chevron-c: var(--c-paper); }
}
