/* ---------------------------------------------------------------------------
   Ajouts V2 : pages résultats et fiche candidat.

   lauriers.css est la copie conforme du site d'origine et n'est pas touchée.
   Tout ce qui est nouveau vit ici, avec les mêmes variables de couleur, pour
   que les deux feuilles restent distinguables.
   --------------------------------------------------------------------------- */

/* --- Menu principal ------------------------------------------------------- */

/* L'en-tête d'origine était un logo et un titre. Il porte maintenant un menu,
   sans changer de hauteur : la page-container compense toujours 88 px de
   barre fixe, et y toucher décalerait toutes les pages. */
.site-header {
  gap: 0.75rem;
}

.site-brand {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  min-width: 0;
}

.site-header .site-header-logo {
  width: 46px;
  height: 46px;
  flex: 0 0 auto;
}

.site-header .site-title {
  margin: 0;
  font-size: 1.15rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--text-main);
  white-space: nowrap;
}

.site-nav ul {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 0.25rem;
  margin: 0;
  padding: 0;
}

.site-nav a {
  display: block;
  padding: 0.45rem 0.75rem;
  border-radius: 999px;
  font-size: 0.92rem;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.site-nav a:hover {
  background-color: var(--ldt-primary-softer);
  color: var(--primary);
}

/* La page en cours se voit, et s'annonce : aria-current est le sélecteur,
   pas une classe — impossible d'avoir l'un sans l'autre. */
.site-nav a[aria-current="page"] {
  /* L'accent du style, ou son primaire s'il n'en définit pas. */
  background-color: var(--ldt-accent, var(--primary));
  color: var(--ldt-on-accent, var(--ldt-on-primary));
  font-weight: 500;
}

.site-nav a:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.site-burger {
  display: none;
  margin-left: auto;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--border-soft);
  border-radius: 0.6rem;
  background-color: var(--ldt-surface);
  cursor: pointer;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
}

.site-burger-bar {
  display: block;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background-color: var(--text-main);
  transition: transform 0.2s ease, opacity 0.15s ease;
}

.site-header.is-menu-open .site-burger-bar:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.site-header.is-menu-open .site-burger-bar:nth-child(2) {
  opacity: 0;
}

.site-header.is-menu-open .site-burger-bar:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

@media (min-width: 700px) {
  .site-nav {
    margin-left: auto;
  }
}

/* Sous 700 px, le menu passe derrière le bouton et s'ouvre en panneau sous la
   barre — il ne pousse pas le contenu, la barre étant fixe. */
@media (max-width: 699px) {
  .site-burger {
    display: flex;
  }

  .site-nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background-color: var(--ldt-surface);
    border-bottom: 1px solid var(--border-soft);
    box-shadow: 0 10px 20px rgba(var(--ldt-shadow-rgb), 0.12);
    padding: 0.4rem 0.75rem 0.75rem;
    display: none;
  }

  .site-header.is-menu-open .site-nav {
    display: block;
  }

  .site-nav ul {
    flex-direction: column;
    align-items: stretch;
    gap: 0.15rem;
  }

  .site-nav a {
    padding: 0.7rem 0.85rem;
    border-radius: 0.6rem;
    font-size: 1rem;
  }

  .site-header .site-title {
    font-size: 1rem;
  }
}

/* Très petits écrans : le titre céderait la place au bouton, on le raccourcit
   plutôt que de le laisser déborder. */
@media (max-width: 400px) {
  .site-header .site-title {
    font-size: 0.9rem;
    white-space: normal;
    line-height: 1.15;
  }
}

/* --- Liens ajoutés dans le rendu d'origine -------------------------------- */

/* Le nom d'un candidat mène à sa fiche, sans que la carte change d'aspect. */
.runner-name-link,
.runner-name-link:hover {
  color: inherit;
  text-decoration: none;
}

.runner-card:hover .runner-name-link {
  color: var(--primary);
}

.edition-results-link {
  text-align: center;
  font-size: 0.9rem;
  margin: 0 0 1rem;
}

/* --- Page résultats ------------------------------------------------------ */

.results-section {
  margin-top: 1.75rem;
}

.results-table {
  width: 100%;
  border-collapse: collapse;
  background-color: var(--ldt-surface);
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 0 10px rgba(var(--ldt-shadow-rgb), 0.11);
  font-size: 0.95rem;
}

.results-table thead th {
  background-color: var(--ldt-primary-soft);
  color: var(--text-muted);
  font-weight: 500;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.55rem 0.6rem;
  text-align: left;
}

.results-table td {
  padding: 0.6rem;
  border-top: 1px solid var(--ldt-border);
  vertical-align: middle;
}

.results-table tbody tr.is-laureate {
  background-color: var(--ldt-primary-softer);
}

.results-table .col-rank {
  width: 3.2rem;
  text-align: center;
  font-size: 1.1rem;
  white-space: nowrap;
}

/* La colonne ne contient que le portrait : pas de marge a droite, il doit
   toucher le bloc nom/pays plutot que flotter entre deux vides. */
.results-table .col-photo {
  width: 3.6rem;
  padding-right: 0;
}

.results-photo {
  display: block;
  width: 44px;
  height: 44px;
  /* aspect-ratio en plus de la hauteur : si une cellule etroite venait a
     comprimer la largeur, le cadre resterait carre au lieu de s ovaliser. */
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  /* La photo remplit le carre et deborde plutot que de se deformer : on
     coupe ce qui depasse. */
  object-fit: cover;
  /* Un peu au-dessus du centre : sur un portrait vertical, un cadrage
     centre rogne le haut du crane. Sans effet sur une photo panoramique,
     dont toute la hauteur est deja utilisee. */
  object-position: center 30%;
  border: 1px solid var(--ldt-border);
  /* Sert aussi de pastille grise quand le candidat n a pas de portrait. */
  background-color: var(--ldt-surface-3);
}

.results-table .col-name a {
  font-weight: 500;
  color: var(--text-main);
}

.results-table .col-name a:hover {
  color: var(--primary);
}

.results-country {
  display: block;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.results-table .col-score {
  width: 5rem;
  text-align: right;
  font-weight: 600;
  color: var(--primary);
  font-size: 1.15rem;
  white-space: nowrap;
}

.results-table .col-detail {
  width: 5rem;
  text-align: right;
  color: var(--text-muted);
  white-space: nowrap;
}

.results-outof {
  font-size: 0.7rem;
  color: var(--text-muted);
  font-weight: 400;
}

.results-table abbr {
  border: 0;
  text-decoration: none;
  color: var(--text-muted);
  font-size: 0.8rem;
}

.results-note {
  margin: 0.6rem 0.2rem 0;
  font-size: 0.85rem;
  line-height: 1.5;
  color: var(--text-muted);
}

/* Sous 420 px, le détail par collège passe à la trappe : le score sur 100
   reste l'information qui compte. */
@media (max-width: 420px) {
  .results-table .col-detail {
    display: none;
  }

  .results-table .col-photo {
    width: 2.9rem;
  }

  .results-photo {
    width: 36px;
    height: 36px;
  }
}

/* --- Vote : bandeau d'annonce -------------------------------------------- */

.vote-notice {
  background-color: var(--ldt-surface);
  border: 1px solid var(--primary);
  border-radius: 1rem;
  padding: 1rem 1.25rem;
  margin-bottom: 1.25rem;
  font-size: 0.9rem;
  line-height: 1.55;
}

.vote-notice p {
  margin-bottom: 0.5rem;
}

.vote-notice p:last-child {
  margin-bottom: 0;
}

.vote-notice-title {
  font-size: 1.25rem;
  font-weight: 500;
  color: var(--primary);
}

.vote-notice-signup {
  background-color: var(--ldt-primary-softer);
  border-radius: 0.6rem;
  padding: 0.6rem 0.8rem;
}

/* Vote clos : le ton passe au neutre, il n'y a plus rien à faire. */
.vote-notice.is-closed {
  border-color: var(--border-soft);
}

.vote-notice.is-closed .vote-notice-title {
  color: var(--text-main);
}

/* --- Vote : récapitulatif du podium --------------------------------------- */

.vote-ballot {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 0.85rem 1rem;
  margin-bottom: 1rem;
}

.vote-ballot-title {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  margin-bottom: 0.5rem;
}

.vote-ballot-list {
  list-style: none;
  padding: 0;
  margin: 0 0 0.75rem;
}

.vote-ballot-list li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.28rem 0;
  font-size: 0.95rem;
  color: var(--text-muted);
  border-bottom: 1px solid var(--ldt-border);
}

.vote-ballot-list li:last-child {
  border-bottom: 0;
}

.vote-ballot-list li.is-filled {
  color: var(--text-main);
  font-weight: 500;
}

.vote-ballot-medal {
  font-size: 1.1rem;
  line-height: 1;
}

.vote-ballot-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-items: center;
  margin: 0;
}

.vote-ballot-profil {
  font-size: 0.85rem;
}

/* Consigne permanente au-dessus des onglets : aucune catégorie n'est ouverte
   au chargement, et une fois l'une choisie elle rappelle qu'il y en a d'autres. */
/* La consigne est la seule chose à faire sur cette page tant qu'aucune
   catégorie n'est ouverte : elle doit se voir, d'où le rouge et le corps
   plus gros. */
.tabs-hint {
  text-align: center;
  font-size: 1.15rem;
  font-weight: 500;
  line-height: 1.45;
  color: var(--ldt-danger);
  background-color: var(--ldt-danger-soft);
  border-bottom: 2px solid var(--ldt-danger-border);
  margin: 0;
  padding: 0.9rem 1rem;
}

/* La flèche pointe les onglets et clignote pour attirer l'œil : sans elle,
   « ci-dessus » se lit sans qu'on lève les yeux. */
.tabs-hint-arrow {
  display: inline-block;
  font-size: 1.9rem;
  font-weight: 700;
  line-height: 0.8;
  vertical-align: -0.15em;
  margin: 0 0.15rem;
  color: var(--ldt-danger);
  animation: tabs-hint-blink 1.4s ease-in-out infinite;
}

@keyframes tabs-hint-blink {
  0%, 100% { opacity: 1; transform: translateY(0); }
  50%      { opacity: 0.2; transform: translateY(-6px); }
}

/* Un clignotement permanent est pénible pour qui y est sensible. */
@media (prefers-reduced-motion: reduce) {
  .tabs-hint-arrow {
    animation: none;
  }
}

/* Indicateur d'état du podium. Ce n'est pas un bouton : il n'y a rien à
   déclencher à cet endroit, et un bouton désactivé aurait laissé croire à une
   action refusée. */
.vote-status {
  display: inline-block;
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.35rem 0.8rem;
  border-radius: 999px;
  background-color: var(--ldt-surface-2);
  color: var(--text-muted);
}

.vote-status.is-ready {
  background-color: var(--ldt-success-soft);
  color: var(--ldt-success);
}

.vote-status.is-partial {
  background-color: var(--ldt-warning-soft);
  color: var(--ldt-warning);
}

.vote-reset {
  background: none;
  border: 0;
  color: var(--text-muted);
  font-size: 0.82rem;
  text-decoration: underline;
  padding: 0 0.3rem;
}

/* --- Vote : boutons sur la carte ------------------------------------------ */

.vote-pick {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.8rem;
  padding-top: 0.8rem;
  border-top: 1px solid var(--ldt-border);
}

/* De vrais boutons : relief léger, coins francs, et surtout la couleur de la
   médaille quand ils sont actifs — le bleu uniforme ne disait pas lequel des
   trois rangs on venait de choisir. */
.vote-pick-btn {
  flex: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  background: linear-gradient(var(--ldt-surface), var(--ldt-surface-2));
  border: 1px solid var(--border-soft);
  border-radius: 999px;
  padding: 0.5rem 0.4rem;
  font-family: inherit;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--text-muted);
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(var(--ldt-shadow-rgb), 0.07);
  transition: transform 0.12s ease, box-shadow 0.12s ease,
              background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.vote-pick-btn span[aria-hidden] {
  font-size: 1rem;
  line-height: 1;
  filter: grayscale(0.55);
  transition: filter 0.15s ease;
}

.vote-pick-btn:hover {
  border-color: var(--ldt-border-strong);
  color: var(--text-main);
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(var(--ldt-shadow-rgb), 0.12);
}

.vote-pick-btn:active {
  transform: translateY(0);
  box-shadow: 0 1px 2px rgba(var(--ldt-shadow-rgb), 0.1);
}

.vote-pick-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.vote-pick-btn.is-active span[aria-hidden] {
  filter: none;
}

.vote-pick-btn.is-active {
  color: var(--ldt-on-primary);
  box-shadow: 0 2px 8px rgba(var(--ldt-shadow-rgb), 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

.vote-pick-btn[data-rank="1"].is-active {
  background: linear-gradient(#f7d154, #e3a90c);
  border-color: #c99209;
  color: #46340a;
}

.vote-pick-btn[data-rank="2"].is-active {
  background: linear-gradient(#eef2f6, #c2cad6);
  border-color: #a4aebd;
  color: #384252;
}

.vote-pick-btn[data-rank="3"].is-active {
  background: linear-gradient(#e2ab7f, #bf7840);
  border-color: #a36435;
  color: #3d2410;
}

/* --- Vote : mise en avant et réordonnancement ----------------------------- */

.runner-card {
  position: relative;
}

/* Cocher une médaille déplace la carte, pas la page. Sans ceci, le
   navigateur prend la carte cliquée pour repère et fait défiler la page pour
   la suivre jusqu'en tête de liste. */
.runner-list {
  overflow-anchor: none;
}

/* Une carte retenue se repère sans avoir à relire les boutons. */
.runner-card.is-chosen {
  box-shadow: 0 0 0 2px var(--primary), 0 0 14px rgba(var(--ldt-primary-rgb), 0.18);
}

/* Pastille du rang, dans l'angle de la carte remontée en tête de liste. */
.vote-rank-badge {
  position: absolute;
  top: -10px;
  left: -8px;
  width: 60px;
  height: 60px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2rem;
  background-color: var(--ldt-surface);
  box-shadow: 0 2px 6px rgba(var(--ldt-shadow-rgb), 0.25);
  z-index: 3;
  transform: scale(0.4);
  opacity: 0;
  transition: transform 0.22s cubic-bezier(0.2, 1.4, 0.4, 1), opacity 0.18s ease;
}

.runner-card.is-chosen .vote-rank-badge {
  transform: scale(1);
  opacity: 1;
}

/* La carte qui vient de changer de place s'annonce brièvement. */
.runner-card.is-moving {
  z-index: 2;
}

@keyframes vote-card-settle {
  0%   { box-shadow: 0 0 0 2px var(--primary), 0 0 26px rgba(var(--ldt-primary-rgb), 0.45); }
  100% { box-shadow: 0 0 0 2px var(--primary), 0 0 14px rgba(var(--ldt-primary-rgb), 0.18); }
}

.runner-card.is-settling {
  animation: vote-card-settle 0.55s ease-out;
}

/* Qui a désactivé les animations ne doit pas subir le déplacement. */
@media (prefers-reduced-motion: reduce) {
  .vote-pick-btn,
  .vote-rank-badge {
    transition: none;
  }

  .runner-card.is-settling {
    animation: none;
  }
}

/* --- Page d'accueil ------------------------------------------------------ */

/* Le logo de l'accueil (.brand-home) est dimensionné par le style actif :
   public/styles/<nom>/style.css. */

.home-upcoming {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 1.25rem;
  text-align: center;
  margin-bottom: 1.75rem;
}

/* Une édition ouverte se démarque : c'est l'action du moment. */
.home-upcoming.is-open {
  border-color: var(--primary);
  background-color: var(--ldt-primary-softer);
}

/* L'année est le titre du bloc, pas une étiquette : elle se lit comme un
   titre de niveau un. */
.home-upcoming-label {
  font-size: 2rem;
  font-weight: 300;
  letter-spacing: 0.02em;
  line-height: 1.1;
  color: var(--text-main);
  margin-bottom: 0.35rem;
}

@media (max-width: 480px) {
  .home-upcoming-label {
    font-size: 1.6rem;
  }
}

.home-upcoming-title {
  font-size: 1.6rem;
  font-weight: 300;
  color: var(--primary);
  margin-bottom: 0.4rem;
}

.home-upcoming-text {
  font-size: 0.92rem;
  color: var(--text-main);
  margin-bottom: 0.9rem;
}

.home-upcoming-secondary {
  font-size: 0.85rem;
  margin: 0.3rem 0 0;
}

.home-past-link {
  text-align: center;
  font-size: 1rem;
  margin: 1.5rem 0 0.5rem;
}

/* --- Page des éditions ---------------------------------------------------- */

.edition-entry {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 0.9rem 1rem 1rem;
  margin-bottom: 0.9rem;
}

.edition-entry-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin-bottom: 0.7rem;
}

.edition-entry-year {
  font-size: 1.5rem;
  font-weight: 500;
  color: var(--primary);
  margin: 0;
}

.edition-entry-links {
  margin: 0 0 0 auto;
  font-size: 0.85rem;
}

.edition-entry-links a {
  margin-left: 0.9rem;
}

.home-edition {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 0.9rem 1rem 1rem;
  margin-bottom: 0.9rem;
}

.home-edition-head {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.home-edition-year {
  font-size: 1.4rem;
  font-weight: 500;
  color: var(--primary);
  margin: 0;
}

.home-edition-links {
  margin: 0 0 0 auto;
  font-size: 0.85rem;
}

.home-edition-links a {
  margin-left: 0.9rem;
}

.home-laureates {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.6rem;
}

.home-laureates a {
  display: block;
  text-align: center;
  color: var(--text-main);
}

.home-laureates img,
.home-laureate-empty {
  display: block;
  width: 62px;
  height: 62px;
  border-radius: 50%;
  object-fit: cover;
  margin: 0 auto 0.35rem;
  background-color: var(--ldt-surface-3);
}

.home-laureate-name {
  display: block;
  font-size: 0.78rem;
  font-weight: 500;
  line-height: 1.25;
}

.home-laureate-cat {
  display: block;
  font-size: 0.7rem;
  color: var(--text-muted);
  line-height: 1.2;
}

@media (max-width: 480px) {
  .home-laureates {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.9rem 0.6rem;
  }
}

/* --- Espace personnel ----------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.profil-signup {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 1rem 1.25rem 1.25rem;
  margin-bottom: 1.25rem;
}

/* Le cadre passe au rouge tant qu'aucun compte n'existe : c'est l'information
   qui décide si le vote comptera ou non. */
.profil-signup.is-unregistered {
  border-color: var(--ldt-danger-border);
  border-width: 2px;
}

.profil-alert {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  background-color: var(--ldt-danger-soft);
  border-radius: 0.7rem;
  padding: 0.75rem 0.9rem;
  margin-bottom: 1rem;
  color: var(--ldt-danger-strong);
  font-size: 0.95rem;
  line-height: 1.45;
}

.profil-alert-icon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--ldt-danger);
  color: var(--ldt-on-primary);
  font-weight: 700;
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.profil-alert b {
  display: block;
  font-size: 1.05rem;
  color: var(--ldt-danger);
}

.profil-alert-detail {
  display: block;
  font-size: 0.85rem;
  color: var(--ldt-danger);
  margin-top: 0.15rem;
}

.profil-signup-title {
  font-size: 1.2rem;
  font-weight: 500;
  color: var(--primary);
  margin-bottom: 0.4rem;
}

.profil-signup-intro {
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--text-main);
  margin-bottom: 0.9rem;
}

.profil-field {
  margin-bottom: 0.7rem;
}

.profil-field label {
  display: block;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  margin-bottom: 0.2rem;
}

.profil-field input {
  width: 100%;
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.5rem 0.7rem;
  border: 1px solid var(--border-soft);
  border-radius: 0.55rem;
  background-color: var(--ldt-surface);
  color: var(--text-main);
}

.profil-field input:disabled {
  background-color: var(--ldt-surface-2);
  color: var(--text-muted);
  cursor: not-allowed;
}

.profil-form-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.75rem;
  margin: 0.4rem 0 0;
}

.profil-soon {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.profil-summary {
  text-align: center;
  font-size: 0.95rem;
  margin: 0 0 1rem;
  color: var(--text-muted);
}

.profil-summary.is-ready {
  color: var(--primary-dark);
  font-weight: 500;
}

.profil-category {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 0.9rem 1rem 1rem;
  margin-bottom: 0.9rem;
}

.profil-category-head {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}

.profil-category-title {
  font-size: 1.1rem;
  font-weight: 500;
  color: var(--primary);
  margin: 0;
}

.profil-state {
  margin-left: auto;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.2rem 0.6rem;
  border-radius: 999px;
  background-color: var(--ldt-surface-2);
  color: var(--text-muted);
}

.profil-state.is-ready {
  background-color: var(--ldt-success-soft);
  color: var(--ldt-success);
}

.profil-state.is-partial {
  background-color: var(--ldt-warning-soft);
  color: var(--ldt-warning);
}

/* Une categorie vide est ce qui empeche le podium de compter : elle passe au
   rouge, comme le reste de ce qui manque sur cette page. */
.profil-state.is-empty {
  background-color: var(--ldt-danger-soft);
  color: var(--ldt-danger);
}

.profil-podium {
  list-style: none;
  padding: 0;
  margin: 0 0 0.6rem;
}

.profil-podium li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--ldt-border);
}

.profil-podium li:last-child {
  border-bottom: 0;
}

.profil-medal {
  font-size: 1.15rem;
  line-height: 1;
  flex: 0 0 auto;
}

/* Le portrait, puis le nom avec le pays dessous : meme composition que la
   colonne Candidat de /YYYY/resultats/. */
.profil-photo {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  border: 1px solid var(--ldt-border);
  /* Sert de pastille grise quand la ligne est vide ou la photo absente. */
  background-color: var(--ldt-surface-3);
  background-size: cover;
  /* Un peu au-dessus du centre, comme sur les resultats : un cadrage
     centre rogne le haut du crane sur un portrait vertical. */
  background-position: center 30%;
}

/* Une place que le votant n'a pas encore attribuée : une silhouette marquée
   d'un « ? ». Réservée aux places vides — un candidat choisi mais sans photo
   garde la pastille neutre, sans quoi on le croirait non choisi. Le portrait
   d'un candidat, posé en style en ligne, l'emporte de toute façon. */
.profil-podium li:not(.is-filled) .profil-photo {
  background-image: url("/img/podium-a-designer.svg");
  background-position: center;
}

.profil-identity {
  flex: 1 1 auto;
  min-width: 0;
}

.profil-name {
  display: block;
  color: var(--text-muted);
}

.profil-country {
  display: block;
  font-size: 0.78rem;
  color: var(--text-muted);
}

.profil-podium li.is-filled .profil-name {
  color: var(--text-main);
  font-weight: 500;
}

.profil-category-actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0;
  font-size: 0.85rem;
}

/* --- Page athlète : identité et saisons ---------------------------------- */

.athlete-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  background-color: var(--ldt-surface);
  border-radius: 1rem;
  box-shadow: 0 0 10px rgba(var(--ldt-shadow-rgb), 0.11);
  padding: 1rem;
  margin-bottom: 1.25rem;
}

.athlete-head-photo {
  width: 84px;
  height: 84px;
  border-radius: 50%;
  object-fit: cover;
  flex: 0 0 auto;
}

.athlete-head-name {
  font-size: 1.5rem;
  font-weight: 300;
  margin: 0;
  line-height: 1.15;
  color: var(--text-main);
}

.athlete-head-name strong {
  font-weight: 600;
}

.athlete-head-country {
  margin: 0.2rem 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.athlete-head-titles {
  margin: 0.35rem 0 0;
  font-size: 0.9rem;
  color: var(--primary-dark);
  font-weight: 500;
}

.athlete-head-links {
  margin: 0.35rem 0 0;
  font-size: 0.82rem;
}

.athlete-head-links a {
  margin-right: 0.9rem;
}

.season-block {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 1rem 1.25rem 1.25rem;
  margin-bottom: 1rem;
}

.season-year {
  font-size: 1.35rem;
  font-weight: 500;
  color: var(--primary);
  margin: 0 0 0.5rem;
}

.season-laurier {
  font-size: 0.92rem;
  background-color: var(--ldt-primary-softer);
  border-radius: 0.6rem;
  padding: 0.5rem 0.75rem;
  margin: 0 0 0.75rem;
}

.season-laurier.is-laureate {
  background-color: var(--ldt-gold-soft);
  border: 1px solid var(--ldt-gold);
}

.season-summary {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-main);
  margin-bottom: 0.75rem;
}

.season-highlights {
  list-style: none;
  padding: 0.6rem 0.8rem;
  margin: 0 0 0.9rem;
  background-color: var(--ldt-surface-2);
  border-radius: 0.6rem;
  font-size: 0.88rem;
}

.season-highlights li {
  padding: 0.12rem 0;
}

.season-races {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.season-races caption {
  caption-side: top;
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  padding-bottom: 0.3rem;
}

.season-races td {
  padding: 0.35rem 0.4rem;
  border-top: 1px solid var(--ldt-border);
  vertical-align: top;
}

.season-date {
  width: 3.4rem;
  color: var(--text-muted);
  white-space: nowrap;
}

.season-dist {
  color: var(--text-muted);
  font-size: 0.78rem;
  white-space: nowrap;
}

.season-rank {
  width: 3rem;
  text-align: right;
  white-space: nowrap;
}

.season-dnf {
  color: var(--ldt-warning);
  font-size: 0.78rem;
}

.season-time {
  width: 4.6rem;
  text-align: right;
  color: var(--text-muted);
  white-space: nowrap;
}

/* --- Fiche candidat ------------------------------------------------------ */

.breadcrumb-trail {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-bottom: 0.75rem;
}

.breadcrumb-trail span {
  margin: 0 0.35rem;
}

.candidate-page .runner-card {
  margin-bottom: 0.9rem;
}

.candidate-result {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 0.85rem 1rem;
  margin-bottom: 0.9rem;
  font-size: 0.92rem;
  line-height: 1.5;
}

.candidate-result.is-laureate {
  border-color: var(--primary);
  background-color: var(--ldt-primary-softer);
}

.candidate-result-rank {
  font-size: 1.9rem;
  line-height: 1;
  flex: 0 0 auto;
}

.candidate-summary {
  margin-top: 1.5rem;
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 1rem 1.25rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text-main);
}

.candidate-summary p {
  margin-bottom: 0;
}

.candidate-links {
  margin-top: 0.9rem;
  font-size: 0.85rem;
}

.candidate-links a {
  margin-right: 1rem;
}

.sibling-list {
  columns: 2;
  column-gap: 1.5rem;
}

@media (max-width: 480px) {
  .sibling-list {
    columns: 1;
  }
}


/* ---------------------------------------------------------------------------
   Comptes votants : état connecté, entrée de menu, échec d'enregistrement.
   Les pages du parcours lui-même (inscription, connexion, mot de passe) ont
   leur propre feuille, compte.css, servie uniquement là-bas.
   --------------------------------------------------------------------------- */

/* Pendant du cadre rouge : une fois le compte actif, le même emplacement dit
   que tout est en ordre, plutôt que de disparaître. Un cadre qui s'efface
   laisse douter qu'il se soit passé quelque chose. */
.profil-signup.is-registered {
  border-color: var(--ldt-success-border);
  border-width: 2px;
}

.profil-account {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  background-color: var(--ldt-success-soft);
  border-radius: 0.7rem;
  padding: 0.75rem 0.9rem;
  margin-bottom: 0.5rem;
  color: var(--ldt-success-strong);
  font-size: 0.95rem;
  line-height: 1.45;
}

.profil-account-icon {
  flex: 0 0 auto;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background-color: var(--ldt-success);
  color: var(--ldt-on-primary);
  font-weight: 700;
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

.profil-account b {
  color: var(--ldt-success-strong);
}

.profil-account > span:last-child > b {
  display: block;
  font-size: 1.05rem;
}

.profil-account-detail {
  display: block;
  font-size: 0.85rem;
  color: var(--ldt-success);
  margin-top: 0.15rem;
}

.profil-account-detail b {
  font-weight: 600;
}

/* Un enregistrement raté ne se voit pas : le podium reste affiché, tout a
   l'air normal. D'où un bandeau franc, en haut de page. */
.vote-sync-error {
  background-color: var(--ldt-danger-soft);
  border: 2px solid var(--ldt-danger-border);
  border-radius: 0.7rem;
  color: var(--ldt-danger);
  font-weight: 600;
  padding: 0.8rem 1rem;
  margin-bottom: 1rem;
}

.compte-flash {
  border-radius: 0.7rem;
  padding: 0.75rem 1rem;
  margin-bottom: 1.25rem;
  font-weight: 600;
}

.compte-flash-success {
  background-color: var(--ldt-success-soft);
  color: var(--ldt-success-strong);
}

.compte-flash-danger {
  background-color: var(--ldt-danger-soft);
  color: var(--ldt-danger);
}


/* --- Carte candidat : identité sur deux lignes, palmarès dans l'en-tête ---
   Les règles d'origine vivent dans lauriers.css, laissé tel quel : c'est la
   copie conforme du site V1, et la modifier ferait perdre la référence.
   -------------------------------------------------------------------------- */

/* Le palmarès devient la troisième colonne : l'en-tête doit pouvoir passer à
   la ligne quand la place manque. */
.runner-header {
  flex-wrap: wrap;
}

.runner-name-link {
  display: block;
}

/* Le nom d'abord, le prénom dessous et plus discret : c'est le patronyme
   qu'on cherche dans une liste de trente candidats. */
.runner-lastname {
  display: block;
  font-weight: 600;
  line-height: 1.2;
  font-size: 1.4rem;
}

.runner-firstname {
  display: block;
  font-size: 1.3em;
  font-weight: 300;
  line-height: 1.25;
  color: var(--text-muted);
}

.runner-card:hover .runner-firstname {
  color: inherit;
}

.runner-flag {
  margin-right: 0.35rem;
}

/* Sorti du corps de la carte, le palmarès n'a plus de filet au-dessus : il
   sépare maintenant deux colonnes, pas deux blocs empilés. */
.runner-header > .runner-palmares {
  flex: 1 1 40%;
  min-width: 0;
  align-self: stretch;
  margin-top: 0;
  padding-top: 0;
  padding-left: 0.9rem;
  border-top: 0;
  border-left: 1px solid var(--ldt-border);
  font-size: 0.88rem;
}

/* Sur un téléphone, deux colonnes ne tiennent pas : le palmarès repasse
   dessous, et retrouve son filet horizontal. */
@media (max-width: 640px) {
  .runner-header > .runner-palmares {
    flex-basis: 100%;
    margin-top: 0.55rem;
    padding-top: 0.5rem;
    padding-left: 0;
    border-left: 0;
    border-top: 1px solid var(--ldt-border);
    font-size: 0.95rem;
  }

  /* A cote d une photo de 96 px, un patronyme de 1,1 rem mange toute la
     largeur et se coupe en deux lignes. */
  .runner-lastname {
    font-size: 1.1rem;
  }

  .runner-firstname {
    font-size: 1.1rem;
  }
}


/* --- Édition à venir : l'annonce et la demande d'alerte ------------------- */

/* Ni le bleu du vote ouvert ni le gris du vote clos : une édition qui se
   prépare est une bonne nouvelle, pas un état d'attente. */
.vote-notice.is-soon {
  border-color: var(--ldt-warning);
  background-color: var(--ldt-warning-soft);
}

.vote-notice.is-soon .vote-notice-title {
  color: var(--ldt-warning);
}

/* Le titre et le texte du bloc « Bientôt », partagés par la page d edition,
   l accueil et /editions/. Classes neutres : le cadre change d une page a
   l autre, le contenu non. */
.edition-soon-title {
  font-size: 1.6rem;
  font-weight: 300;
  color: var(--primary);
  margin-bottom: 0.4rem;
}

.edition-soon-text {
  font-size: 0.92rem;
  color: var(--text-main);
  margin-bottom: 0.9rem;
}

/* Dans le bandeau ambre de la page d edition, le bleu detonnerait. */
.vote-notice.is-soon .edition-soon-title {
  color: var(--ldt-warning);
  font-size: 1.25rem;
}

.alert-form {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--ldt-warning-border);
}

.alert-form-label {
  display: block;
  font-weight: 600;
  font-size: 0.95rem;
  margin-bottom: 0.5rem;
  color: var(--text-main);
}

/* Le champ et le bouton côte à côte tant qu'il y a la place : un formulaire
   d'une seule ligne se remplit sans y penser. */
.alert-form-row {
  display: flex;
  gap: 0.6rem;
  align-items: stretch;
}

.alert-form-input {
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid var(--ldt-border-strong);
  border-radius: 0.6rem;
  padding: 0.6rem 0.75rem;
  font-size: 1rem;
  font-family: inherit;
  background-color: var(--ldt-surface);
}

.alert-form-input:focus {
  outline: 2px solid var(--ldt-warning);
  outline-offset: 1px;
  border-color: var(--ldt-warning);
}

.alert-form .vote-btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Dire ce qu'on fera de l'adresse, à l'endroit où on la demande : c'est ce
   qui décide quelqu'un à la donner. */
.alert-form-note {
  margin: 0.6rem 0 0;
  font-size: 0.82rem;
  line-height: 1.45;
  color: var(--ldt-warning);
}

@media (max-width: 520px) {
  .alert-form-row {
    flex-direction: column;
  }

  .alert-form .vote-btn {
    width: 100%;
  }
}


/* --- Carte candidat repliable --------------------------------------------
   Seul .runner-card-body se replie. Le bouton et les boutons de vote sont en
   dehors : une carte compacte qui cacherait « 1er / 2e / 3e » rendrait la page
   inutile pour ce qu'elle sert.
   -------------------------------------------------------------------------- */

.runner-card {
  position: relative;
}

.runner-card-body {
  position: relative;
  transition: max-height 0.25s ease;
}

.runner-card.is-compact .runner-card-body {
  overflow: hidden;
}

/* Le dégradé dit que ça continue. Sans lui, une coupe nette se lit comme une
   fin de fiche, et personne ne cherche le bouton.

   Court, volontairement : la coupe tombe désormais à une ligne et demie de
   résumé, et un voile de 3 rem les aurait toutes les deux effacées. */
.runner-card.is-compact .runner-card-body::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1.7rem;
  background: linear-gradient(to bottom, transparent, var(--ldt-surface));
  pointer-events: none;
}

.resume-toggle-btn {
  display: block;
  width: 100%;
  margin-top: 0.4rem;
  padding: 0.45rem 0;
  border: 0;
  border-top: 1px dashed var(--ldt-border);
  background: transparent;
  color: var(--primary);
  font-family: inherit;
  font-size: 0.9rem;
  font-weight: 500;
  text-align: center;
  cursor: pointer;
}

.resume-toggle-btn:hover {
  background-color: var(--ldt-primary-softer);
}

/* Le pictogramme devant « Lire plus » / « Réduire » : un chevron dans un
   cercle, qui pointe vers ce qui va se passer — vers le bas pour déplier, vers
   le haut pour replier. Dessiné ici, en masque teinté par la couleur du
   texte, parce que runner-card.js réécrit le libellé à chaque bascule. */
.resume-toggle-btn::before {
  content: "";
  display: inline-block;
  width: 1.05rem;
  height: 1.05rem;
  margin-right: 0.4rem;
  vertical-align: -0.2em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m8 10.5 4 4 4-4'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='m8 10.5 4 4 4-4'/%3E%3C/svg%3E") center / contain no-repeat;
  transition: transform 0.2s ease;
}

.resume-toggle-btn[aria-expanded="true"]::before {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .resume-toggle-btn::before {
    transition: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .runner-card-body {
    transition: none;
  }
}

/* --- Rail des candidats ---------------------------------------------------
   La liste des noms de la catégorie, en marge, pour sauter d'un coureur à
   l'autre et savoir où l'on en est dans une liste de trente.
   -------------------------------------------------------------------------- */

.runner-list-wrap {
  position: relative;
}

.runner-rail {
  position: absolute;
  top: 0;
  bottom: 0;
  /* À cheval sur le bloc : la moitié déborde dans la marge, le reste mord sur
     la liste. Assez décalé pour ne pas couvrir le texte des cartes. */
  left: -104px;
  width: 128px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 5;
}

/* Il n'apparaît qu'une fois la liste atteinte : posé plus haut, il flotterait
   à côté du chapeau sans rien désigner. */
.runner-rail.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* Le cadre est porte par .runner-rail-inner, qui contient aussi le titre :
   la liste ne garde que ce qui la concerne. */
.runner-rail-list {
  list-style: none;
  margin: 0;
  scrollbar-width: thin;
}

.runner-rail-list a {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.28rem 0.45rem;
  border-radius: 0.45rem;
  border-left: 3px solid transparent;
  color: var(--text-muted);
  font-size: 0.74rem;
  line-height: 1.25;
  letter-spacing: 0.01em;
  text-decoration: none;
}

/* La medaille n occupe de la place que si le candidat est sur le podium. */
.runner-rail-medal {
  flex: 0 0 auto;
  font-size: 0.7rem;
  line-height: 1;
}

.runner-rail-medal:empty {
  display: none;
}

.runner-rail-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Retenu au podium : le nom s affirme, sans voler la vedette a celui
   qu on est en train de lire. */
.runner-rail-list a.is-chosen .runner-rail-name {
  color: var(--text-main);
  font-weight: 600;
}

.runner-rail-list a:hover {
  background-color: var(--ldt-primary-softer);
  color: var(--text-main);
}

/* Le coureur qu on est en train de lire : un bandeau bleu plein, texte et
   poignee en negatif. Le filet a gauche se voyait mal sur un rail etroit, et
   ne survivait pas au defilement rapide — un aplat se repere du coin de l oeil.
   La medaille, elle, garde ses couleurs : c est un emoji, et l or sur bleu
   reste lisible. */
.runner-rail-list a.is-current {
  border-left-color: transparent;
  background-color: var(--primary);
  color: var(--ldt-on-primary);
  font-weight: 600;
}

/* Un candidat au podium a son nom force en sombre : sur l aplat bleu il
   deviendrait illisible. On lui rend la couleur du bandeau. */
.runner-rail-list a.is-current .runner-rail-name {
  color: inherit;
}

/* Le survol ne doit pas repeindre par-dessus l aplat : la ligne courante reste
   bleue meme sous le curseur, sinon elle clignote au passage de la souris. */
.runner-rail-list a.is-current:hover {
  background-color: var(--primary);
  color: var(--ldt-on-primary);
}

.runner-rail-list a:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}



@media (prefers-reduced-motion: reduce) {
  .runner-rail {
    transition: none;
  }
}


/* --- Onglets de catégorie -------------------------------------------------
   Retour à la forme classique — des onglets raccordés au panneau, pas des
   pastilles flottantes — mais avec assez de couleur pour qu'on voie du premier
   coup lequel est ouvert et qu'il y en a trois autres.
   -------------------------------------------------------------------------- */

.nav-tabs {

  gap: 3px;
  padding-bottom: 0;
  flex-wrap: wrap;
  justify-content: center;
  /* lauriers.css met overflow-x: auto, hérité du temps où les onglets
     défilaient sur une seule ligne. Un axe en auto force l'autre en auto : la
     barre devenait une zone défilante, et les 2 px dont les onglets
     descendent pour se raccorder au trait suffisaient à la faire défiler
     verticalement. Les onglets passant désormais à la ligne, il n'y a plus
     rien à faire défiler. */
  overflow: visible;
}

.nav-tabs .nav-link {
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: 0.6rem 0.6rem 0 0;
  /* Un onglet fermé est posé en retrait : le fond gris-bleu le distingue du
     panneau blanc sans le faire disparaître. */
  background-color: var(--ldt-primary-soft);
  color: var(--ldt-primary-strong);
  font-weight: 500;
  font-size: 0.95rem;
  padding: 0.5rem 1rem;
  margin-bottom: -2px;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.nav-tabs .nav-link:hover {
  background-color: var(--ldt-primary-soft);
  color: var(--primary-dark, var(--ldt-primary-strong));
}

/* L'onglet ouvert est plein et se raccorde au panneau : c'est ce raccord qui
   fait comprendre que le contenu dessous lui appartient. */
.nav-tabs .nav-link.active {
  background-color: var(--ldt-accent, var(--primary));
  border-color: var(--ldt-accent, var(--primary));
  color: var(--ldt-on-accent, var(--ldt-on-primary));
  font-weight: 600;
}

.nav-tabs .nav-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.tab-pane {
  border-top: 0;
  border-radius: 0 0 1rem 1rem;
}

@media (max-width: 560px) {
  .nav-tabs {
    gap: 2px;
  }

  .nav-tabs .nav-link {
    font-size: 0.82rem;
    padding: 0.42rem 0.6rem;
  }
}


/* --- Grand écran : la carte respire --------------------------------------
   Plus de largeur, plus de place pour le nom et le palmarès, et la fiche
   entière d'emblée. Masquer le résumé demandait un clic par candidat pour
   lire précisément ce qui aide à choisir.
   -------------------------------------------------------------------------- */

@media (min-width: 768px) {
  .page-container {
    max-width: 800px;
  }

  .runner-lastname {
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.15;
  }

  .runner-firstname {
    font-size: 1.1rem;
    line-height: 1.2;
  }

  .runner-country {
    font-size: 1.05rem;
  }

  /* Décalé vers la droite : le filet vertical respire, et la colonne se lit
     comme une seconde colonne plutôt que comme la suite du nom. */
  .runner-header > .runner-palmares {
    padding-left: 1.6rem;
    margin-left: 0.4rem;
    font-size: 1rem;
    line-height: 1.5;
  }

  /* La carte est entière : le bouton n'a plus de raison d'être, et le dégradé
     de coupe non plus. */
  .resume-toggle-btn {
    display: none;
  }

  .runner-card.is-compact .runner-card-body {
    overflow: visible;
  }

  .runner-card.is-compact .runner-card-body::after {
    display: none;
  }
}


/* --- Rail : assez large pour le nom entier -------------------------------- */

.runner-rail {
  left: -186px;
  width: 210px;
}

.runner-rail-list a {
  font-size: 0.78rem;
}

/* Sous 1200 px, la marge ne suffit plus pour un rail de cette largeur : il se
   colle au bord de l'écran, comme sur téléphone, plutôt que de recouvrir la
   moitié d'une carte. */
/* Dès qu il passe en recouvrement, le rail va à DROITE. À gauche il tombait
   sur le portrait et le nom, c est-à-dire sur ce qu on regarde ; à droite il
   ne croise que la fin des lignes, et le pouce qui le manipule ne masque
   plus la carte. */
@media (max-width: 1199px) {
  .runner-rail {
    position: fixed;
    left: auto;
    right: 0;
    top: 50%;
    bottom: auto;
    transform: translateY(-50%);
    width: 150px;
    z-index: 30;
  }
}

@media (max-width: 767px) {
  .runner-rail {
    width: 134px;
  }

  .runner-rail-list a {
    font-size: 0.72rem;
    padding: 0.26rem 0.4rem;
  }
}


/* --- Rail : le cadre passe sur l'enveloppe, qui porte aussi le titre ------
   Le titre et la liste doivent coller ensemble au défilement : c'est donc
   l'enveloppe qui devient collante, plus la liste seule.
   -------------------------------------------------------------------------- */

.runner-rail-inner {
  position: sticky;
  top: 96px;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 150px);
  background-color: rgba(var(--ldt-surface-rgb), 0.94);
  border: 1px solid var(--border-soft);
  border-radius: 0.8rem;
  box-shadow: 0 2px 10px rgba(var(--ldt-shadow-rgb), 0.08);
  overflow: hidden;
}

/* La catégorie parcourue. Posé au bord de l'écran, le rail recouvre le titre
   de la section : sans ce rappel on ne sait plus quelle liste on lit. */
.runner-rail-title {
  flex: 0 0 auto;
  margin: 0;
  padding: 0.4rem 0.6rem;
  border-bottom: 1px solid var(--border-soft);
  background-color: var(--ldt-primary-softer);
  color: var(--primary);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.runner-rail-title-short {
  display: none;
}

/* La liste reprend le défilement, le cadre étant passé au-dessus. */
.runner-rail-list {
  position: static;
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  padding: 0.35rem 0.3rem;
}

@media (max-width: 1199px) {
  .runner-rail-inner {
    position: static;
    max-height: 66vh;
    /* Adossé au bord droit : c est ce côté-là qui disparaît. */
    border-right: 0;
    border-radius: 0.7rem 0 0 0.7rem;
    background-color: rgba(var(--ldt-surface-rgb), 0.96);
    box-shadow: -2px 2px 14px rgba(var(--ldt-shadow-rgb), 0.16);
  }
}

@media (max-width: 767px) {
  /* Plus haut que le centre : au milieu, le rail masque exactement la carte
     qu'on est en train de lire. Au tiers, il laisse le gros de l'écran libre. */
  .runner-rail {
    top: 33%;
  }

  .runner-rail-inner {
    max-height: 58vh;
  }

  /* « Court · H » plutôt que « Trail Court / Homme » : le rail fait 134 px. */
  .runner-rail-title-long {
    display: none;
  }

  .runner-rail-title-short {
    display: inline;
  }

  .runner-rail-title {
    font-size: 0.66rem;
    padding: 0.35rem 0.45rem;
  }
}




/* --- Rail : franchement dans la marge ------------------------------------
   Il ne mord plus sur la liste. Sous 1200 px il n y a pas la place, et il
   bascule en position fixe contre le bord — d ou la borne min-width ici :
   sans elle, ce décalage s appliquait AUSSI au mobile (les media queries
   ne pèsent rien en spécificité, seul l ordre compte) et le rail partait
   hors de l écran.
   -------------------------------------------------------------------------- */

@media (min-width: 1200px) {
  .runner-rail {
    left: -226px;
  }
}


/* --- Téléphone : la médaille du rang passe à droite du nom ----------------
   Par défaut elle déborde en haut à gauche, sur le portrait : elle cache le
   visage, qui est précisément ce qu'on regarde pour reconnaître quelqu'un.
   Le palmarès passant sous l'en-tête, le côté droit est libre à hauteur du
   nom — la carte s'équilibre et le portrait reste entier.
   -------------------------------------------------------------------------- */

@media (max-width: 767px) {
  .vote-rank-badge {
    top: 0.55rem;
    left: auto;
    right: 0.55rem;
    width: 46px;
    height: 46px;
    font-size: 1.55rem;
  }

  /* De la place pour elle : sans cette réserve, un nom long passerait dessous.

     flex-basis à zéro, et pas « auto » : l'en-tête peut passer à la ligne
     (c'est ce qui fait descendre le palmarès), et un élément flexible se
     replie AVANT de rétrécir. Avec une base calculée sur le contenu,
     « KIRIAGO Philemon Ombogo » passait sous la photo. */
  .runner-header-text {
    flex: 1 1 0%;
    padding-right: 3.4rem;
  }
}


/* --- Le rail, en mode classement ------------------------------------------ */

/* La poignee n apparait que quand le vote est ouvert : sans sélecteur de
   podium, il n y a rien a reclasser et le curseur mentirait. */
.runner-rail.is-sortable .runner-rail-list a {
  cursor: grab;
}

.runner-rail.is-dragging .runner-rail-list a {
  cursor: grabbing;
}

/* Pendant le glissement, la ligne suit le pointeur et passe au-dessus des
   autres. Elle n intercepte plus rien : c est ce qui laisse le calcul de la
   position d arrivee lire les lignes situees dessous. */
.runner-rail-list li.is-dragging {
  position: relative;
  z-index: 3;
  pointer-events: none;
}

.runner-rail-list li.is-dragging a {
  background-color: var(--ldt-surface);
  border-left-color: var(--primary);
  box-shadow: 0 6px 16px rgba(var(--ldt-shadow-rgb), 0.18);
  opacity: 0.95;
}

/* Le repere de depot : un filet a la place exacte ou la ligne tombera. */
.runner-rail-drop {
  height: 0;
  margin: 1px 0;
  border-top: 2px solid var(--primary);
  border-radius: 2px;
  list-style: none;
}

/* Hors du podium : la ligne garde une place dans le classement, mais pas de
   medaille. Le filet change de ton pour que la frontiere des trois premieres
   places se voie pendant le geste. */
.runner-rail-drop.is-out {
  border-top-color: var(--border-soft);
  border-top-style: dashed;
}

/* Pendant un glissement au doigt, le rail ne defile pas : c est la ligne qu on
   deplace, pas la liste. */
.runner-rail.is-dragging .runner-rail-list {
  overflow: hidden;
}

/* L appui maintenu qui souleve une ligne ne doit pas selectionner son texte
   ni ouvrir le menu contextuel : c est un geste de classement, pas de copie. */
.runner-rail.is-sortable .runner-rail-list a {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  /* Safari traine un lien meme marque draggable=false : sans ca, le
     glisser natif reprend la main et le curseur passe en  interdit . */
  -webkit-user-drag: none;
}


/* --- Les trois médailles, en cases à cocher -------------------------------
   Une case par médaille, dans la pilule qui portait le bouton : cocher donne
   la marche, décocher la retire. La case reste visible — c'est elle qui dit
   « je peux revenir en arrière », ce qu'un bouton ne disait pas.
   -------------------------------------------------------------------------- */

.vote-pick-btn {
  -webkit-user-select: none;
  user-select: none;
}

.vote-pick-check {
  -webkit-appearance: none;
  appearance: none;
  flex: 0 0 auto;
  width: 1.05rem;
  height: 1.05rem;
  margin: 0;
  border: 1.5px solid var(--ldt-border-strong);
  border-radius: 0.25rem;
  background-color: var(--ldt-surface);
  display: inline-grid;
  place-content: center;
  cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* La coche, dessinée plutôt qu'en police : même trait sur tous les systèmes. */
.vote-pick-check::before {
  content: "";
  width: 0.55rem;
  height: 0.3rem;
  border-left: 2px solid currentColor;
  border-bottom: 2px solid currentColor;
  transform: translateY(-1px) rotate(-45deg) scale(0);
  transition: transform 0.12s ease;
}

.vote-pick-check:checked {
  border-color: currentColor;
  /* Blanc fixe : la pastille de médaille a des couleurs fixes, le reflet
     aussi — il ne dépend pas du style. */
  background-color: rgba(255, 255, 255, 0.85);
}

.vote-pick-check:checked::before {
  transform: translateY(-1px) rotate(-45deg) scale(1);
}

/* Le focus clavier va à la case, mais c'est la pilule entière qu'on voit. */
.vote-pick-check:focus-visible {
  outline: none;
}

.vote-pick-btn:focus-within {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

/* Sur téléphone, trois pilules de front : la case et le libellé doivent
   tenir sans passer à la ligne. */
@media (max-width: 480px) {
  .vote-pick {
    gap: 0.35rem;
  }

  .vote-pick-btn {
    gap: 0.25rem;
    padding: 0.5rem 0.3rem;
    font-size: 0.8rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .vote-pick-check,
  .vote-pick-check::before {
    transition: none;
  }
}

/* Une ligne sous le titre du bulletin : comment on le remplit. */
.vote-ballot-hint {
  margin: -0.35rem 0 0.6rem;
  font-size: 0.78rem;
  color: var(--text-muted);
}


/* --- La poignee du rail ---------------------------------------------------
   Le rail se reclasse a la souris et au doigt, mais rien ne le disait : un
   curseur  main ouverte  ne se voit pas sur telephone, et pas du tout avant
   d avoir survole. La poignee le dit, a l endroit ou le regard est deja — la
   ligne qu on est en train de lire — et sous le curseur.

   Posee sur les trente lignes a la fois, elle n aurait fait qu un mur de
   points ; d ou l apparition ciblee.
   -------------------------------------------------------------------------- */

/* La main est dessinée au trait (stroke="currentColor") : sa teinte se règle
   par color, pas par fill. */
.runner-rail-grip {
  flex: 0 0 auto;
  margin-left: auto;
  width: 15px;
  height: 15px;
  color: var(--ldt-text-faint);
  opacity: 0;
  transition: opacity 0.15s ease, color 0.15s ease;
}

/* Hors vote ouvert il n y a rien a reclasser : la poignee mentirait. */
.runner-rail:not(.is-sortable) .runner-rail-grip {
  display: none;
}

.runner-rail.is-sortable .runner-rail-list a.is-current .runner-rail-grip,
.runner-rail.is-sortable .runner-rail-list a:hover .runner-rail-grip,
.runner-rail.is-sortable .runner-rail-list a:focus-visible .runner-rail-grip {
  opacity: 1;
}

/* Sur l aplat bleu, la poignee passe en negatif comme le texte : en bleu
   elle disparaitrait dans le fond. */
.runner-rail.is-sortable .runner-rail-list a.is-current .runner-rail-grip {
  color: var(--ldt-on-primary);
}

/* Pendant le geste, la poignee reste visible sur la ligne soulevee : c est
   elle qu on tient. */
.runner-rail-list li.is-dragging .runner-rail-grip {
  opacity: 1;
  color: var(--primary);
}

/* Au doigt il n y a ni survol ni curseur : la poignee est montree partout,
   c est le seul indice disponible. */
@media (pointer: coarse) {
  .runner-rail.is-sortable .runner-rail-grip {
    opacity: 0.55;
  }
}


/* --- L en-tete du profil ---------------------------------------------------
   Le titre, l etat du compte et celui de l edition repondaient a la meme
   question — mon vote compte-t-il, et jusqu a quand ? — et y repondaient dans
   trois cadres separes, ce qui obligeait a les lire dans le desordre. Un seul
   bloc, du plus general au plus precis : pour quelle edition, par qui, dans
   quels delais.
   -------------------------------------------------------------------------- */

.profil-entete {
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 1rem;
  padding: 1.1rem 1.25rem 1.25rem;
  margin-bottom: 1.5rem;
}

/* Le cadre passe au rouge tant qu aucun compte n existe : c est l information
   qui decide si le vote comptera ou non. */
.profil-entete.is-unregistered {
  border-color: var(--ldt-danger-border);
  border-width: 2px;
}

.profil-entete-title {
  margin: 0 0 0.8rem;
  font-size: 1.45rem;
  line-height: 1.2;
  color: var(--text-main);
}

/* Meme gabarit que l etat  connecte , en rouge : l oeil reconnait le bandeau
   et va droit au message, quel que soit le regime. */
.profil-account.is-warning {
  background-color: var(--ldt-danger-soft);
  color: var(--ldt-danger-strong);
}

.profil-account.is-warning .profil-account-icon {
  background-color: var(--ldt-danger);
}

.profil-account.is-warning .profil-account-detail {
  color: var(--ldt-danger-strong);
}

.profil-account.is-warning b {
  color: var(--ldt-danger-strong);
}

.profil-entete-etat {
  margin: 0.9rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border-soft);
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text-muted);
}

.profil-entete-etat b {
  color: var(--text-main);
}

.profil-entete-etat.is-closed b {
  color: var(--ldt-warning);
}

/* La synthèse des podiums : une ligne par catégorie, sans cadre — le nom,
   et à droite ce qu'il reste à faire, avec une pastille à la couleur de
   l'état (même code que les pastilles des blocs). Elle mène au bloc. */
.profil-synthese {
  list-style: none;
  display: grid;
  gap: 0 2rem;
  margin: 0.9rem 0 0;
  padding: 0.6rem 0 0;
  border-top: 1px solid var(--border-soft);
}

.profil-synthese.is-after-closed {
  border-top: 0;
  padding-top: 0;
}

@media (min-width: 700px) {
  .profil-synthese {
    grid-template-columns: 1fr 1fr;
  }
}

.profil-synthese-lien {
  display: flex;
  align-items: baseline;
  gap: 0.75rem;
  padding: 0.3rem 0;
  color: var(--ldt-heading);
  text-decoration: none;
}

.profil-synthese-lien:hover .profil-synthese-cat,
.profil-synthese-lien:focus-visible .profil-synthese-cat {
  text-decoration: underline;
  text-underline-offset: 3px;
}

.profil-synthese-cat {
  flex: 1 1 auto;
  min-width: 0;
  font-weight: 500;
  font-size: 0.95rem;
}

.profil-synthese-etat {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.85rem;
  font-weight: 600;
  white-space: nowrap;
}

.profil-synthese-etat::before {
  content: "";
  width: 0.6rem;
  height: 0.6rem;
  border-radius: 50%;
  background-color: currentColor;
}

.profil-synthese-lien.is-ready .profil-synthese-etat {
  color: var(--ldt-success);
}

.profil-synthese-lien.is-partial .profil-synthese-etat {
  color: var(--ldt-warning);
}

.profil-synthese-lien.is-empty .profil-synthese-etat {
  color: var(--ldt-danger);
}

/* Le bloc visé par un lien de la synthèse ne se cache pas sous l'en-tête
   fixe du téléphone, et se signale brièvement. */
.profil-category {
  scroll-margin-top: 90px;
}

.profil-category:target {
  animation: profil-cible 1.6s ease-out;
}

@keyframes profil-cible {
  from {
    box-shadow: 0 0 0 3px rgba(var(--ldt-primary-rgb), 0.45);
  }

  to {
    box-shadow: 0 0 0 3px rgba(var(--ldt-primary-rgb), 0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .profil-category:target {
    animation: none;
  }
}

/* Les trois dates, chacune collee a son libelle : a gauche et a droite d une
   ligne large, l oeil perdait le lien entre les deux. */
.profil-dates {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  font-size: 0.9rem;
}

/* Libelle et date sur une seule ligne, toujours : coupee en deux, une date
   se lit mal et on ne sait plus a quel libelle elle appartient. */
.profil-dates li {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.35rem;
  white-space: nowrap;
  padding: 0.35rem 0;
  border-top: 1px dashed var(--border-soft);
  color: var(--text-muted);
}

.profil-dates li:first-child {
  border-top: 0;
}

/* L echeance qui vient : c est la seule qui demande une action. */
.profil-dates li.is-next {
  color: var(--text-main);
  font-weight: 600;
}

.profil-date-label::after {
  content: " :";
}

.profil-date-value {
  font-variant-numeric: tabular-nums;
}

@media (max-width: 480px) {
  .profil-entete {
    padding: 1rem;
  }

  /* « Clôture des votes : 01/12/2026 à 23 h 59 » ne tient pas sur un petit
     telephone. La section parle deja des votes : « Clôture » suffit. */
  .profil-date-long {
    display: none;
  }

  .profil-dates {
    font-size: 0.85rem;
  }

  .profil-entete-title {
    font-size: 1.25rem;
  }

}

/* --- Menu : icône et sous-menu de l'édition -------------------------------
   Attention au sélecteur .site-nav ul, qui met en ligne TOUTE liste du menu :
   les règles du sous-menu passent par .site-nav .site-subnav pour l'emporter,
   sans quoi il serait affiché en permanence, en rangée. */

.site-nav a.site-nav-with-icon {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
}

.site-nav-icon {
  width: 17px;
  height: 17px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
}

.site-nav-has-sub {
  position: relative;
  display: flex;
  align-items: center;
}

.site-subnav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  margin-left: -0.45rem;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}

.site-subnav-toggle svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.15s ease;
}

.site-subnav-toggle:hover,
.site-subnav-toggle:focus-visible {
  color: var(--primary);
  background-color: var(--ldt-primary-softer);
}

.site-nav-has-sub.is-sub-open .site-subnav-toggle svg {
  transform: rotate(180deg);
}

.site-nav .site-subnav {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 60;
  min-width: 13rem;
  margin: 0;
  padding: 0.35rem;
  flex-direction: column;
  align-items: stretch;
  gap: 0.1rem;
  list-style: none;
  background-color: var(--ldt-surface);
  border: 1px solid var(--border-soft);
  border-radius: 0.8rem;
  box-shadow: 0 12px 28px rgba(var(--ldt-shadow-rgb), 0.14);
}

/* Survol, clavier ou bouton : trois façons d'ouvrir, pour trois façons de
   naviguer. */
.site-nav .site-nav-has-sub:hover > .site-subnav,
.site-nav .site-nav-has-sub:focus-within > .site-subnav,
.site-nav .site-nav-has-sub.is-sub-open > .site-subnav {
  display: flex;
}

.site-nav .site-subnav a {
  border-radius: 0.55rem;
  padding: 0.5rem 0.75rem;
}

/* Sous 700 px, le menu est déjà un panneau : le sous-menu s'y range en
   retrait, toujours déplié. Un second niveau à ouvrir au doigt, dans un
   panneau qu'on vient d'ouvrir, serait un geste de trop. */
@media (max-width: 699px) {
  .site-nav-has-sub {
    display: block;
  }

  .site-subnav-toggle {
    display: none;
  }

  .site-nav .site-subnav {
    display: flex;
    position: static;
    min-width: 0;
    padding: 0 0 0.25rem 0.9rem;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    background: none;
  }

  .site-nav .site-subnav a {
    padding: 0.5rem 0.85rem;
    font-size: 0.92rem;
  }
}

/* --- Bandeau du compte : la déconnexion à droite --------------------------
   Le titre en gras était rendu bloc par « > span:last-child > b ». Le lien de
   déconnexion est désormais le dernier enfant : la règle vise donc le détail
   par sa classe, et un <strong> au fil du texte reste en ligne. */
.profil-account-detail > b {
  display: block;
  font-size: 1.05rem;
}

.profil-account-detail {
  flex: 1 1 auto;
  min-width: 0;
}

/* « Connecté », puis le nom — et pour un expert, son badge. */
.profil-account-name {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem 0.5rem;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ldt-success-strong);
  overflow-wrap: anywhere;
}

.profil-expert {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.1rem 0.55rem 0.1rem 0.3rem;
  border-radius: 999px;
  background-color: var(--ldt-gold-soft);
  color: var(--ldt-gold);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  line-height: 1.5;
}

.profil-expert svg {
  width: 16px;
  height: 16px;
  fill: currentColor;
}

.profil-expert .profil-expert-coche {
  fill: none;
  stroke: var(--ldt-gold-soft);
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.profil-logout {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  margin-left: auto;
  padding: 0.35rem 0.7rem;
  border: 1px solid var(--ldt-success-border);
  border-radius: 999px;
  background-color: var(--ldt-surface);
  color: var(--ldt-success-strong);
  font-size: 0.85rem;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
}

.profil-logout:hover,
.profil-logout:focus-visible {
  background-color: var(--ldt-success-strong);
  border-color: var(--ldt-success-strong);
  color: var(--ldt-on-primary);
}

.profil-logout svg {
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Compte connecté : l'icône, « Connecté + nom » et le bouton sur une même
   ligne, centrés l'un sur l'autre. Le texte est assez court pour tenir à côté
   du bouton même sur téléphone ; un nom long passe à la ligne, le badge
   expert aussi, mais le bouton reste en face. */
.profil-account:not(.is-warning) {
  align-items: center;
}

.profil-expert {
  white-space: nowrap;
}

@media (max-width: 480px) {
  .profil-account:not(.is-warning) {
    gap: 0.6rem;
  }

  .profil-logout {
    padding: 0.35rem 0.6rem;
  }
}

/* Très petit écran : le bouton se réduit à son icône (son nom reste lu par
   les lecteurs d'écran, et s'affiche au survol), pour laisser au nom la
   place de tenir. */
@media (max-width: 379px) {
  .profil-logout {
    padding: 0.5rem;
  }

  .profil-logout-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .profil-logout svg {
    width: 18px;
    height: 18px;
  }
}

/* --- En-tête : aligné sur le contenu, transparent en desktop --------------
   Jusqu'ici une barre fixe de 650 px sur fond blanc, au-dessus d'un contenu
   de 800 px : les deux ne tombaient pas l'un sous l'autre.

   En desktop, l'en-tête reprend sa place en haut de la page et défile avec
   elle. Fixe ET transparent, il aurait laissé passer le texte sous le logo et
   le menu, qui seraient devenus illisibles. Du coup, plus rien à compenser :
   le contenu, le rail et les sauts d'ancre ne réservent plus ses 88 px.

   En mobile, rien ne change : barre fixe, fond blanc, menu derrière le bouton.
   -------------------------------------------------------------------------- */

/* Le logo et le titre prennent de la place, sur téléphone comme ailleurs. */
.site-header .site-header-logo {
  width: 56px;
  height: 56px;
}

.site-header .site-title {
  font-size: 1.2rem;
  font-weight: 600;
}

@media (max-width: 400px) {
  .site-header .site-header-logo {
    width: 50px;
    height: 50px;
  }

  .site-header .site-title {
    font-size: 1.05rem;
  }
}

@media (min-width: 700px) {
  .site-header {
    position: relative;
    left: auto;
    transform: none;
    margin: 0 auto;
    /* Même boîte que .page-container : même largeur, même gouttière. */
    max-width: 650px;
    padding: 20px 10px 6px;
    background-color: transparent;
    border-bottom: 0;
  }

  .site-header .site-header-logo {
    width: 68px;
    height: 68px;
  }

  .site-header .site-title {
    font-size: 1.4rem;
  }

  .page-container {
    padding-top: 12px;
  }

  /* Le cadre du rail collait sous la barre fixe ; il colle maintenant au
     haut de l'écran. */
  .runner-rail-inner {
    top: 24px;
  }
}

@media (min-width: 768px) {
  .site-header {
    max-width: 800px;
    padding-left: 24px;
    padding-right: 24px;
  }
}

@media (min-width: 992px) {
  .site-header .site-header-logo {
    width: 84px;
    height: 84px;
  }

  .site-header .site-title {
    font-size: 1.7rem;
  }
}

/* En mobile aussi, la marque démarre au bord du contenu (10 px de gouttière
   pour .page-container), et le bouton de menu finit à son bord droit. */
@media (max-width: 699px) {
  .site-header {
    padding-left: 10px;
    padding-right: 10px;
  }
}

/* Entre 700 et 767 px, le contenu ne fait que 650 px : le titre venait buter
   contre le menu. Un cran de moins sur cette plage seulement. */
@media (min-width: 700px) and (max-width: 767px) {
  .site-header .site-header-logo {
    width: 60px;
    height: 60px;
  }

  .site-header .site-title {
    font-size: 1.25rem;
  }
}

/* --- Pied de page : aligné sur le contenu, comme l'en-tête ----------------
   Une barre blanche fixe de 650 px sous un contenu de 800 : ses bords ne
   tombaient pas sous ceux des cartes. En desktop, la bande blanche a
   désormais exactement la largeur du contenu (gouttières de .page-container
   déduites) ; en mobile, elle reste une barre d'un bord à l'autre de l'écran.
   Elle reste fixe et blanche : rien ne passe au travers. */
@media (min-width: 700px) {
  .site-footer {
    width: calc(100% - 20px);
    max-width: 630px;
    padding-left: 16px;
    padding-right: 16px;
  }
}

@media (min-width: 768px) {
  .site-footer {
    width: calc(100% - 48px);
    max-width: 752px;
  }
}

/* --- Onglets de catégorie : des cases de même largeur ----------------------
   En flex, chaque onglet prenait la largeur de son libellé : « Trail Long /
   Homme » et « Trail Court / Femme » n'avaient pas la même taille, et sur
   téléphone la seconde ligne ne tombait pas sous la première. Une grille à
   colonnes égales règle les deux : 2 × 2 sur téléphone et tablette, les 4 sur
   une seule ligne à partir du desktop. */
.nav-tabs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 3px;
}

.nav-tabs .nav-item {
  min-width: 0;
}

.nav-tabs .nav-link {
  width: 100%;
  height: 100%;
  text-align: center;
  /* Un libellé trop long pour sa case passe à la ligne plutôt que de
     déborder sur la voisine. */
  white-space: normal;
  line-height: 1.2;
}

@media (min-width: 768px) {
  .nav-tabs {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Sur deux lignes, seule la seconde touche le panneau. La première ne se
   raccorde à rien : ses onglets deviennent des cases arrondies, posées un peu
   au-dessus, au lieu de se faire écraser par la ligne du dessous. */
@media (max-width: 767px) {
  .nav-tabs {
    row-gap: 5px;
  }

  .nav-tabs .nav-item:nth-child(-n+2) .nav-link {
    margin-bottom: 0;
    border-bottom: 1px solid transparent;
    border-radius: 0.6rem;
  }

  .nav-tabs .nav-item:nth-child(-n+2) .nav-link.active {
    border-bottom-color: var(--ldt-accent, var(--primary));
  }
}


/* --- Les courses de l'année, sous la carte d'un candidat ------------------
   Même filet et même titre que le résumé juste au-dessus : c'est une
   rubrique de plus de la saison, pas un encadré à part. Le tableau est celui
   de la page athlète (views/partials/season-races.php).
   -------------------------------------------------------------------------- */

.runner-races {
  margin-top: 0.55rem;
  padding-top: 0.45rem;
  border-top: 1px dashed var(--ldt-border);
}

.runner-races-count {
  display: inline-block;
  min-width: 1.35rem;
  margin-left: 0.25rem;
  padding: 0 0.4rem;
  border-radius: 999px;
  background-color: var(--ldt-surface-2);
  color: var(--text-muted);
  font-size: 0.72rem;
  font-weight: 600;
  line-height: 1.35rem;
  text-align: center;
  letter-spacing: 0;
}

.runner-races .season-races {
  margin-top: 0.2rem;
  font-size: 0.85rem;
}

/* Le filet du titre suffit : pas de trait au-dessus de la première course. */
.runner-races .season-races tr:first-child td {
  border-top: 0;
}

.runner-races .season-races td {
  padding: 0.28rem 0.35rem;
}

.runner-races .season-races td:first-child {
  padding-left: 0;
}

.runner-races .season-races td:last-child {
  padding-right: 0;
}

/* Sur téléphone, le temps passe sous le rang plutôt que de pousser le nom de
   la course sur trois lignes. */
@media (max-width: 480px) {
  .runner-races .season-races tr {
    display: grid;
    grid-template-columns: 3rem 1fr auto;
    border-top: 1px solid var(--ldt-border);
  }

  .runner-races .season-races tr:first-child {
    border-top: 0;
  }

  .runner-races .season-races td {
    border-top: 0;
  }

  .runner-races .season-races .season-time {
    grid-column: 2 / 4;
    width: auto;
    padding-top: 0;
    text-align: left;
    font-size: 0.78rem;
  }
}


/* --- Logo et bouton de thème dans l'en-tête --------------------------------
   Le logo vient du style actif (public/styles/<nom>/logo.html) ; seule sa
   place se règle ici. Le bouton clair / sombre : à gauche du bouton de menu
   sur téléphone, après le menu sur grand écran.
   -------------------------------------------------------------------------- */

.site-brand,
.site-brand:hover {
  text-decoration: none;
}


/* --- Logo livré en fichiers SVG ------------------------------------------
   Un style peut fournir son logo en images (logo-clair.svg, logo-sombre.svg,
   idem pour l'emblème) plutôt qu'en balisage : les deux images sont dans la
   page, le thème n'en montre qu'une. Seule la hauteur se règle, la largeur
   suit les proportions du dessin. Quand le logo prend les couleurs de la
   palette, ce sont des <svg> insérés dans la page, réglés de la même façon. */

.ldt-marque-image {
  display: inline-flex;
  align-items: center;
  line-height: 0;
}

.ldt-marque-image img,
.ldt-marque-image svg {
  display: block;
  width: auto;
  height: 100%;
  max-width: none;
}

.ldt-marque-image .ldt-variante-sombre,
[data-theme="dark"] .ldt-marque-image .ldt-variante-clair {
  display: none;
}

[data-theme="dark"] .ldt-marque-image .ldt-variante-sombre {
  display: block;
}

/* 48 px au plus petit : en dessous, un logo sur deux lignes devient illisible
   (c'est le minimum que donnent les chartes livrées). */
.site-brand .ldt-marque-image {
  height: 48px;
}

@media (min-width: 700px) {
  .site-brand .ldt-marque-image {
    height: 50px;
  }
}

@media (min-width: 992px) {
  .site-brand .ldt-marque-image {
    height: 58px;
  }

  .lauriers-fiche .site-brand .ldt-marque-image {
    height: 50px;
  }
}

/* Les emplacements du logo hors de l'en-tête : accueil (logo complet),
   fiche candidat et bannière des lauréats (emblème, sur fond sombre). Un
   logo en balisage (logo.html) y règle sa taille dans son style.css. */
.brand-home {
  display: flex;
  justify-content: center;
  margin: 0.5rem 0 1.5rem;
}

.brand-home .ldt-marque-image {
  height: 120px;
}

@media (max-width: 480px) {
  .brand-home .ldt-marque-image {
    height: 92px;
  }
}

.brand-card {
  display: flex;
  justify-content: center;
  margin: 0 0 1rem;
}

.brand-card .ldt-marque-image {
  height: 64px;
}

.brand-laureates {
  flex: 0 0 auto;
}

.brand-laureates .ldt-marque-image {
  height: 56px;
}
.site-brand:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 4px;
  border-radius: 0.4rem;
}

.site-theme-toggle {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1px solid var(--border-soft);
  border-radius: 0.6rem;
  background-color: var(--ldt-surface);
  color: var(--ldt-text);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.site-theme-toggle:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.site-theme-toggle:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.site-theme-icon {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Le pictogramme dit ce qu'on obtiendra : la lune en clair, le soleil en
   sombre. */
.site-theme-icon-soleil,
[data-theme="dark"] .site-theme-icon-lune {
  display: none;
}

[data-theme="dark"] .site-theme-icon-soleil {
  display: block;
}

@media (max-width: 699px) {
  .site-theme-toggle {
    margin-left: auto;
  }

  .site-theme-toggle + .site-burger {
    margin-left: 0;
  }
}

@media (min-width: 700px) {
  .site-theme-toggle {
    order: 3;
    width: 38px;
    height: 38px;
    margin-left: 0.15rem;
  }
}

/* --- Fenêtre de confirmation (liens data-confirm, menu.js) ---------------- */

.site-confirm {
  width: min(380px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--ldt-border);
  border-radius: 1rem;
  background-color: var(--ldt-surface);
  color: var(--ldt-text);
  box-shadow: 0 18px 50px rgba(var(--ldt-shadow-rgb), 0.35);
}

.site-confirm::backdrop {
  background-color: rgba(var(--ldt-shadow-rgb), 0.45);
}

.site-confirm-form {
  padding: 1.3rem 1.3rem 1.1rem;
}

.site-confirm-texte {
  margin: 0 0 1.1rem;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--ldt-heading);
}

.site-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.6rem;
}

.site-confirm-actions button {
  padding: 0.5rem 1rem;
  border-radius: 999px;
  font-size: 0.95rem;
  font-weight: 600;
  cursor: pointer;
}

.site-confirm-non {
  border: 1px solid var(--ldt-border-strong);
  background-color: transparent;
  color: var(--ldt-text);
}

.site-confirm-oui {
  border: 1px solid var(--ldt-primary);
  background-color: var(--ldt-primary);
  color: var(--ldt-on-primary);
}

.site-confirm-non:hover,
.site-confirm-non:focus-visible {
  background-color: var(--ldt-surface-2);
}

.site-confirm-oui:hover,
.site-confirm-oui:focus-visible {
  background-color: var(--ldt-primary-strong);
  border-color: var(--ldt-primary-strong);
}

/* --- Mentions légales ----------------------------------------------------- */

.site-footer-sep {
  margin: 0 0.35rem;
  opacity: 0.6;
}

.legal {
  max-width: 760px;
}

.legal-section {
  margin-top: 2rem;
  line-height: 1.6;
  color: var(--ldt-text);
}

.legal-section h3 {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ldt-heading);
  margin-bottom: 0.6rem;
}

.legal-section h4 {
  font-size: 1rem;
  font-weight: 600;
  color: var(--ldt-heading);
  margin: 1.2rem 0 0.4rem;
}

.legal-section ul {
  padding-left: 1.2rem;
}

.legal-section li + li {
  margin-top: 0.35rem;
}

.legal-section a {
  color: var(--ldt-primary);
}

/* Ce qui reste à remplir se voit d'un coup d'œil à la relecture. */
.legal-todo {
  padding: 0.05rem 0.35rem;
  border-radius: 0.3rem;
  background-color: var(--ldt-warning-soft);
  color: var(--ldt-warning);
  border: 1px dashed var(--ldt-warning-border);
  font-weight: 600;
}

.legal-table {
  overflow-x: auto;
  margin: 0.8rem 0 1rem;
}

.legal-table table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

.legal-table th,
.legal-table td {
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--ldt-border);
  text-align: left;
  vertical-align: top;
}

.legal-table th {
  font-size: 0.78rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ldt-text-muted);
}

.legal-table code {
  color: var(--ldt-heading);
  white-space: nowrap;
}

/* Sur téléphone, le lien passe à la ligne : le point n'a plus rien à séparer. */
@media (max-width: 699px) {
  .site-footer-sep {
    display: none;
  }

  .site-footer-sep + a {
    display: block;
    margin-top: 0.15rem;
  }
}
